From: Jan Djärv Date: Thu, 7 Nov 2013 22:21:08 +0000 (+0100) Subject: Import macfont changes from mac-port 4.5. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~912 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5ee2921081ec21d18b1a190bdacb3ebd3bfdc294;p=emacs.git 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index 2f774b87b13..2914c23ef0e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2013-11-07 Jan Djärv + + Import changes from mac-port 4.5. + * 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. + + * macfont.h (kCTVersionNumber10_9): Define if not defined. + 2013-11-07 Paul Eggert Port to C11 aligned_alloc, and fix some integer overflows. diff --git a/src/macfont.h b/src/macfont.h index 141d60bfb0a..4b57c18692e 100644 --- a/src/macfont.h +++ b/src/macfont.h @@ -134,6 +134,9 @@ enum { #define mac_nsctfont_copy_font_descriptor CTFontCopyFontDescriptor +#ifndef kCTVersionNumber10_9 +#define kCTVersionNumber10_9 0x00060000 +#endif #define MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE \ (CFSTR ("MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE")) diff --git a/src/macfont.m b/src/macfont.m index c284b3086f8..10623eb12fe 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) {