From 8ec2822cc5b8839996aaeb062f6acc0a899d98b4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 12 Apr 2007 23:55:33 +0000 Subject: Quantize kerning adjustment, otherwise all the metrics hinting effort will 2007-04-12 Behdad Esfahbod * pango/pango-ot-buffer.c (apply_gpos_ltr), (apply_gpos_rtl), (pango_ot_buffer_output): * pango/pango-types.h: * pango/pangofc-font.c (pango_fc_font_kern_glyphs): * pango/pangofc-private.h: Quantize kerning adjustment, otherwise all the metrics hinting effort will be ruined by a non-whole-pixel kerning value. In the future we want to take lsb_delta and rsb_delta into the game before quantizing the adjustment here, but we don't have those values handy right now. svn path=/trunk/; revision=2225 --- ChangeLog | 13 +++++++++++++ pango/pango-ot-buffer.c | 50 ++++++++++++++++++++++++++++++++----------------- pango/pango-types.h | 2 ++ pango/pangofc-font.c | 11 +++++++++-- pango/pangofc-private.h | 3 +++ 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d4ea3dc..ce6ffa45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-04-12 Behdad Esfahbod + + * pango/pango-ot-buffer.c (apply_gpos_ltr), (apply_gpos_rtl), + (pango_ot_buffer_output): + * pango/pango-types.h: + * pango/pangofc-font.c (pango_fc_font_kern_glyphs): + * pango/pangofc-private.h: + Quantize kerning adjustment, otherwise all the metrics hinting + effort will be ruined by a non-whole-pixel kerning value. + In the future we want to take lsb_delta and rsb_delta into the + game before quantizing the adjustment here, but we don't have + those values handy right now. + 2007-04-09 Behdad Esfahbod * === Released 1.16.2 === diff --git a/pango/pango-ot-buffer.c b/pango/pango-ot-buffer.c index 539d5fd9..ca1ae99d 100644 --- a/pango/pango-ot-buffer.c +++ b/pango/pango-ot-buffer.c @@ -22,9 +22,7 @@ #include #include "pango-ot-private.h" - -#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) -#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) +#include "pangofc-private.h" /** * pango_ot_buffer_new @@ -198,7 +196,8 @@ swap_range (PangoGlyphString *glyphs, int start, int end) static void apply_gpos_ltr (PangoGlyphString *glyphs, - HB_Position positions) + HB_Position positions, + gboolean is_hinted) { int i; @@ -208,6 +207,19 @@ apply_gpos_ltr (PangoGlyphString *glyphs, FT_Pos y_pos = positions[i].y_pos; int back = i; int j; + int adjustment; + + + adjustment = PANGO_UNITS_26_6(positions[i].x_advance); + + if (is_hinted) + adjustment = PANGO_UNITS_ROUND (adjustment); + + if (positions[i].new_advance) + glyphs->glyphs[i].geometry.width = adjustment; + else + glyphs->glyphs[i].geometry.width += adjustment; + while (positions[back].back != 0) { @@ -221,17 +233,13 @@ apply_gpos_ltr (PangoGlyphString *glyphs, 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 (positions[i].new_advance) - glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i].x_advance); - else - glyphs->glyphs[i].geometry.width += PANGO_UNITS_26_6(positions[i].x_advance); } } static void apply_gpos_rtl (PangoGlyphString *glyphs, - HB_Position positions) + HB_Position positions, + gboolean is_hinted) { int i; @@ -243,6 +251,19 @@ apply_gpos_rtl (PangoGlyphString *glyphs, FT_Pos x_pos = positions[i_rev].x_pos; FT_Pos y_pos = positions[i_rev].y_pos; int j; + int adjustment; + + + adjustment = PANGO_UNITS_26_6(positions[i_rev].x_advance); + + if (is_hinted) + adjustment = PANGO_UNITS_ROUND (adjustment); + + if (positions[i_rev].new_advance) + glyphs->glyphs[i].geometry.width = adjustment; + else + glyphs->glyphs[i].geometry.width += adjustment; + while (positions[back_rev].back != 0) { @@ -258,11 +279,6 @@ apply_gpos_rtl (PangoGlyphString *glyphs, 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 (positions[i_rev].new_advance) - glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i_rev].x_advance); - else - glyphs->glyphs[i].geometry.width += PANGO_UNITS_26_6(positions[i_rev].x_advance); } } @@ -350,9 +366,9 @@ pango_ot_buffer_output (PangoOTBuffer *buffer, if (buffer->applied_gpos) { if (buffer->rtl) - apply_gpos_rtl (glyphs, buffer->buffer->positions); + apply_gpos_rtl (glyphs, buffer->buffer->positions, buffer->font->is_hinted); else - apply_gpos_ltr (glyphs, buffer->buffer->positions); + apply_gpos_ltr (glyphs, buffer->buffer->positions, buffer->font->is_hinted); } else pango_fc_font_kern_glyphs (buffer->font, glyphs); diff --git a/pango/pango-types.h b/pango/pango-types.h index 6a9ef191..59ecac0c 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -53,6 +53,8 @@ typedef guint32 PangoGlyph; * That's unlikely to matter for practical use and the expression is much * more compact and faster than alternatives that work exactly for both * integers and floating point. + * + * PANGO_PIXELS also behaves differently for +512 and -512. */ int pango_units_from_double (double d) G_GNUC_CONST; diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 175c104c..dec1f680 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -723,6 +723,7 @@ pango_fc_font_kern_glyphs (PangoFcFont *font, FT_Error error; FT_Vector kerning; int i; + gboolean hinting = font->is_hinted; g_return_if_fail (PANGO_IS_FC_FONT (font)); g_return_if_fail (glyphs != NULL); @@ -745,8 +746,14 @@ pango_fc_font_kern_glyphs (PangoFcFont *font, ft_kerning_default, &kerning); - if (error == FT_Err_Ok) - glyphs->glyphs[i-1].geometry.width += PANGO_UNITS_26_6 (kerning.x); + if (error == FT_Err_Ok) { + int adjustment = PANGO_UNITS_26_6 (kerning.x); + + if (hinting) + adjustment = PANGO_UNITS_ROUND (adjustment); + + glyphs->glyphs[i-1].geometry.width += adjustment; + } } PANGO_FC_FONT_UNLOCK_FACE (font); diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index 27ad5769..09406d13 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -42,6 +42,9 @@ struct _PangoFcMetricsInfo ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) #define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) +#define PANGO_UNITS_ROUND(d) \ + (((d) + (PANGO_SCALE >> 1)) & ~(PANGO_SCALE - 1)) + #define PANGO_FC_GRAVITY "pangogravity" void _pango_fc_font_shutdown (PangoFcFont *fcfont); -- cgit v1.2.1