This source file includes following definitions.
- bidi_get_type
- bidi_check_type
- bidi_get_category
- bidi_isolate_fmt_char
- bidi_mirror_char
- bidi_paired_bracket_type
- bidi_set_sos_type
- bidi_push_embedding_level
- bidi_pop_embedding_level
- bidi_remember_char
- bidi_copy_it
- bidi_cache_reset_to
- bidi_cache_reset
- bidi_cache_shrink
- bidi_cache_fetch_state
- bidi_cache_search
- bidi_cache_find_level_change
- bidi_cache_ensure_space
- bidi_cache_iterator_state
- bidi_cache_find
- bidi_peek_at_next_level
- bidi_push_it
- bidi_pop_it
- bidi_shelve_cache
- bidi_unshelve_cache
- bidi_initialize
- bidi_set_paragraph_end
- bidi_init_it
- bidi_line_init
- bidi_count_bytes
- bidi_char_at_pos
- bidi_fetch_char
- bidi_fetch_char_skip_isolates
- bidi_at_paragraph_end
- bidi_paragraph_cache_on_off
- bidi_find_paragraph_start
- find_first_strong_char
- bidi_paragraph_init
- bidi_explicit_dir_char
- bidi_resolve_explicit
- bidi_resolve_weak
- bidi_resolve_neutral_1
- bidi_find_bracket_pairs
- bidi_record_type_for_neutral
- bidi_resolve_brackets
- bidi_resolve_neutral
- bidi_type_of_next_char
- bidi_level_of_next_char
- bidi_find_other_level_edge
- bidi_move_to_visually_next
- bidi_find_first_overridden
- bidi_dump_cached_states
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 #include <config.h>
242
243 #include "lisp.h"
244 #include "character.h"
245 #include "buffer.h"
246 #include "dispextern.h"
247 #include "region-cache.h"
248 #include "sysstdio.h"
249
250 static bool bidi_initialized = 0;
251
252 static Lisp_Object bidi_type_table, bidi_mirror_table, bidi_brackets_table;
253
254 #define BIDI_EOB (-1)
255
256
257 typedef enum {
258 UNKNOWN_BC,
259 NEUTRAL,
260 WEAK,
261 STRONG,
262 EXPLICIT_FORMATTING
263 } bidi_category_t;
264
265 static Lisp_Object paragraph_start_re, paragraph_separate_re;
266
267
268
269
270
271
272
273
274 static bidi_type_t
275 bidi_get_type (int ch, bidi_dir_t override)
276 {
277 bidi_type_t default_type;
278
279 if (ch == BIDI_EOB)
280 return NEUTRAL_B;
281 if (ch < 0 || ch > MAX_CHAR)
282 emacs_abort ();
283
284 default_type = (bidi_type_t) XFIXNUM (CHAR_TABLE_REF (bidi_type_table, ch));
285
286
287
288
289 if (default_type == UNKNOWN_BT)
290 emacs_abort ();
291
292 switch (default_type)
293 {
294 case WEAK_BN:
295 case NEUTRAL_B:
296 case LRE:
297 case LRO:
298 case RLE:
299 case RLO:
300 case PDF:
301 case LRI:
302 case RLI:
303 case FSI:
304 case PDI:
305 return default_type;
306 default:
307 if (override == L2R)
308 return STRONG_L;
309 else if (override == R2L)
310 return STRONG_R;
311 else
312 return default_type;
313 }
314 }
315
316 static void
317 bidi_check_type (bidi_type_t type)
318 {
319 eassert (UNKNOWN_BT <= type && type <= NEUTRAL_ON);
320 }
321
322
323 static bidi_category_t
324 bidi_get_category (bidi_type_t type)
325 {
326 switch (type)
327 {
328 case UNKNOWN_BT:
329 return UNKNOWN_BC;
330 case STRONG_L:
331 case STRONG_R:
332 case STRONG_AL:
333 return STRONG;
334 case WEAK_EN:
335 case WEAK_ES:
336 case WEAK_ET:
337 case WEAK_AN:
338 case WEAK_CS:
339 case WEAK_NSM:
340 case WEAK_BN:
341 return WEAK;
342 case NEUTRAL_B:
343 case NEUTRAL_S:
344 case NEUTRAL_WS:
345 case NEUTRAL_ON:
346 return NEUTRAL;
347 case LRE:
348 case LRO:
349 case RLE:
350 case RLO:
351 case PDF:
352 case LRI:
353 case RLI:
354 case FSI:
355 case PDI:
356 return EXPLICIT_FORMATTING;
357 default:
358 emacs_abort ();
359 }
360 }
361
362 static bool
363 bidi_isolate_fmt_char (bidi_type_t ch_type)
364 {
365 return (ch_type == LRI || ch_type == RLI || ch_type == PDI || ch_type == FSI);
366 }
367
368
369
370
371
372 int
373 bidi_mirror_char (int c)
374 {
375 Lisp_Object val;
376
377 if (c == BIDI_EOB)
378 return c;
379 if (c < 0 || c > MAX_CHAR)
380 emacs_abort ();
381
382 val = CHAR_TABLE_REF (bidi_mirror_table, c);
383 if (FIXNUMP (val))
384 {
385 int v;
386
387
388
389 eassert (CHAR_VALID_P (XFIXNUM (val)));
390
391 v = XFIXNUM (val);
392
393
394
395 if (v < 0 || v > MAX_CHAR)
396 emacs_abort ();
397
398 return v;
399 }
400
401 return c;
402 }
403
404
405 static bidi_bracket_type_t
406 bidi_paired_bracket_type (int c)
407 {
408 if (c == BIDI_EOB || bidi_inhibit_bpa)
409 return BIDI_BRACKET_NONE;
410 if (c < 0 || c > MAX_CHAR)
411 emacs_abort ();
412
413 return (bidi_bracket_type_t) XFIXNUM (CHAR_TABLE_REF (bidi_brackets_table, c));
414 }
415
416
417
418
419
420 static void
421 bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after)
422 {
423 int higher_level = (level_before > level_after ? level_before : level_after);
424
425
426 bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R);
427
428 bidi_it->prev.type = UNKNOWN_BT;
429 bidi_it->last_strong.type = bidi_it->last_strong.orig_type = UNKNOWN_BT;
430 bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L);
431 bidi_it->prev_for_neutral.charpos = bidi_it->charpos;
432 bidi_it->next_for_neutral.type
433 = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT;
434 }
435
436 #define ISOLATE_STATUS(BIDI_IT, IDX) ((BIDI_IT)->level_stack[IDX].flags & 1)
437 #define OVERRIDE(BIDI_IT, IDX) (((BIDI_IT)->level_stack[IDX].flags >> 1) & 3)
438
439
440
441 static void
442 bidi_push_embedding_level (struct bidi_it *bidi_it,
443 int level, bidi_dir_t override, bool isolate_status)
444 {
445 struct bidi_stack *st;
446 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
447
448 bidi_it->stack_idx++;
449 eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1);
450 st = &bidi_it->level_stack[bidi_it->stack_idx];
451 eassert (level <= (1 << 7));
452 st->level = level;
453 st->flags = (((override & 3) << 1) | (isolate_status != 0));
454 if (isolate_status)
455 {
456 st->last_strong_type = bidi_it->last_strong.type;
457 st->prev_for_neutral_type = bidi_it->prev_for_neutral.type;
458 st->next_for_neutral_type = bidi_it->next_for_neutral.type;
459 st->next_for_neutral_pos = bidi_it->next_for_neutral.charpos;
460 st->flags |= ((bidi_it->sos == L2R ? 0 : 1) << 3);
461 }
462
463
464 bidi_set_sos_type (bidi_it, prev_level, level);
465 }
466
467
468
469
470 static int
471 bidi_pop_embedding_level (struct bidi_it *bidi_it)
472 {
473 int level;
474
475
476
477 if (bidi_it->stack_idx > 0)
478 {
479 bool isolate_status = ISOLATE_STATUS (bidi_it, bidi_it->stack_idx);
480 int old_level = bidi_it->level_stack[bidi_it->stack_idx].level;
481
482 struct bidi_stack st;
483
484 st = bidi_it->level_stack[bidi_it->stack_idx];
485 if (isolate_status)
486 {
487 bidi_dir_t sos = ((st.flags >> 3) & 1);
488
489
490
491
492
493
494
495 bidi_it->prev.orig_type = bidi_it->prev.type = UNKNOWN_BT;
496 bidi_it->last_strong.type = st.last_strong_type;
497 bidi_it->prev_for_neutral.type = st.prev_for_neutral_type;
498 bidi_it->next_for_neutral.type = st.next_for_neutral_type;
499 bidi_it->next_for_neutral.charpos = st.next_for_neutral_pos;
500 bidi_it->sos = (sos == 0 ? L2R : R2L);
501 }
502 else
503 bidi_set_sos_type (bidi_it, old_level,
504 bidi_it->level_stack[bidi_it->stack_idx - 1].level);
505
506 bidi_it->stack_idx--;
507 }
508 level = bidi_it->level_stack[bidi_it->stack_idx].level;
509 eassert (0 <= level && level <= BIDI_MAXDEPTH + 1);
510 return level;
511 }
512
513
514 static void
515 bidi_remember_char (struct bidi_saved_info *saved_info,
516 struct bidi_it *bidi_it, bool from_type)
517 {
518 saved_info->charpos = bidi_it->charpos;
519 if (from_type)
520 saved_info->type = bidi_it->type;
521 else
522 saved_info->type = bidi_it->type_after_wn;
523 bidi_check_type (saved_info->type);
524 saved_info->orig_type = bidi_it->orig_type;
525 bidi_check_type (saved_info->orig_type);
526 }
527
528
529
530 static void
531 bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
532 {
533
534
535 memcpy (to, from,
536 (offsetof (struct bidi_it, level_stack) + sizeof from->level_stack[0]
537 + from->stack_idx * sizeof from->level_stack[0]));
538 }
539
540
541
542
543
544
545
546
547
548 #define BIDI_CACHE_CHUNK 200
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568 #define BIDI_CACHE_MAX_ELTS_PER_SLOT 50000
569 verify (BIDI_CACHE_CHUNK < BIDI_CACHE_MAX_ELTS_PER_SLOT);
570 static ptrdiff_t bidi_cache_max_elts = BIDI_CACHE_MAX_ELTS_PER_SLOT;
571 static struct bidi_it *bidi_cache;
572 static ptrdiff_t bidi_cache_size = 0;
573 enum { elsz = sizeof (struct bidi_it) };
574 static ptrdiff_t bidi_cache_idx;
575 static ptrdiff_t bidi_cache_last_idx;
576 static ptrdiff_t bidi_cache_start = 0;
577
578
579
580
581
582 static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
583 static int bidi_cache_sp;
584
585
586 enum
587 {
588 bidi_shelve_header_size
589 = (sizeof (bidi_cache_idx) + sizeof (bidi_cache_start_stack)
590 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
591 + sizeof (bidi_cache_last_idx) + sizeof (bidi_cache_max_elts))
592 };
593
594
595
596
597 static void
598 bidi_cache_reset_to (int n)
599 {
600 bidi_cache_idx = bidi_cache_start + n;
601 bidi_cache_last_idx = -1;
602 }
603
604
605
606
607
608
609
610 static void
611 bidi_cache_reset (void)
612 {
613 bidi_cache_reset_to (0);
614 }
615
616
617
618
619
620 static void
621 bidi_cache_shrink (void)
622 {
623 if (bidi_cache_size > BIDI_CACHE_CHUNK)
624 {
625 bidi_cache = xrealloc (bidi_cache, BIDI_CACHE_CHUNK * elsz);
626 bidi_cache_size = BIDI_CACHE_CHUNK;
627 }
628 bidi_cache_reset ();
629 bidi_cache_max_elts = BIDI_CACHE_MAX_ELTS_PER_SLOT;
630 }
631
632 static void
633 bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it)
634 {
635 int current_scan_dir = bidi_it->scan_dir;
636
637 if (idx < bidi_cache_start || idx >= bidi_cache_idx)
638 emacs_abort ();
639
640 bidi_copy_it (bidi_it, &bidi_cache[idx]);
641 bidi_it->scan_dir = current_scan_dir;
642 bidi_cache_last_idx = idx;
643 }
644
645
646
647
648
649
650
651 static ptrdiff_t
652 bidi_cache_search (ptrdiff_t charpos, int level, int dir)
653 {
654 ptrdiff_t i, i_start;
655
656 if (bidi_cache_idx > bidi_cache_start)
657 {
658 if (bidi_cache_last_idx == -1)
659 bidi_cache_last_idx = bidi_cache_idx - 1;
660 if (charpos < bidi_cache[bidi_cache_last_idx].charpos)
661 {
662 dir = -1;
663 i_start = bidi_cache_last_idx - 1;
664 }
665 else if (charpos > (bidi_cache[bidi_cache_last_idx].charpos
666 + bidi_cache[bidi_cache_last_idx].nchars - 1))
667 {
668 dir = 1;
669 i_start = bidi_cache_last_idx + 1;
670 }
671 else if (dir)
672 i_start = bidi_cache_last_idx;
673 else
674 {
675 dir = -1;
676 i_start = bidi_cache_idx - 1;
677 }
678
679 if (dir < 0)
680 {
681
682 for (i = i_start; i >= bidi_cache_start; i--)
683 if (bidi_cache[i].charpos <= charpos
684 && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars
685 && (level == -1 || bidi_cache[i].resolved_level <= level))
686 return i;
687 }
688 else
689 {
690 for (i = i_start; i < bidi_cache_idx; i++)
691 if (bidi_cache[i].charpos <= charpos
692 && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars
693 && (level == -1 || bidi_cache[i].resolved_level <= level))
694 return i;
695 }
696 }
697
698 return -1;
699 }
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716 static ptrdiff_t
717 bidi_cache_find_level_change (int level, int dir, bool before)
718 {
719 if (bidi_cache_idx)
720 {
721 ptrdiff_t i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
722 int incr = before ? 1 : 0;
723
724 if (i < 0)
725 i = 0;
726
727 if (!dir)
728 dir = -1;
729 else if (!incr)
730 i += dir;
731
732 if (dir < 0)
733 {
734 while (i >= bidi_cache_start + incr)
735 {
736 if (bidi_cache[i - incr].resolved_level >= 0
737 && bidi_cache[i - incr].resolved_level < level)
738 return i;
739 i--;
740 }
741 }
742 else
743 {
744 while (i < bidi_cache_idx - incr)
745 {
746 if (bidi_cache[i + incr].resolved_level >= 0
747 && bidi_cache[i + incr].resolved_level < level)
748 return i;
749 i++;
750 }
751 }
752 }
753
754 return -1;
755 }
756
757 static void
758 bidi_cache_ensure_space (ptrdiff_t idx)
759 {
760
761 if (idx >= bidi_cache_size)
762 {
763 ptrdiff_t chunk_size = BIDI_CACHE_CHUNK;
764
765 if (bidi_cache_size > bidi_cache_max_elts - chunk_size)
766 chunk_size = bidi_cache_max_elts - bidi_cache_size;
767
768 if (max (idx + 1,
769 bidi_cache_size + chunk_size) <= bidi_cache_max_elts)
770 {
771
772
773 ptrdiff_t string_or_buffer_bound
774 = max (BUF_BYTES_MAX, STRING_BYTES_BOUND);
775
776
777 ptrdiff_t c_bound
778 = (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz;
779 ptrdiff_t max_elts = bidi_cache_max_elts;
780
781 max_elts = min (max_elts, min (string_or_buffer_bound, c_bound));
782
783
784
785 bidi_cache = xpalloc (bidi_cache, &bidi_cache_size,
786 max (chunk_size, idx - bidi_cache_size + 1),
787 max_elts, elsz);
788 eassert (bidi_cache_size > idx);
789 }
790 }
791 }
792
793 static int
794 bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved,
795 bool update_only)
796 {
797 ptrdiff_t idx;
798
799
800 if (bidi_it->scan_dir == -1)
801 emacs_abort ();
802 idx = bidi_cache_search (bidi_it->charpos, -1, 1);
803
804 if (idx < 0 && update_only)
805 return 0;
806
807 if (idx < 0)
808 {
809 idx = bidi_cache_idx;
810 bidi_cache_ensure_space (idx);
811
812
813
814 if (bidi_cache_start < idx && idx < bidi_cache_size
815 && (bidi_it->charpos > (bidi_cache[idx - 1].charpos
816 + bidi_cache[idx - 1].nchars)
817 || bidi_it->charpos < bidi_cache[bidi_cache_start].charpos))
818 {
819 bidi_cache_reset ();
820 idx = bidi_cache_start;
821 }
822 if (bidi_it->nchars <= 0)
823 emacs_abort ();
824
825 if (bidi_cache_size > idx)
826 {
827 bidi_copy_it (&bidi_cache[idx], bidi_it);
828 if (!resolved)
829 bidi_cache[idx].resolved_level = -1;
830 }
831 }
832 else
833 {
834
835
836 bidi_cache[idx].type = bidi_it->type;
837 bidi_check_type (bidi_it->type);
838 bidi_cache[idx].type_after_wn = bidi_it->type_after_wn;
839 bidi_check_type (bidi_it->type_after_wn);
840 if (resolved)
841 bidi_cache[idx].resolved_level = bidi_it->resolved_level;
842 else
843 bidi_cache[idx].resolved_level = -1;
844 bidi_cache[idx].invalid_levels = bidi_it->invalid_levels;
845 bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral;
846 bidi_cache[idx].next_for_ws = bidi_it->next_for_ws;
847 bidi_cache[idx].disp_pos = bidi_it->disp_pos;
848 bidi_cache[idx].disp_prop = bidi_it->disp_prop;
849 bidi_cache[idx].bracket_pairing_pos = bidi_it->bracket_pairing_pos;
850 bidi_cache[idx].bracket_enclosed_type = bidi_it->bracket_enclosed_type;
851 }
852
853 if (bidi_cache_size > idx)
854 {
855 bidi_cache_last_idx = idx;
856 if (idx >= bidi_cache_idx)
857 bidi_cache_idx = idx + 1;
858 return 1;
859 }
860 else
861 {
862
863 bidi_cache_last_idx = -1;
864 return 0;
865 }
866 }
867
868
869
870
871
872
873
874 static bidi_type_t
875 bidi_cache_find (ptrdiff_t charpos, bool resolved_only, struct bidi_it *bidi_it)
876 {
877 ptrdiff_t i = bidi_cache_search (charpos, -1, bidi_it->scan_dir);
878
879 if (i >= bidi_cache_start
880 && (!resolved_only
881
882
883
884
885 || bidi_cache[i].resolved_level >= 0))
886 {
887 bidi_dir_t current_scan_dir = bidi_it->scan_dir;
888
889 bidi_copy_it (bidi_it, &bidi_cache[i]);
890 bidi_cache_last_idx = i;
891
892
893 bidi_it->scan_dir = current_scan_dir;
894 return bidi_it->type;
895 }
896
897 return UNKNOWN_BT;
898 }
899
900 static int
901 bidi_peek_at_next_level (struct bidi_it *bidi_it)
902 {
903 if (bidi_cache_idx == bidi_cache_start)
904 emacs_abort ();
905
906
907 if (bidi_cache_last_idx == -1
908 || (bidi_cache_last_idx >= bidi_cache_idx - 1 && bidi_it->scan_dir > 0))
909 return bidi_cache[bidi_cache_idx - 1].resolved_level;
910 return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level;
911 }
912
913
914
915
916
917
918
919
920
921
922
923 void
924 bidi_push_it (struct bidi_it *bidi_it)
925 {
926
927 bidi_cache_max_elts += BIDI_CACHE_MAX_ELTS_PER_SLOT;
928
929
930 bidi_cache_ensure_space (bidi_cache_idx);
931 bidi_cache[bidi_cache_idx++] = *bidi_it;
932
933
934 eassert (bidi_cache_sp < IT_STACK_SIZE);
935 bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start;
936
937
938 bidi_cache_start = bidi_cache_idx;
939 bidi_cache_last_idx = -1;
940 }
941
942
943
944 void
945 bidi_pop_it (struct bidi_it *bidi_it)
946 {
947 if (bidi_cache_start <= 0)
948 emacs_abort ();
949
950
951
952 bidi_cache_idx = bidi_cache_start - 1;
953
954
955 *bidi_it = bidi_cache[bidi_cache_idx];
956
957
958 if (bidi_cache_sp <= 0)
959 emacs_abort ();
960 bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp];
961
962
963 bidi_cache_last_idx = -1;
964
965 bidi_cache_max_elts -= BIDI_CACHE_MAX_ELTS_PER_SLOT;
966 eassert (bidi_cache_max_elts > 0);
967 }
968
969 static ptrdiff_t bidi_cache_total_alloc;
970
971
972 void *
973 bidi_shelve_cache (void)
974 {
975 unsigned char *databuf;
976 ptrdiff_t alloc;
977
978
979 if (bidi_cache_idx == 0)
980 return NULL;
981
982 alloc = (bidi_shelve_header_size
983 + bidi_cache_idx * sizeof (struct bidi_it));
984 databuf = xmalloc (alloc);
985 bidi_cache_total_alloc += alloc;
986
987 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx));
988 memcpy (databuf + sizeof (bidi_cache_idx),
989 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it));
990 memcpy (databuf + sizeof (bidi_cache_idx)
991 + bidi_cache_idx * sizeof (struct bidi_it),
992 bidi_cache_start_stack, sizeof (bidi_cache_start_stack));
993 memcpy (databuf + sizeof (bidi_cache_idx)
994 + bidi_cache_idx * sizeof (struct bidi_it)
995 + sizeof (bidi_cache_start_stack),
996 &bidi_cache_sp, sizeof (bidi_cache_sp));
997 memcpy (databuf + sizeof (bidi_cache_idx)
998 + bidi_cache_idx * sizeof (struct bidi_it)
999 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
1000 &bidi_cache_start, sizeof (bidi_cache_start));
1001 memcpy (databuf + sizeof (bidi_cache_idx)
1002 + bidi_cache_idx * sizeof (struct bidi_it)
1003 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
1004 + sizeof (bidi_cache_start),
1005 &bidi_cache_last_idx, sizeof (bidi_cache_last_idx));
1006 memcpy (databuf + sizeof (bidi_cache_idx)
1007 + bidi_cache_idx * sizeof (struct bidi_it)
1008 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
1009 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx),
1010 &bidi_cache_max_elts, sizeof (bidi_cache_max_elts));
1011
1012 return databuf;
1013 }
1014
1015
1016
1017
1018
1019
1020 void
1021 bidi_unshelve_cache (void *databuf, bool just_free)
1022 {
1023 unsigned char *p = databuf;
1024
1025 if (!p)
1026 {
1027 if (!just_free)
1028 {
1029
1030 bidi_cache_start = 0;
1031 bidi_cache_sp = 0;
1032 bidi_cache_max_elts = BIDI_CACHE_MAX_ELTS_PER_SLOT;
1033 bidi_cache_reset ();
1034 }
1035 }
1036 else
1037 {
1038 if (just_free)
1039 {
1040 ptrdiff_t idx;
1041
1042 memcpy (&idx, p, sizeof (bidi_cache_idx));
1043 bidi_cache_total_alloc
1044 -= bidi_shelve_header_size + idx * sizeof (struct bidi_it);
1045 }
1046 else
1047 {
1048 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
1049 bidi_cache_ensure_space (bidi_cache_idx);
1050 memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
1051 bidi_cache_idx * sizeof (struct bidi_it));
1052 memcpy (bidi_cache_start_stack,
1053 p + sizeof (bidi_cache_idx)
1054 + bidi_cache_idx * sizeof (struct bidi_it),
1055 sizeof (bidi_cache_start_stack));
1056 memcpy (&bidi_cache_sp,
1057 p + sizeof (bidi_cache_idx)
1058 + bidi_cache_idx * sizeof (struct bidi_it)
1059 + sizeof (bidi_cache_start_stack),
1060 sizeof (bidi_cache_sp));
1061 memcpy (&bidi_cache_start,
1062 p + sizeof (bidi_cache_idx)
1063 + bidi_cache_idx * sizeof (struct bidi_it)
1064 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
1065 sizeof (bidi_cache_start));
1066 memcpy (&bidi_cache_last_idx,
1067 p + sizeof (bidi_cache_idx)
1068 + bidi_cache_idx * sizeof (struct bidi_it)
1069 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
1070 + sizeof (bidi_cache_start),
1071 sizeof (bidi_cache_last_idx));
1072 memcpy (&bidi_cache_max_elts,
1073 p + sizeof (bidi_cache_idx)
1074 + bidi_cache_idx * sizeof (struct bidi_it)
1075 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
1076 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx),
1077 sizeof (bidi_cache_max_elts));
1078 bidi_cache_total_alloc
1079 -= (bidi_shelve_header_size
1080 + bidi_cache_idx * sizeof (struct bidi_it));
1081 }
1082
1083 xfree (p);
1084 }
1085 }
1086
1087
1088
1089
1090
1091 static void
1092 bidi_initialize (void)
1093 {
1094 bidi_type_table = uniprop_table (intern ("bidi-class"));
1095 if (NILP (bidi_type_table))
1096 emacs_abort ();
1097 staticpro (&bidi_type_table);
1098
1099 bidi_mirror_table = uniprop_table (intern ("mirroring"));
1100 if (NILP (bidi_mirror_table))
1101 emacs_abort ();
1102 staticpro (&bidi_mirror_table);
1103
1104 bidi_brackets_table = uniprop_table (intern ("bracket-type"));
1105 if (NILP (bidi_brackets_table))
1106 emacs_abort ();
1107 staticpro (&bidi_brackets_table);
1108
1109 paragraph_start_re = build_string ("^\\(\f\\|[ \t]*\\)$");
1110 staticpro (¶graph_start_re);
1111 paragraph_separate_re = build_string ("^[ \t\f]*$");
1112 staticpro (¶graph_separate_re);
1113
1114 bidi_cache_sp = 0;
1115 bidi_cache_total_alloc = 0;
1116 bidi_cache_max_elts = BIDI_CACHE_MAX_ELTS_PER_SLOT;
1117
1118 bidi_initialized = 1;
1119 }
1120
1121
1122
1123 static void
1124 bidi_set_paragraph_end (struct bidi_it *bidi_it)
1125 {
1126 bidi_it->invalid_levels = 0;
1127 bidi_it->invalid_isolates = 0;
1128 bidi_it->stack_idx = 0;
1129 bidi_it->isolate_level = 0;
1130 bidi_it->resolved_level = bidi_it->level_stack[0].level;
1131 }
1132
1133
1134 void
1135 bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p,
1136 struct bidi_it *bidi_it)
1137 {
1138 if (! bidi_initialized)
1139 bidi_initialize ();
1140 if (charpos >= 0)
1141 bidi_it->charpos = charpos;
1142 if (bytepos >= 0)
1143 bidi_it->bytepos = bytepos;
1144 bidi_it->frame_window_p = frame_window_p;
1145 bidi_it->nchars = -1;
1146 bidi_it->first_elt = 1;
1147 bidi_set_paragraph_end (bidi_it);
1148 bidi_it->new_paragraph = 1;
1149 bidi_it->separator_limit = -1;
1150 bidi_it->type = NEUTRAL_B;
1151 bidi_it->type_after_wn = NEUTRAL_B;
1152 bidi_it->orig_type = NEUTRAL_B;
1153
1154 bidi_it->prev.type = bidi_it->prev.orig_type = UNKNOWN_BT;
1155 bidi_it->last_strong.type = bidi_it->last_strong.orig_type = UNKNOWN_BT;
1156 bidi_it->next_for_neutral.charpos = -1;
1157 bidi_it->next_for_neutral.type
1158 = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT;
1159 bidi_it->prev_for_neutral.charpos = -1;
1160 bidi_it->prev_for_neutral.type
1161 = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
1162 bidi_it->bracket_pairing_pos = -1;
1163 bidi_it->sos = L2R;
1164 bidi_it->disp_pos = -1;
1165 bidi_it->disp_prop = 0;
1166
1167
1168 if (bidi_cache_start == 0)
1169 bidi_cache_shrink ();
1170 else
1171 bidi_cache_reset ();
1172 }
1173
1174
1175 static void
1176 bidi_line_init (struct bidi_it *bidi_it)
1177 {
1178 bidi_it->scan_dir = 1;
1179 bidi_it->stack_idx = 0;
1180 bidi_it->resolved_level = bidi_it->level_stack[0].level;
1181 bidi_it->level_stack[0].flags = 0;
1182 bidi_it->invalid_levels = 0;
1183 bidi_it->isolate_level = 0;
1184 bidi_it->invalid_isolates = 0;
1185
1186
1187 bidi_it->next_en_pos = 0;
1188 bidi_it->next_en_type = UNKNOWN_BT;
1189 bidi_it->next_for_ws.charpos = -1;
1190 bidi_it->next_for_ws.type = UNKNOWN_BT;
1191 bidi_it->bracket_pairing_pos = -1;
1192 bidi_set_sos_type (bidi_it,
1193 (bidi_it->paragraph_dir == R2L ? 1 : 0),
1194 bidi_it->level_stack[0].level);
1195
1196 bidi_cache_reset ();
1197 }
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207 static ptrdiff_t
1208 bidi_count_bytes (const unsigned char *s, ptrdiff_t beg,
1209 ptrdiff_t begbyte, ptrdiff_t end, bool unibyte)
1210 {
1211 ptrdiff_t pos = beg;
1212 const unsigned char *p = s + begbyte, *start = p;
1213
1214 if (unibyte)
1215 p = s + end;
1216 else
1217 {
1218 if (!CHAR_HEAD_P (*p))
1219 emacs_abort ();
1220
1221 while (pos < end)
1222 {
1223 p += BYTES_BY_CHAR_HEAD (*p);
1224 pos++;
1225 }
1226 }
1227
1228 return p - start;
1229 }
1230
1231
1232
1233
1234
1235 static int
1236 bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte)
1237 {
1238 if (s)
1239 {
1240 s += bytepos;
1241 if (unibyte)
1242 return *s;
1243 }
1244 else
1245 s = BYTE_POS_ADDR (bytepos);
1246 return STRING_CHAR (s);
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263 static int
1264 bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
1265 int *disp_prop, struct bidi_string_data *string,
1266 struct window *w,
1267 bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars)
1268 {
1269 int ch;
1270 ptrdiff_t endpos
1271 = (string->s || STRINGP (string->lstring)) ? string->schars : ZV;
1272 struct text_pos pos;
1273
1274
1275
1276 if (charpos < endpos && charpos > *disp_pos)
1277 {
1278 SET_TEXT_POS (pos, charpos, bytepos);
1279 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
1280 disp_prop);
1281
1282
1283
1284
1285 if (max_redisplay_ticks > 0 && *disp_pos > charpos)
1286 update_redisplay_ticks ((*disp_pos - charpos) / 100 + 1, w);
1287 }
1288
1289
1290 if (charpos >= endpos)
1291 {
1292 ch = BIDI_EOB;
1293 *ch_len = 1;
1294 *nchars = 1;
1295 *disp_pos = endpos;
1296 *disp_prop = 0;
1297 }
1298 else if (charpos >= *disp_pos && *disp_prop)
1299 {
1300 ptrdiff_t disp_end_pos;
1301
1302
1303
1304 if (charpos > *disp_pos)
1305 emacs_abort ();
1306
1307
1308
1309
1310 if (*disp_prop == 2)
1311 {
1312
1313
1314
1315 ch = PARAGRAPH_SEPARATOR;
1316 }
1317 else
1318 {
1319
1320
1321 ch = OBJECT_REPLACEMENT_CHARACTER;
1322 }
1323 disp_end_pos = compute_display_string_end (*disp_pos, string);
1324 if (disp_end_pos < 0)
1325 {
1326
1327
1328
1329
1330 *disp_prop = 0;
1331 goto normal_char;
1332 }
1333 *nchars = disp_end_pos - *disp_pos;
1334 if (*nchars <= 0)
1335 emacs_abort ();
1336 if (string->s)
1337 *ch_len = bidi_count_bytes (string->s, *disp_pos, bytepos,
1338 disp_end_pos, string->unibyte);
1339 else if (STRINGP (string->lstring))
1340 *ch_len = bidi_count_bytes (SDATA (string->lstring), *disp_pos,
1341 bytepos, disp_end_pos, string->unibyte);
1342 else
1343 *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos;
1344 }
1345 else
1346 {
1347 normal_char:
1348 if (string->s)
1349 {
1350 if (!string->unibyte)
1351 {
1352 int len;
1353 ch = string_char_and_length (string->s + bytepos, &len);
1354 *ch_len = len;
1355 }
1356 else
1357 {
1358 ch = UNIBYTE_TO_CHAR (string->s[bytepos]);
1359 *ch_len = 1;
1360 }
1361 }
1362 else if (STRINGP (string->lstring))
1363 {
1364 if (!string->unibyte)
1365 {
1366 int len;
1367 ch = string_char_and_length (SDATA (string->lstring) + bytepos,
1368 &len);
1369 *ch_len = len;
1370 }
1371 else
1372 {
1373 ch = UNIBYTE_TO_CHAR (SREF (string->lstring, bytepos));
1374 *ch_len = 1;
1375 }
1376 }
1377 else
1378 {
1379 int len;
1380 ch = string_char_and_length (BYTE_POS_ADDR (bytepos), &len);
1381 *ch_len = len;
1382 }
1383
1384 *nchars = 1;
1385 }
1386
1387
1388
1389 if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos
1390 && *disp_prop)
1391 {
1392 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
1393 *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
1394 disp_prop);
1395 if (max_redisplay_ticks > 0 && *disp_pos > charpos + *nchars)
1396 update_redisplay_ticks ((*disp_pos - charpos - *nchars) / 100 + 1, w);
1397 }
1398
1399 return ch;
1400 }
1401
1402
1403
1404
1405
1406
1407 static int
1408 bidi_fetch_char_skip_isolates (ptrdiff_t charpos, ptrdiff_t bytepos,
1409 ptrdiff_t *disp_pos, int *disp_prop,
1410 struct bidi_string_data *string,
1411 struct window *w, bool frame_window_p,
1412 ptrdiff_t *ch_len, ptrdiff_t *nchars)
1413 {
1414 ptrdiff_t orig_charpos = charpos, orig_bytepos = bytepos;
1415 int ch = bidi_fetch_char (charpos, bytepos, disp_pos, disp_prop, string, w,
1416 frame_window_p, ch_len, nchars);
1417 bidi_type_t ch_type = bidi_get_type (ch, NEUTRAL_DIR);
1418 ptrdiff_t level = 0;
1419
1420 if (ch_type == LRI || ch_type == RLI || ch_type == FSI)
1421 {
1422 level++;
1423 while (level > 0 && ch_type != NEUTRAL_B)
1424 {
1425 charpos += *nchars;
1426 bytepos += *ch_len;
1427 ch = bidi_fetch_char (charpos, bytepos, disp_pos, disp_prop, string,
1428 w, frame_window_p, ch_len, nchars);
1429 ch_type = bidi_get_type (ch, NEUTRAL_DIR);
1430
1431 if (ch_type == LRI || ch_type == RLI || ch_type == FSI)
1432 level++;
1433 else if (ch_type == PDI)
1434 level--;
1435 }
1436 }
1437
1438
1439
1440 *nchars += charpos - orig_charpos;
1441 *ch_len += bytepos - orig_bytepos;
1442 return ch;
1443 }
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456 static ptrdiff_t
1457 bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos)
1458 {
1459 Lisp_Object sep_re;
1460 Lisp_Object start_re;
1461 ptrdiff_t val;
1462
1463 if (STRINGP (BVAR (current_buffer, bidi_paragraph_separate_re)))
1464 sep_re = BVAR (current_buffer, bidi_paragraph_separate_re);
1465 else
1466 sep_re = paragraph_separate_re;
1467 if (STRINGP (BVAR (current_buffer, bidi_paragraph_start_re)))
1468 start_re = BVAR (current_buffer, bidi_paragraph_start_re);
1469 else
1470 start_re = paragraph_start_re;
1471
1472
1473
1474 specpdl_ref count = SPECPDL_INDEX ();
1475 specbind (Qinhibit_quit, Qt);
1476
1477 val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
1478 if (val < 0)
1479 {
1480 if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0)
1481 val = -1;
1482 else
1483 val = -2;
1484 }
1485
1486 unbind_to (count, Qnil);
1487 return val;
1488 }
1489
1490
1491
1492
1493 static struct region_cache *
1494 bidi_paragraph_cache_on_off (void)
1495 {
1496 struct buffer *cache_buffer = current_buffer;
1497 bool indirect_p = false;
1498
1499
1500
1501 if (cache_buffer->base_buffer)
1502 {
1503 cache_buffer = cache_buffer->base_buffer;
1504 indirect_p = true;
1505 }
1506
1507
1508
1509
1510
1511
1512 if (NILP (BVAR (current_buffer, cache_long_scans)))
1513 {
1514 if (!indirect_p
1515 || NILP (BVAR (cache_buffer, cache_long_scans)))
1516 {
1517 if (cache_buffer->bidi_paragraph_cache)
1518 {
1519 free_region_cache (cache_buffer->bidi_paragraph_cache);
1520 cache_buffer->bidi_paragraph_cache = 0;
1521 }
1522 }
1523 return NULL;
1524 }
1525 else
1526 {
1527 if (!indirect_p
1528 || !NILP (BVAR (cache_buffer, cache_long_scans)))
1529 {
1530 if (!cache_buffer->bidi_paragraph_cache)
1531 cache_buffer->bidi_paragraph_cache = new_region_cache ();
1532 }
1533 return cache_buffer->bidi_paragraph_cache;
1534 }
1535 }
1536
1537
1538
1539
1540
1541 #define MAX_PARAGRAPH_SEARCH 7500
1542
1543
1544
1545
1546
1547 static ptrdiff_t
1548 bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1549 {
1550 Lisp_Object re =
1551 STRINGP (BVAR (current_buffer, bidi_paragraph_start_re))
1552 ? BVAR (current_buffer, bidi_paragraph_start_re)
1553 : paragraph_start_re;
1554 ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
1555 struct region_cache *bpc = bidi_paragraph_cache_on_off ();
1556 ptrdiff_t n = 0, oldpos = pos, next;
1557 struct buffer *cache_buffer = current_buffer;
1558
1559 if (cache_buffer->base_buffer)
1560 cache_buffer = cache_buffer->base_buffer;
1561
1562
1563
1564 specpdl_ref count = SPECPDL_INDEX ();
1565 specbind (Qinhibit_quit, Qt);
1566
1567 while (pos_byte > BEGV_BYTE
1568 && n++ < MAX_PARAGRAPH_SEARCH
1569 && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0)
1570 {
1571
1572
1573
1574
1575 dec_both (&pos, &pos_byte);
1576 if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next))
1577 {
1578 pos = next, pos_byte = CHAR_TO_BYTE (pos);
1579 break;
1580 }
1581 else
1582 pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
1583 }
1584 unbind_to (count, Qnil);
1585 if (n >= MAX_PARAGRAPH_SEARCH)
1586 pos = BEGV, pos_byte = BEGV_BYTE;
1587 if (bpc)
1588 know_region_cache (cache_buffer, bpc, pos, oldpos);
1589
1590
1591 pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);
1592 return pos_byte;
1593 }
1594
1595
1596 static ptrdiff_t nsearch_for_strong;
1597
1598
1599
1600
1601
1602 #define MAX_STRONG_CHAR_SEARCH 100000
1603
1604
1605
1606
1607
1608
1609
1610
1611 static bidi_type_t
1612 find_first_strong_char (ptrdiff_t pos, ptrdiff_t bytepos, ptrdiff_t end,
1613 ptrdiff_t *disp_pos, int *disp_prop,
1614 struct bidi_string_data *string, struct window *w,
1615 bool string_p, bool frame_window_p,
1616 ptrdiff_t *ch_len, ptrdiff_t *nchars, bool stop_at_pdi)
1617 {
1618 ptrdiff_t pos1;
1619 bidi_type_t type;
1620 int ch;
1621
1622 if (stop_at_pdi)
1623 {
1624
1625
1626 #ifdef ENABLE_CHECKING
1627 ch = bidi_fetch_char (pos, bytepos, disp_pos, disp_prop, string, w,
1628 frame_window_p, ch_len, nchars);
1629 type = bidi_get_type (ch, NEUTRAL_DIR);
1630 eassert (type == FSI );
1631 #endif
1632 pos += *nchars;
1633 bytepos += *ch_len;
1634 }
1635 ch = bidi_fetch_char_skip_isolates (pos, bytepos, disp_pos, disp_prop, string,
1636 w, frame_window_p, ch_len, nchars);
1637 type = bidi_get_type (ch, NEUTRAL_DIR);
1638
1639 pos1 = pos;
1640 for (pos += *nchars, bytepos += *ch_len;
1641 bidi_get_category (type) != STRONG
1642
1643 && !(stop_at_pdi && type == PDI)
1644
1645
1646 && pos - pos1 < MAX_STRONG_CHAR_SEARCH;
1647 type = bidi_get_type (ch, NEUTRAL_DIR))
1648 {
1649 if (pos >= end)
1650 {
1651
1652
1653 type = NEUTRAL_B;
1654 break;
1655 }
1656 if (!string_p
1657 && type == NEUTRAL_B
1658 && bidi_at_paragraph_end (pos, bytepos) >= -1)
1659 break;
1660
1661 ch = bidi_fetch_char_skip_isolates (pos, bytepos, disp_pos, disp_prop,
1662 string, w, frame_window_p,
1663 ch_len, nchars);
1664 pos += *nchars;
1665 bytepos += *ch_len;
1666 }
1667
1668 nsearch_for_strong += pos - pos1;
1669 return type;
1670 }
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687 void
1688 bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
1689 {
1690 ptrdiff_t bytepos = bidi_it->bytepos;
1691 bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring);
1692 ptrdiff_t pstartbyte;
1693
1694
1695
1696 ptrdiff_t begbyte = string_p ? 0 : BEGV_BYTE;
1697 ptrdiff_t end = string_p ? bidi_it->string.schars : ZV;
1698 ptrdiff_t pos = bidi_it->charpos;
1699
1700 nsearch_for_strong = 0;
1701
1702
1703 if (bytepos == begbyte && bidi_it->charpos == end)
1704 dir = L2R;
1705
1706 else if (bidi_it->charpos >= end || bytepos < begbyte)
1707 emacs_abort ();
1708
1709 if (dir == L2R)
1710 {
1711 bidi_it->paragraph_dir = L2R;
1712 bidi_it->new_paragraph = 0;
1713 }
1714 else if (dir == R2L)
1715 {
1716 bidi_it->paragraph_dir = R2L;
1717 bidi_it->new_paragraph = 0;
1718 }
1719 else if (dir == NEUTRAL_DIR)
1720 {
1721 ptrdiff_t ch_len, nchars;
1722 ptrdiff_t disp_pos = -1;
1723 int disp_prop = 0;
1724 bidi_type_t type;
1725 const unsigned char *s;
1726
1727 if (!bidi_initialized)
1728 bidi_initialize ();
1729
1730
1731
1732
1733
1734 if (!bidi_it->first_elt
1735 && bidi_it->charpos < bidi_it->separator_limit)
1736 return;
1737
1738
1739
1740
1741
1742 pos = bidi_it->charpos;
1743 s = (STRINGP (bidi_it->string.lstring)
1744 ? SDATA (bidi_it->string.lstring)
1745 : bidi_it->string.s);
1746 if (bytepos > begbyte
1747 && bidi_char_at_pos (bytepos, s, bidi_it->string.unibyte) == '\n')
1748 {
1749 bytepos++;
1750 pos++;
1751 }
1752
1753
1754
1755 if (string_p)
1756 {
1757
1758
1759 pstartbyte = 0;
1760 }
1761 else
1762 pstartbyte = bidi_find_paragraph_start (pos, bytepos);
1763 bidi_it->separator_limit = -1;
1764 bidi_it->new_paragraph = 0;
1765
1766
1767
1768 do {
1769 bytepos = pstartbyte;
1770 if (!string_p)
1771 pos = BYTE_TO_CHAR (bytepos);
1772 type = find_first_strong_char (pos, bytepos, end, &disp_pos, &disp_prop,
1773 &bidi_it->string, bidi_it->w,
1774 string_p, bidi_it->frame_window_p,
1775 &ch_len, &nchars, false);
1776 if (type == STRONG_R || type == STRONG_AL)
1777 bidi_it->paragraph_dir = R2L;
1778 else if (type == STRONG_L)
1779 bidi_it->paragraph_dir = L2R;
1780 if (!string_p
1781 && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR)
1782 {
1783
1784 if (pstartbyte == BEGV_BYTE)
1785 bidi_it->paragraph_dir = L2R;
1786 else
1787 {
1788 ptrdiff_t prevpbyte = pstartbyte;
1789 ptrdiff_t p = BYTE_TO_CHAR (pstartbyte), pbyte = pstartbyte;
1790
1791
1792 while (pbyte > BEGV_BYTE && prevpbyte >= pstartbyte)
1793 {
1794
1795
1796
1797 dec_both (&p, &pbyte);
1798 prevpbyte = bidi_find_paragraph_start (p, pbyte);
1799 }
1800 pstartbyte = prevpbyte;
1801 }
1802 }
1803 } while (!string_p
1804 && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR);
1805 }
1806 else
1807 emacs_abort ();
1808
1809
1810
1811
1812 if (bidi_it->paragraph_dir != L2R && bidi_it->paragraph_dir != R2L)
1813 bidi_it->paragraph_dir = L2R;
1814 if (bidi_it->paragraph_dir == R2L)
1815 bidi_it->level_stack[0].level = 1;
1816 else
1817 bidi_it->level_stack[0].level = 0;
1818
1819 bidi_line_init (bidi_it);
1820
1821
1822
1823
1824
1825 ptrdiff_t nexamined = bidi_it->charpos - pos + nsearch_for_strong;
1826 if (max_redisplay_ticks > 0 && nexamined > 0)
1827 update_redisplay_ticks (nexamined / 50, bidi_it->w);
1828 }
1829
1830
1831
1832
1833
1834
1835
1836 static bool
1837 bidi_explicit_dir_char (int ch)
1838 {
1839 bidi_type_t ch_type;
1840
1841 if (!bidi_initialized)
1842 emacs_abort ();
1843 if (ch < 0)
1844 {
1845 eassert (ch == BIDI_EOB);
1846 return false;
1847 }
1848 ch_type = (bidi_type_t) XFIXNUM (CHAR_TABLE_REF (bidi_type_table, ch));
1849 return (ch_type == LRE || ch_type == LRO
1850 || ch_type == RLE || ch_type == RLO
1851 || ch_type == PDF);
1852 }
1853
1854
1855
1856
1857
1858
1859 static int
1860 bidi_resolve_explicit (struct bidi_it *bidi_it)
1861 {
1862 int curchar;
1863 bidi_type_t type, typ1, prev_type = UNKNOWN_BT;
1864 int current_level;
1865 int new_level;
1866 bidi_dir_t override;
1867 bool isolate_status;
1868 bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring);
1869 ptrdiff_t ch_len, nchars, disp_pos, end;
1870 int disp_prop;
1871 ptrdiff_t eob
1872 = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring))
1873 ? bidi_it->string.schars : ZV);
1874
1875
1876 if (bidi_it->type_after_wn != WEAK_BN
1877 && bidi_it->type != WEAK_BN)
1878 {
1879
1880
1881
1882 if (bidi_it->type_after_wn == NEUTRAL_ON
1883 && bidi_get_category (bidi_it->type) == STRONG
1884 && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE)
1885 bidi_remember_char (&bidi_it->prev, bidi_it, 1);
1886 else
1887 bidi_remember_char (&bidi_it->prev, bidi_it, 0);
1888 }
1889 if (bidi_it->type_after_wn == STRONG_R
1890 || bidi_it->type_after_wn == STRONG_L
1891 || bidi_it->type_after_wn == STRONG_AL)
1892 bidi_remember_char (&bidi_it->last_strong, bidi_it, 0);
1893 if (bidi_it->type == STRONG_R || bidi_it->type == STRONG_L
1894 || bidi_it->type == WEAK_EN || bidi_it->type == WEAK_AN)
1895 bidi_remember_char (&bidi_it->prev_for_neutral, bidi_it, 1);
1896
1897
1898
1899 if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos)
1900 {
1901 bidi_it->next_for_neutral.type = UNKNOWN_BT;
1902
1903
1904
1905 if (bidi_it->bracket_pairing_pos == eob)
1906 bidi_it->bracket_pairing_pos = -1;
1907 }
1908 if (bidi_it->next_en_pos >= 0
1909 && bidi_it->charpos >= bidi_it->next_en_pos)
1910 {
1911 bidi_it->next_en_pos = 0;
1912 bidi_it->next_en_type = UNKNOWN_BT;
1913 }
1914
1915
1916
1917
1918 if (bidi_it->bracket_pairing_pos != eob)
1919 {
1920 bidi_it->bracket_pairing_pos = -1;
1921 bidi_it->bracket_enclosed_type = UNKNOWN_BT;
1922 }
1923
1924
1925
1926
1927 if (bidi_it->bytepos < (string_p ? 0 : BEGV_BYTE)
1928 || bidi_it->first_elt)
1929 {
1930 bidi_it->first_elt = 0;
1931 if (string_p)
1932 {
1933 const unsigned char *p
1934 = (STRINGP (bidi_it->string.lstring)
1935 ? SDATA (bidi_it->string.lstring)
1936 : bidi_it->string.s);
1937
1938 if (bidi_it->charpos < 0)
1939 bidi_it->charpos = bidi_it->bytepos = 0;
1940 eassert (bidi_it->bytepos == bidi_count_bytes (p, 0, 0,
1941 bidi_it->charpos,
1942 bidi_it->string.unibyte));
1943 }
1944 else
1945 {
1946 if (bidi_it->charpos < BEGV)
1947 {
1948 bidi_it->charpos = BEGV;
1949 bidi_it->bytepos = BEGV_BYTE;
1950 }
1951 eassert (bidi_it->bytepos == CHAR_TO_BYTE (bidi_it->charpos));
1952 }
1953
1954
1955
1956
1957
1958
1959 if (bidi_it->first_elt && bidi_it->prev.type != UNKNOWN_BT)
1960 {
1961 eassert (bidi_it->prev.charpos == bidi_it->charpos - 1);
1962 prev_type = bidi_it->prev.orig_type;
1963 }
1964 }
1965
1966 else if (bidi_it->charpos < (string_p ? bidi_it->string.schars : ZV))
1967 {
1968
1969
1970 if (bidi_it->nchars <= 0)
1971 emacs_abort ();
1972 bidi_it->charpos += bidi_it->nchars;
1973 if (bidi_it->ch_len == 0)
1974 emacs_abort ();
1975 bidi_it->bytepos += bidi_it->ch_len;
1976 prev_type = bidi_it->orig_type;
1977 }
1978 else
1979 prev_type = NEUTRAL_B;
1980
1981 current_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1982 isolate_status = ISOLATE_STATUS (bidi_it, bidi_it->stack_idx);
1983 override = OVERRIDE (bidi_it, bidi_it->stack_idx);
1984 new_level = current_level;
1985
1986 if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV))
1987 {
1988 curchar = BIDI_EOB;
1989 bidi_it->ch_len = 1;
1990 bidi_it->nchars = 1;
1991 bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV);
1992 bidi_it->disp_prop = 0;
1993 }
1994 else
1995 {
1996
1997
1998
1999
2000 switch (prev_type)
2001 {
2002 case RLI:
2003 if (current_level < BIDI_MAXDEPTH
2004 && bidi_it->invalid_levels == 0
2005 && bidi_it->invalid_isolates == 0)
2006 {
2007 new_level = ((current_level + 1) & ~1) + 1;
2008 bidi_it->isolate_level++;
2009 bidi_push_embedding_level (bidi_it, new_level,
2010 NEUTRAL_DIR, true);
2011 }
2012 else
2013 bidi_it->invalid_isolates++;
2014 break;
2015 case LRI:
2016 if (current_level < BIDI_MAXDEPTH - 1
2017 && bidi_it->invalid_levels == 0
2018 && bidi_it->invalid_isolates == 0)
2019 {
2020 new_level = ((current_level + 2) & ~1);
2021 bidi_it->isolate_level++;
2022 bidi_push_embedding_level (bidi_it, new_level,
2023 NEUTRAL_DIR, true);
2024 }
2025 else
2026 bidi_it->invalid_isolates++;
2027 break;
2028 case PDF:
2029 if (!bidi_it->invalid_isolates)
2030 {
2031 if (bidi_it->invalid_levels)
2032 bidi_it->invalid_levels--;
2033 else if (!isolate_status && bidi_it->stack_idx >= 1)
2034 new_level = bidi_pop_embedding_level (bidi_it);
2035 }
2036 break;
2037 default:
2038 eassert (prev_type != FSI);
2039
2040 break;
2041 }
2042
2043
2044
2045 curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos,
2046 &bidi_it->disp_pos, &bidi_it->disp_prop,
2047 &bidi_it->string, bidi_it->w,
2048 bidi_it->frame_window_p,
2049 &bidi_it->ch_len, &bidi_it->nchars);
2050 }
2051 bidi_it->ch = curchar;
2052 bidi_it->resolved_level = new_level;
2053
2054
2055
2056
2057
2058 type = bidi_get_type (curchar, NEUTRAL_DIR);
2059 bidi_it->orig_type = type;
2060 bidi_check_type (bidi_it->orig_type);
2061
2062 bidi_it->type_after_wn = UNKNOWN_BT;
2063
2064 switch (type)
2065 {
2066 case RLE:
2067 case RLO:
2068 bidi_it->type_after_wn = type;
2069 bidi_check_type (bidi_it->type_after_wn);
2070 type = WEAK_BN;
2071 if (new_level < BIDI_MAXDEPTH
2072 && bidi_it->invalid_levels == 0
2073 && bidi_it->invalid_isolates == 0)
2074 {
2075
2076
2077 new_level = ((new_level + 1) & ~1) + 1;
2078 if (bidi_it->type_after_wn == RLE)
2079 override = NEUTRAL_DIR;
2080 else
2081 override = R2L;
2082 bidi_push_embedding_level (bidi_it, new_level, override, false);
2083 bidi_it->resolved_level = new_level;
2084 }
2085 else
2086 {
2087 if (bidi_it->invalid_isolates == 0)
2088 bidi_it->invalid_levels++;
2089 }
2090 break;
2091 case LRE:
2092 case LRO:
2093 bidi_it->type_after_wn = type;
2094 bidi_check_type (bidi_it->type_after_wn);
2095 type = WEAK_BN;
2096 if (new_level < BIDI_MAXDEPTH - 1
2097 && bidi_it->invalid_levels == 0
2098 && bidi_it->invalid_isolates == 0)
2099 {
2100
2101
2102 new_level = ((new_level + 2) & ~1);
2103 if (bidi_it->type_after_wn == LRE)
2104 override = NEUTRAL_DIR;
2105 else
2106 override = L2R;
2107 bidi_push_embedding_level (bidi_it, new_level, override, false);
2108 bidi_it->resolved_level = new_level;
2109 }
2110 else
2111 {
2112 if (bidi_it->invalid_isolates == 0)
2113 bidi_it->invalid_levels++;
2114 }
2115 break;
2116 case FSI:
2117 end = string_p ? bidi_it->string.schars : ZV;
2118 disp_pos = bidi_it->disp_pos;
2119 disp_prop = bidi_it->disp_prop;
2120 nchars = bidi_it->nchars;
2121 ch_len = bidi_it->ch_len;
2122 typ1 = find_first_strong_char (bidi_it->charpos,
2123 bidi_it->bytepos, end,
2124 &disp_pos, &disp_prop,
2125 &bidi_it->string, bidi_it->w,
2126 string_p, bidi_it->frame_window_p,
2127 &ch_len, &nchars, true);
2128 if (typ1 != STRONG_R && typ1 != STRONG_AL)
2129 {
2130 type = LRI;
2131
2132
2133
2134 bidi_it->orig_type = type;
2135 goto fsi_as_lri;
2136 }
2137 else
2138 {
2139 type = RLI;
2140 bidi_it->orig_type = type;
2141 }
2142 FALLTHROUGH;
2143 case RLI:
2144 if (override == NEUTRAL_DIR)
2145 bidi_it->type_after_wn = type;
2146 else
2147 bidi_it->type_after_wn = (override == L2R ? STRONG_L : STRONG_R);
2148 bidi_check_type (bidi_it->type_after_wn);
2149 break;
2150 case LRI:
2151 fsi_as_lri:
2152 if (override == NEUTRAL_DIR)
2153 bidi_it->type_after_wn = type;
2154 else
2155 bidi_it->type_after_wn = (override == L2R ? STRONG_L : STRONG_R);
2156 bidi_check_type (bidi_it->type_after_wn);
2157 break;
2158 case PDI:
2159 if (bidi_it->invalid_isolates)
2160 bidi_it->invalid_isolates--;
2161 else if (bidi_it->isolate_level > 0)
2162 {
2163 bidi_it->invalid_levels = 0;
2164 while (!ISOLATE_STATUS (bidi_it, bidi_it->stack_idx))
2165 bidi_pop_embedding_level (bidi_it);
2166 eassert (bidi_it->stack_idx > 0);
2167 new_level = bidi_pop_embedding_level (bidi_it);
2168 bidi_it->isolate_level--;
2169 }
2170 bidi_it->resolved_level = new_level;
2171
2172 {
2173 bidi_dir_t stack_override = OVERRIDE (bidi_it, bidi_it->stack_idx);
2174 if (stack_override == L2R)
2175 bidi_it->type_after_wn = STRONG_L;
2176 else if (stack_override == R2L)
2177 bidi_it->type_after_wn = STRONG_R;
2178 else
2179 bidi_it->type_after_wn = type;
2180 }
2181 break;
2182 case PDF:
2183 bidi_it->type_after_wn = type;
2184 bidi_check_type (bidi_it->type_after_wn);
2185 type = WEAK_BN;
2186 break;
2187 default:
2188
2189 break;
2190 }
2191
2192 bidi_it->type = type;
2193 bidi_check_type (bidi_it->type);
2194
2195 if (bidi_it->type == NEUTRAL_B)
2196 {
2197 bidi_set_paragraph_end (bidi_it);
2198
2199 bidi_it->type_after_wn = bidi_it->type;
2200 }
2201
2202 eassert (bidi_it->resolved_level >= 0);
2203 return bidi_it->resolved_level;
2204 }
2205
2206
2207
2208 static bidi_type_t
2209 bidi_resolve_weak (struct bidi_it *bidi_it)
2210 {
2211 bidi_type_t type;
2212 bidi_dir_t override;
2213 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2214 int new_level = bidi_resolve_explicit (bidi_it);
2215 int next_char;
2216 bidi_type_t type_of_next;
2217 struct bidi_it saved_it;
2218 ptrdiff_t eob
2219 = ((STRINGP (bidi_it->string.lstring) || bidi_it->string.s)
2220 ? bidi_it->string.schars : ZV);
2221
2222 type = bidi_it->type;
2223 override = OVERRIDE (bidi_it, bidi_it->stack_idx);
2224
2225 eassert (!(type == UNKNOWN_BT
2226 || type == LRE
2227 || type == LRO
2228 || type == RLE
2229 || type == RLO
2230 || type == PDF));
2231
2232 eassert (prev_level >= 0);
2233 if (bidi_it->type == NEUTRAL_B)
2234 {
2235
2236
2237
2238 bidi_set_sos_type (bidi_it, prev_level, new_level);
2239 }
2240 if (type == NEUTRAL_S || type == NEUTRAL_WS
2241 || type == WEAK_BN || type == STRONG_AL)
2242 bidi_it->type_after_wn = type;
2243 bidi_check_type (bidi_it->type_after_wn);
2244
2245
2246
2247 if (override == R2L)
2248 type = STRONG_R;
2249 else if (override == L2R)
2250 type = STRONG_L;
2251 else
2252 {
2253 if (type == WEAK_NSM)
2254 {
2255
2256
2257
2258
2259
2260
2261
2262
2263 if (bidi_it->prev.type != UNKNOWN_BT
2264
2265 && bidi_it->prev.type != NEUTRAL_B)
2266 {
2267 if (bidi_isolate_fmt_char (bidi_it->prev.type))
2268 {
2269
2270
2271
2272
2273 eassert (bidi_it->invalid_isolates > 0);
2274 type = NEUTRAL_ON;
2275 }
2276 else
2277 {
2278
2279
2280
2281 type = bidi_it->prev.type;
2282 }
2283 }
2284 else if (bidi_it->sos == R2L)
2285 type = STRONG_R;
2286 else if (bidi_it->sos == L2R)
2287 type = STRONG_L;
2288 else
2289 emacs_abort ();
2290 }
2291 if (type == WEAK_EN
2292 && bidi_it->last_strong.type == STRONG_AL)
2293 type = WEAK_AN;
2294 else if (type == STRONG_AL)
2295 type = STRONG_R;
2296 else if ((type == WEAK_ES
2297 && bidi_it->prev.type == WEAK_EN
2298 && bidi_it->prev.orig_type == WEAK_EN)
2299 || (type == WEAK_CS
2300 && ((bidi_it->prev.type == WEAK_EN
2301 && bidi_it->prev.orig_type == WEAK_EN)
2302 || bidi_it->prev.type == WEAK_AN)))
2303 {
2304 const unsigned char *s
2305 = (STRINGP (bidi_it->string.lstring)
2306 ? SDATA (bidi_it->string.lstring)
2307 : bidi_it->string.s);
2308
2309 next_char = (bidi_it->charpos + bidi_it->nchars >= eob
2310 ? BIDI_EOB
2311 : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len,
2312 s, bidi_it->string.unibyte));
2313 type_of_next = bidi_get_type (next_char, override);
2314
2315 if (type_of_next == WEAK_BN
2316 || bidi_explicit_dir_char (next_char))
2317 {
2318 bidi_copy_it (&saved_it, bidi_it);
2319 while (bidi_resolve_explicit (bidi_it) == new_level
2320 && bidi_it->type == WEAK_BN)
2321 type_of_next = bidi_it->type;
2322 bidi_copy_it (bidi_it, &saved_it);
2323 }
2324
2325
2326
2327
2328
2329 if (type == WEAK_ES
2330 && type_of_next == WEAK_EN
2331 && bidi_it->last_strong.type != STRONG_AL)
2332 type = WEAK_EN;
2333 else if (type == WEAK_CS)
2334 {
2335 if (bidi_it->prev.type == WEAK_AN
2336 && (type_of_next == WEAK_AN
2337
2338
2339
2340
2341
2342 || (type_of_next == WEAK_EN
2343 && bidi_it->last_strong.type == STRONG_AL)))
2344 type = WEAK_AN;
2345 else if (bidi_it->prev.type == WEAK_EN
2346 && type_of_next == WEAK_EN
2347 && bidi_it->last_strong.type != STRONG_AL)
2348 type = WEAK_EN;
2349 }
2350 }
2351 else if (type == WEAK_ET
2352 || type == WEAK_BN)
2353 {
2354 if (bidi_it->prev.type == WEAK_EN)
2355 type = WEAK_EN;
2356 else if (bidi_it->next_en_pos > bidi_it->charpos
2357 && bidi_it->next_en_type != WEAK_BN)
2358 {
2359 if (bidi_it->next_en_type == WEAK_EN)
2360 type = WEAK_EN;
2361 }
2362 else if (type == WEAK_BN
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380 && new_level == 0
2381 && !bidi_explicit_dir_char (bidi_it->ch)
2382 && ((bidi_it->last_strong.type == STRONG_L)
2383 || (bidi_it->last_strong.type == UNKNOWN_BT
2384 && bidi_it->sos == L2R)))
2385 type = STRONG_L;
2386 else if (bidi_it->next_en_pos >= 0)
2387 {
2388
2389
2390
2391
2392
2393
2394 ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars;
2395 const unsigned char *s = (STRINGP (bidi_it->string.lstring)
2396 ? SDATA (bidi_it->string.lstring)
2397 : bidi_it->string.s);
2398
2399 if (bidi_it->nchars <= 0)
2400 emacs_abort ();
2401 next_char
2402 = (bidi_it->charpos + bidi_it->nchars >= eob
2403 ? BIDI_EOB
2404 : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s,
2405 bidi_it->string.unibyte));
2406 type_of_next = bidi_get_type (next_char, override);
2407
2408 if (type_of_next == WEAK_ET
2409 || type_of_next == WEAK_BN
2410 || bidi_explicit_dir_char (next_char))
2411 {
2412 bidi_copy_it (&saved_it, bidi_it);
2413 while (bidi_resolve_explicit (bidi_it) == new_level
2414 && (bidi_it->type == WEAK_BN
2415 || bidi_it->type == WEAK_ET))
2416 type_of_next = bidi_it->type;
2417 if (type == WEAK_BN
2418 && bidi_it->charpos == saved_it.charpos + saved_it.nchars)
2419 {
2420
2421
2422
2423
2424
2425 en_pos = saved_it.charpos;
2426 type_of_next = type;
2427 }
2428 else
2429 en_pos = bidi_it->charpos;
2430 bidi_copy_it (bidi_it, &saved_it);
2431 }
2432
2433
2434 bidi_it->next_en_pos = en_pos;
2435 if (type_of_next == WEAK_EN)
2436 {
2437
2438
2439 if (bidi_it->last_strong.type == STRONG_AL)
2440 type_of_next = WEAK_AN;
2441 else if (type == WEAK_BN)
2442 type = NEUTRAL_ON;
2443 else
2444 type = WEAK_EN;
2445 }
2446 else if (type_of_next == NEUTRAL_B)
2447
2448
2449
2450 bidi_it->next_en_pos = -1;
2451
2452 bidi_it->next_en_type = type_of_next;
2453 }
2454 }
2455 }
2456
2457 if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS
2458 || (type == WEAK_BN
2459 && (bidi_it->prev.type == WEAK_CS
2460 || bidi_it->prev.type == WEAK_ES
2461 || bidi_it->prev.type == WEAK_ET)))
2462 type = NEUTRAL_ON;
2463
2464
2465
2466
2467
2468 if (bidi_it->type_after_wn == UNKNOWN_BT)
2469 bidi_it->type_after_wn = type;
2470 bidi_check_type (bidi_it->type_after_wn);
2471
2472 if (type == WEAK_EN)
2473 {
2474 if ((bidi_it->last_strong.type == STRONG_L)
2475 || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sos == L2R))
2476 type = STRONG_L;
2477 }
2478
2479 bidi_it->type = type;
2480 bidi_check_type (bidi_it->type);
2481 return type;
2482 }
2483
2484
2485
2486 static bidi_type_t
2487 bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
2488 {
2489
2490
2491 if (next_type == WEAK_EN || next_type == WEAK_AN)
2492 next_type = STRONG_R;
2493 if (prev_type == WEAK_EN || prev_type == WEAK_AN)
2494 prev_type = STRONG_R;
2495
2496 if (next_type == prev_type)
2497 return next_type;
2498 else if ((lev & 1) == 0)
2499 return STRONG_L;
2500 else
2501 return STRONG_R;
2502 }
2503
2504 #define FLAG_EMBEDDING_INSIDE 1
2505 #define FLAG_OPPOSITE_INSIDE 2
2506
2507
2508
2509 typedef struct bpa_stack_entry {
2510 int close_bracket_char;
2511 int open_bracket_idx;
2512 #ifdef ENABLE_CHECKING
2513 ptrdiff_t open_bracket_pos;
2514 #endif
2515 unsigned flags : 2;
2516 } bpa_stack_entry;
2517
2518
2519
2520
2521 enum { MAX_BPA_STACK = max (1, ((MAX_ALLOCA - 2 * sizeof (struct bidi_it))
2522 / sizeof (bpa_stack_entry))) };
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553 #define CANONICAL_EQU(c) \
2554 ( ASCII_CHAR_P (c) ? c \
2555 : (c) == LEFT_POINTING_ANGLE_BRACKET ? LEFT_ANGLE_BRACKET \
2556 : (c) == RIGHT_POINTING_ANGLE_BRACKET ? RIGHT_ANGLE_BRACKET \
2557 : c )
2558
2559 #ifdef ENABLE_CHECKING
2560 # define STORE_BRACKET_CHARPOS \
2561 bpa_stack[bpa_sp].open_bracket_pos = bidi_it->charpos
2562 #else
2563 # define STORE_BRACKET_CHARPOS
2564 #endif
2565
2566 #define PUSH_BPA_STACK \
2567 do { \
2568 int ch; \
2569 if (bpa_sp < MAX_BPA_STACK - 1 && bidi_cache_last_idx <= INT_MAX) \
2570 { \
2571 bpa_sp++; \
2572 ch = CANONICAL_EQU (bidi_it->ch); \
2573 bpa_stack[bpa_sp].close_bracket_char = bidi_mirror_char (ch); \
2574 bpa_stack[bpa_sp].open_bracket_idx = bidi_cache_last_idx; \
2575 bpa_stack[bpa_sp].flags = 0; \
2576 STORE_BRACKET_CHARPOS; \
2577 } \
2578 } while (0)
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588 static bool
2589 bidi_find_bracket_pairs (struct bidi_it *bidi_it)
2590 {
2591 bidi_bracket_type_t btype;
2592 bidi_type_t type = bidi_it->type;
2593 bool retval = false;
2594 ptrdiff_t n = 0;
2595
2596
2597
2598 if (bidi_it->scan_dir != 1)
2599 emacs_abort ();
2600
2601 btype = bidi_paired_bracket_type (bidi_it->ch);
2602 if (btype == BIDI_BRACKET_OPEN)
2603 {
2604 bpa_stack_entry bpa_stack[MAX_BPA_STACK];
2605 int bpa_sp = -1;
2606 struct bidi_it saved_it;
2607 int base_level = bidi_it->level_stack[0].level;
2608 int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2609 int maxlevel = embedding_level;
2610 bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L;
2611 struct bidi_it tem_it;
2612 bool l2r_seen = false, r2l_seen = false;
2613 ptrdiff_t pairing_pos;
2614 int idx_at_entry = bidi_cache_idx;
2615
2616 verify (MAX_BPA_STACK >= 100);
2617 bidi_copy_it (&saved_it, bidi_it);
2618
2619
2620
2621 tem_it.scan_dir = 1;
2622
2623 while (1)
2624 {
2625 int old_sidx, new_sidx;
2626 int current_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2627
2628 if (maxlevel < current_level)
2629 maxlevel = current_level;
2630
2631
2632
2633
2634
2635
2636
2637 if (btype == BIDI_BRACKET_OPEN && bidi_it->bracket_pairing_pos == -1)
2638 bidi_it->bracket_pairing_pos = bidi_it->charpos;
2639 if (!bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0))
2640 {
2641
2642
2643
2644 bidi_cache_reset_to (idx_at_entry - bidi_cache_start);
2645 bidi_copy_it (bidi_it, &saved_it);
2646 goto give_up;
2647 }
2648 if (btype == BIDI_BRACKET_OPEN)
2649 PUSH_BPA_STACK;
2650 else if (btype == BIDI_BRACKET_CLOSE)
2651 {
2652 int sp = bpa_sp;
2653 int curchar = CANONICAL_EQU (bidi_it->ch);
2654
2655 eassert (sp >= 0);
2656 while (sp >= 0 && bpa_stack[sp].close_bracket_char != curchar)
2657 sp--;
2658 if (sp >= 0)
2659 {
2660
2661 bidi_cache_fetch_state (bpa_stack[sp].open_bracket_idx,
2662 &tem_it);
2663 #ifdef ENABLE_CHECKING
2664 eassert (bpa_stack[sp].open_bracket_pos == tem_it.charpos);
2665 #endif
2666
2667
2668 if (bpa_stack[sp].flags & FLAG_EMBEDDING_INSIDE)
2669 tem_it.bracket_enclosed_type = embedding_type;
2670 else if (bpa_stack[sp].flags & FLAG_OPPOSITE_INSIDE)
2671 tem_it.bracket_enclosed_type
2672 = (embedding_type == STRONG_L ? STRONG_R : STRONG_L);
2673 else
2674 tem_it.bracket_enclosed_type = UNKNOWN_BT;
2675
2676
2677
2678 tem_it.bracket_pairing_pos = bidi_it->charpos;
2679 bidi_cache_iterator_state (&tem_it, 0, 1);
2680
2681
2682 bpa_sp = sp - 1;
2683 }
2684 if (bpa_sp < 0)
2685 {
2686 retval = true;
2687 break;
2688 }
2689 }
2690 else if (bidi_get_category (bidi_it->type_after_wn) != NEUTRAL)
2691 {
2692 unsigned flag = 0;
2693 int sp;
2694
2695
2696
2697 switch (bidi_it->type)
2698 {
2699 case STRONG_L:
2700 flag = ((embedding_level & 1) == 0
2701 ? FLAG_EMBEDDING_INSIDE
2702 : FLAG_OPPOSITE_INSIDE);
2703 l2r_seen = true;
2704 break;
2705 case STRONG_R:
2706 case WEAK_EN:
2707 case WEAK_AN:
2708 flag = ((embedding_level & 1) == 1
2709 ? FLAG_EMBEDDING_INSIDE
2710 : FLAG_OPPOSITE_INSIDE);
2711 r2l_seen = true;
2712 break;
2713 default:
2714 break;
2715 }
2716 if (flag)
2717 {
2718 for (sp = bpa_sp; sp >= 0; sp--)
2719 bpa_stack[sp].flags |= flag;
2720 }
2721 }
2722 old_sidx = bidi_it->stack_idx;
2723 type = bidi_resolve_weak (bidi_it);
2724 n++;
2725
2726 new_sidx = bidi_it->stack_idx;
2727 if (bidi_it->level_stack[new_sidx].level > current_level
2728 && (ISOLATE_STATUS (bidi_it, new_sidx)
2729 || (new_sidx > old_sidx + 1
2730 && ISOLATE_STATUS (bidi_it, new_sidx - 1))))
2731 {
2732 while (bidi_it->level_stack[bidi_it->stack_idx].level
2733 > current_level)
2734 {
2735 if (maxlevel < bidi_it->level_stack[bidi_it->stack_idx].level)
2736 maxlevel = bidi_it->level_stack[bidi_it->stack_idx].level;
2737 if (!bidi_cache_iterator_state (bidi_it,
2738 type == NEUTRAL_B, 0))
2739 {
2740
2741
2742
2743 bidi_cache_reset_to (idx_at_entry - bidi_cache_start);
2744 bidi_copy_it (bidi_it, &saved_it);
2745 goto give_up;
2746 }
2747 type = bidi_resolve_weak (bidi_it);
2748 n++;
2749 }
2750 }
2751 if (type == NEUTRAL_B
2752 || (bidi_it->level_stack[bidi_it->stack_idx].level
2753 != current_level))
2754 {
2755
2756
2757
2758
2759 pairing_pos = bidi_it->charpos;
2760 break;
2761 }
2762 if (bidi_it->type_after_wn == NEUTRAL_ON)
2763 btype = bidi_paired_bracket_type (bidi_it->ch);
2764 else
2765 btype = BIDI_BRACKET_NONE;
2766 }
2767
2768
2769
2770 type = bidi_cache_find (saved_it.charpos, 0, bidi_it);
2771 eassert (type == NEUTRAL_ON);
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788 if (maxlevel == base_level
2789 && (l2r_seen || r2l_seen)
2790 && ((base_level == 0 && !r2l_seen)
2791 || (base_level == 1 && !l2r_seen)))
2792 {
2793 ptrdiff_t eob
2794 = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring))
2795 ? bidi_it->string.schars : ZV);
2796
2797 if (retval)
2798 pairing_pos = bidi_it->bracket_pairing_pos;
2799
2800
2801
2802
2803
2804
2805 bidi_it->bracket_pairing_pos = eob;
2806
2807
2808 bidi_it->bracket_enclosed_type = embedding_type;
2809
2810
2811
2812
2813
2814 bidi_cache_reset_to (bidi_cache_last_idx - bidi_cache_start);
2815
2816
2817 bidi_it->next_for_neutral.type = embedding_type;
2818 bidi_it->next_for_neutral.charpos = pairing_pos;
2819
2820 retval = false;
2821 }
2822 }
2823
2824 give_up:
2825
2826
2827
2828
2829 if (max_redisplay_ticks > 0 && n > 0)
2830 update_redisplay_ticks (n / 20 + 1, bidi_it->w);
2831 return retval;
2832 }
2833
2834 static void
2835 bidi_record_type_for_neutral (struct bidi_saved_info *info, int level,
2836 bool nextp)
2837 {
2838 int idx;
2839
2840 for (idx = bidi_cache_last_idx + 1; idx < bidi_cache_idx; idx++)
2841 {
2842 int lev = bidi_cache[idx].level_stack[bidi_cache[idx].stack_idx].level;
2843
2844 if (lev <= level)
2845 {
2846 eassert (lev == level);
2847 if (nextp)
2848 bidi_cache[idx].next_for_neutral = *info;
2849 else
2850 bidi_cache[idx].prev_for_neutral = *info;
2851 break;
2852 }
2853 }
2854 }
2855
2856 static bidi_type_t
2857 bidi_resolve_brackets (struct bidi_it *bidi_it)
2858 {
2859 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2860 bool resolve_bracket = false;
2861 bidi_type_t type = UNKNOWN_BT;
2862 int ch;
2863 struct bidi_saved_info prev_for_neutral, next_for_neutral;
2864 ptrdiff_t eob
2865 = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring))
2866 ? bidi_it->string.schars : ZV);
2867
2868
2869
2870
2871 if (bidi_it->type == STRONG_L || bidi_it->type == STRONG_R
2872 || bidi_it->type == WEAK_AN || bidi_it->type == WEAK_EN)
2873 bidi_remember_char (&prev_for_neutral, bidi_it, 1);
2874 else
2875 prev_for_neutral = bidi_it->prev_for_neutral;
2876
2877 if (bidi_it->next_for_neutral.charpos > bidi_it->charpos)
2878 next_for_neutral = bidi_it->next_for_neutral;
2879 else
2880 next_for_neutral.charpos = -1;
2881 if (!bidi_it->first_elt)
2882 {
2883 type = bidi_cache_find (bidi_it->charpos + bidi_it->nchars, 0, bidi_it);
2884 ch = bidi_it->ch;
2885 }
2886 if (type == UNKNOWN_BT)
2887 {
2888 type = bidi_resolve_weak (bidi_it);
2889 if (type == NEUTRAL_ON)
2890 {
2891
2892
2893
2894
2895 if (bidi_it->bracket_pairing_pos == eob)
2896 {
2897
2898
2899
2900
2901 if (bidi_it->next_for_neutral.charpos == bidi_it->charpos
2902 && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE)
2903 type = bidi_it->bracket_enclosed_type;
2904 }
2905 else if (bidi_find_bracket_pairs (bidi_it))
2906 resolve_bracket = true;
2907 }
2908 }
2909 else if (bidi_it->bracket_pairing_pos != eob)
2910 {
2911 eassert (bidi_it->resolved_level == -1);
2912
2913
2914
2915
2916
2917 if (bidi_it->level_stack[bidi_it->stack_idx].level > prev_level
2918 && ISOLATE_STATUS (bidi_it, bidi_it->stack_idx))
2919 {
2920 bidi_record_type_for_neutral (&prev_for_neutral, prev_level, 0);
2921 bidi_record_type_for_neutral (&next_for_neutral, prev_level, 1);
2922 }
2923 if (type == NEUTRAL_ON
2924 && bidi_paired_bracket_type (ch) == BIDI_BRACKET_OPEN)
2925 {
2926 if (bidi_it->bracket_pairing_pos > bidi_it->charpos)
2927 {
2928
2929
2930 resolve_bracket = true;
2931 }
2932 else if (bidi_it->bracket_pairing_pos == -1)
2933 {
2934
2935
2936
2937 if (bidi_find_bracket_pairs (bidi_it))
2938 resolve_bracket = true;
2939 }
2940 }
2941
2942
2943
2944 if (bidi_it->level_stack[bidi_it->stack_idx].level == prev_level)
2945 {
2946 bidi_it->prev_for_neutral = prev_for_neutral;
2947 if (next_for_neutral.charpos > 0)
2948 bidi_it->next_for_neutral = next_for_neutral;
2949 }
2950 }
2951
2952
2953 if (resolve_bracket)
2954 {
2955 int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2956 bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L;
2957
2958 eassert (bidi_it->bracket_pairing_pos > bidi_it->charpos);
2959 if (bidi_it->bracket_enclosed_type == embedding_type)
2960 type = embedding_type;
2961 else if (bidi_it->bracket_enclosed_type == STRONG_L
2962 || bidi_it->bracket_enclosed_type == STRONG_R)
2963 {
2964 bidi_type_t prev_type_for_neutral = bidi_it->prev_for_neutral.type;
2965
2966 if (prev_type_for_neutral == UNKNOWN_BT)
2967 prev_type_for_neutral = embedding_type;
2968 switch (prev_type_for_neutral)
2969 {
2970 case STRONG_R:
2971 case WEAK_EN:
2972 case WEAK_AN:
2973 type =
2974 (bidi_it->bracket_enclosed_type == STRONG_R)
2975 ? STRONG_R
2976 : embedding_type;
2977 break;
2978 case STRONG_L:
2979 type =
2980 (bidi_it->bracket_enclosed_type == STRONG_L)
2981 ? STRONG_L
2982 : embedding_type;
2983 break;
2984 default:
2985
2986 break;
2987 }
2988 }
2989 eassert (type == STRONG_L || type == STRONG_R || type == NEUTRAL_ON);
2990
2991
2992
2993 if (type != NEUTRAL_ON)
2994 {
2995 ptrdiff_t idx = bidi_cache_search (bidi_it->bracket_pairing_pos,
2996 -1, 1);
2997
2998 if (idx < bidi_cache_start)
2999 emacs_abort ();
3000 bidi_cache[idx].type = type;
3001 }
3002 }
3003
3004 return type;
3005 }
3006
3007 static bidi_type_t
3008 bidi_resolve_neutral (struct bidi_it *bidi_it)
3009 {
3010 bidi_type_t type = bidi_resolve_brackets (bidi_it);
3011 int current_level;
3012 bool is_neutral;
3013
3014 eassert (type == STRONG_R
3015 || type == STRONG_L
3016 || type == WEAK_BN
3017 || type == WEAK_EN
3018 || type == WEAK_AN
3019 || type == NEUTRAL_B
3020 || type == NEUTRAL_S
3021 || type == NEUTRAL_WS
3022 || type == NEUTRAL_ON
3023 || type == LRI
3024 || type == RLI
3025 || type == PDI);
3026
3027 current_level = bidi_it->level_stack[bidi_it->stack_idx].level;
3028 eassert (current_level >= 0);
3029 is_neutral = bidi_get_category (type) == NEUTRAL;
3030
3031 if ((type != NEUTRAL_B
3032
3033 && (is_neutral || bidi_isolate_fmt_char (type)))
3034
3035 || type == WEAK_BN)
3036 {
3037 if (bidi_it->next_for_neutral.type != UNKNOWN_BT
3038 && (bidi_it->next_for_neutral.charpos > bidi_it->charpos
3039
3040
3041 || (bidi_it->next_for_neutral.charpos == bidi_it->charpos
3042 && bidi_it->type == PDI)))
3043 {
3044 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
3045 bidi_it->next_for_neutral.type,
3046 current_level);
3047 }
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061 else if (current_level == 0
3062 && bidi_it->prev_for_neutral.type == STRONG_L
3063 && (ASCII_CHAR_P (bidi_it->ch)
3064 || (type != WEAK_BN
3065 && !bidi_explicit_dir_char (bidi_it->ch)
3066 && !bidi_isolate_fmt_char (type))))
3067 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
3068 STRONG_L, current_level);
3069 else if (
3070 current_level == 1
3071
3072 && bidi_it->level_stack[0].level == 1
3073
3074
3075 && (bidi_it->prev_for_neutral.type == STRONG_R
3076 || bidi_it->prev_for_neutral.type == WEAK_EN
3077 || bidi_it->prev_for_neutral.type == WEAK_AN)
3078 && type != WEAK_BN
3079 && !bidi_explicit_dir_char (bidi_it->ch)
3080 && !bidi_isolate_fmt_char (type))
3081 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
3082 STRONG_R, current_level);
3083 else
3084 {
3085
3086
3087
3088
3089
3090
3091
3092
3093 struct bidi_it saved_it;
3094 bidi_type_t next_type;
3095 bool adjacent_to_neutrals = is_neutral;
3096
3097 bidi_copy_it (&saved_it, bidi_it);
3098
3099
3100
3101
3102 do {
3103 int old_sidx, new_sidx;
3104
3105
3106
3107 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0);
3108 old_sidx = bidi_it->stack_idx;
3109 type = bidi_resolve_brackets (bidi_it);
3110
3111 new_sidx = bidi_it->stack_idx;
3112 if (bidi_it->level_stack[new_sidx].level > current_level
3113 && (ISOLATE_STATUS (bidi_it, new_sidx)
3114
3115
3116
3117
3118
3119 || (new_sidx > old_sidx + 1
3120 && ISOLATE_STATUS (bidi_it, new_sidx - 1))))
3121 {
3122 while (bidi_it->level_stack[bidi_it->stack_idx].level
3123 > current_level)
3124 {
3125 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0);
3126 type = bidi_resolve_brackets (bidi_it);
3127 }
3128 }
3129 if (!adjacent_to_neutrals
3130 && (bidi_get_category (type) == NEUTRAL
3131 || bidi_isolate_fmt_char (type)))
3132 adjacent_to_neutrals = true;
3133 } while (!(type == NEUTRAL_B
3134 || (type != WEAK_BN
3135 && bidi_get_category (type) != NEUTRAL
3136 && !bidi_isolate_fmt_char (type))
3137
3138
3139 || (bidi_it->level_stack[bidi_it->stack_idx].level
3140 != current_level)));
3141
3142
3143 bidi_remember_char (&saved_it.next_for_neutral, bidi_it, 1);
3144
3145 if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level)
3146 || type == NEUTRAL_B)
3147 {
3148
3149
3150
3151
3152 if (adjacent_to_neutrals)
3153 next_type = bidi_it->prev_for_neutral.type;
3154 else
3155 {
3156
3157
3158 bidi_copy_it (bidi_it, &saved_it);
3159 return bidi_it->type;
3160 }
3161 }
3162 else
3163 {
3164 switch (type)
3165 {
3166 case STRONG_L:
3167 case STRONG_R:
3168 case STRONG_AL:
3169
3170
3171 eassert (type != STRONG_AL);
3172 next_type = type;
3173 break;
3174 case WEAK_EN:
3175 case WEAK_AN:
3176
3177
3178 next_type = STRONG_R;
3179 break;
3180 default:
3181 emacs_abort ();
3182 break;
3183 }
3184 }
3185
3186 type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
3187 next_type, current_level);
3188
3189
3190
3191 saved_it.next_for_neutral.type = next_type;
3192 bidi_check_type (type);
3193
3194 saved_it.type = type;
3195 bidi_check_type (next_type);
3196 bidi_copy_it (bidi_it, &saved_it);
3197 }
3198 }
3199 return type;
3200 }
3201
3202
3203
3204
3205
3206 static bidi_type_t
3207 bidi_type_of_next_char (struct bidi_it *bidi_it)
3208 {
3209 bidi_type_t type;
3210
3211
3212 if (bidi_it->scan_dir != 1)
3213 emacs_abort ();
3214
3215 type = bidi_resolve_neutral (bidi_it);
3216
3217 return type;
3218 }
3219
3220
3221
3222
3223
3224 static int
3225 bidi_level_of_next_char (struct bidi_it *bidi_it)
3226 {
3227 bidi_type_t type = UNKNOWN_BT;
3228 int level;
3229 ptrdiff_t next_char_pos = -2;
3230
3231 if (bidi_it->scan_dir == 1)
3232 {
3233 ptrdiff_t eob
3234 = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring))
3235 ? bidi_it->string.schars : ZV);
3236
3237
3238
3239 if (bidi_it->charpos >= eob)
3240 {
3241 eassert (bidi_it->resolved_level >= 0);
3242 return bidi_it->resolved_level;
3243 }
3244 }
3245
3246
3247
3248
3249 if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt)
3250 {
3251 int bob = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring))
3252 ? 0 : 1);
3253
3254 if (bidi_it->scan_dir > 0)
3255 {
3256 if (bidi_it->nchars <= 0)
3257 emacs_abort ();
3258 next_char_pos = bidi_it->charpos + bidi_it->nchars;
3259 }
3260 else if (bidi_it->charpos >= bob)
3261
3262
3263
3264
3265 next_char_pos = bidi_it->charpos - 1;
3266 if (next_char_pos >= bob - 1)
3267 type = bidi_cache_find (next_char_pos, 1, bidi_it);
3268 if (type != UNKNOWN_BT)
3269 {
3270
3271 eassert (bidi_it->resolved_level >= 0);
3272 return bidi_it->resolved_level;
3273 }
3274 }
3275
3276 if (bidi_it->scan_dir == -1)
3277
3278
3279 emacs_abort ();
3280
3281 if (type == UNKNOWN_BT)
3282 type = bidi_type_of_next_char (bidi_it);
3283
3284 if (type == NEUTRAL_B)
3285 {
3286 eassert (bidi_it->resolved_level >= 0);
3287 return bidi_it->resolved_level;
3288 }
3289
3290 level = bidi_it->level_stack[bidi_it->stack_idx].level;
3291
3292 eassert ((type == STRONG_R
3293 || type == STRONG_L
3294 || type == WEAK_BN
3295 || type == WEAK_EN
3296 || type == WEAK_AN));
3297 bidi_it->type = type;
3298 bidi_check_type (bidi_it->type);
3299
3300
3301
3302
3303 if ((bidi_it->orig_type == NEUTRAL_WS
3304 || (bidi_it->orig_type == WEAK_BN
3305
3306
3307
3308
3309 && level != bidi_it->level_stack[0].level)
3310 || bidi_isolate_fmt_char (bidi_it->orig_type))
3311
3312 && bidi_it->next_for_ws.charpos < bidi_it->charpos)
3313 {
3314 int ch;
3315 ptrdiff_t clen = bidi_it->ch_len;
3316 ptrdiff_t bpos = bidi_it->bytepos;
3317 ptrdiff_t cpos = bidi_it->charpos;
3318 ptrdiff_t disp_pos = bidi_it->disp_pos;
3319 ptrdiff_t nc = bidi_it->nchars;
3320 struct bidi_string_data bs = bidi_it->string;
3321 bidi_type_t chtype;
3322 bool fwp = bidi_it->frame_window_p;
3323 int dpp = bidi_it->disp_prop;
3324
3325 if (bidi_it->nchars <= 0)
3326 emacs_abort ();
3327 do {
3328 ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
3329 bidi_it->w, fwp, &clen, &nc);
3330 chtype = bidi_get_type (ch, NEUTRAL_DIR);
3331 } while (chtype == NEUTRAL_WS || chtype == WEAK_BN
3332 || bidi_isolate_fmt_char (chtype)
3333 || bidi_explicit_dir_char (ch));
3334 bidi_it->next_for_ws.type = chtype;
3335 bidi_check_type (bidi_it->next_for_ws.type);
3336 bidi_it->next_for_ws.charpos = cpos;
3337 }
3338
3339
3340 bidi_cache_iterator_state (bidi_it, 1, 1);
3341
3342
3343 if (bidi_it->orig_type == NEUTRAL_B
3344 || bidi_it->orig_type == NEUTRAL_S
3345 || bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB
3346 || ((bidi_it->orig_type == NEUTRAL_WS
3347 || bidi_it->orig_type == WEAK_BN
3348 || bidi_isolate_fmt_char (bidi_it->orig_type)
3349 || bidi_explicit_dir_char (bidi_it->ch))
3350 && (bidi_it->next_for_ws.type == NEUTRAL_B
3351 || bidi_it->next_for_ws.type == NEUTRAL_S)))
3352 level = bidi_it->level_stack[0].level;
3353 else if ((level & 1) == 0)
3354 {
3355 if (type == STRONG_R)
3356 level++;
3357 else if (type == WEAK_EN || type == WEAK_AN)
3358 level += 2;
3359 }
3360 else
3361 {
3362 if (type == STRONG_L || type == WEAK_EN || type == WEAK_AN)
3363 level++;
3364 }
3365
3366 bidi_it->resolved_level = level;
3367 return level;
3368 }
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390 static void
3391 bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, bool end_flag)
3392 {
3393 int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir;
3394 ptrdiff_t idx;
3395
3396
3397 if ((idx = bidi_cache_find_level_change (level, dir, end_flag))
3398 >= bidi_cache_start)
3399 bidi_cache_fetch_state (idx, bidi_it);
3400 else
3401 {
3402 int new_level;
3403 ptrdiff_t pos0 = bidi_it->charpos;
3404
3405
3406 if (end_flag)
3407 emacs_abort ();
3408
3409 if (!bidi_cache_iterator_state (bidi_it, 1, 0))
3410 {
3411
3412
3413
3414
3415 emacs_abort ();
3416 }
3417 do {
3418 new_level = bidi_level_of_next_char (bidi_it);
3419
3420
3421 if (!bidi_cache_iterator_state (bidi_it, 1, 0))
3422 {
3423 new_level = level - 1;
3424
3425
3426
3427
3428
3429 eassert (new_level == bidi_it->level_stack[0].level);
3430
3431
3432
3433
3434 bidi_cache_fetch_state (bidi_cache_idx - 1, bidi_it);
3435 bidi_it->resolved_level = new_level;
3436 bidi_cache_iterator_state (bidi_it, 1, 1);
3437 }
3438 } while (new_level >= level);
3439
3440
3441
3442
3443 if (max_redisplay_ticks > 0 && bidi_it->charpos > pos0)
3444 update_redisplay_ticks ((bidi_it->charpos - pos0) / 50 + 1, bidi_it->w);
3445 }
3446 }
3447
3448 void
3449 bidi_move_to_visually_next (struct bidi_it *bidi_it)
3450 {
3451 int old_level, new_level, next_level;
3452 struct bidi_it sentinel;
3453
3454 if (bidi_it->charpos < 0 || bidi_it->bytepos < 0)
3455 emacs_abort ();
3456
3457 if (bidi_it->scan_dir == 0)
3458 {
3459 bidi_it->scan_dir = 1;
3460 }
3461
3462
3463 if (!bidi_it->first_elt
3464 && (bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB))
3465 bidi_line_init (bidi_it);
3466
3467
3468
3469
3470 if (bidi_cache_idx == bidi_cache_start)
3471 {
3472 bidi_copy_it (&sentinel, bidi_it);
3473 if (bidi_it->first_elt)
3474 {
3475 sentinel.charpos--;
3476 sentinel.bytepos--;
3477 sentinel.ch = '\n';
3478 sentinel.ch_len = 1;
3479 sentinel.nchars = 1;
3480 }
3481 bidi_cache_iterator_state (&sentinel, 1, 0);
3482 }
3483
3484 old_level = bidi_it->resolved_level;
3485 new_level = bidi_level_of_next_char (bidi_it);
3486
3487
3488
3489
3490 if (new_level != old_level)
3491 {
3492 bool ascending = new_level > old_level;
3493 int level_to_search = ascending ? old_level + 1 : old_level;
3494 int incr = ascending ? 1 : -1;
3495 int expected_next_level = old_level + incr;
3496
3497
3498 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
3499
3500
3501 bidi_it->scan_dir = -bidi_it->scan_dir;
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522 next_level = bidi_peek_at_next_level (bidi_it);
3523 while (next_level != expected_next_level)
3524 {
3525
3526
3527
3528 eassert (next_level >= 0);
3529
3530
3531 eassert (incr > 0
3532 ? next_level > expected_next_level
3533 : next_level < expected_next_level);
3534 expected_next_level += incr;
3535 level_to_search += incr;
3536 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
3537 bidi_it->scan_dir = -bidi_it->scan_dir;
3538 next_level = bidi_peek_at_next_level (bidi_it);
3539 }
3540
3541
3542 next_level = bidi_level_of_next_char (bidi_it);
3543 }
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554 if (bidi_it->scan_dir == 1
3555 && (bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB))
3556 {
3557
3558
3559
3560
3561
3562 if (bidi_it->string.s || STRINGP (bidi_it->string.lstring))
3563 bidi_it->separator_limit = bidi_it->string.schars;
3564 else if (bidi_it->bytepos < ZV_BYTE)
3565 {
3566 ptrdiff_t sep_len
3567 = bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars,
3568 bidi_it->bytepos + bidi_it->ch_len);
3569 if (bidi_it->nchars <= 0)
3570 emacs_abort ();
3571 if (sep_len >= 0)
3572 {
3573 bidi_it->new_paragraph = 1;
3574
3575
3576
3577
3578
3579 if (sep_len > 0)
3580 bidi_it->separator_limit
3581 = bidi_it->charpos + bidi_it->nchars + sep_len;
3582 else
3583 bidi_it->separator_limit = bidi_it->charpos;
3584 }
3585 }
3586 }
3587
3588 if (bidi_it->scan_dir == 1 && bidi_cache_idx > bidi_cache_start)
3589 {
3590
3591
3592
3593 if (bidi_it->resolved_level == bidi_it->level_stack[0].level
3594 && bidi_it->charpos > (bidi_cache[bidi_cache_idx - 1].charpos
3595 + bidi_cache[bidi_cache_idx - 1].nchars - 1))
3596 bidi_cache_reset ();
3597
3598
3599 else if (bidi_it->resolved_level == bidi_it->level_stack[0].level
3600 && bidi_cache_idx >= bidi_cache_size
3601 && bidi_it->charpos == bidi_cache[bidi_cache_idx - 1].charpos)
3602 bidi_cache_reset ();
3603
3604
3605
3606
3607 else
3608 bidi_cache_iterator_state (bidi_it, 1, 0);
3609 }
3610
3611 eassert (bidi_it->resolved_level >= 0
3612 && bidi_it->resolved_level <= BIDI_MAXDEPTH + 2);
3613 }
3614
3615
3616
3617
3618 ptrdiff_t
3619 bidi_find_first_overridden (struct bidi_it *bidi_it)
3620 {
3621 ptrdiff_t eob
3622 = STRINGP (bidi_it->string.lstring) ? bidi_it->string.schars : ZV;
3623 ptrdiff_t found_pos = eob;
3624
3625
3626
3627 int max_l2r = bidi_it->paragraph_dir == L2R ? 0 : 2;
3628 int max_r2l = 1;
3629
3630 int max_weak = bidi_it->paragraph_dir == L2R ? 1 : 2;
3631
3632 do
3633 {
3634
3635
3636
3637 bidi_type_t type = bidi_resolve_weak (bidi_it);
3638 unsigned level = bidi_it->level_stack[bidi_it->stack_idx].level;
3639 bidi_category_t category = bidi_get_category (bidi_it->orig_type);
3640
3641
3642
3643 if ((type == STRONG_R && bidi_it->orig_type == STRONG_L)
3644 || (type == STRONG_L
3645 && (bidi_it->orig_type == STRONG_R
3646 || bidi_it->orig_type == STRONG_AL))
3647
3648
3649
3650 || ((bidi_it->orig_type == STRONG_L
3651 || bidi_it->orig_type == WEAK_EN)
3652 && level > max_l2r)
3653 || ((bidi_it->orig_type == STRONG_R
3654 || bidi_it->orig_type == STRONG_AL)
3655 && level > max_r2l)
3656
3657
3658 || ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON)
3659 && level > max_weak))
3660 found_pos = bidi_it->charpos;
3661 } while (found_pos == eob
3662 && bidi_it->charpos < eob
3663 && bidi_it->ch != BIDI_EOB
3664 && bidi_it->ch != '\n');
3665
3666 return found_pos;
3667 }
3668
3669
3670
3671 void bidi_dump_cached_states (void) EXTERNALLY_VISIBLE;
3672 void
3673 bidi_dump_cached_states (void)
3674 {
3675 ptrdiff_t i;
3676 int ndigits = 1;
3677
3678 if (bidi_cache_idx == 0)
3679 {
3680 fputs ("The cache is empty.\n", stderr);
3681 return;
3682 }
3683 fprintf (stderr, "Total of %"pD"d state%s in cache:\n",
3684 bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s");
3685
3686 for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10)
3687 ndigits++;
3688 fputs ("ch ", stderr);
3689 for (i = 0; i < bidi_cache_idx; i++)
3690 fprintf (stderr, "%*c", ndigits, bidi_cache[i].ch);
3691 fputs ("\nlvl ", stderr);
3692 for (i = 0; i < bidi_cache_idx; i++)
3693 fprintf (stderr, "%*d", ndigits, bidi_cache[i].resolved_level);
3694 fputs ("\npos ", stderr);
3695 for (i = 0; i < bidi_cache_idx; i++)
3696 fprintf (stderr, "%*"pD"d", ndigits, bidi_cache[i].charpos);
3697 putc ('\n', stderr);
3698 }