[pango/line-height-attribute: 29/30] Fix up logical rectangle reporting
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/line-height-attribute: 29/30] Fix up logical rectangle reporting
- Date: Mon, 9 Aug 2021 02:00:48 +0000 (UTC)
commit e2def596629bd6e9499d6b455cd645b360a9b7aa
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Aug 7 21:02:36 2021 -0400
Fix up logical rectangle reporting
Fix up the various apis that are reporting logical
rects to follow these rules:
Logical rectangles of lines are affected by the
line-height attribute, logical rectangles of smaller
units (runs, clusters, chars, cursors, etc) are not.
This fixes the text cursors and block cursors in
GTK to be 'normal' height, even when applying
line-height for double-spacing.
pango/pango-layout.c | 100 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 76 insertions(+), 24 deletions(-)
---
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 447bf890..2a3cb5a2 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -180,7 +180,8 @@ static void pango_layout_line_postprocess (PangoLayoutLine *line,
static void pango_layout_line_leaked (PangoLayoutLine *line);
/* doesn't leak line */
-static PangoLayoutLine* _pango_layout_iter_get_line (PangoLayoutIter *iter);
+static PangoLayoutLine * _pango_layout_iter_get_line (PangoLayoutIter *iter);
+static PangoLayoutRun * _pango_layout_iter_get_run (PangoLayoutIter *iter);
static void pango_layout_get_item_properties (PangoItem *item,
ItemProperties *properties);
@@ -1802,7 +1803,8 @@ pango_layout_index_to_line (PangoLayout *layout,
static PangoLayoutLine *
pango_layout_index_to_line_and_extents (PangoLayout *layout,
int index,
- PangoRectangle *line_rect)
+ PangoRectangle *line_rect,
+ PangoRectangle *run_rect)
{
PangoLayoutIter iter;
PangoLayoutLine *line = NULL;
@@ -1822,7 +1824,26 @@ pango_layout_index_to_line_and_extents (PangoLayout *layout,
pango_layout_iter_get_line_extents (&iter, NULL, line_rect);
if (line->start_index + line->length > index)
- break;
+ {
+ if (run_rect)
+ {
+ while (TRUE)
+ {
+ PangoLayoutRun *run = _pango_layout_iter_get_run (&iter);
+
+ if (run->item->offset <= index && index < run->item->offset + run->item->length)
+ {
+ pango_layout_iter_get_run_extents (&iter, NULL, run_rect);
+ break;
+ }
+
+ if (!pango_layout_iter_next_run (&iter))
+ break;
+ }
+ }
+
+ break;
+ }
if (!pango_layout_iter_next_line (&iter))
break; /* Use end of last line */
@@ -2300,10 +2321,24 @@ pango_layout_index_to_pos (PangoLayout *layout,
layout_line = tmp_line;
- pango_layout_iter_get_line_extents (&iter, NULL, &logical_rect);
-
if (layout_line->start_index + layout_line->length > index)
- break;
+ {
+ while (TRUE)
+ {
+ PangoLayoutRun *run = _pango_layout_iter_get_run (&iter);
+
+ if (run->item->offset <= index && index < run->item->offset + run->item->length)
+ {
+ pango_layout_iter_get_run_extents (&iter, NULL, &logical_rect);
+ break;
+ }
+
+ if (!pango_layout_iter_next_run (&iter))
+ break;
+ }
+
+ break;
+ }
if (!pango_layout_iter_next_line (&iter))
{
@@ -2376,7 +2411,7 @@ pango_layout_get_direction (PangoLayout *layout,
{
PangoLayoutLine *line;
- line = pango_layout_index_to_line_and_extents (layout, index, NULL);
+ line = pango_layout_index_to_line_and_extents (layout, index, NULL, NULL);
if (line)
return pango_layout_line_get_char_direction (line, index);
@@ -2409,6 +2444,7 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
PangoDirection dir1, dir2;
int level1, level2;
PangoRectangle line_rect;
+ PangoRectangle run_rect;
PangoLayoutLine *layout_line = NULL; /* Quiet GCC */
int x1_trailing;
int x2;
@@ -2417,7 +2453,7 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
g_return_if_fail (index >= 0 && index <= layout->length);
layout_line = pango_layout_index_to_line_and_extents (layout, index,
- &line_rect);
+ &line_rect, &run_rect);
g_assert (index >= layout_line->start_index);
@@ -2466,9 +2502,9 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
else
strong_pos->x += x2;
- strong_pos->y = line_rect.y;
+ strong_pos->y = run_rect.y;
strong_pos->width = 0;
- strong_pos->height = line_rect.height;
+ strong_pos->height = run_rect.height;
}
if (weak_pos)
@@ -2481,9 +2517,9 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
else
weak_pos->x += x1_trailing;
- weak_pos->y = line_rect.y;
+ weak_pos->y = run_rect.y;
weak_pos->width = 0;
- weak_pos->height = line_rect.height;
+ weak_pos->height = run_rect.height;
}
}
@@ -5022,6 +5058,7 @@ static void
pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
PangoRectangle *run_ink,
PangoRectangle *run_logical,
+ PangoRectangle *line_logical,
int *height)
{
PangoRectangle logical;
@@ -5030,7 +5067,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
gboolean has_underline;
gboolean has_overline;
- if (G_UNLIKELY (!run_ink && !run_logical && !height))
+ if (G_UNLIKELY (!run_ink && !run_logical && !line_logical && !height))
return;
pango_layout_get_item_properties (run->item, &properties);
@@ -5045,6 +5082,9 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
if (!run_logical && (has_underline || has_overline || properties.strikethrough))
run_logical = &logical;
+ if (!run_logical && line_logical)
+ run_logical = &logical;
+
if (properties.shape_set)
_pango_shape_get_extents (run->item->num_chars,
properties.shape_ink_rect,
@@ -5119,16 +5159,6 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
*height = pango_font_metrics_get_height (metrics);
}
- if (properties.absolute_line_height != 0 || properties.line_height != 0.0)
- {
- int line_height, leading;
-
- line_height = MAX (properties.absolute_line_height, ceilf (properties.line_height *
run_logical->height));
- leading = line_height - run_logical->height;
- run_logical->y -= leading / 2;
- run_logical->height += leading;
- }
-
if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)
{
gboolean is_hinted = (run_logical->y & run_logical->height & (PANGO_SCALE - 1)) == 0;
@@ -5149,6 +5179,21 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
run_logical->y -= properties.rise;
}
+ if (line_logical)
+ {
+ *line_logical = *run_logical;
+
+ if (properties.absolute_line_height != 0 || properties.line_height != 0.0)
+ {
+ 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;
+ }
+ }
+
if (metrics)
pango_font_metrics_unref (metrics);
}
@@ -5228,6 +5273,7 @@ pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
pango_layout_run_get_extents_and_height (run,
ink_rect ? &run_ink : NULL,
+ NULL,
&run_logical,
height ? &run_height : NULL);
@@ -6478,6 +6524,12 @@ _pango_layout_iter_get_line (PangoLayoutIter *iter)
return iter->line;
}
+static PangoLayoutRun *
+_pango_layout_iter_get_run (PangoLayoutIter *iter)
+{
+ return iter->run;
+}
+
/**
* pango_layout_iter_get_line:
* @iter: a `PangoLayoutIter`
@@ -6939,7 +6991,7 @@ pango_layout_iter_get_run_extents (PangoLayoutIter *iter,
if (iter->run)
{
- pango_layout_run_get_extents_and_height (iter->run, ink_rect, logical_rect, NULL);
+ pango_layout_run_get_extents_and_height (iter->run, ink_rect, logical_rect, NULL, NULL);
if (ink_rect)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]