📄 pangoatsui-fontmap.c
字号:
return face->synthetic_italic;}PangoCoverage *_pango_atsui_face_get_coverage (PangoATSUIFace *face, PangoLanguage *language){ int i; /* Note: We currently fake the coverage by reporting that the 255 first * glyphs exist in all fonts, which is not true. It's unclear how to get * this done correctly. */ if (face->coverage) return face->coverage; face->coverage = pango_coverage_new (); for (i = 0; i < 256; i++) pango_coverage_set (face->coverage, i, PANGO_COVERAGE_EXACT); return face->coverage;}static void pango_atsui_font_map_class_init (PangoATSUIFontMapClass *class);static void pango_atsui_font_map_init (PangoATSUIFontMap *atsuifontmap);static guint font_hash_key_hash (const FontHashKey *key);static gboolean font_hash_key_equal (const FontHashKey *key_a, const FontHashKey *key_b);static void font_hash_key_free (FontHashKey *key);G_DEFINE_TYPE (PangoATSUIFontMap, pango_atsui_font_map, PANGO_TYPE_FONT_MAP);static voidpango_atsui_font_map_finalize (GObject *object){ PangoATSUIFontMap *fontmap = PANGO_ATSUI_FONT_MAP (object); g_hash_table_destroy (fontmap->font_hash); g_hash_table_destroy (fontmap->families); G_OBJECT_CLASS (pango_atsui_font_map_parent_class)->finalize (object);}struct _FontHashKey { PangoATSUIFontMap *fontmap; PangoMatrix matrix; PangoFontDescription *desc; char *postscript_name; gpointer context_key;};/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/) * * Not necessarily better than a lot of other hashes, but should be OK, and * well tested with binary data. */#define FNV_32_PRIME ((guint32)0x01000193)#define FNV1_32_INIT ((guint32)0x811c9dc5)static guint32hash_bytes_fnv (unsigned char *buffer, int len, guint32 hval){ while (len--) { hval *= FNV_32_PRIME; hval ^= *buffer++; } return hval;}static gbooleanfont_hash_key_equal (const FontHashKey *key_a, const FontHashKey *key_b){ if (key_a->matrix.xx == key_b->matrix.xx && key_a->matrix.xy == key_b->matrix.xy && key_a->matrix.yx == key_b->matrix.yx && key_a->matrix.yy == key_b->matrix.yy && pango_font_description_equal (key_a->desc, key_b->desc) && strcmp (key_a->postscript_name, key_b->postscript_name) == 0) { if (key_a->context_key) return PANGO_ATSUI_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap, key_a->context_key, key_b->context_key); else return TRUE; } else return FALSE;}static guintfont_hash_key_hash (const FontHashKey *key){ guint32 hash = FNV1_32_INIT; /* We do a bytewise hash on the context matrix */ hash = hash_bytes_fnv ((unsigned char *)(&key->matrix), sizeof(double) * 4, hash); if (key->context_key) hash ^= PANGO_ATSUI_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap, key->context_key); hash ^= g_str_hash (key->postscript_name); return (hash ^ pango_font_description_hash (key->desc));}static voidfont_hash_key_free (FontHashKey *key){ if (key->context_key) PANGO_ATSUI_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap, key->context_key); g_slice_free (FontHashKey, key);}static FontHashKey *font_hash_key_copy (FontHashKey *old){ FontHashKey *key = g_slice_new (FontHashKey); key->fontmap = old->fontmap; key->matrix = old->matrix; key->desc = pango_font_description_copy (old->desc); key->postscript_name = g_strdup (old->postscript_name); if (old->context_key) key->context_key = PANGO_ATSUI_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap, old->context_key); else key->context_key = NULL; return key;}static voidget_context_matrix (PangoContext *context, PangoMatrix *matrix){ const PangoMatrix *set_matrix; static const PangoMatrix identity = PANGO_MATRIX_INIT; if (context) set_matrix = pango_context_get_matrix (context); else set_matrix = NULL; if (set_matrix) *matrix = *set_matrix; else *matrix = identity;}static voidfont_hash_key_for_context (PangoATSUIFontMap *fcfontmap, PangoContext *context, FontHashKey *key){ key->fontmap = fcfontmap; get_context_matrix (context, &key->matrix); if (PANGO_ATSUI_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get) key->context_key = (gpointer)PANGO_ATSUI_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context); else key->context_key = NULL;}static voidpango_atsui_font_map_add (PangoATSUIFontMap *atsuifontmap, PangoContext *context, PangoATSUIFont *atsuifont){ FontHashKey key; FontHashKey *key_copy; PangoATSUIFace *face; _pango_atsui_font_set_font_map (atsuifont, atsuifontmap); font_hash_key_for_context (atsuifontmap, context, &key); face = _pango_atsui_font_get_face (atsuifont); key.postscript_name = (char *)_pango_atsui_face_get_postscript_name (face); key.desc = _pango_atsui_font_get_font_description (atsuifont); key_copy = font_hash_key_copy (&key); _pango_atsui_font_set_context_key (atsuifont, key_copy->context_key); g_hash_table_insert (atsuifontmap->font_hash, key_copy, g_object_ref (atsuifont));}static PangoATSUIFont *pango_atsui_font_map_lookup (PangoATSUIFontMap *atsuifontmap, PangoContext *context, PangoFontDescription *desc, PangoATSUIFace *face){ FontHashKey key; font_hash_key_for_context (atsuifontmap, context, &key); key.postscript_name = (char *)_pango_atsui_face_get_postscript_name (face); key.desc = desc; return g_hash_table_lookup (atsuifontmap->font_hash, &key);}static gbooleanfind_best_match (PangoATSUIFamily *font_family, const PangoFontDescription *description, PangoFontDescription **best_description, PangoATSUIFace **best_face){ PangoFontDescription *new_desc; int i; *best_description = NULL; *best_face = NULL; for (i = 0; i < font_family->n_faces; i++) { new_desc = pango_font_face_describe (font_family->faces[i]); if (pango_font_description_better_match (description, *best_description, new_desc)) { pango_font_description_free (*best_description); *best_description = new_desc; *best_face = (PangoATSUIFace *)font_family->faces[i]; } else pango_font_description_free (new_desc); } if (*best_description) return TRUE; return FALSE;}static PangoFont *pango_atsui_font_map_load_font (PangoFontMap *fontmap, PangoContext *context, const PangoFontDescription *description){ PangoATSUIFontMap *atsuifontmap = (PangoATSUIFontMap *)fontmap; PangoATSUIFamily *font_family; gchar *name; gint size; size = pango_font_description_get_size (description); if (size < 0) return NULL; name = g_utf8_casefold (pango_font_description_get_family (description), -1); font_family = g_hash_table_lookup (atsuifontmap->families, name); g_free (name); if (font_family) { PangoFontDescription *best_description; PangoATSUIFace *best_face; PangoATSUIFont *best_font; /* Force a listing of the available faces */ pango_font_family_list_faces ((PangoFontFamily *)font_family, NULL, NULL); if (!find_best_match (font_family, description, &best_description, &best_face)) return NULL; pango_font_description_set_size (best_description, size); best_font = pango_atsui_font_map_lookup (atsuifontmap, context, best_description, best_face); if (best_font) g_object_ref (best_font); else { PangoATSUIFontMapClass *klass; klass = PANGO_ATSUI_FONT_MAP_GET_CLASS (atsuifontmap); best_font = klass->create_font (atsuifontmap, context, best_face, best_description); if (best_font) pango_atsui_font_map_add (atsuifontmap, context, best_font); /* TODO: Handle the else case here. */ } pango_font_description_free (best_description); return (PangoFont *)best_font; } return NULL;}static voidlist_families_foreach (gpointer key, gpointer value, gpointer user_data){ GSList **list = user_data; *list = g_slist_prepend (*list, value);}static voidpango_atsui_font_map_list_families (PangoFontMap *fontmap, PangoFontFamily ***families, int *n_families){ GSList *family_list = NULL; GSList *tmp_list; PangoATSUIFontMap *atsuifontmap = (PangoATSUIFontMap *)fontmap; if (!n_families) return; g_hash_table_foreach (atsuifontmap->families, list_families_foreach, &family_list); *n_families = g_slist_length (family_list); if (families) { int i = 0; *families = g_new (PangoFontFamily *, *n_families); tmp_list = family_list; while (tmp_list) { (*families)[i] = tmp_list->data; i++; tmp_list = tmp_list->next; } } g_slist_free (family_list);}static voidpango_atsui_font_map_init (PangoATSUIFontMap *atsuifontmap){ NSArray *family_array; NSAutoreleasePool *pool; PangoATSUIFamily *family; int size, i; atsuifontmap->families = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); atsuifontmap->font_hash = g_hash_table_new_full ((GHashFunc)font_hash_key_hash, (GEqualFunc)font_hash_key_equal, (GDestroyNotify)font_hash_key_free, NULL); pool = [[NSAutoreleasePool alloc] init]; family_array = [[NSFontManager sharedFontManager] availableFontFamilies]; size = [family_array count]; for (i = 0; i < size; i++) { NSString *family_name = [family_array objectAtIndex:i]; family = g_object_new (PANGO_TYPE_ATSUI_FAMILY, NULL); family->family_name = g_strdup ([family_name UTF8String]); g_hash_table_insert (atsuifontmap->families, g_utf8_casefold (family->family_name, -1), family); } /* Insert aliases */ family = g_object_new (PANGO_TYPE_ATSUI_FAMILY, NULL); family->family_name = g_strdup ("Sans"); g_hash_table_insert (atsuifontmap->families, g_utf8_casefold (family->family_name, -1), family); family = g_object_new (PANGO_TYPE_ATSUI_FAMILY, NULL); family->family_name = g_strdup ("Serif"); g_hash_table_insert (atsuifontmap->families, g_utf8_casefold (family->family_name, -1), family); family = g_object_new (PANGO_TYPE_ATSUI_FAMILY, NULL); family->family_name = g_strdup ("Monospace"); g_hash_table_insert (atsuifontmap->families, g_utf8_casefold (family->family_name, -1), family); [pool release];}static voidpango_atsui_font_map_class_init (PangoATSUIFontMapClass *class){ GObjectClass *object_class = G_OBJECT_CLASS (class); PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class); object_class->finalize = pango_atsui_font_map_finalize; fontmap_class->load_font = pango_atsui_font_map_load_font; fontmap_class->list_families = pango_atsui_font_map_list_families; fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_ATSUI;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -