aboutsummaryrefslogtreecommitdiffstats
path: root/src/macfont.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/macfont.m')
-rw-r--r--src/macfont.m3270
1 files changed, 1582 insertions, 1688 deletions
diff --git a/src/macfont.m b/src/macfont.m
index 0d702873220..366d087f8c2 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -36,13 +36,11 @@ Original author: YAMAMOTO Mitsuharu
36#include "macfont.h" 36#include "macfont.h"
37#include "macuvs.h" 37#include "macuvs.h"
38 38
39#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
40
41#include <libkern/OSByteOrder.h> 39#include <libkern/OSByteOrder.h>
42 40
43static struct font_driver macfont_driver; 41static struct font_driver macfont_driver;
44 42
45/* Core Text, for Mac OS X 10.5 and later. */ 43/* Core Text, for Mac OS X. */
46static Lisp_Object Qmac_ct; 44static Lisp_Object Qmac_ct;
47 45
48static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph); 46static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph);
@@ -50,25 +48,25 @@ static CGRect mac_ctfont_get_bounding_rect_for_glyph (CTFontRef, CGGlyph);
50static CFArrayRef mac_ctfont_create_available_families (void); 48static CFArrayRef mac_ctfont_create_available_families (void);
51static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef); 49static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef);
52static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef, 50static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef,
53 CTFontRef); 51 CTFontRef);
54static CFComparisonResult mac_font_family_compare (const void *, 52static CFComparisonResult mac_font_family_compare (const void *,
55 const void *, void *); 53 const void *, void *);
56static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef, 54static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef,
57 CFArrayRef); 55 CFArrayRef);
58static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef); 56static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef);
59static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef, 57static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef,
60 struct mac_glyph_layout *, CFIndex); 58 struct mac_glyph_layout *, CFIndex);
61static CFArrayRef 59static CFArrayRef
62mac_font_copy_default_descriptors_for_language (CFStringRef language); 60mac_font_copy_default_descriptors_for_language (CFStringRef language);
63 61
64static CFStringRef 62static CFStringRef
65mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, 63mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
66 CFArrayRef languages); 64 CFArrayRef languages);
67 65
68#if USE_CT_GLYPH_INFO 66#if USE_CT_GLYPH_INFO
69static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef, 67static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef,
70 CTCharacterCollection, 68 CTCharacterCollection,
71 CGFontIndex); 69 CGFontIndex);
72#endif 70#endif
73 71
74/* The font property key specifying the font design destination. The 72/* The font property key specifying the font design destination. The
@@ -129,26 +127,26 @@ static const CGAffineTransform synthetic_italic_atfm = {1, 0, 0.25, 1, 0, 0};
129static const CGFloat synthetic_bold_factor = 0.024; 127static const CGFloat synthetic_bold_factor = 0.024;
130 128
131static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef, 129static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef,
132 FontSymbolicTraits *); 130 FontSymbolicTraits *);
133static void macfont_store_descriptor_attributes (FontDescriptorRef, 131static void macfont_store_descriptor_attributes (FontDescriptorRef,
134 Lisp_Object); 132 Lisp_Object);
135static Lisp_Object macfont_descriptor_entity (FontDescriptorRef, 133static Lisp_Object macfont_descriptor_entity (FontDescriptorRef,
136 Lisp_Object, 134 Lisp_Object,
137 FontSymbolicTraits); 135 FontSymbolicTraits);
138static CFStringRef macfont_create_family_with_symbol (Lisp_Object); 136static CFStringRef macfont_create_family_with_symbol (Lisp_Object);
139static int macfont_glyph_extents (struct font *, CGGlyph, 137static int macfont_glyph_extents (struct font *, CGGlyph,
140 struct font_metrics *, CGFloat *, int); 138 struct font_metrics *, CGFloat *, int);
141static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object); 139static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object);
142static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef, 140static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef,
143 CFCharacterSetRef, 141 CFCharacterSetRef,
144 Lisp_Object, 142 Lisp_Object,
145 CFArrayRef); 143 CFArrayRef);
146static CFIndex macfont_closest_traits_index (CFArrayRef, 144static Boolean macfont_closest_traits_index_p (CFArrayRef, FontSymbolicTraits,
147 FontSymbolicTraits); 145 CFIndex);
148static CFDataRef mac_font_copy_uvs_table (FontRef); 146static CFDataRef mac_font_copy_uvs_table (FontRef);
149static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char, 147static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char,
150 const UTF32Char [], 148 const UTF32Char [],
151 CGGlyph [], CFIndex); 149 CGGlyph [], CFIndex);
152 150
153/* From CFData to a lisp string. Always returns a unibyte string. */ 151/* From CFData to a lisp string. Always returns a unibyte string. */
154 152
@@ -180,15 +178,15 @@ cfstring_to_lisp_nodecode (CFStringRef string)
180 CFIndex i, length = CFStringGetLength (string); 178 CFIndex i, length = CFStringGetLength (string);
181 179
182 for (i = 0; i < length; i++) 180 for (i = 0; i < length; i++)
183 if (CFStringGetCharacterAtIndex (string, i) == 0) 181 if (CFStringGetCharacterAtIndex (string, i) == 0)
184 break; 182 break;
185 183
186 if (i == length) 184 if (i == length)
187 return make_unibyte_string (s, strlen (s)); 185 return make_unibyte_string (s, strlen (s));
188 } 186 }
189 187
190 data = CFStringCreateExternalRepresentation (NULL, string, 188 data = CFStringCreateExternalRepresentation (NULL, string,
191 kCFStringEncodingUTF8, '?'); 189 kCFStringEncodingUTF8, '?');
192 if (data) 190 if (data)
193 { 191 {
194 result = cfdata_to_lisp (data); 192 result = cfdata_to_lisp (data);
@@ -206,12 +204,12 @@ static CFStringRef
206cfstring_create_with_string_noencode (Lisp_Object s) 204cfstring_create_with_string_noencode (Lisp_Object s)
207{ 205{
208 CFStringRef string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s), 206 CFStringRef string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
209 kCFStringEncodingUTF8, false); 207 kCFStringEncodingUTF8, false);
210 208
211 if (string == NULL) 209 if (string == NULL)
212 /* Failed to interpret as UTF 8. Fall back on Mac Roman. */ 210 /* Failed to interpret as UTF 8. Fall back on Mac Roman. */
213 string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s), 211 string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
214 kCFStringEncodingMacRoman, false); 212 kCFStringEncodingMacRoman, false);
215 213
216 return string; 214 return string;
217} 215}
@@ -226,7 +224,7 @@ mac_screen_font_get_advance_width_for_glyph (ScreenFontRef font, CGGlyph glyph)
226 224
227static CGGlyph 225static CGGlyph
228mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection, 226mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
229 CGFontIndex cid) 227 CGFontIndex cid)
230{ 228{
231#if USE_CT_GLYPH_INFO 229#if USE_CT_GLYPH_INFO
232 return mac_ctfont_get_glyph_for_cid ((CTFontRef) font, collection, cid); 230 return mac_ctfont_get_glyph_for_cid ((CTFontRef) font, collection, cid);
@@ -237,17 +235,17 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
237 unichar characters[] = {0xfffd}; 235 unichar characters[] = {0xfffd};
238 NSString *string = 236 NSString *string =
239 [NSString stringWithCharacters:characters 237 [NSString stringWithCharacters:characters
240 length:ARRAYELTS (characters)]; 238 length:ARRAYELTS (characters)];
241 NSGlyphInfo *glyphInfo = 239 NSGlyphInfo *glyphInfo =
242 [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid 240 [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid
243 collection:collection 241 collection:collection
244 baseString:string]; 242 baseString:string];
245 NSDictionary *attributes = 243 NSDictionary *attributes =
246 [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName, 244 [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName,
247 glyphInfo,NSGlyphInfoAttributeName,nil]; 245 glyphInfo,NSGlyphInfoAttributeName,nil];
248 NSTextStorage *textStorage = 246 NSTextStorage *textStorage =
249 [[NSTextStorage alloc] initWithString:string 247 [[NSTextStorage alloc] initWithString:string
250 attributes:attributes]; 248 attributes:attributes];
251 NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 249 NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
252 NSTextContainer *textContainer = [[NSTextContainer alloc] init]; 250 NSTextContainer *textContainer = [[NSTextContainer alloc] init];
253 NSFont *fontInTextStorage; 251 NSFont *fontInTextStorage;
@@ -261,14 +259,14 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
261 (void) [layoutManager glyphRangeForTextContainer:textContainer]; 259 (void) [layoutManager glyphRangeForTextContainer:textContainer];
262 260
263 fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0 261 fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0
264 effectiveRange:NULL]; 262 effectiveRange:NULL];
265 if (fontInTextStorage == nsFont 263 if (fontInTextStorage == nsFont
266 || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]]) 264 || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]])
267 { 265 {
268 NSGlyph glyph = [layoutManager glyphAtIndex:0]; 266 NSGlyph glyph = [layoutManager glyphAtIndex:0];
269 267
270 if (glyph < [nsFont numberOfGlyphs]) 268 if (glyph < [nsFont numberOfGlyphs])
271 result = glyph; 269 result = glyph;
272 } 270 }
273 271
274 [textStorage release]; 272 [textStorage release];
@@ -292,7 +290,7 @@ mac_screen_font_create_with_name (CFStringRef name, CGFloat size)
292 290
293static Boolean 291static Boolean
294mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent, 292mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
295 CGFloat *descent, CGFloat *leading) 293 CGFloat *descent, CGFloat *leading)
296{ 294{
297 NSFont *nsFont = [(NSFont *)font printerFont]; 295 NSFont *nsFont = [(NSFont *)font printerFont];
298 NSTextStorage *textStorage; 296 NSTextStorage *textStorage;
@@ -323,7 +321,7 @@ mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
323 } 321 }
324 322
325 usedRect = [layoutManager lineFragmentUsedRectForGlyphAtIndex:0 323 usedRect = [layoutManager lineFragmentUsedRectForGlyphAtIndex:0
326 effectiveRange:NULL]; 324 effectiveRange:NULL];
327 spaceLocation = [layoutManager locationForGlyphAtIndex:0]; 325 spaceLocation = [layoutManager locationForGlyphAtIndex:0];
328 [textStorage release]; 326 [textStorage release];
329 327
@@ -342,8 +340,8 @@ mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
342 340
343static CFIndex 341static CFIndex
344mac_font_shape_1 (NSFont *font, NSString *string, 342mac_font_shape_1 (NSFont *font, NSString *string,
345 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len, 343 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len,
346 BOOL screen_font_p) 344 BOOL screen_font_p)
347{ 345{
348 NSUInteger i; 346 NSUInteger i;
349 CFIndex result = 0; 347 CFIndex result = 0;
@@ -360,7 +358,7 @@ mac_font_shape_1 (NSFont *font, NSString *string,
360 358
361 /* Append a trailing space to measure baseline position. */ 359 /* Append a trailing space to measure baseline position. */
362 [textStorage appendAttributedString:([[[NSAttributedString alloc] 360 [textStorage appendAttributedString:([[[NSAttributedString alloc]
363 initWithString:@" "] autorelease])]; 361 initWithString:@" "] autorelease])];
364 [textStorage setFont:font]; 362 [textStorage setFont:font];
365 [textContainer setLineFragmentPadding:0]; 363 [textContainer setLineFragmentPadding:0];
366 [layoutManager setUsesScreenFonts:screen_font_p]; 364 [layoutManager setUsesScreenFonts:screen_font_p];
@@ -396,13 +394,13 @@ mac_font_shape_1 (NSFont *font, NSString *string,
396 { 394 {
397 NSRange range; 395 NSRange range;
398 NSFont *fontInTextStorage = 396 NSFont *fontInTextStorage =
399 [textStorage attribute:NSFontAttributeName atIndex:i 397 [textStorage attribute:NSFontAttributeName atIndex:i
400 longestEffectiveRange:&range 398 longestEffectiveRange:&range
401 inRange:(NSMakeRange (0, stringLength))]; 399 inRange:(NSMakeRange (0, stringLength))];
402 400
403 if (!(fontInTextStorage == font 401 if (!(fontInTextStorage == font
404 || [[fontInTextStorage fontName] isEqualToString:[font fontName]])) 402 || [[fontInTextStorage fontName] isEqualToString:[font fontName]]))
405 break; 403 break;
406 i = NSMaxRange (range); 404 i = NSMaxRange (range);
407 } 405 }
408 if (i < stringLength) 406 if (i < stringLength)
@@ -414,12 +412,12 @@ mac_font_shape_1 (NSFont *font, NSString *string,
414 NSRange range = NSMakeRange (0, stringLength); 412 NSRange range = NSMakeRange (0, stringLength);
415 413
416 range = [layoutManager glyphRangeForCharacterRange:range 414 range = [layoutManager glyphRangeForCharacterRange:range
417 actualCharacterRange:NULL]; 415 actualCharacterRange:NULL];
418 numberOfGlyphs = NSMaxRange (range); 416 numberOfGlyphs = NSMaxRange (range);
419 used = numberOfGlyphs; 417 used = numberOfGlyphs;
420 for (i = 0; i < numberOfGlyphs; i++) 418 for (i = 0; i < numberOfGlyphs; i++)
421 if ([layoutManager notShownAttributeForGlyphAtIndex:i]) 419 if ([layoutManager notShownAttributeForGlyphAtIndex:i])
422 used--; 420 used--;
423 } 421 }
424 422
425 if (0 < used && used <= glyph_len) 423 if (0 < used && used <= glyph_len)
@@ -432,186 +430,186 @@ mac_font_shape_1 (NSFont *font, NSString *string,
432 430
433 glyphIndex = 0; 431 glyphIndex = 0;
434 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 432 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
435 glyphIndex++; 433 glyphIndex++;
436 434
437 /* For now we assume the direction is not changed within the 435 /* For now we assume the direction is not changed within the
438 string. */ 436 string. */
439 [layoutManager getGlyphsInRange:(NSMakeRange (glyphIndex, 1)) 437 [layoutManager getGlyphsInRange:(NSMakeRange (glyphIndex, 1))
440 glyphs:NULL characterIndexes:NULL 438 glyphs:NULL characterIndexes:NULL
441 glyphInscriptions:NULL elasticBits:NULL 439 glyphInscriptions:NULL elasticBits:NULL
442 bidiLevels:&bidiLevel]; 440 bidiLevels:&bidiLevel];
443 if (bidiLevel & 1) 441 if (bidiLevel & 1)
444 permutation = xmalloc (sizeof (NSUInteger) * used); 442 permutation = xmalloc (sizeof (NSUInteger) * used);
445 else 443 else
446 permutation = NULL; 444 permutation = NULL;
447 445
448#define RIGHT_TO_LEFT_P permutation 446#define RIGHT_TO_LEFT_P permutation
449 447
450 /* Fill the `comp_range' member of struct mac_glyph_layout, and 448 /* Fill the `comp_range' member of struct mac_glyph_layout, and
451 setup a permutation for right-to-left text. */ 449 setup a permutation for right-to-left text. */
452 compRange = NSMakeRange (0, 0); 450 compRange = NSMakeRange (0, 0);
453 for (range = NSMakeRange (0, 0); NSMaxRange (range) < used; 451 for (range = NSMakeRange (0, 0); NSMaxRange (range) < used;
454 range.length++) 452 range.length++)
455 { 453 {
456 struct mac_glyph_layout *gl = glyph_layouts + NSMaxRange (range); 454 struct mac_glyph_layout *gl = glyph_layouts + NSMaxRange (range);
457 NSUInteger characterIndex = 455 NSUInteger characterIndex =
458 [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; 456 [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
459 457
460 gl->string_index = characterIndex; 458 gl->string_index = characterIndex;
461 459
462 if (characterIndex >= NSMaxRange (compRange)) 460 if (characterIndex >= NSMaxRange (compRange))
463 { 461 {
464 compRange.location = NSMaxRange (compRange); 462 compRange.location = NSMaxRange (compRange);
465 do 463 do
466 { 464 {
467 NSRange characterRange = 465 NSRange characterRange =
468 [string 466 [string
469 rangeOfComposedCharacterSequenceAtIndex:characterIndex]; 467 rangeOfComposedCharacterSequenceAtIndex:characterIndex];
470 468
471 compRange.length = 469 compRange.length =
472 NSMaxRange (characterRange) - compRange.location; 470 NSMaxRange (characterRange) - compRange.location;
473 [layoutManager glyphRangeForCharacterRange:compRange 471 [layoutManager glyphRangeForCharacterRange:compRange
474 actualCharacterRange:&characterRange]; 472 actualCharacterRange:&characterRange];
475 characterIndex = NSMaxRange (characterRange) - 1; 473 characterIndex = NSMaxRange (characterRange) - 1;
476 } 474 }
477 while (characterIndex >= NSMaxRange (compRange)); 475 while (characterIndex >= NSMaxRange (compRange));
478 476
479 if (RIGHT_TO_LEFT_P) 477 if (RIGHT_TO_LEFT_P)
480 for (i = 0; i < range.length; i++) 478 for (i = 0; i < range.length; i++)
481 permutation[range.location + i] = NSMaxRange (range) - i - 1; 479 permutation[range.location + i] = NSMaxRange (range) - i - 1;
482 480
483 range = NSMakeRange (NSMaxRange (range), 0); 481 range = NSMakeRange (NSMaxRange (range), 0);
484 } 482 }
485 483
486 gl->comp_range.location = compRange.location; 484 gl->comp_range.location = compRange.location;
487 gl->comp_range.length = compRange.length; 485 gl->comp_range.length = compRange.length;
488 486
489 while (++glyphIndex < numberOfGlyphs) 487 while (++glyphIndex < numberOfGlyphs)
490 if (![layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 488 if (![layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
491 break; 489 break;
492 } 490 }
493 if (RIGHT_TO_LEFT_P) 491 if (RIGHT_TO_LEFT_P)
494 for (i = 0; i < range.length; i++) 492 for (i = 0; i < range.length; i++)
495 permutation[range.location + i] = NSMaxRange (range) - i - 1; 493 permutation[range.location + i] = NSMaxRange (range) - i - 1;
496 494
497 /* Then fill the remaining members. */ 495 /* Then fill the remaining members. */
498 glyphIndex = prevGlyphIndex = 0; 496 glyphIndex = prevGlyphIndex = 0;
499 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 497 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
500 glyphIndex++; 498 glyphIndex++;
501 499
502 if (!RIGHT_TO_LEFT_P) 500 if (!RIGHT_TO_LEFT_P)
503 totalAdvance = 0; 501 totalAdvance = 0;
504 else 502 else
505 { 503 {
506 NSUInteger nrects; 504 NSUInteger nrects;
507 NSRect *glyphRects = 505 NSRect *glyphRects =
508 [layoutManager 506 [layoutManager
509 rectArrayForGlyphRange:(NSMakeRange (0, numberOfGlyphs)) 507 rectArrayForGlyphRange:(NSMakeRange (0, numberOfGlyphs))
510 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 508 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
511 inTextContainer:textContainer rectCount:&nrects]; 509 inTextContainer:textContainer rectCount:&nrects];
512 510
513 totalAdvance = NSMaxX (glyphRects[0]); 511 totalAdvance = NSMaxX (glyphRects[0]);
514 } 512 }
515 513
516 for (i = 0; i < used; i++) 514 for (i = 0; i < used; i++)
517 { 515 {
518 struct mac_glyph_layout *gl; 516 struct mac_glyph_layout *gl;
519 NSPoint location; 517 NSPoint location;
520 NSUInteger nextGlyphIndex; 518 NSUInteger nextGlyphIndex;
521 NSRange glyphRange; 519 NSRange glyphRange;
522 NSRect *glyphRects; 520 NSRect *glyphRects;
523 NSUInteger nrects; 521 NSUInteger nrects;
524 522
525 if (!RIGHT_TO_LEFT_P) 523 if (!RIGHT_TO_LEFT_P)
526 gl = glyph_layouts + i; 524 gl = glyph_layouts + i;
527 else 525 else
528 { 526 {
529 NSUInteger dest = permutation[i]; 527 NSUInteger dest = permutation[i];
530 528
531 gl = glyph_layouts + dest; 529 gl = glyph_layouts + dest;
532 if (i < dest) 530 if (i < dest)
533 { 531 {
534 CFIndex tmp = gl->string_index; 532 CFIndex tmp = gl->string_index;
535 533
536 gl->string_index = glyph_layouts[i].string_index; 534 gl->string_index = glyph_layouts[i].string_index;
537 glyph_layouts[i].string_index = tmp; 535 glyph_layouts[i].string_index = tmp;
538 } 536 }
539 } 537 }
540 gl->glyph_id = [layoutManager glyphAtIndex:glyphIndex]; 538 gl->glyph_id = [layoutManager glyphAtIndex:glyphIndex];
541 539
542 location = [layoutManager locationForGlyphAtIndex:glyphIndex]; 540 location = [layoutManager locationForGlyphAtIndex:glyphIndex];
543 gl->baseline_delta = spaceLocation.y - location.y; 541 gl->baseline_delta = spaceLocation.y - location.y;
544 542
545 for (nextGlyphIndex = glyphIndex + 1; nextGlyphIndex < numberOfGlyphs; 543 for (nextGlyphIndex = glyphIndex + 1; nextGlyphIndex < numberOfGlyphs;
546 nextGlyphIndex++) 544 nextGlyphIndex++)
547 if (![layoutManager 545 if (![layoutManager
548 notShownAttributeForGlyphAtIndex:nextGlyphIndex]) 546 notShownAttributeForGlyphAtIndex:nextGlyphIndex])
549 break; 547 break;
550 548
551 if (!RIGHT_TO_LEFT_P) 549 if (!RIGHT_TO_LEFT_P)
552 { 550 {
553 CGFloat maxX; 551 CGFloat maxX;
554 552
555 if (prevGlyphIndex == 0) 553 if (prevGlyphIndex == 0)
556 glyphRange = NSMakeRange (0, nextGlyphIndex); 554 glyphRange = NSMakeRange (0, nextGlyphIndex);
557 else 555 else
558 glyphRange = NSMakeRange (glyphIndex, 556 glyphRange = NSMakeRange (glyphIndex,
559 nextGlyphIndex - glyphIndex); 557 nextGlyphIndex - glyphIndex);
560 glyphRects = 558 glyphRects =
561 [layoutManager 559 [layoutManager
562 rectArrayForGlyphRange:glyphRange 560 rectArrayForGlyphRange:glyphRange
563 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 561 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
564 inTextContainer:textContainer rectCount:&nrects]; 562 inTextContainer:textContainer rectCount:&nrects];
565 maxX = max (NSMaxX (glyphRects[0]), totalAdvance); 563 maxX = max (NSMaxX (glyphRects[0]), totalAdvance);
566 gl->advance_delta = location.x - totalAdvance; 564 gl->advance_delta = location.x - totalAdvance;
567 gl->advance = maxX - totalAdvance; 565 gl->advance = maxX - totalAdvance;
568 totalAdvance = maxX; 566 totalAdvance = maxX;
569 } 567 }
570 else 568 else
571 { 569 {
572 CGFloat minX; 570 CGFloat minX;
573 571
574 if (nextGlyphIndex == numberOfGlyphs) 572 if (nextGlyphIndex == numberOfGlyphs)
575 glyphRange = NSMakeRange (prevGlyphIndex, 573 glyphRange = NSMakeRange (prevGlyphIndex,
576 numberOfGlyphs - prevGlyphIndex); 574 numberOfGlyphs - prevGlyphIndex);
577 else 575 else
578 glyphRange = NSMakeRange (prevGlyphIndex, 576 glyphRange = NSMakeRange (prevGlyphIndex,
579 glyphIndex + 1 - prevGlyphIndex); 577 glyphIndex + 1 - prevGlyphIndex);
580 glyphRects = 578 glyphRects =
581 [layoutManager 579 [layoutManager
582 rectArrayForGlyphRange:glyphRange 580 rectArrayForGlyphRange:glyphRange
583 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 581 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
584 inTextContainer:textContainer rectCount:&nrects]; 582 inTextContainer:textContainer rectCount:&nrects];
585 minX = min (NSMinX (glyphRects[0]), totalAdvance); 583 minX = min (NSMinX (glyphRects[0]), totalAdvance);
586 gl->advance = totalAdvance - minX; 584 gl->advance = totalAdvance - minX;
587 totalAdvance = minX; 585 totalAdvance = minX;
588 gl->advance_delta = location.x - totalAdvance; 586 gl->advance_delta = location.x - totalAdvance;
589 } 587 }
590 588
591 prevGlyphIndex = glyphIndex + 1; 589 prevGlyphIndex = glyphIndex + 1;
592 glyphIndex = nextGlyphIndex; 590 glyphIndex = nextGlyphIndex;
593 } 591 }
594 592
595 if (RIGHT_TO_LEFT_P) 593 if (RIGHT_TO_LEFT_P)
596 xfree (permutation); 594 xfree (permutation);
597 595
598#undef RIGHT_TO_LEFT_P 596#undef RIGHT_TO_LEFT_P
599 597
600 result = used; 598 result = used;
601 } 599 }
602 [textStorage release]; 600 [textStorage release];
603 601
604 return result; 602 return result;
605} 603}
606 604
607static CFIndex 605static CFIndex
608mac_screen_font_shape (ScreenFontRef font, CFStringRef string, 606mac_screen_font_shape (ScreenFontRef font, CFStringRef string,
609 struct mac_glyph_layout *glyph_layouts, 607 struct mac_glyph_layout *glyph_layouts,
610 CFIndex glyph_len) 608 CFIndex glyph_len)
611{ 609{
612 return mac_font_shape_1 ([(NSFont *)font printerFont], 610 return mac_font_shape_1 ([(NSFont *)font printerFont],
613 (NSString *) string, 611 (NSString *) string,
614 glyph_layouts, glyph_len, YES); 612 glyph_layouts, glyph_len, YES);
615} 613}
616 614
617static CGColorRef 615static CGColorRef
@@ -649,6 +647,7 @@ get_cgcolor(unsigned long idx, struct frame *f)
649 CGColorRelease (refcol_); \ 647 CGColorRelease (refcol_); \
650 } while (0) 648 } while (0)
651 649
650
652 651
653/* Mac font driver. */ 652/* Mac font driver. */
654 653
@@ -711,17 +710,17 @@ static const struct
711 CFStringRef font_names[3]; 710 CFStringRef font_names[3];
712} macfont_language_default_font_names[] = { 711} macfont_language_default_font_names[] = {
713 { CFSTR ("ja"), { CFSTR ("HiraKakuProN-W3"), /* 10.5 - 10.9 */ 712 { CFSTR ("ja"), { CFSTR ("HiraKakuProN-W3"), /* 10.5 - 10.9 */
714 CFSTR ("HiraKakuPro-W3"), /* 10.4 */ 713 CFSTR ("HiraKakuPro-W3"), /* 10.4 */
715 NULL }}, 714 NULL }},
716 { CFSTR ("ko"), { CFSTR ("AppleSDGothicNeo-Regular"), /* 10.8 - 10.9 */ 715 { CFSTR ("ko"), { CFSTR ("AppleSDGothicNeo-Regular"), /* 10.8 - 10.9 */
717 CFSTR ("AppleGothic"), /* 10.4 - 10.7 */ 716 CFSTR ("AppleGothic"), /* 10.4 - 10.7 */
718 NULL }}, 717 NULL }},
719 { CFSTR ("zh-Hans"), { CFSTR ("STHeitiSC-Light"), /* 10.6 - 10.9 */ 718 { CFSTR ("zh-Hans"), { CFSTR ("STHeitiSC-Light"), /* 10.6 - 10.9 */
720 CFSTR ("STXihei"), /* 10.4 - 10.5 */ 719 CFSTR ("STXihei"), /* 10.4 - 10.5 */
721 NULL }}, 720 NULL }},
722 { CFSTR ("zh-Hant"), { CFSTR ("STHeitiTC-Light"), /* 10.6 - 10.9 */ 721 { CFSTR ("zh-Hant"), { CFSTR ("STHeitiTC-Light"), /* 10.6 - 10.9 */
723 CFSTR ("LiHeiPro"), /* 10.4 - 10.5 */ 722 CFSTR ("LiHeiPro"), /* 10.4 - 10.5 */
724 NULL }}, 723 NULL }},
725 { NULL } 724 { NULL }
726}; 725};
727#endif 726#endif
@@ -736,8 +735,8 @@ macfont_update_antialias_threshold (void)
736 735
737 threshold = 736 threshold =
738 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"), 737 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
739 kCFPreferencesCurrentApplication, 738 kCFPreferencesCurrentApplication,
740 &valid_p); 739 &valid_p);
741 if (valid_p) 740 if (valid_p)
742 macfont_antialias_threshold = threshold; 741 macfont_antialias_threshold = threshold;
743} 742}
@@ -771,7 +770,7 @@ macfont_store_utf32char_to_unichars (UTF32Char c, UniChar *unichars)
771 770
772static Boolean 771static Boolean
773cfnumber_get_font_symbolic_traits_value (CFNumberRef number, 772cfnumber_get_font_symbolic_traits_value (CFNumberRef number,
774 FontSymbolicTraits *sym_traits) 773 FontSymbolicTraits *sym_traits)
775{ 774{
776 SInt64 sint64_value; 775 SInt64 sint64_value;
777 776
@@ -789,7 +788,7 @@ cfnumber_get_font_symbolic_traits_value (CFNumberRef number,
789 788
790static void 789static void
791macfont_store_descriptor_attributes (FontDescriptorRef desc, 790macfont_store_descriptor_attributes (FontDescriptorRef desc,
792 Lisp_Object spec_or_entity) 791 Lisp_Object spec_or_entity)
793{ 792{
794 CFStringRef str; 793 CFStringRef str;
795 CFDictionaryRef dict; 794 CFDictionaryRef dict;
@@ -797,66 +796,66 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc,
797 CGFloat floatval; 796 CGFloat floatval;
798 797
799 str = mac_font_descriptor_copy_attribute (desc, 798 str = mac_font_descriptor_copy_attribute (desc,
800 MAC_FONT_FAMILY_NAME_ATTRIBUTE); 799 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
801 if (str) 800 if (str)
802 { 801 {
803 ASET (spec_or_entity, FONT_FAMILY_INDEX, 802 ASET (spec_or_entity, FONT_FAMILY_INDEX,
804 macfont_intern_prop_cfstring (str)); 803 macfont_intern_prop_cfstring (str));
805 CFRelease (str); 804 CFRelease (str);
806 } 805 }
807 dict = mac_font_descriptor_copy_attribute (desc, MAC_FONT_TRAITS_ATTRIBUTE); 806 dict = mac_font_descriptor_copy_attribute (desc, MAC_FONT_TRAITS_ATTRIBUTE);
808 if (dict) 807 if (dict)
809 { 808 {
810 struct { 809 struct {
811 enum font_property_index index; 810 enum font_property_index index;
812 CFStringRef trait; 811 CFStringRef trait;
813 CGPoint points[6]; 812 CGPoint points[6];
814 } numeric_traits[] = 813 } numeric_traits[] =
815 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT, 814 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT,
816 {{-0.4, 50}, /* light */ 815 {{-0.4, 50}, /* light */
817 {-0.24, 87.5}, /* (semi-light + normal) / 2 */ 816 {-0.24, 87.5}, /* (semi-light + normal) / 2 */
818 {0, 100}, /* normal */ 817 {0, 100}, /* normal */
819 {0.24, 140}, /* (semi-bold + normal) / 2 */ 818 {0.24, 140}, /* (semi-bold + normal) / 2 */
820 {0.4, 200}, /* bold */ 819 {0.4, 200}, /* bold */
821 {CGFLOAT_MAX, CGFLOAT_MAX}}}, 820 {CGFLOAT_MAX, CGFLOAT_MAX}}},
822 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT, 821 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT,
823 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}, 822 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}},
824 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT, 823 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT,
825 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; 824 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}};
826 int i; 825 int i;
827 826
828 for (i = 0; i < ARRAYELTS (numeric_traits); i++) 827 for (i = 0; i < ARRAYELTS (numeric_traits); i++)
829 { 828 {
830 num = CFDictionaryGetValue (dict, numeric_traits[i].trait); 829 num = CFDictionaryGetValue (dict, numeric_traits[i].trait);
831 if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval)) 830 if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval))
832 { 831 {
833 CGPoint *point = numeric_traits[i].points; 832 CGPoint *point = numeric_traits[i].points;
834 833
835 while (point->x < floatval) 834 while (point->x < floatval)
836 point++; 835 point++;
837 if (point == numeric_traits[i].points) 836 if (point == numeric_traits[i].points)
838 point++; 837 point++;
839 else if (point->x == CGFLOAT_MAX) 838 else if (point->x == CGFLOAT_MAX)
840 point--; 839 point--;
841 floatval = (point - 1)->y + ((floatval - (point - 1)->x) 840 floatval = (point - 1)->y + ((floatval - (point - 1)->x)
842 * ((point->y - (point - 1)->y) 841 * ((point->y - (point - 1)->y)
843 / (point->x - (point - 1)->x))); 842 / (point->x - (point - 1)->x)));
844 FONT_SET_STYLE (spec_or_entity, numeric_traits[i].index, 843 FONT_SET_STYLE (spec_or_entity, numeric_traits[i].index,
845 make_number (lround (floatval))); 844 make_number (lround (floatval)));
846 } 845 }
847 } 846 }
848 847
849 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 848 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
850 if (num) 849 if (num)
851 { 850 {
852 FontSymbolicTraits sym_traits; 851 FontSymbolicTraits sym_traits;
853 int spacing; 852 int spacing;
854 853
855 cfnumber_get_font_symbolic_traits_value (num, &sym_traits); 854 cfnumber_get_font_symbolic_traits_value (num, &sym_traits);
856 spacing = (sym_traits & MAC_FONT_TRAIT_MONO_SPACE 855 spacing = (sym_traits & MAC_FONT_TRAIT_MONO_SPACE
857 ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL); 856 ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL);
858 ASET (spec_or_entity, FONT_SPACING_INDEX, make_number (spacing)); 857 ASET (spec_or_entity, FONT_SPACING_INDEX, make_number (spacing));
859 } 858 }
860 859
861 CFRelease (dict); 860 CFRelease (dict);
862 } 861 }
@@ -871,7 +870,7 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc,
871 870
872static Lisp_Object 871static Lisp_Object
873macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra, 872macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
874 FontSymbolicTraits synth_sym_traits) 873 FontSymbolicTraits synth_sym_traits)
875{ 874{
876 Lisp_Object entity; 875 Lisp_Object entity;
877 CFDictionaryRef dict; 876 CFDictionaryRef dict;
@@ -891,7 +890,7 @@ macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
891 CFNumberRef num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 890 CFNumberRef num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
892 891
893 if (num) 892 if (num)
894 cfnumber_get_font_symbolic_traits_value (num, &sym_traits); 893 cfnumber_get_font_symbolic_traits_value (num, &sym_traits);
895 CFRelease (dict); 894 CFRelease (dict);
896 } 895 }
897 if (EQ (AREF (entity, FONT_SIZE_INDEX), make_number (0))) 896 if (EQ (AREF (entity, FONT_SIZE_INDEX), make_number (0)))
@@ -899,16 +898,16 @@ macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
899 ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra)); 898 ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
900 name = mac_font_descriptor_copy_attribute (desc, MAC_FONT_NAME_ATTRIBUTE); 899 name = mac_font_descriptor_copy_attribute (desc, MAC_FONT_NAME_ATTRIBUTE);
901 font_put_extra (entity, QCfont_entity, 900 font_put_extra (entity, QCfont_entity,
902 make_save_ptr_int ((void *) name, sym_traits)); 901 make_save_ptr_int ((void *) name, sym_traits));
903 if (synth_sym_traits & MAC_FONT_TRAIT_ITALIC) 902 if (synth_sym_traits & MAC_FONT_TRAIT_ITALIC)
904 FONT_SET_STYLE (entity, FONT_SLANT_INDEX, 903 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
905 make_number (FONT_SLANT_SYNTHETIC_ITALIC)); 904 make_number (FONT_SLANT_SYNTHETIC_ITALIC));
906 if (synth_sym_traits & MAC_FONT_TRAIT_BOLD) 905 if (synth_sym_traits & MAC_FONT_TRAIT_BOLD)
907 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, 906 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
908 make_number (FONT_WEIGHT_SYNTHETIC_BOLD)); 907 make_number (FONT_WEIGHT_SYNTHETIC_BOLD));
909 if (synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 908 if (synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
910 ASET (entity, FONT_SPACING_INDEX, 909 ASET (entity, FONT_SPACING_INDEX,
911 make_number (FONT_SPACING_SYNTHETIC_MONO)); 910 make_number (FONT_SPACING_SYNTHETIC_MONO));
912 911
913 return entity; 912 return entity;
914} 913}
@@ -925,22 +924,9 @@ macfont_create_family_with_symbol (Lisp_Object symbol)
925 if (family_name == NULL) 924 if (family_name == NULL)
926 return NULL; 925 return NULL;
927 926
928#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
929#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
930 if (CTFontManagerCompareFontFamilyNames != NULL)
931#endif
932 { 927 {
933 family_name_comparator = CTFontManagerCompareFontFamilyNames; 928 family_name_comparator = CTFontManagerCompareFontFamilyNames;
934 } 929 }
935#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
936 else /* CTFontManagerCompareFontFamilyNames == NULL */
937#endif
938#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */
939#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
940 {
941 family_name_comparator = mac_font_family_compare;
942 }
943#endif
944 930
945 if ((*family_name_comparator) (family_name, CFSTR ("LastResort"), NULL) 931 if ((*family_name_comparator) (family_name, CFSTR ("LastResort"), NULL)
946 == kCFCompareEqualTo) 932 == kCFCompareEqualTo)
@@ -948,36 +934,36 @@ macfont_create_family_with_symbol (Lisp_Object symbol)
948 else 934 else
949 while (1) 935 while (1)
950 { 936 {
951 CFIndex i, count; 937 CFIndex i, count;
952 938
953 if (families == NULL) 939 if (families == NULL)
954 { 940 {
955 families = mac_font_create_available_families (); 941 families = mac_font_create_available_families ();
956 using_cache_p = 0; 942 using_cache_p = 0;
957 if (families == NULL) 943 if (families == NULL)
958 break; 944 break;
959 } 945 }
960 946
961 count = CFArrayGetCount (families); 947 count = CFArrayGetCount (families);
962 i = CFArrayBSearchValues (families, CFRangeMake (0, count), 948 i = CFArrayBSearchValues (families, CFRangeMake (0, count),
963 (const void *) family_name, 949 (const void *) family_name,
964 family_name_comparator, NULL); 950 family_name_comparator, NULL);
965 if (i < count) 951 if (i < count)
966 { 952 {
967 CFStringRef name = CFArrayGetValueAtIndex (families, i); 953 CFStringRef name = CFArrayGetValueAtIndex (families, i);
968 954
969 if ((*family_name_comparator) (name, family_name, NULL) 955 if ((*family_name_comparator) (name, family_name, NULL)
970 == kCFCompareEqualTo) 956 == kCFCompareEqualTo)
971 result = CFRetain (name); 957 result = CFRetain (name);
972 } 958 }
973 959
974 if (result || !using_cache_p) 960 if (result || !using_cache_p)
975 break; 961 break;
976 else 962 else
977 { 963 {
978 CFRelease (families); 964 CFRelease (families);
979 families = NULL; 965 families = NULL;
980 } 966 }
981 } 967 }
982 968
983 CFRelease (family_name); 969 CFRelease (family_name);
@@ -1004,23 +990,23 @@ struct macfont_metrics
1004 signed width_frac : WIDTH_FRAC_BITS, width_int : 16 - WIDTH_FRAC_BITS; 990 signed width_frac : WIDTH_FRAC_BITS, width_int : 16 - WIDTH_FRAC_BITS;
1005}; 991};
1006 992
1007#define METRICS_VALUE(metrics, member) \ 993#define METRICS_VALUE(metrics, member) \
1008 (((metrics)->member##_high << 8) | (metrics)->member##_low) 994 (((metrics)->member##_high << 8) | (metrics)->member##_low)
1009#define METRICS_SET_VALUE(metrics, member, value) \ 995#define METRICS_SET_VALUE(metrics, member, value) \
1010 do {short tmp = (value); (metrics)->member##_low = tmp & 0xff; \ 996 do {short tmp = (value); (metrics)->member##_low = tmp & 0xff; \
1011 (metrics)->member##_high = tmp >> 8;} while (0) 997 (metrics)->member##_high = tmp >> 8;} while (0)
1012 998
1013enum metrics_status 999enum metrics_status
1014 { 1000{
1015 METRICS_INVALID = -1, /* metrics entry is invalid */ 1001 METRICS_INVALID = -1, /* metrics entry is invalid */
1016 METRICS_WIDTH_VALID = -2 /* width is valid but others are invalid */ 1002 METRICS_WIDTH_VALID = -2 /* width is valid but others are invalid */
1017 }; 1003};
1018 1004
1019#define METRICS_STATUS(metrics) \ 1005#define METRICS_STATUS(metrics) \
1020 (METRICS_VALUE (metrics, ascent) + METRICS_VALUE (metrics, descent)) 1006 (METRICS_VALUE (metrics, ascent) + METRICS_VALUE (metrics, descent))
1021#define METRICS_SET_STATUS(metrics, status) \ 1007#define METRICS_SET_STATUS(metrics, status) \
1022 do {METRICS_SET_VALUE (metrics, ascent, 0); \ 1008 do {METRICS_SET_VALUE (metrics, ascent, 0); \
1023 METRICS_SET_VALUE (metrics, descent, status);} while (0) 1009 METRICS_SET_VALUE (metrics, descent, status);} while (0)
1024 1010
1025#define METRICS_NCOLS_PER_ROW (128) 1011#define METRICS_NCOLS_PER_ROW (128)
1026#define LCD_FONT_SMOOTHING_LEFT_MARGIN (0.396f) 1012#define LCD_FONT_SMOOTHING_LEFT_MARGIN (0.396f)
@@ -1028,8 +1014,8 @@ enum metrics_status
1028 1014
1029static int 1015static int
1030macfont_glyph_extents (struct font *font, CGGlyph glyph, 1016macfont_glyph_extents (struct font *font, CGGlyph glyph,
1031 struct font_metrics *metrics, CGFloat *advance_delta, 1017 struct font_metrics *metrics, CGFloat *advance_delta,
1032 int force_integral_p) 1018 int force_integral_p)
1033{ 1019{
1034 struct macfont_info *macfont_info = (struct macfont_info *) font; 1020 struct macfont_info *macfont_info = (struct macfont_info *) font;
1035 FontRef macfont = macfont_info->macfont; 1021 FontRef macfont = macfont_info->macfont;
@@ -1042,11 +1028,11 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1042 if (row >= macfont_info->metrics_nrows) 1028 if (row >= macfont_info->metrics_nrows)
1043 { 1029 {
1044 macfont_info->metrics = 1030 macfont_info->metrics =
1045 xrealloc (macfont_info->metrics, 1031 xrealloc (macfont_info->metrics,
1046 sizeof (struct macfont_metrics *) * (row + 1)); 1032 sizeof (struct macfont_metrics *) * (row + 1));
1047 memset (macfont_info->metrics + macfont_info->metrics_nrows, 0, 1033 memset (macfont_info->metrics + macfont_info->metrics_nrows, 0,
1048 (sizeof (struct macfont_metrics *) 1034 (sizeof (struct macfont_metrics *)
1049 * (row + 1 - macfont_info->metrics_nrows))); 1035 * (row + 1 - macfont_info->metrics_nrows)));
1050 macfont_info->metrics_nrows = row + 1; 1036 macfont_info->metrics_nrows = row + 1;
1051 } 1037 }
1052 if (macfont_info->metrics[row] == NULL) 1038 if (macfont_info->metrics[row] == NULL)
@@ -1056,7 +1042,7 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1056 1042
1057 new = xmalloc (sizeof (struct macfont_metrics) * METRICS_NCOLS_PER_ROW); 1043 new = xmalloc (sizeof (struct macfont_metrics) * METRICS_NCOLS_PER_ROW);
1058 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++) 1044 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
1059 METRICS_SET_STATUS (new + i, METRICS_INVALID); 1045 METRICS_SET_STATUS (new + i, METRICS_INVALID);
1060 macfont_info->metrics[row] = new; 1046 macfont_info->metrics[row] = new;
1061 } 1047 }
1062 cache = macfont_info->metrics[row] + col; 1048 cache = macfont_info->metrics[row] + col;
@@ -1066,17 +1052,17 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1066 CGFloat fwidth; 1052 CGFloat fwidth;
1067 1053
1068 if (macfont_info->screen_font) 1054 if (macfont_info->screen_font)
1069 fwidth = mac_screen_font_get_advance_width_for_glyph (macfont_info->screen_font, glyph); 1055 fwidth = mac_screen_font_get_advance_width_for_glyph (macfont_info->screen_font, glyph);
1070 else 1056 else
1071 fwidth = mac_font_get_advance_width_for_glyph (macfont, glyph); 1057 fwidth = mac_font_get_advance_width_for_glyph (macfont, glyph);
1072 1058
1073 /* For synthetic mono fonts, cache->width_{int,frac} holds the 1059 /* For synthetic mono fonts, cache->width_{int,frac} holds the
1074 advance delta value. */ 1060 advance delta value. */
1075 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) 1061 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO)
1076 fwidth = (font->pixel_size - fwidth) / 2; 1062 fwidth = (font->pixel_size - fwidth) / 2;
1077 cache->width_int = lround (fwidth); 1063 cache->width_int = lround (fwidth);
1078 cache->width_frac = lround ((fwidth - cache->width_int) 1064 cache->width_frac = lround ((fwidth - cache->width_int)
1079 * WIDTH_FRAC_SCALE); 1065 * WIDTH_FRAC_SCALE);
1080 METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID); 1066 METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID);
1081 } 1067 }
1082 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) 1068 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO)
@@ -1087,52 +1073,52 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1087 if (metrics) 1073 if (metrics)
1088 { 1074 {
1089 if (METRICS_STATUS (cache) == METRICS_WIDTH_VALID) 1075 if (METRICS_STATUS (cache) == METRICS_WIDTH_VALID)
1090 { 1076 {
1091 CGRect bounds = mac_font_get_bounding_rect_for_glyph (macfont, glyph); 1077 CGRect bounds = mac_font_get_bounding_rect_for_glyph (macfont, glyph);
1092 1078
1093 if (macfont_info->synthetic_italic_p) 1079 if (macfont_info->synthetic_italic_p)
1094 { 1080 {
1095 /* We assume the members a, b, c, and d in 1081 /* We assume the members a, b, c, and d in
1096 synthetic_italic_atfm are non-negative. */ 1082 synthetic_italic_atfm are non-negative. */
1097 bounds.origin = 1083 bounds.origin =
1098 CGPointApplyAffineTransform (bounds.origin, 1084 CGPointApplyAffineTransform (bounds.origin,
1099 synthetic_italic_atfm); 1085 synthetic_italic_atfm);
1100 bounds.size = 1086 bounds.size =
1101 CGSizeApplyAffineTransform (bounds.size, synthetic_italic_atfm); 1087 CGSizeApplyAffineTransform (bounds.size, synthetic_italic_atfm);
1102 } 1088 }
1103 if (macfont_info->synthetic_bold_p) 1089 if (macfont_info->synthetic_bold_p)
1104 { 1090 {
1105 CGFloat d = 1091 CGFloat d =
1106 - synthetic_bold_factor * mac_font_get_size (macfont) / 2; 1092 - synthetic_bold_factor * mac_font_get_size (macfont) / 2;
1107 1093
1108 bounds = CGRectInset (bounds, d, d); 1094 bounds = CGRectInset (bounds, d, d);
1109 } 1095 }
1110 switch (macfont_info->spacing) 1096 switch (macfont_info->spacing)
1111 { 1097 {
1112 case MACFONT_SPACING_PROPORTIONAL: 1098 case MACFONT_SPACING_PROPORTIONAL:
1113 bounds.origin.x += - (cache->width_frac 1099 bounds.origin.x += - (cache->width_frac
1114 / (CGFloat) (WIDTH_FRAC_SCALE * 2)); 1100 / (CGFloat) (WIDTH_FRAC_SCALE * 2));
1115 break; 1101 break;
1116 case MACFONT_SPACING_MONO: 1102 case MACFONT_SPACING_MONO:
1117 break; 1103 break;
1118 case MACFONT_SPACING_SYNTHETIC_MONO: 1104 case MACFONT_SPACING_SYNTHETIC_MONO:
1119 bounds.origin.x += (cache->width_int 1105 bounds.origin.x += (cache->width_int
1120 + (cache->width_frac 1106 + (cache->width_frac
1121 / (CGFloat) WIDTH_FRAC_SCALE)); 1107 / (CGFloat) WIDTH_FRAC_SCALE));
1122 break; 1108 break;
1123 } 1109 }
1124 if (bounds.size.width > 0) 1110 if (bounds.size.width > 0)
1125 { 1111 {
1126 bounds.origin.x -= LCD_FONT_SMOOTHING_LEFT_MARGIN; 1112 bounds.origin.x -= LCD_FONT_SMOOTHING_LEFT_MARGIN;
1127 bounds.size.width += (LCD_FONT_SMOOTHING_LEFT_MARGIN 1113 bounds.size.width += (LCD_FONT_SMOOTHING_LEFT_MARGIN
1128 + LCD_FONT_SMOOTHING_RIGHT_MARGIN); 1114 + LCD_FONT_SMOOTHING_RIGHT_MARGIN);
1129 } 1115 }
1130 bounds = CGRectIntegral (bounds); 1116 bounds = CGRectIntegral (bounds);
1131 METRICS_SET_VALUE (cache, lbearing, CGRectGetMinX (bounds)); 1117 METRICS_SET_VALUE (cache, lbearing, CGRectGetMinX (bounds));
1132 METRICS_SET_VALUE (cache, rbearing, CGRectGetMaxX (bounds)); 1118 METRICS_SET_VALUE (cache, rbearing, CGRectGetMaxX (bounds));
1133 METRICS_SET_VALUE (cache, ascent, CGRectGetMaxY (bounds)); 1119 METRICS_SET_VALUE (cache, ascent, CGRectGetMaxY (bounds));
1134 METRICS_SET_VALUE (cache, descent, -CGRectGetMinY (bounds)); 1120 METRICS_SET_VALUE (cache, descent, -CGRectGetMinY (bounds));
1135 } 1121 }
1136 metrics->lbearing = METRICS_VALUE (cache, lbearing); 1122 metrics->lbearing = METRICS_VALUE (cache, lbearing);
1137 metrics->rbearing = METRICS_VALUE (cache, rbearing); 1123 metrics->rbearing = METRICS_VALUE (cache, rbearing);
1138 metrics->width = width; 1124 metrics->width = width;
@@ -1143,22 +1129,22 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1143 if (advance_delta) 1129 if (advance_delta)
1144 { 1130 {
1145 switch (macfont_info->spacing) 1131 switch (macfont_info->spacing)
1146 { 1132 {
1147 case MACFONT_SPACING_PROPORTIONAL: 1133 case MACFONT_SPACING_PROPORTIONAL:
1148 *advance_delta = (force_integral_p ? 0 1134 *advance_delta = (force_integral_p ? 0
1149 : - (cache->width_frac 1135 : - (cache->width_frac
1150 / (CGFloat) (WIDTH_FRAC_SCALE * 2))); 1136 / (CGFloat) (WIDTH_FRAC_SCALE * 2)));
1151 break; 1137 break;
1152 case MACFONT_SPACING_MONO: 1138 case MACFONT_SPACING_MONO:
1153 *advance_delta = 0; 1139 *advance_delta = 0;
1154 break; 1140 break;
1155 case MACFONT_SPACING_SYNTHETIC_MONO: 1141 case MACFONT_SPACING_SYNTHETIC_MONO:
1156 *advance_delta = (force_integral_p ? cache->width_int 1142 *advance_delta = (force_integral_p ? cache->width_int
1157 : (cache->width_int 1143 : (cache->width_int
1158 + (cache->width_frac 1144 + (cache->width_frac
1159 / (CGFloat) WIDTH_FRAC_SCALE))); 1145 / (CGFloat) WIDTH_FRAC_SCALE)));
1160 break; 1146 break;
1161 } 1147 }
1162 } 1148 }
1163 1149
1164 return width; 1150 return width;
@@ -1220,7 +1206,7 @@ static CFCharacterSetRef macfont_get_cf_charset (struct font *);
1220static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef); 1206static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef);
1221static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char); 1207static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char);
1222static CGGlyph macfont_get_glyph_for_cid (struct font *font, 1208static CGGlyph macfont_get_glyph_for_cid (struct font *font,
1223 CharacterCollection, CGFontIndex); 1209 CharacterCollection, CGFontIndex);
1224static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *); 1210static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *);
1225 1211
1226static struct macfont_cache * 1212static struct macfont_cache *
@@ -1231,39 +1217,39 @@ macfont_lookup_cache (CFStringRef key)
1231 if (macfont_cache_dictionary == NULL) 1217 if (macfont_cache_dictionary == NULL)
1232 { 1218 {
1233 macfont_cache_dictionary = 1219 macfont_cache_dictionary =
1234 CFDictionaryCreateMutable (NULL, 0, 1220 CFDictionaryCreateMutable (NULL, 0,
1235 &kCFTypeDictionaryKeyCallBacks, NULL); 1221 &kCFTypeDictionaryKeyCallBacks, NULL);
1236 cache = NULL; 1222 cache = NULL;
1237 } 1223 }
1238 else 1224 else
1239 cache = ((struct macfont_cache *) 1225 cache = ((struct macfont_cache *)
1240 CFDictionaryGetValue (macfont_cache_dictionary, key)); 1226 CFDictionaryGetValue (macfont_cache_dictionary, key));
1241 1227
1242 if (cache == NULL) 1228 if (cache == NULL)
1243 { 1229 {
1244 FontRef macfont = mac_font_create_with_name (key, 0); 1230 FontRef macfont = mac_font_create_with_name (key, 0);
1245 1231
1246 if (macfont) 1232 if (macfont)
1247 { 1233 {
1248 cache = xzalloc (sizeof (struct macfont_cache)); 1234 cache = xzalloc (sizeof (struct macfont_cache));
1249 /* Treat the LastResort font as if it contained glyphs for 1235 /* Treat the LastResort font as if it contained glyphs for
1250 all characters. This may look too rough, but neither 1236 all characters. This may look too rough, but neither
1251 CTFontCopyCharacterSet nor -[NSFont coveredCharacterSet] 1237 CTFontCopyCharacterSet nor -[NSFont coveredCharacterSet]
1252 for this font is correct for non-BMP characters on Mac OS 1238 for this font is correct for non-BMP characters on Mac OS
1253 X 10.5, anyway. */ 1239 X 10.5, anyway. */
1254 if (CFEqual (key, CFSTR ("LastResort"))) 1240 if (CFEqual (key, CFSTR ("LastResort")))
1255 { 1241 {
1256 CFRange range = CFRangeMake (0, MAX_UNICODE_CHAR + 1); 1242 CFRange range = CFRangeMake (0, MAX_UNICODE_CHAR + 1);
1257 1243
1258 cache->cf_charset = 1244 cache->cf_charset =
1259 CFCharacterSetCreateWithCharactersInRange (NULL, range); 1245 CFCharacterSetCreateWithCharactersInRange (NULL, range);
1260 } 1246 }
1261 if (cache->cf_charset == NULL) 1247 if (cache->cf_charset == NULL)
1262 cache->cf_charset = mac_font_copy_character_set (macfont); 1248 cache->cf_charset = mac_font_copy_character_set (macfont);
1263 CFDictionaryAddValue (macfont_cache_dictionary, key, 1249 CFDictionaryAddValue (macfont_cache_dictionary, key,
1264 (const void *) cache); 1250 (const void *) cache);
1265 CFRelease (macfont); 1251 CFRelease (macfont);
1266 } 1252 }
1267 } 1253 }
1268 1254
1269 return cache; 1255 return cache;
@@ -1285,13 +1271,13 @@ macfont_release_cache (struct macfont_cache *cache)
1285 int i; 1271 int i;
1286 1272
1287 for (i = 0; i < cache->glyph.nrows; i++) 1273 for (i = 0; i < cache->glyph.nrows; i++)
1288 xfree (cache->glyph.matrix[i]); 1274 xfree (cache->glyph.matrix[i]);
1289 xfree (cache->glyph.matrix); 1275 xfree (cache->glyph.matrix);
1290 if (cache->glyph.dictionary) 1276 if (cache->glyph.dictionary)
1291 CFRelease (cache->glyph.dictionary); 1277 CFRelease (cache->glyph.dictionary);
1292 memset (&cache->glyph, 0, sizeof (cache->glyph)); 1278 memset (&cache->glyph, 0, sizeof (cache->glyph));
1293 if (cache->uvs.table) 1279 if (cache->uvs.table)
1294 CFRelease (cache->uvs.table); 1280 CFRelease (cache->uvs.table);
1295 memset (&cache->uvs, 0, sizeof (cache->uvs)); 1281 memset (&cache->uvs, 0, sizeof (cache->uvs));
1296 } 1282 }
1297} 1283}
@@ -1325,124 +1311,114 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1325 int nkeys_or_perm = cache->glyph.row_nkeys_or_perm[row]; 1311 int nkeys_or_perm = cache->glyph.row_nkeys_or_perm[row];
1326 1312
1327 if (nkeys_or_perm < ROW_PERM_OFFSET) 1313 if (nkeys_or_perm < ROW_PERM_OFFSET)
1328 { 1314 {
1329 UniChar unichars[256], ch; 1315 UniChar unichars[256], ch;
1330 CGGlyph *glyphs; 1316 CGGlyph *glyphs;
1331 int i, len; 1317 int i, len;
1332 int nrows; 1318 int nrows;
1333#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1319 dispatch_queue_t queue;
1334 dispatch_queue_t queue; 1320 dispatch_group_t group = NULL;
1335 dispatch_group_t group = NULL; 1321
1336#else 1322 if (row != 0)
1337 int nkeys; 1323 {
1338#endif 1324 CFMutableDictionaryRef dictionary;
1339 1325 uintptr_t key, value;
1340 if (row != 0) 1326 int nshifts;
1341 { 1327 CGGlyph glyph;
1342 CFMutableDictionaryRef dictionary; 1328
1343 uintptr_t key, value; 1329 if (cache->glyph.dictionary == NULL)
1344 int nshifts; 1330 cache->glyph.dictionary =
1345 CGGlyph glyph; 1331 CFDictionaryCreateMutable (NULL, 0, NULL, NULL);
1346 1332 dictionary = cache->glyph.dictionary;
1347 if (cache->glyph.dictionary == NULL) 1333 key = c / NGLYPHS_IN_VALUE;
1348 cache->glyph.dictionary = 1334 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8);
1349 CFDictionaryCreateMutable (NULL, 0, NULL, NULL); 1335 value = ((uintptr_t)
1350 dictionary = cache->glyph.dictionary; 1336 CFDictionaryGetValue (dictionary, (const void *) key));
1351 key = c / NGLYPHS_IN_VALUE; 1337 glyph = (value >> nshifts);
1352 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8); 1338 if (glyph)
1353 value = ((uintptr_t) 1339 return glyph;
1354 CFDictionaryGetValue (dictionary, (const void *) key)); 1340
1355 glyph = (value >> nshifts); 1341 if (nkeys_or_perm + 1 != ROW_PERM_OFFSET)
1356 if (glyph) 1342 {
1357 return glyph; 1343 ch = c;
1358 1344 if (!mac_font_get_glyphs_for_characters (macfont, &ch,
1359 if (nkeys_or_perm + 1 != ROW_PERM_OFFSET) 1345 &glyph, 1)
1360 { 1346 || glyph == 0)
1361 ch = c; 1347 glyph = kCGFontIndexInvalid;
1362 if (!mac_font_get_glyphs_for_characters (macfont, &ch, 1348
1363 &glyph, 1) 1349 if (value == 0)
1364 || glyph == 0) 1350 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm + 1;
1365 glyph = kCGFontIndexInvalid; 1351 value |= ((uintptr_t) glyph << nshifts);
1366 1352 CFDictionarySetValue (dictionary, (const void *) key,
1367 if (value == 0) 1353 (const void *) value);
1368 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm + 1; 1354
1369 value |= ((uintptr_t) glyph << nshifts); 1355 return glyph;
1370 CFDictionarySetValue (dictionary, (const void *) key, 1356 }
1371 (const void *) value); 1357
1372 1358 queue =
1373 return glyph; 1359 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1374 } 1360 group = dispatch_group_create ();
1375 1361 dispatch_group_async (group, queue, ^{
1376#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1362 int nkeys;
1377 queue = 1363 uintptr_t key;
1378 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 1364 nkeys = nkeys_or_perm;
1379 group = dispatch_group_create (); 1365 for (key = row * (256 / NGLYPHS_IN_VALUE); ; key++)
1380 dispatch_group_async (group, queue, ^{ 1366 if (CFDictionaryContainsKey (dictionary,
1381 int nkeys; 1367 (const void *) key))
1382 uintptr_t key; 1368 {
1383#endif 1369 CFDictionaryRemoveValue (dictionary,
1384 nkeys = nkeys_or_perm; 1370 (const void *) key);
1385 for (key = row * (256 / NGLYPHS_IN_VALUE); ; key++) 1371 if (--nkeys == 0)
1386 if (CFDictionaryContainsKey (dictionary, 1372 break;
1387 (const void *) key)) 1373 }
1388 { 1374 });
1389 CFDictionaryRemoveValue (dictionary, 1375 }
1390 (const void *) key); 1376
1391 if (--nkeys == 0) 1377 len = 0;
1392 break; 1378 for (i = 0; i < 256; i++)
1393 } 1379 {
1394#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1380 ch = row * 256 + i;
1395 }); 1381 if (CFCharacterSetIsLongCharacterMember (cache->cf_charset, ch))
1396#endif 1382 unichars[len++] = ch;
1397 } 1383 }
1398 1384
1399 len = 0; 1385 glyphs = xmalloc (sizeof (CGGlyph) * 256);
1400 for (i = 0; i < 256; i++) 1386 if (len > 0)
1401 { 1387 {
1402 ch = row * 256 + i; 1388 mac_font_get_glyphs_for_characters (macfont, unichars,
1403 if (CFCharacterSetIsLongCharacterMember (cache->cf_charset, ch)) 1389 glyphs, len);
1404 unichars[len++] = ch; 1390 while (i > len)
1405 } 1391 {
1406 1392 int next = unichars[len - 1] % 256;
1407 glyphs = xmalloc (sizeof (CGGlyph) * 256); 1393
1408 if (len > 0) 1394 while (--i > next)
1409 { 1395 glyphs[i] = kCGFontIndexInvalid;
1410 mac_font_get_glyphs_for_characters (macfont, unichars, 1396
1411 glyphs, len); 1397 len--;
1412 while (i > len) 1398 glyphs[i] = glyphs[len];
1413 { 1399 if (len == 0)
1414 int next = unichars[len - 1] % 256; 1400 break;
1415 1401 }
1416 while (--i > next) 1402 }
1417 glyphs[i] = kCGFontIndexInvalid; 1403 if (i > len)
1418 1404 while (i-- > 0)
1419 len--; 1405 glyphs[i] = kCGFontIndexInvalid;
1420 glyphs[i] = glyphs[len]; 1406
1421 if (len == 0) 1407 nrows = cache->glyph.nrows;
1422 break; 1408 nkeys_or_perm = nrows + ROW_PERM_OFFSET;
1423 } 1409 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm;
1424 } 1410 nrows++;
1425 if (i > len) 1411 cache->glyph.matrix = xrealloc (cache->glyph.matrix,
1426 while (i-- > 0) 1412 sizeof (CGGlyph *) * nrows);
1427 glyphs[i] = kCGFontIndexInvalid; 1413 cache->glyph.matrix[nrows - 1] = glyphs;
1428 1414 cache->glyph.nrows = nrows;
1429 nrows = cache->glyph.nrows; 1415
1430 nkeys_or_perm = nrows + ROW_PERM_OFFSET; 1416 if (group)
1431 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm; 1417 {
1432 nrows++; 1418 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
1433 cache->glyph.matrix = xrealloc (cache->glyph.matrix, 1419 dispatch_release (group);
1434 sizeof (CGGlyph *) * nrows); 1420 }
1435 cache->glyph.matrix[nrows - 1] = glyphs; 1421 }
1436 cache->glyph.nrows = nrows;
1437
1438#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
1439 if (group)
1440 {
1441 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
1442 dispatch_release (group);
1443 }
1444#endif
1445 }
1446 1422
1447 return cache->glyph.matrix[nkeys_or_perm - ROW_PERM_OFFSET][c % 256]; 1423 return cache->glyph.matrix[nkeys_or_perm - ROW_PERM_OFFSET][c % 256];
1448 } 1424 }
@@ -1453,29 +1429,29 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1453 CGGlyph glyph; 1429 CGGlyph glyph;
1454 1430
1455 if (cache->glyph.dictionary == NULL) 1431 if (cache->glyph.dictionary == NULL)
1456 cache->glyph.dictionary = 1432 cache->glyph.dictionary =
1457 CFDictionaryCreateMutable (NULL, 0, NULL, NULL); 1433 CFDictionaryCreateMutable (NULL, 0, NULL, NULL);
1458 key = c / NGLYPHS_IN_VALUE; 1434 key = c / NGLYPHS_IN_VALUE;
1459 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8); 1435 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8);
1460 value = (uintptr_t) CFDictionaryGetValue (cache->glyph.dictionary, 1436 value = (uintptr_t) CFDictionaryGetValue (cache->glyph.dictionary,
1461 (const void *) key); 1437 (const void *) key);
1462 glyph = (value >> nshifts); 1438 glyph = (value >> nshifts);
1463 if (glyph == 0) 1439 if (glyph == 0)
1464 { 1440 {
1465 UniChar unichars[2]; 1441 UniChar unichars[2];
1466 CGGlyph glyphs[2]; 1442 CGGlyph glyphs[2];
1467 CFIndex count = macfont_store_utf32char_to_unichars (c, unichars); 1443 CFIndex count = macfont_store_utf32char_to_unichars (c, unichars);
1468 1444
1469 if (mac_font_get_glyphs_for_characters (macfont, unichars, glyphs, 1445 if (mac_font_get_glyphs_for_characters (macfont, unichars, glyphs,
1470 count)) 1446 count))
1471 glyph = glyphs[0]; 1447 glyph = glyphs[0];
1472 if (glyph == 0) 1448 if (glyph == 0)
1473 glyph = kCGFontIndexInvalid; 1449 glyph = kCGFontIndexInvalid;
1474 1450
1475 value |= ((uintptr_t) glyph << nshifts); 1451 value |= ((uintptr_t) glyph << nshifts);
1476 CFDictionarySetValue (cache->glyph.dictionary, 1452 CFDictionarySetValue (cache->glyph.dictionary,
1477 (const void *) key, (const void *) value); 1453 (const void *) key, (const void *) value);
1478 } 1454 }
1479 1455
1480 return glyph; 1456 return glyph;
1481 } 1457 }
@@ -1483,7 +1459,7 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1483 1459
1484static CGGlyph 1460static CGGlyph
1485macfont_get_glyph_for_cid (struct font *font, CharacterCollection collection, 1461macfont_get_glyph_for_cid (struct font *font, CharacterCollection collection,
1486 CGFontIndex cid) 1462 CGFontIndex cid)
1487{ 1463{
1488 struct macfont_info *macfont_info = (struct macfont_info *) font; 1464 struct macfont_info *macfont_info = (struct macfont_info *) font;
1489 FontRef macfont = macfont_info->macfont; 1465 FontRef macfont = macfont_info->macfont;
@@ -1504,34 +1480,34 @@ macfont_get_uvs_table (struct font *font, CharacterCollection *collection)
1504 { 1480 {
1505 CFDataRef uvs_table = mac_font_copy_uvs_table (macfont); 1481 CFDataRef uvs_table = mac_font_copy_uvs_table (macfont);
1506 CharacterCollection uvs_collection = 1482 CharacterCollection uvs_collection =
1507 MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING; 1483 MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING;
1508 1484
1509 if (uvs_table == NULL 1485 if (uvs_table == NULL
1510 && mac_font_get_glyph_for_cid (macfont, 1486 && mac_font_get_glyph_for_cid (macfont,
1511 MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1, 1487 MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1,
1512 6480) != kCGFontIndexInvalid) 1488 6480) != kCGFontIndexInvalid)
1513 { 1489 {
1514 /* If the glyph for U+4E55 is accessible via its CID 6480, 1490 /* If the glyph for U+4E55 is accessible via its CID 6480,
1515 then we use the Adobe-Japan1 UVS table, which maps a 1491 then we use the Adobe-Japan1 UVS table, which maps a
1516 variation sequence to a CID, as a fallback. */ 1492 variation sequence to a CID, as a fallback. */
1517 static CFDataRef mac_uvs_table_adobe_japan1 = NULL; 1493 static CFDataRef mac_uvs_table_adobe_japan1 = NULL;
1518 1494
1519 if (mac_uvs_table_adobe_japan1 == NULL) 1495 if (mac_uvs_table_adobe_japan1 == NULL)
1520 mac_uvs_table_adobe_japan1 = 1496 mac_uvs_table_adobe_japan1 =
1521 CFDataCreateWithBytesNoCopy (NULL, 1497 CFDataCreateWithBytesNoCopy (NULL,
1522 mac_uvs_table_adobe_japan1_bytes, 1498 mac_uvs_table_adobe_japan1_bytes,
1523 sizeof (mac_uvs_table_adobe_japan1_bytes), 1499 sizeof (mac_uvs_table_adobe_japan1_bytes),
1524 kCFAllocatorNull); 1500 kCFAllocatorNull);
1525 if (mac_uvs_table_adobe_japan1) 1501 if (mac_uvs_table_adobe_japan1)
1526 { 1502 {
1527 uvs_table = CFRetain (mac_uvs_table_adobe_japan1); 1503 uvs_table = CFRetain (mac_uvs_table_adobe_japan1);
1528 uvs_collection = MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1; 1504 uvs_collection = MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1;
1529 } 1505 }
1530 } 1506 }
1531 if (uvs_table == NULL) 1507 if (uvs_table == NULL)
1532 cache->uvs.table = kCFNull; 1508 cache->uvs.table = kCFNull;
1533 else 1509 else
1534 cache->uvs.table = uvs_table; 1510 cache->uvs.table = uvs_table;
1535 cache->uvs.collection = uvs_collection; 1511 cache->uvs.collection = uvs_collection;
1536 } 1512 }
1537 1513
@@ -1553,12 +1529,12 @@ static Lisp_Object macfont_open (struct frame *, Lisp_Object, int);
1553static void macfont_close (struct font *); 1529static void macfont_close (struct font *);
1554static int macfont_has_char (Lisp_Object, int); 1530static int macfont_has_char (Lisp_Object, int);
1555static unsigned macfont_encode_char (struct font *, int); 1531static unsigned macfont_encode_char (struct font *, int);
1556static int macfont_text_extents (struct font *, unsigned int *, int, 1532static void macfont_text_extents (struct font *, unsigned int *, int,
1557 struct font_metrics *); 1533 struct font_metrics *);
1558static int macfont_draw (struct glyph_string *, int, int, int, int, bool); 1534static int macfont_draw (struct glyph_string *, int, int, int, int, bool);
1559static Lisp_Object macfont_shape (Lisp_Object); 1535static Lisp_Object macfont_shape (Lisp_Object);
1560static int macfont_variation_glyphs (struct font *, int c, 1536static int macfont_variation_glyphs (struct font *, int c,
1561 unsigned variations[256]); 1537 unsigned variations[256]);
1562static void macfont_filter_properties (Lisp_Object, Lisp_Object); 1538static void macfont_filter_properties (Lisp_Object, Lisp_Object);
1563 1539
1564static struct font_driver macfont_driver = 1540static struct font_driver macfont_driver =
@@ -1610,19 +1586,19 @@ macfont_get_charset (Lisp_Object registry)
1610 for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++) 1586 for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
1611 { 1587 {
1612 if (str[i] == '.') 1588 if (str[i] == '.')
1613 re[j++] = '\\'; 1589 re[j++] = '\\';
1614 else if (str[i] == '*') 1590 else if (str[i] == '*')
1615 re[j++] = '.'; 1591 re[j++] = '.';
1616 re[j] = str[i]; 1592 re[j] = str[i];
1617 if (re[j] == '?') 1593 if (re[j] == '?')
1618 re[j] = '.'; 1594 re[j] = '.';
1619 } 1595 }
1620 re[j] = '\0'; 1596 re[j] = '\0';
1621 regexp = make_unibyte_string (re, j); 1597 regexp = make_unibyte_string (re, j);
1622 for (i = 0; cf_charset_table[i].name; i++) 1598 for (i = 0; cf_charset_table[i].name; i++)
1623 if (fast_c_string_match_ignore_case 1599 if (fast_c_string_match_ignore_case
1624 (regexp, cf_charset_table[i].name, 1600 (regexp, cf_charset_table[i].name,
1625 strlen (cf_charset_table[i].name)) >= 0) 1601 strlen (cf_charset_table[i].name)) >= 0)
1626 break; 1602 break;
1627 if (! cf_charset_table[i].name) 1603 if (! cf_charset_table[i].name)
1628 return -1; 1604 return -1;
@@ -1635,27 +1611,27 @@ macfont_get_charset (Lisp_Object registry)
1635 CFMutableCharacterSetRef charset = CFCharacterSetCreateMutable (NULL); 1611 CFMutableCharacterSetRef charset = CFCharacterSetCreateMutable (NULL);
1636 1612
1637 if (! charset) 1613 if (! charset)
1638 return -1; 1614 return -1;
1639 for (j = 0; uniquifier[j]; j++) 1615 for (j = 0; uniquifier[j]; j++)
1640 { 1616 {
1641 count += macfont_store_utf32char_to_unichars (uniquifier[j], 1617 count += macfont_store_utf32char_to_unichars (uniquifier[j],
1642 unichars + count); 1618 unichars + count);
1643 CFCharacterSetAddCharactersInRange (charset, 1619 CFCharacterSetAddCharactersInRange (charset,
1644 CFRangeMake (uniquifier[j], 1)); 1620 CFRangeMake (uniquifier[j], 1));
1645 } 1621 }
1646 1622
1647 string = CFStringCreateWithCharacters (NULL, unichars, count); 1623 string = CFStringCreateWithCharacters (NULL, unichars, count);
1648 if (! string) 1624 if (! string)
1649 { 1625 {
1650 CFRelease (charset); 1626 CFRelease (charset);
1651 return -1; 1627 return -1;
1652 } 1628 }
1653 cf_charset_table[i].cf_charset = CFCharacterSetCreateCopy (NULL, 1629 cf_charset_table[i].cf_charset = CFCharacterSetCreateCopy (NULL,
1654 charset); 1630 charset);
1655 CFRelease (charset); 1631 CFRelease (charset);
1656 /* CFCharacterSetCreateWithCharactersInString does not handle 1632 /* CFCharacterSetCreateWithCharactersInString does not handle
1657 surrogate pairs properly as of Mac OS X 10.5. */ 1633 surrogate pairs properly as of Mac OS X 10.5. */
1658 cf_charset_table[i].cf_charset_string = string; 1634 cf_charset_table[i].cf_charset_string = string;
1659 } 1635 }
1660 return i; 1636 return i;
1661} 1637}
@@ -1668,19 +1644,19 @@ struct OpenTypeSpec
1668 unsigned int *features[2]; 1644 unsigned int *features[2];
1669}; 1645};
1670 1646
1671#define OTF_SYM_TAG(SYM, TAG) \ 1647#define OTF_SYM_TAG(SYM, TAG) \
1672 do { \ 1648 do { \
1673 unsigned char *p = SDATA (SYMBOL_NAME (SYM)); \ 1649 unsigned char *p = SDATA (SYMBOL_NAME (SYM)); \
1674 TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; \ 1650 TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; \
1675 } while (0) 1651 } while (0)
1676 1652
1677#define OTF_TAG_STR(TAG, P) \ 1653#define OTF_TAG_STR(TAG, P) \
1678 do { \ 1654 do { \
1679 (P)[0] = (char) (TAG >> 24); \ 1655 (P)[0] = (char) (TAG >> 24); \
1680 (P)[1] = (char) ((TAG >> 16) & 0xFF); \ 1656 (P)[1] = (char) ((TAG >> 16) & 0xFF); \
1681 (P)[2] = (char) ((TAG >> 8) & 0xFF); \ 1657 (P)[2] = (char) ((TAG >> 8) & 0xFF); \
1682 (P)[3] = (char) (TAG & 0xFF); \ 1658 (P)[3] = (char) (TAG & 0xFF); \
1683 (P)[4] = '\0'; \ 1659 (P)[4] = '\0'; \
1684 } while (0) 1660 } while (0)
1685 1661
1686static struct OpenTypeSpec * 1662static struct OpenTypeSpec *
@@ -1699,9 +1675,9 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1699 OTF_SYM_TAG (spec->script, spec->script_tag); 1675 OTF_SYM_TAG (spec->script, spec->script_tag);
1700 val = assq_no_quit (spec->script, Votf_script_alist); 1676 val = assq_no_quit (spec->script, Votf_script_alist);
1701 if (CONSP (val) && SYMBOLP (XCDR (val))) 1677 if (CONSP (val) && SYMBOLP (XCDR (val)))
1702 spec->script = XCDR (val); 1678 spec->script = XCDR (val);
1703 else 1679 else
1704 spec->script = Qnil; 1680 spec->script = Qnil;
1705 } 1681 }
1706 else 1682 else
1707 spec->script_tag = 0x44464C54; /* "DFLT" */ 1683 spec->script_tag = 0x44464C54; /* "DFLT" */
@@ -1711,7 +1687,7 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1711 { 1687 {
1712 val = XCAR (otf_spec); 1688 val = XCAR (otf_spec);
1713 if (! NILP (val)) 1689 if (! NILP (val))
1714 OTF_SYM_TAG (val, spec->langsys_tag); 1690 OTF_SYM_TAG (val, spec->langsys_tag);
1715 otf_spec = XCDR (otf_spec); 1691 otf_spec = XCDR (otf_spec);
1716 } 1692 }
1717 spec->nfeatures[0] = spec->nfeatures[1] = 0; 1693 spec->nfeatures[0] = spec->nfeatures[1] = 0;
@@ -1721,31 +1697,31 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1721 1697
1722 val = XCAR (otf_spec); 1698 val = XCAR (otf_spec);
1723 if (NILP (val)) 1699 if (NILP (val))
1724 continue; 1700 continue;
1725 len = Flength (val); 1701 len = Flength (val);
1726 spec->features[i] = 1702 spec->features[i] =
1727 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len) 1703 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len)
1728 ? 0 1704 ? 0
1729 : malloc (XINT (len) * sizeof *spec->features[i])); 1705 : malloc (XINT (len) * sizeof *spec->features[i]));
1730 if (! spec->features[i]) 1706 if (! spec->features[i])
1731 { 1707 {
1732 if (i > 0 && spec->features[0]) 1708 if (i > 0 && spec->features[0])
1733 free (spec->features[0]); 1709 free (spec->features[0]);
1734 free (spec); 1710 free (spec);
1735 return NULL; 1711 return NULL;
1736 } 1712 }
1737 for (j = 0, negative = 0; CONSP (val); val = XCDR (val)) 1713 for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
1738 { 1714 {
1739 if (NILP (XCAR (val))) 1715 if (NILP (XCAR (val)))
1740 negative = 1; 1716 negative = 1;
1741 else 1717 else
1742 { 1718 {
1743 unsigned int tag; 1719 unsigned int tag;
1744 1720
1745 OTF_SYM_TAG (XCAR (val), tag); 1721 OTF_SYM_TAG (XCAR (val), tag);
1746 spec->features[i][j++] = negative ? tag & 0x80000000 : tag; 1722 spec->features[i][j++] = negative ? tag & 0x80000000 : tag;
1747 } 1723 }
1748 } 1724 }
1749 spec->nfeatures[i] = j; 1725 spec->nfeatures[i] = j;
1750 } 1726 }
1751 return spec; 1727 return spec;
@@ -1769,16 +1745,16 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1769 CGPoint points[6]; 1745 CGPoint points[6];
1770 } numeric_traits[] = 1746 } numeric_traits[] =
1771 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT, 1747 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT,
1772 {{-0.4, 50}, /* light */ 1748 {{-0.4, 50}, /* light */
1773 {-0.24, 87.5}, /* (semi-light + normal) / 2 */ 1749 {-0.24, 87.5}, /* (semi-light + normal) / 2 */
1774 {0, 100}, /* normal */ 1750 {0, 100}, /* normal */
1775 {0.24, 140}, /* (semi-bold + normal) / 2 */ 1751 {0.24, 140}, /* (semi-bold + normal) / 2 */
1776 {0.4, 200}, /* bold */ 1752 {0.4, 200}, /* bold */
1777 {CGFLOAT_MAX, CGFLOAT_MAX}}}, 1753 {CGFLOAT_MAX, CGFLOAT_MAX}}},
1778 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT, 1754 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT,
1779 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}, 1755 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}},
1780 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT, 1756 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT,
1781 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; 1757 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}};
1782 1758
1783 registry = AREF (spec, FONT_REGISTRY_INDEX); 1759 registry = AREF (spec, FONT_REGISTRY_INDEX);
1784 if (NILP (registry) 1760 if (NILP (registry)
@@ -1792,17 +1768,17 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1792 1768
1793 cf_charset_idx = macfont_get_charset (registry); 1769 cf_charset_idx = macfont_get_charset (registry);
1794 if (cf_charset_idx < 0) 1770 if (cf_charset_idx < 0)
1795 goto err; 1771 goto err;
1796 charset = cf_charset_table[cf_charset_idx].cf_charset; 1772 charset = cf_charset_table[cf_charset_idx].cf_charset;
1797 charset_string = cf_charset_table[cf_charset_idx].cf_charset_string; 1773 charset_string = cf_charset_table[cf_charset_idx].cf_charset_string;
1798 lang = cf_charset_table[cf_charset_idx].lang; 1774 lang = cf_charset_table[cf_charset_idx].lang;
1799 if (lang) 1775 if (lang)
1800 { 1776 {
1801 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 1777 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
1802 if (! langarray) 1778 if (! langarray)
1803 goto err; 1779 goto err;
1804 CFArrayAppendValue (langarray, lang); 1780 CFArrayAppendValue (langarray, lang);
1805 } 1781 }
1806 } 1782 }
1807 1783
1808 for (extra = AREF (spec, FONT_EXTRA_INDEX); 1784 for (extra = AREF (spec, FONT_EXTRA_INDEX);
@@ -1813,35 +1789,35 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1813 tmp = XCAR (extra); 1789 tmp = XCAR (extra);
1814 key = XCAR (tmp), val = XCDR (tmp); 1790 key = XCAR (tmp), val = XCDR (tmp);
1815 if (EQ (key, QClang)) 1791 if (EQ (key, QClang))
1816 { 1792 {
1817 if (! langarray) 1793 if (! langarray)
1818 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 1794 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
1819 if (! langarray) 1795 if (! langarray)
1820 goto err; 1796 goto err;
1821 if (SYMBOLP (val)) 1797 if (SYMBOLP (val))
1822 val = list1 (val); 1798 val = list1 (val);
1823 for (; CONSP (val); val = XCDR (val)) 1799 for (; CONSP (val); val = XCDR (val))
1824 if (SYMBOLP (XCAR (val))) 1800 if (SYMBOLP (XCAR (val)))
1825 { 1801 {
1826 CFStringRef lang = 1802 CFStringRef lang =
1827 cfstring_create_with_string_noencode (SYMBOL_NAME 1803 cfstring_create_with_string_noencode (SYMBOL_NAME
1828 (XCAR (val))); 1804 (XCAR (val)));
1829 1805
1830 if (lang == NULL) 1806 if (lang == NULL)
1831 goto err; 1807 goto err;
1832 CFArrayAppendValue (langarray, lang); 1808 CFArrayAppendValue (langarray, lang);
1833 CFRelease (lang); 1809 CFRelease (lang);
1834 } 1810 }
1835 } 1811 }
1836 else if (EQ (key, QCotf)) 1812 else if (EQ (key, QCotf))
1837 { 1813 {
1838 otspec = macfont_get_open_type_spec (val); 1814 otspec = macfont_get_open_type_spec (val);
1839 if (! otspec) 1815 if (! otspec)
1840 goto err; 1816 goto err;
1841 script = otspec->script; 1817 script = otspec->script;
1842 } 1818 }
1843 else if (EQ (key, QCscript)) 1819 else if (EQ (key, QCscript))
1844 script = val; 1820 script = val;
1845 } 1821 }
1846 1822
1847 if (! NILP (script) && ! charset) 1823 if (! NILP (script) && ! charset)
@@ -1849,40 +1825,40 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1849 Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars); 1825 Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars);
1850 1826
1851 if (CONSP (chars) && CONSP (CDR (chars))) 1827 if (CONSP (chars) && CONSP (CDR (chars)))
1852 { 1828 {
1853 CFMutableStringRef string = CFStringCreateMutable (NULL, 0); 1829 CFMutableStringRef string = CFStringCreateMutable (NULL, 0);
1854 CFMutableCharacterSetRef cs = CFCharacterSetCreateMutable (NULL); 1830 CFMutableCharacterSetRef cs = CFCharacterSetCreateMutable (NULL);
1855 1831
1856 if (! string || !cs) 1832 if (! string || !cs)
1857 { 1833 {
1858 if (string) 1834 if (string)
1859 CFRelease (string); 1835 CFRelease (string);
1860 else if (cs) 1836 else if (cs)
1861 CFRelease (cs); 1837 CFRelease (cs);
1862 goto err; 1838 goto err;
1863 } 1839 }
1864 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) 1840 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
1865 if (CHARACTERP (XCAR (chars))) 1841 if (CHARACTERP (XCAR (chars)))
1866 { 1842 {
1867 UniChar unichars[2]; 1843 UniChar unichars[2];
1868 CFIndex count = 1844 CFIndex count =
1869 macfont_store_utf32char_to_unichars (XFASTINT (XCAR (chars)), 1845 macfont_store_utf32char_to_unichars (XFASTINT (XCAR (chars)),
1870 unichars); 1846 unichars);
1871 CFRange range = CFRangeMake (XFASTINT (XCAR (chars)), 1); 1847 CFRange range = CFRangeMake (XFASTINT (XCAR (chars)), 1);
1872 1848
1873 CFStringAppendCharacters (string, unichars, count); 1849 CFStringAppendCharacters (string, unichars, count);
1874 CFCharacterSetAddCharactersInRange (cs, range); 1850 CFCharacterSetAddCharactersInRange (cs, range);
1875 } 1851 }
1876 charset = cs; 1852 charset = cs;
1877 /* CFCharacterSetCreateWithCharactersInString does not 1853 /* CFCharacterSetCreateWithCharactersInString does not
1878 handle surrogate pairs properly as of Mac OS X 10.5. */ 1854 handle surrogate pairs properly as of Mac OS X 10.5. */
1879 charset_string = string; 1855 charset_string = string;
1880 } 1856 }
1881 } 1857 }
1882 1858
1883 attributes = CFDictionaryCreateMutable (NULL, 0, 1859 attributes = CFDictionaryCreateMutable (NULL, 0,
1884 &kCFTypeDictionaryKeyCallBacks, 1860 &kCFTypeDictionaryKeyCallBacks,
1885 &kCFTypeDictionaryValueCallBacks); 1861 &kCFTypeDictionaryValueCallBacks);
1886 if (! attributes) 1862 if (! attributes)
1887 goto err; 1863 goto err;
1888 1864
@@ -1892,15 +1868,15 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1892 CFStringRef family = macfont_create_family_with_symbol (tmp); 1868 CFStringRef family = macfont_create_family_with_symbol (tmp);
1893 1869
1894 if (! family) 1870 if (! family)
1895 goto err; 1871 goto err;
1896 CFDictionaryAddValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE, 1872 CFDictionaryAddValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE,
1897 family); 1873 family);
1898 CFRelease (family); 1874 CFRelease (family);
1899 } 1875 }
1900 1876
1901 traits = CFDictionaryCreateMutable (NULL, 4, 1877 traits = CFDictionaryCreateMutable (NULL, 4,
1902 &kCFTypeDictionaryKeyCallBacks, 1878 &kCFTypeDictionaryKeyCallBacks,
1903 &kCFTypeDictionaryValueCallBacks); 1879 &kCFTypeDictionaryValueCallBacks);
1904 if (! traits) 1880 if (! traits)
1905 goto err; 1881 goto err;
1906 1882
@@ -1908,40 +1884,40 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1908 { 1884 {
1909 tmp = AREF (spec, numeric_traits[i].index); 1885 tmp = AREF (spec, numeric_traits[i].index);
1910 if (INTEGERP (tmp)) 1886 if (INTEGERP (tmp))
1911 { 1887 {
1912 CGPoint *point = numeric_traits[i].points; 1888 CGPoint *point = numeric_traits[i].points;
1913 CGFloat floatval = (XINT (tmp) >> 8); // XXX 1889 CGFloat floatval = (XINT (tmp) >> 8); // XXX
1914 CFNumberRef num; 1890 CFNumberRef num;
1915 1891
1916 while (point->y < floatval) 1892 while (point->y < floatval)
1917 point++; 1893 point++;
1918 if (point == numeric_traits[i].points) 1894 if (point == numeric_traits[i].points)
1919 point++; 1895 point++;
1920 else if (point->y == CGFLOAT_MAX) 1896 else if (point->y == CGFLOAT_MAX)
1921 point--; 1897 point--;
1922 floatval = (point - 1)->x + ((floatval - (point - 1)->y) 1898 floatval = (point - 1)->x + ((floatval - (point - 1)->y)
1923 * ((point->x - (point - 1)->x) 1899 * ((point->x - (point - 1)->x)
1924 / (point->y - (point - 1)->y))); 1900 / (point->y - (point - 1)->y)));
1925 if (floatval > 1.0) 1901 if (floatval > 1.0)
1926 floatval = 1.0; 1902 floatval = 1.0;
1927 else if (floatval < -1.0) 1903 else if (floatval < -1.0)
1928 floatval = -1.0; 1904 floatval = -1.0;
1929 num = CFNumberCreate (NULL, kCFNumberCGFloatType, &floatval); 1905 num = CFNumberCreate (NULL, kCFNumberCGFloatType, &floatval);
1930 if (! num) 1906 if (! num)
1931 goto err; 1907 goto err;
1932 CFDictionaryAddValue (traits, numeric_traits[i].trait, num); 1908 CFDictionaryAddValue (traits, numeric_traits[i].trait, num);
1933 CFRelease (num); 1909 CFRelease (num);
1934 } 1910 }
1935 } 1911 }
1936 if (CFDictionaryGetCount (traits)) 1912 if (CFDictionaryGetCount (traits))
1937 CFDictionaryAddValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE, traits); 1913 CFDictionaryAddValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE, traits);
1938 1914
1939 if (charset) 1915 if (charset)
1940 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE, 1916 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE,
1941 charset); 1917 charset);
1942 if (charset_string) 1918 if (charset_string)
1943 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE, 1919 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE,
1944 charset_string); 1920 charset_string);
1945 if (langarray) 1921 if (langarray)
1946 CFDictionaryAddValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE, langarray); 1922 CFDictionaryAddValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE, langarray);
1947 1923
@@ -1962,9 +1938,9 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1962 if (otspec) 1938 if (otspec)
1963 { 1939 {
1964 if (otspec->nfeatures[0] > 0) 1940 if (otspec->nfeatures[0] > 0)
1965 free (otspec->features[0]); 1941 free (otspec->features[0]);
1966 if (otspec->nfeatures[1] > 0) 1942 if (otspec->nfeatures[1] > 0)
1967 free (otspec->features[1]); 1943 free (otspec->features[1]);
1968 free (otspec); 1944 free (otspec);
1969 } 1945 }
1970 1946
@@ -1973,38 +1949,38 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1973 1949
1974static Boolean 1950static Boolean
1975macfont_supports_charset_and_languages_p (FontDescriptorRef desc, 1951macfont_supports_charset_and_languages_p (FontDescriptorRef desc,
1976 CFCharacterSetRef charset, 1952 CFCharacterSetRef charset,
1977 Lisp_Object chars, 1953 Lisp_Object chars,
1978 CFArrayRef languages) 1954 CFArrayRef languages)
1979{ 1955{
1980 Boolean result = true; 1956 Boolean result = true;
1981 1957
1982 if (charset || VECTORP (chars)) 1958 if (charset || VECTORP (chars))
1983 { 1959 {
1984 CFCharacterSetRef desc_charset = 1960 CFCharacterSetRef desc_charset =
1985 mac_font_descriptor_copy_attribute (desc, 1961 mac_font_descriptor_copy_attribute (desc,
1986 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 1962 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
1987 1963
1988 if (desc_charset == NULL) 1964 if (desc_charset == NULL)
1989 result = false; 1965 result = false;
1990 else 1966 else
1991 { 1967 {
1992 if (charset) 1968 if (charset)
1993 result = CFCharacterSetIsSupersetOfSet (desc_charset, charset); 1969 result = CFCharacterSetIsSupersetOfSet (desc_charset, charset);
1994 else /* VECTORP (chars) */ 1970 else /* VECTORP (chars) */
1995 { 1971 {
1996 ptrdiff_t j; 1972 ptrdiff_t j;
1997 1973
1998 for (j = 0; j < ASIZE (chars); j++) 1974 for (j = 0; j < ASIZE (chars); j++)
1999 if (TYPE_RANGED_INTEGERP (UTF32Char, AREF (chars, j)) 1975 if (TYPE_RANGED_INTEGERP (UTF32Char, AREF (chars, j))
2000 && CFCharacterSetIsLongCharacterMember (desc_charset, 1976 && CFCharacterSetIsLongCharacterMember (desc_charset,
2001 XFASTINT (AREF (chars, j)))) 1977 XFASTINT (AREF (chars, j))))
2002 break; 1978 break;
2003 if (j == ASIZE (chars)) 1979 if (j == ASIZE (chars))
2004 result = false; 1980 result = false;
2005 } 1981 }
2006 CFRelease (desc_charset); 1982 CFRelease (desc_charset);
2007 } 1983 }
2008 } 1984 }
2009 if (result && languages) 1985 if (result && languages)
2010 result = mac_font_descriptor_supports_languages (desc, languages); 1986 result = mac_font_descriptor_supports_languages (desc, languages);
@@ -2012,38 +1988,49 @@ macfont_supports_charset_and_languages_p (FontDescriptorRef desc,
2012 return result; 1988 return result;
2013} 1989}
2014 1990
2015static CFIndex 1991static int
2016macfont_closest_traits_index (CFArrayRef traits_array, 1992macfont_traits_distance (FontSymbolicTraits sym_traits1,
2017 FontSymbolicTraits target) 1993 FontSymbolicTraits sym_traits2)
1994{
1995 FontSymbolicTraits diff = (sym_traits1 ^ sym_traits2);
1996 int distance = 0;
1997
1998 /* We prefer synthetic bold of italic to synthetic italic of bold
1999 when both bold and italic are available but bold-italic is not
2000 available. */
2001 if (diff & MAC_FONT_TRAIT_BOLD)
2002 distance |= (1 << 0);
2003 if (diff & MAC_FONT_TRAIT_ITALIC)
2004 distance |= (1 << 1);
2005 if (diff & MAC_FONT_TRAIT_MONO_SPACE)
2006 distance |= (1 << 2);
2007
2008 return distance;
2009}
2010
2011static Boolean
2012macfont_closest_traits_index_p (CFArrayRef traits_array,
2013 FontSymbolicTraits target,
2014 CFIndex index)
2018{ 2015{
2019 CFIndex i, result = -1, count = CFArrayGetCount (traits_array); 2016 CFIndex i, count = CFArrayGetCount (traits_array);
2020 int min_distance = (1 << 3); 2017 FontSymbolicTraits traits;
2018 int my_distance;
2019
2020 traits = ((FontSymbolicTraits) (uintptr_t)
2021 CFArrayGetValueAtIndex (traits_array, index));
2022 my_distance = macfont_traits_distance (target, traits);
2021 2023
2022 for (i = 0; i < count; i++) 2024 for (i = 0; i < count; i++)
2023 { 2025 if (i != index)
2024 FontSymbolicTraits traits, diff; 2026 {
2025 int distance = 0; 2027 traits = ((FontSymbolicTraits) (uintptr_t)
2026 2028 CFArrayGetValueAtIndex (traits_array, i));
2027 traits = ((FontSymbolicTraits) (uintptr_t) 2029 if (macfont_traits_distance (target, traits) < my_distance)
2028 CFArrayGetValueAtIndex (traits_array, i)); 2030 return false;
2029 diff = (target ^ traits); 2031 }
2030 /* We prefer synthetic bold of italic to synthetic italic of
2031 bold when both bold and italic are available but bold-italic
2032 is not available. */
2033 if (diff & MAC_FONT_TRAIT_BOLD)
2034 distance |= (1 << 0);
2035 if (diff & MAC_FONT_TRAIT_ITALIC)
2036 distance |= (1 << 1);
2037 if (diff & MAC_FONT_TRAIT_MONO_SPACE)
2038 distance |= (1 << 2);
2039 if (distance < min_distance)
2040 {
2041 min_distance = distance;
2042 result = i;
2043 }
2044 }
2045 2032
2046 return result; 2033 return true;
2047} 2034}
2048 2035
2049static Lisp_Object 2036static Lisp_Object
@@ -2068,7 +2055,7 @@ macfont_list (struct frame *f, Lisp_Object spec)
2068 { 2055 {
2069 family_name = macfont_create_family_with_symbol (family); 2056 family_name = macfont_create_family_with_symbol (family);
2070 if (family_name == NULL) 2057 if (family_name == NULL)
2071 goto finish; 2058 goto finish;
2072 } 2059 }
2073 2060
2074 attributes = macfont_create_attributes_with_spec (spec); 2061 attributes = macfont_create_attributes_with_spec (spec);
@@ -2081,14 +2068,14 @@ macfont_list (struct frame *f, Lisp_Object spec)
2081 spacing = XINT (AREF (spec, FONT_SPACING_INDEX)); 2068 spacing = XINT (AREF (spec, FONT_SPACING_INDEX));
2082 2069
2083 traits = ((CFMutableDictionaryRef) 2070 traits = ((CFMutableDictionaryRef)
2084 CFDictionaryGetValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE)); 2071 CFDictionaryGetValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE));
2085 2072
2086 n = FONT_SLANT_NUMERIC (spec); 2073 n = FONT_SLANT_NUMERIC (spec);
2087 if (n < 0 || n == FONT_SLANT_SYNTHETIC_ITALIC) 2074 if (n < 0 || n == FONT_SLANT_SYNTHETIC_ITALIC)
2088 { 2075 {
2089 synth_sym_traits |= MAC_FONT_TRAIT_ITALIC; 2076 synth_sym_traits |= MAC_FONT_TRAIT_ITALIC;
2090 if (traits) 2077 if (traits)
2091 CFDictionaryRemoveValue (traits, MAC_FONT_SLANT_TRAIT); 2078 CFDictionaryRemoveValue (traits, MAC_FONT_SLANT_TRAIT);
2092 } 2079 }
2093 2080
2094 n = FONT_WEIGHT_NUMERIC (spec); 2081 n = FONT_WEIGHT_NUMERIC (spec);
@@ -2096,7 +2083,7 @@ macfont_list (struct frame *f, Lisp_Object spec)
2096 { 2083 {
2097 synth_sym_traits |= MAC_FONT_TRAIT_BOLD; 2084 synth_sym_traits |= MAC_FONT_TRAIT_BOLD;
2098 if (traits) 2085 if (traits)
2099 CFDictionaryRemoveValue (traits, MAC_FONT_WEIGHT_TRAIT); 2086 CFDictionaryRemoveValue (traits, MAC_FONT_WEIGHT_TRAIT);
2100 } 2087 }
2101 2088
2102 if (languages 2089 if (languages
@@ -2105,15 +2092,15 @@ macfont_list (struct frame *f, Lisp_Object spec)
2105 CFStringRef language = CFArrayGetValueAtIndex (languages, 0); 2092 CFStringRef language = CFArrayGetValueAtIndex (languages, 0);
2106 2093
2107 if (CFStringHasPrefix (language, CFSTR ("ja")) 2094 if (CFStringHasPrefix (language, CFSTR ("ja"))
2108 || CFStringHasPrefix (language, CFSTR ("ko")) 2095 || CFStringHasPrefix (language, CFSTR ("ko"))
2109 || CFStringHasPrefix (language, CFSTR ("zh"))) 2096 || CFStringHasPrefix (language, CFSTR ("zh")))
2110 synth_sym_traits |= MAC_FONT_TRAIT_MONO_SPACE; 2097 synth_sym_traits |= MAC_FONT_TRAIT_MONO_SPACE;
2111 } 2098 }
2112 2099
2113 /* Create array of families. */ 2100 /* Create array of families. */
2114 if (family_name) 2101 if (family_name)
2115 families = CFArrayCreate (NULL, (const void **) &family_name, 2102 families = CFArrayCreate (NULL, (const void **) &family_name,
2116 1, &kCFTypeArrayCallBacks); 2103 1, &kCFTypeArrayCallBacks);
2117 else 2104 else
2118 { 2105 {
2119 CFStringRef pref_family; 2106 CFStringRef pref_family;
@@ -2121,46 +2108,46 @@ macfont_list (struct frame *f, Lisp_Object spec)
2121 2108
2122 families = mac_font_create_available_families (); 2109 families = mac_font_create_available_families ();
2123 if (families == NULL) 2110 if (families == NULL)
2124 goto err; 2111 goto err;
2125 2112
2126 families_count = CFArrayGetCount (families); 2113 families_count = CFArrayGetCount (families);
2127 2114
2128 /* Move preferred family to the front if exists. */ 2115 /* Move preferred family to the front if exists. */
2129 pref_family = 2116 pref_family =
2130 mac_font_create_preferred_family_for_attributes (attributes); 2117 mac_font_create_preferred_family_for_attributes (attributes);
2131 if (pref_family) 2118 if (pref_family)
2132 { 2119 {
2133 pref_family_index = 2120 pref_family_index =
2134 CFArrayGetFirstIndexOfValue (families, 2121 CFArrayGetFirstIndexOfValue (families,
2135 CFRangeMake (0, families_count), 2122 CFRangeMake (0, families_count),
2136 pref_family); 2123 pref_family);
2137 CFRelease (pref_family); 2124 CFRelease (pref_family);
2138 } 2125 }
2139 if (pref_family_index > 0) 2126 if (pref_family_index > 0)
2140 { 2127 {
2141 CFMutableArrayRef mutable_families = 2128 CFMutableArrayRef mutable_families =
2142 CFArrayCreateMutable (NULL, families_count, &kCFTypeArrayCallBacks); 2129 CFArrayCreateMutable (NULL, families_count, &kCFTypeArrayCallBacks);
2143 2130
2144 if (mutable_families) 2131 if (mutable_families)
2145 { 2132 {
2146 CFArrayAppendValue (mutable_families, 2133 CFArrayAppendValue (mutable_families,
2147 CFArrayGetValueAtIndex (families, 2134 CFArrayGetValueAtIndex (families,
2148 pref_family_index)); 2135 pref_family_index));
2149 CFArrayAppendArray (mutable_families, families, 2136 CFArrayAppendArray (mutable_families, families,
2150 CFRangeMake (0, pref_family_index)); 2137 CFRangeMake (0, pref_family_index));
2151 if (pref_family_index + 1 < families_count) 2138 if (pref_family_index + 1 < families_count)
2152 CFArrayAppendArray (mutable_families, families, 2139 CFArrayAppendArray (mutable_families, families,
2153 CFRangeMake (pref_family_index + 1, 2140 CFRangeMake (pref_family_index + 1,
2154 families_count 2141 families_count
2155 - (pref_family_index + 1))); 2142 - (pref_family_index + 1)));
2156 CFRelease (families); 2143 CFRelease (families);
2157 families = mutable_families; 2144 families = mutable_families;
2158 } 2145 }
2159 } 2146 }
2160 } 2147 }
2161 2148
2162 charset = CFDictionaryGetValue (attributes, 2149 charset = CFDictionaryGetValue (attributes,
2163 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 2150 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
2164 if (charset) 2151 if (charset)
2165 { 2152 {
2166 CFRetain (charset); 2153 CFRetain (charset);
@@ -2170,11 +2157,11 @@ macfont_list (struct frame *f, Lisp_Object spec)
2170 { 2157 {
2171 val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX)); 2158 val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX));
2172 if (! NILP (val)) 2159 if (! NILP (val))
2173 { 2160 {
2174 val = assq_no_quit (XCDR (val), Vscript_representative_chars); 2161 val = assq_no_quit (XCDR (val), Vscript_representative_chars);
2175 if (CONSP (val) && VECTORP (XCDR (val))) 2162 if (CONSP (val) && VECTORP (XCDR (val)))
2176 chars = XCDR (val); 2163 chars = XCDR (val);
2177 } 2164 }
2178 val = Qnil; 2165 val = Qnil;
2179 } 2166 }
2180 2167
@@ -2198,151 +2185,152 @@ macfont_list (struct frame *f, Lisp_Object spec)
2198 int j; 2185 int j;
2199 2186
2200 CFDictionarySetValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE, 2187 CFDictionarySetValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE,
2201 family_name); 2188 family_name);
2202 pat_desc = mac_font_descriptor_create_with_attributes (attributes); 2189 pat_desc = mac_font_descriptor_create_with_attributes (attributes);
2203 if (! pat_desc) 2190 if (! pat_desc)
2204 goto err; 2191 goto err;
2205 2192
2206 /* CTFontDescriptorCreateMatchingFontDescriptors on Mac OS X 2193 /* CTFontDescriptorCreateMatchingFontDescriptors on Mac OS X
2207 10.7 returns NULL if pat_desc represents the LastResort font. 2194 10.7 returns NULL if pat_desc represents the LastResort font.
2208 So we use CTFontDescriptorCreateMatchingFontDescriptor (no 2195 So we use CTFontDescriptorCreateMatchingFontDescriptor (no
2209 trailing "s") for such a font. */ 2196 trailing "s") for such a font. */
2210 if (!CFEqual (family_name, CFSTR ("LastResort"))) 2197 if (!CFEqual (family_name, CFSTR ("LastResort")))
2211 descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc, 2198 descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc,
2212 NULL); 2199 NULL);
2213 else 2200 else
2214 { 2201 {
2215 FontDescriptorRef lr_desc = 2202 FontDescriptorRef lr_desc =
2216 mac_font_descriptor_create_matching_font_descriptor (pat_desc, 2203 mac_font_descriptor_create_matching_font_descriptor (pat_desc,
2217 NULL); 2204 NULL);
2218 if (lr_desc) 2205 if (lr_desc)
2219 { 2206 {
2220 descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1, 2207 descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1,
2221 &kCFTypeArrayCallBacks); 2208 &kCFTypeArrayCallBacks);
2222 CFRelease (lr_desc); 2209 CFRelease (lr_desc);
2223 } 2210 }
2224 else 2211 else
2225 descs = NULL; 2212 descs = NULL;
2226 } 2213 }
2227 CFRelease (pat_desc); 2214 CFRelease (pat_desc);
2228 if (! descs) 2215 if (! descs)
2229 goto err; 2216 goto err;
2230 2217
2231 descs_count = CFArrayGetCount (descs); 2218 descs_count = CFArrayGetCount (descs);
2232 if (descs_count == 0 2219 if (descs_count == 0
2233 || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0), 2220 || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0),
2234 charset, chars, 2221 charset, chars,
2235 languages)) 2222 languages))
2236 { 2223 {
2237 CFRelease (descs); 2224 CFRelease (descs);
2238 continue; 2225 continue;
2239 } 2226 }
2240 2227
2241 filtered_descs = 2228 filtered_descs =
2242 CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks); 2229 CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks);
2243 traits_array = CFArrayCreateMutable (NULL, descs_count, NULL); 2230 traits_array = CFArrayCreateMutable (NULL, descs_count, NULL);
2244 for (j = 0; j < descs_count; j++) 2231 for (j = 0; j < descs_count; j++)
2245 { 2232 {
2246 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j); 2233 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
2247 CFDictionaryRef dict; 2234 CFDictionaryRef dict;
2248 CFNumberRef num; 2235 CFNumberRef num;
2249 FontSymbolicTraits sym_traits; 2236 FontSymbolicTraits sym_traits;
2250 2237
2251 dict = mac_font_descriptor_copy_attribute (desc, 2238 dict = mac_font_descriptor_copy_attribute (desc,
2252 MAC_FONT_TRAITS_ATTRIBUTE); 2239 MAC_FONT_TRAITS_ATTRIBUTE);
2253 if (dict == NULL) 2240 if (dict == NULL)
2254 continue; 2241 continue;
2255 2242
2256 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 2243 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
2257 CFRelease (dict); 2244 CFRelease (dict);
2258 if (num == NULL 2245 if (num == NULL
2259 || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits)) 2246 || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits))
2260 continue; 2247 continue;
2261 2248
2262 if (spacing >= 0 2249 if (spacing >= 0
2263 && !(synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 2250 && !(synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
2264 && (((sym_traits & MAC_FONT_TRAIT_MONO_SPACE) != 0) 2251 && (((sym_traits & MAC_FONT_TRAIT_MONO_SPACE) != 0)
2265 != (spacing >= FONT_SPACING_MONO))) 2252 != (spacing >= FONT_SPACING_MONO)))
2266 continue; 2253 continue;
2267 2254
2268 /* Don't use a color bitmap font unless its family is 2255 /* Don't use a color bitmap font unless its family is
2269 explicitly specified. */ 2256 explicitly specified. */
2270 if ((sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) && NILP (family)) 2257 if ((sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) && NILP (family))
2271 continue; 2258 continue;
2272 2259
2273 if (j > 0 2260 if (j > 0
2274 && !macfont_supports_charset_and_languages_p (desc, charset, 2261 && !macfont_supports_charset_and_languages_p (desc, charset,
2275 chars, languages)) 2262 chars, languages))
2276 continue; 2263 continue;
2277 2264
2278 CFArrayAppendValue (filtered_descs, desc); 2265 CFArrayAppendValue (filtered_descs, desc);
2279 CFArrayAppendValue (traits_array, 2266 CFArrayAppendValue (traits_array,
2280 (const void *) (uintptr_t) sym_traits); 2267 (const void *) (uintptr_t) sym_traits);
2281 } 2268 }
2282 2269
2283 CFRelease (descs); 2270 CFRelease (descs);
2284 descs = filtered_descs; 2271 descs = filtered_descs;
2285 descs_count = CFArrayGetCount (descs); 2272 descs_count = CFArrayGetCount (descs);
2286 2273
2287 for (j = 0; j < descs_count; j++) 2274 for (j = 0; j < descs_count; j++)
2288 { 2275 {
2289 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j); 2276 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
2290 FontSymbolicTraits sym_traits = 2277 FontSymbolicTraits sym_traits =
2291 ((FontSymbolicTraits) (uintptr_t) 2278 ((FontSymbolicTraits) (uintptr_t)
2292 CFArrayGetValueAtIndex (traits_array, j)); 2279 CFArrayGetValueAtIndex (traits_array, j));
2293 FontSymbolicTraits mask_min, mask_max, imask, bmask, mmask; 2280 FontSymbolicTraits mask_min, mask_max, imask, bmask, mmask;
2294 2281
2295 mask_min = ((synth_sym_traits ^ sym_traits) 2282 mask_min = ((synth_sym_traits ^ sym_traits)
2296 & (MAC_FONT_TRAIT_ITALIC | MAC_FONT_TRAIT_BOLD)); 2283 & (MAC_FONT_TRAIT_ITALIC | MAC_FONT_TRAIT_BOLD));
2297 if (FONT_SLANT_NUMERIC (spec) < 0) 2284 if (FONT_SLANT_NUMERIC (spec) < 0)
2298 mask_min &= ~MAC_FONT_TRAIT_ITALIC; 2285 mask_min &= ~MAC_FONT_TRAIT_ITALIC;
2299 if (FONT_WEIGHT_NUMERIC (spec) < 0) 2286 if (FONT_WEIGHT_NUMERIC (spec) < 0)
2300 mask_min &= ~MAC_FONT_TRAIT_BOLD; 2287 mask_min &= ~MAC_FONT_TRAIT_BOLD;
2301 2288
2302 mask_max = (synth_sym_traits & ~sym_traits); 2289 mask_max = (synth_sym_traits & ~sym_traits);
2303 /* Synthetic bold does not work for bitmap-only fonts on Mac 2290 /* Synthetic bold does not work for bitmap-only fonts on Mac
2304 OS X 10.6. */ 2291 OS X 10.6. */
2305 if ((mask_min ^ mask_max) & MAC_FONT_TRAIT_BOLD) 2292 if ((mask_min ^ mask_max) & MAC_FONT_TRAIT_BOLD)
2306 { 2293 {
2307 CFNumberRef format = 2294 CFNumberRef format =
2308 mac_font_descriptor_copy_attribute (desc, 2295 mac_font_descriptor_copy_attribute (desc,
2309 MAC_FONT_FORMAT_ATTRIBUTE); 2296 MAC_FONT_FORMAT_ATTRIBUTE);
2310 2297
2311 if (format) 2298 if (format)
2312 { 2299 {
2313 uint32_t format_val; 2300 uint32_t format_val;
2314 2301
2315 if (CFNumberGetValue (format, kCFNumberSInt32Type, 2302 if (CFNumberGetValue (format, kCFNumberSInt32Type,
2316 &format_val) 2303 &format_val)
2317 && format_val == MAC_FONT_FORMAT_BITMAP) 2304 && format_val == MAC_FONT_FORMAT_BITMAP)
2318 mask_max &= ~MAC_FONT_TRAIT_BOLD; 2305 mask_max &= ~MAC_FONT_TRAIT_BOLD;
2319 } 2306 }
2320 } 2307 }
2321 if (spacing >= 0) 2308 if (spacing >= 0)
2322 mask_min |= (mask_max & MAC_FONT_TRAIT_MONO_SPACE); 2309 mask_min |= (mask_max & MAC_FONT_TRAIT_MONO_SPACE);
2323 2310
2324 for (mmask = (mask_min & MAC_FONT_TRAIT_MONO_SPACE); 2311 for (mmask = (mask_min & MAC_FONT_TRAIT_MONO_SPACE);
2325 mmask <= (mask_max & MAC_FONT_TRAIT_MONO_SPACE); 2312 mmask <= (mask_max & MAC_FONT_TRAIT_MONO_SPACE);
2326 mmask += MAC_FONT_TRAIT_MONO_SPACE) 2313 mmask += MAC_FONT_TRAIT_MONO_SPACE)
2327 for (bmask = (mask_min & MAC_FONT_TRAIT_BOLD); 2314 for (bmask = (mask_min & MAC_FONT_TRAIT_BOLD);
2328 bmask <= (mask_max & MAC_FONT_TRAIT_BOLD); 2315 bmask <= (mask_max & MAC_FONT_TRAIT_BOLD);
2329 bmask += MAC_FONT_TRAIT_BOLD) 2316 bmask += MAC_FONT_TRAIT_BOLD)
2330 for (imask = (mask_min & MAC_FONT_TRAIT_ITALIC); 2317 for (imask = (mask_min & MAC_FONT_TRAIT_ITALIC);
2331 imask <= (mask_max & MAC_FONT_TRAIT_ITALIC); 2318 imask <= (mask_max & MAC_FONT_TRAIT_ITALIC);
2332 imask += MAC_FONT_TRAIT_ITALIC) 2319 imask += MAC_FONT_TRAIT_ITALIC)
2333 { 2320 {
2334 FontSymbolicTraits synth = (imask | bmask | mmask); 2321 FontSymbolicTraits synth = (imask | bmask | mmask);
2335 2322
2336 if (synth == 0 2323 if (synth == 0
2337 || j == macfont_closest_traits_index (traits_array, 2324 || macfont_closest_traits_index_p (traits_array,
2338 (sym_traits | synth))) 2325 (sym_traits | synth),
2339 { 2326 j))
2340 entity = macfont_descriptor_entity (desc, extra, synth); 2327 {
2341 if (! NILP (entity)) 2328 entity = macfont_descriptor_entity (desc, extra, synth);
2342 val = Fcons (entity, val); 2329 if (! NILP (entity))
2343 } 2330 val = Fcons (entity, val);
2344 } 2331 }
2345 } 2332 }
2333 }
2346 2334
2347 CFRelease (traits_array); 2335 CFRelease (traits_array);
2348 CFRelease (descs); 2336 CFRelease (descs);
@@ -2384,13 +2372,13 @@ macfont_match (struct frame * frame, Lisp_Object spec)
2384 if (pat_desc) 2372 if (pat_desc)
2385 { 2373 {
2386 desc = mac_font_descriptor_create_matching_font_descriptor (pat_desc, 2374 desc = mac_font_descriptor_create_matching_font_descriptor (pat_desc,
2387 NULL); 2375 NULL);
2388 CFRelease (pat_desc); 2376 CFRelease (pat_desc);
2389 } 2377 }
2390 if (desc) 2378 if (desc)
2391 { 2379 {
2392 entity = macfont_descriptor_entity (desc, AREF (spec, FONT_EXTRA_INDEX), 2380 entity = macfont_descriptor_entity (desc, AREF (spec, FONT_EXTRA_INDEX),
2393 0); 2381 0);
2394 CFRelease (desc); 2382 CFRelease (desc);
2395 } 2383 }
2396 unblock_input (); 2384 unblock_input ();
@@ -2413,7 +2401,7 @@ macfont_list_family (struct frame *frame)
2413 CFIndex i, count = CFArrayGetCount (families); 2401 CFIndex i, count = CFArrayGetCount (families);
2414 2402
2415 for (i = 0; i < count; i++) 2403 for (i = 0; i < count; i++)
2416 list = Fcons (macfont_intern_prop_cfstring (CFArrayGetValueAtIndex (families, i)), list); 2404 list = Fcons (macfont_intern_prop_cfstring (CFArrayGetValueAtIndex (families, i)), list);
2417 CFRelease (families); 2405 CFRelease (families);
2418 } 2406 }
2419 2407
@@ -2426,7 +2414,7 @@ static void
2426macfont_free_entity (Lisp_Object entity) 2414macfont_free_entity (Lisp_Object entity)
2427{ 2415{
2428 Lisp_Object val = assq_no_quit (QCfont_entity, 2416 Lisp_Object val = assq_no_quit (QCfont_entity,
2429 AREF (entity, FONT_EXTRA_INDEX)); 2417 AREF (entity, FONT_EXTRA_INDEX));
2430 CFStringRef name = XSAVE_POINTER (XCDR (val), 0); 2418 CFStringRef name = XSAVE_POINTER (XCDR (val), 0);
2431 2419
2432 block_input (); 2420 block_input ();
@@ -2444,7 +2432,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2444 int size; 2432 int size;
2445 FontRef macfont; 2433 FontRef macfont;
2446 FontSymbolicTraits sym_traits; 2434 FontSymbolicTraits sym_traits;
2447 int i, total_width; 2435 char name[256];
2436 int len, i, total_width;
2448 CGGlyph glyph; 2437 CGGlyph glyph;
2449 CGFloat ascent, descent, leading; 2438 CGFloat ascent, descent, leading;
2450 2439
@@ -2472,7 +2461,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2472 return Qnil; 2461 return Qnil;
2473 2462
2474 font_object = font_build_object (VECSIZE (struct macfont_info), 2463 font_object = font_build_object (VECSIZE (struct macfont_info),
2475 Qmac_ct, entity, size); 2464 Qmac_ct, entity, size);
2476 font = XFONT_OBJECT (font_object); 2465 font = XFONT_OBJECT (font_object);
2477 font->pixel_size = size; 2466 font->pixel_size = size;
2478 font->driver = &macfont_driver; 2467 font->driver = &macfont_driver;
@@ -2487,7 +2476,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2487 val = assq_no_quit (QCdestination, AREF (entity, FONT_EXTRA_INDEX)); 2476 val = assq_no_quit (QCdestination, AREF (entity, FONT_EXTRA_INDEX));
2488 if (CONSP (val) && EQ (XCDR (val), make_number (1))) 2477 if (CONSP (val) && EQ (XCDR (val), make_number (1)))
2489 macfont_info->screen_font = mac_screen_font_create_with_name (font_name, 2478 macfont_info->screen_font = mac_screen_font_create_with_name (font_name,
2490 size); 2479 size);
2491 else 2480 else
2492 macfont_info->screen_font = NULL; 2481 macfont_info->screen_font = NULL;
2493 macfont_info->cache = macfont_lookup_cache (font_name); 2482 macfont_info->cache = macfont_lookup_cache (font_name);
@@ -2507,8 +2496,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2507 if (sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 2496 if (sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
2508 macfont_info->spacing = MACFONT_SPACING_MONO; 2497 macfont_info->spacing = MACFONT_SPACING_MONO;
2509 else if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)) 2498 else if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))
2510 && (XINT (AREF (entity, FONT_SPACING_INDEX)) 2499 && (XINT (AREF (entity, FONT_SPACING_INDEX))
2511 == FONT_SPACING_SYNTHETIC_MONO)) 2500 == FONT_SPACING_SYNTHETIC_MONO))
2512 macfont_info->spacing = MACFONT_SPACING_SYNTHETIC_MONO; 2501 macfont_info->spacing = MACFONT_SPACING_SYNTHETIC_MONO;
2513 if (macfont_info->synthetic_italic_p || macfont_info->synthetic_bold_p) 2502 if (macfont_info->synthetic_italic_p || macfont_info->synthetic_bold_p)
2514 macfont_info->antialias = MACFONT_ANTIALIAS_ON; 2503 macfont_info->antialias = MACFONT_ANTIALIAS_ON;
@@ -2516,8 +2505,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2516 { 2505 {
2517 val = assq_no_quit (QCantialias, AREF (entity, FONT_EXTRA_INDEX)); 2506 val = assq_no_quit (QCantialias, AREF (entity, FONT_EXTRA_INDEX));
2518 if (CONSP (val)) 2507 if (CONSP (val))
2519 macfont_info->antialias = 2508 macfont_info->antialias =
2520 NILP (XCDR (val)) ? MACFONT_ANTIALIAS_OFF : MACFONT_ANTIALIAS_ON; 2509 NILP (XCDR (val)) ? MACFONT_ANTIALIAS_OFF : MACFONT_ANTIALIAS_ON;
2521 } 2510 }
2522 macfont_info->color_bitmap_p = 0; 2511 macfont_info->color_bitmap_p = 0;
2523 if (sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) 2512 if (sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS)
@@ -2535,7 +2524,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2535 { 2524 {
2536 glyph = macfont_get_glyph_for_character (font, ' ' + i); 2525 glyph = macfont_get_glyph_for_character (font, ' ' + i);
2537 if (glyph == kCGFontIndexInvalid) 2526 if (glyph == kCGFontIndexInvalid)
2538 break; 2527 break;
2539 total_width += macfont_glyph_extents (font, glyph, NULL, NULL, 0); 2528 total_width += macfont_glyph_extents (font, glyph, NULL, NULL, 0);
2540 } 2529 }
2541 if (i == 95) 2530 if (i == 95)
@@ -2544,8 +2533,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2544 font->average_width = font->space_width; /* XXX */ 2533 font->average_width = font->space_width; /* XXX */
2545 2534
2546 if (!(macfont_info->screen_font 2535 if (!(macfont_info->screen_font
2547 && mac_screen_font_get_metrics (macfont_info->screen_font, 2536 && mac_screen_font_get_metrics (macfont_info->screen_font,
2548 &ascent, &descent, &leading))) 2537 &ascent, &descent, &leading)))
2549 { 2538 {
2550 CFStringRef family_name; 2539 CFStringRef family_name;
2551 2540
@@ -2553,21 +2542,21 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2553 descent = mac_font_get_descent (macfont); 2542 descent = mac_font_get_descent (macfont);
2554 leading = mac_font_get_leading (macfont); 2543 leading = mac_font_get_leading (macfont);
2555 /* AppKit and WebKit do some adjustment to the heights of 2544 /* AppKit and WebKit do some adjustment to the heights of
2556 Courier, Helvetica, and Times. */ 2545 Courier, Helvetica, and Times. */
2557 family_name = mac_font_copy_family_name (macfont); 2546 family_name = mac_font_copy_family_name (macfont);
2558 if (family_name) 2547 if (family_name)
2559 { 2548 {
2560 if (CFEqual (family_name, CFSTR ("Courier")) 2549 if (CFEqual (family_name, CFSTR ("Courier"))
2561 || CFEqual (family_name, CFSTR ("Helvetica")) 2550 || CFEqual (family_name, CFSTR ("Helvetica"))
2562 || CFEqual (family_name, CFSTR ("Times"))) 2551 || CFEqual (family_name, CFSTR ("Times")))
2563 ascent += (ascent + descent) * .15f; 2552 ascent += (ascent + descent) * .15f;
2564 else if (CFStringHasPrefix (family_name, CFSTR ("Hiragino"))) 2553 else if (CFStringHasPrefix (family_name, CFSTR ("Hiragino")))
2565 { 2554 {
2566 leading *= .25f; 2555 leading *= .25f;
2567 ascent += leading; 2556 ascent += leading;
2568 } 2557 }
2569 CFRelease (family_name); 2558 CFRelease (family_name);
2570 } 2559 }
2571 } 2560 }
2572 font->ascent = ascent + 0.5f; 2561 font->ascent = ascent + 0.5f;
2573 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX)); 2562 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
@@ -2598,20 +2587,25 @@ static void
2598macfont_close (struct font *font) 2587macfont_close (struct font *font)
2599{ 2588{
2600 struct macfont_info *macfont_info = (struct macfont_info *) font; 2589 struct macfont_info *macfont_info = (struct macfont_info *) font;
2601 int i;
2602 2590
2603 block_input (); 2591 if (macfont_info->cache)
2604 CFRelease (macfont_info->macfont); 2592 {
2605 CGFontRelease (macfont_info->cgfont); 2593 int i;
2606 if (macfont_info->screen_font) 2594
2607 CFRelease (macfont_info->screen_font); 2595 block_input ();
2608 macfont_release_cache (macfont_info->cache); 2596 CFRelease (macfont_info->macfont);
2609 for (i = 0; i < macfont_info->metrics_nrows; i++) 2597 CGFontRelease (macfont_info->cgfont);
2610 if (macfont_info->metrics[i]) 2598 if (macfont_info->screen_font)
2611 xfree (macfont_info->metrics[i]); 2599 CFRelease (macfont_info->screen_font);
2612 if (macfont_info->metrics) 2600 macfont_release_cache (macfont_info->cache);
2613 xfree (macfont_info->metrics); 2601 for (i = 0; i < macfont_info->metrics_nrows; i++)
2614 unblock_input (); 2602 if (macfont_info->metrics[i])
2603 xfree (macfont_info->metrics[i]);
2604 if (macfont_info->metrics)
2605 xfree (macfont_info->metrics);
2606 macfont_info->cache = NULL;
2607 unblock_input ();
2608 }
2615} 2609}
2616 2610
2617static int 2611static int
@@ -2653,9 +2647,9 @@ macfont_encode_char (struct font *font, int c)
2653 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE; 2647 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE;
2654} 2648}
2655 2649
2656static int 2650static void
2657macfont_text_extents (struct font *font, unsigned int *code, int nglyphs, 2651macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
2658 struct font_metrics *metrics) 2652 struct font_metrics *metrics)
2659{ 2653{
2660 int width, i; 2654 int width, i;
2661 2655
@@ -2665,32 +2659,30 @@ macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
2665 { 2659 {
2666 struct font_metrics m; 2660 struct font_metrics m;
2667 int w = macfont_glyph_extents (font, code[i], metrics ? &m : NULL, 2661 int w = macfont_glyph_extents (font, code[i], metrics ? &m : NULL,
2668 NULL, 0); 2662 NULL, 0);
2669 2663
2670 if (metrics) 2664 if (metrics)
2671 { 2665 {
2672 if (width + m.lbearing < metrics->lbearing) 2666 if (width + m.lbearing < metrics->lbearing)
2673 metrics->lbearing = width + m.lbearing; 2667 metrics->lbearing = width + m.lbearing;
2674 if (width + m.rbearing > metrics->rbearing) 2668 if (width + m.rbearing > metrics->rbearing)
2675 metrics->rbearing = width + m.rbearing; 2669 metrics->rbearing = width + m.rbearing;
2676 if (m.ascent > metrics->ascent) 2670 if (m.ascent > metrics->ascent)
2677 metrics->ascent = m.ascent; 2671 metrics->ascent = m.ascent;
2678 if (m.descent > metrics->descent) 2672 if (m.descent > metrics->descent)
2679 metrics->descent = m.descent; 2673 metrics->descent = m.descent;
2680 } 2674 }
2681 width += w; 2675 width += w;
2682 } 2676 }
2683 unblock_input (); 2677 unblock_input ();
2684 2678
2685 if (metrics) 2679 if (metrics)
2686 metrics->width = width; 2680 metrics->width = width;
2687
2688 return width;
2689} 2681}
2690 2682
2691static int 2683static int
2692macfont_draw (struct glyph_string *s, int from, int to, int x, int y, 2684macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2693 bool with_background) 2685 bool with_background)
2694{ 2686{
2695 struct frame * f = s->f; 2687 struct frame * f = s->f;
2696 struct macfont_info *macfont_info = (struct macfont_info *) s->font; 2688 struct macfont_info *macfont_info = (struct macfont_info *) s->font;
@@ -2702,7 +2694,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2702 bool no_antialias_p = 2694 bool no_antialias_p =
2703 (macfont_info->antialias == MACFONT_ANTIALIAS_OFF 2695 (macfont_info->antialias == MACFONT_ANTIALIAS_OFF
2704 || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT 2696 || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT
2705 && font_size <= macfont_antialias_threshold)); 2697 && font_size <= macfont_antialias_threshold));
2706 int len = to - from; 2698 int len = to - from;
2707 struct face *face = s->face; 2699 struct face *face = s->face;
2708 CGContextRef context; 2700 CGContextRef context;
@@ -2712,29 +2704,29 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2712 if (with_background) 2704 if (with_background)
2713 background_rect = CGRectMake (x, y - FONT_BASE (s->font), 2705 background_rect = CGRectMake (x, y - FONT_BASE (s->font),
2714 s->width, FONT_HEIGHT (s->font)); 2706 s->width, FONT_HEIGHT (s->font));
2715 else 2707 else
2716 background_rect = CGRectNull; 2708 background_rect = CGRectNull;
2717 2709
2718 text_position = CGPointMake (x, -y); 2710 text_position = CGPointMake (x, -y);
2719 glyphs = xmalloc (sizeof (CGGlyph) * len); 2711 glyphs = xmalloc (sizeof (CGGlyph) * len);
2720 { 2712 {
2721 CGFloat advance_delta; 2713 CGFloat advance_delta = 0;
2722 int i; 2714 int i;
2723 CGFloat total_width = 0; 2715 CGFloat total_width = 0;
2724 2716
2725 positions = xmalloc (sizeof (CGPoint) * len); 2717 positions = xmalloc (sizeof (CGPoint) * len);
2726 for (i = 0; i < len; i++) 2718 for (i = 0; i < len; i++)
2727 { 2719 {
2728 int width; 2720 int width;
2729 2721
2730 glyphs[i] = s->char2b[from + i]; 2722 glyphs[i] = s->char2b[from + i];
2731 width = (s->padding_p ? 1 2723 width = (s->padding_p ? 1
2732 : macfont_glyph_extents (s->font, glyphs[i], 2724 : macfont_glyph_extents (s->font, glyphs[i],
2733 NULL, &advance_delta, 2725 NULL, &advance_delta,
2734 no_antialias_p)); 2726 no_antialias_p));
2735 positions[i].x = total_width + advance_delta; 2727 positions[i].x = total_width + advance_delta;
2736 positions[i].y = 0; 2728 positions[i].y = 0;
2737 total_width += width; 2729 total_width += width;
2738 } 2730 }
2739 } 2731 }
2740 2732
@@ -2743,7 +2735,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2743 2735
2744 if (!CGRectIsNull (background_rect)) 2736 if (!CGRectIsNull (background_rect))
2745 { 2737 {
2746 if (s->hl == DRAW_MOUSE_FACE) 2738 if (s->hl == DRAW_MOUSE_FACE)
2747 { 2739 {
2748 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); 2740 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2749 if (!face) 2741 if (!face)
@@ -2756,20 +2748,21 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2756 if (macfont_info->cgfont) 2748 if (macfont_info->cgfont)
2757 { 2749 {
2758 CGAffineTransform atfm; 2750 CGAffineTransform atfm;
2751
2759 CGContextScaleCTM (context, 1, -1); 2752 CGContextScaleCTM (context, 1, -1);
2760 CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f); 2753 CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
2761 if (macfont_info->synthetic_italic_p) 2754 if (macfont_info->synthetic_italic_p)
2762 atfm = synthetic_italic_atfm; 2755 atfm = synthetic_italic_atfm;
2763 else 2756 else
2764 atfm = CGAffineTransformIdentity; 2757 atfm = CGAffineTransformIdentity;
2765 if (macfont_info->synthetic_bold_p) 2758 if (macfont_info->synthetic_bold_p)
2766 { 2759 {
2767 CGContextSetTextDrawingMode (context, kCGTextFillStroke); 2760 CGContextSetTextDrawingMode (context, kCGTextFillStroke);
2768 CGContextSetLineWidth (context, synthetic_bold_factor * font_size); 2761 CGContextSetLineWidth (context, synthetic_bold_factor * font_size);
2769 CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND (context, face, f); 2762 CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND (context, face, f);
2770 } 2763 }
2771 if (no_antialias_p) 2764 if (no_antialias_p)
2772 CGContextSetShouldAntialias (context, false); 2765 CGContextSetShouldAntialias (context, false);
2773 2766
2774 CGContextSetTextMatrix (context, atfm); 2767 CGContextSetTextMatrix (context, atfm);
2775 CGContextSetTextPosition (context, text_position.x, text_position.y); 2768 CGContextSetTextPosition (context, text_position.x, text_position.y);
@@ -2777,23 +2770,23 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2777#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 2770#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
2778 if (macfont_info->color_bitmap_p 2771 if (macfont_info->color_bitmap_p
2779#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 2772#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
2780 && CTFontDrawGlyphs != NULL 2773 && CTFontDrawGlyphs != NULL
2781#endif 2774#endif
2782 ) 2775 )
2783 { 2776 {
2784 if (len > 0) 2777 if (len > 0)
2785 { 2778 {
2786 CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len, 2779 CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len,
2787 context); 2780 context);
2788 } 2781 }
2789 } 2782 }
2790 else 2783 else
2791#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ 2784#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
2792 { 2785 {
2793 CGContextSetFont (context, macfont_info->cgfont); 2786 CGContextSetFont (context, macfont_info->cgfont);
2794 CGContextSetFontSize (context, font_size); 2787 CGContextSetFontSize (context, font_size);
2795 CGContextShowGlyphsAtPositions (context, glyphs, positions, len); 2788 CGContextShowGlyphsAtPositions (context, glyphs, positions, len);
2796 } 2789 }
2797 } 2790 }
2798 2791
2799 2792
@@ -2831,9 +2824,9 @@ macfont_shape (Lisp_Object lgstring)
2831 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i); 2824 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
2832 2825
2833 if (NILP (lglyph)) 2826 if (NILP (lglyph))
2834 break; 2827 break;
2835 if (LGLYPH_CHAR (lglyph) >= 0x10000) 2828 if (LGLYPH_CHAR (lglyph) >= 0x10000)
2836 nonbmp_len++; 2829 nonbmp_len++;
2837 } 2830 }
2838 2831
2839 len = i; 2832 len = i;
@@ -2848,25 +2841,25 @@ macfont_shape (Lisp_Object lgstring)
2848 UTF32Char c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i)); 2841 UTF32Char c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
2849 2842
2850 if (macfont_store_utf32char_to_unichars (c, unichars + i + j) > 1) 2843 if (macfont_store_utf32char_to_unichars (c, unichars + i + j) > 1)
2851 { 2844 {
2852 nonbmp_indices[j] = i + j; 2845 nonbmp_indices[j] = i + j;
2853 j++; 2846 j++;
2854 } 2847 }
2855 } 2848 }
2856 nonbmp_indices[j] = len + j; /* sentinel */ 2849 nonbmp_indices[j] = len + j; /* sentinel */
2857 2850
2858 block_input (); 2851 block_input ();
2859 2852
2860 string = CFStringCreateWithCharactersNoCopy (NULL, unichars, len + nonbmp_len, 2853 string = CFStringCreateWithCharactersNoCopy (NULL, unichars, len + nonbmp_len,
2861 kCFAllocatorNull); 2854 kCFAllocatorNull);
2862 if (string) 2855 if (string)
2863 { 2856 {
2864 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len); 2857 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len);
2865 if (macfont_info->screen_font) 2858 if (macfont_info->screen_font)
2866 used = mac_screen_font_shape (macfont_info->screen_font, string, 2859 used = mac_screen_font_shape (macfont_info->screen_font, string,
2867 glyph_layouts, glyph_len); 2860 glyph_layouts, glyph_len);
2868 else 2861 else
2869 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len); 2862 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len);
2870 CFRelease (string); 2863 CFRelease (string);
2871 } 2864 }
2872 2865
@@ -2886,40 +2879,40 @@ macfont_shape (Lisp_Object lgstring)
2886 int xoff, yoff, wadjust; 2879 int xoff, yoff, wadjust;
2887 2880
2888 if (NILP (lglyph)) 2881 if (NILP (lglyph))
2889 { 2882 {
2890 lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil); 2883 lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil);
2891 LGSTRING_SET_GLYPH (lgstring, i, lglyph); 2884 LGSTRING_SET_GLYPH (lgstring, i, lglyph);
2892 } 2885 }
2893 2886
2894 from = gl->comp_range.location; 2887 from = gl->comp_range.location;
2895 /* Convert UTF-16 index to UTF-32. */ 2888 /* Convert UTF-16 index to UTF-32. */
2896 j = 0; 2889 j = 0;
2897 while (nonbmp_indices[j] < from) 2890 while (nonbmp_indices[j] < from)
2898 j++; 2891 j++;
2899 from -= j; 2892 from -= j;
2900 LGLYPH_SET_FROM (lglyph, from); 2893 LGLYPH_SET_FROM (lglyph, from);
2901 2894
2902 to = gl->comp_range.location + gl->comp_range.length; 2895 to = gl->comp_range.location + gl->comp_range.length;
2903 /* Convert UTF-16 index to UTF-32. */ 2896 /* Convert UTF-16 index to UTF-32. */
2904 while (nonbmp_indices[j] < to) 2897 while (nonbmp_indices[j] < to)
2905 j++; 2898 j++;
2906 to -= j; 2899 to -= j;
2907 LGLYPH_SET_TO (lglyph, to - 1); 2900 LGLYPH_SET_TO (lglyph, to - 1);
2908 2901
2909 /* LGLYPH_CHAR is used in `describe-char' for checking whether 2902 /* LGLYPH_CHAR is used in `describe-char' for checking whether
2910 the composition is trivial. */ 2903 the composition is trivial. */
2911 { 2904 {
2912 UTF32Char c; 2905 UTF32Char c;
2913 2906
2914 if (unichars[gl->string_index] >= 0xD800 2907 if (unichars[gl->string_index] >= 0xD800
2915 && unichars[gl->string_index] < 0xDC00) 2908 && unichars[gl->string_index] < 0xDC00)
2916 c = (((unichars[gl->string_index] - 0xD800) << 10) 2909 c = (((unichars[gl->string_index] - 0xD800) << 10)
2917 + (unichars[gl->string_index + 1] - 0xDC00) + 0x10000); 2910 + (unichars[gl->string_index + 1] - 0xDC00) + 0x10000);
2918 else 2911 else
2919 c = unichars[gl->string_index]; 2912 c = unichars[gl->string_index];
2920 if (macfont_get_glyph_for_character (font, c) != gl->glyph_id) 2913 if (macfont_get_glyph_for_character (font, c) != gl->glyph_id)
2921 c = 0; 2914 c = 0;
2922 LGLYPH_SET_CHAR (lglyph, c); 2915 LGLYPH_SET_CHAR (lglyph, c);
2923 } 2916 }
2924 2917
2925 { 2918 {
@@ -2938,15 +2931,15 @@ macfont_shape (Lisp_Object lgstring)
2938 yoff = lround (- gl->baseline_delta); 2931 yoff = lround (- gl->baseline_delta);
2939 wadjust = lround (gl->advance); 2932 wadjust = lround (gl->advance);
2940 if (xoff != 0 || yoff != 0 || wadjust != metrics.width) 2933 if (xoff != 0 || yoff != 0 || wadjust != metrics.width)
2941 { 2934 {
2942 Lisp_Object vec; 2935 Lisp_Object vec;
2943 2936
2944 vec = Fmake_vector (make_number (3), Qnil); 2937 vec = Fmake_vector (make_number (3), Qnil);
2945 ASET (vec, 0, make_number (xoff)); 2938 ASET (vec, 0, make_number (xoff));
2946 ASET (vec, 1, make_number (yoff)); 2939 ASET (vec, 1, make_number (yoff));
2947 ASET (vec, 2, make_number (wadjust)); 2940 ASET (vec, 2, make_number (wadjust));
2948 LGLYPH_SET_ADJUSTMENT (lglyph, vec); 2941 LGLYPH_SET_ADJUSTMENT (lglyph, vec);
2949 } 2942 }
2950 } 2943 }
2951 2944
2952 unblock_input (); 2945 unblock_input ();
@@ -2969,7 +2962,7 @@ struct uvs_table
2969 UInt32 length, num_var_selector_records; 2962 UInt32 length, num_var_selector_records;
2970 struct variation_selector_record variation_selector_records[1]; 2963 struct variation_selector_record variation_selector_records[1];
2971}; 2964};
2972#define SIZEOF_UVS_TABLE_HEADER \ 2965#define SIZEOF_UVS_TABLE_HEADER \
2973 (sizeof (struct uvs_table) - sizeof (struct variation_selector_record)) 2966 (sizeof (struct uvs_table) - sizeof (struct variation_selector_record))
2974 2967
2975struct unicode_value_range 2968struct unicode_value_range
@@ -2981,7 +2974,7 @@ struct default_uvs_table {
2981 UInt32 num_unicode_value_ranges; 2974 UInt32 num_unicode_value_ranges;
2982 struct unicode_value_range unicode_value_ranges[1]; 2975 struct unicode_value_range unicode_value_ranges[1];
2983}; 2976};
2984#define SIZEOF_DEFAULT_UVS_TABLE_HEADER \ 2977#define SIZEOF_DEFAULT_UVS_TABLE_HEADER \
2985 (sizeof (struct default_uvs_table) - sizeof (struct unicode_value_range)) 2978 (sizeof (struct default_uvs_table) - sizeof (struct unicode_value_range))
2986 2979
2987struct uvs_mapping 2980struct uvs_mapping
@@ -2994,7 +2987,7 @@ struct non_default_uvs_table
2994 UInt32 num_uvs_mappings; 2987 UInt32 num_uvs_mappings;
2995 struct uvs_mapping uvs_mappings[1]; 2988 struct uvs_mapping uvs_mappings[1];
2996}; 2989};
2997#define SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER \ 2990#define SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER \
2998 (sizeof (struct non_default_uvs_table) - sizeof (struct uvs_mapping)) 2991 (sizeof (struct non_default_uvs_table) - sizeof (struct uvs_mapping))
2999#pragma pack(pop) 2992#pragma pack(pop)
3000 2993
@@ -3026,98 +3019,98 @@ mac_font_copy_uvs_table (FontRef font)
3026 3019
3027#if __LP64__ 3020#if __LP64__
3028 if (CFDataGetLength (cmap_table) > UINT32_MAX) 3021 if (CFDataGetLength (cmap_table) > UINT32_MAX)
3029 goto finish; 3022 goto finish;
3030#endif 3023#endif
3031 3024
3032 cmap_len = CFDataGetLength (cmap_table); 3025 cmap_len = CFDataGetLength (cmap_table);
3033 if (sizeof_sfntCMapHeader > cmap_len) 3026 if (sizeof_sfntCMapHeader > cmap_len)
3034 goto finish; 3027 goto finish;
3035 3028
3036 ntables = BUINT16_VALUE (cmap->numTables); 3029 ntables = BUINT16_VALUE (cmap->numTables);
3037 if (ntables > ((cmap_len - sizeof_sfntCMapHeader) 3030 if (ntables > ((cmap_len - sizeof_sfntCMapHeader)
3038 / sizeof_sfntCMapEncoding)) 3031 / sizeof_sfntCMapEncoding))
3039 goto finish; 3032 goto finish;
3040 3033
3041 for (i = 0; i < ntables; i++) 3034 for (i = 0; i < ntables; i++)
3042 if ((BUINT16_VALUE (cmap->encoding[i].platformID) 3035 if ((BUINT16_VALUE (cmap->encoding[i].platformID)
3043 == kFontUnicodePlatform) 3036 == kFontUnicodePlatform)
3044 && (BUINT16_VALUE (cmap->encoding[i].scriptID) 3037 && (BUINT16_VALUE (cmap->encoding[i].scriptID)
3045 == 5)) /* kFontUnicodeV4_0VariationSequenceSemantics */ 3038 == 5)) /* kFontUnicodeV4_0VariationSequenceSemantics */
3046 { 3039 {
3047 uvs_offset = BUINT32_VALUE (cmap->encoding[i].offset); 3040 uvs_offset = BUINT32_VALUE (cmap->encoding[i].offset);
3048 break; 3041 break;
3049 } 3042 }
3050 if (i == ntables 3043 if (i == ntables
3051 || uvs_offset > cmap_len 3044 || uvs_offset > cmap_len
3052 || SIZEOF_UVS_TABLE_HEADER > cmap_len - uvs_offset) 3045 || SIZEOF_UVS_TABLE_HEADER > cmap_len - uvs_offset)
3053 goto finish; 3046 goto finish;
3054 3047
3055 uvs = (struct uvs_table *) ((UInt8 *) cmap + uvs_offset); 3048 uvs = (struct uvs_table *) ((UInt8 *) cmap + uvs_offset);
3056 uvs_len = BUINT32_VALUE (uvs->length); 3049 uvs_len = BUINT32_VALUE (uvs->length);
3057 if (uvs_len > cmap_len - uvs_offset 3050 if (uvs_len > cmap_len - uvs_offset
3058 || SIZEOF_UVS_TABLE_HEADER > uvs_len) 3051 || SIZEOF_UVS_TABLE_HEADER > uvs_len)
3059 goto finish; 3052 goto finish;
3060 3053
3061 if (BUINT16_VALUE (uvs->format) != 14) 3054 if (BUINT16_VALUE (uvs->format) != 14)
3062 goto finish; 3055 goto finish;
3063 3056
3064 nrecords = BUINT32_VALUE (uvs->num_var_selector_records); 3057 nrecords = BUINT32_VALUE (uvs->num_var_selector_records);
3065 if (nrecords > ((uvs_len - SIZEOF_UVS_TABLE_HEADER) 3058 if (nrecords > ((uvs_len - SIZEOF_UVS_TABLE_HEADER)
3066 / sizeof (struct variation_selector_record))) 3059 / sizeof (struct variation_selector_record)))
3067 goto finish; 3060 goto finish;
3068 3061
3069 records = uvs->variation_selector_records; 3062 records = uvs->variation_selector_records;
3070 for (i = 0; i < nrecords; i++) 3063 for (i = 0; i < nrecords; i++)
3071 { 3064 {
3072 UInt32 default_uvs_offset, non_default_uvs_offset; 3065 UInt32 default_uvs_offset, non_default_uvs_offset;
3073 3066
3074 default_uvs_offset = BUINT32_VALUE (records[i].default_uvs_offset); 3067 default_uvs_offset = BUINT32_VALUE (records[i].default_uvs_offset);
3075 if (default_uvs_offset) 3068 if (default_uvs_offset)
3076 { 3069 {
3077 struct default_uvs_table *default_uvs; 3070 struct default_uvs_table *default_uvs;
3078 UInt32 nranges; 3071 UInt32 nranges;
3079 3072
3080 if (default_uvs_offset > uvs_len 3073 if (default_uvs_offset > uvs_len
3081 || (SIZEOF_DEFAULT_UVS_TABLE_HEADER 3074 || (SIZEOF_DEFAULT_UVS_TABLE_HEADER
3082 > uvs_len - default_uvs_offset)) 3075 > uvs_len - default_uvs_offset))
3083 goto finish; 3076 goto finish;
3084 3077
3085 default_uvs = ((struct default_uvs_table *) 3078 default_uvs = ((struct default_uvs_table *)
3086 ((UInt8 *) uvs + default_uvs_offset)); 3079 ((UInt8 *) uvs + default_uvs_offset));
3087 nranges = BUINT32_VALUE (default_uvs->num_unicode_value_ranges); 3080 nranges = BUINT32_VALUE (default_uvs->num_unicode_value_ranges);
3088 if (nranges > ((uvs_len - default_uvs_offset 3081 if (nranges > ((uvs_len - default_uvs_offset
3089 - SIZEOF_DEFAULT_UVS_TABLE_HEADER) 3082 - SIZEOF_DEFAULT_UVS_TABLE_HEADER)
3090 / sizeof (struct unicode_value_range))) 3083 / sizeof (struct unicode_value_range)))
3091 goto finish; 3084 goto finish;
3092 /* Now 2 * nranges can't overflow, so we can safely use 3085 /* Now 2 * nranges can't overflow, so we can safely use
3093 `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' in 3086 `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' in
3094 mac_font_get_glyphs_for_variants. */ 3087 mac_font_get_glyphs_for_variants. */
3095 } 3088 }
3096 3089
3097 non_default_uvs_offset = 3090 non_default_uvs_offset =
3098 BUINT32_VALUE (records[i].non_default_uvs_offset); 3091 BUINT32_VALUE (records[i].non_default_uvs_offset);
3099 if (non_default_uvs_offset) 3092 if (non_default_uvs_offset)
3100 { 3093 {
3101 struct non_default_uvs_table *non_default_uvs; 3094 struct non_default_uvs_table *non_default_uvs;
3102 UInt32 nmappings; 3095 UInt32 nmappings;
3103 3096
3104 if (non_default_uvs_offset > uvs_len 3097 if (non_default_uvs_offset > uvs_len
3105 || (SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER 3098 || (SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER
3106 > uvs_len - non_default_uvs_offset)) 3099 > uvs_len - non_default_uvs_offset))
3107 goto finish; 3100 goto finish;
3108 3101
3109 non_default_uvs = ((struct non_default_uvs_table *) 3102 non_default_uvs = ((struct non_default_uvs_table *)
3110 ((UInt8 *) uvs + non_default_uvs_offset)); 3103 ((UInt8 *) uvs + non_default_uvs_offset));
3111 nmappings = BUINT32_VALUE (non_default_uvs->num_uvs_mappings); 3104 nmappings = BUINT32_VALUE (non_default_uvs->num_uvs_mappings);
3112 if (nmappings > ((uvs_len - non_default_uvs_offset 3105 if (nmappings > ((uvs_len - non_default_uvs_offset
3113 - SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER) 3106 - SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER)
3114 / sizeof (struct uvs_mapping))) 3107 / sizeof (struct uvs_mapping)))
3115 goto finish; 3108 goto finish;
3116 /* Now 2 * nmappings can't overflow, so we can safely 3109 /* Now 2 * nmappings can't overflow, so we can safely
3117 use `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' 3110 use `(lo + hi) / 2' instead of `lo + (hi - lo) / 2'
3118 in mac_font_get_glyphs_for_variants. */ 3111 in mac_font_get_glyphs_for_variants. */
3119 } 3112 }
3120 } 3113 }
3121 3114
3122 uvs_table = CFDataCreate (NULL, (UInt8 *) uvs, uvs_len); 3115 uvs_table = CFDataCreate (NULL, (UInt8 *) uvs, uvs_len);
3123 3116
@@ -3140,18 +3133,16 @@ mac_font_copy_uvs_table (FontRef font)
3140 3133
3141static void 3134static void
3142mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c, 3135mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c,
3143 const UTF32Char selectors[], CGGlyph glyphs[], 3136 const UTF32Char selectors[], CGGlyph glyphs[],
3144 CFIndex count) 3137 CFIndex count)
3145{ 3138{
3146 struct uvs_table *uvs = (struct uvs_table *) CFDataGetBytePtr (uvs_table); 3139 struct uvs_table *uvs = (struct uvs_table *) CFDataGetBytePtr (uvs_table);
3147 struct variation_selector_record *records = uvs->variation_selector_records; 3140 struct variation_selector_record *records = uvs->variation_selector_records;
3148 CFIndex i; 3141 CFIndex i;
3149 UInt32 ir, nrecords; 3142 UInt32 ir, nrecords;
3150#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3151 dispatch_queue_t queue = 3143 dispatch_queue_t queue =
3152 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 3144 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3153 dispatch_group_t group = dispatch_group_create (); 3145 dispatch_group_t group = dispatch_group_create ();
3154#endif
3155 3146
3156 nrecords = BUINT32_VALUE (uvs->num_var_selector_records); 3147 nrecords = BUINT32_VALUE (uvs->num_var_selector_records);
3157 i = 0; 3148 i = 0;
@@ -3161,86 +3152,80 @@ mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c,
3161 UInt32 default_uvs_offset, non_default_uvs_offset; 3152 UInt32 default_uvs_offset, non_default_uvs_offset;
3162 3153
3163 if (selectors[i] < BUINT24_VALUE (records[ir].var_selector)) 3154 if (selectors[i] < BUINT24_VALUE (records[ir].var_selector))
3164 { 3155 {
3165 glyphs[i++] = kCGFontIndexInvalid; 3156 glyphs[i++] = kCGFontIndexInvalid;
3166 continue; 3157 continue;
3167 } 3158 }
3168 else if (selectors[i] > BUINT24_VALUE (records[ir].var_selector)) 3159 else if (selectors[i] > BUINT24_VALUE (records[ir].var_selector))
3169 { 3160 {
3170 ir++; 3161 ir++;
3171 continue; 3162 continue;
3172 } 3163 }
3173 3164
3174 /* selectors[i] == BUINT24_VALUE (records[ir].var_selector) */ 3165 /* selectors[i] == BUINT24_VALUE (records[ir].var_selector) */
3175 default_uvs_offset = BUINT32_VALUE (records[ir].default_uvs_offset); 3166 default_uvs_offset = BUINT32_VALUE (records[ir].default_uvs_offset);
3176 non_default_uvs_offset = 3167 non_default_uvs_offset =
3177 BUINT32_VALUE (records[ir].non_default_uvs_offset); 3168 BUINT32_VALUE (records[ir].non_default_uvs_offset);
3178#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3179 dispatch_group_async (group, queue, ^{ 3169 dispatch_group_async (group, queue, ^{
3180#endif 3170 glyphs[i] = kCGFontIndexInvalid;
3181 glyphs[i] = kCGFontIndexInvalid; 3171
3182 3172 if (default_uvs_offset)
3183 if (default_uvs_offset) 3173 {
3184 { 3174 struct default_uvs_table *default_uvs =
3185 struct default_uvs_table *default_uvs = 3175 (struct default_uvs_table *) ((UInt8 *) uvs
3186 (struct default_uvs_table *) ((UInt8 *) uvs 3176 + default_uvs_offset);
3187 + default_uvs_offset); 3177 struct unicode_value_range *ranges =
3188 struct unicode_value_range *ranges = 3178 default_uvs->unicode_value_ranges;
3189 default_uvs->unicode_value_ranges; 3179 UInt32 lo, hi;
3190 UInt32 lo, hi; 3180
3191 3181 lo = 0;
3192 lo = 0; 3182 hi = BUINT32_VALUE (default_uvs->num_unicode_value_ranges);
3193 hi = BUINT32_VALUE (default_uvs->num_unicode_value_ranges); 3183 while (lo < hi)
3194 while (lo < hi) 3184 {
3195 { 3185 UInt32 mid = (lo + hi) / 2;
3196 UInt32 mid = (lo + hi) / 2; 3186
3197 3187 if (c < BUINT24_VALUE (ranges[mid].start_unicode_value))
3198 if (c < BUINT24_VALUE (ranges[mid].start_unicode_value)) 3188 hi = mid;
3199 hi = mid; 3189 else
3200 else 3190 lo = mid + 1;
3201 lo = mid + 1; 3191 }
3202 } 3192 if (hi > 0
3203 if (hi > 0 3193 && (c <= (BUINT24_VALUE (ranges[hi - 1].start_unicode_value)
3204 && (c <= (BUINT24_VALUE (ranges[hi - 1].start_unicode_value) 3194 + BUINT8_VALUE (ranges[hi - 1].additional_count))))
3205 + BUINT8_VALUE (ranges[hi - 1].additional_count)))) 3195 glyphs[i] = 0;
3206 glyphs[i] = 0; 3196 }
3207 } 3197
3208 3198 if (glyphs[i] == kCGFontIndexInvalid && non_default_uvs_offset)
3209 if (glyphs[i] == kCGFontIndexInvalid && non_default_uvs_offset) 3199 {
3210 { 3200 struct non_default_uvs_table *non_default_uvs =
3211 struct non_default_uvs_table *non_default_uvs = 3201 (struct non_default_uvs_table *) ((UInt8 *) uvs
3212 (struct non_default_uvs_table *) ((UInt8 *) uvs 3202 + non_default_uvs_offset);
3213 + non_default_uvs_offset); 3203 struct uvs_mapping *mappings = non_default_uvs->uvs_mappings;
3214 struct uvs_mapping *mappings = non_default_uvs->uvs_mappings; 3204 UInt32 lo, hi;
3215 UInt32 lo, hi; 3205
3216 3206 lo = 0;
3217 lo = 0; 3207 hi = BUINT32_VALUE (non_default_uvs->num_uvs_mappings);
3218 hi = BUINT32_VALUE (non_default_uvs->num_uvs_mappings); 3208 while (lo < hi)
3219 while (lo < hi) 3209 {
3220 { 3210 UInt32 mid = (lo + hi) / 2;
3221 UInt32 mid = (lo + hi) / 2; 3211
3222 3212 if (c < BUINT24_VALUE (mappings[mid].unicode_value))
3223 if (c < BUINT24_VALUE (mappings[mid].unicode_value)) 3213 hi = mid;
3224 hi = mid; 3214 else
3225 else 3215 lo = mid + 1;
3226 lo = mid + 1; 3216 }
3227 } 3217 if (hi > 0 &&
3228 if (hi > 0 && 3218 BUINT24_VALUE (mappings[hi - 1].unicode_value) == c)
3229 BUINT24_VALUE (mappings[hi - 1].unicode_value) == c) 3219 glyphs[i] = BUINT16_VALUE (mappings[hi - 1].glyph_id);
3230 glyphs[i] = BUINT16_VALUE (mappings[hi - 1].glyph_id); 3220 }
3231 } 3221 });
3232#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3233 });
3234#endif
3235 i++; 3222 i++;
3236 ir++; 3223 ir++;
3237 } 3224 }
3238 while (i < count) 3225 while (i < count)
3239 glyphs[i++] = kCGFontIndexInvalid; 3226 glyphs[i++] = kCGFontIndexInvalid;
3240#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3241 dispatch_group_wait (group, DISPATCH_TIME_FOREVER); 3227 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
3242 dispatch_release (group); 3228 dispatch_release (group);
3243#endif
3244} 3229}
3245 3230
3246static int 3231static int
@@ -3259,26 +3244,26 @@ macfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
3259 CGGlyph glyphs[256]; 3244 CGGlyph glyphs[256];
3260 3245
3261 for (i = 0; i < 16; i++) 3246 for (i = 0; i < 16; i++)
3262 selectors[i] = 0xFE00 + i; 3247 selectors[i] = 0xFE00 + i;
3263 for (; i < 256; i++) 3248 for (; i < 256; i++)
3264 selectors[i] = 0xE0100 + (i - 16); 3249 selectors[i] = 0xE0100 + (i - 16);
3265 mac_font_get_glyphs_for_variants (uvs_table, c, selectors, glyphs, 256); 3250 mac_font_get_glyphs_for_variants (uvs_table, c, selectors, glyphs, 256);
3266 for (i = 0; i < 256; i++) 3251 for (i = 0; i < 256; i++)
3267 { 3252 {
3268 CGGlyph glyph = glyphs[i]; 3253 CGGlyph glyph = glyphs[i];
3269 3254
3270 if (uvs_collection != MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING 3255 if (uvs_collection != MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING
3271 && glyph != kCGFontIndexInvalid) 3256 && glyph != kCGFontIndexInvalid)
3272 glyph = macfont_get_glyph_for_cid (font, uvs_collection, glyph); 3257 glyph = macfont_get_glyph_for_cid (font, uvs_collection, glyph);
3273 if (glyph == kCGFontIndexInvalid) 3258 if (glyph == kCGFontIndexInvalid)
3274 variations[i] = 0; 3259 variations[i] = 0;
3275 else 3260 else
3276 { 3261 {
3277 variations[i] = (glyph ? glyph 3262 variations[i] = (glyph ? glyph
3278 : macfont_get_glyph_for_character (font, c)); 3263 : macfont_get_glyph_for_character (font, c));
3279 n++; 3264 n++;
3280 } 3265 }
3281 } 3266 }
3282 } 3267 }
3283 unblock_input (); 3268 unblock_input ();
3284 3269
@@ -3306,7 +3291,7 @@ macfont_filter_properties (Lisp_Object font, Lisp_Object alist)
3306 3291
3307static Boolean 3292static Boolean
3308mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor, 3293mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor,
3309 CFArrayRef languages) 3294 CFArrayRef languages)
3310{ 3295{
3311 Boolean result = true; 3296 Boolean result = true;
3312 CFArrayRef desc_languages = 3297 CFArrayRef desc_languages =
@@ -3321,13 +3306,13 @@ mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor,
3321 desc_languages_count = CFArrayGetCount (desc_languages); 3306 desc_languages_count = CFArrayGetCount (desc_languages);
3322 languages_count = CFArrayGetCount (languages); 3307 languages_count = CFArrayGetCount (languages);
3323 for (i = 0; i < languages_count; i++) 3308 for (i = 0; i < languages_count; i++)
3324 if (!CFArrayContainsValue (desc_languages, 3309 if (!CFArrayContainsValue (desc_languages,
3325 CFRangeMake (0, desc_languages_count), 3310 CFRangeMake (0, desc_languages_count),
3326 CFArrayGetValueAtIndex (languages, i))) 3311 CFArrayGetValueAtIndex (languages, i)))
3327 { 3312 {
3328 result = false; 3313 result = false;
3329 break; 3314 break;
3330 } 3315 }
3331 CFRelease (desc_languages); 3316 CFRelease (desc_languages);
3332 } 3317 }
3333 3318
@@ -3345,79 +3330,79 @@ mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef attributes)
3345 { 3330 {
3346 CFStringRef keys[] = { 3331 CFStringRef keys[] = {
3347#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 3332#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
3348 kCTLanguageAttributeName 3333 kCTLanguageAttributeName
3349#else 3334#else
3350 CFSTR ("NSLanguage") 3335 CFSTR ("NSLanguage")
3351#endif 3336#endif
3352 }; 3337 };
3353 CFTypeRef values[] = {NULL}; 3338 CFTypeRef values[] = {NULL};
3354 CFIndex num_values = 0; 3339 CFIndex num_values = 0;
3355 CFArrayRef languages 3340 CFArrayRef languages
3356 = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); 3341 = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE);
3357 3342
3358 if (languages && CFArrayGetCount (languages) > 0) 3343 if (languages && CFArrayGetCount (languages) > 0)
3359 { 3344 {
3360 if (CTGetCoreTextVersion () >= kCTVersionNumber10_9) 3345 if (CTGetCoreTextVersion () >= kCTVersionNumber10_9)
3361 values[num_values++] = CFArrayGetValueAtIndex (languages, 0); 3346 values[num_values++] = CFArrayGetValueAtIndex (languages, 0);
3362 else 3347 else
3363 { 3348 {
3364 CFCharacterSetRef charset = 3349 CFCharacterSetRef charset =
3365 CFDictionaryGetValue (attributes, 3350 CFDictionaryGetValue (attributes,
3366 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 3351 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
3367 3352
3368 result = mac_font_copy_default_name_for_charset_and_languages (charset, languages); 3353 result = mac_font_copy_default_name_for_charset_and_languages (charset, languages);
3369 } 3354 }
3370 } 3355 }
3371 if (result == NULL) 3356 if (result == NULL)
3372 { 3357 {
3373 CFAttributedStringRef attr_string = NULL; 3358 CFAttributedStringRef attr_string = NULL;
3374 CTLineRef ctline = NULL; 3359 CTLineRef ctline = NULL;
3375 CFDictionaryRef attrs 3360 CFDictionaryRef attrs
3376 = CFDictionaryCreate (NULL, (const void **) keys, 3361 = CFDictionaryCreate (NULL, (const void **) keys,
3377 (const void **) values, num_values, 3362 (const void **) values, num_values,
3378 &kCFTypeDictionaryKeyCallBacks, 3363 &kCFTypeDictionaryKeyCallBacks,
3379 &kCFTypeDictionaryValueCallBacks); 3364 &kCFTypeDictionaryValueCallBacks);
3380 3365
3381 if (attrs) 3366 if (attrs)
3382 { 3367 {
3383 attr_string = CFAttributedStringCreate (NULL, charset_string, 3368 attr_string = CFAttributedStringCreate (NULL, charset_string,
3384 attrs); 3369 attrs);
3385 CFRelease (attrs); 3370 CFRelease (attrs);
3386 } 3371 }
3387 if (attr_string) 3372 if (attr_string)
3388 { 3373 {
3389 ctline = CTLineCreateWithAttributedString (attr_string); 3374 ctline = CTLineCreateWithAttributedString (attr_string);
3390 CFRelease (attr_string); 3375 CFRelease (attr_string);
3391 } 3376 }
3392 if (ctline) 3377 if (ctline)
3393 { 3378 {
3394 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3379 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3395 CFIndex i, nruns = CFArrayGetCount (runs); 3380 CFIndex i, nruns = CFArrayGetCount (runs);
3396 CTFontRef font; 3381 CTFontRef font;
3397 3382
3398 for (i = 0; i < nruns; i++) 3383 for (i = 0; i < nruns; i++)
3399 { 3384 {
3400 CTRunRef run = CFArrayGetValueAtIndex (runs, i); 3385 CTRunRef run = CFArrayGetValueAtIndex (runs, i);
3401 CFDictionaryRef attributes = CTRunGetAttributes (run); 3386 CFDictionaryRef attributes = CTRunGetAttributes (run);
3402 CTFontRef font_in_run; 3387 CTFontRef font_in_run;
3403 3388
3404 if (attributes == NULL) 3389 if (attributes == NULL)
3405 break; 3390 break;
3406 font_in_run = 3391 font_in_run =
3407 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3392 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3408 if (font_in_run == NULL) 3393 if (font_in_run == NULL)
3409 break; 3394 break;
3410 if (i == 0) 3395 if (i == 0)
3411 font = font_in_run; 3396 font = font_in_run;
3412 else if (!mac_ctfont_equal_in_postscript_name (font, 3397 else if (!mac_ctfont_equal_in_postscript_name (font,
3413 font_in_run)) 3398 font_in_run))
3414 break; 3399 break;
3415 } 3400 }
3416 if (nruns > 0 && i == nruns) 3401 if (nruns > 0 && i == nruns)
3417 result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute); 3402 result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute);
3418 CFRelease (ctline); 3403 CFRelease (ctline);
3419 } 3404 }
3420 } 3405 }
3421 } 3406 }
3422 3407
3423 return result; 3408 return result;
@@ -3427,14 +3412,14 @@ static inline double
3427mac_ctfont_get_advance_width_for_glyph (CTFontRef font, CGGlyph glyph) 3412mac_ctfont_get_advance_width_for_glyph (CTFontRef font, CGGlyph glyph)
3428{ 3413{
3429 return CTFontGetAdvancesForGlyphs (font, kCTFontDefaultOrientation, 3414 return CTFontGetAdvancesForGlyphs (font, kCTFontDefaultOrientation,
3430 &glyph, NULL, 1); 3415 &glyph, NULL, 1);
3431} 3416}
3432 3417
3433static inline CGRect 3418static inline CGRect
3434mac_ctfont_get_bounding_rect_for_glyph (CTFontRef font, CGGlyph glyph) 3419mac_ctfont_get_bounding_rect_for_glyph (CTFontRef font, CGGlyph glyph)
3435{ 3420{
3436 return CTFontGetBoundingRectsForGlyphs (font, kCTFontDefaultOrientation, 3421 return CTFontGetBoundingRectsForGlyphs (font, kCTFontDefaultOrientation,
3437 &glyph, NULL, 1); 3422 &glyph, NULL, 1);
3438} 3423}
3439 3424
3440static CFArrayRef 3425static CFArrayRef
@@ -3442,83 +3427,31 @@ mac_ctfont_create_available_families (void)
3442{ 3427{
3443 CFMutableArrayRef families = NULL; 3428 CFMutableArrayRef families = NULL;
3444 3429
3445#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
3446#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3447 if (CTFontManagerCopyAvailableFontFamilyNames != NULL)
3448#endif
3449 { 3430 {
3450 CFArrayRef orig_families = CTFontManagerCopyAvailableFontFamilyNames (); 3431 CFArrayRef orig_families = CTFontManagerCopyAvailableFontFamilyNames ();
3451 3432
3452 if (orig_families) 3433 if (orig_families)
3453 { 3434 {
3454 CFIndex i, count = CFArrayGetCount (orig_families); 3435 CFIndex i, count = CFArrayGetCount (orig_families);
3455 3436
3456 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks); 3437 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks);
3457 if (families) 3438 if (families)
3458 for (i = 0; i < count; i++) 3439 for (i = 0; i < count; i++)
3459 { 3440 {
3460 CFStringRef family = CFArrayGetValueAtIndex (orig_families, i); 3441 CFStringRef family = CFArrayGetValueAtIndex (orig_families, i);
3461 3442
3462 if (!CFStringHasPrefix (family, CFSTR (".")) 3443 if (!CFStringHasPrefix (family, CFSTR ("."))
3463 && (CTFontManagerCompareFontFamilyNames (family, 3444 && (CTFontManagerCompareFontFamilyNames (family,
3464 CFSTR ("LastResort"), 3445 CFSTR ("LastResort"),
3465 NULL) 3446 NULL)
3466 != kCFCompareEqualTo)) 3447 != kCFCompareEqualTo))
3467 CFArrayAppendValue (families, family); 3448 CFArrayAppendValue (families, family);
3468 } 3449 }
3469 CFRelease (orig_families); 3450 CFRelease (orig_families);
3470 } 3451 }
3471 }
3472#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3473 else /* CTFontManagerCopyAvailableFontFamilyNames == NULL */
3474#endif
3475#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */
3476#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3477 {
3478 CTFontCollectionRef collection;
3479 CFArrayRef descs = NULL;
3480
3481 collection = CTFontCollectionCreateFromAvailableFonts (NULL);
3482 if (collection)
3483 {
3484 descs = CTFontCollectionCreateMatchingFontDescriptors (collection);
3485 CFRelease (collection);
3486 }
3487 if (descs)
3488 {
3489 CFIndex i, count = CFArrayGetCount (descs);
3490
3491 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks);
3492 if (families)
3493 for (i = 0; i < count; i++)
3494 {
3495 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i);
3496 CFStringRef name =
3497 mac_font_descriptor_copy_attribute (desc,
3498 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
3499
3500 if (name)
3501 {
3502 CFIndex p, limit = CFArrayGetCount (families);
3503
3504 p = CFArrayBSearchValues (families, CFRangeMake (0, limit),
3505 (const void *) name,
3506 mac_font_family_compare, NULL);
3507 if (p >= limit)
3508 CFArrayAppendValue (families, name);
3509 else if (mac_font_family_compare
3510 (CFArrayGetValueAtIndex (families, p),
3511 name, NULL) != kCFCompareEqualTo)
3512 CFArrayInsertValueAtIndex (families, p, name);
3513 CFRelease (name);
3514 }
3515 }
3516 CFRelease (descs);
3517 }
3518 } 3452 }
3519#endif
3520 3453
3521 return families; 3454 return families;
3522} 3455}
3523 3456
3524static Boolean 3457static Boolean
@@ -3536,10 +3469,10 @@ mac_ctfont_equal_in_postscript_name (CTFontRef font1, CTFontRef font2)
3536 { 3469 {
3537 name2 = CTFontCopyPostScriptName (font2); 3470 name2 = CTFontCopyPostScriptName (font2);
3538 if (name2) 3471 if (name2)
3539 { 3472 {
3540 result = CFEqual (name1, name2); 3473 result = CFEqual (name1, name2);
3541 CFRelease (name2); 3474 CFRelease (name2);
3542 } 3475 }
3543 CFRelease (name1); 3476 CFRelease (name1);
3544 } 3477 }
3545 3478
@@ -3548,7 +3481,7 @@ mac_ctfont_equal_in_postscript_name (CTFontRef font1, CTFontRef font2)
3548 3481
3549static CTLineRef 3482static CTLineRef
3550mac_ctfont_create_line_with_string_and_font (CFStringRef string, 3483mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3551 CTFontRef macfont) 3484 CTFontRef macfont)
3552{ 3485{
3553 CFStringRef keys[] = {kCTFontAttributeName, kCTKernAttributeName}; 3486 CFStringRef keys[] = {kCTFontAttributeName, kCTKernAttributeName};
3554 CFTypeRef values[] = {NULL, NULL}; 3487 CFTypeRef values[] = {NULL, NULL};
@@ -3562,10 +3495,10 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3562 if (values[1]) 3495 if (values[1])
3563 { 3496 {
3564 attributes = CFDictionaryCreate (NULL, (const void **) keys, 3497 attributes = CFDictionaryCreate (NULL, (const void **) keys,
3565 (const void **) values, 3498 (const void **) values,
3566 ARRAYELTS (keys), 3499 ARRAYELTS (keys),
3567 &kCFTypeDictionaryKeyCallBacks, 3500 &kCFTypeDictionaryKeyCallBacks,
3568 &kCFTypeDictionaryValueCallBacks); 3501 &kCFTypeDictionaryValueCallBacks);
3569 CFRelease (values[1]); 3502 CFRelease (values[1]);
3570 } 3503 }
3571 if (attributes) 3504 if (attributes)
@@ -3581,30 +3514,30 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3581 if (ctline) 3514 if (ctline)
3582 { 3515 {
3583 /* Abandon if ctline contains some fonts other than the 3516 /* Abandon if ctline contains some fonts other than the
3584 specified one. */ 3517 specified one. */
3585 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3518 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3586 CFIndex i, nruns = CFArrayGetCount (runs); 3519 CFIndex i, nruns = CFArrayGetCount (runs);
3587 3520
3588 for (i = 0; i < nruns; i++) 3521 for (i = 0; i < nruns; i++)
3589 { 3522 {
3590 CTRunRef run = CFArrayGetValueAtIndex (runs, i); 3523 CTRunRef run = CFArrayGetValueAtIndex (runs, i);
3591 CFDictionaryRef attributes = CTRunGetAttributes (run); 3524 CFDictionaryRef attributes = CTRunGetAttributes (run);
3592 CTFontRef font_in_run; 3525 CTFontRef font_in_run;
3593 3526
3594 if (attributes == NULL) 3527 if (attributes == NULL)
3595 break; 3528 break;
3596 font_in_run = 3529 font_in_run =
3597 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3530 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3598 if (font_in_run == NULL) 3531 if (font_in_run == NULL)
3599 break; 3532 break;
3600 if (!mac_ctfont_equal_in_postscript_name (macfont, font_in_run)) 3533 if (!mac_ctfont_equal_in_postscript_name (macfont, font_in_run))
3601 break; 3534 break;
3602 } 3535 }
3603 if (i < nruns) 3536 if (i < nruns)
3604 { 3537 {
3605 CFRelease (ctline); 3538 CFRelease (ctline);
3606 ctline = NULL; 3539 ctline = NULL;
3607 } 3540 }
3608 } 3541 }
3609 3542
3610 return ctline; 3543 return ctline;
@@ -3612,7 +3545,7 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3612 3545
3613static CFIndex 3546static CFIndex
3614mac_ctfont_shape (CTFontRef font, CFStringRef string, 3547mac_ctfont_shape (CTFontRef font, CFStringRef string,
3615 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len) 3548 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len)
3616{ 3549{
3617 CFIndex used, result = 0; 3550 CFIndex used, result = 0;
3618 CTLineRef ctline = mac_ctfont_create_line_with_string_and_font (string, font); 3551 CTLineRef ctline = mac_ctfont_create_line_with_string_and_font (string, font);
@@ -3629,128 +3562,128 @@ mac_ctfont_shape (CTFontRef font, CFStringRef string,
3629 CFIndex total_glyph_count = 0; 3562 CFIndex total_glyph_count = 0;
3630 3563
3631 for (k = 0; k < ctrun_count; k++) 3564 for (k = 0; k < ctrun_count; k++)
3632 { 3565 {
3633 CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k); 3566 CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k);
3634 CFIndex i, min_location, glyph_count = CTRunGetGlyphCount (ctrun); 3567 CFIndex i, min_location, glyph_count = CTRunGetGlyphCount (ctrun);
3635 struct mac_glyph_layout *glbuf = glyph_layouts + total_glyph_count; 3568 struct mac_glyph_layout *glbuf = glyph_layouts + total_glyph_count;
3636 CFRange string_range, comp_range, range; 3569 CFRange string_range, comp_range, range;
3637 CFIndex *permutation; 3570 CFIndex *permutation;
3638 3571
3639 if (CTRunGetStatus (ctrun) & kCTRunStatusRightToLeft) 3572 if (CTRunGetStatus (ctrun) & kCTRunStatusRightToLeft)
3640 permutation = xmalloc (sizeof (CFIndex) * glyph_count); 3573 permutation = xmalloc (sizeof (CFIndex) * glyph_count);
3641 else 3574 else
3642 permutation = NULL; 3575 permutation = NULL;
3643 3576
3644#define RIGHT_TO_LEFT_P permutation 3577#define RIGHT_TO_LEFT_P permutation
3645 3578
3646 /* Now the `comp_range' member of struct mac_glyph_layout is 3579 /* Now the `comp_range' member of struct mac_glyph_layout is
3647 temporarily used as a work area such that: 3580 temporarily used as a work area such that:
3648 glbuf[i].comp_range.location = 3581 glbuf[i].comp_range.location =
3649 min {compRange[i + 1].location, ..., 3582 min {compRange[i + 1].location, ...,
3650 compRange[glyph_count - 1].location, 3583 compRange[glyph_count - 1].location,
3651 maxRange (stringRangeForCTRun)} 3584 maxRange (stringRangeForCTRun)}
3652 glbuf[i].comp_range.length = maxRange (compRange[i]) 3585 glbuf[i].comp_range.length = maxRange (compRange[i])
3653 where compRange[i] is the range of composed characters 3586 where compRange[i] is the range of composed characters
3654 containing i-th glyph. */ 3587 containing i-th glyph. */
3655 string_range = CTRunGetStringRange (ctrun); 3588 string_range = CTRunGetStringRange (ctrun);
3656 min_location = string_range.location + string_range.length; 3589 min_location = string_range.location + string_range.length;
3657 for (i = 0; i < glyph_count; i++) 3590 for (i = 0; i < glyph_count; i++)
3658 { 3591 {
3659 struct mac_glyph_layout *gl = glbuf + glyph_count - i - 1; 3592 struct mac_glyph_layout *gl = glbuf + glyph_count - i - 1;
3660 CFIndex glyph_index; 3593 CFIndex glyph_index;
3661 CFRange rng; 3594 CFRange rng;
3662 3595
3663 if (!RIGHT_TO_LEFT_P) 3596 if (!RIGHT_TO_LEFT_P)
3664 glyph_index = glyph_count - i - 1; 3597 glyph_index = glyph_count - i - 1;
3665 else 3598 else
3666 glyph_index = i; 3599 glyph_index = i;
3667 CTRunGetStringIndices (ctrun, CFRangeMake (glyph_index, 1), 3600 CTRunGetStringIndices (ctrun, CFRangeMake (glyph_index, 1),
3668 &gl->string_index); 3601 &gl->string_index);
3669 rng = 3602 rng =
3670 CFStringGetRangeOfComposedCharactersAtIndex (string, 3603 CFStringGetRangeOfComposedCharactersAtIndex (string,
3671 gl->string_index); 3604 gl->string_index);
3672 gl->comp_range.location = min_location; 3605 gl->comp_range.location = min_location;
3673 gl->comp_range.length = rng.location + rng.length; 3606 gl->comp_range.length = rng.location + rng.length;
3674 if (rng.location < min_location) 3607 if (rng.location < min_location)
3675 min_location = rng.location; 3608 min_location = rng.location;
3676 } 3609 }
3677 3610
3678 /* Fill the `comp_range' member of struct mac_glyph_layout, 3611 /* Fill the `comp_range' member of struct mac_glyph_layout,
3679 and setup a permutation for right-to-left text. */ 3612 and setup a permutation for right-to-left text. */
3680 comp_range = CFRangeMake (string_range.location, 0); 3613 comp_range = CFRangeMake (string_range.location, 0);
3681 range = CFRangeMake (0, 0); 3614 range = CFRangeMake (0, 0);
3682 while (1) 3615 while (1)
3683 { 3616 {
3684 struct mac_glyph_layout *gl = 3617 struct mac_glyph_layout *gl =
3685 glbuf + range.location + range.length; 3618 glbuf + range.location + range.length;
3686 3619
3687 if (gl->comp_range.length 3620 if (gl->comp_range.length
3688 > comp_range.location + comp_range.length) 3621 > comp_range.location + comp_range.length)
3689 comp_range.length = gl->comp_range.length - comp_range.location; 3622 comp_range.length = gl->comp_range.length - comp_range.location;
3690 min_location = gl->comp_range.location; 3623 min_location = gl->comp_range.location;
3691 range.length++; 3624 range.length++;
3692 3625
3693 if (min_location >= comp_range.location + comp_range.length) 3626 if (min_location >= comp_range.location + comp_range.length)
3694 { 3627 {
3695 comp_range.length = min_location - comp_range.location; 3628 comp_range.length = min_location - comp_range.location;
3696 for (i = 0; i < range.length; i++) 3629 for (i = 0; i < range.length; i++)
3697 { 3630 {
3698 glbuf[range.location + i].comp_range = comp_range; 3631 glbuf[range.location + i].comp_range = comp_range;
3699 if (RIGHT_TO_LEFT_P) 3632 if (RIGHT_TO_LEFT_P)
3700 permutation[range.location + i] = 3633 permutation[range.location + i] =
3701 range.location + range.length - i - 1; 3634 range.location + range.length - i - 1;
3702 } 3635 }
3703 3636
3704 comp_range = CFRangeMake (min_location, 0); 3637 comp_range = CFRangeMake (min_location, 0);
3705 range.location += range.length; 3638 range.location += range.length;
3706 range.length = 0; 3639 range.length = 0;
3707 if (range.location == glyph_count) 3640 if (range.location == glyph_count)
3708 break; 3641 break;
3709 } 3642 }
3710 } 3643 }
3711 3644
3712 /* Then fill the remaining members. */ 3645 /* Then fill the remaining members. */
3713 for (range = CFRangeMake (0, 1); range.location < glyph_count; 3646 for (range = CFRangeMake (0, 1); range.location < glyph_count;
3714 range.location++) 3647 range.location++)
3715 { 3648 {
3716 struct mac_glyph_layout *gl; 3649 struct mac_glyph_layout *gl;
3717 CGPoint position; 3650 CGPoint position;
3718 3651
3719 if (!RIGHT_TO_LEFT_P) 3652 if (!RIGHT_TO_LEFT_P)
3720 gl = glbuf + range.location; 3653 gl = glbuf + range.location;
3721 else 3654 else
3722 { 3655 {
3723 CFIndex src, dest; 3656 CFIndex src, dest;
3724 3657
3725 src = glyph_count - 1 - range.location; 3658 src = glyph_count - 1 - range.location;
3726 dest = permutation[src]; 3659 dest = permutation[src];
3727 gl = glbuf + dest; 3660 gl = glbuf + dest;
3728 if (src < dest) 3661 if (src < dest)
3729 { 3662 {
3730 CFIndex tmp = gl->string_index; 3663 CFIndex tmp = gl->string_index;
3731 3664
3732 gl->string_index = glbuf[src].string_index; 3665 gl->string_index = glbuf[src].string_index;
3733 glbuf[src].string_index = tmp; 3666 glbuf[src].string_index = tmp;
3734 } 3667 }
3735 } 3668 }
3736 CTRunGetGlyphs (ctrun, range, &gl->glyph_id); 3669 CTRunGetGlyphs (ctrun, range, &gl->glyph_id);
3737 3670
3738 CTRunGetPositions (ctrun, range, &position); 3671 CTRunGetPositions (ctrun, range, &position);
3739 gl->advance_delta = position.x - total_advance; 3672 gl->advance_delta = position.x - total_advance;
3740 gl->baseline_delta = position.y; 3673 gl->baseline_delta = position.y;
3741 gl->advance = (gl->advance_delta 3674 gl->advance = (gl->advance_delta
3742 + CTRunGetTypographicBounds (ctrun, range, 3675 + CTRunGetTypographicBounds (ctrun, range,
3743 NULL, NULL, NULL)); 3676 NULL, NULL, NULL));
3744 total_advance += gl->advance; 3677 total_advance += gl->advance;
3745 } 3678 }
3746 3679
3747 if (RIGHT_TO_LEFT_P) 3680 if (RIGHT_TO_LEFT_P)
3748 xfree (permutation); 3681 xfree (permutation);
3749 3682
3750#undef RIGHT_TO_LEFT_P 3683#undef RIGHT_TO_LEFT_P
3751 3684
3752 total_glyph_count += glyph_count; 3685 total_glyph_count += glyph_count;
3753 } 3686 }
3754 3687
3755 result = used; 3688 result = used;
3756 } 3689 }
@@ -3765,7 +3698,7 @@ mac_ctfont_shape (CTFontRef font, CFStringRef string,
3765#if USE_CT_GLYPH_INFO 3698#if USE_CT_GLYPH_INFO
3766static CGGlyph 3699static CGGlyph
3767mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, 3700mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3768 CGFontIndex cid) 3701 CGFontIndex cid)
3769{ 3702{
3770 CGGlyph result = kCGFontIndexInvalid; 3703 CGGlyph result = kCGFontIndexInvalid;
3771 UniChar characters[] = {0xfffd}; 3704 UniChar characters[] = {0xfffd};
@@ -3779,27 +3712,27 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3779 if (string) 3712 if (string)
3780 { 3713 {
3781 CTGlyphInfoRef glyph_info = 3714 CTGlyphInfoRef glyph_info =
3782 CTGlyphInfoCreateWithCharacterIdentifier (cid, collection, string); 3715 CTGlyphInfoCreateWithCharacterIdentifier (cid, collection, string);
3783 CFDictionaryRef attributes = NULL; 3716 CFDictionaryRef attributes = NULL;
3784 3717
3785 if (glyph_info) 3718 if (glyph_info)
3786 { 3719 {
3787 CFStringRef keys[] = {kCTFontAttributeName, 3720 CFStringRef keys[] = {kCTFontAttributeName,
3788 kCTGlyphInfoAttributeName}; 3721 kCTGlyphInfoAttributeName};
3789 CFTypeRef values[] = {font, glyph_info}; 3722 CFTypeRef values[] = {font, glyph_info};
3790 3723
3791 attributes = CFDictionaryCreate (NULL, (const void **) keys, 3724 attributes = CFDictionaryCreate (NULL, (const void **) keys,
3792 (const void **) values, 3725 (const void **) values,
3793 ARRAYELTS (keys), 3726 ARRAYELTS (keys),
3794 &kCFTypeDictionaryKeyCallBacks, 3727 &kCFTypeDictionaryKeyCallBacks,
3795 &kCFTypeDictionaryValueCallBacks); 3728 &kCFTypeDictionaryValueCallBacks);
3796 CFRelease (glyph_info); 3729 CFRelease (glyph_info);
3797 } 3730 }
3798 if (attributes) 3731 if (attributes)
3799 { 3732 {
3800 attr_string = CFAttributedStringCreate (NULL, string, attributes); 3733 attr_string = CFAttributedStringCreate (NULL, string, attributes);
3801 CFRelease (attributes); 3734 CFRelease (attributes);
3802 } 3735 }
3803 CFRelease (string); 3736 CFRelease (string);
3804 } 3737 }
3805 if (attr_string) 3738 if (attr_string)
@@ -3812,24 +3745,24 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3812 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3745 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3813 3746
3814 if (CFArrayGetCount (runs) > 0) 3747 if (CFArrayGetCount (runs) > 0)
3815 { 3748 {
3816 CTRunRef run = CFArrayGetValueAtIndex (runs, 0); 3749 CTRunRef run = CFArrayGetValueAtIndex (runs, 0);
3817 CFDictionaryRef attributes = CTRunGetAttributes (run); 3750 CFDictionaryRef attributes = CTRunGetAttributes (run);
3818 3751
3819 if (attributes) 3752 if (attributes)
3820 { 3753 {
3821 CTFontRef font_in_run = 3754 CTFontRef font_in_run =
3822 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3755 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3823 3756
3824 if (font_in_run 3757 if (font_in_run
3825 && mac_ctfont_equal_in_postscript_name (font_in_run, font)) 3758 && mac_ctfont_equal_in_postscript_name (font_in_run, font))
3826 { 3759 {
3827 CTRunGetGlyphs (run, CFRangeMake (0, 1), &result); 3760 CTRunGetGlyphs (run, CFRangeMake (0, 1), &result);
3828 if (result >= CTFontGetGlyphCount (font)) 3761 if (result >= CTFontGetGlyphCount (font))
3829 result = kCGFontIndexInvalid; 3762 result = kCGFontIndexInvalid;
3830 } 3763 }
3831 } 3764 }
3832 } 3765 }
3833 CFRelease (ctline); 3766 CFRelease (ctline);
3834 } 3767 }
3835 3768
@@ -3837,41 +3770,6 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3837} 3770}
3838#endif 3771#endif
3839 3772
3840#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3841static inline int
3842mac_font_family_group (CFStringRef family)
3843{
3844 if (CFStringHasPrefix (family, CFSTR ("#")))
3845 return 2;
3846 else
3847 {
3848 CFRange range;
3849
3850 range = CFStringFind (family, CFSTR ("Apple"),
3851 kCFCompareCaseInsensitive | kCFCompareAnchored);
3852 if (range.location != kCFNotFound)
3853 return 1;
3854
3855 return 0;
3856 }
3857}
3858
3859static CFComparisonResult
3860mac_font_family_compare (const void *val1, const void *val2, void *context)
3861{
3862 CFStringRef family1 = (CFStringRef) val1, family2 = (CFStringRef) val2;
3863 int group1, group2;
3864
3865 group1 = mac_font_family_group (family1);
3866 group2 = mac_font_family_group (family2);
3867 if (group1 < group2)
3868 return kCFCompareLessThan;
3869 if (group1 > group2)
3870 return kCFCompareGreaterThan;
3871 return CFStringCompare (family1, family2, kCFCompareCaseInsensitive);
3872}
3873#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */
3874
3875static CFArrayRef 3773static CFArrayRef
3876mac_font_copy_default_descriptors_for_language (CFStringRef language) 3774mac_font_copy_default_descriptors_for_language (CFStringRef language)
3877{ 3775{
@@ -3883,22 +3781,22 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3883#endif 3781#endif
3884 { 3782 {
3885 CTFontRef user_font = 3783 CTFontRef user_font =
3886 CTFontCreateUIFontForLanguage (kCTFontUserFontType, 0, language); 3784 CTFontCreateUIFontForLanguage (kCTFontUserFontType, 0, language);
3887 3785
3888 if (user_font) 3786 if (user_font)
3889 { 3787 {
3890 CFArrayRef languages = 3788 CFArrayRef languages =
3891 CFArrayCreate (NULL, (const void **) &language, 1, 3789 CFArrayCreate (NULL, (const void **) &language, 1,
3892 &kCFTypeArrayCallBacks); 3790 &kCFTypeArrayCallBacks);
3893 3791
3894 if (languages) 3792 if (languages)
3895 { 3793 {
3896 result = CTFontCopyDefaultCascadeListForLanguages (user_font, 3794 result = CTFontCopyDefaultCascadeListForLanguages (user_font,
3897 languages); 3795 languages);
3898 CFRelease (languages); 3796 CFRelease (languages);
3899 } 3797 }
3900 CFRelease (user_font); 3798 CFRelease (user_font);
3901 } 3799 }
3902 } 3800 }
3903#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 3801#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
3904 else /* CTFontCopyDefaultCascadeListForLanguages == NULL */ 3802 else /* CTFontCopyDefaultCascadeListForLanguages == NULL */
@@ -3909,55 +3807,55 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3909 CFIndex i; 3807 CFIndex i;
3910 3808
3911 for (i = 0; macfont_language_default_font_names[i].language; i++) 3809 for (i = 0; macfont_language_default_font_names[i].language; i++)
3912 { 3810 {
3913 if (CFEqual (macfont_language_default_font_names[i].language, 3811 if (CFEqual (macfont_language_default_font_names[i].language,
3914 language)) 3812 language))
3915 { 3813 {
3916 CFMutableArrayRef descriptors = 3814 CFMutableArrayRef descriptors =
3917 CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 3815 CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
3918 3816
3919 if (descriptors) 3817 if (descriptors)
3920 { 3818 {
3921 CFIndex j; 3819 CFIndex j;
3922 3820
3923 for (j = 0; 3821 for (j = 0;
3924 macfont_language_default_font_names[i].font_names[j]; 3822 macfont_language_default_font_names[i].font_names[j];
3925 j++) 3823 j++)
3926 { 3824 {
3927 CFDictionaryRef attributes = 3825 CFDictionaryRef attributes =
3928 CFDictionaryCreate (NULL, 3826 CFDictionaryCreate (NULL,
3929 ((const void **) 3827 ((const void **)
3930 &MAC_FONT_NAME_ATTRIBUTE), 3828 &MAC_FONT_NAME_ATTRIBUTE),
3931 ((const void **) 3829 ((const void **)
3932 &macfont_language_default_font_names[i].font_names[j]), 3830 &macfont_language_default_font_names[i].font_names[j]),
3933 1, &kCFTypeDictionaryKeyCallBacks, 3831 1, &kCFTypeDictionaryKeyCallBacks,
3934 &kCFTypeDictionaryValueCallBacks); 3832 &kCFTypeDictionaryValueCallBacks);
3935 3833
3936 if (attributes) 3834 if (attributes)
3937 { 3835 {
3938 FontDescriptorRef pat_desc = 3836 FontDescriptorRef pat_desc =
3939 mac_font_descriptor_create_with_attributes (attributes); 3837 mac_font_descriptor_create_with_attributes (attributes);
3940 3838
3941 if (pat_desc) 3839 if (pat_desc)
3942 { 3840 {
3943 FontDescriptorRef descriptor = 3841 FontDescriptorRef descriptor =
3944 mac_font_descriptor_create_matching_font_descriptor (pat_desc, NULL); 3842 mac_font_descriptor_create_matching_font_descriptor (pat_desc, NULL);
3945 3843
3946 if (descriptor) 3844 if (descriptor)
3947 { 3845 {
3948 CFArrayAppendValue (descriptors, descriptor); 3846 CFArrayAppendValue (descriptors, descriptor);
3949 CFRelease (descriptor); 3847 CFRelease (descriptor);
3950 } 3848 }
3951 CFRelease (pat_desc); 3849 CFRelease (pat_desc);
3952 } 3850 }
3953 CFRelease (attributes); 3851 CFRelease (attributes);
3954 } 3852 }
3955 } 3853 }
3956 result = descriptors; 3854 result = descriptors;
3957 } 3855 }
3958 break; 3856 break;
3959 } 3857 }
3960 } 3858 }
3961 } 3859 }
3962#endif 3860#endif
3963 3861
@@ -3966,7 +3864,7 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3966 3864
3967static CFStringRef 3865static CFStringRef
3968mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, 3866mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
3969 CFArrayRef languages) 3867 CFArrayRef languages)
3970{ 3868{
3971 CFStringRef result = NULL; 3869 CFStringRef result = NULL;
3972 CFStringRef language = CFArrayGetValueAtIndex (languages, 0); 3870 CFStringRef language = CFArrayGetValueAtIndex (languages, 0);
@@ -3978,29 +3876,29 @@ mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
3978 CFIndex i, count = CFArrayGetCount (descriptors); 3876 CFIndex i, count = CFArrayGetCount (descriptors);
3979 3877
3980 for (i = 0; i < count; i++) 3878 for (i = 0; i < count; i++)
3981 { 3879 {
3982 FontDescriptorRef descriptor = 3880 FontDescriptorRef descriptor =
3983 CFArrayGetValueAtIndex (descriptors, i); 3881 CFArrayGetValueAtIndex (descriptors, i);
3984 3882
3985 if (macfont_supports_charset_and_languages_p (descriptor, charset, 3883 if (macfont_supports_charset_and_languages_p (descriptor, charset,
3986 Qnil, languages)) 3884 Qnil, languages))
3987 { 3885 {
3988 CFStringRef family = 3886 CFStringRef family =
3989 mac_font_descriptor_copy_attribute (descriptor, 3887 mac_font_descriptor_copy_attribute (descriptor,
3990 MAC_FONT_FAMILY_NAME_ATTRIBUTE); 3888 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
3991 if (family) 3889 if (family)
3992 { 3890 {
3993 if (!CFStringHasPrefix (family, CFSTR (".")) 3891 if (!CFStringHasPrefix (family, CFSTR ("."))
3994 && !CFEqual (family, CFSTR ("LastResort"))) 3892 && !CFEqual (family, CFSTR ("LastResort")))
3995 { 3893 {
3996 result = family; 3894 result = family;
3997 break; 3895 break;
3998 } 3896 }
3999 else 3897 else
4000 CFRelease (family); 3898 CFRelease (family);
4001 } 3899 }
4002 } 3900 }
4003 } 3901 }
4004 CFRelease (descriptors); 3902 CFRelease (descriptors);
4005 } 3903 }
4006 3904
@@ -4022,13 +3920,10 @@ mac_register_font_driver (struct frame *f)
4022 register_font_driver (&macfont_driver, f); 3920 register_font_driver (&macfont_driver, f);
4023} 3921}
4024 3922
4025#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
4026
4027 3923
4028void 3924void
4029syms_of_macfont (void) 3925syms_of_macfont (void)
4030{ 3926{
4031#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
4032 static struct font_driver mac_font_driver; 3927 static struct font_driver mac_font_driver;
4033 3928
4034 DEFSYM (Qmac_ct, "mac-ct"); 3929 DEFSYM (Qmac_ct, "mac-ct");
@@ -4037,5 +3932,4 @@ syms_of_macfont (void)
4037 3932
4038 DEFSYM (QCdestination, ":destination"); 3933 DEFSYM (QCdestination, ":destination");
4039 DEFSYM (QCminspace, ":minspace"); 3934 DEFSYM (QCminspace, ":minspace");
4040#endif
4041} 3935}