summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-09-24 23:50:09 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-09-24 23:50:09 +0000
commit1bdcb77e1032c4b02f4838752b0ed64ef11036c9 (patch)
tree3fde8583f047c2e0432d2ad3713ebd71b953aacb /pango
parent2025b487babed269d7a6106c6eb7f6956da3ebfd (diff)
downloadpango-1bdcb77e1032c4b02f4838752b0ed64ef11036c9.tar.gz
Patch from Alex Larsson
Mon Sep 24 19:18:48 2001 Owen Taylor <otaylor@redhat.com> Patch from Alex Larsson * pango/pango-layout.c (pango_layout_index_to_line_and_extents, pango_layout_index_to_line): Extract out some code portions into separate functions and fix problems with cursor motion in multi-paragraph layouts. * pango/pango-layout.c (pango_layout_index_to_pos): Fix for multi-paragraph layouts. * pango/pango-layout.c (pango_layout_move_cursor_visually): Fix for multi-paragraph layouts.
Diffstat (limited to 'pango')
-rw-r--r--pango/pango-layout.c217
1 files changed, 114 insertions, 103 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index ba904bdf..22df08be 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -1035,7 +1035,84 @@ pango_layout_line_index_to_x (PangoLayoutLine *line,
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 (PangoLayout *layout,
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,27 @@ pango_layout_index_to_line_x (PangoLayout *layout,
pango_layout_check_lines (layout);
- tmp_list = layout->lines;
- while (tmp_list)
- {
- PangoLayoutLine *tmp_line = tmp_list->data;
-
- /* 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 = pango_layout_index_to_line (layout, index,
+ &line_num, NULL, NULL);
- layout_line = tmp_line;
- ++line_num;
+ if (layout_line)
+ {
+ /* use end of line if index was in the paragraph delimiters */
+ 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);
+ }
+ else
+ {
+ if (line)
+ *line = -1;
+ if (x_pos)
+ *x_pos = -1;
}
-
- if (line)
- *line = -1;
- if (x_pos)
- *x_pos = -1;
}
/**
@@ -1161,9 +1218,8 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
{
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;
@@ -1181,30 +1237,10 @@ pango_layout_move_cursor_visually (PangoLayout *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--)
@@ -1242,8 +1278,11 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
}
line = next_line;
}
-
+
+ /* Handle paragraph separators as an extra position */
vis_pos = g_utf8_strlen (layout->text + line->start_index, line->length);
+ if (line->start_index + line->length != old_index)
+ vis_pos++;
}
else if (vis_pos == n_vis && direction > 0)
{
@@ -1268,7 +1307,10 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
line = prev_line;
}
+ /* Handle paragraph separators as an extra position */
vis_pos = 0;
+ if (line->start_index != old_index)
+ vis_pos--;
}
vis2log_map = pango_layout_line_get_vis2log_map (line, strong);
@@ -1432,12 +1474,12 @@ pango_layout_index_to_pos (PangoLayout *layout,
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
@@ -1483,16 +1525,8 @@ pango_layout_line_get_range (PangoLayoutLine *line,
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;
@@ -1662,37 +1696,14 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
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);