/* 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.
#include "composite.h"
#include "fontset.h"
#include "font.h"
+#include "termchar.h"
#include "nsgui.h"
#include "nsterm.h"
#include "macfont.h"
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,
#endif
/* The font property key specifying the font design destination. The
- value is an unsigned integer code: 0 for WYSIWIG, and 1 for Video
+ value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video
text. (See the documentation of X Logical Font Description
Conventions.) In the Mac font driver, 1 means the screen font is
used for calculating some glyph metrics. You can see the
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
{
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'. */
unichar characters[] = {0xfffd};
NSString *string =
[NSString stringWithCharacters:characters
- length:(sizeof (characters)
- / sizeof (characters[0]))];
+ length:ARRAYELTS (characters)];
NSGlyphInfo *glyphInfo =
[NSGlyphInfo glyphInfoWithCharacterIdentifier:cid
collection:collection
if (!(textStorage && layoutManager && textContainer))
{
[textStorage release];
-
+
return 0;
}
return cgColor;
}
-#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, s) \
- CGContextSetFillColorWithColor (context, \
- get_cgcolor (NS_FACE_FOREGROUND (s->face), \
- s->f))
-
-#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, s) \
- CGContextSetFillColorWithColor (context, \
- get_cgcolor (NS_FACE_BACKGROUND (s->face), \
- s->f))
-
-#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, s) \
- CGContextSetStrokeColorWithColor (context, \
- get_cgcolor (NS_FACE_FOREGROUND (s->face),\
- s->f))
+#define CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND(context, face, f) \
+ do { \
+ CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \
+ CGContextSetFillColorWithColor (context, refcol_) ; \
+ CGColorRelease (refcol_); \
+ } while (0)
+#define CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND(context, face, f) \
+ do { \
+ CGColorRef refcol_ = get_cgcolor (NS_FACE_BACKGROUND (face), f); \
+ CGContextSetFillColorWithColor (context, refcol_); \
+ CGColorRelease (refcol_); \
+ } while (0)
+#define CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND(context, face, f) \
+ do { \
+ CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \
+ CGContextSetStrokeColorWithColor (context, refcol_); \
+ CGColorRelease (refcol_); \
+ } while (0)
\f
/* Mac font driver. */
{ "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")},
{ 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;
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;
{{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))
/* The cached glyph for a character c is stored as the (c %
NGLYPHS_IN_VALUE)-th CGGlyph block of a value for the key (c /
- NGLYPHS_IN_VALUE). However, the glyph for a BMP characrer c is
+ NGLYPHS_IN_VALUE). However, the glyph for a BMP character c is
not stored here if row_nkeys_or_perm[c / 256] >=
ROW_PERM_OFFSET. */
CFMutableDictionaryRef dictionary;
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);
static Lisp_Object macfont_list_family (struct frame *);
static void macfont_free_entity (Lisp_Object);
static Lisp_Object macfont_open (struct frame *, Lisp_Object, int);
-static void macfont_close (struct frame *, struct font *);
+static void macfont_close (struct font *);
static int macfont_has_char (Lisp_Object, int);
static unsigned macfont_encode_char (struct font *, int);
static int macfont_text_extents (struct font *, unsigned int *, int,
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))
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));
}
}
+ 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);
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
macfont_info = (struct macfont_info *) font;
macfont_info->macfont = macfont;
macfont_info->cgfont = mac_font_copy_graphics_font (macfont);
-
+
val = assq_no_quit (QCdestination, AREF (entity, FONT_EXTRA_INDEX));
if (CONSP (val) && EQ (XCDR (val), make_number (1)))
macfont_info->screen_font = mac_screen_font_create_with_name (font_name,
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")))
{
}
static void
-macfont_close (struct frame * f, struct font *font)
+macfont_close (struct font *font)
{
struct macfont_info *macfont_info = (struct macfont_info *) font;
int i;
}
unblock_input ();
- if (metrics)
+ if (metrics)
metrics->width = width;
return width;
{
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 ();
+ 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;
+
+ 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;
+ }
+ }
+
context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState (context);
-#if 0
- if (s->num_clips > 0)
+ if (!CGRectIsNull (background_rect))
{
- CGRect clips[2];
-
- 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
-
- if (with_background)
- {
- 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
{
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
{
if (len > 0)
{
- CTFontDrawGlyphs (macfont, glyphs, positions, len, context);
+ CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len,
+ context);
}
}
else
}
}
+
+ xfree (glyphs);
+ xfree (positions);
CGContextRestoreGState (context);
unblock_input ();
return len;
}
-Lisp_Object
+static Lisp_Object
macfont_shape (Lisp_Object lgstring)
{
struct font *font;
}
len = i;
- assume (len <= TYPE_MAXIMUM (EMACS_INT) - 2);
if (INT_MAX / 2 < len)
memory_full (SIZE_MAX);
#define BUINT32_VALUE(lval) OSReadBigInt32 (&(lval), 0)
/* Return UVS subtable for the specified FONT. If the subtable is not
- found or ill-formated, then return NULL. */
+ found or ill-formatted, then return NULL. */
static CFDataRef
mac_font_copy_uvs_table (FontRef font)
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);
}
}
name2 = CTFontCopyPostScriptName (font2);
if (name2)
{
- result = (CFStringCompare (name1, name2, 0) == kCFCompareEqualTo);
+ result = CFEqual (name1, name2);
CFRelease (name2);
}
CFRelease (name1);
{
attributes = CFDictionaryCreate (NULL, (const void **) keys,
(const void **) values,
- sizeof (keys) / sizeof (keys[0]),
+ ARRAYELTS (keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease (values[1]);
return ctline;
}
-CFIndex
+static CFIndex
mac_ctfont_shape (CTFontRef font, CFStringRef string,
struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len)
{
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)
{
CTLineRef ctline = NULL;
string = CFStringCreateWithCharacters (NULL, characters,
- sizeof (characters)
- / sizeof (characters[0]));
+ ARRAYELTS (characters));
+
if (string)
{
CTGlyphInfoRef glyph_info =
attributes = CFDictionaryCreate (NULL, (const void **) keys,
(const void **) values,
- sizeof (keys) / sizeof (keys[0]),
+ ARRAYELTS (keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease (glyph_info);
}
}
-CFComparisonResult
+static CFComparisonResult
mac_font_family_compare (const void *val1, const void *val2, void *context)
{
CFStringRef family1 = (CFStringRef) val1, family2 = (CFStringRef) val2;
}
#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)
{