diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-11-19 11:47:42 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-18 12:47:53 -0700 |
commit | 8901ef5b832091cae2a28cd4537574ee1ae012a3 (patch) | |
tree | 43e60653a75612fc5d8b09d6cef00e0176f578c8 /pango/pangofc-font.c | |
parent | ceea8a00ce38fec1c0879d61a79911abc5788374 (diff) | |
download | pango-8901ef5b832091cae2a28cd4537574ee1ae012a3.tar.gz |
fc: Move font setup code from the shaper
Move all the code that sets up the hb_font_t to
pango_fc_font_create_hb_font, and use it from
the shaper. This is the second step towards
taking over font management.
Even better, harfbuzz has a ready-made function
for this. We can drop a lot of FT_Face-using code
this way. We assume unhinted rendering for now,
so we can set ppem to 0.
Diffstat (limited to 'pango/pangofc-font.c')
-rw-r--r-- | pango/pangofc-font.c | 142 |
1 files changed, 119 insertions, 23 deletions
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 437c7709..7c4f64e9 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -46,6 +46,7 @@ #include "pango-layout.h" #include "pango-impl-utils.h" +#include <harfbuzz/hb-ot.h> #include <fontconfig/fcfreetype.h> #include FT_TRUETYPE_TABLES_H @@ -1066,40 +1067,135 @@ pango_fc_font_get_features (PangoFont *font, (*num_features)++; } } +} -static hb_font_t * -pango_fc_font_create_hb_font (PangoFont *font) +extern gpointer get_gravity_class (void); + +static PangoGravity +pango_fc_font_key_get_gravity (PangoFcFontKey *key) { - PangoFcFont *fcfont = PANGO_FC_FONT (font); - hb_face_t *hb_face; + FcPattern *pattern; + PangoGravity gravity = PANGO_GRAVITY_SOUTH; + FcChar8 *s; - hb_face = pango_fc_font_map_get_hb_face (PANGO_FC_FONT_MAP (fcfont->fontmap), fcfont); + pattern = pango_fc_font_key_get_pattern (key); + if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)&s) == FcResultMatch) + { + GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), (char *)s); + gravity = value->value; + } - return hb_font_create (hb_face); + return gravity; +} + +static double +get_font_size (PangoFcFontKey *key) +{ + FcPattern *pattern; + double size; + double dpi; + + pattern = pango_fc_font_key_get_pattern (key); + if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) + return size; + + /* Just in case FC_PIXEL_SIZE got unset between pango_fc_make_pattern() + * and here. That would be very weird. + */ + + if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch) + dpi = 72; + + if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch) + return size * dpi / 72.; + + /* Whatever */ + return 18.; } static void -pango_fc_font_get_features (PangoFont *font, - hb_feature_t *features, - guint len, - guint *num_features) +parse_variations (const char *variations, + hb_variation_t **hb_variations, + guint *n_variations) +{ + guint n; + hb_variation_t *var; + int i; + const char *p; + + n = 1; + for (i = 0; variations[i]; i++) + { + if (variations[i] == ',') + n++; + } + + var = g_new (hb_variation_t, n); + + p = variations; + n = 0; + while (p && *p) + { + char *end = strchr (p, ','); + if (hb_variation_from_string (p, end ? end - p: -1, &var[n])) + n++; + p = end ? end + 1 : NULL; + } + + *hb_variations = var; + *n_variations = n; +} + +static hb_font_t * +pango_fc_font_create_hb_font (PangoFont *font) { - /* Setup features from fontconfig pattern. */ PangoFcFont *fc_font = PANGO_FC_FONT (font); - if (fc_font->font_pattern) + PangoFcFontKey *key; + hb_face_t *hb_face; + hb_font_t *hb_font; + double x_scale_inv, y_scale_inv; + double x_scale, y_scale; + double size; + PangoGravity gravity; + + x_scale_inv = y_scale_inv = 1.0; + key = _pango_fc_font_get_font_key (fc_font); + if (key) { - char *s; - while (*num_features < len && - FcResultMatch == FcPatternGetString (fc_font->font_pattern, - PANGO_FC_FONT_FEATURES, - *num_features, - (FcChar8 **) &s)) + const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key); + pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv); + } + if (PANGO_GRAVITY_IS_IMPROPER (gravity)) + { + x_scale_inv = -x_scale_inv; + y_scale_inv = -y_scale_inv; + } + + x_scale = 1. / x_scale_inv; + y_scale = 1. / y_scale_inv; + + size = get_font_size (key); + gravity = pango_fc_font_key_get_gravity (key); + hb_face = pango_fc_font_map_get_hb_face (PANGO_FC_FONT_MAP (fc_font->fontmap), fc_font); + + hb_font = hb_font_create (hb_face); + hb_font_set_scale (hb_font, + size * PANGO_SCALE * x_scale, + size * PANGO_SCALE * y_scale); + if (key) + { + const char *variations = pango_fc_font_key_get_variations (key); + if (variations) { - gboolean ret = hb_feature_from_string (s, -1, &features[*num_features]); - features[*num_features].start = 0; - features[*num_features].end = (unsigned int) -1; - if (ret) - (*num_features)++; + guint n_variations; + hb_variation_t *hb_variations; + + parse_variations (variations, &hb_variations, &n_variations); + hb_font_set_variations (hb_font, hb_variations, n_variations); + + g_free (hb_variations); } } + + return hb_font; } |