diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-08-05 16:35:10 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-08-05 16:35:10 -0700 |
commit | 458bfed397af18e460d01b888d1da095b6b95034 (patch) | |
tree | 6f3933c2deab13b0df064d87e7b6fa25d835cfcb /src | |
parent | 0e51f7172bd1ab8b9c1bb52598afb5017e19b9c3 (diff) | |
parent | 4640dd881c07162a6120ccb3b117b748badf78c9 (diff) |
Merge from trunk.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 28 | ||||
-rw-r--r-- | src/bidi.c | 75 | ||||
-rw-r--r-- | src/dispextern.h | 2 | ||||
-rw-r--r-- | src/dispnew.c | 2 | ||||
-rw-r--r-- | src/indent.c | 2 | ||||
-rw-r--r-- | src/window.c | 18 | ||||
-rw-r--r-- | src/xdisp.c | 74 |
7 files changed, 127 insertions, 74 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 94e7d98f81..53925dae40 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -408,6 +408,34 @@ (gs_load): Use printmax_t to print the widest integers possible. Check for integer overflow when computing image height and width. +2011-08-05 Eli Zaretskii <eliz@gnu.org> + + * bidi.c <bidi_cache_total_alloc>: Now static. + (bidi_initialize): Initialize bidi_cache_total_alloc. + + *xdisp.c (display_line): Release buffer allocated for shelved bidi + cache. (Bug#9221) + + * bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total + amount allocated this far in `bidi_cache_total_alloc'. + (bidi_unshelve_cache): Accept an additional argument JUST_FREE; if + non-zero, only free the data buffer without restoring the cache + contents. All callers changed. + + * dispextern.h (bidi_unshelve_cache): Update prototype. + + * xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to) + (move_it_in_display_line, move_it_to) + (move_it_vertically_backward, move_it_by_lines): Replace the call + to xfree to an equivalent call to bidi_unshelve_cache. + (move_it_in_display_line_to): Fix logic of returning + MOVE_POS_MATCH_OR_ZV in the bidi case. (Bug#9224) + +2011-08-05 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that + came from a string character with a `cursor' property. (Bug#9229) + 2011-08-04 Jan Djärv <jan.h.d@swipnet.se> * Makefile.in (LIB_PTHREAD): New variable. diff --git a/src/bidi.c b/src/bidi.c index f499ec37b9..f6ad22f8ea 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -628,17 +628,24 @@ bidi_pop_it (struct bidi_it *bidi_it) bidi_cache_last_idx = -1; } +static ptrdiff_t bidi_cache_total_alloc; + /* Stash away a copy of the cache and its control variables. */ void * bidi_shelve_cache (void) { unsigned char *databuf; + ptrdiff_t alloc; + /* Empty cache. */ if (bidi_cache_idx == 0) return NULL; - databuf = xmalloc (bidi_shelve_header_size - + bidi_cache_idx * sizeof (struct bidi_it)); + alloc = (bidi_shelve_header_size + + bidi_cache_idx * sizeof (struct bidi_it)); + databuf = xmalloc (alloc); + bidi_cache_total_alloc += alloc; + memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); memcpy (databuf + sizeof (bidi_cache_idx), bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); @@ -664,7 +671,7 @@ bidi_shelve_cache (void) /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ void -bidi_unshelve_cache (void *databuf) +bidi_unshelve_cache (void *databuf, int just_free) { unsigned char *p = databuf; @@ -677,30 +684,43 @@ bidi_unshelve_cache (void *databuf) } else { - memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); - bidi_cache_ensure_space (bidi_cache_idx); - memcpy (bidi_cache, p + sizeof (bidi_cache_idx), - bidi_cache_idx * sizeof (struct bidi_it)); - memcpy (bidi_cache_start_stack, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it), - sizeof (bidi_cache_start_stack)); - memcpy (&bidi_cache_sp, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack), - sizeof (bidi_cache_sp)); - memcpy (&bidi_cache_start, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), - sizeof (bidi_cache_start)); - memcpy (&bidi_cache_last_idx, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) - + sizeof (bidi_cache_start), - sizeof (bidi_cache_last_idx)); + if (just_free) + { + ptrdiff_t idx; + + memcpy (&idx, p, sizeof (bidi_cache_idx)); + bidi_cache_total_alloc -= + bidi_shelve_header_size + idx * sizeof (struct bidi_it); + } + else + { + memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); + bidi_cache_ensure_space (bidi_cache_idx); + memcpy (bidi_cache, p + sizeof (bidi_cache_idx), + bidi_cache_idx * sizeof (struct bidi_it)); + memcpy (bidi_cache_start_stack, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it), + sizeof (bidi_cache_start_stack)); + memcpy (&bidi_cache_sp, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack), + sizeof (bidi_cache_sp)); + memcpy (&bidi_cache_start, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), + sizeof (bidi_cache_start)); + memcpy (&bidi_cache_last_idx, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start), + sizeof (bidi_cache_last_idx)); + bidi_cache_total_alloc -= + bidi_shelve_header_size + bidi_cache_idx * sizeof (struct bidi_it); + } xfree (p); } @@ -747,6 +767,7 @@ bidi_initialize (void) staticpro (¶graph_separate_re); bidi_cache_sp = 0; + bidi_cache_total_alloc = 0; bidi_initialized = 1; } diff --git a/src/dispextern.h b/src/dispextern.h index 4976131018..02d1089e3e 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2979,7 +2979,7 @@ extern int bidi_mirror_char (int); extern void bidi_push_it (struct bidi_it *); extern void bidi_pop_it (struct bidi_it *); extern void *bidi_shelve_cache (void); -extern void bidi_unshelve_cache (void *); +extern void bidi_unshelve_cache (void *, int); /* Defined in xdisp.c */ diff --git a/src/dispnew.c b/src/dispnew.c index fde9be6bf5..5fedbb75a3 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5289,7 +5289,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p argument is ZV to prevent move_it_in_display_line from matching based on buffer positions. */ move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); Fset_buffer (old_current_buffer); diff --git a/src/indent.c b/src/indent.c index 37873351aa..313315e908 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2126,7 +2126,7 @@ whether or not it is currently displayed in some window. */) } SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); } if (BUFFERP (old_buffer)) diff --git a/src/window.c b/src/window.c index 04fea6b9bf..96b1144acf 100644 --- a/src/window.c +++ b/src/window.c @@ -1379,7 +1379,7 @@ if it isn't already recorded. */) if (it.current_y < it.last_visible_y) move_it_past_eol (&it); value = make_number (IT_CHARPOS (it)); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); if (old_buffer) set_buffer_internal (old_buffer); @@ -4273,7 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) } start = it.current.pos; - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); } else if (auto_window_vscroll_p) { @@ -4417,7 +4417,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) } else { - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); if (noerror) return; else if (n < 0) /* could happen with empty buffers */ @@ -4434,7 +4434,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) w->vscroll = 0; else { - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); if (noerror) return; else @@ -4583,7 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) SET_PT_BOTH (charpos, bytepos); } } - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); } @@ -5010,7 +5010,7 @@ displayed_window_lines (struct window *w) start_display (&it, w, start); move_it_vertically (&it, height); bottom_y = line_bottom_y (&it); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); /* rms: On a non-window display, the value of it.vpos at the bottom of the screen @@ -5116,7 +5116,7 @@ and redisplay normally--don't erase and redraw the frame. */) move_it_vertically_backward (&it, window_box_height (w) / 2); charpos = IT_CHARPOS (it); bytepos = IT_BYTEPOS (it); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); } else if (iarg < 0) { @@ -5164,7 +5164,7 @@ and redisplay normally--don't erase and redraw the frame. */) } if (h <= 0) { - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); return Qnil; } @@ -5187,7 +5187,7 @@ and redisplay normally--don't erase and redraw the frame. */) charpos = IT_CHARPOS (it); bytepos = IT_BYTEPOS (it); - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); } else { diff --git a/src/xdisp.c b/src/xdisp.c index bffb7bcdd7..481dd35c5d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -604,7 +604,7 @@ int current_mode_line_height, current_header_line_height; #define SAVE_IT(ITCOPY,ITORIG,CACHE) \ do { \ if (CACHE) \ - xfree (CACHE); \ + bidi_unshelve_cache (CACHE, 1); \ ITCOPY = ITORIG; \ CACHE = bidi_shelve_cache(); \ } while (0) @@ -613,7 +613,7 @@ int current_mode_line_height, current_header_line_height; do { \ if (pITORIG != pITCOPY) \ *(pITORIG) = *(pITCOPY); \ - bidi_unshelve_cache (CACHE); \ + bidi_unshelve_cache (CACHE, 0); \ CACHE = NULL; \ } while (0) @@ -1341,9 +1341,9 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, *vpos = it2.vpos; } else - xfree (it2data); + bidi_unshelve_cache (it2data, 1); } - bidi_unshelve_cache (itdata); + bidi_unshelve_cache (itdata, 0); if (old_buffer) set_buffer_internal_1 (old_buffer); @@ -2624,7 +2624,7 @@ init_iterator (struct it *it, struct window *w, it->paragraph_embedding = R2L; else it->paragraph_embedding = NEUTRAL_DIR; - bidi_unshelve_cache (NULL); + bidi_unshelve_cache (NULL, 0); bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), &it->bidi_it); } @@ -5615,7 +5615,7 @@ back_to_previous_visible_line_start (struct it *it) pos = --IT_CHARPOS (it2); --IT_BYTEPOS (it2); it2.sp = 0; - bidi_unshelve_cache (NULL); + bidi_unshelve_cache (NULL, 0); it2.string_from_display_prop_p = 0; it2.from_disp_prop_p = 0; if (handle_display_prop (&it2) == HANDLED_RETURN @@ -5825,7 +5825,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) { bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), &it->bidi_it); - bidi_unshelve_cache (NULL); + bidi_unshelve_cache (NULL, 0); it->bidi_it.paragraph_dir = NEUTRAL_DIR; it->bidi_it.string.s = NULL; it->bidi_it.string.lstring = Qnil; @@ -8006,13 +8006,13 @@ move_it_in_display_line_to (struct it *it, positions smaller than TO_CHARPOS, return MOVE_POS_MATCH_OR_ZV, like the unidirectional display did. */ - if ((op & MOVE_TO_POS) != 0 + if (it->bidi_p && (op & MOVE_TO_POS) != 0 && !saw_smaller_pos && IT_CHARPOS (*it) > to_charpos) { - result = MOVE_POS_MATCH_OR_ZV; - if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) + if (IT_CHARPOS (ppos_it) < ZV) RESTORE_IT (it, &ppos_it, ppos_data); + goto buffer_pos_reached; } else result = MOVE_NEWLINE_OR_CR; @@ -8051,14 +8051,13 @@ move_it_in_display_line_to (struct it *it, character positions smaller than TO_CHARPOS, return MOVE_POS_MATCH_OR_ZV, like the unidirectional display did. */ - || ((op & MOVE_TO_POS) != 0 + || (it->bidi_p && (op & MOVE_TO_POS) != 0 && !saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)) { - result = MOVE_POS_MATCH_OR_ZV; - if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV) + if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV) RESTORE_IT (it, &ppos_it, ppos_data); - break; + goto buffer_pos_reached; } if (ITERATOR_AT_END_OF_LINE_P (it)) { @@ -8066,14 +8065,13 @@ move_it_in_display_line_to (struct it *it, break; } } - else if ((op & MOVE_TO_POS) != 0 + else if (it->bidi_p && (op & MOVE_TO_POS) != 0 && !saw_smaller_pos && IT_CHARPOS (*it) > to_charpos) { - result = MOVE_POS_MATCH_OR_ZV; - if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) + if (IT_CHARPOS (ppos_it) < ZV) RESTORE_IT (it, &ppos_it, ppos_data); - break; + goto buffer_pos_reached; } result = MOVE_LINE_TRUNCATED; break; @@ -8093,13 +8091,13 @@ move_it_in_display_line_to (struct it *it, done: if (atpos_data) - xfree (atpos_data); + bidi_unshelve_cache (atpos_data, 1); if (atx_data) - xfree (atx_data); + bidi_unshelve_cache (atx_data, 1); if (wrap_data) - xfree (wrap_data); + bidi_unshelve_cache (wrap_data, 1); if (ppos_data) - xfree (ppos_data); + bidi_unshelve_cache (ppos_data, 1); /* Restore the iterator settings altered at the beginning of this function. */ @@ -8134,7 +8132,7 @@ move_it_in_display_line (struct it *it, (it, -1, prev_x, MOVE_TO_X); } else - xfree (save_data); + bidi_unshelve_cache (save_data, 1); } else move_it_in_display_line_to (it, to_charpos, to_x, op); @@ -8393,7 +8391,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos } if (backup_data) - xfree (backup_data); + bidi_unshelve_cache (backup_data, 1); TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); } @@ -8472,7 +8470,7 @@ move_it_vertically_backward (struct it *it, int dy) RESTORE_IT (it, it, it2data); if (nlines > 0) move_it_by_lines (it, nlines); - xfree (it3data); + bidi_unshelve_cache (it3data, 1); } else { @@ -8668,7 +8666,7 @@ move_it_by_lines (struct it *it, int dvpos) if (IT_CHARPOS (*it) >= start_charpos) RESTORE_IT (it, &it2, it2data); else - xfree (it2data); + bidi_unshelve_cache (it2data, 1); } else RESTORE_IT (it, it, it2data); @@ -13704,14 +13702,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, w->cursor.vpos >= 0 /* that candidate is not the row we are processing */ && MATRIX_ROW (matrix, w->cursor.vpos) != row - /* the row we are processing is part of a continued line */ - && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row)) /* Make sure cursor.vpos specifies a row whose start and end charpos occlude point. This is because some callers of this function leave cursor.vpos at the row where the cursor was displayed during the last redisplay cycle. */ && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old - && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))) + && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))) { struct glyph *g1 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos; @@ -13720,15 +13716,20 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)) return 0; /* Keep the candidate whose buffer position is the closest to - point. */ + point or has the `cursor' property. */ if (/* previous candidate is a glyph in TEXT_AREA of that row */ w->cursor.hpos >= 0 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos) - && BUFFERP (g1->object) - && (g1->charpos == pt_old /* an exact match always wins */ - || (BUFFERP (glyph->object) - && eabs (g1->charpos - pt_old) - < eabs (glyph->charpos - pt_old)))) + && ((BUFFERP (g1->object) + && (g1->charpos == pt_old /* an exact match always wins */ + || (BUFFERP (glyph->object) + && eabs (g1->charpos - pt_old) + < eabs (glyph->charpos - pt_old)))) + /* previous candidate is a glyph from a string that has + a non-nil `cursor' property */ + || (STRINGP (g1->object) + && !NILP (Fget_char_property (make_number (g1->charpos), + Qcursor, g1->object))))) return 0; /* If this candidate gives an exact match, use that. */ if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old) @@ -18774,6 +18775,9 @@ display_line (struct it *it) } } + if (wrap_data) + bidi_unshelve_cache (wrap_data, 1); + /* If line is not empty and hscrolled, maybe insert truncation glyphs at the left window margin. */ if (it->first_visible_x |