summaryrefslogtreecommitdiff
path: root/pango/pangofc-font.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-11-19 11:47:42 -0500
committerMatthias Clasen <mclasen@redhat.com>2019-07-18 12:47:53 -0700
commit8901ef5b832091cae2a28cd4537574ee1ae012a3 (patch)
tree43e60653a75612fc5d8b09d6cef00e0176f578c8 /pango/pangofc-font.c
parentceea8a00ce38fec1c0879d61a79911abc5788374 (diff)
downloadpango-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.c142
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;
}