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