diff options
author | nyamatongwe <unknown> | 2011-05-26 09:14:45 +1000 |
---|---|---|
committer | nyamatongwe <unknown> | 2011-05-26 09:14:45 +1000 |
commit | 82266f54fef82a3481bf9ec091d85c2c202df5ec (patch) | |
tree | 9478fbba514910e3648d97940ccd3771c9b64509 /cocoa/QuartzTextLayout.h | |
parent | 1ef9f42a4e839bf12d454e8560e7d697e1e3b0c9 (diff) | |
download | scintilla-mirror-82266f54fef82a3481bf9ec091d85c2c202df5ec.tar.gz |
Convert text drawing and measurement to use Core Text API.
Contributed by Elizabeth Irizarry of Adobe with some modifications
by Neil Hodgson.
Diffstat (limited to 'cocoa/QuartzTextLayout.h')
-rw-r--r-- | cocoa/QuartzTextLayout.h | 150 |
1 files changed, 56 insertions, 94 deletions
diff --git a/cocoa/QuartzTextLayout.h b/cocoa/QuartzTextLayout.h index 64bf492d4..033ac98fb 100644 --- a/cocoa/QuartzTextLayout.h +++ b/cocoa/QuartzTextLayout.h @@ -15,127 +15,89 @@ #include "QuartzTextStyle.h" + class QuartzTextLayout { public: /** Create a text layout for drawing on the specified context. */ - QuartzTextLayout( CGContextRef context ) : layout( NULL ), unicode_string( NULL ), unicode_length( 0 ) + QuartzTextLayout( CGContextRef context ) { - OSStatus err = ATSUCreateTextLayout( &layout ); - if (0 != err) - layout = NULL; - + mString = NULL; + mLine = NULL; setContext(context); - - ATSUAttributeTag tag = kATSULineLayoutOptionsTag; - ByteCount size = sizeof( ATSLineLayoutOptions ); - ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics; //| kATSLineFractDisable | kATSLineUseQDRendering - ATSUAttributeValuePtr valuePtr = &rendering; - err = ATSUSetLayoutControls( layout, 1, &tag, &size, &valuePtr ); } ~QuartzTextLayout() { - if (NULL != layout) - ATSUDisposeTextLayout( layout ); - layout = NULL; - - if ( unicode_string != NULL ) - { - delete[] unicode_string; - unicode_string = NULL; - unicode_length = 0; - } - } - - /** Assign a string to the text layout object. */ - // TODO: Create a UTF8 version - // TODO: Optimise the ASCII version by not copying so much - OSStatus setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding ) - { - if (NULL == layout) - return -1; - CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); - if (!str) - return -1; - - unicode_length = CFStringGetLength( str ); - if (unicode_string) - delete[] unicode_string; - unicode_string = new UniChar[ unicode_length ]; - CFStringGetCharacters( str, CFRangeMake( 0, unicode_length ), unicode_string ); - - CFRelease( str ); - str = NULL; - - OSStatus err; - err = ATSUSetTextPointerLocation( layout, unicode_string, kATSUFromTextBeginning, kATSUToTextEnd, unicode_length ); - if( err != noErr ) return err; - - // Turn on the default font fallbacks - return ATSUSetTransientFontMatching( layout, true ); + if ( mString != NULL ) + { + CFRelease(mString); + mString = NULL; + } + if ( mLine != NULL ) + { + CFRelease(mLine); + mLine = NULL; + } } inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) { - this->setText( buffer, byteLength, kCFStringEncodingUTF8 ); - ATSUSetRunStyle( layout, r.getATSUStyle(), 0, unicode_length ); - } - - /** Apply the specified text style on the entire range of text. */ - void setStyle( const QuartzTextStyle& style ) - { - ATSUSetRunStyle( layout, style.getATSUStyle(), kATSUFromTextBeginning, kATSUToTextEnd ); + CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, kCFStringEncodingUTF8, false ); + if (!str) + return; + + CFMutableDictionaryRef stringAttribs = r.getCTStyle(); + + if (mString != NULL) + CFRelease(mString); + mString = ::CFAttributedStringCreate(NULL, str, stringAttribs); + + if (mLine != NULL) + CFRelease(mLine); + mLine = ::CTLineCreateWithAttributedString(mString); + + CFRelease( str ); } - /** Draw the text layout into the current CGContext at the specified position, flipping the CGContext's Y axis if required. + /** Draw the text layout into the current CGContext at the specified position. * @param x The x axis position to draw the baseline in the current CGContext. - * @param y The y axis position to draw the baseline in the current CGContext. - * @param flipTextYAxis If true, the CGContext's Y axis will be flipped before drawing the text, and restored afterwards. Use this when drawing in an HIView's CGContext, where the origin is the top left corner. */ - void draw( float x, float y, bool flipTextYAxis = false ) + * @param y The y axis position to draw the baseline in the current CGContext. */ + void draw( float x, float y ) { - if (NULL == layout || 0 == unicode_length) - return; - if ( flipTextYAxis ) - { - CGContextSaveGState( gc ); - CGContextScaleCTM( gc, 1.0, -1.0 ); - y = -y; - } - - OSStatus err; - err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) ); - - if ( flipTextYAxis ) CGContextRestoreGState( gc ); + if (mLine == NULL) + return; + + ::CGContextSetTextMatrix(gc, CGAffineTransformMakeScale(1.0, -1.0)); + + // Set the text drawing position. + ::CGContextSetTextPosition(gc, x, y); + + // And finally, draw! + ::CTLineDraw(mLine, gc); } - - /** Sets a single text layout control on the ATSUTextLayout object. - * @param tag The control to set. - * @param size The size of the parameter pointed to by value. - * @param value A pointer to the new value for the control. - */ - void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) - { - ATSUSetLayoutControls( layout, 1, &tag, &size, &value ); + + float MeasureStringWidth() + { + if (mLine == NULL) + return 0.0f; + + return ::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL); + } + + CTLineRef getCTLine() { + return mLine; } - - ATSUTextLayout getLayout() { - return layout; - } - - inline CFIndex getLength() const { return unicode_length; } + inline void setContext (CGContextRef context) { gc = context; - if (NULL != layout) - setControl( kATSUCGContextTag, sizeof( gc ), &gc ); } private: - ATSUTextLayout layout; - UniChar* unicode_string; - int unicode_length; CGContextRef gc; + CFAttributedStringRef mString; + CTLineRef mLine; }; #endif |