diff options
Diffstat (limited to 'src/macfont.m')
| -rw-r--r-- | src/macfont.m | 3270 |
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 | ||
| 43 | static struct font_driver macfont_driver; | 41 | static 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. */ |
| 46 | static Lisp_Object Qmac_ct; | 44 | static Lisp_Object Qmac_ct; |
| 47 | 45 | ||
| 48 | static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph); | 46 | static 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); | |||
| 50 | static CFArrayRef mac_ctfont_create_available_families (void); | 48 | static CFArrayRef mac_ctfont_create_available_families (void); |
| 51 | static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef); | 49 | static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef); |
| 52 | static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef, | 50 | static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef, |
| 53 | CTFontRef); | 51 | CTFontRef); |
| 54 | static CFComparisonResult mac_font_family_compare (const void *, | 52 | static CFComparisonResult mac_font_family_compare (const void *, |
| 55 | const void *, void *); | 53 | const void *, void *); |
| 56 | static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef, | 54 | static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef, |
| 57 | CFArrayRef); | 55 | CFArrayRef); |
| 58 | static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef); | 56 | static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef); |
| 59 | static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef, | 57 | static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef, |
| 60 | struct mac_glyph_layout *, CFIndex); | 58 | struct mac_glyph_layout *, CFIndex); |
| 61 | static CFArrayRef | 59 | static CFArrayRef |
| 62 | mac_font_copy_default_descriptors_for_language (CFStringRef language); | 60 | mac_font_copy_default_descriptors_for_language (CFStringRef language); |
| 63 | 61 | ||
| 64 | static CFStringRef | 62 | static CFStringRef |
| 65 | mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, | 63 | mac_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 |
| 69 | static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef, | 67 | static 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}; | |||
| 129 | static const CGFloat synthetic_bold_factor = 0.024; | 127 | static const CGFloat synthetic_bold_factor = 0.024; |
| 130 | 128 | ||
| 131 | static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef, | 129 | static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef, |
| 132 | FontSymbolicTraits *); | 130 | FontSymbolicTraits *); |
| 133 | static void macfont_store_descriptor_attributes (FontDescriptorRef, | 131 | static void macfont_store_descriptor_attributes (FontDescriptorRef, |
| 134 | Lisp_Object); | 132 | Lisp_Object); |
| 135 | static Lisp_Object macfont_descriptor_entity (FontDescriptorRef, | 133 | static Lisp_Object macfont_descriptor_entity (FontDescriptorRef, |
| 136 | Lisp_Object, | 134 | Lisp_Object, |
| 137 | FontSymbolicTraits); | 135 | FontSymbolicTraits); |
| 138 | static CFStringRef macfont_create_family_with_symbol (Lisp_Object); | 136 | static CFStringRef macfont_create_family_with_symbol (Lisp_Object); |
| 139 | static int macfont_glyph_extents (struct font *, CGGlyph, | 137 | static int macfont_glyph_extents (struct font *, CGGlyph, |
| 140 | struct font_metrics *, CGFloat *, int); | 138 | struct font_metrics *, CGFloat *, int); |
| 141 | static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object); | 139 | static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object); |
| 142 | static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef, | 140 | static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef, |
| 143 | CFCharacterSetRef, | 141 | CFCharacterSetRef, |
| 144 | Lisp_Object, | 142 | Lisp_Object, |
| 145 | CFArrayRef); | 143 | CFArrayRef); |
| 146 | static CFIndex macfont_closest_traits_index (CFArrayRef, | 144 | static Boolean macfont_closest_traits_index_p (CFArrayRef, FontSymbolicTraits, |
| 147 | FontSymbolicTraits); | 145 | CFIndex); |
| 148 | static CFDataRef mac_font_copy_uvs_table (FontRef); | 146 | static CFDataRef mac_font_copy_uvs_table (FontRef); |
| 149 | static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char, | 147 | static 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 | |||
| 206 | cfstring_create_with_string_noencode (Lisp_Object s) | 204 | cfstring_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 | ||
| 227 | static CGGlyph | 225 | static CGGlyph |
| 228 | mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection, | 226 | mac_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 | ||
| 293 | static Boolean | 291 | static Boolean |
| 294 | mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent, | 292 | mac_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 | ||
| 343 | static CFIndex | 341 | static CFIndex |
| 344 | mac_font_shape_1 (NSFont *font, NSString *string, | 342 | mac_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 | ||
| 607 | static CFIndex | 605 | static CFIndex |
| 608 | mac_screen_font_shape (ScreenFontRef font, CFStringRef string, | 606 | mac_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 | ||
| 617 | static CGColorRef | 615 | static 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 | ||
| 772 | static Boolean | 771 | static Boolean |
| 773 | cfnumber_get_font_symbolic_traits_value (CFNumberRef number, | 772 | cfnumber_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 | ||
| 790 | static void | 789 | static void |
| 791 | macfont_store_descriptor_attributes (FontDescriptorRef desc, | 790 | macfont_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 | ||
| 872 | static Lisp_Object | 871 | static Lisp_Object |
| 873 | macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra, | 872 | macfont_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 | ||
| 1013 | enum metrics_status | 999 | enum 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 | ||
| 1029 | static int | 1015 | static int |
| 1030 | macfont_glyph_extents (struct font *font, CGGlyph glyph, | 1016 | macfont_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 *); | |||
| 1220 | static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef); | 1206 | static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef); |
| 1221 | static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char); | 1207 | static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char); |
| 1222 | static CGGlyph macfont_get_glyph_for_cid (struct font *font, | 1208 | static CGGlyph macfont_get_glyph_for_cid (struct font *font, |
| 1223 | CharacterCollection, CGFontIndex); | 1209 | CharacterCollection, CGFontIndex); |
| 1224 | static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *); | 1210 | static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *); |
| 1225 | 1211 | ||
| 1226 | static struct macfont_cache * | 1212 | static 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 | ||
| 1484 | static CGGlyph | 1460 | static CGGlyph |
| 1485 | macfont_get_glyph_for_cid (struct font *font, CharacterCollection collection, | 1461 | macfont_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); | |||
| 1553 | static void macfont_close (struct font *); | 1529 | static void macfont_close (struct font *); |
| 1554 | static int macfont_has_char (Lisp_Object, int); | 1530 | static int macfont_has_char (Lisp_Object, int); |
| 1555 | static unsigned macfont_encode_char (struct font *, int); | 1531 | static unsigned macfont_encode_char (struct font *, int); |
| 1556 | static int macfont_text_extents (struct font *, unsigned int *, int, | 1532 | static void macfont_text_extents (struct font *, unsigned int *, int, |
| 1557 | struct font_metrics *); | 1533 | struct font_metrics *); |
| 1558 | static int macfont_draw (struct glyph_string *, int, int, int, int, bool); | 1534 | static int macfont_draw (struct glyph_string *, int, int, int, int, bool); |
| 1559 | static Lisp_Object macfont_shape (Lisp_Object); | 1535 | static Lisp_Object macfont_shape (Lisp_Object); |
| 1560 | static int macfont_variation_glyphs (struct font *, int c, | 1536 | static int macfont_variation_glyphs (struct font *, int c, |
| 1561 | unsigned variations[256]); | 1537 | unsigned variations[256]); |
| 1562 | static void macfont_filter_properties (Lisp_Object, Lisp_Object); | 1538 | static void macfont_filter_properties (Lisp_Object, Lisp_Object); |
| 1563 | 1539 | ||
| 1564 | static struct font_driver macfont_driver = | 1540 | static 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 | ||
| 1686 | static struct OpenTypeSpec * | 1662 | static 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 | ||
| 1974 | static Boolean | 1950 | static Boolean |
| 1975 | macfont_supports_charset_and_languages_p (FontDescriptorRef desc, | 1951 | macfont_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 | ||
| 2015 | static CFIndex | 1991 | static int |
| 2016 | macfont_closest_traits_index (CFArrayRef traits_array, | 1992 | macfont_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 | |||
| 2011 | static Boolean | ||
| 2012 | macfont_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 | ||
| 2049 | static Lisp_Object | 2036 | static 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 | |||
| 2426 | macfont_free_entity (Lisp_Object entity) | 2414 | macfont_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 | |||
| 2598 | macfont_close (struct font *font) | 2587 | macfont_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 | ||
| 2617 | static int | 2611 | static 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 | ||
| 2656 | static int | 2650 | static void |
| 2657 | macfont_text_extents (struct font *font, unsigned int *code, int nglyphs, | 2651 | macfont_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 | ||
| 2691 | static int | 2683 | static int |
| 2692 | macfont_draw (struct glyph_string *s, int from, int to, int x, int y, | 2684 | macfont_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 | ||
| 2975 | struct unicode_value_range | 2968 | struct 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 | ||
| 2987 | struct uvs_mapping | 2980 | struct 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 | ||
| 3141 | static void | 3134 | static void |
| 3142 | mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c, | 3135 | mac_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 | ||
| 3246 | static int | 3231 | static 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 | ||
| 3307 | static Boolean | 3292 | static Boolean |
| 3308 | mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor, | 3293 | mac_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 | |||
| 3427 | mac_ctfont_get_advance_width_for_glyph (CTFontRef font, CGGlyph glyph) | 3412 | mac_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 | ||
| 3433 | static inline CGRect | 3418 | static inline CGRect |
| 3434 | mac_ctfont_get_bounding_rect_for_glyph (CTFontRef font, CGGlyph glyph) | 3419 | mac_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 | ||
| 3440 | static CFArrayRef | 3425 | static 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 | ||
| 3524 | static Boolean | 3457 | static 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 | ||
| 3549 | static CTLineRef | 3482 | static CTLineRef |
| 3550 | mac_ctfont_create_line_with_string_and_font (CFStringRef string, | 3483 | mac_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 | ||
| 3613 | static CFIndex | 3546 | static CFIndex |
| 3614 | mac_ctfont_shape (CTFontRef font, CFStringRef string, | 3547 | mac_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 |
| 3766 | static CGGlyph | 3699 | static CGGlyph |
| 3767 | mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, | 3700 | mac_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 | ||
| 3841 | static inline int | ||
| 3842 | mac_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 | |||
| 3859 | static CFComparisonResult | ||
| 3860 | mac_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 | |||
| 3875 | static CFArrayRef | 3773 | static CFArrayRef |
| 3876 | mac_font_copy_default_descriptors_for_language (CFStringRef language) | 3774 | mac_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 | ||
| 3967 | static CFStringRef | 3865 | static CFStringRef |
| 3968 | mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, | 3866 | mac_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 | ||
| 4028 | void | 3924 | void |
| 4029 | syms_of_macfont (void) | 3925 | syms_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 | } |