xref: /aosp_15_r20/external/icu/libicu/cts_headers/ubidiimp.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker ******************************************************************************
5*0e209d39SAndroid Build Coastguard Worker *
6*0e209d39SAndroid Build Coastguard Worker *   Copyright (C) 1999-2016, International Business Machines
7*0e209d39SAndroid Build Coastguard Worker *   Corporation and others.  All Rights Reserved.
8*0e209d39SAndroid Build Coastguard Worker *
9*0e209d39SAndroid Build Coastguard Worker ******************************************************************************
10*0e209d39SAndroid Build Coastguard Worker *   file name:  ubidiimp.h
11*0e209d39SAndroid Build Coastguard Worker *   encoding:   UTF-8
12*0e209d39SAndroid Build Coastguard Worker *   tab size:   8 (not used)
13*0e209d39SAndroid Build Coastguard Worker *   indentation:4
14*0e209d39SAndroid Build Coastguard Worker *
15*0e209d39SAndroid Build Coastguard Worker *   created on: 1999aug06
16*0e209d39SAndroid Build Coastguard Worker *   created by: Markus W. Scherer, updated by Matitiahu Allouche
17*0e209d39SAndroid Build Coastguard Worker */
18*0e209d39SAndroid Build Coastguard Worker 
19*0e209d39SAndroid Build Coastguard Worker #ifndef UBIDIIMP_H
20*0e209d39SAndroid Build Coastguard Worker #define UBIDIIMP_H
21*0e209d39SAndroid Build Coastguard Worker 
22*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
23*0e209d39SAndroid Build Coastguard Worker #include "unicode/ubidi.h"
24*0e209d39SAndroid Build Coastguard Worker #include "unicode/uchar.h"
25*0e209d39SAndroid Build Coastguard Worker #include "ubidi_props.h"
26*0e209d39SAndroid Build Coastguard Worker 
27*0e209d39SAndroid Build Coastguard Worker /* miscellaneous definitions ---------------------------------------------- */
28*0e209d39SAndroid Build Coastguard Worker 
29*0e209d39SAndroid Build Coastguard Worker // ICU-20853=ICU-20935 Solaris #defines CS and ES in sys/regset.h
30*0e209d39SAndroid Build Coastguard Worker #ifdef CS
31*0e209d39SAndroid Build Coastguard Worker #   undef CS
32*0e209d39SAndroid Build Coastguard Worker #endif
33*0e209d39SAndroid Build Coastguard Worker #ifdef ES
34*0e209d39SAndroid Build Coastguard Worker #   undef ES
35*0e209d39SAndroid Build Coastguard Worker #endif
36*0e209d39SAndroid Build Coastguard Worker 
37*0e209d39SAndroid Build Coastguard Worker typedef uint8_t DirProp;
38*0e209d39SAndroid Build Coastguard Worker typedef uint32_t Flags;
39*0e209d39SAndroid Build Coastguard Worker 
40*0e209d39SAndroid Build Coastguard Worker /*  Comparing the description of the BiDi algorithm with this implementation
41*0e209d39SAndroid Build Coastguard Worker     is easier with the same names for the BiDi types in the code as there.
42*0e209d39SAndroid Build Coastguard Worker     See UCharDirection in uchar.h .
43*0e209d39SAndroid Build Coastguard Worker */
44*0e209d39SAndroid Build Coastguard Worker enum {
45*0e209d39SAndroid Build Coastguard Worker     L=  U_LEFT_TO_RIGHT,                /*  0 */
46*0e209d39SAndroid Build Coastguard Worker     R=  U_RIGHT_TO_LEFT,                /*  1 */
47*0e209d39SAndroid Build Coastguard Worker     EN= U_EUROPEAN_NUMBER,              /*  2 */
48*0e209d39SAndroid Build Coastguard Worker     ES= U_EUROPEAN_NUMBER_SEPARATOR,    /*  3 */
49*0e209d39SAndroid Build Coastguard Worker     ET= U_EUROPEAN_NUMBER_TERMINATOR,   /*  4 */
50*0e209d39SAndroid Build Coastguard Worker     AN= U_ARABIC_NUMBER,                /*  5 */
51*0e209d39SAndroid Build Coastguard Worker     CS= U_COMMON_NUMBER_SEPARATOR,      /*  6 */
52*0e209d39SAndroid Build Coastguard Worker     B=  U_BLOCK_SEPARATOR,              /*  7 */
53*0e209d39SAndroid Build Coastguard Worker     S=  U_SEGMENT_SEPARATOR,            /*  8 */
54*0e209d39SAndroid Build Coastguard Worker     WS= U_WHITE_SPACE_NEUTRAL,          /*  9 */
55*0e209d39SAndroid Build Coastguard Worker     ON= U_OTHER_NEUTRAL,                /* 10 */
56*0e209d39SAndroid Build Coastguard Worker     LRE=U_LEFT_TO_RIGHT_EMBEDDING,      /* 11 */
57*0e209d39SAndroid Build Coastguard Worker     LRO=U_LEFT_TO_RIGHT_OVERRIDE,       /* 12 */
58*0e209d39SAndroid Build Coastguard Worker     AL= U_RIGHT_TO_LEFT_ARABIC,         /* 13 */
59*0e209d39SAndroid Build Coastguard Worker     RLE=U_RIGHT_TO_LEFT_EMBEDDING,      /* 14 */
60*0e209d39SAndroid Build Coastguard Worker     RLO=U_RIGHT_TO_LEFT_OVERRIDE,       /* 15 */
61*0e209d39SAndroid Build Coastguard Worker     PDF=U_POP_DIRECTIONAL_FORMAT,       /* 16 */
62*0e209d39SAndroid Build Coastguard Worker     NSM=U_DIR_NON_SPACING_MARK,         /* 17 */
63*0e209d39SAndroid Build Coastguard Worker     BN= U_BOUNDARY_NEUTRAL,             /* 18 */
64*0e209d39SAndroid Build Coastguard Worker     FSI=U_FIRST_STRONG_ISOLATE,         /* 19 */
65*0e209d39SAndroid Build Coastguard Worker     LRI=U_LEFT_TO_RIGHT_ISOLATE,        /* 20 */
66*0e209d39SAndroid Build Coastguard Worker     RLI=U_RIGHT_TO_LEFT_ISOLATE,        /* 21 */
67*0e209d39SAndroid Build Coastguard Worker     PDI=U_POP_DIRECTIONAL_ISOLATE,      /* 22 */
68*0e209d39SAndroid Build Coastguard Worker     ENL,    /* EN after W7 */           /* 23 */
69*0e209d39SAndroid Build Coastguard Worker     ENR,    /* EN not subject to W7 */  /* 24 */
70*0e209d39SAndroid Build Coastguard Worker     dirPropCount
71*0e209d39SAndroid Build Coastguard Worker };
72*0e209d39SAndroid Build Coastguard Worker 
73*0e209d39SAndroid Build Coastguard Worker /*  Sometimes, bit values are more appropriate
74*0e209d39SAndroid Build Coastguard Worker     to deal with directionality properties.
75*0e209d39SAndroid Build Coastguard Worker     Abbreviations in these macro names refer to names
76*0e209d39SAndroid Build Coastguard Worker     used in the BiDi algorithm.
77*0e209d39SAndroid Build Coastguard Worker */
78*0e209d39SAndroid Build Coastguard Worker #define DIRPROP_FLAG(dir) (1UL<<(dir))
79*0e209d39SAndroid Build Coastguard Worker #define PURE_DIRPROP(prop)  ((prop)&~0xE0)    ?????????????????????????
80*0e209d39SAndroid Build Coastguard Worker 
81*0e209d39SAndroid Build Coastguard Worker /* special flag for multiple runs from explicit embedding codes */
82*0e209d39SAndroid Build Coastguard Worker #define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
83*0e209d39SAndroid Build Coastguard Worker 
84*0e209d39SAndroid Build Coastguard Worker /* are there any characters that are LTR or RTL? */
85*0e209d39SAndroid Build Coastguard Worker #define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(ENL)|DIRPROP_FLAG(ENR)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(LRI))
86*0e209d39SAndroid Build Coastguard Worker #define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(RLI))
87*0e209d39SAndroid Build Coastguard Worker #define MASK_R_AL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL))
88*0e209d39SAndroid Build Coastguard Worker #define MASK_STRONG_EN_AN (DIRPROP_FLAG(L)|DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN))
89*0e209d39SAndroid Build Coastguard Worker 
90*0e209d39SAndroid Build Coastguard Worker /* explicit embedding codes */
91*0e209d39SAndroid Build Coastguard Worker #define MASK_EXPLICIT (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO)|DIRPROP_FLAG(PDF))
92*0e209d39SAndroid Build Coastguard Worker 
93*0e209d39SAndroid Build Coastguard Worker /* explicit isolate codes */
94*0e209d39SAndroid Build Coastguard Worker #define MASK_ISO (DIRPROP_FLAG(LRI)|DIRPROP_FLAG(RLI)|DIRPROP_FLAG(FSI)|DIRPROP_FLAG(PDI))
95*0e209d39SAndroid Build Coastguard Worker 
96*0e209d39SAndroid Build Coastguard Worker #define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
97*0e209d39SAndroid Build Coastguard Worker 
98*0e209d39SAndroid Build Coastguard Worker /* paragraph and segment separators */
99*0e209d39SAndroid Build Coastguard Worker #define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
100*0e209d39SAndroid Build Coastguard Worker 
101*0e209d39SAndroid Build Coastguard Worker /* all types that are counted as White Space or Neutral in some steps */
102*0e209d39SAndroid Build Coastguard Worker #define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT|MASK_ISO)
103*0e209d39SAndroid Build Coastguard Worker 
104*0e209d39SAndroid Build Coastguard Worker /* types that are neutrals or could becomes neutrals in (Wn) */
105*0e209d39SAndroid Build Coastguard Worker #define MASK_POSSIBLE_N (DIRPROP_FLAG(ON)|DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_WS)
106*0e209d39SAndroid Build Coastguard Worker 
107*0e209d39SAndroid Build Coastguard Worker /*
108*0e209d39SAndroid Build Coastguard Worker  *  These types may be changed to "e",
109*0e209d39SAndroid Build Coastguard Worker  *  the embedding type (L or R) of the run,
110*0e209d39SAndroid Build Coastguard Worker  *  in the BiDi algorithm (N2)
111*0e209d39SAndroid Build Coastguard Worker  */
112*0e209d39SAndroid Build Coastguard Worker #define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
113*0e209d39SAndroid Build Coastguard Worker 
114*0e209d39SAndroid Build Coastguard Worker /* the dirProp's L and R are defined to 0 and 1 values in UCharDirection */
115*0e209d39SAndroid Build Coastguard Worker #define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
116*0e209d39SAndroid Build Coastguard Worker 
117*0e209d39SAndroid Build Coastguard Worker #define IS_DEFAULT_LEVEL(level) ((level)>=0xfe)
118*0e209d39SAndroid Build Coastguard Worker 
119*0e209d39SAndroid Build Coastguard Worker /*
120*0e209d39SAndroid Build Coastguard Worker  *  The following bit is used for the directional isolate status.
121*0e209d39SAndroid Build Coastguard Worker  *  Stack entries corresponding to isolate sequences are greater than ISOLATE.
122*0e209d39SAndroid Build Coastguard Worker  */
123*0e209d39SAndroid Build Coastguard Worker #define ISOLATE  0x0100
124*0e209d39SAndroid Build Coastguard Worker 
125*0e209d39SAndroid Build Coastguard Worker U_CFUNC UBiDiLevel
126*0e209d39SAndroid Build Coastguard Worker ubidi_getParaLevelAtIndex(const UBiDi *pBiDi, int32_t index);
127*0e209d39SAndroid Build Coastguard Worker 
128*0e209d39SAndroid Build Coastguard Worker #define GET_PARALEVEL(ubidi, index) \
129*0e209d39SAndroid Build Coastguard Worker             ((UBiDiLevel)(!(ubidi)->defaultParaLevel || (index)<(ubidi)->paras[0].limit ? \
130*0e209d39SAndroid Build Coastguard Worker                          (ubidi)->paraLevel : ubidi_getParaLevelAtIndex((ubidi), (index))))
131*0e209d39SAndroid Build Coastguard Worker 
132*0e209d39SAndroid Build Coastguard Worker /* number of paras entries allocated initially without malloc */
133*0e209d39SAndroid Build Coastguard Worker #define SIMPLE_PARAS_COUNT      10
134*0e209d39SAndroid Build Coastguard Worker /* number of isolate entries allocated initially without malloc */
135*0e209d39SAndroid Build Coastguard Worker #define SIMPLE_ISOLATES_COUNT   5
136*0e209d39SAndroid Build Coastguard Worker /* number of isolate run entries for paired brackets allocated initially without malloc */
137*0e209d39SAndroid Build Coastguard Worker #define SIMPLE_OPENINGS_COUNT   20
138*0e209d39SAndroid Build Coastguard Worker 
139*0e209d39SAndroid Build Coastguard Worker #define CR  0x000D
140*0e209d39SAndroid Build Coastguard Worker #define LF  0x000A
141*0e209d39SAndroid Build Coastguard Worker 
142*0e209d39SAndroid Build Coastguard Worker /* Run structure for reordering --------------------------------------------- */
143*0e209d39SAndroid Build Coastguard Worker enum {
144*0e209d39SAndroid Build Coastguard Worker     LRM_BEFORE=1,
145*0e209d39SAndroid Build Coastguard Worker     LRM_AFTER=2,
146*0e209d39SAndroid Build Coastguard Worker     RLM_BEFORE=4,
147*0e209d39SAndroid Build Coastguard Worker     RLM_AFTER=8
148*0e209d39SAndroid Build Coastguard Worker };
149*0e209d39SAndroid Build Coastguard Worker 
150*0e209d39SAndroid Build Coastguard Worker typedef struct Para {
151*0e209d39SAndroid Build Coastguard Worker     int32_t limit;
152*0e209d39SAndroid Build Coastguard Worker     int32_t level;
153*0e209d39SAndroid Build Coastguard Worker } Para;
154*0e209d39SAndroid Build Coastguard Worker 
155*0e209d39SAndroid Build Coastguard Worker enum {                                  /* flags for Opening.flags */
156*0e209d39SAndroid Build Coastguard Worker     FOUND_L=DIRPROP_FLAG(L),
157*0e209d39SAndroid Build Coastguard Worker     FOUND_R=DIRPROP_FLAG(R)
158*0e209d39SAndroid Build Coastguard Worker };
159*0e209d39SAndroid Build Coastguard Worker 
160*0e209d39SAndroid Build Coastguard Worker typedef struct Opening {
161*0e209d39SAndroid Build Coastguard Worker     int32_t position;                   /* position of opening bracket */
162*0e209d39SAndroid Build Coastguard Worker     int32_t match;                      /* matching char or -position of closing bracket */
163*0e209d39SAndroid Build Coastguard Worker     int32_t contextPos;                 /* position of last strong char found before opening */
164*0e209d39SAndroid Build Coastguard Worker     uint16_t flags;                     /* bits for L or R/AL found within the pair */
165*0e209d39SAndroid Build Coastguard Worker     UBiDiDirection contextDir;          /* L or R according to last strong char before opening */
166*0e209d39SAndroid Build Coastguard Worker     uint8_t filler;                     /* to complete a nice multiple of 4 chars */
167*0e209d39SAndroid Build Coastguard Worker } Opening;
168*0e209d39SAndroid Build Coastguard Worker 
169*0e209d39SAndroid Build Coastguard Worker typedef struct IsoRun {
170*0e209d39SAndroid Build Coastguard Worker     int32_t  contextPos;                /* position of char determining context */
171*0e209d39SAndroid Build Coastguard Worker     uint16_t start;                     /* index of first opening entry for this run */
172*0e209d39SAndroid Build Coastguard Worker     uint16_t limit;                     /* index after last opening entry for this run */
173*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel level;                   /* level of this run */
174*0e209d39SAndroid Build Coastguard Worker     DirProp lastStrong;                 /* bidi class of last strong char found in this run */
175*0e209d39SAndroid Build Coastguard Worker     DirProp lastBase;                   /* bidi class of last base char found in this run */
176*0e209d39SAndroid Build Coastguard Worker     UBiDiDirection contextDir;          /* L or R to use as context for following openings */
177*0e209d39SAndroid Build Coastguard Worker } IsoRun;
178*0e209d39SAndroid Build Coastguard Worker 
179*0e209d39SAndroid Build Coastguard Worker typedef struct BracketData {
180*0e209d39SAndroid Build Coastguard Worker     UBiDi   *pBiDi;
181*0e209d39SAndroid Build Coastguard Worker     /* array of opening entries which should be enough in most cases; no malloc() */
182*0e209d39SAndroid Build Coastguard Worker     Opening simpleOpenings[SIMPLE_OPENINGS_COUNT];
183*0e209d39SAndroid Build Coastguard Worker     Opening *openings;                  /* pointer to current array of entries */
184*0e209d39SAndroid Build Coastguard Worker     int32_t openingsCount;              /* number of allocated entries */
185*0e209d39SAndroid Build Coastguard Worker     int32_t isoRunLast;                 /* index of last used entry */
186*0e209d39SAndroid Build Coastguard Worker     /* array of nested isolated sequence entries; can never excess UBIDI_MAX_EXPLICIT_LEVEL
187*0e209d39SAndroid Build Coastguard Worker        + 1 for index 0, + 1 for before the first isolated sequence */
188*0e209d39SAndroid Build Coastguard Worker     IsoRun  isoRuns[UBIDI_MAX_EXPLICIT_LEVEL+2];
189*0e209d39SAndroid Build Coastguard Worker     UBool isNumbersSpecial;             /* reordering mode for NUMBERS_SPECIAL */
190*0e209d39SAndroid Build Coastguard Worker } BracketData;
191*0e209d39SAndroid Build Coastguard Worker 
192*0e209d39SAndroid Build Coastguard Worker typedef struct Isolate {
193*0e209d39SAndroid Build Coastguard Worker     int32_t startON;
194*0e209d39SAndroid Build Coastguard Worker     int32_t start1;
195*0e209d39SAndroid Build Coastguard Worker     int32_t state;
196*0e209d39SAndroid Build Coastguard Worker     int16_t stateImp;
197*0e209d39SAndroid Build Coastguard Worker } Isolate;
198*0e209d39SAndroid Build Coastguard Worker 
199*0e209d39SAndroid Build Coastguard Worker typedef struct Run {
200*0e209d39SAndroid Build Coastguard Worker     int32_t logicalStart,   /* first character of the run; b31 indicates even/odd level */
201*0e209d39SAndroid Build Coastguard Worker             visualLimit,    /* last visual position of the run +1 */
202*0e209d39SAndroid Build Coastguard Worker             insertRemove;   /* if >0, flags for inserting LRM/RLM before/after run,
203*0e209d39SAndroid Build Coastguard Worker                                if <0, count of bidi controls within run            */
204*0e209d39SAndroid Build Coastguard Worker } Run;
205*0e209d39SAndroid Build Coastguard Worker 
206*0e209d39SAndroid Build Coastguard Worker /* in a Run, logicalStart will get this bit set if the run level is odd */
207*0e209d39SAndroid Build Coastguard Worker #define INDEX_ODD_BIT (1UL<<31)
208*0e209d39SAndroid Build Coastguard Worker 
209*0e209d39SAndroid Build Coastguard Worker #define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)((level)&1)<<31))
210*0e209d39SAndroid Build Coastguard Worker #define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)((level)&1)<<31))
211*0e209d39SAndroid Build Coastguard Worker #define REMOVE_ODD_BIT(x)                 ((x)&=~INDEX_ODD_BIT)
212*0e209d39SAndroid Build Coastguard Worker 
213*0e209d39SAndroid Build Coastguard Worker #define GET_INDEX(x)   ((x)&~INDEX_ODD_BIT)
214*0e209d39SAndroid Build Coastguard Worker #define GET_ODD_BIT(x) ((uint32_t)(x)>>31)
215*0e209d39SAndroid Build Coastguard Worker #define IS_ODD_RUN(x)  ((UBool)(((x)&INDEX_ODD_BIT)!=0))
216*0e209d39SAndroid Build Coastguard Worker #define IS_EVEN_RUN(x) ((UBool)(((x)&INDEX_ODD_BIT)==0))
217*0e209d39SAndroid Build Coastguard Worker 
218*0e209d39SAndroid Build Coastguard Worker U_CFUNC UBool
219*0e209d39SAndroid Build Coastguard Worker ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
220*0e209d39SAndroid Build Coastguard Worker 
221*0e209d39SAndroid Build Coastguard Worker /** BiDi control code points */
222*0e209d39SAndroid Build Coastguard Worker enum {
223*0e209d39SAndroid Build Coastguard Worker     ZWNJ_CHAR=0x200c,
224*0e209d39SAndroid Build Coastguard Worker     ZWJ_CHAR,
225*0e209d39SAndroid Build Coastguard Worker     LRM_CHAR,
226*0e209d39SAndroid Build Coastguard Worker     RLM_CHAR,
227*0e209d39SAndroid Build Coastguard Worker     LRE_CHAR=0x202a,
228*0e209d39SAndroid Build Coastguard Worker     RLE_CHAR,
229*0e209d39SAndroid Build Coastguard Worker     PDF_CHAR,
230*0e209d39SAndroid Build Coastguard Worker     LRO_CHAR,
231*0e209d39SAndroid Build Coastguard Worker     RLO_CHAR,
232*0e209d39SAndroid Build Coastguard Worker     LRI_CHAR=0x2066,
233*0e209d39SAndroid Build Coastguard Worker     RLI_CHAR,
234*0e209d39SAndroid Build Coastguard Worker     FSI_CHAR,
235*0e209d39SAndroid Build Coastguard Worker     PDI_CHAR
236*0e209d39SAndroid Build Coastguard Worker };
237*0e209d39SAndroid Build Coastguard Worker 
238*0e209d39SAndroid Build Coastguard Worker #define IS_BIDI_CONTROL_CHAR(c) (((uint32_t)(c)&0xfffffffc)==ZWNJ_CHAR || (uint32_t)((c)-LRE_CHAR)<5 || (uint32_t)((c)-LRI_CHAR)<4)
239*0e209d39SAndroid Build Coastguard Worker 
240*0e209d39SAndroid Build Coastguard Worker /* InsertPoints structure for noting where to put BiDi marks ---------------- */
241*0e209d39SAndroid Build Coastguard Worker 
242*0e209d39SAndroid Build Coastguard Worker typedef struct Point {
243*0e209d39SAndroid Build Coastguard Worker     int32_t pos;            /* position in text */
244*0e209d39SAndroid Build Coastguard Worker     int32_t flag;           /* flag for LRM/RLM, before/after */
245*0e209d39SAndroid Build Coastguard Worker } Point;
246*0e209d39SAndroid Build Coastguard Worker 
247*0e209d39SAndroid Build Coastguard Worker typedef struct InsertPoints {
248*0e209d39SAndroid Build Coastguard Worker     int32_t capacity;       /* number of points allocated */
249*0e209d39SAndroid Build Coastguard Worker     int32_t size;           /* number of points used */
250*0e209d39SAndroid Build Coastguard Worker     int32_t confirmed;      /* number of points confirmed */
251*0e209d39SAndroid Build Coastguard Worker     UErrorCode errorCode;   /* for eventual memory shortage */
252*0e209d39SAndroid Build Coastguard Worker     Point *points;          /* pointer to array of points */
253*0e209d39SAndroid Build Coastguard Worker } InsertPoints;
254*0e209d39SAndroid Build Coastguard Worker 
255*0e209d39SAndroid Build Coastguard Worker 
256*0e209d39SAndroid Build Coastguard Worker /* UBiDi structure ----------------------------------------------------------- */
257*0e209d39SAndroid Build Coastguard Worker 
258*0e209d39SAndroid Build Coastguard Worker struct UBiDi {
259*0e209d39SAndroid Build Coastguard Worker     /* pointer to parent paragraph object (pointer to self if this object is
260*0e209d39SAndroid Build Coastguard Worker      * a paragraph object); set to NULL in a newly opened object; set to a
261*0e209d39SAndroid Build Coastguard Worker      * real value after a successful execution of ubidi_setPara or ubidi_setLine
262*0e209d39SAndroid Build Coastguard Worker      */
263*0e209d39SAndroid Build Coastguard Worker     const UBiDi * pParaBiDi;
264*0e209d39SAndroid Build Coastguard Worker 
265*0e209d39SAndroid Build Coastguard Worker     /* alias pointer to the current text */
266*0e209d39SAndroid Build Coastguard Worker     const UChar *text;
267*0e209d39SAndroid Build Coastguard Worker 
268*0e209d39SAndroid Build Coastguard Worker     /* length of the current text */
269*0e209d39SAndroid Build Coastguard Worker     int32_t originalLength;
270*0e209d39SAndroid Build Coastguard Worker 
271*0e209d39SAndroid Build Coastguard Worker     /* if the UBIDI_OPTION_STREAMING option is set, this is the length
272*0e209d39SAndroid Build Coastguard Worker      * of text actually processed by ubidi_setPara, which may be shorter than
273*0e209d39SAndroid Build Coastguard Worker      * the original length.
274*0e209d39SAndroid Build Coastguard Worker      * Otherwise, it is identical to the original length.
275*0e209d39SAndroid Build Coastguard Worker      */
276*0e209d39SAndroid Build Coastguard Worker     int32_t length;
277*0e209d39SAndroid Build Coastguard Worker 
278*0e209d39SAndroid Build Coastguard Worker     /* if the UBIDI_OPTION_REMOVE_CONTROLS option is set, and/or
279*0e209d39SAndroid Build Coastguard Worker      * marks are allowed to be inserted in one of the reordering mode, the
280*0e209d39SAndroid Build Coastguard Worker      * length of the result string may be different from the processed length.
281*0e209d39SAndroid Build Coastguard Worker      */
282*0e209d39SAndroid Build Coastguard Worker     int32_t resultLength;
283*0e209d39SAndroid Build Coastguard Worker 
284*0e209d39SAndroid Build Coastguard Worker     /* memory sizes in bytes */
285*0e209d39SAndroid Build Coastguard Worker     int32_t dirPropsSize, levelsSize, openingsSize, parasSize, runsSize, isolatesSize;
286*0e209d39SAndroid Build Coastguard Worker 
287*0e209d39SAndroid Build Coastguard Worker     /* allocated memory */
288*0e209d39SAndroid Build Coastguard Worker     DirProp *dirPropsMemory;
289*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel *levelsMemory;
290*0e209d39SAndroid Build Coastguard Worker     Opening *openingsMemory;
291*0e209d39SAndroid Build Coastguard Worker     Para *parasMemory;
292*0e209d39SAndroid Build Coastguard Worker     Run *runsMemory;
293*0e209d39SAndroid Build Coastguard Worker     Isolate *isolatesMemory;
294*0e209d39SAndroid Build Coastguard Worker 
295*0e209d39SAndroid Build Coastguard Worker     /* indicators for whether memory may be allocated after ubidi_open() */
296*0e209d39SAndroid Build Coastguard Worker     UBool mayAllocateText, mayAllocateRuns;
297*0e209d39SAndroid Build Coastguard Worker 
298*0e209d39SAndroid Build Coastguard Worker     /* arrays with one value per text-character */
299*0e209d39SAndroid Build Coastguard Worker     DirProp *dirProps;
300*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel *levels;
301*0e209d39SAndroid Build Coastguard Worker 
302*0e209d39SAndroid Build Coastguard Worker     /* are we performing an approximation of the "inverse BiDi" algorithm? */
303*0e209d39SAndroid Build Coastguard Worker     UBool isInverse;
304*0e209d39SAndroid Build Coastguard Worker 
305*0e209d39SAndroid Build Coastguard Worker     /* are we using the basic algorithm or its variation? */
306*0e209d39SAndroid Build Coastguard Worker     UBiDiReorderingMode reorderingMode;
307*0e209d39SAndroid Build Coastguard Worker 
308*0e209d39SAndroid Build Coastguard Worker     /* UBIDI_REORDER_xxx values must be ordered so that all the regular
309*0e209d39SAndroid Build Coastguard Worker      * logical to visual modes come first, and all inverse BiDi modes
310*0e209d39SAndroid Build Coastguard Worker      * come last.
311*0e209d39SAndroid Build Coastguard Worker      */
312*0e209d39SAndroid Build Coastguard Worker     #define UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL    UBIDI_REORDER_NUMBERS_SPECIAL
313*0e209d39SAndroid Build Coastguard Worker 
314*0e209d39SAndroid Build Coastguard Worker     /* bitmask for reordering options */
315*0e209d39SAndroid Build Coastguard Worker     uint32_t reorderingOptions;
316*0e209d39SAndroid Build Coastguard Worker 
317*0e209d39SAndroid Build Coastguard Worker     /* must block separators receive level 0? */
318*0e209d39SAndroid Build Coastguard Worker     UBool orderParagraphsLTR;
319*0e209d39SAndroid Build Coastguard Worker 
320*0e209d39SAndroid Build Coastguard Worker     /* the paragraph level */
321*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel paraLevel;
322*0e209d39SAndroid Build Coastguard Worker     /* original paraLevel when contextual */
323*0e209d39SAndroid Build Coastguard Worker     /* must be one of UBIDI_DEFAULT_xxx or 0 if not contextual */
324*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel defaultParaLevel;
325*0e209d39SAndroid Build Coastguard Worker 
326*0e209d39SAndroid Build Coastguard Worker     /* context data */
327*0e209d39SAndroid Build Coastguard Worker     const UChar *prologue;
328*0e209d39SAndroid Build Coastguard Worker     int32_t proLength;
329*0e209d39SAndroid Build Coastguard Worker     const UChar *epilogue;
330*0e209d39SAndroid Build Coastguard Worker     int32_t epiLength;
331*0e209d39SAndroid Build Coastguard Worker 
332*0e209d39SAndroid Build Coastguard Worker     /* the following is set in ubidi_setPara, used in processPropertySeq */
333*0e209d39SAndroid Build Coastguard Worker     const struct ImpTabPair * pImpTabPair;  /* pointer to levels state table pair */
334*0e209d39SAndroid Build Coastguard Worker 
335*0e209d39SAndroid Build Coastguard Worker     /* the overall paragraph or line directionality - see UBiDiDirection */
336*0e209d39SAndroid Build Coastguard Worker     UBiDiDirection direction;
337*0e209d39SAndroid Build Coastguard Worker 
338*0e209d39SAndroid Build Coastguard Worker     /* flags is a bit set for which directional properties are in the text */
339*0e209d39SAndroid Build Coastguard Worker     Flags flags;
340*0e209d39SAndroid Build Coastguard Worker 
341*0e209d39SAndroid Build Coastguard Worker     /* lastArabicPos is index to the last AL in the text, -1 if none */
342*0e209d39SAndroid Build Coastguard Worker     int32_t lastArabicPos;
343*0e209d39SAndroid Build Coastguard Worker 
344*0e209d39SAndroid Build Coastguard Worker     /* characters after trailingWSStart are WS and are */
345*0e209d39SAndroid Build Coastguard Worker     /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
346*0e209d39SAndroid Build Coastguard Worker     int32_t trailingWSStart;
347*0e209d39SAndroid Build Coastguard Worker 
348*0e209d39SAndroid Build Coastguard Worker     /* fields for paragraph handling */
349*0e209d39SAndroid Build Coastguard Worker     int32_t paraCount;                  /* set in getDirProps() */
350*0e209d39SAndroid Build Coastguard Worker     /* filled in getDirProps() */
351*0e209d39SAndroid Build Coastguard Worker     Para *paras;
352*0e209d39SAndroid Build Coastguard Worker 
353*0e209d39SAndroid Build Coastguard Worker     /* for relatively short text, we only need a tiny array of paras (no malloc()) */
354*0e209d39SAndroid Build Coastguard Worker     Para simpleParas[SIMPLE_PARAS_COUNT];
355*0e209d39SAndroid Build Coastguard Worker 
356*0e209d39SAndroid Build Coastguard Worker     /* fields for line reordering */
357*0e209d39SAndroid Build Coastguard Worker     int32_t runCount;     /* ==-1: runs not set up yet */
358*0e209d39SAndroid Build Coastguard Worker     Run *runs;
359*0e209d39SAndroid Build Coastguard Worker 
360*0e209d39SAndroid Build Coastguard Worker     /* for non-mixed text, we only need a tiny array of runs (no malloc()) */
361*0e209d39SAndroid Build Coastguard Worker     Run simpleRuns[1];
362*0e209d39SAndroid Build Coastguard Worker 
363*0e209d39SAndroid Build Coastguard Worker     /* maximum or current nesting depth of isolate sequences */
364*0e209d39SAndroid Build Coastguard Worker     /* Within resolveExplicitLevels() and checkExplicitLevels(), this is the maximal
365*0e209d39SAndroid Build Coastguard Worker        nesting encountered.
366*0e209d39SAndroid Build Coastguard Worker        Within resolveImplicitLevels(), this is the index of the current isolates
367*0e209d39SAndroid Build Coastguard Worker        stack entry. */
368*0e209d39SAndroid Build Coastguard Worker     int32_t isolateCount;
369*0e209d39SAndroid Build Coastguard Worker     Isolate *isolates;
370*0e209d39SAndroid Build Coastguard Worker 
371*0e209d39SAndroid Build Coastguard Worker     /* for simple text, have a small stack (no malloc()) */
372*0e209d39SAndroid Build Coastguard Worker     Isolate simpleIsolates[SIMPLE_ISOLATES_COUNT];
373*0e209d39SAndroid Build Coastguard Worker 
374*0e209d39SAndroid Build Coastguard Worker     /* for inverse Bidi with insertion of directional marks */
375*0e209d39SAndroid Build Coastguard Worker     InsertPoints insertPoints;
376*0e209d39SAndroid Build Coastguard Worker 
377*0e209d39SAndroid Build Coastguard Worker     /* for option UBIDI_OPTION_REMOVE_CONTROLS */
378*0e209d39SAndroid Build Coastguard Worker     int32_t controlCount;
379*0e209d39SAndroid Build Coastguard Worker 
380*0e209d39SAndroid Build Coastguard Worker     /* for Bidi class callback */
381*0e209d39SAndroid Build Coastguard Worker     UBiDiClassCallback *fnClassCallback;    /* action pointer */
382*0e209d39SAndroid Build Coastguard Worker     const void *coClassCallback;            /* context pointer */
383*0e209d39SAndroid Build Coastguard Worker };
384*0e209d39SAndroid Build Coastguard Worker 
385*0e209d39SAndroid Build Coastguard Worker #define IS_VALID_PARA(x) ((x) && ((x)->pParaBiDi==(x)))
386*0e209d39SAndroid Build Coastguard Worker #define IS_VALID_PARA_OR_LINE(x) ((x) && ((x)->pParaBiDi==(x) || (((x)->pParaBiDi) && (x)->pParaBiDi->pParaBiDi==(x)->pParaBiDi)))
387*0e209d39SAndroid Build Coastguard Worker 
388*0e209d39SAndroid Build Coastguard Worker typedef union {
389*0e209d39SAndroid Build Coastguard Worker     DirProp *dirPropsMemory;
390*0e209d39SAndroid Build Coastguard Worker     UBiDiLevel *levelsMemory;
391*0e209d39SAndroid Build Coastguard Worker     Opening *openingsMemory;
392*0e209d39SAndroid Build Coastguard Worker     Para *parasMemory;
393*0e209d39SAndroid Build Coastguard Worker     Run *runsMemory;
394*0e209d39SAndroid Build Coastguard Worker     Isolate *isolatesMemory;
395*0e209d39SAndroid Build Coastguard Worker } BidiMemoryForAllocation;
396*0e209d39SAndroid Build Coastguard Worker 
397*0e209d39SAndroid Build Coastguard Worker /* Macros for initial checks at function entry */
398*0e209d39SAndroid Build Coastguard Worker #define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
399*0e209d39SAndroid Build Coastguard Worker     if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue; \
400*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
401*0e209d39SAndroid Build Coastguard Worker #define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
402*0e209d39SAndroid Build Coastguard Worker     if(!IS_VALID_PARA(bidi)) { \
403*0e209d39SAndroid Build Coastguard Worker         errcode=U_INVALID_STATE_ERROR; \
404*0e209d39SAndroid Build Coastguard Worker         return retvalue; \
405*0e209d39SAndroid Build Coastguard Worker     } \
406*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
407*0e209d39SAndroid Build Coastguard Worker #define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
408*0e209d39SAndroid Build Coastguard Worker     if(!IS_VALID_PARA_OR_LINE(bidi)) { \
409*0e209d39SAndroid Build Coastguard Worker         errcode=U_INVALID_STATE_ERROR; \
410*0e209d39SAndroid Build Coastguard Worker         return retvalue; \
411*0e209d39SAndroid Build Coastguard Worker     } \
412*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
413*0e209d39SAndroid Build Coastguard Worker #define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
414*0e209d39SAndroid Build Coastguard Worker     if((arg)<(start) || (arg)>=(limit)) { \
415*0e209d39SAndroid Build Coastguard Worker         (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
416*0e209d39SAndroid Build Coastguard Worker         return retvalue; \
417*0e209d39SAndroid Build Coastguard Worker     } \
418*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
419*0e209d39SAndroid Build Coastguard Worker 
420*0e209d39SAndroid Build Coastguard Worker #define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode) UPRV_BLOCK_MACRO_BEGIN { \
421*0e209d39SAndroid Build Coastguard Worker     if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return; \
422*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
423*0e209d39SAndroid Build Coastguard Worker #define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
424*0e209d39SAndroid Build Coastguard Worker     if(!IS_VALID_PARA(bidi)) { \
425*0e209d39SAndroid Build Coastguard Worker         errcode=U_INVALID_STATE_ERROR; \
426*0e209d39SAndroid Build Coastguard Worker         return; \
427*0e209d39SAndroid Build Coastguard Worker     } \
428*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
429*0e209d39SAndroid Build Coastguard Worker #define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
430*0e209d39SAndroid Build Coastguard Worker     if(!IS_VALID_PARA_OR_LINE(bidi)) { \
431*0e209d39SAndroid Build Coastguard Worker         errcode=U_INVALID_STATE_ERROR; \
432*0e209d39SAndroid Build Coastguard Worker         return; \
433*0e209d39SAndroid Build Coastguard Worker     } \
434*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
435*0e209d39SAndroid Build Coastguard Worker #define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode) UPRV_BLOCK_MACRO_BEGIN { \
436*0e209d39SAndroid Build Coastguard Worker     if((arg)<(start) || (arg)>=(limit)) { \
437*0e209d39SAndroid Build Coastguard Worker         (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
438*0e209d39SAndroid Build Coastguard Worker         return; \
439*0e209d39SAndroid Build Coastguard Worker     } \
440*0e209d39SAndroid Build Coastguard Worker } UPRV_BLOCK_MACRO_END
441*0e209d39SAndroid Build Coastguard Worker 
442*0e209d39SAndroid Build Coastguard Worker /* helper function to (re)allocate memory if allowed */
443*0e209d39SAndroid Build Coastguard Worker U_CFUNC UBool
444*0e209d39SAndroid Build Coastguard Worker ubidi_getMemory(BidiMemoryForAllocation *pMemory, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded);
445*0e209d39SAndroid Build Coastguard Worker 
446*0e209d39SAndroid Build Coastguard Worker /* helper macros for each allocated array in UBiDi */
447*0e209d39SAndroid Build Coastguard Worker #define getDirPropsMemory(pBiDi, length) \
448*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
449*0e209d39SAndroid Build Coastguard Worker                         (pBiDi)->mayAllocateText, (length))
450*0e209d39SAndroid Build Coastguard Worker 
451*0e209d39SAndroid Build Coastguard Worker #define getLevelsMemory(pBiDi, length) \
452*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
453*0e209d39SAndroid Build Coastguard Worker                         (pBiDi)->mayAllocateText, (length))
454*0e209d39SAndroid Build Coastguard Worker 
455*0e209d39SAndroid Build Coastguard Worker #define getRunsMemory(pBiDi, length) \
456*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
457*0e209d39SAndroid Build Coastguard Worker                         (pBiDi)->mayAllocateRuns, (length)*sizeof(Run))
458*0e209d39SAndroid Build Coastguard Worker 
459*0e209d39SAndroid Build Coastguard Worker /* additional macros used by ubidi_open() - always allow allocation */
460*0e209d39SAndroid Build Coastguard Worker #define getInitialDirPropsMemory(pBiDi, length) \
461*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
462*0e209d39SAndroid Build Coastguard Worker                         true, (length))
463*0e209d39SAndroid Build Coastguard Worker 
464*0e209d39SAndroid Build Coastguard Worker #define getInitialLevelsMemory(pBiDi, length) \
465*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
466*0e209d39SAndroid Build Coastguard Worker                         true, (length))
467*0e209d39SAndroid Build Coastguard Worker 
468*0e209d39SAndroid Build Coastguard Worker #define getInitialOpeningsMemory(pBiDi, length) \
469*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->openingsMemory, &(pBiDi)->openingsSize, \
470*0e209d39SAndroid Build Coastguard Worker                         true, (length)*sizeof(Opening))
471*0e209d39SAndroid Build Coastguard Worker 
472*0e209d39SAndroid Build Coastguard Worker #define getInitialParasMemory(pBiDi, length) \
473*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->parasMemory, &(pBiDi)->parasSize, \
474*0e209d39SAndroid Build Coastguard Worker                         true, (length)*sizeof(Para))
475*0e209d39SAndroid Build Coastguard Worker 
476*0e209d39SAndroid Build Coastguard Worker #define getInitialRunsMemory(pBiDi, length) \
477*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
478*0e209d39SAndroid Build Coastguard Worker                         true, (length)*sizeof(Run))
479*0e209d39SAndroid Build Coastguard Worker 
480*0e209d39SAndroid Build Coastguard Worker #define getInitialIsolatesMemory(pBiDi, length) \
481*0e209d39SAndroid Build Coastguard Worker         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->isolatesMemory, &(pBiDi)->isolatesSize, \
482*0e209d39SAndroid Build Coastguard Worker                         true, (length)*sizeof(Isolate))
483*0e209d39SAndroid Build Coastguard Worker 
484*0e209d39SAndroid Build Coastguard Worker #endif
485