[futurebasic] Re: [FB] CG Color

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : March 2011 : Group Archive : Group : All Groups

From: Ken Shmidheiser <kshmidheiser@...>
Date: Sun, 6 Mar 2011 18:42:23 -0500
Concerning his frustration with

>I wanted to go to HIThemeDrawTextBox for both screen and printing. 
>Using a CGcontext with DrawThemeTextBox does not give me any back 
>color control, only forecolor.

Steve,

The following demo uses CoreText in OS X 10.5 and newer to draw some 
text into a context. Here I simply grab the context of an FB window 
and work with it, but the code can easily be used to draw text into 
any context.

While as a whole it may look complicated, once you break it down into 
steps, it's pretty easy to work with for simple examples. If you were 
writing a text or word processor from scratch, you probably would use 
the lower level CoreText to accomplish that. Otherwise, you may be 
better off using a higher level text manager.

Ken

/*

    Following is a demo of drawing text
    into a context using CoreText.

    Ken Shmidheiser
    March 6, 2011

    Note: Min OS deployment must be set to 10.5 or higher for CoreText.

    In FB 5.5 and earlier, the the CTFrame.incl toolbox
    call CTFrameGetLineOrigins should be opened from within
    the application package and changed:

Change:
toolbox CTFrameGetLineOrigins( CTFrameRef frame, CFRange range, 
CGPoint origins )// AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;

Corrected:
toolbox CTFrameGetLineOrigins( CTFrameRef frame, CFRange range, 
CGPoint * origins )// AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;

*/

if system(_sysVers) < 1050 then shutdown ("Requires OS X 10.5 or newer")

include "Tlbx CoreGraphics.incl"
include "Tlbx CoreText.incl"

dim as CFAttributedStringRef           tempString
dim as CFMutableAttributedStringRef    attrString
dim as CTFramesetterRef                framesetter
dim as CGMutablePathRef                path
dim as CTFrameRef                      frame
dim as CFIndex                         i, count
dim as CGPoint                         origins
dim as CFArrayRef                      lines
dim as CFRange                         range
dim as CGContextRef                    context
dim as CGrafPtr                        port
dim as CTFontRef                       font
dim as Double                          fontSize
dim as CTTextAlignment                 alignment
dim as CTParagraphStyleSetting         settings
dim as CTParagraphStyleRef             paragraphStyle
dim as CFIndex                         theNumberOfSettings
dim as CGColorSpaceRef                 rgbColorSpace
dim as CGColorRef                      black, red
dim as CGRect                          wndRect

window 1,,(0,0)-(500,300),_docNoGrow

//    get port bounds for the window
GetPort( @port )

//    get context for the port bounds
fn QDBeginCGContext( port, @context )

//    initialize text matrix (or expect unpredictable results)
CGContextSetTextMatrix( context, CGAffineTransformIdentity )

//    set context background to opaque black before setting other colors
//    if it is set after other colors, like font color, it will be an overlay
black = fn CGColorCreateGenericRGB( 0.0, 0.0, 0.0, 1.0 )
CGContextSetFillColorWithColor( context, black )
wndRect = fn CGRectMake( 0, 0, window( _width ), window( _height ) )
CGContextFillRect( context, wndRect )
CFRelease( black )

//    create CFAttributedString with some text
tempString = fn CFAttributedStringCreate( _kCFAllocatorDefault, 
@"Hello, World!", #0 )

//    convert string to a CFMutableAttributedStringRef for input into 
CFAttributedStringSetAttribute
attrString = fn CFAttributedStringCreateMutableCopy( 
_kCFAllocatorDefault, 0, tempString )

//     release the temporary string
CFRelease( tempString )

//    create font color (red for this demo)
red = fn CGColorCreateGenericRGB( 1.0, 0.0, 0.0, 1.0 )

//    set the string's font color attribute
CFAttributedStringSetAttribute( attrString, fn CFRangeMake( 0, fn 
CFAttributedStringGetLength( attrString ) ), 
kCTForegroundColorAttributeName, red )
CFRelease( red )

//    create font face and size
fontSize = 50.5     //font size is in points
font = fn CTFontCreateWithName( @"Times New Roman Bold", fontSize, #0 )

//    set string's font attribute
CFAttributedStringSetAttribute( attrString, fn CFRangeMake( 0, fn 
CFAttributedStringGetLength( attrString ) ), kCTFontAttributeName, 
font )
CFRelease( font )

//     prepare font alignment
theNumberOfSettings = 1
alignment = _kCTCenterTextAlignment
settings.spec = _kCTParagraphStyleSpecifierAlignment
settings.valueSize = sizeof(alignment)
settings.value = @alignment

//     create paragraph style
paragraphStyle = fn CTParagraphStyleCreate( settings, theNumberOfSettings )

//    set string's paragraph style attribute
CFAttributedStringSetAttribute( attrString, fn CFRangeMake( 0, fn 
CFAttributedStringGetLength( attrString ) ), 
kCTParagraphStyleAttributeName, paragraphStyle )
CFRelease( paragraphStyle )

//     create framesetter for string
framesetter = fn CTFramesetterCreateWithAttributedString( attrString )
fn CFRelease( attrString )

//      create path, rect and frame to hold string and center in window
path = fn CGPathCreateMutable()
CGPathAddRect( path, #0, fn CGRectMake( wndRect.origin.x, 
wndRect.origin.y, wndRect.size.width, ( wndRect.size.height/2 ) + 
fontSize ) )
frame = fn CTFramesetterCreateFrame(framesetter, fn CFRangeMake( 0, 0 
), path, #0 )
fn CFRelease( framesetter )
fn CFRelease( path )

lines = fn CTFrameGetLines( frame )
count = fn CFArrayGetCount( lines )
for i = 0 to count
range = fn CFRangeMake( i, 1 )
CTFrameGetLineOrigins( frame, range, @origins )
i++
next

//      draw the frame
CTFrameDraw( frame, context )
fn CFRelease( frame )

//      synchronize the context
CGContextSynchronize( context )

fn QDEndCGContext( port, @context )

RunApplicationEventLoop()