X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a67c4ae05909874c97f86b11dcb8ddc88b3e960c..47571310770234371eb6e361214056efd1b67137:/src/macfont.m diff --git a/src/macfont.m b/src/macfont.m index c284b3086f..60f261d554 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -1,5 +1,5 @@ /* Font driver on Mac OSX Core text. - Copyright (C) 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -30,6 +30,7 @@ Original author: YAMAMOTO Mitsuharu #include "composite.h" #include "fontset.h" #include "font.h" +#include "termchar.h" #include "nsgui.h" #include "nsterm.h" #include "macfont.h" @@ -57,6 +58,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, @@ -77,7 +85,7 @@ static Lisp_Object QCminspace; struct macfont_metrics; -/* The actual structure for Mac font that can be casted to struct font. */ +/* The actual structure for Mac font that can be cast to struct font. */ struct macfont_info { @@ -88,11 +96,11 @@ struct macfont_info struct macfont_cache *cache; struct macfont_metrics **metrics; short metrics_nrows; - unsigned synthetic_italic_p : 1; - unsigned synthetic_bold_p : 1; + bool_bf synthetic_italic_p : 1; + bool_bf synthetic_bold_p : 1; unsigned spacing : 2; unsigned antialias : 2; - unsigned color_bitmap_p : 1; + bool_bf color_bitmap_p : 1; }; /* Values for the `spacing' member in `struct macfont_info'. */ @@ -229,8 +237,7 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection, unichar characters[] = {0xfffd}; NSString *string = [NSString stringWithCharacters:characters - length:(sizeof (characters) - / sizeof (characters[0]))]; + length:ARRAYELTS (characters)]; NSGlyphInfo *glyphInfo = [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid collection:collection @@ -623,24 +630,21 @@ get_cgcolor(unsigned long idx, struct frame *f) return cgColor; } -#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, s) \ +#define CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND(context, face, f) \ do { \ - CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (s->face), \ - s->f); \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \ CGContextSetFillColorWithColor (context, refcol_) ; \ CGColorRelease (refcol_); \ } while (0) -#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, s) \ +#define CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND(context, face, f) \ do { \ - CGColorRef refcol_ = get_cgcolor (NS_FACE_BACKGROUND (s->face),\ - s->f); \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_BACKGROUND (face), f); \ CGContextSetFillColorWithColor (context, refcol_); \ CGColorRelease (refcol_); \ } while (0) -#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, s) \ +#define CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND(context, face, f) \ do { \ - CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (s->face),\ - s->f); \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \ CGContextSetStrokeColorWithColor (context, refcol_); \ CGColorRelease (refcol_); \ } while (0) @@ -676,7 +680,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 +704,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; @@ -750,7 +776,7 @@ cfnumber_get_font_symbolic_traits_value (CFNumberRef number, SInt64 sint64_value; /* Getting symbolic traits with kCFNumberSInt32Type is lossy on Mac - OS 10.6 when the value is greater than or equal to 1 << 31. */ + OS X 10.6 when the value is greater than or equal to 1 << 31. */ if (CFNumberGetValue (number, kCFNumberSInt64Type, &sint64_value)) { *sym_traits = (FontSymbolicTraits) sint64_value; @@ -799,7 +825,7 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc, {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; int i; - for (i = 0; i < sizeof (numeric_traits) / sizeof (numeric_traits[0]); i++) + for (i = 0; i < ARRAYELTS (numeric_traits); i++) { num = CFDictionaryGetValue (dict, numeric_traits[i].trait); if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval)) @@ -1225,8 +1251,7 @@ macfont_lookup_cache (CFStringRef key) CTFontCopyCharacterSet nor -[NSFont coveredCharacterSet] for this font is correct for non-BMP characters on Mac OS X 10.5, anyway. */ - if (CFStringCompare (key, CFSTR ("LastResort"), 0) - == kCFCompareEqualTo) + if (CFEqual (key, CFSTR ("LastResort"))) { CFRange range = CFRangeMake (0, MAX_UNICODE_CHAR + 1); @@ -1555,8 +1580,6 @@ static struct font_driver macfont_driver = macfont_draw, NULL, /* get_bitmap */ NULL, /* free_bitmap */ - NULL, /* get_outline */ - NULL, /* free_outline */ NULL, /* anchor_point */ NULL, /* otf_capability */ NULL, /* otf_drive */ @@ -1881,7 +1904,7 @@ macfont_create_attributes_with_spec (Lisp_Object spec) if (! traits) goto err; - for (i = 0; i < sizeof (numeric_traits) / sizeof (numeric_traits[0]); i++) + for (i = 0; i < ARRAYELTS (numeric_traits); i++) { tmp = AREF (spec, numeric_traits[i].index); if (INTEGERP (tmp)) @@ -2052,33 +2075,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 +2159,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); @@ -2185,27 +2207,26 @@ macfont_list (struct frame *f, Lisp_Object spec) 10.7 returns NULL if pat_desc represents the LastResort font. So we use CTFontDescriptorCreateMatchingFontDescriptor (no trailing "s") for such a font. */ - if (CFStringCompare (family_name, CFSTR ("LastResort"), 0) - != kCFCompareEqualTo) - descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc, - NULL); + if (!CFEqual (family_name, CFSTR ("LastResort"))) + descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc, + NULL); else - { - FontDescriptorRef lr_desc = - mac_font_descriptor_create_matching_font_descriptor (pat_desc, - NULL); - if (lr_desc) - { - descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1, - &kCFTypeArrayCallBacks); - CFRelease (lr_desc); - } - else - descs = NULL; - } + { + FontDescriptorRef lr_desc = + mac_font_descriptor_create_matching_font_descriptor (pat_desc, + NULL); + if (lr_desc) + { + descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1, + &kCFTypeArrayCallBacks); + CFRelease (lr_desc); + } + else + descs = NULL; + } CFRelease (pat_desc); if (! descs) - goto err; + goto err; descs_count = CFArrayGetCount (descs); if (descs_count == 0 @@ -2423,8 +2444,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size) int size; FontRef macfont; FontSymbolicTraits sym_traits; - char name[256]; - int len, i, total_width; + int i, total_width; CGGlyph glyph; CGFloat ascent, descent, leading; @@ -2451,17 +2471,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size) if (! macfont) return Qnil; - font_object = font_make_object (VECSIZE (struct macfont_info), entity, size); - ASET (font_object, FONT_TYPE_INDEX, macfont_driver.type); - len = font_unparse_xlfd (entity, size, name, 256); - if (len > 0) - ASET (font_object, FONT_NAME_INDEX, make_string (name, len)); - len = font_unparse_fcname (entity, size, name, 256); - if (len > 0) - ASET (font_object, FONT_FULLNAME_INDEX, make_string (name, len)); - else - ASET (font_object, FONT_FULLNAME_INDEX, - AREF (font_object, FONT_NAME_INDEX)); + font_object = font_build_object (VECSIZE (struct macfont_info), + Qmac_ct, entity, size); font = XFONT_OBJECT (font_object); font->pixel_size = size; font->driver = &macfont_driver; @@ -2546,12 +2557,9 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size) family_name = mac_font_copy_family_name (macfont); if (family_name) { - if ((CFStringCompare (family_name, CFSTR ("Courier"), 0) - == kCFCompareEqualTo) - || (CFStringCompare (family_name, CFSTR ("Helvetica"), 0) - == kCFCompareEqualTo) - || (CFStringCompare (family_name, CFSTR ("Times"), 0) - == kCFCompareEqualTo)) + if (CFEqual (family_name, CFSTR ("Courier")) + || CFEqual (family_name, CFSTR ("Helvetica")) + || CFEqual (family_name, CFSTR ("Times"))) ascent += (ascent + descent) * .15f; else if (CFStringHasPrefix (family_name, CFSTR ("Hiragino"))) { @@ -2590,25 +2598,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 @@ -2691,69 +2694,70 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, { struct frame * f = s->f; struct macfont_info *macfont_info = (struct macfont_info *) s->font; - FontRef macfont = macfont_info->macfont; + CGRect background_rect; + CGPoint text_position; + CGGlyph *glyphs; + CGPoint *positions; + CGFloat font_size = mac_font_get_size (macfont_info->macfont); + bool no_antialias_p = + (macfont_info->antialias == MACFONT_ANTIALIAS_OFF + || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT + && font_size <= macfont_antialias_threshold)); + int len = to - from; + struct face *face = s->face; CGContextRef context; - BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; - int end = isComposite ? s->cmp_to : s->nchars; - int len = end - s->cmp_from; - int i; block_input (); - context = [[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState (context); + if (with_background) + background_rect = CGRectMake (x, y - FONT_BASE (s->font), + s->width, FONT_HEIGHT (s->font)); + else + background_rect = CGRectNull; + + text_position = CGPointMake (x, -y); + glyphs = xmalloc (sizeof (CGGlyph) * len); + { + CGFloat advance_delta; + int i; + CGFloat total_width = 0; -#if 0 - if (s->num_clips > 0) - { - CGRect clips[2]; + positions = xmalloc (sizeof (CGPoint) * len); + for (i = 0; i < len; i++) + { + int width; + + glyphs[i] = s->char2b[from + i]; + width = (s->padding_p ? 1 + : macfont_glyph_extents (s->font, glyphs[i], + NULL, &advance_delta, + no_antialias_p)); + positions[i].x = total_width + advance_delta; + positions[i].y = 0; + total_width += width; + } + } - for (i = 0; i < s->num_clips; i++) - clips[i] = mac_rect_make (f, s->clip[i].left, s->clip[i].top, - s->clip[i].right - s->clip[i].left, - s->clip[i].bottom - s->clip[i].top); - CGContextClipToRects (context, clips, s->num_clips); - } -#endif + context = [[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState (context); - if (with_background) + if (!CGRectIsNull (background_rect)) { - CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, s); - CGContextFillRect (context, - CGRectMake (x, y, - s->width, FONT_HEIGHT (s->font))); + if (s->hl == DRAW_MOUSE_FACE) + { + face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + if (!face) + face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); + } + CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face, f); + CGContextFillRects (context, &background_rect, 1); } if (macfont_info->cgfont) { - CGGlyph *glyphs = alloca (sizeof (CGGlyph) * len); - CGPoint *positions = alloca (sizeof (CGPoint) * len); - CGFloat total_width = 0; - CGFloat font_size = mac_font_get_size (macfont); CGAffineTransform atfm; - CGFloat advance_delta = 0; - int y_draw = -s->ybase; - int no_antialias_p = - (macfont_info->antialias == MACFONT_ANTIALIAS_OFF - || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT - && font_size <= macfont_antialias_threshold)); - - for (i = 0; i < len; i++) - { - int width; - - glyphs[i] = *(s->char2b + s->cmp_from + i); - width = (s->padding_p ? 1 - : macfont_glyph_extents (s->font, glyphs[i], - NULL, &advance_delta, - no_antialias_p)); - positions[i].x = total_width + advance_delta; - positions[i].y = 0; - total_width += width; - } - CGContextScaleCTM (context, 1, -1); - CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, s); + CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f); if (macfont_info->synthetic_italic_p) atfm = synthetic_italic_atfm; else @@ -2762,13 +2766,13 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, { CGContextSetTextDrawingMode (context, kCGTextFillStroke); CGContextSetLineWidth (context, synthetic_bold_factor * font_size); - CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, s); + CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND (context, face, f); } if (no_antialias_p) CGContextSetShouldAntialias (context, false); CGContextSetTextMatrix (context, atfm); - CGContextSetTextPosition (context, x, y_draw); + CGContextSetTextPosition (context, text_position.x, text_position.y); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if (macfont_info->color_bitmap_p @@ -2779,7 +2783,8 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, { if (len > 0) { - CTFontDrawGlyphs (macfont, glyphs, positions, len, context); + CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len, + context); } } else @@ -2791,6 +2796,9 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y, } } + + xfree (glyphs); + xfree (positions); CGContextRestoreGState (context); unblock_input (); @@ -2798,7 +2806,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 +3343,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) + if (languages && CFArrayGetCount (languages) > 0) { - attr_string = CFAttributedStringCreate (NULL, charset_string, attrs); - CFRelease (attrs); - } - if (attr_string) - { - 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) + { + attr_string = CFAttributedStringCreate (NULL, charset_string, + attrs); + CFRelease (attrs); + } + if (attr_string) + { + ctline = CTLineCreateWithAttributedString (attr_string); + CFRelease (attr_string); + } + if (ctline) { - CTRunRef run = CFArrayGetValueAtIndex (runs, i); - CFDictionaryRef attributes = CTRunGetAttributes (run); - CTFontRef font_in_run; + 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); } } @@ -3498,7 +3537,7 @@ mac_ctfont_equal_in_postscript_name (CTFontRef font1, CTFontRef font2) name2 = CTFontCopyPostScriptName (font2); if (name2) { - result = (CFStringCompare (name1, name2, 0) == kCFCompareEqualTo); + result = CFEqual (name1, name2); CFRelease (name2); } CFRelease (name1); @@ -3524,7 +3563,7 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string, { attributes = CFDictionaryCreate (NULL, (const void **) keys, (const void **) values, - sizeof (keys) / sizeof (keys[0]), + ARRAYELTS (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease (values[1]); @@ -3571,7 +3610,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 +3763,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) { @@ -3735,8 +3774,8 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, CTLineRef ctline = NULL; string = CFStringCreateWithCharacters (NULL, characters, - sizeof (characters) - / sizeof (characters[0])); + ARRAYELTS (characters)); + if (string) { CTGlyphInfoRef glyph_info = @@ -3751,7 +3790,7 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, attributes = CFDictionaryCreate (NULL, (const void **) keys, (const void **) values, - sizeof (keys) / sizeof (keys[0]), + ARRAYELTS (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease (glyph_info); @@ -3817,7 +3856,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 +3872,141 @@ 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 (CFEqual (macfont_language_default_font_names[i].language, + language)) + { + 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 (".")) + && !CFEqual (family, CFSTR ("LastResort"))) + { + result = family; + break; + } + else + CFRelease (family); + } + } + } + CFRelease (descriptors); + } + + return result; +} + void * macfont_get_nsctfont (struct font *font) {