#include "character.h"
#include "buffer.h"
#include "dispextern.h"
+#include "region-cache.h"
static bool bidi_initialized = 0;
are zero-based character positions in S, BEGBYTE is byte position
corresponding to BEG. UNIBYTE means S is a unibyte string. */
static ptrdiff_t
-bidi_count_bytes (const unsigned char *s, const ptrdiff_t beg,
- const ptrdiff_t begbyte, const ptrdiff_t end, bool unibyte)
+bidi_count_bytes (const unsigned char *s, ptrdiff_t beg,
+ ptrdiff_t begbyte, ptrdiff_t end, bool unibyte)
{
ptrdiff_t pos = beg;
const unsigned char *p = s + begbyte, *start = p;
static int
bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
int *disp_prop, struct bidi_string_data *string,
+ struct window *w,
bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars)
{
int ch;
if (charpos < endpos && charpos > *disp_pos)
{
SET_TEXT_POS (pos, charpos, bytepos);
- *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+ *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
disp_prop);
}
&& *disp_prop)
{
SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
- *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+ *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
disp_prop);
}
return val;
}
+/* If the user has requested the long scans caching, make sure that
+ BIDI cache is enabled. Otherwise, make sure it's disabled. */
+
+static struct region_cache *
+bidi_paragraph_cache_on_off (void)
+{
+ if (NILP (BVAR (current_buffer, cache_long_scans)))
+ {
+ if (current_buffer->bidi_paragraph_cache)
+ {
+ free_region_cache (current_buffer->bidi_paragraph_cache);
+ current_buffer->bidi_paragraph_cache = 0;
+ }
+ return NULL;
+ }
+ else
+ {
+ if (!current_buffer->bidi_paragraph_cache)
+ current_buffer->bidi_paragraph_cache = new_region_cache ();
+ return current_buffer->bidi_paragraph_cache;
+ }
+}
+
/* On my 2005-vintage machine, searching back for paragraph start
takes ~1 ms per line. And bidi_paragraph_init is called 4 times
when user types C-p. The number below limits each call to
{
Lisp_Object re = paragraph_start_re;
ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
- ptrdiff_t n = 0;
+ struct region_cache *bpc = bidi_paragraph_cache_on_off ();
+ ptrdiff_t n = 0, oldpos = pos, next;
while (pos_byte > BEGV_BYTE
&& n++ < MAX_PARAGRAPH_SEARCH
of the text over which we scan back includes
paragraph_start_re? */
DEC_BOTH (pos, pos_byte);
- pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
+ if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
+ {
+ pos = next, pos_byte = CHAR_TO_BYTE (pos);
+ break;
+ }
+ else
+ pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
}
if (n >= MAX_PARAGRAPH_SEARCH)
- pos_byte = BEGV_BYTE;
+ pos = BEGV, pos_byte = BEGV_BYTE;
+ if (bpc)
+ know_region_cache (current_buffer, bpc, pos, oldpos);
return pos_byte;
}
if (!string_p)
pos = BYTE_TO_CHAR (bytepos);
ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop,
- &bidi_it->string,
+ &bidi_it->string, bidi_it->w,
bidi_it->frame_window_p, &ch_len, &nchars);
type = bidi_get_type (ch, NEUTRAL_DIR);
break;
/* Fetch next character and advance to get past it. */
ch = bidi_fetch_char (pos, bytepos, &disp_pos,
- &disp_prop, &bidi_it->string,
+ &disp_prop, &bidi_it->string, bidi_it->w,
bidi_it->frame_window_p, &ch_len, &nchars);
pos += nchars;
bytepos += ch_len;
a single character u+FFFC. */
curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos,
&bidi_it->disp_pos, &bidi_it->disp_prop,
- &bidi_it->string, bidi_it->frame_window_p,
+ &bidi_it->string, bidi_it->w,
+ bidi_it->frame_window_p,
&bidi_it->ch_len, &bidi_it->nchars);
}
bidi_it->ch = curchar;
emacs_abort ();
do {
ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
- fwp, &clen, &nc);
+ bidi_it->w, fwp, &clen, &nc);
if (ch == '\n' || ch == BIDI_EOB)
chtype = NEUTRAL_B;
else