📄 pangox.c
字号:
const char *str, PangoFontMetrics *metrics){ GSList *subfonts = NULL; itemize_string_foreach (font, language, str, get_subfonts_foreach, &subfonts); get_font_metrics_from_subfonts (font, subfonts, metrics); g_slist_free (subfonts);}static voidaverage_width_foreach (PangoFont *font, PangoGlyphInfo *glyph_info, gpointer data){ int *width = data; *width += glyph_info->geometry.width;}/* Get composite font metrics for all subfonts resulting from shaping * string str with the given font */static gdoubleget_total_width_for_string (PangoFont *font, PangoLanguage *language, const char *str){ int width = 0; itemize_string_foreach (font, language, str, average_width_foreach, &width); return width;}static PangoFontMetrics *pango_x_font_get_metrics (PangoFont *font, PangoLanguage *language){ PangoXMetricsInfo *info = NULL; /* Quiet gcc */ PangoXFont *xfont = (PangoXFont *)font; GSList *tmp_list; const char *sample_str = pango_language_get_sample_string (language); tmp_list = xfont->metrics_by_lang; while (tmp_list) { info = tmp_list->data; if (info->sample_str == sample_str) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; } if (!tmp_list) { PangoFontMetrics *metrics; info = g_new0 (PangoXMetricsInfo, 1); xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info); info->sample_str = sample_str; metrics = pango_font_metrics_new (); get_font_metrics_from_string (font, language, sample_str, metrics); metrics->approximate_digit_width = get_total_width_for_string (font, language, "0123456789") / 10; info->metrics = metrics; } return pango_font_metrics_ref (info->metrics);}static PangoFontMap *pango_x_font_get_font_map (PangoFont *font){ PangoXFont *xfont = (PangoXFont *)font; return xfont->fontmap;}/* 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);}/* Substitute in a charset into an XLFD. Return the * (g_malloc'd) new name, or %NULL if the XLFD cannot * match the charset */static char *name_for_charset (char *xlfd, char *charset){ char *p; char *dash_charset = g_strconcat ("-", charset, NULL); char *result = NULL; int ndashes = 0; for (p = xlfd; *p; p++) if (*p == '-') ndashes++; if (ndashes == 14) /* Complete XLFD */ { if (match_end (xlfd, "-*-*")) { result = g_malloc (strlen (xlfd) - 4 + strlen (dash_charset) + 1); strncpy (result, xlfd, strlen (xlfd) - 4); strcpy (result + strlen (xlfd) - 4, dash_charset); } if (match_end (xlfd, dash_charset)) result = g_strdup (xlfd); } else if (ndashes == 13) { if (match_end (xlfd, "-*")) { result = g_malloc (strlen (xlfd) - 2 + strlen (dash_charset) + 1); strncpy (result, xlfd, strlen (xlfd) - 2); strcpy (result + strlen (xlfd) - 2, dash_charset); } if (match_end (xlfd, dash_charset)) result = g_strdup (xlfd); } else { if (match_end (xlfd, "*")) { result = g_malloc (strlen (xlfd) + strlen (dash_charset) + 1); strcpy (result, xlfd); strcpy (result + strlen (xlfd), dash_charset); } if (match_end (xlfd, dash_charset)) result = g_strdup (xlfd); } g_free (dash_charset); return result;}static PangoXSubfontpango_x_insert_subfont (PangoFont *font, const char *xlfd){ PangoXFont *xfont = (PangoXFont *)font; PangoXSubfontInfo *info; info = g_new (PangoXSubfontInfo, 1); info->xlfd = g_strdup (xlfd); info->font_struct = NULL; xfont->n_subfonts++; if (xfont->n_subfonts > xfont->max_subfonts) { xfont->max_subfonts *= 2; xfont->subfonts = g_renew (PangoXSubfontInfo *, xfont->subfonts, xfont->max_subfonts); } xfont->subfonts[xfont->n_subfonts - 1] = info; return xfont->n_subfonts;}/** * pango_x_list_subfonts: * @font: a #PangoFont. * @charsets: the charsets to list subfonts for. * @n_charsets: the number of charsets in @charsets. * @subfont_ids: location to store a pointer to an array of subfont IDs for each found subfont; * the result must be freed using g_free(). * @subfont_charsets: location to store a pointer to an array of subfont IDs for each found subfont; * the result must be freed using g_free(). * * Lists the subfonts of a given font. The result is ordered first by charset, * and then within each charset, by the order of fonts in the font specification. * * Return value: length of the arrays stored in @subfont_ids and * @subfont_charsets. **/intpango_x_list_subfonts (PangoFont *font, char **charsets, int n_charsets, PangoXSubfont **subfont_ids, int **subfont_charsets){ PangoXFont *xfont = (PangoXFont *)font; PangoXSubfont **subfont_lists; PangoFontMap *fontmap; int i, j; int n_subfonts = 0; g_return_val_if_fail (font != NULL, 0); g_return_val_if_fail (n_charsets == 0 || charsets != NULL, 0); fontmap = pango_x_font_map_for_display (xfont->display); subfont_lists = g_new (PangoXSubfont *, n_charsets); for (j=0; j<n_charsets; j++) { subfont_lists[j] = g_hash_table_lookup (xfont->subfonts_by_charset, charsets[j]); if (!subfont_lists[j]) { subfont_lists[j] = g_new (PangoXSubfont, xfont->n_fonts); for (i = 0; i < xfont->n_fonts; i++) { PangoXSubfont subfont = 0; char *xlfd; if (xfont->size == -1) { xlfd = name_for_charset (xfont->fonts[i], charsets[j]); if (xlfd) { int count; char **names = XListFonts (xfont->display, xlfd, 1, &count); if (count > 0) subfont = pango_x_insert_subfont (font, names[0]); XFreeFontNames (names); g_free (xlfd); } } else { xlfd = pango_x_make_matching_xlfd (fontmap, xfont->fonts[i], charsets[j], xfont->size); if (xlfd) { subfont = pango_x_insert_subfont (font, xlfd); g_free (xlfd); } } subfont_lists[j][i] = subfont; } g_hash_table_insert (xfont->subfonts_by_charset, g_strdup (charsets[j]), subfont_lists[j]); } for (i = 0; i < xfont->n_fonts; i++) if (subfont_lists[j][i]) n_subfonts++; } *subfont_ids = g_new (PangoXSubfont, n_subfonts); *subfont_charsets = g_new (int, n_subfonts); n_subfonts = 0; for (j=0; j<n_charsets; j++) for (i=0; i<xfont->n_fonts; i++) if (subfont_lists[j][i]) { (*subfont_ids)[n_subfonts] = subfont_lists[j][i]; (*subfont_charsets)[n_subfonts] = j; n_subfonts++; } g_free (subfont_lists); return n_subfonts;}/** * pango_x_has_glyph: * @font: a #PangoFont which must be from the X backend. * @glyph: the index of a glyph in the font. (Formed * using the #PANGO_X_MAKE_GLYPH macro) * * Checks if the given glyph is present in a X font. * * Return value: %TRUE if the glyph is present. **/gbooleanpango_x_has_glyph (PangoFont *font, PangoGlyph glyph){ PangoXSubfontInfo *subfont; XCharStruct *cs; guint16 char_index = PANGO_X_GLYPH_INDEX (glyph); guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyph); subfont = pango_x_find_subfont (font, subfont_index); if (!subfont) return FALSE; cs = pango_x_get_per_char (font, subfont, char_index); if (cs && (cs->lbearing != cs->rbearing || cs->width != 0)) return TRUE; else return FALSE;}/** * pango_x_font_subfont_xlfd: * @font: a #PangoFont which must be from the X backend. * @subfont_id: the id of a subfont within the font. * * Determines the X Logical Font Description for the specified * subfont. * * Return value: A newly-allocated string containing the XLFD for the * subfont. This string must be freed with g_free(). **/char *pango_x_font_subfont_xlfd (PangoFont *font, PangoXSubfont subfont_id){ PangoXSubfontInfo *subfont; g_return_val_if_fail (font != NULL, NULL); g_return_val_if_fail (PANGO_X_IS_FONT (font), NULL); subfont = pango_x_find_subfont (font, subfont_id); if (!subfont) { g_warning ("pango_x_font_subfont_xlfd: Invalid subfont_id specified"); return NULL; } return g_strdup (subfont->xlfd);}static voidpango_x_font_dispose (GObject *object){ PangoXFont *xfont = PANGO_X_FONT (object); /* If the font is not already in the freed-fonts cache, add it, * if it is already there, do nothing and the font will be * freed. */ if (!xfont->in_cache && xfont->fontmap) pango_x_fontmap_cache_add (xfont->fontmap, xfont); G_OBJECT_CLASS (parent_class)->dispose (object);}static voidsubfonts_foreach (gpointer key, gpointer value, gpointer data){ g_free (key); g_free (value);}static voidfree_metrics_info (PangoXMetricsInfo *info){ pango_font_metrics_unref (info->metrics); g_free (info);}static voidpango_x_font_finalize (GObject *object){ PangoXFont *xfont = (PangoXFont *)object; PangoXFontCache *cache = pango_x_font_map_get_font_cache (xfont->fontmap); int i; for (i=0; i<xfont->n_subfonts; i++) { PangoXSubfontInfo *info = xfont->subfonts[i]; g_free (info->xlfd); if (info->font_struct) pango_x_font_cache_unload (cache, info->font_struct); g_free (info); } g_free (xfont->subfonts); g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL); g_hash_table_destroy (xfont->subfonts_by_charset); g_slist_foreach (xfont->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (xfont->metrics_by_lang); if (xfont->xface) pango_x_face_remove (xfont->xface, (PangoFont *)xfont); g_object_unref (xfont->fontmap); g_strfreev (xfont->fonts); G_OBJECT_CLASS (parent_class)->finalize (object);}static PangoFontDescription *pango_x_font_describe (PangoFont *font){ /* FIXME: this doesn't work for fonts from pango_x_font_load() */ PangoXFont *xfont = (PangoXFont *)font; if (xfont->xface) { PangoFontDescription *desc = pango_font_face_describe (PANGO_FONT_FACE (xfont->xface)); pango_font_description_set_size (desc, xfont->size); return desc; } else return NULL;}PangoMap *pango_x_get_shaper_map (PangoLanguage *language){ static guint engine_type_id = 0; static guint render_type_id = 0; if (engine_type_id == 0) { engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE); render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_X); } return pango_find_map (language, engine_type_id, render_type_id);}static PangoCoverage *pango_x_font_get_coverage (PangoFont *font, PangoLanguage *language){ PangoXFont *xfont = (PangoXFont *)font; return pango_x_face_get_coverage (xfont->xface, font, language);}static PangoEngineShape *pango_x_font_find_shaper (PangoFont *font,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -