diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-07 21:02:36 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-08 21:56:32 -0400 |
commit | e2def596629bd6e9499d6b455cd645b360a9b7aa (patch) | |
tree | 46c937c21032171717b431ff8d427aa7fa151b0e | |
parent | 5a20c4837a6d08ca2d4be46e33255fcd9d8fd575 (diff) | |
download | pango-e2def596629bd6e9499d6b455cd645b360a9b7aa.tar.gz |
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.
-rw-r--r-- | pango/pango-layout.c | 100 |
1 files 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) { |