diff options
-rw-r--r-- | pango/pangocairo-fcfont.c | 7 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 86 | ||||
-rw-r--r-- | tests/testmisc.c | 56 |
3 files changed, 113 insertions, 36 deletions
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 85cc45c8..4453b5ab 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -75,14 +75,13 @@ static PangoFontMetrics * pango_cairo_fc_font_create_base_metrics_for_context (PangoCairoFont *cfont, PangoContext *context) { - PangoFcFont *fcfont = (PangoFcFont *) (cfont); + PangoCairoFcFont *cffont = (PangoCairoFcFont *) cfont; + PangoFcFont *fcfont = (PangoFcFont *) cfont; PangoFontMetrics *metrics; - const cairo_font_options_t *options; metrics = pango_fc_font_create_base_metrics_for_context (fcfont, context); - options = pango_cairo_context_get_font_options (context); - if (cairo_font_options_get_hint_metrics (options) == CAIRO_HINT_METRICS_ON) + if (_pango_cairo_font_private_is_metrics_hinted (&cffont->cf_priv)) { metrics->ascent = PANGO_PIXELS_CEIL (metrics->ascent) * PANGO_SCALE; metrics->descent = PANGO_PIXELS_CEIL (metrics->descent) * PANGO_SCALE; diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 69c375c3..503f863b 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -693,7 +693,7 @@ get_space_extents (PangoCairoFontPrivate *cf_priv, cairo_text_extents_t extents; c[0] = hexdigits[i]; - cairo_scaled_font_text_extents (cf_priv->scaled_font, c, &extents); + cairo_scaled_font_text_extents (_pango_cairo_font_private_get_scaled_font (cf_priv), c, &extents); hex_width += extents.width; } width = pango_units_from_double (hex_width / 16); @@ -784,40 +784,60 @@ struct _PangoCairoFontGlyphExtentsCacheEntry static gboolean _pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_priv) { - cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv); - cairo_font_extents_t font_extents; - - if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) - return FALSE; + hb_font_extents_t extents; - cairo_scaled_font_extents (scaled_font, &font_extents); + hb_font_get_h_extents (pango_font_get_hb_font (PANGO_FONT (cf_priv->cfont)), + &extents); cf_priv->font_extents.x = 0; cf_priv->font_extents.width = 0; - cf_priv->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent); + cf_priv->font_extents.height = extents.ascender - extents.descender; + switch (cf_priv->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: - cf_priv->font_extents.y = - pango_units_from_double (font_extents.ascent); - break; + cf_priv->font_extents.y = - extents.ascender; + break; case PANGO_GRAVITY_NORTH: - cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent); - break; + cf_priv->font_extents.y = extents.descender; + break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: - { - int ascent = pango_units_from_double (font_extents.ascent + font_extents.descent) / 2; - if (cf_priv->is_hinted) - ascent = PANGO_UNITS_ROUND (ascent); - cf_priv->font_extents.y = - ascent; - } + { + int ascent = cf_priv->font_extents.height / 2; + if (cf_priv->is_hinted) + ascent = PANGO_UNITS_ROUND (ascent); + cf_priv->font_extents.y = - ascent; + } + break; } - cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES); - /* Make sure all cache entries are invalid initially */ - cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */ + if (cf_priv->is_hinted) + { + if (cf_priv->font_extents.y < 0) + cf_priv->font_extents.y = PANGO_UNITS_ROUND (cf_priv->font_extents.y - PANGO_SCALE/2); + else + cf_priv->font_extents.y = PANGO_UNITS_ROUND (cf_priv->font_extents.y + PANGO_SCALE/2); + if (cf_priv->font_extents.height < 0) + cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height - PANGO_SCALE/2); + else + cf_priv->font_extents.height = PANGO_UNITS_ROUND (cf_priv->font_extents.height + PANGO_SCALE/2); + } + + if (PANGO_GRAVITY_IS_IMPROPER (cf_priv->gravity)) + { + cf_priv->font_extents.y = - cf_priv->font_extents.y; + cf_priv->font_extents.height = - cf_priv->font_extents.height; + } + + if (!cf_priv->glyph_extents_cache) + { + cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES); + /* Make sure all cache entries are invalid initially */ + cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */ + } return TRUE; } @@ -841,7 +861,10 @@ compute_glyph_extents (PangoCairoFontPrivate *cf_priv, &cairo_glyph, 1, &extents); entry->glyph = glyph; - entry->width = pango_units_from_double (extents.x_advance); + if (PANGO_GRAVITY_IS_VERTICAL (cf_priv->gravity)) + entry->width = pango_units_from_double (extents.y_advance); + else + entry->width = pango_units_from_double (extents.x_advance); entry->ink_rect.x = pango_units_from_double (extents.x_bearing); entry->ink_rect.y = pango_units_from_double (extents.y_bearing); entry->ink_rect.width = pango_units_from_double (extents.width); @@ -904,6 +927,23 @@ _pango_cairo_font_private_get_glyph_extents (PangoCairoFontPrivate *cf_priv, if (logical_rect) { *logical_rect = cf_priv->font_extents; - logical_rect->width = entry->width; + switch (cf_priv->gravity) + { + case PANGO_GRAVITY_SOUTH: + logical_rect->width = entry->width; + break; + case PANGO_GRAVITY_EAST: + logical_rect->width = cf_priv->font_extents.height; + break; + case PANGO_GRAVITY_NORTH: + logical_rect->width = entry->width; + break; + case PANGO_GRAVITY_WEST: + logical_rect->width = - cf_priv->font_extents.height; + break; + case PANGO_GRAVITY_AUTO: + default: + g_assert_not_reached (); + } } } diff --git a/tests/testmisc.c b/tests/testmisc.c index 85a3b0b5..2e14f11e 100644 --- a/tests/testmisc.c +++ b/tests/testmisc.c @@ -125,9 +125,6 @@ test_line_height (void) g_object_unref (context); } -#if 0 -/* These tests fail since I had to revert 20ec670e124e446107 - */ static void test_line_height2 (void) { @@ -255,7 +252,6 @@ test_cursor_height2 (void) g_object_unref (layout); g_object_unref (context); } -#endif static void test_attr_list_update (void) @@ -661,6 +657,47 @@ test_empty_line_height (void) g_object_unref (context); } +static void +test_gravity_metrics (void) +{ + PangoFontMap *map; + PangoContext *context; + PangoFontDescription *desc; + PangoFont *font; + PangoGlyph glyph; + PangoGravity gravity; + PangoRectangle ink[4]; + PangoRectangle log[4]; + + map = pango_cairo_font_map_get_default (); + context = pango_font_map_create_context (map); + + desc = pango_font_description_from_string ("Cantarell 64"); + + glyph = 1; /* A */ + + for (gravity = PANGO_GRAVITY_SOUTH; gravity <= PANGO_GRAVITY_WEST; gravity++) + { + pango_font_description_set_gravity (desc, gravity); + font = pango_font_map_load_font (map, context, desc); + pango_font_get_glyph_extents (font, glyph, &ink[gravity], &log[gravity]); + g_object_unref (font); + } + + g_assert_cmpint (ink[PANGO_GRAVITY_EAST].width, ==, ink[PANGO_GRAVITY_SOUTH].height); + g_assert_cmpint (ink[PANGO_GRAVITY_EAST].height, ==, ink[PANGO_GRAVITY_SOUTH].width); + g_assert_cmpint (ink[PANGO_GRAVITY_NORTH].width, ==, ink[PANGO_GRAVITY_SOUTH].width); + g_assert_cmpint (ink[PANGO_GRAVITY_NORTH].height, ==, ink[PANGO_GRAVITY_SOUTH].height); + g_assert_cmpint (ink[PANGO_GRAVITY_WEST].width, ==, ink[PANGO_GRAVITY_SOUTH].height); + g_assert_cmpint (ink[PANGO_GRAVITY_WEST].height, ==, ink[PANGO_GRAVITY_SOUTH].width); + + g_assert_cmpint (log[PANGO_GRAVITY_SOUTH].width, ==, - log[PANGO_GRAVITY_NORTH].width); + g_assert_cmpint (log[PANGO_GRAVITY_EAST].width, ==, - log[PANGO_GRAVITY_WEST].width); + + pango_font_description_free (desc); + g_object_unref (context); +} + int main (int argc, char *argv[]) { @@ -672,11 +709,11 @@ main (int argc, char *argv[]) g_test_add_func ("/layout/short-string-crash", test_short_string_crash); g_test_add_func ("/language/emoji-crash", test_language_emoji_crash); g_test_add_func ("/layout/line-height", test_line_height); - //g_test_add_func ("/layout/line-height2", test_line_height2); - //g_test_add_func ("/layout/line-height3", test_line_height3); - //g_test_add_func ("/layout/run-height", test_run_height); - //g_test_add_func ("/layout/cursor-height", test_cursor_height); - //g_test_add_func ("/layout/cursor-height2", test_cursor_height2); + g_test_add_func ("/layout/line-height2", test_line_height2); + g_test_add_func ("/layout/line-height3", test_line_height3); + g_test_add_func ("/layout/run-height", test_run_height); + g_test_add_func ("/layout/cursor-height", test_cursor_height); + g_test_add_func ("/layout/cursor-height2", test_cursor_height2); g_test_add_func ("/attr-list/update", test_attr_list_update); g_test_add_func ("/misc/version-info", test_version_info); g_test_add_func ("/misc/is-zerowidth", test_is_zero_width); @@ -692,6 +729,7 @@ main (int argc, char *argv[]) g_test_add_func ("/layout/index-to-x", test_index_to_x); g_test_add_func ("/layout/extents", test_extents); g_test_add_func ("/layout/empty-line-height", test_empty_line_height); + g_test_add_func ("/layout/gravity-metrics", test_gravity_metrics); return g_test_run (); } |