summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-10-20 10:52:36 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-10-20 10:52:36 +0000
commita0d7555fc00f04d1283acd5cac36feab77433e53 (patch)
treec7b5831dbf287db07cbae4192e7ccf9d5c98e2ed /pango
parent5820cc12cb9f05b90149c7236166e588b5bda2bc (diff)
parent1a3c69d37200f42a5a744ab7775ab1ac30b7a1a2 (diff)
downloadpango-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.c68
-rw-r--r--pango/pangocairo-fcfont.c14
-rw-r--r--pango/pangocairo-font.c43
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;
}