diff options
| author | Eli Zaretskii | 2011-06-23 21:09:52 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-06-23 21:09:52 +0300 |
| commit | 58b9f433ad4a4ea20e0c51997ca8a9aaab79a213 (patch) | |
| tree | 21af9e9dc36b10b28c74e2a32009fdcd9db3610e /src | |
| parent | cbb09f044675c83f7e1f3a73dfe944a90a583dfe (diff) | |
| download | emacs-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/ChangeLog | 9 | ||||
| -rw-r--r-- | src/bidi.c | 120 | ||||
| -rw-r--r-- | src/dispextern.h | 2 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-06-18 Eli Zaretskii <eliz@gnu.org> | 10 | 2011-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. */ |
| 90 | static INLINE bidi_type_t | 90 | static inline bidi_type_t |
| 91 | bidi_get_type (int ch, bidi_dir_t override) | 91 | bidi_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. */ |
| 141 | static INLINE bidi_category_t | 141 | static inline bidi_category_t |
| 142 | bidi_get_category (bidi_type_t type) | 142 | bidi_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. */ |
| 207 | static INLINE void | 207 | static inline void |
| 208 | bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | 208 | bidi_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. */ |
| 238 | static INLINE void | 238 | static inline void |
| 239 | bidi_push_embedding_level (struct bidi_it *bidi_it, | 239 | bidi_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. */ |
| 251 | static INLINE int | 251 | static inline int |
| 252 | bidi_pop_embedding_level (struct bidi_it *bidi_it) | 252 | bidi_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. */ |
| 261 | static INLINE void | 261 | static inline void |
| 262 | bidi_remember_char (struct bidi_saved_info *saved_info, | 262 | bidi_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. */ |
| 277 | static INLINE void | 277 | static inline void |
| 278 | bidi_copy_it (struct bidi_it *to, struct bidi_it *from) | 278 | bidi_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. */ |
| 311 | static INLINE void | 311 | static inline void |
| 312 | bidi_cache_reset (void) | 312 | bidi_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. */ |
| 322 | static INLINE void | 322 | static inline void |
| 323 | bidi_cache_shrink (void) | 323 | bidi_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 | ||
| 334 | static INLINE void | 334 | static inline void |
| 335 | bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) | 335 | bidi_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. */ |
| 351 | static INLINE int | 351 | static inline int |
| 352 | bidi_cache_search (EMACS_INT charpos, int level, int dir) | 352 | bidi_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 | ||
| 452 | static INLINE void | 452 | static inline void |
| 453 | bidi_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 | |||
| 464 | static inline void | ||
| 453 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | 465 | bidi_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 | ||
| 513 | static INLINE bidi_type_t | 519 | static inline bidi_type_t |
| 514 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) | 520 | bidi_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 | ||
| 533 | static INLINE int | 539 | static inline int |
| 534 | bidi_peek_at_next_level (struct bidi_it *bidi_it) | 540 | bidi_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 | ||
| 555 | static int bidi_cache_start_stack[CACHE_STACK_SIZE]; | ||
| 556 | static 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. */ | ||
| 563 | void | ||
| 564 | bidi_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. */ | ||
| 583 | void | ||
| 584 | bidi_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 | ***********************************************************************/ |
| 545 | static void | 609 | static 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 (¶graph_separate_re); | 643 | staticpro (¶graph_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. */ |
| 585 | static INLINE void | 652 | static inline void |
| 586 | bidi_set_paragraph_end (struct bidi_it *bidi_it) | 653 | bidi_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 | ||
| 1019 | static INLINE int | 1087 | static inline int |
| 1020 | bidi_explicit_dir_char (int ch) | 1088 | bidi_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. */ |
| 1518 | static INLINE bidi_type_t | 1586 | static inline bidi_type_t |
| 1519 | bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | 1587 | bidi_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 *); | |||
| 2962 | extern void bidi_move_to_visually_next (struct bidi_it *); | 2962 | extern void bidi_move_to_visually_next (struct bidi_it *); |
| 2963 | extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); | 2963 | extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); |
| 2964 | extern int bidi_mirror_char (int); | 2964 | extern int bidi_mirror_char (int); |
| 2965 | extern void bidi_push_it (struct bidi_it *); | ||
| 2966 | extern void bidi_pop_it (struct bidi_it *); | ||
| 2965 | 2967 | ||
| 2966 | /* Defined in xdisp.c */ | 2968 | /* Defined in xdisp.c */ |
| 2967 | 2969 | ||