aboutsummaryrefslogtreecommitdiffhomepage
path: root/cocoa/QuartzTextLayout.h
diff options
context:
space:
mode:
authornyamatongwe <unknown>2011-05-26 09:14:45 +1000
committernyamatongwe <unknown>2011-05-26 09:14:45 +1000
commit82266f54fef82a3481bf9ec091d85c2c202df5ec (patch)
tree9478fbba514910e3648d97940ccd3771c9b64509 /cocoa/QuartzTextLayout.h
parent1ef9f42a4e839bf12d454e8560e7d697e1e3b0c9 (diff)
downloadscintilla-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.h150
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