📄 pangofc-fontmap.c
字号:
#ifdef FC_WIDTHstatic PangoStretchpango_fc_convert_width_to_pango (int fc_stretch){ switch (fc_stretch) { case FC_WIDTH_NORMAL: return PANGO_STRETCH_NORMAL; case FC_WIDTH_ULTRACONDENSED: return PANGO_STRETCH_ULTRA_CONDENSED; case FC_WIDTH_EXTRACONDENSED: return PANGO_STRETCH_EXTRA_CONDENSED; case FC_WIDTH_CONDENSED: return PANGO_STRETCH_CONDENSED; case FC_WIDTH_SEMICONDENSED: return PANGO_STRETCH_SEMI_CONDENSED; case FC_WIDTH_SEMIEXPANDED: return PANGO_STRETCH_SEMI_EXPANDED; case FC_WIDTH_EXPANDED: return PANGO_STRETCH_EXPANDED; case FC_WIDTH_EXTRAEXPANDED: return PANGO_STRETCH_EXTRA_EXPANDED; case FC_WIDTH_ULTRAEXPANDED: return PANGO_STRETCH_ULTRA_EXPANDED; default: return PANGO_STRETCH_NORMAL; }}#endif/** * pango_fc_font_description_from_pattern: * @pattern: a #FcPattern * @include_size: if %TRUE, the pattern will include the size from * the @pattern; otherwise the resulting pattern will be unsized. * (only %FC_SIZE is examined, not %FC_PIXEL_SIZE) * * Creates a #PangoFontDescription that matches the specified * Fontconfig pattern as closely as possible. Many possible Fontconfig * pattern values, such as %FC_RASTERIZER or %FC_DPI, don't make sense in * the context of #PangoFontDescription, so will be ignored. * * Return value: a new #PangoFontDescription. Free with * pango_font_description_free(). * * Since: 1.4 **/PangoFontDescription *pango_fc_font_description_from_pattern (FcPattern *pattern, gboolean include_size){ PangoFontDescription *desc; PangoStyle style; PangoWeight weight; PangoStretch stretch; double size; PangoGravity gravity; FcChar8 *s; int i; FcResult res; desc = pango_font_description_new (); res = FcPatternGetString (pattern, FC_FAMILY, 0, (FcChar8 **) &s); g_assert (res == FcResultMatch); pango_font_description_set_family (desc, (gchar *)s); if (FcPatternGetInteger (pattern, FC_SLANT, 0, &i) == FcResultMatch) style = pango_fc_convert_slant_to_pango (i); else style = PANGO_STYLE_NORMAL; pango_font_description_set_style (desc, style); if (FcPatternGetInteger (pattern, FC_WEIGHT, 0, &i) == FcResultMatch) weight = pango_fc_convert_weight_to_pango (i); else weight = PANGO_WEIGHT_NORMAL; pango_font_description_set_weight (desc, weight);#ifdef FC_WIDTH if (FcPatternGetInteger (pattern, FC_WIDTH, 0, &i) == FcResultMatch) stretch = pango_fc_convert_width_to_pango (i); else#endif stretch = PANGO_STRETCH_NORMAL; pango_font_description_set_stretch (desc, stretch); pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL); if (include_size && FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch) pango_font_description_set_size (desc, size * PANGO_SCALE); if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)&s) == FcResultMatch) { GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), s); gravity = value->value; } else gravity = PANGO_GRAVITY_SOUTH; pango_font_description_set_gravity (desc, gravity); return desc;}/* * PangoFcFace */static PangoFontDescription *make_alias_description (PangoFcFamily *fcfamily, gboolean bold, gboolean italic){ PangoFontDescription *desc = pango_font_description_new (); pango_font_description_set_family (desc, fcfamily->family_name); pango_font_description_set_style (desc, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); pango_font_description_set_weight (desc, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL); return desc;}static PangoFontDescription *pango_fc_face_describe (PangoFontFace *face){ PangoFcFace *fcface = PANGO_FC_FACE (face); PangoFcFamily *fcfamily = fcface->family; PangoFontDescription *desc = NULL; FcResult res; FcPattern *match_pattern; FcPattern *result_pattern; if (fcface->fake) { if (strcmp (fcface->style, "Regular") == 0) return make_alias_description (fcfamily, FALSE, FALSE); else if (strcmp (fcface->style, "Bold") == 0) return make_alias_description (fcfamily, TRUE, FALSE); else if (strcmp (fcface->style, "Italic") == 0) return make_alias_description (fcfamily, FALSE, TRUE); else /* Bold Italic */ return make_alias_description (fcfamily, TRUE, TRUE); } match_pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, fcfamily->family_name, FC_STYLE, FcTypeString, fcface->style, NULL); g_assert (match_pattern); FcConfigSubstitute (NULL, match_pattern, FcMatchPattern); FcDefaultSubstitute (match_pattern); result_pattern = FcFontMatch (NULL, match_pattern, &res); if (result_pattern) { desc = pango_fc_font_description_from_pattern (result_pattern, FALSE); FcPatternDestroy (result_pattern); /* Unset gravity. We want gravity to be set to descriptions of fonts, * but not faces. */ pango_font_description_unset_fields (desc, PANGO_FONT_MASK_GRAVITY); } FcPatternDestroy (match_pattern); return desc;}static const char *pango_fc_face_get_face_name (PangoFontFace *face){ PangoFcFace *fcface = PANGO_FC_FACE (face); return fcface->style;}static intcompare_ints (gconstpointer ap, gconstpointer bp){ int a = *(int *)ap; int b = *(int *)bp; if (a == b) return 0; else if (a > b) return 1; else return -1;}static voidpango_fc_face_list_sizes (PangoFontFace *face, int **sizes, int *n_sizes){ PangoFcFace *fcface = PANGO_FC_FACE (face); FcPattern *pattern; FcFontSet *fontset; FcObjectSet *objectset; pattern = FcPatternCreate (); FcPatternAddString (pattern, FC_FAMILY, fcface->family->family_name); FcPatternAddString (pattern, FC_STYLE, fcface->style); objectset = FcObjectSetCreate (); FcObjectSetAdd (objectset, FC_PIXEL_SIZE); fontset = FcFontList (NULL, pattern, objectset); if (fontset) { GArray *size_array; double size, dpi = -1.0; int i, size_i; size_array = g_array_new (FALSE, FALSE, sizeof (int)); for (i = 0; i < fontset->nfont; i++) { if (FcPatternGetDouble (fontset->fonts[i], FC_PIXEL_SIZE, 0, &size) == FcResultMatch) { if (dpi < 0) dpi = pango_fc_font_map_get_resolution (fcface->family->fontmap, NULL); size_i = (int) (PANGO_SCALE * size * 72.0 / dpi); g_array_append_val (size_array, size_i); } } g_array_sort (size_array, compare_ints); if (size_array->len == 0) { *n_sizes = 0; if (sizes) *sizes = NULL; g_array_free (size_array, TRUE); } else { *n_sizes = size_array->len; if (sizes) { *sizes = (int *) size_array->data; g_array_free (size_array, FALSE); } else g_array_free (size_array, TRUE); } FcFontSetDestroy (fontset); } else { *n_sizes = 0; if (sizes) *sizes = NULL; } FcPatternDestroy (pattern); FcObjectSetDestroy (objectset);}static gbooleanpango_fc_family_is_monospace (PangoFontFamily *family){ PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family); return fcfamily->spacing == FC_MONO ||#ifdef FC_DUAL fcfamily->spacing == FC_DUAL ||#endif fcfamily->spacing == FC_CHARCELL;}static voidpango_fc_face_class_init (PangoFontFaceClass *class){ class->describe = pango_fc_face_describe; class->get_face_name = pango_fc_face_get_face_name; class->list_sizes = pango_fc_face_list_sizes;}static GTypepango_fc_face_get_type (void){ static GType object_type = 0; if (!object_type) { const GTypeInfo object_info = { sizeof (PangoFontFaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_fc_face_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoFcFace), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, NULL /* value_table */ }; object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, I_("PangoFcFace"), &object_info, 0); } return object_type;}/* * PangoFcFamily */static PangoFcFace *create_face (PangoFcFamily *fcfamily, const char *style, gboolean fake){ PangoFcFace *face = g_object_new (PANGO_FC_TYPE_FACE, NULL); face->style = g_strdup (style); face->family = fcfamily; face->fake = fake; return face;}static voidpango_fc_family_list_faces (PangoFontFamily *family, PangoFontFace ***faces, int *n_faces){ PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family); PangoFcFontMap *fcfontmap = fcfamily->fontmap; PangoFcFontMapPrivate *priv = fcfontmap->priv; if (fcfamily->n_faces < 0) { FcFontSet *fontset; int i; if (is_alias_family (fcfamily->family_name) || priv->closed) { fcfamily->n_faces = 4; fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces); i = 0; fcfamily->faces[i++] = create_face (fcfamily, "Regular", TRUE); fcfamily->faces[i++] = create_face (fcfamily, "Bold", TRUE); fcfamily->faces[i++] = create_face (fcfamily, "Italic", TRUE); fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic", TRUE); } else { FcObjectSet *os = FcObjectSetBuild (FC_STYLE, FC_WEIGHT, FC_SLANT, NULL); FcPattern *pat = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, fcfamily->family_name, NULL); enum { REGULAR, ITALIC, BOLD, BOLD_ITALIC }; /* Regular, Italic, Bold, Bold Italic */ gboolean has_face [4] = { FALSE, FALSE, FALSE, FALSE }; PangoFcFace **faces; gint num = 0; fontset = FcFontList (NULL, pat, os); FcPatternDestroy (pat); FcObjectSetDestroy (os); /* at most we have 3 additional artifical faces */ faces = g_new (PangoFcFace *, fontset->nfont + 3); for (i = 0; i < fontset->nfont; i++) { FcChar8 *style, *font_style = NULL; int weight, slant; if (FcPatternGetInteger(fontset->fonts[i], FC_WEIGHT, 0, &weight) != FcResultMatch) weight = FC_WEIGHT_MEDIUM; if (FcPatternGetInteger(fontset->fonts[i], FC_SLANT, 0, &slant) != FcResultMatch) slant = FC_SLANT_ROMAN; if (FcPatternGetString (fontset->fonts[i], FC_STYLE, 0, &font_style) != FcResultMatch) font_style = NULL; if (weight <= FC_WEIGHT_MEDIUM) { if (slant == FC_SLANT_ROMAN) { has_face[REGULAR] = TRUE; style = "Regular"; } else { has_face[ITALIC] = TRUE; style = "Italic"; } } else { if (slant == FC_SLANT_ROMAN) { has_face[BOLD] = TRUE; style = "Bold"; } else { has_face[BOLD_ITALIC] = TRUE; style = "Bold Italic"; } } if (!font_style) font_style = style; faces[num++] = create_face (fcfamily, font_style, FALSE); } if (has_face[REGULAR]) { if (!has_face[ITALIC]) faces[num++] = create_face (fcfamily, "Italic", TRUE); if (!has_face[BOLD]) faces[num++] = create_face (fcfamily, "Bold", TRUE); } if ((has_face[REGULAR] || has_face[ITALIC] || has_face[BOLD]) && !has_face[BOLD_ITALIC]) faces[num++] = create_face (fcfamily, "Bold Italic", TRUE); faces = g_renew (PangoFcFace *, faces, num); fcfamily->n_faces = num; fcfamily->faces = faces; FcFontSetDestroy (fontset); } } if (n_faces) *n_faces = fcfamily->n_faces; if (faces) *faces = g_memdup (fcfamily->faces, fcfamily->n_faces * sizeof (PangoFontFace *));}static const char *pango_fc_family_get_name (PangoFontFamily *family){ PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family); return fcfamily->family_name;}static voidpango_fc_family_class_init (PangoFontFamilyClass *class){ class->list_faces = pango_fc_family_list_faces; class->get_name = pango_fc_family_get_name; class->is_monospace = pango_fc_family_is_monospace;}static voidpango_fc_family_init (PangoFcFamily *fcfamily){ fcfamily->n_faces = -1;}static GTypepango_fc_family_get_type (void){ static GType object_type = 0; if (!object_type) { const GTypeInfo object_info = { sizeof (PangoFontFamilyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_fc_family_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoFcFamily), 0, /* n_preallocs */ (GInstanceInitFunc) pango_fc_family_init, NULL /* value_table */ }; object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, I_("PangoFcFamily"), &object_info, 0); } return object_type;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -