25 extern unsigned fl_utf8toUtf16(
const char* src,
unsigned srclen,
unsigned short* dst,
unsigned dstlen);
27 static CGAffineTransform
font_mx = { 1, 0, 0, -1, 0, 0 };
28 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 32 const int Fl_X::CoreText_threshold = 100500;
34 #define HAS_ATSU (!__LP64__) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11 45 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 47 CFStringRef str = CFStringCreateWithCString(
NULL,
name, kCFStringEncodingUTF8);
48 fontref = CTFontCreateWithName(str,
size,
NULL);
50 const UniChar A[2]={
'W',
'.'};
51 CTFontGetGlyphsForCharacters(fontref, A, glyph, 2);
54 CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, advances, 2);
55 w = advances[0].width;
56 if ( fabs(advances[0].width - advances[1].width) < 1E-2 ) {
59 CGFloat fsize =
size / ( w/floor(w + 0.5) );
60 fontref = CTFontCreateWithName(str, fsize,
NULL);
61 w = CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph,
NULL, 1);
64 ascent = (short)(CTFontGetAscent(fontref) + 0.5);
65 descent = (short)(CTFontGetDescent(fontref) + 0.5);
67 for (
unsigned i = 0; i <
sizeof(width)/
sizeof(
float*); i++) width[i] =
NULL;
69 static CFNumberRef zero_ref;
71 zero_ref = CFNumberCreate(
NULL, kCFNumberFloat32Type, &zero);
74 attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
76 &kCFTypeDictionaryKeyCallBacks,
77 &kCFTypeDictionaryValueCallBacks);
78 CFDictionarySetValue (
attributes, kCTKernAttributeName, zero_ref);
81 CFDictionarySetValue (
attributes, kCTFontAttributeName, fontref);
82 CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, CFSTR(
"Wj"),
attributes);
83 CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
85 CGFloat fascent, fdescent;
86 CTLineGetTypographicBounds(ctline, &fascent, &fdescent,
NULL);
88 ascent = (short)(fascent + 0.5);
89 descent = (short)(fdescent + 0.5);
98 descent = Size-ascent;
102 err = ATSUCreateTextLayout(&layout);
103 UniChar mTxt[2] = { 65, 0 };
104 err = ATSUSetTextPointerLocation(layout, mTxt, kATSUFromTextBeginning, 1, 1);
105 err = ATSUCreateStyle(&style);
106 err = ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
110 Fixed fsize = IntToFixed(Size);
112 ATSUFindFontFromName(
name, strlen(
name), kFontFullName, kFontMacintoshPlatform, kFontNoScriptCode, kFontEnglishLanguage, &fontID);
115 ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag };
116 ByteCount sBytes[] = {
sizeof(ATSUFontID),
sizeof(Fixed),
sizeof(CGAffineTransform) };
117 ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &
font_mx };
118 if (fontID != kATSUInvalidFontID) err = ATSUSetAttributes(style, 1, sTag, sBytes, sAttr);
119 err = ATSUSetAttributes(style, 2, sTag + 1, sBytes + 1, sAttr + 1);
121 ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics | kATSLineDisableAllLayoutOperations;
122 ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag };
123 ByteCount aBytes[] = {
sizeof(ATSLineLayoutOptions) };
124 ATSUAttributeValuePtr aAttr[] = { &llo };
125 err = ATSUSetLineControls (layout, kATSUFromTextBeginning, 1, aTag, aBytes, aAttr);
127 Fixed bBefore, bAfter, bAscent, bDescent;
128 err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent);
132 float fa = -FixedToFloat(bAscent),
fd = -FixedToFloat(bDescent);
133 if (fa>0.0
f &&
fd>0.0
f) {
138 int w = FixedToInt(bAfter);
140 q_width = FixedToInt(bAfter);
142 # define ENABLE_TRANSIENT_FONTS 1 144 # ifdef ENABLE_TRANSIENT_FONTS 147 ATSUSetTransientFontMatching (layout,
true);
150 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 171 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 174 for (
unsigned i = 0; i <
sizeof(width)/
sizeof(
float*); i++) {
175 if (width[i])
free(width[i]);
183 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 188 {
"Arial-BoldItalicMT"},
192 {
"Courier-BoldOblique"},
193 {
"TimesNewRomanPSMT"},
194 {
"TimesNewRomanPS-BoldMT"},
195 {
"TimesNewRomanPS-ItalicMT"},
196 {
"TimesNewRomanPS-BoldItalicMT"},
208 {
"Arial Bold Italic"},
211 {
"Courier New Italic"},
212 {
"Courier New Bold Italic"},
214 {
"Times New Roman Bold"},
215 {
"Times New Roman Italic"},
216 {
"Times New Roman Bold Italic"},
243 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 256 if (
f->size == size)
return f;
272 this->font_descriptor(
find(fnum, size) );
275 int Fl_Quartz_Graphics_Driver::height() {
278 return fl_fontsize->ascent + fl_fontsize->descent;
281 int Fl_Quartz_Graphics_Driver::descent() {
284 return fl_fontsize->descent+1;
287 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 291 CTFontRef font2 = fl_fontsize->fontref;
292 bool must_release =
false;
294 bool b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2);
297 CFStringRef str = CFStringCreateWithCharactersNoCopy(
NULL, txt, 2, kCFAllocatorNull);
299 font2 = CTFontCreateForString(font2, str, CFRangeMake(0,2));
302 b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2);
304 if (
b) CTFontGetAdvancesForGlyphs(font2, kCTFontHorizontalOrientation, glyphs, &a, 1);
305 else a.width = fl_fontsize->q_width;
306 if(must_release) CFRelease(font2);
313 CFDictionarySetValue(
attributes, kCTFontAttributeName, fl_fontsize->fontref);
314 CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16,
attributes);
315 CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
317 retval = CTLineGetOffsetForStringIndex(ctline, 2,
NULL);
324 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 329 for (i = 0; i < n; i++) {
331 if (
uni >= 0xD800 &&
uni <= 0xDBFF) {
336 if (i+1 < n && txt[i+1] >= 0xFE00 && txt[i+1] <= 0xFE0F) {
337 CFStringRef substr = CFStringCreateWithCharacters(
NULL, txt + i, 2);
343 const int block = 0x10000 / (
sizeof(fl_fontsize->width)/
sizeof(
float*));
345 unsigned int r =
uni >> 7;
346 if (!fl_fontsize->width[r]) {
349 fl_fontsize->width[r] = (
float*)
malloc(
sizeof(
float) * block);
350 UniChar ii = r * block;
353 for (
int j = 0; j < block; j++) {
355 bool b = CTFontGetGlyphsForCharacters(fl_fontsize->fontref, &ii, &glyph, 1);
357 CTFontGetAdvancesForGlyphs(fl_fontsize->fontref, kCTFontHorizontalOrientation, &glyph, &advance_size, 1);
359 advance_size.width = -1e9;
361 fl_fontsize->width[r][j] = advance_size.width;
366 double wdt = fl_fontsize->width[r][
uni & (block-1)];
370 CTFontRef font2 = fl_fontsize->fontref;
371 bool must_release =
false;
372 bool b = CTFontGetGlyphsForCharacters(font2, &
uni, &glyph, 1);
374 CFStringRef str = CFStringCreateWithCharactersNoCopy(
NULL, &
uni, 1, kCFAllocatorNull);
376 font2 = CTFontCreateForString(font2, str, CFRangeMake(0,1));
379 b = CTFontGetGlyphsForCharacters(font2, &
uni, &glyph, 1);
381 if (
b) CTFontGetAdvancesForGlyphs(font2, kCTFontHorizontalOrientation, &glyph, &advance_size, 1);
382 else advance_size.width = 0.;
384 wdt = fl_fontsize->width[r][
uni & (block-1)] = advance_size.width;
385 if (must_release) CFRelease(font2);
394 Fixed bBefore, bAfter, bAscent, bDescent;
395 ATSUTextLayout layout;
397 ATSUAttributeTag iTag;
398 ATSUAttributeValuePtr iValuePtr;
402 layout = fl_fontsize->layout;
405 iTag = kATSUCGContextTag;
407 ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
409 err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n);
410 err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, n, &bBefore, &bAfter, &bAscent, &bDescent);
412 int len = FixedToInt(bAfter);
415 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 421 double Fl_Quartz_Graphics_Driver::width(
const char* txt,
int n) {
428 double Fl_Quartz_Graphics_Driver::width(
unsigned int wc) {
446 void Fl_Quartz_Graphics_Driver::text_extents(
const char *str8,
int n,
int &
dx,
int &
dy,
int &w,
int &h) {
450 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 452 CFStringRef str16 = CFStringCreateWithCharactersNoCopy(
NULL, txt, n, kCFAllocatorNull);
453 CFDictionarySetValue (
attributes, kCTFontAttributeName, fl_fontsize->fontref);
454 CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16,
attributes);
456 CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
458 CGContextSetTextPosition(
fl_gc, 0, 0);
459 CGContextSetShouldAntialias(
fl_gc,
true);
460 CGRect
rect = CTLineGetImageBounds(ctline,
fl_gc);
461 CGContextSetShouldAntialias(
fl_gc,
false);
463 dx = floor(
rect.origin.x + 0.5);
464 dy = floor(-
rect.origin.y -
rect.size.height + 0.5);
465 w =
rect.size.width + 0.5;
466 h =
rect.size.height + 0.5;
472 ATSUTextLayout layout;
474 ATSUAttributeTag iTag;
475 ATSUAttributeValuePtr iValuePtr;
479 layout = fl_fontsize->layout;
482 iTag = kATSUCGContextTag;
484 ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
486 err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n);
488 err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, n, 0, 0, &bbox);
489 w = bbox.right - bbox.left;
490 h = bbox.bottom - bbox.top;
495 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 501 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 506 CGFloat components[4] = {r/255.0f, g/255.0f,
b/255.0f, 1.};
507 static CGColorSpaceRef cspace =
NULL;
508 if (cspace ==
NULL) {
509 cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
511 return CGColorCreate(cspace, components);
518 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 520 CFMutableStringRef str16 = CFStringCreateMutableWithExternalCharactersNoCopy(
NULL, uniStr, n, n, kCFAllocatorNull);
521 if (str16 ==
NULL)
return;
524 CFDictionarySetValue (
attributes, kCTForegroundColorAttributeName,
color);
525 CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16,
attributes);
528 CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
531 CGContextSetTextPosition(
fl_gc,
x,
y);
532 CGContextSetShouldAntialias(
fl_gc,
true);
533 CTLineDraw(ctline,
fl_gc);
534 CGContextSetShouldAntialias(
fl_gc,
false);
544 ATSUAttributeTag iTag = kATSUCGContextTag;
545 ATSUAttributeValuePtr iValuePtr=&
fl_gc;
546 ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
548 err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
549 CGContextSetShouldAntialias(
fl_gc,
true);
550 err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(
x), FloatToFixed(
y));
551 CGContextSetShouldAntialias(
fl_gc,
false);
553 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 572 CGContextTranslateCTM(
fl_gc,
x,
y);
573 CGContextRotateCTM(
fl_gc, - angle*(
M_PI/180) );
578 void Fl_Quartz_Graphics_Driver::rtl_draw(
const char* c,
int n,
int x,
int y) {
580 text_extents(c, n,
dx,
dy, w, h);