2 * fribidi-bidi.c - bidirectional algorithm
5 * Behdad Esfahbod, 2001, 2002, 2004
6 * Dov Grobgeld, 1999, 2000, 2017
8 * Copyright (C) 2004 Sharif FarsiWeb, Inc
9 * Copyright (C) 2001,2002 Behdad Esfahbod
10 * Copyright (C) 1999,2000,2017 Dov Grobgeld
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this library, in a file named COPYING; if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301, USA
27 * For licensing issues, contact <fribidi.license@gmail.com>.
32 #include <fribidi-bidi.h>
33 #include <fribidi-mirroring.h>
34 #include <fribidi-brackets.h>
35 #include <fribidi-unicode.h>
37 #include "bidi-types.h"
41 * This file implements most of Unicode Standard Annex #9, Tracking Number 13.
45 # define MAX(a,b) ((a) > (b) ? (a) : (b))
48 /* Some convenience macros */
49 #define RL_TYPE(list) ((list)->type)
50 #define RL_LEN(list) ((list)->len)
51 #define RL_LEVEL(list) ((list)->level)
53 /* "Within this scope, bidirectional types EN and AN are treated as R" */
54 #define RL_TYPE_AN_EN_AS_RTL(list) ( \
55 (((list)->type == FRIBIDI_TYPE_AN) || ((list)->type == FRIBIDI_TYPE_EN) | ((list)->type == FRIBIDI_TYPE_RTL)) ? FRIBIDI_TYPE_RTL : (list)->type)
56 #define RL_BRACKET_TYPE(list) ((list)->bracket_type)
57 #define RL_ISOLATE_LEVEL(list) ((list)->isolate_level)
59 #define LOCAL_BRACKET_SIZE 16
61 /* Pairing nodes are used for holding a pair of open/close brackets as
63 struct _FriBidiPairingNodeStruct {
66 struct _FriBidiPairingNodeStruct *next;
68 typedef struct _FriBidiPairingNodeStruct FriBidiPairingNode;
77 fribidi_assert (second);
78 fribidi_assert (second->next);
80 fribidi_assert (first);
82 first->next = second->next;
83 first->next->prev = first;
84 RL_LEN (first) += RL_LEN (second);
85 if (second->next_isolate)
86 second->next_isolate->prev_isolate = first;
87 first->next_isolate = second->next_isolate;
89 fribidi_free (second);
98 fribidi_assert (list);
101 for_run_list (list, list)
102 if (RL_TYPE (list->prev) == RL_TYPE (list)
103 && RL_LEVEL (list->prev) == RL_LEVEL (list)
104 && RL_BRACKET_TYPE(list) == FRIBIDI_NO_BRACKET /* Don't join brackets! */
105 && RL_BRACKET_TYPE(list->prev) == FRIBIDI_NO_BRACKET
107 list = merge_with_prev (list);
115 fribidi_assert (list);
119 for_run_list (list, list)
121 if (RL_LEVEL (list->prev) == RL_LEVEL (list)
123 ((RL_TYPE (list->prev) == RL_TYPE (list)
124 || (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev))
125 && FRIBIDI_IS_NEUTRAL (RL_TYPE (list)))))
126 && RL_BRACKET_TYPE(list) == FRIBIDI_NO_BRACKET /* Don't join brackets! */
127 && RL_BRACKET_TYPE(list->prev) == FRIBIDI_NO_BRACKET
129 list = merge_with_prev (list);
134 /* Search for an adjacent run in the forward or backward direction.
135 It uses the next_isolate and prev_isolate run for short circuited searching.
138 /* The static sentinel is used to signal the end of an isolating
140 static FriBidiRun sentinel = { NULL, NULL, 0,0, FRIBIDI_TYPE_SENTINEL, -1,-1,FRIBIDI_NO_BRACKET, NULL, NULL };
142 static FriBidiRun *get_adjacent_run(FriBidiRun *list, fribidi_boolean forward, fribidi_boolean skip_neutral)
144 FriBidiRun *ppp = forward ? list->next_isolate : list->prev_isolate;
150 FriBidiCharType ppp_type = RL_TYPE (ppp);
152 if (ppp_type == FRIBIDI_TYPE_SENTINEL)
155 /* Note that when sweeping forward we continue one run
156 beyond the PDI to see what lies behind. When looking
157 backwards, this is not necessary as the leading isolate
158 run has already been assigned the resolved level. */
159 if (ppp->isolate_level > list->isolate_level /* <- How can this be true? */
160 || (forward && ppp_type == FRIBIDI_TYPE_PDI)
161 || (skip_neutral && !FRIBIDI_IS_STRONG(ppp_type)))
163 ppp = forward ? ppp->next_isolate : ppp->prev_isolate;
176 /*======================================================================
177 * For debugging, define some functions for printing the types and the
179 *----------------------------------------------------------------------*/
181 static char char_from_level_array[] = {
182 '$', /* -1 == FRIBIDI_SENTINEL, indicating
183 * start or end of string. */
184 /* 0-61 == 0-9,a-z,A-Z are the the only valid levels before resolving
185 * implicits. after that the level @ may be appear too. */
186 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
187 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
188 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
189 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
190 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
191 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
194 /* TBD - insert another 125-64 levels */
196 '@', /* 62 == only must appear after resolving
199 '!', /* 63 == FRIBIDI_LEVEL_INVALID, internal error,
200 * this level shouldn't be seen. */
202 '*', '*', '*', '*', '*' /* >= 64 == overflows, this levels and higher
203 * levels show a real bug!. */
206 #define fribidi_char_from_level(level) char_from_level_array[(level) + 1]
215 MSG (" Run types : ");
216 for_run_list (pp, pp)
218 MSG6 ("%d:%d(%s)[%d,%d] ",
219 pp->pos, pp->len, fribidi_get_bidi_type_name (pp->type), pp->level, pp->isolate_level);
225 print_resolved_levels (
231 MSG (" Res. levels: ");
232 for_run_list (pp, pp)
234 register FriBidiStrIndex i;
235 for (i = RL_LEN (pp); i; i--)
236 MSG2 ("%c", fribidi_char_from_level (RL_LEVEL (pp)));
242 print_resolved_types (
248 MSG (" Res. types : ");
249 for_run_list (pp, pp)
252 for (i = RL_LEN (pp); i; i--)
253 MSG2 ("%s ", fribidi_get_bidi_type_name (pp->type));
261 const FriBidiCharType *bidi_types,
262 const FriBidiStrIndex len
265 register FriBidiStrIndex i;
267 fribidi_assert (bidi_types);
269 MSG (" Org. types : ");
270 for (i = 0; i < len; i++)
271 MSG2 ("%s ", fribidi_get_bidi_type_name (bidi_types[i]));
275 static void print_pairing_nodes(FriBidiPairingNode *nodes)
280 MSG3 ("(%d, %d) ", nodes->open->pos, nodes->close->pos);
288 /*=========================================================================
289 * define macros for push and pop the status in to / out of the stack
290 *-------------------------------------------------------------------------*/
292 /* There are a few little points in pushing into and popping from the status
294 1. when the embedding level is not valid (more than
295 FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=125), you must reject it, and not to push
296 into the stack, but when you see a PDF, you must find the matching code,
297 and if it was pushed in the stack, pop it, it means you must pop if and
298 only if you have pushed the matching code, the over_pushed var counts the
299 number of rejected codes so far.
301 2. there's a more confusing point too, when the embedding level is exactly
302 FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1=124, an LRO, LRE, or LRI is rejected
303 because the new level would be FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL+1=126, that
304 is invalid; but an RLO, RLE, or RLI is accepted because the new level is
305 FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=125, that is valid, so the rejected codes
306 may be not continuous in the logical order, in fact there are at most two
307 continuous intervals of codes, with an RLO, RLE, or RLI between them. To
308 support this case, the first_interval var counts the number of rejected
309 codes in the first interval, when it is 0, means that there is only one
314 /* a. If this new level would be valid, then this embedding code is valid.
315 Remember (push) the current embedding level and override status.
316 Reset current level to this new level, and reset the override status to
318 b. If the new level would not be valid, then this code is invalid. Don't
319 change the current level or override status.
321 #define PUSH_STATUS \
323 if LIKELY(over_pushed == 0 \
324 && isolate_overflow == 0 \
325 && new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL) \
327 if UNLIKELY(level == FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL - 1) \
328 first_interval = over_pushed; \
329 status_stack[stack_size].level = level; \
330 status_stack[stack_size].isolate_level = isolate_level; \
331 status_stack[stack_size].isolate = isolate; \
332 status_stack[stack_size].override = override; \
335 override = new_override; \
336 } else if LIKELY(isolate_overflow == 0) \
340 /* If there was a valid matching code, restore (pop) the last remembered
341 (pushed) embedding level and directional override.
347 if UNLIKELY(over_pushed > first_interval) \
351 if LIKELY(over_pushed == first_interval) \
352 first_interval = 0; \
354 level = status_stack[stack_size].level; \
355 override = status_stack[stack_size].override; \
356 isolate = status_stack[stack_size].isolate; \
357 isolate_level = status_stack[stack_size].isolate_level; \
363 /* Return the type of previous run or the SOR, if already at the start of
365 #define PREV_TYPE_OR_SOR(pp) \
367 RL_LEVEL(pp->prev) == RL_LEVEL(pp) ? \
368 RL_TYPE(pp->prev) : \
369 FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->prev), RL_LEVEL(pp))) \
372 /* Return the type of next run or the EOR, if already at the end of
374 #define NEXT_TYPE_OR_EOR(pp) \
376 RL_LEVEL(pp->next) == RL_LEVEL(pp) ? \
377 RL_TYPE(pp->next) : \
378 FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->next), RL_LEVEL(pp))) \
382 /* Return the embedding direction of a link. */
383 #define FRIBIDI_EMBEDDING_DIRECTION(link) \
384 FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(link))
387 FRIBIDI_ENTRY FriBidiParType
388 fribidi_get_par_direction (
390 const FriBidiCharType *bidi_types,
391 const FriBidiStrIndex len
394 register FriBidiStrIndex i;
396 fribidi_assert (bidi_types);
398 for (i = 0; i < len; i++)
399 if (FRIBIDI_IS_LETTER (bidi_types[i]))
400 return FRIBIDI_IS_RTL (bidi_types[i]) ? FRIBIDI_PAR_RTL :
403 return FRIBIDI_PAR_ON;
406 /* Push a new entry to the pairing linked list */
407 static FriBidiPairingNode * pairing_nodes_push(FriBidiPairingNode *nodes,
411 FriBidiPairingNode *node = fribidi_malloc(sizeof(FriBidiPairingNode));
419 /* Sort by merge sort */
420 static void pairing_nodes_front_back_split(FriBidiPairingNode *source,
422 FriBidiPairingNode **front,
423 FriBidiPairingNode **back)
425 FriBidiPairingNode *pfast, *pslow;
426 if (!source || !source->next)
434 pfast = source->next;
450 static FriBidiPairingNode *
451 pairing_nodes_sorted_merge(FriBidiPairingNode *nodes1,
452 FriBidiPairingNode *nodes2)
454 FriBidiPairingNode *res = NULL;
460 if (nodes1->open->pos < nodes2->open->pos)
463 res->next = pairing_nodes_sorted_merge(nodes1->next, nodes2);
468 res->next = pairing_nodes_sorted_merge(nodes1, nodes2->next);
473 static void sort_pairing_nodes(FriBidiPairingNode **nodes)
475 FriBidiPairingNode *front, *back;
477 /* 0 or 1 node case */
478 if (!*nodes || !(*nodes)->next)
481 pairing_nodes_front_back_split(*nodes, &front, &back);
482 sort_pairing_nodes(&front);
483 sort_pairing_nodes(&back);
484 *nodes = pairing_nodes_sorted_merge(front, back);
487 static void free_pairing_nodes(FriBidiPairingNode *nodes)
491 FriBidiPairingNode *p = nodes;
497 FRIBIDI_ENTRY FriBidiLevel
498 fribidi_get_par_embedding_levels_ex (
500 const FriBidiCharType *bidi_types,
501 const FriBidiBracketType *bracket_types,
502 const FriBidiStrIndex len,
503 /* input and output */
504 FriBidiParType *pbase_dir,
506 FriBidiLevel *embedding_levels
509 FriBidiLevel base_level, max_level = 0;
510 FriBidiParType base_dir;
511 FriBidiRun *main_run_list = NULL, *explicits_list = NULL, *pp;
512 fribidi_boolean status = false;
513 int max_iso_level = 0;
522 DBG ("in fribidi_get_par_embedding_levels");
524 fribidi_assert (bidi_types);
525 fribidi_assert (pbase_dir);
526 fribidi_assert (embedding_levels);
528 /* Determinate character types */
530 /* Get run-length encoded character types */
531 main_run_list = run_list_encode_bidi_types (bidi_types, bracket_types, len);
533 (!main_run_list) goto out;
536 /* Find base level */
537 /* If no strong base_dir was found, resort to the weak direction
538 that was passed on input. */
539 base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir);
540 if (!FRIBIDI_IS_STRONG (*pbase_dir))
541 /* P2. P3. Search for first strong character and use its direction as
544 int valid_isolate_count = 0;
545 for_run_list (pp, main_run_list)
547 if (RL_TYPE(pp) == FRIBIDI_TYPE_PDI)
549 /* Ignore if there is no matching isolate */
550 if (valid_isolate_count>0)
551 valid_isolate_count--;
553 else if (FRIBIDI_IS_ISOLATE(RL_TYPE(pp)))
554 valid_isolate_count++;
555 else if (valid_isolate_count==0 && FRIBIDI_IS_LETTER (RL_TYPE (pp)))
557 base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp));
558 *pbase_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
563 base_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
564 DBG2 (" base level : %c", fribidi_char_from_level (base_level));
565 DBG2 (" base dir : %s", fribidi_get_bidi_type_name (base_dir));
569 (fribidi_debug_status ())
571 print_types_re (main_run_list);
575 /* Explicit Levels and Directions */
576 DBG ("explicit levels and directions");
578 FriBidiLevel level, new_level = 0;
579 int isolate_level = 0;
580 FriBidiCharType override, new_override;
582 int stack_size, over_pushed, first_interval;
583 int valid_isolate_count = 0;
584 int isolate_overflow = 0;
585 int isolate = 0; /* The isolate status flag */
588 FriBidiCharType override; /* only LTR, RTL and ON are valid */
592 } status_stack[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
593 FriBidiRun temp_link;
594 FriBidiRun *run_per_isolate_level[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
596 memset(run_per_isolate_level, 0, sizeof(run_per_isolate_level[0])
597 * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
599 /* explicits_list is a list like main_run_list, that holds the explicit
600 codes that are removed from main_run_list, to reinsert them later by
601 calling the shadow_run_list.
603 explicits_list = new_run_list ();
605 (!explicits_list) goto out;
607 /* X1. Begin by setting the current embedding level to the paragraph
608 embedding level. Set the directional override status to neutral,
609 and directional isolate status to false.
611 Process each character iteratively, applying rules X2 through X8.
612 Only embedding levels from 0 to 123 are valid in this phase. */
615 override = FRIBIDI_TYPE_ON;
620 valid_isolate_count = 0;
621 isolate_overflow = 0;
623 for_run_list (pp, main_run_list)
625 FriBidiCharType this_type = RL_TYPE (pp);
626 RL_ISOLATE_LEVEL (pp) = isolate_level;
628 if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type))
630 if (FRIBIDI_IS_STRONG (this_type))
631 { /* LRE, RLE, LRO, RLO */
632 /* 1. Explicit Embeddings */
633 /* X2. With each RLE, compute the least greater odd
635 /* X3. With each LRE, compute the least greater even
637 /* 2. Explicit Overrides */
638 /* X4. With each RLO, compute the least greater odd
640 /* X5. With each LRO, compute the least greater even
642 new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type);
643 for (i = RL_LEN (pp); i; i--)
646 ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) -
647 FRIBIDI_DIR_TO_LEVEL (this_type);
652 else if (this_type == FRIBIDI_TYPE_PDF)
654 /* 3. Terminating Embeddings and overrides */
655 /* X7. With each PDF, determine the matching embedding or
657 for (i = RL_LEN (pp); i; i--)
659 if (stack_size && status_stack[stack_size-1].isolate != 0)
665 /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */
666 /* Remove element and add it to explicits_list */
667 RL_LEVEL (pp) = FRIBIDI_SENTINEL;
668 temp_link.next = pp->next;
669 move_node_before (pp, explicits_list);
672 else if (this_type == FRIBIDI_TYPE_PDI)
673 /* X6a. pop the direction of the stack */
675 for (i = RL_LEN (pp); i; i--)
677 if (isolate_overflow > 0)
680 RL_LEVEL (pp) = level;
683 else if (valid_isolate_count > 0)
685 /* Pop away all LRE,RLE,LRO, RLO levels
686 from the stack, as these are implicitly
687 terminated by the PDI */
688 while (stack_size && !status_stack[stack_size-1].isolate)
690 over_pushed = 0; /* The PDI resets the overpushed! */
693 valid_isolate_count--;
694 RL_LEVEL (pp) = level;
695 RL_ISOLATE_LEVEL (pp) = isolate_level;
699 /* Ignore isolated PDI's by turning them into ON's */
700 RL_TYPE (pp) = FRIBIDI_TYPE_ON;
701 RL_LEVEL (pp) = level;
705 else if (FRIBIDI_IS_ISOLATE(this_type))
707 /* TBD support RL_LEN > 1 */
708 new_override = FRIBIDI_TYPE_ON;
710 if (this_type == FRIBIDI_TYPE_LRI)
711 new_level = level + 2 - (level%2);
712 else if (this_type == FRIBIDI_TYPE_RLI)
713 new_level = level + 1 + (level%2);
714 else if (this_type == FRIBIDI_TYPE_FSI)
716 /* Search for a local strong character until we
717 meet the corresponding PDI or the end of the
720 int isolate_count = 0;
721 int fsi_base_level = 0;
722 for_run_list (fsi_pp, pp)
724 if (RL_TYPE(fsi_pp) == FRIBIDI_TYPE_PDI)
727 if (valid_isolate_count < 0)
730 else if (FRIBIDI_IS_ISOLATE(RL_TYPE(fsi_pp)))
732 else if (isolate_count==0 && FRIBIDI_IS_LETTER (RL_TYPE (fsi_pp)))
734 fsi_base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (fsi_pp));
739 /* Same behavior like RLI and LRI above */
740 if (FRIBIDI_LEVEL_IS_RTL (fsi_base_level))
741 new_level = level + 1 + (level%2);
743 new_level = level + 2 - (level%2);
746 RL_LEVEL (pp) = level;
747 RL_ISOLATE_LEVEL (pp) = isolate_level;
748 if (isolate_level < FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1)
751 if (!FRIBIDI_IS_NEUTRAL (override))
752 RL_TYPE (pp) = override;
754 if (new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL)
756 valid_isolate_count++;
761 isolate_overflow += 1;
763 else if (this_type == FRIBIDI_TYPE_BS)
765 /* X8. All explicit directional embeddings and overrides are
766 completely terminated at the end of each paragraph. Paragraph
767 separators are not included in the embedding. */
772 /* X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
773 a. Set the level of the current character to the current
775 b. Whenever the directional override status is not neutral,
776 reset the current character type to the directional override
778 RL_LEVEL (pp) = level;
779 if (!FRIBIDI_IS_NEUTRAL (override))
780 RL_TYPE (pp) = override;
784 /* Build the isolate_level connections */
785 for_run_list (pp, main_run_list)
787 int isolate_level = RL_ISOLATE_LEVEL (pp);
788 if (run_per_isolate_level[isolate_level])
790 run_per_isolate_level[isolate_level]->next_isolate = pp;
791 pp->prev_isolate = run_per_isolate_level[isolate_level];
793 run_per_isolate_level[isolate_level] = pp;
796 /* Implementing X8. It has no effect on a single paragraph! */
798 override = FRIBIDI_TYPE_ON;
802 /* X10. The remaining rules are applied to each run of characters at the
803 same level. For each run, determine the start-of-level-run (sor) and
804 end-of-level-run (eor) type, either L or R. This depends on the
805 higher of the two levels on either side of the boundary (at the start
806 or end of the paragraph, the level of the 'other' run is the base
807 embedding level). If the higher level is odd, the type is R, otherwise
809 /* Resolving Implicit Levels can be done out of X10 loop, so only change
810 of Resolving Weak Types and Resolving Neutral Types is needed. */
812 compact_list (main_run_list);
816 (fribidi_debug_status ())
818 print_types_re (main_run_list);
819 print_bidi_string (bidi_types, len);
820 print_resolved_levels (main_run_list);
821 print_resolved_types (main_run_list);
825 /* 4. Resolving weak types. Also calculate the maximum isolate level */
827 DBG ("resolving weak types");
829 int last_strong_stack[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
830 FriBidiCharType prev_type_orig;
833 last_strong_stack[0] = base_dir;
835 for_run_list (pp, main_run_list)
837 register FriBidiCharType prev_type, this_type, next_type;
838 FriBidiRun *ppp_prev, *ppp_next;
841 ppp_prev = get_adjacent_run(pp, false, false);
842 ppp_next = get_adjacent_run(pp, true, false);
844 this_type = RL_TYPE (pp);
845 iso_level = RL_ISOLATE_LEVEL(pp);
847 if (iso_level > max_iso_level)
848 max_iso_level = iso_level;
850 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
851 prev_type = RL_TYPE(ppp_prev);
853 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
855 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
856 next_type = RL_TYPE(ppp_next);
858 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
860 if (FRIBIDI_IS_STRONG (prev_type))
861 last_strong_stack[iso_level] = prev_type;
864 Examine each non-spacing mark (NSM) in the level run, and change the
865 type of the NSM to the type of the previous character. If the NSM
866 is at the start of the level run, it will get the type of sor. */
867 /* Implementation note: it is important that if the previous character
868 is not sor, then we should merge this run with the previous,
869 because of rules like W5, that we assume all of a sequence of
870 adjacent ETs are in one FriBidiRun. */
871 if (this_type == FRIBIDI_TYPE_NSM)
873 /* New rule in Unicode 6.3 */
874 if (FRIBIDI_IS_ISOLATE (RL_TYPE (pp->prev)))
875 RL_TYPE(pp) = FRIBIDI_TYPE_ON;
877 if (RL_LEVEL (ppp_prev) == RL_LEVEL (pp))
879 if (ppp_prev == pp->prev)
880 pp = merge_with_prev (pp);
883 RL_TYPE (pp) = prev_type;
885 if (prev_type == next_type && RL_LEVEL (pp) == RL_LEVEL (pp->next))
887 if (ppp_next == pp->next)
888 pp = merge_with_prev (pp->next);
890 continue; /* As we know the next condition cannot be true. */
893 /* W2: European numbers. */
894 if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_AL)
896 RL_TYPE (pp) = FRIBIDI_TYPE_AN;
898 /* Resolving dependency of loops for rules W1 and W2, so we
899 can merge them in one loop. */
900 if (next_type == FRIBIDI_TYPE_NSM)
901 RL_TYPE (ppp_next) = FRIBIDI_TYPE_AN;
906 last_strong_stack[0] = base_dir;
908 /* Resolving dependency of loops for rules W4 and W5, W5 may
909 want to prevent W4 to take effect in the next turn, do this
912 /* Resolving dependency of loops for rules W4 and W5 with W7,
913 W7 may change an EN to L but it sets the prev_type_orig if needed,
914 so W4 and W5 in next turn can still do their works. */
915 prev_type_orig = FRIBIDI_TYPE_ON;
917 /* Each isolate level has its own memory of the last strong character */
918 for_run_list (pp, main_run_list)
920 register FriBidiCharType prev_type, this_type, next_type;
922 FriBidiRun *ppp_prev, *ppp_next;
924 this_type = RL_TYPE (pp);
925 iso_level = RL_ISOLATE_LEVEL(pp);
927 ppp_prev = get_adjacent_run(pp, false, false);
928 ppp_next = get_adjacent_run(pp, true, false);
930 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
931 prev_type = RL_TYPE(ppp_prev);
933 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
935 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
936 next_type = RL_TYPE(ppp_next);
938 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
940 if (FRIBIDI_IS_STRONG (prev_type))
941 last_strong_stack[iso_level] = prev_type;
945 /* W3: Change ALs to R. */
946 if (this_type == FRIBIDI_TYPE_AL)
948 RL_TYPE (pp) = FRIBIDI_TYPE_RTL;
950 prev_type_orig = FRIBIDI_TYPE_ON;
954 /* W4. A single european separator changes to a european number.
955 A single common separator between two numbers of the same type
956 changes to that type. */
958 && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type)
959 && FRIBIDI_IS_NUMBER (prev_type_orig)
960 && prev_type_orig == next_type
961 && (prev_type_orig == FRIBIDI_TYPE_EN
962 || this_type == FRIBIDI_TYPE_CS))
964 RL_TYPE (pp) = prev_type;
965 this_type = RL_TYPE (pp);
969 /* W5. A sequence of European terminators adjacent to European
970 numbers changes to All European numbers. */
971 if (this_type == FRIBIDI_TYPE_ET
972 && (prev_type_orig == FRIBIDI_TYPE_EN
973 || next_type == FRIBIDI_TYPE_EN))
975 RL_TYPE (pp) = FRIBIDI_TYPE_EN;
977 this_type = RL_TYPE (pp);
980 /* W6. Otherwise change separators and terminators to other neutral. */
981 if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type))
982 RL_TYPE (pp) = FRIBIDI_TYPE_ON;
984 /* W7. Change european numbers to L. */
985 if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_LTR)
987 RL_TYPE (pp) = FRIBIDI_TYPE_LTR;
988 prev_type_orig = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ?
989 FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON);
992 prev_type_orig = PREV_TYPE_OR_SOR (pp->next);
996 compact_neutrals (main_run_list);
1000 (fribidi_debug_status ())
1002 print_resolved_levels (main_run_list);
1003 print_resolved_types (main_run_list);
1007 /* 5. Resolving Neutral Types */
1009 DBG ("resolving neutral types - N0");
1011 /* BD16 - Build list of all pairs*/
1012 int num_iso_levels = max_iso_level + 1;
1013 FriBidiPairingNode *pairing_nodes = NULL;
1014 FriBidiRun *local_bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL][LOCAL_BRACKET_SIZE];
1015 FriBidiRun **bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
1016 int bracket_stack_size[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
1017 int last_level = RL_LEVEL(main_run_list);
1018 int last_iso_level = 0;
1020 memset(bracket_stack, 0, sizeof(bracket_stack[0])*num_iso_levels);
1021 memset(bracket_stack_size, 0, sizeof(bracket_stack_size[0])*num_iso_levels);
1023 /* populate the bracket_size. The first LOCAL_BRACKET_SIZE entries
1024 of the stack are one the stack. Allocate the rest of the entries.
1028 for (iso_level=0; iso_level < LOCAL_BRACKET_SIZE; iso_level++)
1029 bracket_stack[iso_level] = local_bracket_stack[iso_level];
1031 for (iso_level=LOCAL_BRACKET_SIZE; iso_level < num_iso_levels; iso_level++)
1032 bracket_stack[iso_level] = fribidi_malloc (sizeof (bracket_stack[0])
1033 * FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS);
1036 /* Build the bd16 pair stack. */
1037 for_run_list (pp, main_run_list)
1039 int level = RL_LEVEL(pp);
1040 int iso_level = RL_ISOLATE_LEVEL(pp);
1041 FriBidiBracketType brack_prop = RL_BRACKET_TYPE(pp);
1043 /* Interpret the isolating run sequence as such that they
1044 end at a change in the level, unless the iso_level has been
1046 if (level != last_level && last_iso_level == iso_level)
1047 bracket_stack_size[last_iso_level] = 0;
1049 if (brack_prop!= FRIBIDI_NO_BRACKET
1050 && RL_TYPE(pp)==FRIBIDI_TYPE_ON)
1052 if (FRIBIDI_IS_BRACKET_OPEN(brack_prop))
1054 if (bracket_stack_size[iso_level]==FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS)
1057 /* push onto the pair stack */
1058 bracket_stack[iso_level][bracket_stack_size[iso_level]++] = pp;
1062 int stack_idx = bracket_stack_size[iso_level] - 1;
1063 while (stack_idx >= 0)
1065 FriBidiBracketType se_brack_prop = RL_BRACKET_TYPE(bracket_stack[iso_level][stack_idx]);
1066 if (FRIBIDI_BRACKET_ID(se_brack_prop) == FRIBIDI_BRACKET_ID(brack_prop))
1068 bracket_stack_size[iso_level] = stack_idx;
1070 pairing_nodes = pairing_nodes_push(pairing_nodes,
1071 bracket_stack[iso_level][stack_idx],
1080 last_iso_level = iso_level;
1083 /* The list must now be sorted for the next algo to work! */
1084 sort_pairing_nodes(&pairing_nodes);
1088 (fribidi_debug_status ())
1090 print_pairing_nodes (pairing_nodes);
1096 FriBidiPairingNode *ppairs = pairing_nodes;
1099 int embedding_level = ppairs->open->level;
1101 /* Find matching strong. */
1102 fribidi_boolean found = false;
1104 for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
1106 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1108 /* Calculate level like in resolve implicit levels below to prevent
1109 embedded levels not to match the base_level */
1110 int this_level = RL_LEVEL (ppn) +
1111 (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1114 if (FRIBIDI_IS_STRONG (this_type) && this_level == embedding_level)
1116 RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = this_level%2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
1123 /* Search for any strong type preceding and within the bracket pair */
1126 /* Search for a preceding strong */
1127 int prec_strong_level = embedding_level; /* TBDov! Extract from Isolate level in effect */
1128 int iso_level = RL_ISOLATE_LEVEL(ppairs->open);
1129 for (ppn = ppairs->open->prev; ppn->type != FRIBIDI_TYPE_SENTINEL; ppn=ppn->prev)
1131 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1132 if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
1134 prec_strong_level = RL_LEVEL (ppn) +
1135 (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1141 for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
1143 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1144 if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
1146 /* By constraint this is opposite the embedding direction,
1147 since we did not match the N0b rule. We must now
1148 compare with the preceding strong to establish whether
1149 to apply N0c1 (opposite) or N0c2 embedding */
1150 RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = prec_strong_level % 2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
1157 ppairs = ppairs->next;
1160 free_pairing_nodes(pairing_nodes);
1162 if (num_iso_levels >= LOCAL_BRACKET_SIZE)
1165 /* Only need to free the non static members */
1166 for (i=LOCAL_BRACKET_SIZE; i<num_iso_levels; i++)
1167 fribidi_free(bracket_stack[i]);
1170 /* Remove the bracket property and re-compact */
1172 const FriBidiBracketType NoBracket = FRIBIDI_NO_BRACKET;
1173 for_run_list (pp, main_run_list)
1174 pp->bracket_type = NoBracket;
1175 compact_neutrals (main_run_list);
1181 (fribidi_debug_status ())
1183 print_resolved_levels (main_run_list);
1184 print_resolved_types (main_run_list);
1189 DBG ("resolving neutral types - N1+N2");
1191 for_run_list (pp, main_run_list)
1193 FriBidiCharType prev_type, this_type, next_type;
1194 FriBidiRun *ppp_prev, *ppp_next;
1196 ppp_prev = get_adjacent_run(pp, false, false);
1197 ppp_next = get_adjacent_run(pp, true, false);
1199 /* "European and Arabic numbers are treated as though they were R"
1200 FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */
1201 this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp));
1203 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
1204 prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_prev));
1206 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
1208 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
1209 next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_next));
1211 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
1213 if (FRIBIDI_IS_NEUTRAL (this_type))
1214 RL_TYPE (pp) = (prev_type == next_type) ?
1215 /* N1. */ prev_type :
1216 /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp);
1220 compact_list (main_run_list);
1224 (fribidi_debug_status ())
1226 print_resolved_levels (main_run_list);
1227 print_resolved_types (main_run_list);
1231 /* 6. Resolving implicit levels */
1232 DBG ("resolving implicit levels");
1234 max_level = base_level;
1236 for_run_list (pp, main_run_list)
1238 FriBidiCharType this_type;
1241 this_type = RL_TYPE (pp);
1242 level = RL_LEVEL (pp);
1246 if (FRIBIDI_IS_NUMBER (this_type))
1247 RL_LEVEL (pp) = (level + 2) & ~1;
1251 (FRIBIDI_LEVEL_IS_RTL (level) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1253 if (RL_LEVEL (pp) > max_level)
1254 max_level = RL_LEVEL (pp);
1258 compact_list (main_run_list);
1262 (fribidi_debug_status ())
1264 print_bidi_string (bidi_types, len);
1265 print_resolved_levels (main_run_list);
1266 print_resolved_types (main_run_list);
1270 /* Reinsert the explicit codes & BN's that are already removed, from the
1271 explicits_list to main_run_list. */
1272 DBG ("reinserting explicit codes");
1274 (explicits_list->next != explicits_list)
1276 register FriBidiRun *p;
1277 register fribidi_boolean stat =
1278 shadow_run_list (main_run_list, explicits_list, true);
1279 explicits_list = NULL;
1283 /* Set level of inserted explicit chars to that of their previous
1284 * char, such that they do not affect reordering. */
1285 p = main_run_list->next;
1286 if (p != main_run_list && p->level == FRIBIDI_SENTINEL)
1287 p->level = base_level;
1288 for_run_list (p, main_run_list) if (p->level == FRIBIDI_SENTINEL)
1289 p->level = p->prev->level;
1294 (fribidi_debug_status ())
1296 print_types_re (main_run_list);
1297 print_resolved_levels (main_run_list);
1298 print_resolved_types (main_run_list);
1302 DBG ("reset the embedding levels, 1, 2, 3.");
1304 register int j, state, pos;
1305 register FriBidiCharType char_type;
1306 register FriBidiRun *p, *q, *list;
1308 /* L1. Reset the embedding levels of some chars:
1309 1. segment separators,
1310 2. paragraph separators,
1311 3. any sequence of whitespace characters preceding a segment
1312 separator or paragraph separator, and
1313 4. any sequence of whitespace characters and/or isolate formatting
1314 characters at the end of the line.
1315 ... (to be continued in fribidi_reorder_line()). */
1316 list = new_run_list ();
1322 for (j = len - 1; j >= -1; j--)
1324 /* close up the open link at the end */
1326 char_type = bidi_types[j];
1328 char_type = FRIBIDI_TYPE_ON;
1329 if (!state && FRIBIDI_IS_SEPARATOR (char_type))
1335 !(FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS(char_type)
1336 || FRIBIDI_IS_ISOLATE(char_type)))
1343 free_run_list (list);
1349 p->level = base_level;
1350 move_node_before (p, q);
1355 (!shadow_run_list (main_run_list, list, false)) goto out;
1360 (fribidi_debug_status ())
1362 print_types_re (main_run_list);
1363 print_resolved_levels (main_run_list);
1364 print_resolved_types (main_run_list);
1369 FriBidiStrIndex pos = 0;
1370 for_run_list (pp, main_run_list)
1372 register FriBidiStrIndex l;
1373 register FriBidiLevel level = pp->level;
1374 for (l = pp->len; l; l--)
1375 embedding_levels[pos++] = level;
1382 DBG ("leaving fribidi_get_par_embedding_levels");
1385 free_run_list (main_run_list);
1387 (explicits_list) free_run_list (explicits_list);
1389 return status ? max_level + 1 : 0;
1394 bidi_string_reverse (
1396 const FriBidiStrIndex len
1401 fribidi_assert (str);
1403 for (i = 0; i < len / 2; i++)
1405 FriBidiChar tmp = str[i];
1406 str[i] = str[len - 1 - i];
1407 str[len - 1 - i] = tmp;
1412 index_array_reverse (
1413 FriBidiStrIndex *arr,
1414 const FriBidiStrIndex len
1419 fribidi_assert (arr);
1421 for (i = 0; i < len / 2; i++)
1423 FriBidiStrIndex tmp = arr[i];
1424 arr[i] = arr[len - 1 - i];
1425 arr[len - 1 - i] = tmp;
1430 FRIBIDI_ENTRY FriBidiLevel
1431 fribidi_reorder_line (
1433 FriBidiFlags flags, /* reorder flags */
1434 const FriBidiCharType *bidi_types,
1435 const FriBidiStrIndex len,
1436 const FriBidiStrIndex off,
1437 const FriBidiParType base_dir,
1438 /* input and output */
1439 FriBidiLevel *embedding_levels,
1440 FriBidiChar *visual_str,
1442 FriBidiStrIndex *map
1445 fribidi_boolean status = false;
1446 FriBidiLevel max_level = 0;
1455 DBG ("in fribidi_reorder_line");
1457 fribidi_assert (bidi_types);
1458 fribidi_assert (embedding_levels);
1460 DBG ("reset the embedding levels, 4. whitespace at the end of line");
1462 register FriBidiStrIndex i;
1464 /* L1. Reset the embedding levels of some chars:
1465 4. any sequence of white space characters at the end of the line. */
1466 for (i = off + len - 1; i >= off &&
1467 FRIBIDI_IS_EXPLICIT_OR_BN_OR_WS (bidi_types[i]); i--)
1468 embedding_levels[i] = FRIBIDI_DIR_TO_LEVEL (base_dir);
1471 /* 7. Reordering resolved levels */
1473 register FriBidiLevel level;
1474 register FriBidiStrIndex i;
1476 /* Reorder both the outstring and the order array */
1478 if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_REORDER_NSM))
1480 /* L3. Reorder NSMs. */
1481 for (i = off + len - 1; i >= off; i--)
1482 if (FRIBIDI_LEVEL_IS_RTL (embedding_levels[i])
1483 && bidi_types[i] == FRIBIDI_TYPE_NSM)
1485 register FriBidiStrIndex seq_end = i;
1486 level = embedding_levels[i];
1488 for (i--; i >= off &&
1489 FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM (bidi_types[i])
1490 && embedding_levels[i] == level; i--)
1493 if (i < off || embedding_levels[i] != level)
1496 DBG ("warning: NSM(s) at the beginning of level run");
1501 bidi_string_reverse (visual_str + i, seq_end - i + 1);
1505 index_array_reverse (map + i, seq_end - i + 1);
1510 /* Find max_level of the line. We don't reuse the paragraph
1511 * max_level, both for a cleaner API, and that the line max_level
1512 * may be far less than paragraph max_level. */
1513 for (i = off + len - 1; i >= off; i--)
1514 if (embedding_levels[i] > max_level)
1515 max_level = embedding_levels[i];
1518 for (level = max_level; level > 0; level--)
1519 for (i = off + len - 1; i >= off; i--)
1520 if (embedding_levels[i] >= level)
1522 /* Find all stretches that are >= level_idx */
1523 register FriBidiStrIndex seq_end = i;
1524 for (i--; i >= off && embedding_levels[i] >= level; i--)
1528 bidi_string_reverse (visual_str + i + 1, seq_end - i);
1530 index_array_reverse (map + i + 1, seq_end - i);
1540 return status ? max_level + 1 : 0;
1543 /* Editor directions:
1544 * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent