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];
595 int prev_isolate_level = 0; /* When running over the isolate levels, remember the previous level */
597 memset(run_per_isolate_level, 0, sizeof(run_per_isolate_level[0])
598 * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
600 /* explicits_list is a list like main_run_list, that holds the explicit
601 codes that are removed from main_run_list, to reinsert them later by
602 calling the shadow_run_list.
604 explicits_list = new_run_list ();
606 (!explicits_list) goto out;
608 /* X1. Begin by setting the current embedding level to the paragraph
609 embedding level. Set the directional override status to neutral,
610 and directional isolate status to false.
612 Process each character iteratively, applying rules X2 through X8.
613 Only embedding levels from 0 to 123 are valid in this phase. */
616 override = FRIBIDI_TYPE_ON;
621 valid_isolate_count = 0;
622 isolate_overflow = 0;
624 for_run_list (pp, main_run_list)
626 FriBidiCharType this_type = RL_TYPE (pp);
627 RL_ISOLATE_LEVEL (pp) = isolate_level;
629 if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type))
631 if (FRIBIDI_IS_STRONG (this_type))
632 { /* LRE, RLE, LRO, RLO */
633 /* 1. Explicit Embeddings */
634 /* X2. With each RLE, compute the least greater odd
636 /* X3. With each LRE, compute the least greater even
638 /* 2. Explicit Overrides */
639 /* X4. With each RLO, compute the least greater odd
641 /* X5. With each LRO, compute the least greater even
643 new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type);
644 for (i = RL_LEN (pp); i; i--)
647 ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) -
648 FRIBIDI_DIR_TO_LEVEL (this_type);
653 else if (this_type == FRIBIDI_TYPE_PDF)
655 /* 3. Terminating Embeddings and overrides */
656 /* X7. With each PDF, determine the matching embedding or
658 for (i = RL_LEN (pp); i; i--)
660 if (stack_size && status_stack[stack_size-1].isolate != 0)
666 /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */
667 /* Remove element and add it to explicits_list */
668 RL_LEVEL (pp) = FRIBIDI_SENTINEL;
669 temp_link.next = pp->next;
670 move_node_before (pp, explicits_list);
673 else if (this_type == FRIBIDI_TYPE_PDI)
674 /* X6a. pop the direction of the stack */
676 for (i = RL_LEN (pp); i; i--)
678 if (isolate_overflow > 0)
681 RL_LEVEL (pp) = level;
684 else if (valid_isolate_count > 0)
686 /* Pop away all LRE,RLE,LRO, RLO levels
687 from the stack, as these are implicitly
688 terminated by the PDI */
689 while (stack_size && !status_stack[stack_size-1].isolate)
691 over_pushed = 0; /* The PDI resets the overpushed! */
694 valid_isolate_count--;
695 RL_LEVEL (pp) = level;
696 RL_ISOLATE_LEVEL (pp) = isolate_level;
700 /* Ignore isolated PDI's by turning them into ON's */
701 RL_TYPE (pp) = FRIBIDI_TYPE_ON;
702 RL_LEVEL (pp) = level;
706 else if (FRIBIDI_IS_ISOLATE(this_type))
708 /* TBD support RL_LEN > 1 */
709 new_override = FRIBIDI_TYPE_ON;
711 if (this_type == FRIBIDI_TYPE_LRI)
712 new_level = level + 2 - (level%2);
713 else if (this_type == FRIBIDI_TYPE_RLI)
714 new_level = level + 1 + (level%2);
715 else if (this_type == FRIBIDI_TYPE_FSI)
717 /* Search for a local strong character until we
718 meet the corresponding PDI or the end of the
721 int isolate_count = 0;
722 int fsi_base_level = 0;
723 for_run_list (fsi_pp, pp)
725 if (RL_TYPE(fsi_pp) == FRIBIDI_TYPE_PDI)
728 if (valid_isolate_count < 0)
731 else if (FRIBIDI_IS_ISOLATE(RL_TYPE(fsi_pp)))
733 else if (isolate_count==0 && FRIBIDI_IS_LETTER (RL_TYPE (fsi_pp)))
735 fsi_base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (fsi_pp));
740 /* Same behavior like RLI and LRI above */
741 if (FRIBIDI_LEVEL_IS_RTL (fsi_base_level))
742 new_level = level + 1 + (level%2);
744 new_level = level + 2 - (level%2);
747 RL_LEVEL (pp) = level;
748 RL_ISOLATE_LEVEL (pp) = isolate_level;
749 if (isolate_level < FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1)
752 if (!FRIBIDI_IS_NEUTRAL (override))
753 RL_TYPE (pp) = override;
755 if (new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL)
757 valid_isolate_count++;
762 isolate_overflow += 1;
764 else if (this_type == FRIBIDI_TYPE_BS)
766 /* X8. All explicit directional embeddings and overrides are
767 completely terminated at the end of each paragraph. Paragraph
768 separators are not included in the embedding. */
773 /* X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
774 a. Set the level of the current character to the current
776 b. Whenever the directional override status is not neutral,
777 reset the current character type to the directional override
779 RL_LEVEL (pp) = level;
780 if (!FRIBIDI_IS_NEUTRAL (override))
781 RL_TYPE (pp) = override;
785 /* Build the isolate_level connections */
786 prev_isolate_level = 0;
787 for_run_list (pp, main_run_list)
789 int isolate_level = RL_ISOLATE_LEVEL (pp);
792 /* When going from an upper to a lower level, zero out all higher levels
793 in order not erroneous connections! */
794 if (isolate_level<prev_isolate_level)
795 for (i=isolate_level+1; i<=prev_isolate_level; i++)
796 run_per_isolate_level[i]=0;
797 prev_isolate_level = isolate_level;
799 if (run_per_isolate_level[isolate_level])
801 run_per_isolate_level[isolate_level]->next_isolate = pp;
802 pp->prev_isolate = run_per_isolate_level[isolate_level];
804 run_per_isolate_level[isolate_level] = pp;
807 /* Implementing X8. It has no effect on a single paragraph! */
809 override = FRIBIDI_TYPE_ON;
813 /* X10. The remaining rules are applied to each run of characters at the
814 same level. For each run, determine the start-of-level-run (sor) and
815 end-of-level-run (eor) type, either L or R. This depends on the
816 higher of the two levels on either side of the boundary (at the start
817 or end of the paragraph, the level of the 'other' run is the base
818 embedding level). If the higher level is odd, the type is R, otherwise
820 /* Resolving Implicit Levels can be done out of X10 loop, so only change
821 of Resolving Weak Types and Resolving Neutral Types is needed. */
823 compact_list (main_run_list);
827 (fribidi_debug_status ())
829 print_types_re (main_run_list);
830 print_bidi_string (bidi_types, len);
831 print_resolved_levels (main_run_list);
832 print_resolved_types (main_run_list);
836 /* 4. Resolving weak types. Also calculate the maximum isolate level */
838 DBG ("4a. resolving weak types");
840 int last_strong_stack[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
841 FriBidiCharType prev_type_orig;
844 last_strong_stack[0] = base_dir;
846 for_run_list (pp, main_run_list)
848 register FriBidiCharType prev_type, this_type, next_type;
849 FriBidiRun *ppp_prev, *ppp_next;
852 ppp_prev = get_adjacent_run(pp, false, false);
853 ppp_next = get_adjacent_run(pp, true, false);
855 this_type = RL_TYPE (pp);
856 iso_level = RL_ISOLATE_LEVEL(pp);
858 if (iso_level > max_iso_level)
859 max_iso_level = iso_level;
861 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
862 prev_type = RL_TYPE(ppp_prev);
864 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
866 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
867 next_type = RL_TYPE(ppp_next);
869 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
871 if (FRIBIDI_IS_STRONG (prev_type))
872 last_strong_stack[iso_level] = prev_type;
875 Examine each non-spacing mark (NSM) in the level run, and change the
876 type of the NSM to the type of the previous character. If the NSM
877 is at the start of the level run, it will get the type of sor. */
878 /* Implementation note: it is important that if the previous character
879 is not sor, then we should merge this run with the previous,
880 because of rules like W5, that we assume all of a sequence of
881 adjacent ETs are in one FriBidiRun. */
882 if (this_type == FRIBIDI_TYPE_NSM)
884 /* New rule in Unicode 6.3 */
885 if (FRIBIDI_IS_ISOLATE (RL_TYPE (pp->prev)))
886 RL_TYPE(pp) = FRIBIDI_TYPE_ON;
888 if (RL_LEVEL (ppp_prev) == RL_LEVEL (pp))
890 if (ppp_prev == pp->prev)
891 pp = merge_with_prev (pp);
894 RL_TYPE (pp) = prev_type;
896 if (prev_type == next_type && RL_LEVEL (pp) == RL_LEVEL (pp->next))
898 if (ppp_next == pp->next)
899 pp = merge_with_prev (pp->next);
901 continue; /* As we know the next condition cannot be true. */
904 /* W2: European numbers. */
905 if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_AL)
907 RL_TYPE (pp) = FRIBIDI_TYPE_AN;
909 /* Resolving dependency of loops for rules W1 and W2, so we
910 can merge them in one loop. */
911 if (next_type == FRIBIDI_TYPE_NSM)
912 RL_TYPE (ppp_next) = FRIBIDI_TYPE_AN;
918 (fribidi_debug_status ())
920 print_resolved_levels (main_run_list);
921 print_resolved_types (main_run_list);
925 /* The last iso level is used to invalidate the the last strong values when going from
926 a higher to a lower iso level. When this occur, all "last_strong" values are
927 set to the base_dir. */
928 last_strong_stack[0] = base_dir;
930 DBG ("4b. resolving weak types. W4 and W5");
932 /* Resolving dependency of loops for rules W4 and W5, W5 may
933 want to prevent W4 to take effect in the next turn, do this
936 /* Resolving dependency of loops for rules W4 and W5 with W7,
937 W7 may change an EN to L but it sets the prev_type_orig if needed,
938 so W4 and W5 in next turn can still do their works. */
939 prev_type_orig = FRIBIDI_TYPE_ON;
941 /* Each isolate level has its own memory of the last strong character */
942 for_run_list (pp, main_run_list)
944 register FriBidiCharType prev_type, this_type, next_type;
946 FriBidiRun *ppp_prev, *ppp_next;
948 this_type = RL_TYPE (pp);
949 iso_level = RL_ISOLATE_LEVEL(pp);
951 ppp_prev = get_adjacent_run(pp, false, false);
952 ppp_next = get_adjacent_run(pp, true, false);
954 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
955 prev_type = RL_TYPE(ppp_prev);
957 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
959 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
960 next_type = RL_TYPE(ppp_next);
962 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
964 if (FRIBIDI_IS_STRONG (prev_type))
965 last_strong_stack[iso_level] = prev_type;
969 /* W3: Change ALs to R. */
970 if (this_type == FRIBIDI_TYPE_AL)
972 RL_TYPE (pp) = FRIBIDI_TYPE_RTL;
974 prev_type_orig = FRIBIDI_TYPE_ON;
978 /* W4. A single european separator changes to a european number.
979 A single common separator between two numbers of the same type
980 changes to that type. */
982 && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type)
983 && FRIBIDI_IS_NUMBER (prev_type_orig)
984 && prev_type_orig == next_type
985 && (prev_type_orig == FRIBIDI_TYPE_EN
986 || this_type == FRIBIDI_TYPE_CS))
988 RL_TYPE (pp) = prev_type;
989 this_type = RL_TYPE (pp);
993 /* W5. A sequence of European terminators adjacent to European
994 numbers changes to All European numbers. */
995 if (this_type == FRIBIDI_TYPE_ET
996 && (prev_type_orig == FRIBIDI_TYPE_EN
997 || next_type == FRIBIDI_TYPE_EN))
999 RL_TYPE (pp) = FRIBIDI_TYPE_EN;
1001 this_type = RL_TYPE (pp);
1004 /* W6. Otherwise change separators and terminators to other neutral. */
1005 if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type))
1006 RL_TYPE (pp) = FRIBIDI_TYPE_ON;
1008 /* W7. Change european numbers to L. */
1009 if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_LTR)
1011 RL_TYPE (pp) = FRIBIDI_TYPE_LTR;
1012 prev_type_orig = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ?
1013 FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON);
1016 prev_type_orig = PREV_TYPE_OR_SOR (pp->next);
1020 compact_neutrals (main_run_list);
1024 (fribidi_debug_status ())
1026 print_resolved_levels (main_run_list);
1027 print_resolved_types (main_run_list);
1031 /* 5. Resolving Neutral Types */
1033 DBG ("5. resolving neutral types - N0");
1035 /* BD16 - Build list of all pairs*/
1036 int num_iso_levels = max_iso_level + 1;
1037 FriBidiPairingNode *pairing_nodes = NULL;
1038 FriBidiRun *local_bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL][LOCAL_BRACKET_SIZE];
1039 FriBidiRun **bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
1040 int bracket_stack_size[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
1041 int last_level = RL_LEVEL(main_run_list);
1042 int last_iso_level = 0;
1044 memset(bracket_stack, 0, sizeof(bracket_stack[0])*num_iso_levels);
1045 memset(bracket_stack_size, 0, sizeof(bracket_stack_size[0])*num_iso_levels);
1047 /* populate the bracket_size. The first LOCAL_BRACKET_SIZE entries
1048 of the stack are one the stack. Allocate the rest of the entries.
1052 for (iso_level=0; iso_level < LOCAL_BRACKET_SIZE; iso_level++)
1053 bracket_stack[iso_level] = local_bracket_stack[iso_level];
1055 for (iso_level=LOCAL_BRACKET_SIZE; iso_level < num_iso_levels; iso_level++)
1056 bracket_stack[iso_level] = fribidi_malloc (sizeof (bracket_stack[0])
1057 * FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS);
1060 /* Build the bd16 pair stack. */
1061 for_run_list (pp, main_run_list)
1063 int level = RL_LEVEL(pp);
1064 int iso_level = RL_ISOLATE_LEVEL(pp);
1065 FriBidiBracketType brack_prop = RL_BRACKET_TYPE(pp);
1067 /* Interpret the isolating run sequence as such that they
1068 end at a change in the level, unless the iso_level has been
1070 if (level != last_level && last_iso_level == iso_level)
1071 bracket_stack_size[last_iso_level] = 0;
1073 if (brack_prop!= FRIBIDI_NO_BRACKET
1074 && RL_TYPE(pp)==FRIBIDI_TYPE_ON)
1076 if (FRIBIDI_IS_BRACKET_OPEN(brack_prop))
1078 if (bracket_stack_size[iso_level]==FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS)
1081 /* push onto the pair stack */
1082 bracket_stack[iso_level][bracket_stack_size[iso_level]++] = pp;
1086 int stack_idx = bracket_stack_size[iso_level] - 1;
1087 while (stack_idx >= 0)
1089 FriBidiBracketType se_brack_prop = RL_BRACKET_TYPE(bracket_stack[iso_level][stack_idx]);
1090 if (FRIBIDI_BRACKET_ID(se_brack_prop) == FRIBIDI_BRACKET_ID(brack_prop))
1092 bracket_stack_size[iso_level] = stack_idx;
1094 pairing_nodes = pairing_nodes_push(pairing_nodes,
1095 bracket_stack[iso_level][stack_idx],
1104 last_iso_level = iso_level;
1107 /* The list must now be sorted for the next algo to work! */
1108 sort_pairing_nodes(&pairing_nodes);
1112 (fribidi_debug_status ())
1114 print_pairing_nodes (pairing_nodes);
1120 FriBidiPairingNode *ppairs = pairing_nodes;
1123 int embedding_level = ppairs->open->level;
1125 /* Find matching strong. */
1126 fribidi_boolean found = false;
1128 for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
1130 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1132 /* Calculate level like in resolve implicit levels below to prevent
1133 embedded levels not to match the base_level */
1134 int this_level = RL_LEVEL (ppn) +
1135 (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1138 if (FRIBIDI_IS_STRONG (this_type) && this_level == embedding_level)
1140 RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = this_level%2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
1147 /* Search for any strong type preceding and within the bracket pair */
1150 /* Search for a preceding strong */
1151 int prec_strong_level = embedding_level; /* TBDov! Extract from Isolate level in effect */
1152 int iso_level = RL_ISOLATE_LEVEL(ppairs->open);
1153 for (ppn = ppairs->open->prev; ppn->type != FRIBIDI_TYPE_SENTINEL; ppn=ppn->prev)
1155 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1156 if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
1158 prec_strong_level = RL_LEVEL (ppn) +
1159 (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1165 for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
1167 FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
1168 if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
1170 /* By constraint this is opposite the embedding direction,
1171 since we did not match the N0b rule. We must now
1172 compare with the preceding strong to establish whether
1173 to apply N0c1 (opposite) or N0c2 embedding */
1174 RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = prec_strong_level % 2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
1181 ppairs = ppairs->next;
1184 free_pairing_nodes(pairing_nodes);
1186 if (num_iso_levels >= LOCAL_BRACKET_SIZE)
1189 /* Only need to free the non static members */
1190 for (i=LOCAL_BRACKET_SIZE; i<num_iso_levels; i++)
1191 fribidi_free(bracket_stack[i]);
1194 /* Remove the bracket property and re-compact */
1196 const FriBidiBracketType NoBracket = FRIBIDI_NO_BRACKET;
1197 for_run_list (pp, main_run_list)
1198 pp->bracket_type = NoBracket;
1199 compact_neutrals (main_run_list);
1205 (fribidi_debug_status ())
1207 print_resolved_levels (main_run_list);
1208 print_resolved_types (main_run_list);
1213 DBG ("resolving neutral types - N1+N2");
1215 for_run_list (pp, main_run_list)
1217 FriBidiCharType prev_type, this_type, next_type;
1218 FriBidiRun *ppp_prev, *ppp_next;
1220 ppp_prev = get_adjacent_run(pp, false, false);
1221 ppp_next = get_adjacent_run(pp, true, false);
1223 /* "European and Arabic numbers are treated as though they were R"
1224 FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */
1225 this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp));
1227 if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
1228 prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_prev));
1230 prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
1232 if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
1233 next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_next));
1235 next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
1237 if (FRIBIDI_IS_NEUTRAL (this_type))
1238 RL_TYPE (pp) = (prev_type == next_type) ?
1239 /* N1. */ prev_type :
1240 /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp);
1244 compact_list (main_run_list);
1248 (fribidi_debug_status ())
1250 print_resolved_levels (main_run_list);
1251 print_resolved_types (main_run_list);
1255 /* 6. Resolving implicit levels */
1256 DBG ("resolving implicit levels");
1258 max_level = base_level;
1260 for_run_list (pp, main_run_list)
1262 FriBidiCharType this_type;
1265 this_type = RL_TYPE (pp);
1266 level = RL_LEVEL (pp);
1270 if (FRIBIDI_IS_NUMBER (this_type))
1271 RL_LEVEL (pp) = (level + 2) & ~1;
1275 (FRIBIDI_LEVEL_IS_RTL (level) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
1277 if (RL_LEVEL (pp) > max_level)
1278 max_level = RL_LEVEL (pp);
1282 compact_list (main_run_list);
1286 (fribidi_debug_status ())
1288 print_bidi_string (bidi_types, len);
1289 print_resolved_levels (main_run_list);
1290 print_resolved_types (main_run_list);
1294 /* Reinsert the explicit codes & BN's that are already removed, from the
1295 explicits_list to main_run_list. */
1296 DBG ("reinserting explicit codes");
1298 (explicits_list->next != explicits_list)
1300 register FriBidiRun *p;
1301 register fribidi_boolean stat =
1302 shadow_run_list (main_run_list, explicits_list, true);
1303 explicits_list = NULL;
1307 /* Set level of inserted explicit chars to that of their previous
1308 * char, such that they do not affect reordering. */
1309 p = main_run_list->next;
1310 if (p != main_run_list && p->level == FRIBIDI_SENTINEL)
1311 p->level = base_level;
1312 for_run_list (p, main_run_list) if (p->level == FRIBIDI_SENTINEL)
1313 p->level = p->prev->level;
1318 (fribidi_debug_status ())
1320 print_types_re (main_run_list);
1321 print_resolved_levels (main_run_list);
1322 print_resolved_types (main_run_list);
1326 DBG ("reset the embedding levels, 1, 2, 3.");
1328 register int j, state, pos;
1329 register FriBidiCharType char_type;
1330 register FriBidiRun *p, *q, *list;
1332 /* L1. Reset the embedding levels of some chars:
1333 1. segment separators,
1334 2. paragraph separators,
1335 3. any sequence of whitespace characters preceding a segment
1336 separator or paragraph separator, and
1337 4. any sequence of whitespace characters and/or isolate formatting
1338 characters at the end of the line.
1339 ... (to be continued in fribidi_reorder_line()). */
1340 list = new_run_list ();
1346 for (j = len - 1; j >= -1; j--)
1348 /* close up the open link at the end */
1350 char_type = bidi_types[j];
1352 char_type = FRIBIDI_TYPE_ON;
1353 if (!state && FRIBIDI_IS_SEPARATOR (char_type))
1359 !(FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS(char_type)
1360 || FRIBIDI_IS_ISOLATE(char_type)))
1367 free_run_list (list);
1373 p->level = base_level;
1374 move_node_before (p, q);
1379 (!shadow_run_list (main_run_list, list, false)) goto out;
1384 (fribidi_debug_status ())
1386 print_types_re (main_run_list);
1387 print_resolved_levels (main_run_list);
1388 print_resolved_types (main_run_list);
1393 FriBidiStrIndex pos = 0;
1394 for_run_list (pp, main_run_list)
1396 register FriBidiStrIndex l;
1397 register FriBidiLevel level = pp->level;
1398 for (l = pp->len; l; l--)
1399 embedding_levels[pos++] = level;
1406 DBG ("leaving fribidi_get_par_embedding_levels");
1409 free_run_list (main_run_list);
1411 (explicits_list) free_run_list (explicits_list);
1413 return status ? max_level + 1 : 0;
1418 bidi_string_reverse (
1420 const FriBidiStrIndex len
1425 fribidi_assert (str);
1427 for (i = 0; i < len / 2; i++)
1429 FriBidiChar tmp = str[i];
1430 str[i] = str[len - 1 - i];
1431 str[len - 1 - i] = tmp;
1436 index_array_reverse (
1437 FriBidiStrIndex *arr,
1438 const FriBidiStrIndex len
1443 fribidi_assert (arr);
1445 for (i = 0; i < len / 2; i++)
1447 FriBidiStrIndex tmp = arr[i];
1448 arr[i] = arr[len - 1 - i];
1449 arr[len - 1 - i] = tmp;
1454 FRIBIDI_ENTRY FriBidiLevel
1455 fribidi_reorder_line (
1457 FriBidiFlags flags, /* reorder flags */
1458 const FriBidiCharType *bidi_types,
1459 const FriBidiStrIndex len,
1460 const FriBidiStrIndex off,
1461 const FriBidiParType base_dir,
1462 /* input and output */
1463 FriBidiLevel *embedding_levels,
1464 FriBidiChar *visual_str,
1466 FriBidiStrIndex *map
1469 fribidi_boolean status = false;
1470 FriBidiLevel max_level = 0;
1479 DBG ("in fribidi_reorder_line");
1481 fribidi_assert (bidi_types);
1482 fribidi_assert (embedding_levels);
1484 DBG ("reset the embedding levels, 4. whitespace at the end of line");
1486 register FriBidiStrIndex i;
1488 /* L1. Reset the embedding levels of some chars:
1489 4. any sequence of white space characters at the end of the line. */
1490 for (i = off + len - 1; i >= off &&
1491 FRIBIDI_IS_EXPLICIT_OR_BN_OR_WS (bidi_types[i]); i--)
1492 embedding_levels[i] = FRIBIDI_DIR_TO_LEVEL (base_dir);
1495 /* 7. Reordering resolved levels */
1497 register FriBidiLevel level;
1498 register FriBidiStrIndex i;
1500 /* Reorder both the outstring and the order array */
1502 if (FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_REORDER_NSM))
1504 /* L3. Reorder NSMs. */
1505 for (i = off + len - 1; i >= off; i--)
1506 if (FRIBIDI_LEVEL_IS_RTL (embedding_levels[i])
1507 && bidi_types[i] == FRIBIDI_TYPE_NSM)
1509 register FriBidiStrIndex seq_end = i;
1510 level = embedding_levels[i];
1512 for (i--; i >= off &&
1513 FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM (bidi_types[i])
1514 && embedding_levels[i] == level; i--)
1517 if (i < off || embedding_levels[i] != level)
1520 DBG ("warning: NSM(s) at the beginning of level run");
1525 bidi_string_reverse (visual_str + i, seq_end - i + 1);
1529 index_array_reverse (map + i, seq_end - i + 1);
1534 /* Find max_level of the line. We don't reuse the paragraph
1535 * max_level, both for a cleaner API, and that the line max_level
1536 * may be far less than paragraph max_level. */
1537 for (i = off + len - 1; i >= off; i--)
1538 if (embedding_levels[i] > max_level)
1539 max_level = embedding_levels[i];
1542 for (level = max_level; level > 0; level--)
1543 for (i = off + len - 1; i >= off; i--)
1544 if (embedding_levels[i] >= level)
1546 /* Find all stretches that are >= level_idx */
1547 register FriBidiStrIndex seq_end = i;
1548 for (i--; i >= off && embedding_levels[i] >= level; i--)
1552 bidi_string_reverse (visual_str + i + 1, seq_end - i);
1554 index_array_reverse (map + i + 1, seq_end - i);
1564 return status ? max_level + 1 : 0;
1567 /* Editor directions:
1568 * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent