PangoLayout handling of positions on paragraph boundaries
- From: Alex Larsson <alexl redhat com>
- To: <gtk-i18n-list gnome org>, <gtk-devel-list gnome org>
- Subject: PangoLayout handling of positions on paragraph boundaries
- Date: Fri, 7 Sep 2001 12:45:47 -0400 (EDT)
The handling of position on paragraph boundaries in PangoLayout is
buggy. Here is a fix, it also refactors some common code to helper
functions.
/ Alex
Index: pango/pango-layout.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-layout.c,v
retrieving revision 1.71
diff -u -p -r1.71 pango-layout.c
--- pango/pango-layout.c 2001/08/24 16:23:07 1.71
+++ pango/pango-layout.c 2001/09/07 16:21:16
@@ -1035,7 +1035,84 @@ pango_layout_line_index_to_x (PangoLayou
if (x_pos)
*x_pos = width;
}
-
+
+static PangoLayoutLine *
+pango_layout_index_to_line (PangoLayout *layout,
+ int index,
+ int *line_nr,
+ PangoLayoutLine **line_before,
+ PangoLayoutLine **line_after)
+{
+ GSList *tmp_list;
+ GSList *line_list;
+ PangoLayoutLine *line = NULL;
+ PangoLayoutLine *prev_line = NULL;
+ int i = 0;
+
+ line_list = tmp_list = layout->lines;
+ while (tmp_list)
+ {
+ PangoLayoutLine *tmp_line = tmp_list->data;
+
+ if (tmp_line && tmp_line->start_index > index)
+ break; /* index was in paragraph delimiters */
+
+ prev_line = line;
+ line = tmp_line;
+ line_list = tmp_list;
+ i++;
+
+ if (line->start_index + line->length > index)
+ break;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (line_nr)
+ *line_nr = i;
+
+ if (line_before)
+ *line_before = prev_line;
+
+ if (line_after)
+ *line_after = (line_list && line_list->next) ? line_list->next->data : NULL;
+
+ return line;
+}
+
+static PangoLayoutLine *
+pango_layout_index_to_line_and_extents (PangoLayout *layout,
+ int index,
+ PangoRectangle *line_rect)
+{
+ PangoLayoutIter *iter;
+ PangoLayoutLine *line = NULL;
+
+ iter = pango_layout_get_iter (layout);
+
+ while (TRUE)
+ {
+ PangoLayoutLine *tmp_line = pango_layout_iter_get_line (iter);
+
+ if (tmp_line && tmp_line->start_index > index)
+ break; /* index was in paragraph delimiters */
+
+ line = tmp_line;
+
+ pango_layout_iter_get_line_extents (iter, NULL, line_rect);
+
+ if (line->start_index + line->length > index)
+ break;
+
+ if (!pango_layout_iter_next_line (iter))
+ break; /* Use end of last line */
+ }
+
+ pango_layout_iter_free (iter);
+
+ return line;
+}
+
/**
* pango_layout_index_to_line_x:
* @layout: a #PangoLayout
@@ -1058,8 +1135,7 @@ pango_layout_index_to_line_x (PangoLayou
int *line,
int *x_pos)
{
- GSList *tmp_list;
- int line_num = 0;
+ int line_num;
PangoLayoutLine *layout_line = NULL;
g_return_if_fail (layout != NULL);
@@ -1068,46 +1144,30 @@ pango_layout_index_to_line_x (PangoLayou
pango_layout_check_lines (layout);
- tmp_list = layout->lines;
- while (tmp_list)
- {
- PangoLayoutLine *tmp_line = tmp_list->data;
+ layout_line = pango_layout_index_to_line (layout, index,
+ &line_num, NULL, NULL);
+ if (layout_line)
+ {
/* use end of previous layout_line if index was in the paragraph
* delimiters
*/
- if (layout_line && layout_line->start_index > index)
- {
- if (line)
- *line = line_num;
-
- pango_layout_line_index_to_x (layout_line,
- layout_line->start_index + layout_line->length,
- trailing, x_pos);
- return;
-
- }
-
- layout_line = tmp_line;
- ++line_num;
+ if (index > layout_line->start_index + layout_line->length)
+ index = layout_line->start_index + layout_line->length;
- if ((layout_line->start_index + layout_line->length) > index)
- {
- if (line)
- *line = line_num;
-
- pango_layout_line_index_to_x (layout_line, index,
- trailing, x_pos);
- return;
- }
-
- tmp_list = tmp_list->next;
+ if (line)
+ *line = line_num;
+
+ pango_layout_line_index_to_x (layout_line, index,
+ trailing, x_pos);
}
-
- if (line)
- *line = -1;
- if (x_pos)
- *x_pos = -1;
+ else
+ {
+ if (line)
+ *line = -1;
+ if (x_pos)
+ *x_pos = -1;
+ }
}
/**
@@ -1161,9 +1221,8 @@ pango_layout_move_cursor_visually (Pango
{
PangoDirection base_dir;
PangoLayoutLine *line = NULL;
- PangoLayoutLine *prev_line = NULL;
+ PangoLayoutLine *prev_line;
PangoLayoutLine *next_line;
- GSList *tmp_list;
int *log2vis_map;
int *vis2log_map;
@@ -1180,31 +1239,11 @@ pango_layout_move_cursor_visually (Pango
pango_layout_check_lines (layout);
base_dir = pango_context_get_base_dir (layout->context);
-
- /* Find the line the old cursor is on
- */
- tmp_list = layout->lines;
- while (tmp_list)
- {
- PangoLayoutLine *tmp_line = tmp_list->data;
-
- if (line && line->start_index > old_index)
- break; /* stick with the previous line */
-
- prev_line = line;
- line = tmp_line;
-
- if (line->start_index + line->length > old_index || !tmp_list->next)
- break;
-
- tmp_list = tmp_list->next;
- }
- if (tmp_list->next)
- next_line = tmp_list->next->data;
- else
- next_line = NULL;
-
+ /* Find the line the old cursor is on */
+ line = pango_layout_index_to_line (layout, old_index,
+ NULL, &prev_line, &next_line);
+
start_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);
while (old_trailing--)
@@ -1243,7 +1282,7 @@ pango_layout_move_cursor_visually (Pango
line = next_line;
}
- vis_pos = g_utf8_strlen (layout->text + line->start_index, line->length);
+ vis_pos = g_utf8_strlen (layout->text + line->start_index, line->length) + 1; /* We're always decreasing this below */
}
else if (vis_pos == n_vis && direction > 0)
{
@@ -1268,7 +1307,7 @@ pango_layout_move_cursor_visually (Pango
line = prev_line;
}
- vis_pos = 0;
+ vis_pos = -1; /* We're always increasing this below */
}
vis2log_map = pango_layout_line_get_vis2log_map (line, strong);
@@ -1432,12 +1471,12 @@ pango_layout_index_to_pos (PangoLayout
g_return_if_fail (pos != NULL);
iter = pango_layout_get_iter (layout);
-
+
while (TRUE)
{
PangoLayoutLine *tmp_line = pango_layout_iter_get_line (iter);
- if (layout_line && tmp_line->start_index > index)
+ if (tmp_line && tmp_line->start_index > index)
{
/* index is in the paragraph delimiters, move to
* end of previous line
@@ -1492,16 +1531,8 @@ pango_layout_line_get_range (PangoLayout
char **end)
{
char *p;
- GSList *tmp_list;
-
- p = line->layout->text;
- tmp_list = line->layout->lines;
- while (tmp_list->data != line)
- {
- p += ((PangoLayoutLine *)tmp_list->data)->length;
- tmp_list = tmp_list->next;
- }
+ p = line->layout->text + line->start_index;
if (start)
*start = p;
@@ -1671,37 +1702,14 @@ pango_layout_get_cursor_pos (PangoLayout
PangoLayoutLine *layout_line = NULL; /* Quiet GCC */
int x1_trailing;
int x2;
- PangoLayoutIter *iter;
g_return_if_fail (layout != NULL);
g_return_if_fail (index >= 0 && index <= layout->length);
base_dir = pango_context_get_base_dir (layout->context);
-
- iter = pango_layout_get_iter (layout);
-
- /* Find the line */
- while (TRUE)
- {
- PangoLayoutLine *tmp_line;
-
- tmp_line = pango_layout_iter_get_line (iter);
- if (layout_line && layout_line->start_index > index)
- break; /* keep previous layout_line and line_rect */
-
- layout_line = tmp_line;
- pango_layout_iter_get_line_extents (iter, NULL, &line_rect);
-
- if ((layout_line->start_index + layout_line->length) > index)
- break;
-
- if (!pango_layout_iter_next_line (iter))
- break; /* use end of the last line */
- }
-
- pango_layout_iter_free (iter);
- iter = NULL;
+ layout_line = pango_layout_index_to_line_and_extents (layout, index,
+ &line_rect);
g_assert (index >= layout_line->start_index);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]