summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2001-02-13 16:59:56 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-02-13 16:59:56 +0000
commit0bca108a0ab7e081dc57640af3fbf9870749e7b8 (patch)
treebe95bdd126e650769eab20fa33aed71c0a7011cc /pango
parent80d53b6380d64d3bc2c13c6d2fcfe924d45c3d93 (diff)
downloadpango-0bca108a0ab7e081dc57640af3fbf9870749e7b8.tar.gz
properly update the tail of the list (pango_attr_list_change): flip order
2001-02-12 Havoc Pennington <hp@redhat.com> * pango/pango-attributes.c (pango_attr_list_insert_internal): properly update the tail of the list (pango_attr_list_change): flip order of tmp_list2 = tmp_list2->next and prev2 = tmp_list2 to avoid setting prev2 and tmp_list2 to the same value thus creating a mangled list. * pango/pango-layout.c (pango_layout_xy_to_index): When returning FALSE, set the index/trailing to the nearest location, instead of setting them to 0. (pango_layout_line_x_to_index): Fix a bug where line->start_index wasn't used. Return boolean for whether we had to clamp the value to get an index.
Diffstat (limited to 'pango')
-rw-r--r--pango/pango-attributes.c7
-rw-r--r--pango/pango-layout.c139
-rw-r--r--pango/pango-layout.h2
3 files changed, 104 insertions, 44 deletions
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 9b958672..af04ffed 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -803,6 +803,8 @@ pango_attr_list_insert_internal (PangoAttrList *list,
(!before && ((PangoAttribute *)list->attributes_tail->data)->start_index == start_index))
{
g_slist_append (list->attributes_tail, attr);
+ list->attributes_tail = list->attributes_tail->next;
+ g_assert (list->attributes_tail);
}
else
{
@@ -992,6 +994,9 @@ pango_attr_list_change (PangoAttrList *list,
* tmp_list points to prev->next.
*/
+ g_assert (prev->data == attr);
+ g_assert (prev->next == tmp_list);
+
/* We now have the range inserted into the list one way or the
* other. Fix up the remainder
*/
@@ -1043,8 +1048,8 @@ pango_attr_list_change (PangoAttrList *list,
if (tmp_attr2->start_index >= tmp_attr->start_index)
break;
+ prev2 = tmp_list2;
tmp_list2 = tmp_list2->next;
- prev2 = tmp_list2;
}
/* Now remove and insert before tmp_list2. We'll
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 30abc2fe..73d61d3e 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -1231,9 +1231,13 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
* 0 represents the trailing edge of the cluster.
*
* Convert from X and Y position within a layout to the byte
- * offset to the character at that logical position.
- *
- * Return value: TRUE if the position was within the layout
+ * index to the character at that logical position. If the
+ * position is not inside the layout, the closest position is chosen
+ * (the x/y position will be clamped inside the layout).
+ * If a closest position is chosen, then the function returns %FALSE;
+ * on an exact hit, it returns %TRUE.
+ *
+ * Return value: %TRUE if the coordinates were inside text
**/
gboolean
pango_layout_xy_to_index (PangoLayout *layout,
@@ -1243,11 +1247,19 @@ pango_layout_xy_to_index (PangoLayout *layout,
gboolean *trailing)
{
PangoLayoutIter *iter;
+ PangoLayoutLine *prev_line = NULL;
+ PangoLayoutLine *found = NULL;
+ int found_line_x = 0;
+ int prev_first = 0;
+ int prev_last = 0;
+ int prev_line_x = 0;
+ gboolean retval = FALSE;
+ gboolean outside = FALSE;
+
+ g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE);
+
+ iter = pango_layout_get_iter (layout);
- g_return_val_if_fail (layout != NULL, FALSE);
-
- iter = pango_layout_get_iter (layout);
-
do
{
PangoRectangle line_logical;
@@ -1255,21 +1267,59 @@ pango_layout_xy_to_index (PangoLayout *layout,
pango_layout_iter_get_line_extents (iter, NULL, &line_logical);
pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
-
- if (y >= first_y &&
- y < last_y)
+
+ if (y < first_y)
+ {
+ if (prev_line && y < (prev_last + (first_y - prev_last) / 2))
+ {
+ found = prev_line;
+ found_line_x = prev_line_x;
+ }
+ else
+ {
+ if (prev_line == NULL)
+ outside = TRUE; /* off the top */
+
+ found = pango_layout_iter_get_line (iter);
+ found_line_x = x - line_logical.x;
+ }
+ }
+ else if (y >= first_y &&
+ y < last_y)
{
- pango_layout_line_x_to_index (pango_layout_iter_get_line (iter),
- x - line_logical.x,
- index, trailing);
- pango_layout_iter_free (iter);
- return TRUE;
+ found = pango_layout_iter_get_line (iter);
+ found_line_x = x - line_logical.x;
}
+
+ prev_line = pango_layout_iter_get_line (iter);
+ prev_first = first_y;
+ prev_last = last_y;
+ prev_line_x = x - line_logical.x;
+
+ if (found != NULL)
+ break;
}
while (pango_layout_iter_next_line (iter));
-
+
pango_layout_iter_free (iter);
- return FALSE;
+
+ if (found == NULL)
+ {
+ /* Off the bottom of the layout */
+ outside = TRUE;
+
+ found = prev_line;
+ found_line_x = prev_line_x;
+ }
+
+ retval = pango_layout_line_x_to_index (found,
+ found_line_x,
+ index, trailing);
+
+ if (outside)
+ retval = FALSE;
+
+ return retval;
}
/**
@@ -2761,12 +2811,12 @@ pango_layout_line_unref (PangoLayoutLine *line)
* 0 represents the trailing edge of the cluster.
*
* Convert from x offset to the byte index of the corresponding
- * character within the text of the layout. If the @x_pos
- * is negative or greater than the length of the line, then
- * then the result will be 0, or the last index in the line
- * depending on the base direction of the layout.
+ * character within the text of the layout. If @x_pos is outside the line,
+ * the start or end of the line will be stored at @index.
+ *
+ * Return value: %FALSE if @x_pos was outside the line, %TRUE if inside
*/
-void
+gboolean
pango_layout_line_x_to_index (PangoLayoutLine *line,
int x_pos,
int *index,
@@ -2774,26 +2824,23 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
{
GSList *tmp_list;
gint start_pos = 0;
- gint first_index = 0, last_index;
+ gint first_index = 0; /* line->start_index */
+ gint last_index; /* last char in line */
+ gint end_index; /* end iterator for line (one char past last_index) */
PangoDirection base_dir;
gboolean last_trailing;
- g_return_if_fail (line != NULL);
- g_return_if_fail (LINE_IS_VALID (line));
+ g_return_val_if_fail (line != NULL, FALSE);
+ g_return_val_if_fail (LINE_IS_VALID (line), FALSE);
if (!LINE_IS_VALID (line))
- return;
+ return FALSE;
base_dir = pango_context_get_base_dir (line->layout->context);
/* Find the last index in the line
*/
- tmp_list = line->layout->lines;
- while (tmp_list->data != line)
- {
- first_index += ((PangoLayoutLine *)tmp_list->data)->length;
- tmp_list = tmp_list->next;
- }
+ first_index = line->start_index;
if (line->length == 0)
{
@@ -2802,16 +2849,13 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
if (trailing)
*trailing = 0;
- return;
+ return FALSE;
}
+
+ g_assert (line->length > 0);
- if (line->length > 0)
- {
- last_index = first_index + line->length;
- last_index = g_utf8_prev_char (line->layout->text + last_index) - line->layout->text;
- }
- else
- last_index = first_index; /* FIXME - does this make sense at all? */
+ end_index = first_index + line->length;
+ last_index = g_utf8_prev_char (line->layout->text + end_index) - line->layout->text;
/* This is a HACK. If a program only keeps track if cursor (etc)
* indices and not the trailing flag, then the trailing index of the
@@ -2820,16 +2864,22 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
* positions with wrapped lines should distinguish leading and
* trailing cursors.
*/
+ tmp_list = line->layout->lines;
+ while (tmp_list->data != line)
+ tmp_list = tmp_list->next;
+
last_trailing = tmp_list->next ? 0 : 1;
if (x_pos < 0)
{
+ /* pick the leftmost char */
if (index)
*index = (base_dir == PANGO_DIRECTION_LTR) ? first_index : last_index;
+ /* and its leftmost edge */
if (trailing)
*trailing = (base_dir == PANGO_DIRECTION_LTR) ? 0 : last_trailing;
- return;
+ return FALSE;
}
tmp_list = line->runs;
@@ -2868,17 +2918,22 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
*index += pos;
}
- return;
+ return TRUE;
}
start_pos += logical_rect.width;
tmp_list = tmp_list->next;
}
+ /* pick the rightmost char */
if (index)
*index = (base_dir == PANGO_DIRECTION_LTR) ? last_index : first_index;
+
+ /* and its rightmost edge */
if (trailing)
*trailing = (base_dir == PANGO_DIRECTION_LTR) ? last_trailing : 0;
+
+ return FALSE;
}
/**
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index b20e95a2..76bef0e8 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -168,7 +168,7 @@ GSList * pango_layout_get_lines (PangoLayout *layout);
void pango_layout_line_ref (PangoLayoutLine *line);
void pango_layout_line_unref (PangoLayoutLine *line);
-void pango_layout_line_x_to_index (PangoLayoutLine *line,
+gboolean pango_layout_line_x_to_index (PangoLayoutLine *line,
int x_pos,
int *index,
int *trailing);