summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libview/ev-view.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 2cd2a864..0c5f6973 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -4231,9 +4231,11 @@ position_caret_cursor_at_location (EvView *view,
guint n_areas = 0;
gint page;
gint offset = -1 ;
+ gint first_line_offset;
+ gint last_line_offset = -1;
gint doc_x, doc_y;
EvRectangle *rect;
- guint i, j;
+ guint i;
if (!view->caret_enabled || view->rotation != 0)
return FALSE;
@@ -4249,29 +4251,38 @@ position_caret_cursor_at_location (EvView *view,
if (!areas)
return FALSE;
- /* First look for the line of text at location */
- for (i = 0; i < n_areas; i++) {
+ i = 0;
+ while (i < n_areas && offset == -1) {
rect = areas + i;
- if (doc_y >= rect->y1 && doc_y <= rect->y2)
- break;
- }
-
- if (i == n_areas)
- return FALSE;
-
- if (doc_x <= rect->x1) {
- /* Location is before the start of the line */
- offset = i;
- } else {
- for (j = i; j < n_areas; j++) {
- rect = areas + j;
+ first_line_offset = -1;
+ while (doc_y >= rect->y1 && doc_y <= rect->y2) {
+ if (first_line_offset == -1) {
+ if (doc_x <= rect->x1) {
+ /* Location is before the start of the line */
+ if (last_line_offset != -1) {
+ EvRectangle *last = areas + last_line_offset;
+ gint dx1, dx2;
+
+ /* If there's a previous line, check distances */
+
+ dx1 = doc_x - last->x2;
+ dx2 = rect->x1 - doc_x;
+
+ if (dx1 < dx2)
+ offset = last_line_offset;
+ else
+ offset = i;
+ } else {
+ offset = i;
+ }
- if (doc_y < rect->y1) {
- /* Location is after the end of the line */
- offset = j;
- break;
+ last_line_offset = i + 1;
+ break;
+ }
+ first_line_offset = i;
}
+ last_line_offset = i + 1;
if (doc_x >= rect->x1 && doc_x <= rect->x2) {
/* Location is inside the line. Position the caret before
@@ -4279,20 +4290,26 @@ position_caret_cursor_at_location (EvView *view,
* falls within the left or right half of the bounding box.
*/
if (doc_x <= rect->x1 + (rect->x2 - rect->x1) / 2)
- offset = j;
+ offset = i;
else
- offset = j + 1;
+ offset = i + 1;
break;
}
+ i++;
+ rect = areas + i;
}
- }
- if (offset == -1) {
- /* This is the last line and loocation is after the end of the line */
- offset = n_areas;
+ if (first_line_offset == -1)
+ i++;
}
+ if (last_line_offset == -1)
+ return FALSE;
+
+ if (offset == -1)
+ offset = last_line_offset;
+
if (view->cursor_offset != offset || view->cursor_page != page) {
view->cursor_offset = offset;
view->cursor_page = page;
@@ -5170,7 +5187,6 @@ cursor_backward_line (EvView *view)
PangoLogAttr *log_attrs = NULL;
gulong n_attrs;
- /* FIXME: Keep the line offset when moving between lines */
if (!cursor_go_to_line_start (view))
return FALSE;
@@ -5181,7 +5197,8 @@ cursor_backward_line (EvView *view)
do {
view->cursor_offset--;
- } while (view->cursor_offset >= 0 && !log_attrs[view->cursor_offset].is_cursor_position);
+ } while (view->cursor_offset >= 0 && !log_attrs[view->cursor_offset].is_mandatory_break);
+ view->cursor_offset = MAX (0, view->cursor_offset);
return TRUE;
}
@@ -5219,7 +5236,6 @@ cursor_forward_line (EvView *view)
PangoLogAttr *log_attrs = NULL;
gulong n_attrs;
- /* FIXME: Keep the line offset when moving between lines */
if (!cursor_go_to_line_end (view))
return FALSE;
@@ -5324,7 +5340,8 @@ ev_view_move_cursor (EvView *view,
return TRUE;
if (step == GTK_MOVEMENT_DISPLAY_LINES) {
- position_caret_cursor_at_location (view, view->cursor_line_offset,
+ position_caret_cursor_at_location (view,
+ MAX (rect.x, view->cursor_line_offset),
rect.y + (rect.height / 2));
} else {
view->cursor_line_offset = rect.x;