diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2009-11-17 19:31:23 -0500 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2009-11-17 19:31:23 -0500 |
commit | d9abcaf566e9cd7f702c98958f99f90fd53b4c0b (patch) | |
tree | 56795cbfc1a72f0c4b76fb456b97b1ac86e3bb7f /pango/pango-ot-buffer.c | |
parent | 4ccabeffc20f899163bf610356871afb197e9bf8 (diff) | |
download | pango-d9abcaf566e9cd7f702c98958f99f90fd53b4c0b.tar.gz |
Bug 341481 - pangocairo kerning problem with nonidentity scaling
Finally fix this embarrassing bug. The fix is a kludge, but it will
be redone for 1.28 (harfbuzz-ng) anyway.
Diffstat (limited to 'pango/pango-ot-buffer.c')
-rw-r--r-- | pango/pango-ot-buffer.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/pango/pango-ot-buffer.c b/pango/pango-ot-buffer.c index 533c3102..f5a68512 100644 --- a/pango/pango-ot-buffer.c +++ b/pango/pango-ot-buffer.c @@ -207,6 +207,9 @@ pango_ot_buffer_get_glyphs (const PangoOTBuffer *buffer, static void apply_gpos_ltr (PangoGlyphString *glyphs, hb_glyph_position_t *positions, + gboolean scale, + double xscale, + double yscale, gboolean is_hinted) { int i; @@ -224,6 +227,8 @@ apply_gpos_ltr (PangoGlyphString *glyphs, if (is_hinted) adjustment = PANGO_UNITS_ROUND (adjustment); + if (G_UNLIKELY (scale)) + adjustment *= xscale; if (positions[i].new_advance) glyphs->glyphs[i].geometry.width = adjustment; @@ -241,14 +246,25 @@ apply_gpos_ltr (PangoGlyphString *glyphs, for (j = back; j < i; j++) glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[j].geometry.width; - glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); - glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + if (G_UNLIKELY (scale)) + { + glyphs->glyphs[i].geometry.x_offset += xscale * PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= yscale * PANGO_UNITS_26_6(y_pos); + } + else + { + glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + } } } static void apply_gpos_rtl (PangoGlyphString *glyphs, hb_glyph_position_t *positions, + gboolean scale, + double xscale, + double yscale, gboolean is_hinted) { int i; @@ -268,6 +284,8 @@ apply_gpos_rtl (PangoGlyphString *glyphs, if (is_hinted) adjustment = PANGO_UNITS_ROUND (adjustment); + if (G_UNLIKELY (scale)) + adjustment *= xscale; if (positions[i_rev].new_advance) glyphs->glyphs[i].geometry.width = adjustment; @@ -287,8 +305,16 @@ apply_gpos_rtl (PangoGlyphString *glyphs, for (j = i; j < back; j++) glyphs->glyphs[i].geometry.x_offset += glyphs->glyphs[j].geometry.width; - glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); - glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + if (G_UNLIKELY (scale)) + { + glyphs->glyphs[i].geometry.x_offset += xscale * PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= yscale * PANGO_UNITS_26_6(y_pos); + } + else + { + glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + } } } @@ -376,10 +402,28 @@ pango_ot_buffer_output (const PangoOTBuffer *buffer, positions = hb_buffer_get_glyph_positions (buffer->buffer); if (buffer->applied_gpos) { + gboolean scale = FALSE; + double xscale = 1, yscale = 1; + PangoFcFontKey *key = _pango_fc_font_get_font_key (buffer->font); + + /* This is a kludge, and dupped in pango_fc_font_kern_glyphs(). + * Should move the scale factor to PangoFcFont layer. */ + if (key) { + const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key); + PangoMatrix identity = PANGO_MATRIX_INIT; + if (G_UNLIKELY (matrix && 0 != memcmp (&identity, matrix, 4 * sizeof (double)))) + { + scale = TRUE; + pango_matrix_get_font_scale_factors (matrix, &xscale, &yscale); + if (xscale) xscale = 1 / xscale; + if (yscale) yscale = 1 / yscale; + } + } + if (buffer->rtl) - apply_gpos_rtl (glyphs, positions, buffer->font->is_hinted); + apply_gpos_rtl (glyphs, positions, scale, xscale, yscale, buffer->font->is_hinted); else - apply_gpos_ltr (glyphs, positions, buffer->font->is_hinted); + apply_gpos_ltr (glyphs, positions, scale, xscale, yscale, buffer->font->is_hinted); } else { |