summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-06-28 19:53:13 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-06-28 19:53:13 +0000
commit3ff63658b026f35452bc7cea3b2d8c0f6095320a (patch)
tree874a159ec73c3d1fcd9adb46d89729aa0aa34427
parent34118705fc86d6218a590d260634c884635a20fa (diff)
parentd4356779945855f7cc950dbe162285ccf21bcce9 (diff)
downloadpango-3ff63658b026f35452bc7cea3b2d8c0f6095320a.tar.gz
Merge branch 'bring-back-better-rounding' into 'master'
shape: Bring back careful rounding code Closes #562 See merge request GNOME/pango!344
-rw-r--r--pango/shape.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/pango/shape.c b/pango/shape.c
index 04407732..b870ecad 100644
--- a/pango/shape.c
+++ b/pango/shape.c
@@ -151,6 +151,32 @@ fallback_shape (const char *text,
pango_glyph_string_reverse_range (glyphs, 0, glyphs->num_glyphs);
}
+/* FIXME: This is very ugly. We are out of room for vfuncs, so we can't
+ * easily add api to get is_hinted and the matrix from the PangoFcFont.
+ *
+ * Keep in sync with pangofc-font.h!
+ */
+struct _PangoFcFont
+{
+ PangoFont parent_instance;
+
+ gpointer font_pattern; /* fully resolved pattern */
+ PangoFontMap *fontmap; /* associated map */
+ gpointer priv; /* used internally */
+ PangoMatrix matrix; /* used internally */
+ PangoFontDescription *description;
+
+ GSList *metrics_by_lang;
+
+ guint is_hinted : 1;
+ guint is_transformed : 1;
+};
+typedef struct _PangoFcFont PangoFcFont;
+
+#define PANGO_IS_FC_FONT(obj) \
+ g_type_is_a (((GTypeInstance*)obj)->g_class->g_type, \
+ g_type_from_name ("PangoFcFont"))
+
/**
* pango_shape_with_flags:
* @item_text: valid UTF-8 text to shape
@@ -294,11 +320,54 @@ pango_shape_with_flags (const gchar *item_text,
if (flags & PANGO_SHAPE_ROUND_POSITIONS)
{
- for (i = 0; i < glyphs->num_glyphs; i++)
+ if (PANGO_IS_FC_FONT (analysis->font))
{
- glyphs->glyphs[i].geometry.width = PANGO_UNITS_ROUND (glyphs->glyphs[i].geometry.width );
- glyphs->glyphs[i].geometry.x_offset = PANGO_UNITS_ROUND (glyphs->glyphs[i].geometry.x_offset);
- glyphs->glyphs[i].geometry.y_offset = PANGO_UNITS_ROUND (glyphs->glyphs[i].geometry.y_offset);
+ PangoFcFont *fc_font = (PangoFcFont *)analysis->font;
+ if (fc_font->is_hinted)
+ {
+ double x_scale_inv, y_scale_inv;
+ double x_scale, y_scale;
+
+ x_scale_inv = y_scale_inv = 1.0;
+ pango_matrix_get_font_scale_factors (&fc_font->matrix, &x_scale_inv, &y_scale_inv);
+ if (PANGO_GRAVITY_IS_IMPROPER (analysis->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;
+
+ if (x_scale == 1.0 && y_scale == 1.0)
+ {
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ glyphs->glyphs[i].geometry.width = PANGO_UNITS_ROUND (glyphs->glyphs[i].geometry.width);
+ }
+ else
+ {
+ #if 0
+ if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
+ {
+ /* XXX */
+ double tmp = x_scale;
+ x_scale = y_scale;
+ y_scale = -tmp;
+ }
+ #endif
+ #define HINT(value, scale_inv, scale) (PANGO_UNITS_ROUND ((int) ((value) * scale)) * scale_inv)
+ #define HINT_X(value) HINT ((value), x_scale, x_scale_inv)
+ #define HINT_Y(value) HINT ((value), y_scale, y_scale_inv)
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ glyphs->glyphs[i].geometry.width = HINT_X (glyphs->glyphs[i].geometry.width);
+ glyphs->glyphs[i].geometry.x_offset = HINT_X (glyphs->glyphs[i].geometry.x_offset);
+ glyphs->glyphs[i].geometry.y_offset = HINT_Y (glyphs->glyphs[i].geometry.y_offset);
+ }
+ #undef HINT_Y
+ #undef HINT_X
+ #undef HINT
+ }
+ }
}
}
}