aboutsummaryrefslogtreecommitdiffhomepage
path: root/cocoa/PlatCocoa.mm
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa/PlatCocoa.mm')
-rw-r--r--cocoa/PlatCocoa.mm207
1 files changed, 60 insertions, 147 deletions
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm
index 6e8620b0b..3a70fcd93 100644
--- a/cocoa/PlatCocoa.mm
+++ b/cocoa/PlatCocoa.mm
@@ -156,23 +156,15 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b
int extraFontFlag)
{
// TODO: How should I handle the characterSet request?
- Release();
-
- QuartzTextStyle* style = new QuartzTextStyle();
- fid = style;
-
- // Find the font
- QuartzFont font(faceName, strlen(faceName));
-
- // We set Font, Size, Bold, Italic
- QuartzTextSize textSize(size);
- QuartzTextBold isBold(bold);
- QuartzTextItalic isItalic(italic);
-
- // Actually set the attributes
- QuartzTextStyleAttribute* attributes[] = { &font, &textSize, &isBold, &isItalic };
- style->setAttributes(attributes, sizeof(attributes) / sizeof(*attributes));
- style->setFontFeature(kLigaturesType, kCommonLigaturesOffSelector);
+ Release();
+
+ QuartzTextStyle* style = new QuartzTextStyle();
+ fid = style;
+
+ // Create the font with attributes
+ QuartzFont font(faceName, strlen(faceName), size, bold, italic);
+ CTFontRef fontRef = font.getFontID();
+ style->setFontRef(fontRef);
}
//--------------------------------------------------------------------------------------------------
@@ -774,78 +766,49 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const c
void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len,
ColourAllocated fore)
{
- textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
-
- // The Quartz RGB fill color influences the ATSUI color
- FillColour(fore);
-
- // Draw text vertically flipped as OS X uses a coordinate system where +Y is upwards.
- textLayout->draw(rc.left, ybase, true);
+ ColourDesired colour(fore.AsLong());
+ CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0,colour.GetGreen()/255.0,colour.GetBlue()/255.0,1.0);
+
+ QuartzTextStyle* style = reinterpret_cast<QuartzTextStyle*>(font_.GetID());
+ style->setCTStyleColor(color);
+
+ textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
+ textLayout->draw(rc.left, ybase);
}
//--------------------------------------------------------------------------------------------------
void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions)
{
- // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html
- // sample includes use of ATSUGetGlyphInfo which would be better for older
- // OSX systems. We should expand to using that on older systems as well.
- for (int i = 0; i < len; i++)
- positions [i] = 0;
-
- // We need the right X coords, so we have to append a char to get the left coord of thast extra char
- char* buf = (char*) malloc (len+1);
- if (!buf)
- return;
-
- memcpy (buf, s, len);
- buf [len] = '.';
-
- textLayout->setText (reinterpret_cast<const UInt8*>(buf), len+1, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
- ATSUGlyphInfoArray* theGlyphInfoArrayPtr;
- ByteCount theArraySize;
-
- // Get the GlyphInfoArray
- ATSUTextLayout layout = textLayout->getLayout();
- if ( noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, NULL))
- {
- theGlyphInfoArrayPtr = (ATSUGlyphInfoArray *) malloc (theArraySize + sizeof(ItemCount) + sizeof(ATSUTextLayout));
- if (theGlyphInfoArrayPtr)
- {
- if (noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, theGlyphInfoArrayPtr))
- {
- // do not count the first item, which is at the beginning of the line
- for ( UniCharCount unicodePosition = 1, i = 0; i < len && unicodePosition < theGlyphInfoArrayPtr->numGlyphs; unicodePosition ++ )
- {
- // The ideal position is the x coordinate of the glyph, relative to the beginning of the line
- int position = (int)( theGlyphInfoArrayPtr->glyphs[unicodePosition].idealX + 0.5 ); // These older APIs return float values
- unsigned char uch = s[i];
- positions[i++] = position;
-
- // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters,
- // as 1 unicode character can map to multiple UTF8 characters.
- // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF
- // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html
- if ( unicodeMode )
- {
- unsigned char mask = 0xc0;
- int count = 1;
- // Add one additonal byte for each extra high order one in the byte
- while ( uch >= mask && count < 8 )
- {
- positions[i++] = position;
- count ++;
- mask = mask >> 1 | 0x80; // add an additional one in the highest order position
- }
- }
- }
- }
-
- // Free the GlyphInfoArray
- free (theGlyphInfoArrayPtr);
- }
- }
- free (buf);
+ for (int i = 0; i < len; i++)
+ positions [i] = 0;
+ textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
+
+ CTLineRef mLine = textLayout->getCTLine();
+ assert(mLine != NULL);
+
+ CGFloat* secondaryOffset= 0;
+ int unicodeCharStart = 0;
+ for ( int i = 0; i < len+1; i ++ ){
+ unsigned char uch = s[i];
+ CFIndex charIndex = unicodeCharStart+1;
+ CGFloat advance = CTLineGetOffsetForStringIndex(mLine, charIndex, secondaryOffset);
+
+ if ( unicodeMode )
+ {
+ unsigned char mask = 0xc0;
+ int lcount = 1;
+ // Add one additonal byte for each extra high order one in the byte
+ while ( uch >= mask && lcount < 8 )
+ {
+ positions[i++] = (int)(advance+0.5);
+ lcount ++;
+ mask = mask >> 1 | 0x80; // add an additional one in the highest order position
+ }
+ }
+ positions[i] = (int)(advance+0.5);
+ unicodeCharStart++;
+ }
}
int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
@@ -853,19 +816,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
{
textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
- // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout?
- unsigned long actualNumberOfBounds = 0;
- ATSTrapezoid glyphBounds;
-
- // We get a single bound, since the text should only require one. If it requires more, there is an issue
- if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 )
- {
- Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" );
- return 0;
- }
-
- //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) );
- return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x );
+ return textLayout->MeasureStringWidth();
}
return 1;
}
@@ -876,32 +827,12 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) {
{
textLayout->setText (reinterpret_cast<const UInt8*>(str), 1, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
- // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout?
- unsigned long actualNumberOfBounds = 0;
- ATSTrapezoid glyphBounds;
-
- // We get a single bound, since the text should only require one. If it requires more, there is an issue
- if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 )
- {
- Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" );
- return 0;
- }
-
- return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x );
+ return textLayout->MeasureStringWidth();
}
else
return 1;
}
-// Three possible strategies for determining ascent and descent of font:
-// 1) Call ATSUGetGlyphBounds with string containing all letters, numbers and punctuation.
-// 2) Use the ascent and descent fields of the font.
-// 3) Call ATSUGetGlyphBounds with string as 1 but also including accented capitals.
-// Smallest values given by 1 and largest by 3 with 2 in between.
-// Techniques 1 and 2 sometimes chop off extreme portions of ascenders and
-// descenders but are mostly OK except for accented characters which are
-// rarely used in code.
-
// This string contains a good range of characters to test for size.
const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
@@ -910,16 +841,18 @@ int SurfaceImpl::Ascent(Font &font_) {
if (!font_.GetID())
return 1;
- ATSUTextMeasurement ascent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSUAscentTag );
- return Fix2Long( ascent );
+ float ascent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAscent();
+ return ascent + 0.5;
+
}
int SurfaceImpl::Descent(Font &font_) {
if (!font_.GetID())
return 1;
- ATSUTextMeasurement descent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSUDescentTag );
- return Fix2Long( descent );
+ float descent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getDescent();
+ return descent + 0.5;
+
}
int SurfaceImpl::InternalLeading(Font &) {
@@ -932,12 +865,15 @@ int SurfaceImpl::ExternalLeading(Font &font_) {
if (!font_.GetID())
return 1;
- ATSUTextMeasurement lineGap = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSULeadingTag );
- return Fix2Long( lineGap );
+ float leading = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getLeading();
+ return leading + 0.5;
+
}
int SurfaceImpl::Height(Font &font_) {
- return Ascent(font_) + Descent(font_);
+
+ int ht = Ascent(font_) + Descent(font_);
+ return ht;
}
int SurfaceImpl::AverageCharWidth(Font &font_) {
@@ -949,29 +885,6 @@ int SurfaceImpl::AverageCharWidth(Font &font_) {
int width = WidthText( font_, sizeString, sizeStringLength );
return (int) ((width / (float) sizeStringLength) + 0.5);
-
- /*
- ATSUStyle textStyle = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getATSUStyle();
- ATSUFontID fontID;
-
- ByteCount actualSize = 0;
- if ( ATSUGetAttribute( textStyle, kATSUFontTag, sizeof( fontID ), &fontID, &actualSize ) != noErr )
- {
- Platform::DebugDisplay( "ATSUGetAttribute failed" );
- return 1;
- }
-
- ATSFontMetrics metrics;
- memset( &metrics, 0, sizeof( metrics ) );
- if ( ATSFontGetHorizontalMetrics( fontID, kATSOptionFlagsDefault, &metrics ) != noErr )
- {
- Platform::DebugDisplay( "ATSFontGetHorizontalMetrics failed in AverageCharWidth" );
- return 1;
- }
-
- printf( "%f %f %f\n", metrics.avgAdvanceWidth * 32, metrics.ascent * 32, metrics.descent * 32 );
-
- return (int) (metrics.avgAdvanceWidth + 0.5);*/
}
int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) {