diff options
author | Jan Djärv <jan.h.d@swipnet.se> | 2013-11-07 23:21:08 +0100 |
---|---|---|
committer | Jan Djärv <jan.h.d@swipnet.se> | 2013-11-07 23:21:08 +0100 |
commit | 5ee2921081ec21d18b1a190bdacb3ebd3bfdc294 (patch) | |
tree | 9fbf407c98c2c8bdd9657e631c2a68cf59ae33f4 /src/macfont.m | |
parent | 3220d5279d488e51afb3a49cda5c48fa9ca4e36c (diff) |
Import macfont changes from mac-port 4.5.
* macfont.h (kCTVersionNumber10_9): Define if not defined.
* macfont.m (mac_font_copy_default_descriptors_for_language)
(mac_font_copy_default_name_for_charset_and_languages): Declare.
(cf_charset_table): big-5-0 has uniquifier 0x4EDC.
(macfont_language_default_font_names): New.
(macfont_list): Rearrange language/charset code.
(macfont_close): Don't check for macfont_info->cache.
(mac_ctfont_create_preferred_family_for_attributes): New font
selection code, call
mac_font_copy_default_name_for_charset_and_languages.
(mac_font_copy_default_descriptors_for_language)
(mac_font_copy_default_name_for_charset_and_languages): New functions.
Diffstat (limited to 'src/macfont.m')
-rw-r--r-- | src/macfont.m | 364 |
1 files changed, 277 insertions, 87 deletions
diff --git a/src/macfont.m b/src/macfont.m index c284b3086f..10623eb12f 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -57,6 +57,13 @@ static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef, static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef); static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef, struct mac_glyph_layout *, CFIndex); +static CFArrayRef +mac_font_copy_default_descriptors_for_language (CFStringRef language); + +static CFStringRef +mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, + CFArrayRef languages); + #if USE_CT_GLYPH_INFO static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef, CTCharacterCollection, @@ -676,7 +683,7 @@ static struct { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }}, { "iso8859-16", { 0x00A0, 0x0218}}, { "gb2312.1980-0", { 0x4E13 }, CFSTR ("zh-Hans")}, - { "big5-0", { /* 0xF6B1 in ftfont.c */ 0xF7E5 }, CFSTR ("zh-Hant") }, + { "big5-0", { /* 0xF6B1 in ftfont.c */ 0x4EDC }, CFSTR ("zh-Hant") }, { "jisx0208.1983-0", { 0x4E55 }, CFSTR ("ja")}, { "ksc5601.1987-0", { 0xAC00 }, CFSTR ("ko")}, { "cns11643.1992-1", { 0xFE32 }, CFSTR ("zh-Hant")}, @@ -700,9 +707,31 @@ static struct { NULL } }; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 +static const struct +{ + CFStringRef language; + CFStringRef font_names[3]; +} macfont_language_default_font_names[] = { + { CFSTR ("ja"), { CFSTR ("HiraKakuProN-W3"), /* 10.5 - 10.9 */ + CFSTR ("HiraKakuPro-W3"), /* 10.4 */ + NULL }}, + { CFSTR ("ko"), { CFSTR ("AppleSDGothicNeo-Regular"), /* 10.8 - 10.9 */ + CFSTR ("AppleGothic"), /* 10.4 - 10.7 */ + NULL }}, + { CFSTR ("zh-Hans"), { CFSTR ("STHeitiSC-Light"), /* 10.6 - 10.9 */ + CFSTR ("STXihei"), /* 10.4 - 10.5 */ + NULL }}, + { CFSTR ("zh-Hant"), { CFSTR ("STHeitiTC-Light"), /* 10.6 - 10.9 */ + CFSTR ("LiHeiPro"), /* 10.4 - 10.5 */ + NULL }}, + { NULL } +}; +#endif + static CGFloat macfont_antialias_threshold; -void +static void macfont_update_antialias_threshold (void) { int threshold; @@ -2052,33 +2081,7 @@ macfont_list (struct frame *f, Lisp_Object spec) if (! attributes) goto finish; - charset = ((CFCharacterSetRef) - CFDictionaryGetValue (attributes, - MAC_FONT_CHARACTER_SET_ATTRIBUTE)); - if (charset) - { - CFRetain (charset); - CFDictionaryRemoveValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE); - } - else - { - val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX)); - if (! NILP (val)) - { - val = assq_no_quit (XCDR (val), Vscript_representative_chars); - if (CONSP (val) && VECTORP (XCDR (val))) - chars = XCDR (val); - } - val = Qnil; - } - - languages = ((CFArrayRef) - CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE)); - if (languages) - { - CFRetain (languages); - CFDictionaryRemoveValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); - } + languages = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); if (INTEGERP (AREF (spec, FONT_SPACING_INDEX))) spacing = XINT (AREF (spec, FONT_SPACING_INDEX)); @@ -2162,6 +2165,31 @@ macfont_list (struct frame *f, Lisp_Object spec) } } + charset = CFDictionaryGetValue (attributes, + MAC_FONT_CHARACTER_SET_ATTRIBUTE); + if (charset) + { + CFRetain (charset); + CFDictionaryRemoveValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE); + } + else + { + val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX)); + if (! NILP (val)) + { + val = assq_no_quit (XCDR (val), Vscript_representative_chars); + if (CONSP (val) && VECTORP (XCDR (val))) + chars = XCDR (val); + } + val = Qnil; + } + + if (languages) + { + CFRetain (languages); + CFDictionaryRemoveValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); + } + val = Qnil; extra = AREF (spec, FONT_EXTRA_INDEX); families_count = CFArrayGetCount (families); @@ -2590,25 +2618,20 @@ static void macfont_close (struct font *font) { struct macfont_info *macfont_info = (struct macfont_info *) font; + int i; - if (macfont_info->cache) - { - int i; - - block_input (); - CFRelease (macfont_info->macfont); - CGFontRelease (macfont_info->cgfont); - if (macfont_info->screen_font) - CFRelease (macfont_info->screen_font); - macfont_release_cache (macfont_info->cache); - macfont_info->cache = NULL; - for (i = 0; i < macfont_info->metrics_nrows; i++) - if (macfont_info->metrics[i]) - xfree (macfont_info->metrics[i]); - if (macfont_info->metrics) - xfree (macfont_info->metrics); - unblock_input (); - } + block_input (); + CFRelease (macfont_info->macfont); + CGFontRelease (macfont_info->cgfont); + if (macfont_info->screen_font) + CFRelease (macfont_info->screen_font); + macfont_release_cache (macfont_info->cache); + for (i = 0; i < macfont_info->metrics_nrows; i++) + if (macfont_info->metrics[i]) + xfree (macfont_info->metrics[i]); + if (macfont_info->metrics) + xfree (macfont_info->metrics); + unblock_input (); } static int @@ -2798,7 +2821,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, return len; } -Lisp_Object +static Lisp_Object macfont_shape (Lisp_Object lgstring) { struct font *font; @@ -3335,49 +3358,80 @@ mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef attributes) if (charset_string && CFStringGetLength (charset_string) > 0) { - CFAttributedStringRef attr_string = NULL; - CTLineRef ctline = NULL; - CFDictionaryRef attrs = - CFDictionaryCreate (NULL, NULL, NULL, 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + CFStringRef keys[] = { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + kCTLanguageAttributeName +#else + CFSTR ("NSLanguage") +#endif + }; + CFTypeRef values[] = {NULL}; + CFIndex num_values = 0; + CFArrayRef languages + = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); - if (attrs) - { - attr_string = CFAttributedStringCreate (NULL, charset_string, attrs); - CFRelease (attrs); - } - if (attr_string) + if (languages && CFArrayGetCount (languages) > 0) { - ctline = CTLineCreateWithAttributedString (attr_string); - CFRelease (attr_string); + if (CTGetCoreTextVersion () >= kCTVersionNumber10_9) + values[num_values++] = CFArrayGetValueAtIndex (languages, 0); + else + { + CFCharacterSetRef charset = + CFDictionaryGetValue (attributes, + MAC_FONT_CHARACTER_SET_ATTRIBUTE); + + result = mac_font_copy_default_name_for_charset_and_languages (charset, languages); + } } - if (ctline) + if (result == NULL) { - CFArrayRef runs = CTLineGetGlyphRuns (ctline); - CFIndex i, nruns = CFArrayGetCount (runs); - CTFontRef font; - - for (i = 0; i < nruns; i++) + CFAttributedStringRef attr_string = NULL; + CTLineRef ctline = NULL; + CFDictionaryRef attrs + = CFDictionaryCreate (NULL, (const void **) keys, + (const void **) values, num_values, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (attrs) { - CTRunRef run = CFArrayGetValueAtIndex (runs, i); - CFDictionaryRef attributes = CTRunGetAttributes (run); - CTFontRef font_in_run; + attr_string = CFAttributedStringCreate (NULL, charset_string, + attrs); + CFRelease (attrs); + } + if (attr_string) + { + ctline = CTLineCreateWithAttributedString (attr_string); + CFRelease (attr_string); + } + if (ctline) + { + CFArrayRef runs = CTLineGetGlyphRuns (ctline); + CFIndex i, nruns = CFArrayGetCount (runs); + CTFontRef font; - if (attributes == NULL) - break; - font_in_run = - CFDictionaryGetValue (attributes, kCTFontAttributeName); - if (font_in_run == NULL) - break; - if (i == 0) - font = font_in_run; - else if (!mac_ctfont_equal_in_postscript_name (font, font_in_run)) - break; + for (i = 0; i < nruns; i++) + { + CTRunRef run = CFArrayGetValueAtIndex (runs, i); + CFDictionaryRef attributes = CTRunGetAttributes (run); + CTFontRef font_in_run; + + if (attributes == NULL) + break; + font_in_run = + CFDictionaryGetValue (attributes, kCTFontAttributeName); + if (font_in_run == NULL) + break; + if (i == 0) + font = font_in_run; + else if (!mac_ctfont_equal_in_postscript_name (font, + font_in_run)) + break; + } + if (nruns > 0 && i == nruns) + result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute); + CFRelease (ctline); } - if (nruns > 0 && i == nruns) - result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute); - CFRelease (ctline); } } @@ -3571,7 +3625,7 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string, return ctline; } -CFIndex +static CFIndex mac_ctfont_shape (CTFontRef font, CFStringRef string, struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len) { @@ -3724,7 +3778,7 @@ mac_ctfont_shape (CTFontRef font, CFStringRef string, created by CFStringCreateWithCharacters as of Mac OS X 10.5.8 and 10.6.3. For now, we use the NSGlyphInfo version instead. */ #if USE_CT_GLYPH_INFO -CGGlyph +static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, CGFontIndex cid) { @@ -3817,7 +3871,7 @@ mac_font_family_group (CFStringRef family) } } -CFComparisonResult +static CFComparisonResult mac_font_family_compare (const void *val1, const void *val2, void *context) { CFStringRef family1 = (CFStringRef) val1, family2 = (CFStringRef) val2; @@ -3833,6 +3887,142 @@ mac_font_family_compare (const void *val1, const void *val2, void *context) } #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +static CFArrayRef +mac_font_copy_default_descriptors_for_language (CFStringRef language) +{ + CFArrayRef result = NULL; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + if (CTFontCopyDefaultCascadeListForLanguages != NULL) +#endif + { + CTFontRef user_font = + CTFontCreateUIFontForLanguage (kCTFontUserFontType, 0, language); + + if (user_font) + { + CFArrayRef languages = + CFArrayCreate (NULL, (const void **) &language, 1, + &kCFTypeArrayCallBacks); + + if (languages) + { + result = CTFontCopyDefaultCascadeListForLanguages (user_font, + languages); + CFRelease (languages); + } + CFRelease (user_font); + } + } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + else /* CTFontCopyDefaultCascadeListForLanguages == NULL */ +#endif +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + { + CFIndex i; + + for (i = 0; macfont_language_default_font_names[i].language; i++) + { + if (CFStringCompare (macfont_language_default_font_names[i].language, + language, 0) == kCFCompareEqualTo) + { + CFMutableArrayRef descriptors = + CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); + + if (descriptors) + { + CFIndex j; + + for (j = 0; + macfont_language_default_font_names[i].font_names[j]; + j++) + { + CFDictionaryRef attributes = + CFDictionaryCreate (NULL, + ((const void **) + &MAC_FONT_NAME_ATTRIBUTE), + ((const void **) + &macfont_language_default_font_names[i].font_names[j]), + 1, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (attributes) + { + FontDescriptorRef pat_desc = + mac_font_descriptor_create_with_attributes (attributes); + + if (pat_desc) + { + FontDescriptorRef descriptor = + mac_font_descriptor_create_matching_font_descriptor (pat_desc, NULL); + + if (descriptor) + { + CFArrayAppendValue (descriptors, descriptor); + CFRelease (descriptor); + } + CFRelease (pat_desc); + } + CFRelease (attributes); + } + } + result = descriptors; + } + break; + } + } + } +#endif + + return result; +} + +static CFStringRef +mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, + CFArrayRef languages) +{ + CFStringRef result = NULL; + CFStringRef language = CFArrayGetValueAtIndex (languages, 0); + CFArrayRef descriptors = + mac_font_copy_default_descriptors_for_language (language); + + if (descriptors) + { + CFIndex i, count = CFArrayGetCount (descriptors); + + for (i = 0; i < count; i++) + { + FontDescriptorRef descriptor = + CFArrayGetValueAtIndex (descriptors, i); + + if (macfont_supports_charset_and_languages_p (descriptor, charset, + Qnil, languages)) + { + CFStringRef family = + mac_font_descriptor_copy_attribute (descriptor, + MAC_FONT_FAMILY_NAME_ATTRIBUTE); + if (family) + { + if (!CFStringHasPrefix (family, CFSTR (".")) + && (CFStringCompare (family, CFSTR ("LastResort"), 0) + != kCFCompareEqualTo)) + { + result = family; + break; + } + else + CFRelease (family); + } + } + } + CFRelease (descriptors); + } + + return result; +} + void * macfont_get_nsctfont (struct font *font) { |