diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-10-20 10:52:36 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-10-20 10:52:36 +0000 |
commit | a0d7555fc00f04d1283acd5cac36feab77433e53 (patch) | |
tree | c7b5831dbf287db07cbae4192e7ccf9d5c98e2ed /pango | |
parent | 5820cc12cb9f05b90149c7236166e588b5bda2bc (diff) | |
parent | 1a3c69d37200f42a5a744ab7775ab1ac30b7a1a2 (diff) | |
download | pango-a0d7555fc00f04d1283acd5cac36feab77433e53.tar.gz |
Merge branch 'empty-line-height-attr-fix' into 'main'
Fix empty line heights
Closes #421
See merge request GNOME/pango!481
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-layout.c | 68 | ||||
-rw-r--r-- | pango/pangocairo-fcfont.c | 14 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 43 |
3 files changed, 86 insertions, 39 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 74799ddc..6e761f2c 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -193,6 +193,7 @@ static void pango_layout_get_item_properties (PangoItem *item, static void pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, int index, PangoRectangle *logical_rect, + gboolean apply_line_height, int *height); static void pango_layout_finalize (GObject *object); @@ -1908,17 +1909,15 @@ pango_layout_index_to_line_and_extents (PangoLayout *layout, { if (run_rect) { - *run_rect = *line_rect; - while (TRUE) { PangoLayoutRun *run = _pango_layout_iter_get_run (&iter); - if (!run) - break; - pango_layout_iter_get_run_extents (&iter, NULL, run_rect); + if (!run) + break; + if (run->item->offset <= index && index < run->item->offset + run->item->length) break; @@ -4482,7 +4481,7 @@ pango_layout_check_lines (PangoLayout *layout) { PangoRectangle logical = { 0, }; int height = 0; - pango_layout_get_empty_extents_and_height_at_index (layout, 0, &logical, &height); + pango_layout_get_empty_extents_and_height_at_index (layout, 0, &logical, TRUE, &height); state.line_height = layout->line_spacing == 0.0 ? logical.height : layout->line_spacing * height; } @@ -5115,6 +5114,7 @@ static void pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, int index, PangoRectangle *logical_rect, + gboolean apply_line_height, int *height) { if (logical_rect) @@ -5122,6 +5122,8 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, PangoFont *font; PangoFontDescription *font_desc = NULL; gboolean free_font_desc = FALSE; + double line_height_factor = 0.0; + int absolute_line_height = 0; font_desc = pango_context_get_font_description (layout->context); @@ -5147,6 +5149,8 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, if (start <= index && index < end) { + PangoAttribute *attr; + if (!free_font_desc) { font_desc = pango_font_description_copy_static (font_desc); @@ -5158,6 +5162,14 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, NULL, NULL); + attr = pango_attr_iterator_get (&iter, PANGO_ATTR_LINE_HEIGHT); + if (attr) + line_height_factor = ((PangoAttrFloat *)attr)->value; + + attr = pango_attr_iterator_get (&iter, PANGO_ATTR_ABSOLUTE_LINE_HEIGHT); + if (attr) + absolute_line_height = ((PangoAttrInt *)attr)->value; + break; } @@ -5183,6 +5195,18 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, *height = pango_font_metrics_get_height (metrics); pango_font_metrics_unref (metrics); + + if (apply_line_height && + (absolute_line_height != 0 || line_height_factor != 0.0)) + { + int line_height, leading; + + line_height = MAX (absolute_line_height, ceilf (line_height_factor * logical_rect->height)); + + leading = line_height - logical_rect->height; + logical_rect->y -= leading / 2; + logical_rect->height += leading; + } } else { @@ -5206,14 +5230,6 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout, } static void -pango_layout_line_get_empty_extents_and_height (PangoLayoutLine *line, - PangoRectangle *logical_rect, - int *height) -{ - pango_layout_get_empty_extents_and_height_at_index (line->layout, line->start_index, logical_rect, height); -} - -static void pango_layout_run_get_extents_and_height (PangoLayoutRun *run, PangoRectangle *run_ink, PangoRectangle *run_logical, @@ -5347,6 +5363,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run, int line_height, leading; line_height = MAX (properties.absolute_line_height, ceilf (properties.line_height * line_logical->height)); + leading = line_height - line_logical->height; line_logical->y -= leading / 2; line_logical->height += leading; @@ -5479,7 +5496,7 @@ pango_layout_line_get_extents_and_height (PangoLayoutLine *line, PangoRectangle r, *rect; rect = logical_rect ? logical_rect : &r; - pango_layout_line_get_empty_extents_and_height (line, rect, height); + pango_layout_get_empty_extents_and_height_at_index (line->layout, line->start_index, rect, TRUE, height); } if (caching) @@ -7341,18 +7358,35 @@ pango_layout_iter_get_run_extents (PangoLayoutIter *iter, } else { - /* The empty run at the end of a line */ + if (iter->line->runs) + { + /* The empty run at the end of a non-empty line */ + PangoLayoutRun *run = g_slist_last (iter->line->runs)->data; + pango_layout_run_get_extents_and_height (run, ink_rect, logical_rect, NULL, NULL); + } + else + { + PangoRectangle r; - pango_layout_iter_get_line_extents (iter, ink_rect, logical_rect); + pango_layout_get_empty_extents_and_height_at_index (iter->layout, 0, &r, FALSE, NULL); + + if (ink_rect) + *ink_rect = r; + + if (logical_rect) + *logical_rect = r; + } if (ink_rect) { + offset_y (iter, &ink_rect->y); ink_rect->x = iter->run_x; ink_rect->width = 0; } if (logical_rect) { + offset_y (iter, &logical_rect->y); logical_rect->x = iter->run_x; logical_rect->width = 0; } diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 0019f83a..85cc45c8 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -76,8 +76,20 @@ pango_cairo_fc_font_create_base_metrics_for_context (PangoCairoFont *cfont, PangoContext *context) { PangoFcFont *fcfont = (PangoFcFont *) (cfont); + PangoFontMetrics *metrics; + const cairo_font_options_t *options; - return pango_fc_font_create_base_metrics_for_context (fcfont, context); + 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) + { + metrics->ascent = PANGO_PIXELS_CEIL (metrics->ascent) * PANGO_SCALE; + metrics->descent = PANGO_PIXELS_CEIL (metrics->descent) * PANGO_SCALE; + metrics->height = PANGO_PIXELS_CEIL (metrics->height) * PANGO_SCALE; + } + + return metrics; } static void diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 69c375c3..15c5be4a 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -784,40 +784,41 @@ 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; - - cairo_scaled_font_extents (scaled_font, &font_extents); + PangoCairoFont *cfont = cf_priv->cfont; + PangoFontMetrics *metrics = _pango_cairo_font_get_metrics (PANGO_FONT (cfont), NULL); 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 = metrics->ascent + metrics->descent; + 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 = - metrics->ascent; + break; case PANGO_GRAVITY_NORTH: - cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent); - break; + cf_priv->font_extents.y = - metrics->descent; + 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 = (metrics->ascent + metrics->descent) / 2; + if (cf_priv->is_hinted) + ascent = PANGO_UNITS_ROUND (ascent); + cf_priv->font_extents.y = - ascent; + } } - 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 */ + pango_font_metrics_unref (metrics); + + 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; } |