diff options
Diffstat (limited to 'pango/pango-layout.c')
-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) { |