From: Eli Zaretskii Date: Thu, 23 Jun 2011 18:09:52 +0000 (+0300) Subject: Added to bidi.c support functions for reordering display strings. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~14 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=58b9f433ad4a4ea20e0c51997ca8a9aaab79a213;p=emacs.git Added to bidi.c support functions for reordering display strings. src/bidi.c (bidi_push_it, bidi_pop_it): New functions. (bidi_initialize): Initialize the bidi cache start stack pointer. (bidi_cache_ensure_space): New function, refactored from part of bidi_cache_iterator_state. src/dispextern.h (bidi_push_it, bidi_pop_it): Add prototypes. --- diff --git a/src/ChangeLog b/src/ChangeLog index 37e1e85219f..40576554636 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2011-06-23 Eli Zaretskii + + * dispextern.h (bidi_push_it, bidi_pop_it): Add prototypes. + + * bidi.c (bidi_push_it, bidi_pop_it): New functions. + (bidi_initialize): Initialize the bidi cache start stack pointer. + (bidi_cache_ensure_space): New function, refactored from part of + bidi_cache_iterator_state. + 2011-06-18 Eli Zaretskii * xdisp.c (tool_bar_lines_needed, redisplay_tool_bar) diff --git a/src/bidi.c b/src/bidi.c index 0f5d43147e2..b03e93df817 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -87,7 +87,7 @@ static Lisp_Object Qparagraph_start, Qparagraph_separate; /* Return the bidi type of a character CH, subject to the current directional OVERRIDE. */ -static INLINE bidi_type_t +static inline bidi_type_t bidi_get_type (int ch, bidi_dir_t override) { bidi_type_t default_type; @@ -138,7 +138,7 @@ bidi_check_type (bidi_type_t type) } /* Given a bidi TYPE of a character, return its category. */ -static INLINE bidi_category_t +static inline bidi_category_t bidi_get_category (bidi_type_t type) { switch (type) @@ -204,7 +204,7 @@ bidi_mirror_char (int c) embedding levels on either side of the run boundary. Also, update the saved info about previously seen characters, since that info is generally valid for a single level run. */ -static INLINE void +static inline void bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) { int higher_level = level_before > level_after ? level_before : level_after; @@ -235,7 +235,7 @@ bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) /* Push the current embedding level and override status; reset the current level to LEVEL and the current override status to OVERRIDE. */ -static INLINE void +static inline void bidi_push_embedding_level (struct bidi_it *bidi_it, int level, bidi_dir_t override) { @@ -248,7 +248,7 @@ bidi_push_embedding_level (struct bidi_it *bidi_it, /* Pop the embedding level and directional override status from the stack, and return the new level. */ -static INLINE int +static inline int bidi_pop_embedding_level (struct bidi_it *bidi_it) { /* UAX#9 says to ignore invalid PDFs. */ @@ -258,7 +258,7 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) } /* Record in SAVED_INFO the information about the current character. */ -static INLINE void +static inline void bidi_remember_char (struct bidi_saved_info *saved_info, struct bidi_it *bidi_it) { @@ -274,7 +274,7 @@ bidi_remember_char (struct bidi_saved_info *saved_info, /* Copy the bidi iterator from FROM to TO. To save cycles, this only copies the part of the level stack that is actually in use. */ -static INLINE void +static inline void bidi_copy_it (struct bidi_it *to, struct bidi_it *from) { int i; @@ -308,7 +308,7 @@ static EMACS_INT bidi_cache_start = 0; /* start of cache for this intact. This is called when the cached information is no more useful for the current iteration, e.g. when we were reseated to a new position on the same object. */ -static INLINE void +static inline void bidi_cache_reset (void) { bidi_cache_idx = bidi_cache_start; @@ -319,7 +319,7 @@ bidi_cache_reset (void) iterator for reordering a buffer or a string that does not come from display properties, because that means all the previously cached info is of no further use. */ -static INLINE void +static inline void bidi_cache_shrink (void) { if (bidi_cache_size > BIDI_CACHE_CHUNK) @@ -331,7 +331,7 @@ bidi_cache_shrink (void) bidi_cache_reset (); } -static INLINE void +static inline void bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) { int current_scan_dir = bidi_it->scan_dir; @@ -348,7 +348,7 @@ bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) level less or equal to LEVEL. if LEVEL is -1, disregard the resolved levels in cached states. DIR, if non-zero, means search in that direction from the last cache hit. */ -static INLINE int +static inline int bidi_cache_search (EMACS_INT charpos, int level, int dir) { int i, i_start; @@ -449,7 +449,19 @@ bidi_cache_find_level_change (int level, int dir, int before) return -1; } -static INLINE void +static inline void +bidi_cache_ensure_space (int idx) +{ + /* Enlarge the cache as needed. */ + if (idx >= bidi_cache_size) + { + bidi_cache_size += BIDI_CACHE_CHUNK; + bidi_cache = + (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); + } +} + +static inline void bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) { int idx; @@ -462,13 +474,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) if (idx < 0) { idx = bidi_cache_idx; - /* Enlarge the cache as needed. */ - if (idx >= bidi_cache_size) - { - bidi_cache_size += BIDI_CACHE_CHUNK; - bidi_cache = - (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); - } + bidi_cache_ensure_space (idx); /* Character positions should correspond to cache positions 1:1. If we are outside the range of cached positions, the cache is useless and must be reset. */ @@ -510,7 +516,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) bidi_cache_idx = idx + 1; } -static INLINE bidi_type_t +static inline bidi_type_t bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) { int i = bidi_cache_search (charpos, level, bidi_it->scan_dir); @@ -530,7 +536,7 @@ bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) return UNKNOWN_BT; } -static INLINE int +static inline int bidi_peek_at_next_level (struct bidi_it *bidi_it) { if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1) @@ -538,6 +544,64 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it) return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; } + +/*********************************************************************** + Pushing and popping the bidi iterator state + ***********************************************************************/ +/* 10-slot stack for saving the start of the previous level of the + cache. xdisp.c maintains a 5-slot cache for its iterator state, + and we need just a little bit more. */ +#define CACHE_STACK_SIZE 10 +static int bidi_cache_start_stack[CACHE_STACK_SIZE]; +static int bidi_cache_sp; + +/* Push the bidi iterator state in preparation for reordering a + different object, e.g. display string found at certain buffer + position. Pushing the bidi iterator boils to saving its entire + state on the cache and starting a new cache "stacked" on top of the + current cache. */ +void +bidi_push_it (struct bidi_it *bidi_it) +{ + /* Save the current iterator state in its entirety after the last + used cache slot. */ + bidi_cache_ensure_space (bidi_cache_idx); + memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it)); + + /* Push the current cache start onto the stack. */ + if (bidi_cache_sp >= CACHE_STACK_SIZE) + abort (); + bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start; + + /* Start a new level of cache, and make it empty. */ + bidi_cache_start = bidi_cache_idx; + bidi_cache_last_idx = -1; +} + +/* Restore the iterator state saved by bidi_push_it and return the + cache to the corresponding state. */ +void +bidi_pop_it (struct bidi_it *bidi_it) +{ + if (bidi_cache_start <= 0) + abort (); + + /* Reset the next free cache slot index to what it was before the + call to bidi_push_it. */ + bidi_cache_idx = bidi_cache_start - 1; + + /* Restore the bidi iterator state saved in the cache. */ + memcpy (bidi_it, &bidi_cache[bidi_cache_idx], sizeof (struct bidi_it)); + + /* Pop the previous cache start from the stack. */ + if (bidi_cache_sp <= 0) + abort (); + bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp]; + + /* Invalidate the last-used cache slot data. */ + bidi_cache_last_idx = -1; +} + /*********************************************************************** Initialization @@ -577,12 +641,15 @@ bidi_initialize (void) if (!STRINGP (paragraph_separate_re)) paragraph_separate_re = build_string ("[ \t\f]*$"); staticpro (¶graph_separate_re); + + bidi_cache_sp = 0; + bidi_initialized = 1; } /* Do whatever UAX#9 clause X8 says should be done at paragraph's end. */ -static INLINE void +static inline void bidi_set_paragraph_end (struct bidi_it *bidi_it) { bidi_it->invalid_levels = 0; @@ -630,6 +697,8 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, "stack". */ if (bidi_cache_start == 0) bidi_cache_shrink (); + else + bidi_cache_reset (); } /* Perform initializations for reordering a new line of bidi text. */ @@ -1012,11 +1081,10 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) /*********************************************************************** Resolving explicit and implicit levels. - The rest of the file constitutes the core - of the UBA implementation. + The rest of this file constitutes the core of the UBA implementation. ***********************************************************************/ -static INLINE int +static inline int bidi_explicit_dir_char (int ch) { bidi_type_t ch_type; @@ -1515,7 +1583,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) /* Resolve the type of a neutral character according to the type of surrounding strong text and the current embedding level. */ -static INLINE bidi_type_t +static inline bidi_type_t bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) { /* N1: European and Arabic numbers are treated as though they were R. */ diff --git a/src/dispextern.h b/src/dispextern.h index 5cb28fa0f7a..acd7862e5dc 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2962,6 +2962,8 @@ extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *); extern void bidi_move_to_visually_next (struct bidi_it *); extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); extern int bidi_mirror_char (int); +extern void bidi_push_it (struct bidi_it *); +extern void bidi_pop_it (struct bidi_it *); /* Defined in xdisp.c */