summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/pango-layout.c100
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)
{