diff --git a/configure.ac b/configure.ac index 42c04ef..1260b8a 100644 --- a/configure.ac +++ b/configure.ac @@ -185,7 +185,7 @@ changequote(,)dnl if test "x$GCC" = "xyes"; then case " $CFLAGS " in *[\ \ ]-Wall[\ \ ]*) ;; - *) CFLAGS="$CFLAGS -Wall" ;; + *) CFLAGS="$CFLAGS -Wall -ObjC" ;; esac fi changequote([,])dnl diff --git a/pango/pangocairo-coretext.h b/pango/pangocairo-coretext.h index 31faf9b..f562587 100644 --- a/pango/pangocairo-coretext.h +++ b/pango/pangocairo-coretext.h @@ -43,6 +43,19 @@ struct _PangoCairoCoreTextFontMap gdouble dpi; }; +struct _PangoCairoCoreTextFont +{ + PangoCoreTextFont font; + PangoCairoFontPrivate cf_priv; + + int abs_size; +}; + +struct _PangoCairoCoreTextFontClass +{ + PangoCoreTextFontClass parent_class; +}; + GType pango_cairo_core_text_font_map_get_type (void) G_GNUC_CONST; PangoCoreTextFont * diff --git a/pango/pangocairo-coretextfont.c b/pango/pangocairo-coretextfont.c index 0f2a9ef..463b6e2 100644 --- a/pango/pangocairo-coretextfont.c +++ b/pango/pangocairo-coretextfont.c @@ -23,6 +23,7 @@ #include "config.h" +#import #include #include "pango-impl-utils.h" @@ -32,21 +33,6 @@ #include "pangocairo-coretext.h" #include "pangocairo-coretextfont.h" -struct _PangoCairoCoreTextFont -{ - PangoCoreTextFont font; - PangoCairoFontPrivate cf_priv; - - int abs_size; -}; - -struct _PangoCairoCoreTextFontClass -{ - PangoCoreTextFontClass parent_class; -}; - - - static cairo_font_face_t *pango_cairo_core_text_font_create_font_face (PangoCairoFont *font); static PangoFontMetrics *pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font, PangoContext *context); @@ -204,6 +190,75 @@ pango_cairo_core_text_font_init (PangoCairoCoreTextFont *cafont G_GNUC_UNUSED) { } +static gchar * +gchar_from_cf_string (CFStringRef str) +{ + CFIndex len; + gchar *buffer; + + /* GetLength returns the number of UTF-16 pairs, so this number + * times 2 should definitely give us enough space for UTF8. + * We add one for the terminating zero. + */ + len = CFStringGetLength (str) * 2 + 1; + buffer = g_new0 (char, len); + CFStringGetCString (str, buffer, len, kCFStringEncodingUTF8); + + return buffer; +} + +static gchar * +ct_font_descriptor_get_family_name (CTFontDescriptorRef desc, + gboolean may_fail) +{ + CFStringRef cf_str; + char *buffer; + + cf_str = CTFontDescriptorCopyAttribute (desc, kCTFontFamilyNameAttribute); + if (!cf_str) + { + int i; + + /* No font family name is set, try to retrieve font name and deduce + * the family name from that instead. + */ + cf_str = CTFontDescriptorCopyAttribute (desc, kCTFontNameAttribute); + if (!cf_str) + { + if (may_fail) + return NULL; + + /* This font is likely broken, return a default family name ... */ + return g_strdup ("Sans"); + } + + buffer = gchar_from_cf_string (cf_str); + CFRelease (cf_str); + + for (i = 0; i < strlen (buffer); i++) + if (buffer[i] == '-') + break; + + if (i < strlen (buffer)) + { + char *ret; + + ret = g_strndup (buffer, i); + g_free (buffer); + + return ret; + } + else + return buffer; + } + /* else */ + + buffer = gchar_from_cf_string (cf_str); + CFRelease (cf_str); + + return buffer; +} + PangoCoreTextFont * _pango_cairo_core_text_font_new (PangoCairoCoreTextFontMap *cafontmap, PangoCoreTextFontKey *key) diff --git a/pango/pangocairo-coretextfontmap.c b/pango/pangocairo-coretextfontmap.c index ba5dcec..6cb3809 100644 --- a/pango/pangocairo-coretextfontmap.c +++ b/pango/pangocairo-coretextfontmap.c @@ -26,6 +26,9 @@ #include "pangocairo.h" #include "pangocairo-private.h" #include "pangocairo-coretext.h" +#include "pangocairo-coretextfont.h" + +#import typedef struct _PangoCairoCoreTextFontMapClass PangoCairoCoreTextFontMapClass; @@ -161,6 +164,106 @@ pango_cairo_core_text_font_map_context_key_equal (PangoCoreTextFontMap *fontmap return cairo_font_options_equal (key_a, key_b); } +static int +get_scaled_size (PangoCoreTextFontMap *fontmap, + PangoContext *context, + const PangoFontDescription *desc) +{ + double size = pango_font_description_get_size (desc); + + if (!pango_font_description_get_size_is_absolute (desc)) + { + double dpi = pango_cairo_core_text_font_map_get_resolution_core_text (fontmap, context); + size = size * dpi / 72.; + } + + return .5 + pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)) * size; +} + +static PangoCoreTextFont * +pango_cairo_core_text_font_map_load_font (PangoCoreTextFontMap *fontmap, + PangoContext *context, + const PangoFontDescription *description) +{ + char *descname = pango_font_description_get_family (description); + + if (strcmp (descname, "-apple-system-font") == 0) + { + PangoCoreTextFont *cfont; + NSFont *sysfont; + CTFontDescriptorRef ctfontdescriptor; + cairo_matrix_t font_matrix; + PangoCoreTextFontsetKey fontset_key; + PangoCoreTextFontKey key; + PangoLanguage *language; + PangoFontDescription *tmp_desc; + gboolean synthetic_italic = FALSE; + double abs_size = get_scaled_size (fontmap, context, description); + double size = pango_units_to_double (abs_size) / pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)); + + sysfont = [NSFont systemFontOfSize: size]; + ctfontdescriptor = (CTFontDescriptorRef)[sysfont fontDescriptor]; + + PangoCairoCoreTextFont *cafont = g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT, NULL); + cfont = PANGO_CORE_TEXT_FONT (cafont); + cafont->abs_size = abs_size; + _pango_core_text_font_set_ctfont (cfont, CFRetain (sysfont)); + + tmp_desc = pango_font_description_copy_static (description); + + _pango_core_text_fontset_key_init (&fontset_key, + fontmap, + context, + tmp_desc, + pango_context_get_language (context)); + _pango_core_text_font_key_init (&key, + fontmap, + &fontset_key, + ctfontdescriptor, + synthetic_italic); + + if (pango_core_text_font_key_get_synthetic_italic (&key)) + synthetic_italic = TRUE; + + if (synthetic_italic) + { + cairo_matrix_init (&font_matrix, + 1, 0, + -0.25, 1, + 0, 0); + } + else + { + cairo_matrix_init_identity (&font_matrix); + } + + cairo_matrix_scale (&font_matrix, size, size); + + _pango_cairo_font_private_initialize (&cafont->cf_priv, + (PangoCairoFont *)cafont, + pango_core_text_font_key_get_gravity (&key), + pango_core_text_font_key_get_context_key (&key), + pango_core_text_font_key_get_matrix (&key), + &font_matrix); + + PangoCoreTextFont *tmp_font = _pango_core_text_font_map_lookup_font (fontmap, &key); + if (tmp_font) + { + g_object_ref (tmp_font); + return tmp_font; + } + else + { + g_object_ref (cfont); + _pango_core_text_font_map_add (PANGO_CORE_TEXT_FONT_MAP (fontmap), &key, cfont); + + return cfont; + } + } + + return PANGO_FONT_MAP_CLASS (pango_cairo_core_text_font_map_parent_class)->load_font (fontmap, context, description); +} + static void pango_cairo_core_text_font_map_class_init (PangoCairoCoreTextFontMapClass *class) { @@ -170,6 +273,7 @@ pango_cairo_core_text_font_map_class_init (PangoCairoCoreTextFontMapClass *class object_class->finalize = pango_cairo_core_text_font_map_finalize; + fontmap_class->load_font = pango_cairo_core_text_font_map_load_font; fontmap_class->get_serial = pango_cairo_core_text_font_map_get_serial; fontmap_class->changed = pango_cairo_core_text_font_map_changed; diff --git a/pango/pangocoretext-fontmap.c b/pango/pangocoretext-fontmap.c index bcbb173..4234bf1 100644 --- a/pango/pangocoretext-fontmap.c +++ b/pango/pangocoretext-fontmap.c @@ -28,6 +28,7 @@ #include "pango-impl-utils.h" #include "modules.h" +#import #include typedef struct _FontHashKey FontHashKey; @@ -826,28 +827,12 @@ get_scaled_size (PangoCoreTextFontMap *fontmap, return .5 + pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)) * size; } - -/* - * PangoCoreTextFontsetKey - */ -struct _PangoCoreTextFontsetKey -{ - PangoCoreTextFontMap *fontmap; - PangoLanguage *language; - PangoFontDescription *desc; - PangoMatrix matrix; - int pixelsize; - double resolution; - PangoGravity gravity; - gpointer context_key; -}; - -static void -pango_core_text_fontset_key_init (PangoCoreTextFontsetKey *key, - PangoCoreTextFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *desc, - PangoLanguage *language) +void +_pango_core_text_fontset_key_init (PangoCoreTextFontsetKey *key, + PangoCoreTextFontMap *fontmap, + PangoContext *context, + const PangoFontDescription *desc, + PangoLanguage *language) { if (!language && context) language = pango_context_get_language (context); @@ -960,27 +945,12 @@ pango_core_text_fontset_key_get_context_key (const PangoCoreTextFontsetKey *key) return key->context_key; } -/* - * PangoCoreTextFontKey - */ -struct _PangoCoreTextFontKey -{ - PangoCoreTextFontMap *fontmap; - CTFontDescriptorRef ctfontdescriptor; - PangoMatrix matrix; - PangoGravity gravity; - int pixelsize; - double resolution; - gboolean synthetic_italic; - gpointer context_key; -}; - -static void -pango_core_text_font_key_init (PangoCoreTextFontKey *key, - PangoCoreTextFontMap *ctfontmap, - PangoCoreTextFontsetKey *fontset_key, - CTFontDescriptorRef ctdescriptor, - gboolean synthetic_italic) +void +_pango_core_text_font_key_init (PangoCoreTextFontKey *key, + PangoCoreTextFontMap *ctfontmap, + PangoCoreTextFontsetKey *fontset_key, + CTFontDescriptorRef ctdescriptor, + gboolean synthetic_italic) { key->fontmap = ctfontmap; key->ctfontdescriptor = ctdescriptor; @@ -1104,14 +1074,24 @@ pango_core_text_font_key_get_ctfontdescriptor (const PangoCoreTextFontKey *key) return key->ctfontdescriptor; } +PangoCoreTextFont * +_pango_core_text_font_map_lookup_font (PangoCoreTextFontMap *fontmap, + PangoCoreTextFontKey *key) +{ + return g_hash_table_lookup (fontmap->font_hash, key); +} - -static void -pango_core_text_font_map_add (PangoCoreTextFontMap *ctfontmap, - PangoCoreTextFontKey *key, - PangoCoreTextFont *ctfont) +void +_pango_core_text_font_map_add (PangoCoreTextFontMap *ctfontmap, + PangoCoreTextFontKey *key, + PangoCoreTextFont *ctfont) { PangoCoreTextFontKey *key_copy; + PangoCoreTextFont *tmp; + + tmp = g_hash_table_lookup (ctfontmap->font_hash, key); + if (tmp) + return; _pango_core_text_font_set_font_map (ctfont, ctfontmap); @@ -1130,8 +1110,8 @@ pango_core_text_font_map_new_font (PangoCoreTextFontMap *fontmap, PangoCoreTextFont *font; PangoCoreTextFontKey key; - pango_core_text_font_key_init (&key, fontmap, fontset_key, ctfontdescriptor, - synthetic_italic); + _pango_core_text_font_key_init (&key, fontmap, fontset_key, ctfontdescriptor, + synthetic_italic); font = g_hash_table_lookup (fontmap->font_hash, &key); if (font) @@ -1144,7 +1124,7 @@ pango_core_text_font_map_new_font (PangoCoreTextFontMap *fontmap, if (!font) return NULL; - pango_core_text_font_map_add (fontmap, &key, font); + _pango_core_text_font_map_add (fontmap, &key, font); return font; } @@ -1295,8 +1275,8 @@ pango_core_text_font_map_load_fontset (PangoFontMap *fontmap, PangoCoreTextFontMap *ctfontmap = PANGO_CORE_TEXT_FONT_MAP (fontmap); static gboolean warned_full_fallback = FALSE; /* MT-safe */ - pango_core_text_fontset_key_init (&key, ctfontmap, - context, desc, language); + _pango_core_text_fontset_key_init (&key, ctfontmap, + context, desc, language); fontset = g_hash_table_lookup (ctfontmap->fontset_hash, &key); @@ -1320,8 +1300,8 @@ pango_core_text_font_map_load_fontset (PangoFontMap *fontmap, tmp_desc = pango_font_description_copy_static (desc); pango_font_description_set_family_static (tmp_desc, "Sans"); - pango_core_text_fontset_key_init (&key, ctfontmap, context, tmp_desc, - language); + _pango_core_text_fontset_key_init (&key, ctfontmap, context, tmp_desc, + language); fontset = g_hash_table_lookup (ctfontmap->fontset_hash, &key); if (G_LIKELY (fontset)) @@ -1450,6 +1430,53 @@ pango_core_text_font_map_init (PangoCoreTextFontMap *ctfontmap) CFRelease (dict); } + if (true) + { + NSFont *sysfont = [NSFont systemFontOfSize: 0.0]; + NSString *name = [[NSFont fontWithName: [[sysfont fontDescriptor] postscriptName] size: 0.0] familyName]; + + NSArray *fontfaces = [[NSFontManager sharedFontManager] availableMembersOfFontFamily: name]; + int num_faces = [fontfaces count]; + CFRelease (name); + + for (int faceindex = 0; faceindex < num_faces; faceindex++) + { + SInt64 font_traits; + char *buffer; + char *family_name; + CFNumberRef number; + CFDictionaryRef dict; + CTFontDescriptorRef desc = [sysfont fontDescriptor]; + + buffer = ct_font_descriptor_get_family_name (desc, TRUE); + if (!buffer) + continue; + + family_name = g_utf8_casefold (buffer, -1); + family = g_hash_table_lookup (ctfontmap->families, family_name); + if (!family) + { + family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL); + g_hash_table_insert (ctfontmap->families, g_strdup ("-apple-system-font"), family); + family->family_name = g_strdup (buffer); + } + + g_free (buffer); + g_free (family_name); + + dict = CTFontDescriptorCopyAttribute (desc, kCTFontTraitsAttribute); + number = (CFNumberRef)CFDictionaryGetValue (dict, kCTFontSymbolicTrait); + + if (CFNumberGetValue (number, kCFNumberSInt64Type, &font_traits)) + { + if ((font_traits & kCTFontMonoSpaceTrait) == kCTFontMonoSpaceTrait) + family->is_monospace = TRUE; + } + + CFRelease (dict); + } + } + /* Insert aliases */ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL); family->family_name = g_strdup ("Sans"); diff --git a/pango/pangocoretext-private.h b/pango/pangocoretext-private.h index 8076eae..5c6ce41 100644 --- a/pango/pangocoretext-private.h +++ b/pango/pangocoretext-private.h @@ -81,6 +81,30 @@ struct _PangoCoreTextFontMapClass PangoContext *context); }; +struct _PangoCoreTextFontKey +{ + PangoCoreTextFontMap *fontmap; + CTFontDescriptorRef ctfontdescriptor; + PangoMatrix matrix; + PangoGravity gravity; + int pixelsize; + double resolution; + gboolean synthetic_italic; + gpointer context_key; +}; + +struct _PangoCoreTextFontsetKey +{ + PangoCoreTextFontMap *fontmap; + PangoLanguage *language; + PangoFontDescription *desc; + PangoMatrix matrix; + int pixelsize; + double resolution; + PangoGravity gravity; + gpointer context_key; +}; + GType pango_core_text_font_map_get_type (void) G_GNUC_CONST; @@ -97,6 +121,24 @@ void _pango_core_text_font_set_font_key (PangoCoreTextF void _pango_core_text_font_set_ctfont (PangoCoreTextFont *font, CTFontRef font_ref); +void _pango_core_text_fontset_key_init (PangoCoreTextFontsetKey *key, + PangoCoreTextFontMap *fontmap, + PangoContext *context, + const PangoFontDescription *desc, + PangoLanguage *language); +void _pango_core_text_font_key_init (PangoCoreTextFontKey *key, + PangoCoreTextFontMap *ctfontmap, + PangoCoreTextFontsetKey *fontset_key, + CTFontDescriptorRef ctdescriptor, + gboolean synthetic_italic); + +void _pango_core_text_font_map_add (PangoCoreTextFontMap *ctfontmap, + PangoCoreTextFontKey *key, + PangoCoreTextFont *ctfont); + +PangoCoreTextFont *_pango_core_text_font_map_lookup_font (PangoCoreTextFontMap *fontmap, + PangoCoreTextFontKey *key); + PangoFontDescription *_pango_core_text_font_description_from_ct_font_descriptor (CTFontDescriptorRef desc); int pango_core_text_font_key_get_absolute_size (const PangoCoreTextFontKey *key);