aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-06-23 21:09:52 +0300
committerEli Zaretskii2011-06-23 21:09:52 +0300
commit58b9f433ad4a4ea20e0c51997ca8a9aaab79a213 (patch)
tree21af9e9dc36b10b28c74e2a32009fdcd9db3610e /src
parentcbb09f044675c83f7e1f3a73dfe944a90a583dfe (diff)
downloademacs-58b9f433ad4a4ea20e0c51997ca8a9aaab79a213.tar.gz
emacs-58b9f433ad4a4ea20e0c51997ca8a9aaab79a213.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/bidi.c120
-rw-r--r--src/dispextern.h2
3 files changed, 105 insertions, 26 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 37e1e85219f..40576554636 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12011-06-23 Eli Zaretskii <eliz@gnu.org>
2
3 * dispextern.h (bidi_push_it, bidi_pop_it): Add prototypes.
4
5 * bidi.c (bidi_push_it, bidi_pop_it): New functions.
6 (bidi_initialize): Initialize the bidi cache start stack pointer.
7 (bidi_cache_ensure_space): New function, refactored from part of
8 bidi_cache_iterator_state.
9
12011-06-18 Eli Zaretskii <eliz@gnu.org> 102011-06-18 Eli Zaretskii <eliz@gnu.org>
2 11
3 * xdisp.c (tool_bar_lines_needed, redisplay_tool_bar) 12 * 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;
87 87
88/* Return the bidi type of a character CH, subject to the current 88/* Return the bidi type of a character CH, subject to the current
89 directional OVERRIDE. */ 89 directional OVERRIDE. */
90static INLINE bidi_type_t 90static inline bidi_type_t
91bidi_get_type (int ch, bidi_dir_t override) 91bidi_get_type (int ch, bidi_dir_t override)
92{ 92{
93 bidi_type_t default_type; 93 bidi_type_t default_type;
@@ -138,7 +138,7 @@ bidi_check_type (bidi_type_t type)
138} 138}
139 139
140/* Given a bidi TYPE of a character, return its category. */ 140/* Given a bidi TYPE of a character, return its category. */
141static INLINE bidi_category_t 141static inline bidi_category_t
142bidi_get_category (bidi_type_t type) 142bidi_get_category (bidi_type_t type)
143{ 143{
144 switch (type) 144 switch (type)
@@ -204,7 +204,7 @@ bidi_mirror_char (int c)
204 embedding levels on either side of the run boundary. Also, update 204 embedding levels on either side of the run boundary. Also, update
205 the saved info about previously seen characters, since that info is 205 the saved info about previously seen characters, since that info is
206 generally valid for a single level run. */ 206 generally valid for a single level run. */
207static INLINE void 207static inline void
208bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) 208bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after)
209{ 209{
210 int higher_level = level_before > level_after ? level_before : level_after; 210 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)
235 235
236/* Push the current embedding level and override status; reset the 236/* Push the current embedding level and override status; reset the
237 current level to LEVEL and the current override status to OVERRIDE. */ 237 current level to LEVEL and the current override status to OVERRIDE. */
238static INLINE void 238static inline void
239bidi_push_embedding_level (struct bidi_it *bidi_it, 239bidi_push_embedding_level (struct bidi_it *bidi_it,
240 int level, bidi_dir_t override) 240 int level, bidi_dir_t override)
241{ 241{
@@ -248,7 +248,7 @@ bidi_push_embedding_level (struct bidi_it *bidi_it,
248 248
249/* Pop the embedding level and directional override status from the 249/* Pop the embedding level and directional override status from the
250 stack, and return the new level. */ 250 stack, and return the new level. */
251static INLINE int 251static inline int
252bidi_pop_embedding_level (struct bidi_it *bidi_it) 252bidi_pop_embedding_level (struct bidi_it *bidi_it)
253{ 253{
254 /* UAX#9 says to ignore invalid PDFs. */ 254 /* UAX#9 says to ignore invalid PDFs. */
@@ -258,7 +258,7 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it)
258} 258}
259 259
260/* Record in SAVED_INFO the information about the current character. */ 260/* Record in SAVED_INFO the information about the current character. */
261static INLINE void 261static inline void
262bidi_remember_char (struct bidi_saved_info *saved_info, 262bidi_remember_char (struct bidi_saved_info *saved_info,
263 struct bidi_it *bidi_it) 263 struct bidi_it *bidi_it)
264{ 264{
@@ -274,7 +274,7 @@ bidi_remember_char (struct bidi_saved_info *saved_info,
274 274
275/* Copy the bidi iterator from FROM to TO. To save cycles, this only 275/* Copy the bidi iterator from FROM to TO. To save cycles, this only
276 copies the part of the level stack that is actually in use. */ 276 copies the part of the level stack that is actually in use. */
277static INLINE void 277static inline void
278bidi_copy_it (struct bidi_it *to, struct bidi_it *from) 278bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
279{ 279{
280 int i; 280 int i;
@@ -308,7 +308,7 @@ static EMACS_INT bidi_cache_start = 0; /* start of cache for this
308 intact. This is called when the cached information is no more 308 intact. This is called when the cached information is no more
309 useful for the current iteration, e.g. when we were reseated to a 309 useful for the current iteration, e.g. when we were reseated to a
310 new position on the same object. */ 310 new position on the same object. */
311static INLINE void 311static inline void
312bidi_cache_reset (void) 312bidi_cache_reset (void)
313{ 313{
314 bidi_cache_idx = bidi_cache_start; 314 bidi_cache_idx = bidi_cache_start;
@@ -319,7 +319,7 @@ bidi_cache_reset (void)
319 iterator for reordering a buffer or a string that does not come 319 iterator for reordering a buffer or a string that does not come
320 from display properties, because that means all the previously 320 from display properties, because that means all the previously
321 cached info is of no further use. */ 321 cached info is of no further use. */
322static INLINE void 322static inline void
323bidi_cache_shrink (void) 323bidi_cache_shrink (void)
324{ 324{
325 if (bidi_cache_size > BIDI_CACHE_CHUNK) 325 if (bidi_cache_size > BIDI_CACHE_CHUNK)
@@ -331,7 +331,7 @@ bidi_cache_shrink (void)
331 bidi_cache_reset (); 331 bidi_cache_reset ();
332} 332}
333 333
334static INLINE void 334static inline void
335bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) 335bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
336{ 336{
337 int current_scan_dir = bidi_it->scan_dir; 337 int current_scan_dir = bidi_it->scan_dir;
@@ -348,7 +348,7 @@ bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
348 level less or equal to LEVEL. if LEVEL is -1, disregard the 348 level less or equal to LEVEL. if LEVEL is -1, disregard the
349 resolved levels in cached states. DIR, if non-zero, means search 349 resolved levels in cached states. DIR, if non-zero, means search
350 in that direction from the last cache hit. */ 350 in that direction from the last cache hit. */
351static INLINE int 351static inline int
352bidi_cache_search (EMACS_INT charpos, int level, int dir) 352bidi_cache_search (EMACS_INT charpos, int level, int dir)
353{ 353{
354 int i, i_start; 354 int i, i_start;
@@ -449,7 +449,19 @@ bidi_cache_find_level_change (int level, int dir, int before)
449 return -1; 449 return -1;
450} 450}
451 451
452static INLINE void 452static inline void
453bidi_cache_ensure_space (int idx)
454{
455 /* Enlarge the cache as needed. */
456 if (idx >= bidi_cache_size)
457 {
458 bidi_cache_size += BIDI_CACHE_CHUNK;
459 bidi_cache =
460 (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
461 }
462}
463
464static inline void
453bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) 465bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
454{ 466{
455 int idx; 467 int idx;
@@ -462,13 +474,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
462 if (idx < 0) 474 if (idx < 0)
463 { 475 {
464 idx = bidi_cache_idx; 476 idx = bidi_cache_idx;
465 /* Enlarge the cache as needed. */ 477 bidi_cache_ensure_space (idx);
466 if (idx >= bidi_cache_size)
467 {
468 bidi_cache_size += BIDI_CACHE_CHUNK;
469 bidi_cache =
470 (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
471 }
472 /* Character positions should correspond to cache positions 1:1. 478 /* Character positions should correspond to cache positions 1:1.
473 If we are outside the range of cached positions, the cache is 479 If we are outside the range of cached positions, the cache is
474 useless and must be reset. */ 480 useless and must be reset. */
@@ -510,7 +516,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
510 bidi_cache_idx = idx + 1; 516 bidi_cache_idx = idx + 1;
511} 517}
512 518
513static INLINE bidi_type_t 519static inline bidi_type_t
514bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) 520bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it)
515{ 521{
516 int i = bidi_cache_search (charpos, level, bidi_it->scan_dir); 522 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)
530 return UNKNOWN_BT; 536 return UNKNOWN_BT;
531} 537}
532 538
533static INLINE int 539static inline int
534bidi_peek_at_next_level (struct bidi_it *bidi_it) 540bidi_peek_at_next_level (struct bidi_it *bidi_it)
535{ 541{
536 if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1) 542 if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1)
@@ -540,6 +546,64 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it)
540 546
541 547
542/*********************************************************************** 548/***********************************************************************
549 Pushing and popping the bidi iterator state
550 ***********************************************************************/
551/* 10-slot stack for saving the start of the previous level of the
552 cache. xdisp.c maintains a 5-slot cache for its iterator state,
553 and we need just a little bit more. */
554#define CACHE_STACK_SIZE 10
555static int bidi_cache_start_stack[CACHE_STACK_SIZE];
556static int bidi_cache_sp;
557
558/* Push the bidi iterator state in preparation for reordering a
559 different object, e.g. display string found at certain buffer
560 position. Pushing the bidi iterator boils to saving its entire
561 state on the cache and starting a new cache "stacked" on top of the
562 current cache. */
563void
564bidi_push_it (struct bidi_it *bidi_it)
565{
566 /* Save the current iterator state in its entirety after the last
567 used cache slot. */
568 bidi_cache_ensure_space (bidi_cache_idx);
569 memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it));
570
571 /* Push the current cache start onto the stack. */
572 if (bidi_cache_sp >= CACHE_STACK_SIZE)
573 abort ();
574 bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start;
575
576 /* Start a new level of cache, and make it empty. */
577 bidi_cache_start = bidi_cache_idx;
578 bidi_cache_last_idx = -1;
579}
580
581/* Restore the iterator state saved by bidi_push_it and return the
582 cache to the corresponding state. */
583void
584bidi_pop_it (struct bidi_it *bidi_it)
585{
586 if (bidi_cache_start <= 0)
587 abort ();
588
589 /* Reset the next free cache slot index to what it was before the
590 call to bidi_push_it. */
591 bidi_cache_idx = bidi_cache_start - 1;
592
593 /* Restore the bidi iterator state saved in the cache. */
594 memcpy (bidi_it, &bidi_cache[bidi_cache_idx], sizeof (struct bidi_it));
595
596 /* Pop the previous cache start from the stack. */
597 if (bidi_cache_sp <= 0)
598 abort ();
599 bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp];
600
601 /* Invalidate the last-used cache slot data. */
602 bidi_cache_last_idx = -1;
603}
604
605
606/***********************************************************************
543 Initialization 607 Initialization
544 ***********************************************************************/ 608 ***********************************************************************/
545static void 609static void
@@ -577,12 +641,15 @@ bidi_initialize (void)
577 if (!STRINGP (paragraph_separate_re)) 641 if (!STRINGP (paragraph_separate_re))
578 paragraph_separate_re = build_string ("[ \t\f]*$"); 642 paragraph_separate_re = build_string ("[ \t\f]*$");
579 staticpro (&paragraph_separate_re); 643 staticpro (&paragraph_separate_re);
644
645 bidi_cache_sp = 0;
646
580 bidi_initialized = 1; 647 bidi_initialized = 1;
581} 648}
582 649
583/* Do whatever UAX#9 clause X8 says should be done at paragraph's 650/* Do whatever UAX#9 clause X8 says should be done at paragraph's
584 end. */ 651 end. */
585static INLINE void 652static inline void
586bidi_set_paragraph_end (struct bidi_it *bidi_it) 653bidi_set_paragraph_end (struct bidi_it *bidi_it)
587{ 654{
588 bidi_it->invalid_levels = 0; 655 bidi_it->invalid_levels = 0;
@@ -630,6 +697,8 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
630 "stack". */ 697 "stack". */
631 if (bidi_cache_start == 0) 698 if (bidi_cache_start == 0)
632 bidi_cache_shrink (); 699 bidi_cache_shrink ();
700 else
701 bidi_cache_reset ();
633} 702}
634 703
635/* Perform initializations for reordering a new line of bidi text. */ 704/* 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)
1012 1081
1013/*********************************************************************** 1082/***********************************************************************
1014 Resolving explicit and implicit levels. 1083 Resolving explicit and implicit levels.
1015 The rest of the file constitutes the core 1084 The rest of this file constitutes the core of the UBA implementation.
1016 of the UBA implementation.
1017 ***********************************************************************/ 1085 ***********************************************************************/
1018 1086
1019static INLINE int 1087static inline int
1020bidi_explicit_dir_char (int ch) 1088bidi_explicit_dir_char (int ch)
1021{ 1089{
1022 bidi_type_t ch_type; 1090 bidi_type_t ch_type;
@@ -1515,7 +1583,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1515 1583
1516/* Resolve the type of a neutral character according to the type of 1584/* Resolve the type of a neutral character according to the type of
1517 surrounding strong text and the current embedding level. */ 1585 surrounding strong text and the current embedding level. */
1518static INLINE bidi_type_t 1586static inline bidi_type_t
1519bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) 1587bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
1520{ 1588{
1521 /* N1: European and Arabic numbers are treated as though they were R. */ 1589 /* 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 *);
2962extern void bidi_move_to_visually_next (struct bidi_it *); 2962extern void bidi_move_to_visually_next (struct bidi_it *);
2963extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); 2963extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int);
2964extern int bidi_mirror_char (int); 2964extern int bidi_mirror_char (int);
2965extern void bidi_push_it (struct bidi_it *);
2966extern void bidi_pop_it (struct bidi_it *);
2965 2967
2966/* Defined in xdisp.c */ 2968/* Defined in xdisp.c */
2967 2969