aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2008-07-10 23:47:00 +0000
committerChong Yidong2008-07-10 23:47:00 +0000
commit3873a30f7f059d7f4a37eeb68d9123c5a1eb578a (patch)
tree473ceb030d003076affc08ab6dd9d9023d5013f8 /src
parente0f47a6850bb4abd4103b05ee323d82a1dca92f5 (diff)
downloademacs-3873a30f7f059d7f4a37eeb68d9123c5a1eb578a.tar.gz
emacs-3873a30f7f059d7f4a37eeb68d9123c5a1eb578a.zip
(move_it_to): Backtrack if past the edge of a wrapped line.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c87
1 files changed, 51 insertions, 36 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 00bedccd9f8..f5dfd547705 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -7117,6 +7117,9 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7117 { 7117 {
7118 struct it it_backup; 7118 struct it it_backup;
7119 7119
7120 if (it->line_wrap == WORD_WRAP)
7121 it_backup = *it;
7122
7120 /* TO_Y specified means stop at TO_X in the line containing 7123 /* TO_Y specified means stop at TO_X in the line containing
7121 TO_Y---or at TO_CHARPOS if this is reached first. The 7124 TO_Y---or at TO_CHARPOS if this is reached first. The
7122 problem is that we can't really tell whether the line 7125 problem is that we can't really tell whether the line
@@ -7129,28 +7132,19 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7129 If we didn't use TO_X == 0, we would stop at the end of 7132 If we didn't use TO_X == 0, we would stop at the end of
7130 the line which is probably not what a caller would expect 7133 the line which is probably not what a caller would expect
7131 to happen. */ 7134 to happen. */
7132 skip = move_it_in_display_line_to (it, to_charpos, 7135 skip = move_it_in_display_line_to
7133 ((op & MOVE_TO_X) 7136 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7134 ? to_x : 0), 7137 (MOVE_TO_X | (op & MOVE_TO_POS)));
7135 (MOVE_TO_X
7136 | (op & MOVE_TO_POS)));
7137 7138
7138 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */ 7139 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7139 if (skip == MOVE_POS_MATCH_OR_ZV) 7140 if (skip == MOVE_POS_MATCH_OR_ZV)
7141 reached = 5;
7142 else if (skip == MOVE_X_REACHED)
7140 { 7143 {
7141 reached = 5; 7144 /* If TO_X was reached, we want to know whether TO_Y is
7142 break; 7145 in the line. We know this is the case if the already
7143 } 7146 scanned glyphs make the line tall enough. Otherwise,
7144 7147 we must check by scanning the rest of the line. */
7145 /* If TO_X was reached, we would like to know whether TO_Y
7146 is in the line. This can only be said if we know the
7147 total line height which requires us to scan the rest of
7148 the line. */
7149 if (skip == MOVE_X_REACHED)
7150 {
7151 /* Wait! We can conclude that TO_Y is in the line if
7152 the already scanned glyphs make the line tall enough
7153 because further scanning doesn't make it shorter. */
7154 line_height = it->max_ascent + it->max_descent; 7148 line_height = it->max_ascent + it->max_descent;
7155 if (to_y >= it->current_y 7149 if (to_y >= it->current_y
7156 && to_y < it->current_y + line_height) 7150 && to_y < it->current_y + line_height)
@@ -7163,27 +7157,48 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7163 skip2 = move_it_in_display_line_to (it, to_charpos, -1, 7157 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7164 op & MOVE_TO_POS); 7158 op & MOVE_TO_POS);
7165 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it))); 7159 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7166 } 7160 line_height = it->max_ascent + it->max_descent;
7167 7161 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7168 /* Now, decide whether TO_Y is in this line. */
7169 line_height = it->max_ascent + it->max_descent;
7170 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7171 7162
7172 if (to_y >= it->current_y 7163 if (to_y >= it->current_y
7173 && to_y < it->current_y + line_height) 7164 && to_y < it->current_y + line_height)
7174 { 7165 {
7175 if (skip == MOVE_X_REACHED) 7166 /* If TO_Y is in this line and TO_X was reached
7176 /* If TO_Y is in this line and TO_X was reached above, 7167 above, we scanned too far. We have to restore
7177 we scanned too far. We have to restore IT's settings 7168 IT's settings to the ones before skipping. */
7178 to the ones before skipping. */ 7169 *it = it_backup;
7179 *it = it_backup; 7170 reached = 6;
7180 reached = 6; 7171 }
7172 else
7173 {
7174 skip = skip2;
7175 if (skip == MOVE_POS_MATCH_OR_ZV)
7176 reached = 7;
7177 }
7181 } 7178 }
7182 else if (skip == MOVE_X_REACHED) 7179 else
7183 { 7180 {
7184 skip = skip2; 7181 /* Check whether TO_Y is in this line. */
7185 if (skip == MOVE_POS_MATCH_OR_ZV) 7182 line_height = it->max_ascent + it->max_descent;
7186 reached = 7; 7183 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7184
7185 if (to_y >= it->current_y
7186 && to_y < it->current_y + line_height)
7187 {
7188 /* When word-wrap is on, TO_X may lie past the end
7189 of a wrapped line. Then it->current is the
7190 character on the next line, so backtrack to the
7191 space before the wrap point. */
7192 if (skip == MOVE_LINE_CONTINUED
7193 && it->line_wrap == WORD_WRAP)
7194 {
7195 int prev_x = max (it->current_x - 1, 0);
7196 *it = it_backup;
7197 skip = move_it_in_display_line_to
7198 (it, -1, prev_x, MOVE_TO_X);
7199 }
7200 reached = 6;
7201 }
7187 } 7202 }
7188 7203
7189 if (reached) 7204 if (reached)