📄 pangox-fontmap.c
字号:
style = PANGO_STYLE_NORMAL; if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer)) { for (i=0; i<G_N_ELEMENTS(styles_map); i++) { if (!strcmp (styles_map[i].text, slant_buffer)) { style = styles_map[i].value; break; } } } else strcpy (slant_buffer, "*"); variant = PANGO_VARIANT_NORMAL; weight = PANGO_WEIGHT_NORMAL; if (pango_x_get_xlfd_field (fontname, XLFD_WEIGHT, weight_buffer)) { for (i=0; i<G_N_ELEMENTS(weights_map); i++) { if (!strcmp (weights_map[i].text, weight_buffer)) { weight = weights_map[i].value; break; } } } else strcpy (weight_buffer, "*"); stretch = PANGO_STRETCH_NORMAL; if (pango_x_get_xlfd_field (fontname, XLFD_SET_WIDTH, set_width_buffer)) { for (i=0; i<G_N_ELEMENTS(stretches_map); i++) { if (!strcmp (stretches_map[i].text, set_width_buffer)) { stretch = stretches_map[i].value; break; } } } else strcpy (set_width_buffer, "*"); font_family = pango_x_get_font_family (xfontmap, family_name); tmp_list = font_family->font_entries; while (tmp_list) { xface = tmp_list->data; if (pango_font_description_get_style (xface->description) == style && pango_font_description_get_weight (xface->description) == weight && pango_font_description_get_stretch (xface->description) == stretch && pango_font_description_get_variant (xface->description) == variant) return; tmp_list = tmp_list->next; } description = pango_font_description_new (); pango_font_description_set_family_static (description, font_family->family_name); pango_font_description_set_style (description, style); pango_font_description_set_weight (description, weight); pango_font_description_set_stretch (description, stretch); pango_font_description_set_variant (description, variant); xface = g_object_new (PANGO_X_TYPE_FACE, NULL); xface->description = description; xface->cached_fonts = NULL; xface->coverage = NULL; xface->xlfd = g_strconcat ("-*-", family_buffer, "-", weight_buffer, "-", slant_buffer, "-", set_width_buffer, "--*-*-*-*-*-*-*-*", NULL); font_family->font_entries = g_slist_append (font_family->font_entries, xface); xfontmap->n_fonts++;}/* Compare the tail of a to b */static gbooleanmatch_end (const char *a, const char *b){ size_t len_a = strlen (a); size_t len_b = strlen (b); if (len_b > len_a) return FALSE; else return (strcmp (a + len_a - len_b, b) == 0);}/* Given a XLFD, charset and size, find the best matching installed X font. * The XLFD must be a full XLFD (14 fields) */char *pango_x_make_matching_xlfd (PangoFontMap *fontmap, char *xlfd, const char *charset, int size){ PangoXFontMap *xfontmap; GSList *tmp_list; PangoXSizeInfo *size_info; char *identifier; char *closest_match = NULL; gint match_distance = 0; gboolean match_scaleable = FALSE; char *result = NULL; char *dash_charset; xfontmap = PANGO_X_FONT_MAP (fontmap); dash_charset = g_strconcat ("-", charset, NULL); if (!match_end (xlfd, "-*-*") && !match_end (xlfd, dash_charset)) { g_free (dash_charset); return NULL; } identifier = pango_x_get_identifier (xlfd); size_info = g_hash_table_lookup (xfontmap->size_infos, identifier); g_free (identifier); if (!size_info) { g_free (dash_charset); return NULL; } tmp_list = size_info->xlfds; while (tmp_list) { char *tmp_xlfd = tmp_list->data; if (match_end (tmp_xlfd, dash_charset)) { int font_size = pango_x_get_size (xfontmap, tmp_xlfd); if (size != -1) { int new_distance = (font_size == 0) ? 0 : abs (font_size - size); if (!closest_match || new_distance < match_distance || (new_distance < PANGO_SCALE && match_scaleable && font_size != 0)) { closest_match = tmp_xlfd; match_scaleable = (font_size == 0); match_distance = new_distance; } } } tmp_list = tmp_list->next; } if (closest_match) { if (match_scaleable) { char *prefix_end, *p; int n_dashes = 0; int target_size; char *prefix; /* OK, we have a match; let's modify it to fit this size and charset */ p = closest_match; while (n_dashes < 6) { if (*p == '-') n_dashes++; p++; } prefix_end = p - 1; while (n_dashes < 9) { if (*p == '-') n_dashes++; p++; } target_size = (int)((double)size / xfontmap->resolution + 0.5); prefix = g_strndup (closest_match, prefix_end - closest_match); result = g_strdup_printf ("%s--%d-*-*-*-*-*-%s", prefix, target_size, charset); g_free (prefix); } else { result = g_strdup (closest_match); } } g_free (dash_charset); return result;}/** * pango_x_font_map_get_font_cache: * @font_map: a #PangoXFontMap. * * Obtains the font cache associated with the given font map. * * Return value: the #PangoXFontCache of @font_map. **/PangoXFontCache *pango_x_font_map_get_font_cache (PangoFontMap *font_map){ g_return_val_if_fail (font_map != NULL, NULL); g_return_val_if_fail (PANGO_X_IS_FONT_MAP (font_map), NULL); return PANGO_X_FONT_MAP (font_map)->font_cache;}Display *pango_x_fontmap_get_display (PangoFontMap *fontmap){ g_return_val_if_fail (fontmap != NULL, NULL); g_return_val_if_fail (PANGO_X_IS_FONT_MAP (fontmap), NULL); return PANGO_X_FONT_MAP (fontmap)->display;}voidpango_x_fontmap_cache_add (PangoFontMap *fontmap, PangoXFont *xfont){ PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (fontmap); if (xfontmap->freed_fonts->length == MAX_FREED_FONTS) { PangoXFont *old_font = g_queue_pop_tail (xfontmap->freed_fonts); g_object_unref (old_font); } g_object_ref (xfont); g_queue_push_head (xfontmap->freed_fonts, xfont); xfont->in_cache = TRUE;}voidpango_x_fontmap_cache_remove (PangoFontMap *fontmap, PangoXFont *xfont){ PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (fontmap); GList *link = g_list_find (xfontmap->freed_fonts->head, xfont); if (link == xfontmap->freed_fonts->tail) { xfontmap->freed_fonts->tail = xfontmap->freed_fonts->tail->prev; if (xfontmap->freed_fonts->tail) xfontmap->freed_fonts->tail->next = NULL; } xfontmap->freed_fonts->head = g_list_delete_link (xfontmap->freed_fonts->head, link); xfontmap->freed_fonts->length--; xfont->in_cache = FALSE; g_object_unref (xfont);}static voidpango_x_fontmap_cache_clear (PangoXFontMap *xfontmap){ g_list_foreach (xfontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); g_list_free (xfontmap->freed_fonts->head); xfontmap->freed_fonts->head = NULL; xfontmap->freed_fonts->tail = NULL; xfontmap->freed_fonts->length = 0;}Atompango_x_fontmap_atom_from_name (PangoFontMap *fontmap, const char *atomname){ PangoXFontMap *xfm = PANGO_X_FONT_MAP(fontmap); gpointer found; Atom atom; found = g_hash_table_lookup (xfm->to_atom_cache, atomname); if (found) return (Atom)(GPOINTER_TO_UINT(found)); atom = XInternAtom (xfm->display, atomname, FALSE); g_hash_table_insert (xfm->to_atom_cache, g_strdup (atomname), (gpointer)atom); return atom;}G_CONST_RETURN char *pango_x_fontmap_name_from_atom (PangoFontMap *fontmap, Atom atom){ PangoXFontMap *xfm = PANGO_X_FONT_MAP(fontmap); gpointer found; char *name, *name2; found = g_hash_table_lookup (xfm->from_atom_cache, GUINT_TO_POINTER(atom)); if (found) return (const char *)found; name = XGetAtomName (xfm->display, atom); name2 = g_strdup (name); XFree (name); g_hash_table_insert (xfm->from_atom_cache, (gpointer)atom, name2); return name2;}/* * PangoXFace */static PangoFontDescription *pango_x_face_describe (PangoFontFace *face){ PangoXFace *xface = PANGO_X_FACE (face); return pango_font_description_copy (xface->description);}static const char *pango_x_face_get_face_name (PangoFontFace *face){ PangoXFace *xface = PANGO_X_FACE (face); if (!xface->face_name) { PangoFontDescription *desc = pango_font_face_describe (face); pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); xface->face_name = pango_font_description_to_string (desc); pango_font_description_free (desc); } return xface->face_name;}static voidpango_x_face_class_init (PangoFontFaceClass *class){ class->describe = pango_x_face_describe; class->get_face_name = pango_x_face_get_face_name;}GTypepango_x_face_get_type (void){ static GType object_type = 0; if (!object_type) { const GTypeInfo object_info = { sizeof (PangoFontFaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_x_face_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoXFace), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, NULL /* value_table */ }; object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, I_("PangoXFace"), &object_info, 0); } return object_type;}/* Cut and paste here to avoid an inter-module dependency */static PangoCoverageLevelengine_shape_covers (PangoEngineShape *engine, PangoFont *font, PangoLanguage *language, gunichar wc){ g_return_val_if_fail (PANGO_IS_ENGINE_SHAPE (engine), PANGO_COVERAGE_NONE); g_return_val_if_fail (PANGO_IS_FONT (font), PANGO_COVERAGE_NONE); return PANGO_ENGINE_SHAPE_GET_CLASS (engine)->covers (engine, font, language, wc);}PangoCoverage *pango_x_face_get_coverage (PangoXFace *xface, PangoFont *font, PangoLanguage *language){ PangoXFont *xfont; PangoXFontMap *xfontmap = NULL; /* Quiet gcc */ PangoCoverage *result = NULL; Atom atom = None; if (xface) { if (xface->coverage) { pango_coverage_ref (xface->coverage); return xface->coverage; } xfont = (PangoXFont *)font; xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display); if (xface->xlfd) { const char *lang_str = language ? pango_language_to_string (language) : "*"; char *str = g_strconcat (lang_str, "|", xface->xlfd, NULL); result = pango_x_get_cached_coverage (xfontmap, str, &atom); g_free (str); } } if (!result) { PangoMap *shape_map; PangoEngineShape *engine; gunichar wc; result = pango_coverage_new (); shape_map = pango_x_get_shaper_map (language); engine = (PangoEngineShape *)pango_map_get_engine (shape_map, PANGO_SCRIPT_COMMON); for (wc = 0; wc < 65536; wc++) { PangoCoverageLevel level; level = engine_shape_covers (engine, font, language, wc); if (level != PANGO_COVERAGE_NONE) pango_coverage_set (result, wc, level); } if (atom) pango_x_store_cached_coverage (xfontmap, atom, result); } if (xface) { xface->coverage = result; pango_coverage_ref (result); } return result;}voidpango_x_face_remove (PangoXFace *xface, PangoFont *font){ xface->cached_fonts = g_slist_remove (xface->cached_fonts, font);}/* * PangoXFontFamily */static voidpango_x_family_list_faces (PangoFontFamily *family, PangoFontFace ***faces, int *n_faces){ PangoXFamily *xfamily = PANGO_X_FAMILY (family); *n_faces = g_slist_length (xfamily->font_entries); if (faces) { GSList *tmp_list; int i = 0; *faces = g_new (PangoFontFace *, *n_faces); tmp_list = xfamily->font_entries; while (tmp_list) { (*faces)[i++] = tmp_list->data; tmp_list = tmp_list->next; } }}G_CONST_RETURN char *pango_x_family_get_name (PangoFontFamily *family){ PangoXFamily *xfamily = PANGO_X_FAMILY (family); return xfamily->family_name;}static voidpango_x_family_class_init (PangoFontFamilyClass *class){ class->list_faces = pango_x_family_list_faces; class->get_name = pango_x_family_get_name;}GTypepango_x_family_get_type (void){ static GType object_type = 0; if (!object_type) { const GTypeInfo object_info = { sizeof (PangoFontFamilyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_x_family_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoXFamily), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, NULL /* value_table */ }; object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, I_("PangoXFamily"), &object_info, 0); } return object_type;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -