summaryrefslogtreecommitdiff
path: root/src/macfont.m
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2013-11-07 23:21:08 +0100
committerJan Djärv <jan.h.d@swipnet.se>2013-11-07 23:21:08 +0100
commit5ee2921081ec21d18b1a190bdacb3ebd3bfdc294 (patch)
tree9fbf407c98c2c8bdd9657e631c2a68cf59ae33f4 /src/macfont.m
parent3220d5279d488e51afb3a49cda5c48fa9ca4e36c (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.m364
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)
{