16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1999-2013, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: ubidi.c 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 1999jul27 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer, updated by Matitiahu Allouche 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uchar.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ubidi.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ubidi_props.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ubidiimp.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * General implementation notes: 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Throughout the implementation, there are comments like (W2) that refer to 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rules of the BiDi algorithm in its version 5, in this example to the second 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rule of the resolution of weak types. 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For handling surrogate pairs, where two UChar's form one "abstract" (or UTF-32) 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * character according to UTF-16, the second UChar gets the directional property of 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the entire character assigned, while the first one gets a BN, a boundary 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * neutral, type, which is ignored by most of the algorithm according to 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rule (X9) and the implementation suggestions of the BiDi algorithm. 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Later, adjustWSLevels() will set the level for each BN to that of the 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * following character (UChar), which results in surrogate pairs getting the 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * same level on each of their surrogates. 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In a UTF-8 implementation, the same thing could be done: the last byte of 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a multi-byte sequence would get the "real" property, while all previous 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * bytes of that sequence would get BN. 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It is not possible to assign all those parts of a character the same real 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * property because this would fail in the resolution of weak types with rules 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that look at immediately surrounding types. 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * As a related topic, this implementation does not remove Boundary Neutral 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * types from the input, but ignores them wherever this is relevant. 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For example, the loop for the resolution of the weak types reads 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * types until it finds a non-BN. 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Also, explicit embedding codes are neither changed into BN nor removed. 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * They are only treated the same way real BNs are. 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * As stated before, adjustWSLevels() takes care of them at the end. 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For the purpose of conformance, the levels of all these codes 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * do not matter. 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Note that this implementation never modifies the dirProps 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after the initial setup, except for FSI which is changed to either 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * LRI or RLI in getDirProps(), and paired brackets which may be changed 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to L or R according to N0. 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In this implementation, the resolution of weak types (Wn), 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * neutrals (Nn), and the assignment of the resolved level (In) 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * are all done in one single loop, in resolveImplicitLevels(). 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Changes of dirProp values are done on the fly, without writing 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * them back to the dirProps array. 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This implementation contains code that allows to bypass steps of the 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * algorithm that are not needed on the specific paragraph 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in order to speed up the most common cases considerably, 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * like text that is entirely LTR, or RTL text without numbers. 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Most of this is done by setting a bit for each directional property 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in a flags variable and later checking for whether there are 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * any LTR characters or any RTL characters, or both, whether 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * there are any explicit embedding codes, etc. 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If the (Xn) steps are performed, then the flags are re-evaluated, 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * because they will then not contain the embedding codes any more 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and will be adjusted for override codes, so that subsequently 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * more bypassing may be possible than what the initial flags suggested. 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If the text is not mixed-directional, then the 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * algorithm steps for the weak type resolution are not performed, 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and all levels are set to the paragraph level. 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If there are no explicit embedding codes, then the (Xn) steps 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * are not performed. 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If embedding levels are supplied as a parameter, then all 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * explicit embedding codes are ignored, and the (Xn) steps 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * are not performed. 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * White Space types could get the level of the run they belong to, 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and are checked with a test of (flags&MASK_EMBEDDING) to 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * consider if the paragraph direction should be considered in 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the flags variable. 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If there are no White Space types in the paragraph, then 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (L1) is not necessary in adjustWSLevels(). 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* to avoid some conditional statements, use tiny constant arrays */ 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const Flags flagLR[2]={ DIRPROP_FLAG(L), DIRPROP_FLAG(R) }; 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const Flags flagE[2]={ DIRPROP_FLAG(LRE), DIRPROP_FLAG(RLE) }; 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const Flags flagO[2]={ DIRPROP_FLAG(LRO), DIRPROP_FLAG(RLO) }; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DIRPROP_FLAG_LR(level) flagLR[(level)&1] 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DIRPROP_FLAG_E(level) flagE[(level)&1] 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DIRPROP_FLAG_O(level) flagO[(level)&1] 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DIR_FROM_STRONG(strong) ((strong)==L ? L : R) 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UBiDi object management -------------------------------------------------- */ 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDi * U_EXPORT2 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_open(void) 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode=U_ZERO_ERROR; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ubidi_openSized(0, 0, &errorCode); 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDi * U_EXPORT2 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode) { 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDi *pBiDi; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the argument values */ 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(maxLength<0 || maxRunCount<0) { 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; /* invalid arguments */ 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate memory for the object */ 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi=(UBiDi *)uprv_malloc(sizeof(UBiDi)); 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi==NULL) { 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the object, all pointers NULL, all flags FALSE, all sizes 0 */ 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(pBiDi, 0, sizeof(UBiDi)); 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get BiDi properties */ 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->bdp=ubidi_getSingleton(); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate memory for arrays as requested */ 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(maxLength>0) { 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( !getInitialDirPropsMemory(pBiDi, maxLength) || 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org !getInitialLevelsMemory(pBiDi, maxLength) 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->mayAllocateText=TRUE; 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(maxRunCount>0) { 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(maxRunCount==1) { 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* use simpleRuns[] */ 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runsSize=sizeof(Run); 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(!getInitialRunsMemory(pBiDi, maxRunCount)) { 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->mayAllocateRuns=TRUE; 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*pErrorCode)) { 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi; 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_close(pBiDi); 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We are allowed to allocate memory if memory==NULL or 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * mayAllocate==TRUE for each array that we need. 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We also try to grow memory as needed if we 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * allocate it. 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Assume sizeNeeded>0. 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If *pMemory!=NULL, then assume *pSize>0. 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ### this realloc() may unnecessarily copy the old data, 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * which we know we don't need any more; 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is this the best way to do this?? 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBool 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getMemory(BidiMemoryForAllocation *bidiMem, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded) { 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void **pMemory = (void **)bidiMem; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check for existing memory */ 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pMemory==NULL) { 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we need to allocate memory */ 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(mayAllocate && (*pMemory=uprv_malloc(sizeNeeded))!=NULL) { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pSize=sizeNeeded; 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sizeNeeded<=*pSize) { 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* there is already enough memory */ 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(!mayAllocate) { 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* not enough memory, and we must not allocate */ 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we try to grow */ 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *memory; 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* in most cases, we do not need the copy-old-data part of 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * realloc, but it is needed when adding runs using getRunsMemory() 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in setParaRunsOnly() 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((memory=uprv_realloc(*pMemory, sizeNeeded))!=NULL) { 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pMemory=memory; 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pSize=sizeNeeded; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we failed to grow */ 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_close(UBiDi *pBiDi) { 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi!=NULL) { 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pParaBiDi=NULL; /* in case one tries to reuse this block */ 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->dirPropsMemory!=NULL) { 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->dirPropsMemory); 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->levelsMemory!=NULL) { 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->levelsMemory); 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->openingsMemory!=NULL) { 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->openingsMemory); 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->parasMemory!=NULL) { 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->parasMemory); 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->runsMemory!=NULL) { 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->runsMemory); 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->isolatesMemory!=NULL) { 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->isolatesMemory); 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->insertPoints.points!=NULL) { 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi->insertPoints.points); 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pBiDi); 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* set to approximate "inverse BiDi" ---------------------------------------- */ 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setInverse(UBiDi *pBiDi, UBool isInverse) { 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi!=NULL) { 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isInverse=isInverse; 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode = isInverse ? UBIDI_REORDER_INVERSE_NUMBERS_AS_L 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : UBIDI_REORDER_DEFAULT; 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_isInverse(UBiDi *pBiDi) { 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi!=NULL) { 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->isInverse; 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* FOOD FOR THOUGHT: currently the reordering modes are a mixture of 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * algorithm for direct BiDi, algorithm for inverse BiDi and the bizarre 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * concept of RUNS_ONLY which is a double operation. 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It could be advantageous to divide this into 3 concepts: 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a) Operation: direct / inverse / RUNS_ONLY 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * b) Direct algorithm: default / NUMBERS_SPECIAL / GROUP_NUMBERS_WITH_R 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * c) Inverse algorithm: default / INVERSE_LIKE_DIRECT / NUMBERS_SPECIAL 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This would allow combinations not possible today like RUNS_ONLY with 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * NUMBERS_SPECIAL. 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Also allow to set INSERT_MARKS for the direct step of RUNS_ONLY and 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * REMOVE_CONTROLS for the inverse step. 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Not all combinations would be supported, and probably not all do make sense. 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This would need to document which ones are supported and what are the 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * fallbacks for unsupported combinations. 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode) { 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((pBiDi!=NULL) && (reorderingMode >= UBIDI_REORDER_DEFAULT) 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (reorderingMode < UBIDI_REORDER_COUNT)) { 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode = reorderingMode; 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isInverse = (UBool)(reorderingMode == UBIDI_REORDER_INVERSE_NUMBERS_AS_L); 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDiReorderingMode U_EXPORT2 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getReorderingMode(UBiDi *pBiDi) { 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBiDi!=NULL) { 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->reorderingMode; 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_REORDER_DEFAULT; 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions) { 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) { 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reorderingOptions&=~UBIDI_OPTION_INSERT_MARKS; 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBiDi!=NULL) { 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingOptions=reorderingOptions; 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI uint32_t U_EXPORT2 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getReorderingOptions(UBiDi *pBiDi) { 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBiDi!=NULL) { 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->reorderingOptions; 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDiDirection U_EXPORT2 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getBaseDirection(const UChar *text, 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t length){ 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 uchar; 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCharDirection dir; 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( text==NULL || length<-1 ){ 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_NEUTRAL; 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==-1) { 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=u_strlen(text); 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for( i = 0 ; i < length; ) { 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* i is incremented by U16_NEXT */ 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_NEXT(text, i, length, uchar); 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dir = u_charDirection(uchar); 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( dir == U_LEFT_TO_RIGHT ) 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_LTR; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( dir == U_RIGHT_TO_LEFT || dir ==U_RIGHT_TO_LEFT_ARABIC ) 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_RTL; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_NEUTRAL; 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* perform (P2)..(P3) ------------------------------------------------------- */ 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the directionality of the first strong character 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after the last B in prologue, if any. 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Requires prologue!=null. 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic DirProp 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgfirstL_R_AL(UBiDi *pBiDi) { 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *text=pBiDi->prologue; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=pBiDi->proLength; 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 uchar; 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp, result=ON; 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<length; ) { 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* i is incremented by U16_NEXT */ 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_NEXT(text, i, length, uchar); 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=(DirProp)ubidi_getCustomizedClass(pBiDi, uchar); 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result==ON) { 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L || dirProp==R || dirProp==AL) { 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result=dirProp; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==B) { 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result=ON; 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Check that there are enough entries in the array pointed to by pBiDi->paras 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcheckParaCount(UBiDi *pBiDi) { 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count=pBiDi->paraCount; 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->paras==pBiDi->simpleParas) { 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(count<=SIMPLE_PARAS_SIZE) 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!getInitialParasMemory(pBiDi, SIMPLE_PARAS_SIZE * 2)) 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras=pBiDi->parasMemory; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(pBiDi->parasMemory, pBiDi->simpleParas, SIMPLE_PARAS_SIZE * sizeof(Para)); 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!getInitialParasMemory(pBiDi, count * 2)) 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras=pBiDi->parasMemory; 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Get the directional properties for the text, calculate the flags bit-set, and 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * determine the paragraph level if necessary (in pBiDi->paras[i].level). 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * FSI initiators are also resolved and their dirProp replaced with LRI or RLI. 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orggetDirProps(UBiDi *pBiDi) { 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *text=pBiDi->text; 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=pBiDi->dirPropsMemory; /* pBiDi->dirProps is const */ 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i=0, originalLength=pBiDi->originalLength; 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Flags flags=0; /* collect all directionalities in the text */ 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 uchar; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp=0, defaultParaLevel=0; /* initialize to avoid compiler warnings */ 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isDefaultLevel=IS_DEFAULT_LEVEL(pBiDi->paraLevel); 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* for inverse BiDi, the default para level is set to RTL if there is a 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org strong R or AL character at either end of the text */ 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isDefaultLevelInverse=isDefaultLevel && (UBool) 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT || 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL); 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t lastArabicPos=-1; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t controlCount=0; 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool removeBiDiControls = (UBool)(pBiDi->reorderingOptions & 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBIDI_OPTION_REMOVE_CONTROLS); 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org typedef enum { 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NOT_SEEKING_STRONG, /* 0: not contextual paraLevel, not after FSI */ 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SEEKING_STRONG_FOR_PARA, /* 1: looking for first strong char in para */ 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SEEKING_STRONG_FOR_FSI, /* 2: looking for first strong after FSI */ 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LOOKING_FOR_PDI /* 3: found strong after FSI, looking for PDI */ 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } State; 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org State state; 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp lastStrong=ON; /* for default level & inverse BiDi */ 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The following stacks are used to manage isolate sequences. Those 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sequences may be nested, but obviously never more deeply than the 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maximum explicit embedding level. 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStack is the index of the last used entry in the stack. A value of -1 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org means that there is no open isolate sequence. 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStack is reset to -1 on paragraph boundaries. */ 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The following stack contains the position of the initiator of 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org each open isolate sequence */ 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t isolateStartStack[UBIDI_MAX_EXPLICIT_LEVEL+1]; 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The following stack contains the last known state before 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org encountering the initiator of an isolate sequence */ 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t previousStateStack[UBIDI_MAX_EXPLICIT_LEVEL+1]; 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t stackLast=-1; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->length=0; 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultParaLevel=pBiDi->paraLevel&1; 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isDefaultLevel) { 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[0].level=defaultParaLevel; 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStrong=defaultParaLevel; 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->proLength>0 && /* there is a prologue */ 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (dirProp=firstL_R_AL(pBiDi))!=ON) { /* with a strong character */ 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L) 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[0].level=0; /* set the default para level */ 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[0].level=1; /* set the default para level */ 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=NOT_SEEKING_STRONG; 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=SEEKING_STRONG_FOR_PARA; 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[0].level=pBiDi->paraLevel; 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=NOT_SEEKING_STRONG; 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* count paragraphs and determine the paragraph level (P2..P3) */ 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * see comment in ubidi.h: 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the UBIDI_DEFAULT_XXX values are designed so that 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * their bit 0 alone yields the intended default 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for( /* i=0 above */ ; i<originalLength; ) { 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* i is incremented by U16_NEXT */ 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_NEXT(text, i, originalLength, uchar); 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(dirProp=(DirProp)ubidi_getCustomizedClass(pBiDi, uchar)); 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i-1]=dirProp; 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(uchar>0xffff) { /* set the lead surrogate's property to BN */ 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(BN); 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i-2]=BN; 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(removeBiDiControls && IS_BIDI_CONTROL_CHAR(uchar)) 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org controlCount++; 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L) { 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(state==SEEKING_STRONG_FOR_PARA) { 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=0; 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=NOT_SEEKING_STRONG; 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(state==SEEKING_STRONG_FOR_FSI) { 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast<=UBIDI_MAX_EXPLICIT_LEVEL) { 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[isolateStartStack[stackLast]]=LRI; 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(LRI); 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=LOOKING_FOR_PDI; 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStrong=L; 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==R || dirProp==AL) { 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(state==SEEKING_STRONG_FOR_PARA) { 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=1; 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=NOT_SEEKING_STRONG; 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(state==SEEKING_STRONG_FOR_FSI) { 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast<=UBIDI_MAX_EXPLICIT_LEVEL) { 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[isolateStartStack[stackLast]]=RLI; 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(RLI); 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=LOOKING_FOR_PDI; 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStrong=R; 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==AL) 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastArabicPos=i-1; 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp>=FSI && dirProp<=RLI) { /* FSI, LRI or RLI */ 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast++; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast<=UBIDI_MAX_EXPLICIT_LEVEL) { 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateStartStack[stackLast]=i-1; 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousStateStack[stackLast]=state; 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==FSI) 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=SEEKING_STRONG_FOR_FSI; 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=LOOKING_FOR_PDI; 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==PDI) { 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(state==SEEKING_STRONG_FOR_FSI) { 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast<=UBIDI_MAX_EXPLICIT_LEVEL) { 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[isolateStartStack[stackLast]]=LRI; 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(LRI); 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast>=0) { 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast<=UBIDI_MAX_EXPLICIT_LEVEL) 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=previousStateStack[stackLast]; 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast--; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==B) { 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<originalLength && uchar==CR && text[i]==LF) /* do nothing on the CR */ 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].limit=i; 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isDefaultLevelInverse && lastStrong==R) 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=1; 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) { 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* When streaming, we only process whole paragraphs 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org thus some updates are only done on paragraph boundaries */ 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->length=i; /* i is index to next character */ 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->controlCount=controlCount; 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<originalLength) { /* B not last char in text */ 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraCount++; 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(checkParaCount(pBiDi)==FALSE) /* not enough memory for a new para entry */ 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isDefaultLevel) { 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=defaultParaLevel; 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=SEEKING_STRONG_FOR_PARA; 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastStrong=defaultParaLevel; 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=pBiDi->paraLevel; 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=NOT_SEEKING_STRONG; 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast=-1; 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Ignore still open isolate sequences with overflow */ 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast>UBIDI_MAX_EXPLICIT_LEVEL) { 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast=UBIDI_MAX_EXPLICIT_LEVEL; 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProps[previousStateStack[UBIDI_MAX_EXPLICIT_LEVEL]]!=FSI) 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=LOOKING_FOR_PDI; 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Resolve direction of still unresolved open FSI sequences */ 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(stackLast>=0) { 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(state==SEEKING_STRONG_FOR_FSI) { 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[isolateStartStack[stackLast]]=LRI; 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(LRI); 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org state=previousStateStack[stackLast]; 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast--; 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* When streaming, ignore text after the last paragraph separator */ 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) { 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->length<originalLength) 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraCount--; 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].limit=originalLength; 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->controlCount=controlCount; 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* For inverse bidi, default para direction is RTL if there is 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org a strong R or AL at either end of the paragraph */ 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isDefaultLevelInverse && lastStrong==R) { 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras[pBiDi->paraCount-1].level=1; 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isDefaultLevel) { 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel=pBiDi->paras[0].level; 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The following is needed to resolve the text direction for default level 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org paragraphs containing no strong character */ 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<pBiDi->paraCount; i++) 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_LR(pBiDi->paras[i].level); 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->orderParagraphsLTR && (flags&DIRPROP_FLAG(B))) { 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(L); 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->flags=flags; 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->lastArabicPos=lastArabicPos; 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* determine the paragraph level at position index */ 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBiDiLevel 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getParaLevelAtIndex(const UBiDi *pBiDi, int32_t pindex) { 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<pBiDi->paraCount; i++) 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pindex<pBiDi->paras[i].limit) 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i>=pBiDi->paraCount) 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=pBiDi->paraCount-1; 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UBiDiLevel)(pBiDi->paras[i].level); 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Functions for handling paired brackets ----------------------------------- */ 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In the isoRuns array, the first entry is used for text outside of any 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolate sequence. Higher entries are used for each more deeply nested 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolate sequence. isoRunLast is the index of the last used entry. The 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org openings array is used to note the data of opening brackets not yet 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matched by a closing bracket, or matched but still susceptible to change 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level. 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Each isoRun entry contains the index of the first and 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org one-after-last openings entries for pending opening brackets it 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org contains. The next openings entry to use is the one-after-last of the 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org most deeply nested isoRun entry. 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isoRun entries also contain their current embedding level and the last 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org encountered strong character, since these will be needed to resolve 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the level of paired brackets. */ 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketInit(UBiDi *pBiDi, BracketData *bd) { 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->pBiDi=pBiDi; 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRunLast=0; 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].start=0; 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].limit=0; 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].level=GET_PARALEVEL(pBiDi, 0); 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].lastStrong=bd->isoRuns[0].contextDir=GET_PARALEVEL(pBiDi, 0)&1; 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].lastStrongPos=bd->isoRuns[0].contextPos=0; 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->openingsMemory) { 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings=pBiDi->openingsMemory; 674d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174jshin@chromium.org bd->openingsCount=pBiDi->openingsSize / sizeof(Opening); 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings=bd->simpleOpenings; 677d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174jshin@chromium.org bd->openingsCount=SIMPLE_OPENINGS_SIZE; 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isNumbersSpecial=bd->pBiDi->reorderingMode==UBIDI_REORDER_NUMBERS_SPECIAL || 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL; 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* paragraph boundary */ 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketProcessB(BracketData *bd, UBiDiLevel level) { 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRunLast=0; 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].limit=0; 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].level=level; 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].lastStrong=bd->isoRuns[0].contextDir=level&1; 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRuns[0].lastStrongPos=bd->isoRuns[0].contextPos=0; 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* LRE, LRO, RLE, RLO, PDF */ 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketProcessBoundary(BracketData *bd, int32_t lastCcPos, 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel contextLevel, UBiDiLevel embeddingLevel) { 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IsoRun *pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=bd->pBiDi->dirProps; 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(DIRPROP_FLAG(dirProps[lastCcPos])&MASK_ISO) /* after an isolate */ 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)> 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (contextLevel&~UBIDI_LEVEL_OVERRIDE)) /* not a PDF */ 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org contextLevel=embeddingLevel; 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->limit=pLastIsoRun->start; 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->level=embeddingLevel; 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrong=pLastIsoRun->contextDir=contextLevel&1; 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrongPos=pLastIsoRun->contextPos=lastCcPos; 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* LRI or RLI */ 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketProcessLRI_RLI(BracketData *bd, UBiDiLevel level) { 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IsoRun *pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int16_t lastLimit; 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastLimit=pLastIsoRun->limit; 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRunLast++; 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun++; 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->start=pLastIsoRun->limit=lastLimit; 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->level=level; 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrong=pLastIsoRun->contextDir=level&1; 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrongPos=pLastIsoRun->contextPos=0; 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* PDI */ 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketProcessPDI(BracketData *bd) { 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->isoRunLast--; 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* newly found opening bracket: create an openings entry */ 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool /* return TRUE if success */ 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketAddOpening(BracketData *bd, UChar match, int32_t position) { 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IsoRun *pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Opening *pOpening; 735d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174jshin@chromium.org if(pLastIsoRun->limit>=bd->openingsCount) { /* no available new entry */ 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDi *pBiDi=bd->pBiDi; 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!getInitialOpeningsMemory(pBiDi, pLastIsoRun->limit * 2)) 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(bd->openings==bd->simpleOpenings) 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(pBiDi->openingsMemory, bd->simpleOpenings, 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SIMPLE_OPENINGS_SIZE * sizeof(Opening)); 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings=pBiDi->openingsMemory; /* may have changed */ 743d2abf6c1e1f986f4a8db0341b8a8c55c55ec1174jshin@chromium.org bd->openingsCount=pBiDi->openingsSize / sizeof(Opening); 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening=&bd->openings[pLastIsoRun->limit]; 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->position=position; 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->match=match; 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->contextDir=pLastIsoRun->contextDir; 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->contextPos=pLastIsoRun->contextPos; 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->flags=0; 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->limit++; 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* change N0c1 to N0c2 when a preceding bracket is assigned the embedding level */ 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgfixN0c(BracketData *bd, int32_t openingIndex, int32_t newPropPosition, DirProp newProp) { 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* This function calls itself recursively */ 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IsoRun *pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Opening *qOpening; 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=bd->pBiDi->dirProps; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t k, openingPosition, closingPosition; 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=openingIndex+1, qOpening=&bd->openings[k]; k<pLastIsoRun->limit; k++, qOpening++) { 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(qOpening->match>=0) /* not an N0c match */ 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newPropPosition<qOpening->contextPos) 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newPropPosition>=qOpening->position) 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newProp==qOpening->contextDir) 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org openingPosition=qOpening->position; 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[openingPosition]=dirProps[newPropPosition]; 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org closingPosition=-(qOpening->match); 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[closingPosition]= newProp; /* can never be AL */ 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org qOpening->match=0; /* prevent further changes */ 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fixN0c(bd, k, openingPosition, newProp); 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fixN0c(bd, k, closingPosition, newProp); 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* handle strong characters, digits and candidates for closing brackets */ 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool /* return TRUE if success */ 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbracketProcessChar(BracketData *bd, int32_t position, DirProp dirProp) { 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IsoRun *pLastIsoRun; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Opening *pOpening, *qOpening; 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps, newProp; 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiDirection direction; 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t flag; 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, k; 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool stable; 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c, match; 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps=bd->pBiDi->dirProps; 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(DIRPROP_FLAG(dirProp)&MASK_STRONG_EN_AN) { /* L, R, AL, EN or AN */ 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* AN after R or AL becomes R or AL; after L or L+AN, it is kept as-is */ 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==AN && (pLastIsoRun->lastStrong==R || pLastIsoRun->lastStrong==AL)) 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=pLastIsoRun->lastStrong; 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* EN after L or L+AN becomes L; after R or AL, it becomes R or AL */ 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==EN) { 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pLastIsoRun->lastStrong==L || pLastIsoRun->lastStrong==AN) { 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=L; 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bd->isNumbersSpecial) 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[position]=ENL; 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=pLastIsoRun->lastStrong; /* may be R or AL */ 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bd->isNumbersSpecial) 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[position]= dirProp==AL ? AN : ENR; 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrong=dirProp; 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->contextDir=DIR_FROM_STRONG(dirProp); 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->lastStrongPos=pLastIsoRun->contextPos=position; 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==AL || dirProp==AN) 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=R; 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flag=DIRPROP_FLAG(dirProp); 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* strong characters found after an unmatched opening bracket 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org must be noted for possibly applying N0b */ 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=pLastIsoRun->start; i<pLastIsoRun->limit; i++) 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings[i].flags|=flag; 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp!=ON) 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* First see if it is a matching closing bracket. Hopefully, this is more 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org efficient than checking if it is a closing bracket at all */ 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=bd->pBiDi->text[position]; 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun=&bd->isoRuns[bd->isoRunLast]; 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=pLastIsoRun->limit-1; i>=pLastIsoRun->start; i--) { 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(bd->openings[i].match!=c) 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* We have a match */ 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening=&bd->openings[i]; 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction=pLastIsoRun->level&1; 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stable=TRUE; /* assume stable until proved otherwise */ 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The stable flag is set when brackets are paired and their 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level is resolved and cannot be changed by what will be 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org found later in the source string. 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org An unstable match can occur only when applying N0c, where 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the resolved level depends on the preceding context, and 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this context may be affected by text occurring later. 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Example: RTL paragraph containing: abc[(latin) HEBREW] 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org When the closing parenthesis is encountered, it appears 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org that N0c1 must be applied since 'abc' sets an opposite 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction context and both parentheses receive level 2. 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org However, when the closing square bracket is processed, 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org N0b applies because of 'HEBREW' being included within the 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org brackets, thus the square brackets are treated like R and 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org receive level 1. However, this changes the preceding 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context of the opening parenthesis, and it now appears 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org that N0c2 must be applied to the parentheses rather than 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org N0c1. */ 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((direction==0 && pOpening->flags&FOUND_L) || 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (direction==1 && pOpening->flags&FOUND_R)) { /* N0b */ 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newProp=direction; 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(pOpening->flags&(FOUND_L|FOUND_R)) { /* N0c */ 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(direction!=pOpening->contextDir) { 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newProp=pOpening->contextDir; /* N0c1 */ 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* it is stable if there is no preceding text or in 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org conditions too complicated and not worth checking */ 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stable=(i==pLastIsoRun->start); 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newProp=direction; /* N0c2 */ 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newProp=BN; /* N0d */ 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newProp!=BN) { 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[pOpening->position]=newProp; 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[position]=newProp; 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->contextDir=newProp; 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->contextPos=position; 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Update nested N0c pairs that may be affected */ 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newProp==direction) 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fixN0c(bd, i, pOpening->position, newProp); 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stable) { 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->limit=i; /* forget any brackets nested within this pair */ 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remove lower located synonyms if any */ 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(pLastIsoRun->limit>pLastIsoRun->start && 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings[pLastIsoRun->limit-1].position==pOpening->position) 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLastIsoRun->limit--; 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pOpening->match=-position; 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* neutralize lower located synonyms if any */ 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org k=i-1; 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(k>=pLastIsoRun->start && 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings[k].position==pOpening->position) 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bd->openings[k--].match=0; 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* neutralize any unmatched opening between the current pair; 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org this will also neutralize higher located synonyms if any */ 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=i+1; k<pLastIsoRun->limit; k++) { 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org qOpening=&bd->openings[k]; 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(qOpening->position>=position) 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(qOpening->match>0) 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org qOpening->match=0; 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* We get here only if the ON character was not a matching closing bracket */ 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Now see if it is an opening bracket */ 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org match=u_getBidiPairedBracket(c); /* get the matching char */ 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match==c) /* if no matching char */ 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(ubidi_getPairedBracketType(bd->pBiDi->bdp, c)!=U_BPT_OPEN) 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; /* not an opening bracket */ 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* special case: process synonyms 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org create an opening entry for each synonym */ 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(match==0x232A) { /* RIGHT-POINTING ANGLE BRACKET */ 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bracketAddOpening(bd, 0x3009, position)) 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(match==0x3009) { /* RIGHT ANGLE BRACKET */ 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bracketAddOpening(bd, 0x232A, position)) 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return bracketAddOpening(bd, match, position); 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* perform (X1)..(X9) ------------------------------------------------------- */ 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* determine if the text is mixed-directional or single-directional */ 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBiDiDirection 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdirectionFromFlags(UBiDi *pBiDi) { 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Flags flags=pBiDi->flags; 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if the text contains AN and neutrals, then some neutrals may become RTL */ 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(flags&MASK_RTL || ((flags&DIRPROP_FLAG(AN)) && (flags&MASK_POSSIBLE_N)))) { 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_LTR; 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(!(flags&MASK_LTR)) { 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_RTL; 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_MIXED; 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Resolve the explicit levels as specified by explicit embedding codes. 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Recalculate the flags to have them reflect the real properties 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after taking the explicit embeddings into account. 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The BiDi algorithm is designed to result in the same behavior whether embedding 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * levels are externally specified (from "styled text", supposedly the preferred 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * method) or set by explicit embedding codes (LRx, RLx, PDF, FSI, PDI) in the plain text. 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * That is why (X9) instructs to remove all not-isolate explicit codes (and BN). 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * However, in a real implementation, the removal of these codes and their index 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * positions in the plain text is undesirable since it would result in 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * reallocated, reindexed text. 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Instead, this implementation leaves the codes in there and just ignores them 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in the subsequent processing. 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In order to get the same reordering behavior, positions with a BN or a not-isolate 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * explicit embedding code just get the same level assigned as the last "real" 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * character. 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Some implementations, not this one, then overwrite some of these 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * directionality properties at "real" same-level-run boundaries by 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * L or R codes so that the resolution of weak types can be performed on the 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * entire paragraph at once instead of having to parse it once more and 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * perform that resolution on same-level-runs. 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This limits the scope of the implicit rules in effectively 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the same way as the run limits. 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Instead, this implementation does not modify these codes, except for 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * paired brackets whose properties (ON) may be replaced by L or R. 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * On one hand, the paragraph has to be scanned for same-level-runs, but 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * on the other hand, this saves another loop to reset these codes, 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or saves making and modifying a copy of dirProps[]. 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Note that (Pn) and (Xn) changed significantly from version 4 of the BiDi algorithm. 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Handling the stack of explicit levels (Xn): 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * With the BiDi stack of explicit levels, as pushed with each 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * LRE, RLE, LRO, RLO, LRI, RLI and FSO and popped with each PDF and PDI, 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the explicit level must never exceed UBIDI_MAX_EXPLICIT_LEVEL. 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In order to have a correct push-pop semantics even in the case of overflows, 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * overflow counters and a valid isolate counter are used as described in UAX#9 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * section 3.3.2 "Explicit Levels and Directions". 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This implementation assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd. 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBiDiDirection 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgresolveExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) { 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=pBiDi->dirProps; 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *levels=pBiDi->levels; 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *text=pBiDi->text; 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i=0, length=pBiDi->length; 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Flags flags=pBiDi->flags; /* collect all directionalities in the text */ 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel level=GET_PARALEVEL(pBiDi, 0); 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiDirection direction; 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount=0; 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { return UBIDI_LTR; } 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* determine if the text is mixed-directional or single-directional */ 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction=directionFromFlags(pBiDi); 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we may not need to resolve any explicit levels */ 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((direction!=UBIDI_MIXED)) { 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* not mixed directionality: levels don't matter - trailingWSStart will be 0 */ 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return direction; 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingMode > UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL) { 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* inverse BiDi: mixed, but all characters are at the same embedding level */ 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set all levels to the paragraph level */ 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t paraIndex, start, limit; 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(paraIndex=0; paraIndex<pBiDi->paraCount; paraIndex++) { 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(paraIndex==0) 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=pBiDi->paras[paraIndex-1].limit; 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=pBiDi->paras[paraIndex].limit; 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pBiDi->paras[paraIndex].level; 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=start; i<limit; i++) 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=level; 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return direction; /* no bracket matching for inverse BiDi */ 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(flags&(MASK_EXPLICIT|MASK_ISO))) { 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no embeddings, set all levels to the paragraph level */ 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we still have to perform bracket matching */ 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t paraIndex, start, limit; 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org BracketData bracketData; 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketInit(pBiDi, &bracketData); 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(paraIndex=0; paraIndex<pBiDi->paraCount; paraIndex++) { 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(paraIndex==0) 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=pBiDi->paras[paraIndex-1].limit; 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=pBiDi->paras[paraIndex].limit; 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pBiDi->paras[paraIndex].level; 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=start; i<limit; i++) { 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=level; 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=dirProps[i]; 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==B) { 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((i+1)<length) { 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(text[i]==CR && text[i+1]==LF) 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; /* skip CR when followed by LF */ 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessB(&bracketData, level); 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bracketProcessChar(&bracketData, i, dirProp)) { 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_LTR; 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return direction; 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* continue to perform (Xn) */ 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* (X1) level is set for all codes, embeddingLevel keeps track of the push/pop operations */ 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* both variables may carry the UBIDI_LEVEL_OVERRIDE flag to indicate the override status */ 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel embeddingLevel=level, newLevel; 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel previousLevel=level; /* previous level for regular (not CC) characters */ 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t lastCcPos=0; /* index of last effective LRx,RLx, PDx */ 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t stack[UBIDI_MAX_EXPLICIT_LEVEL+2]; /* we never push anything >=UBIDI_MAX_EXPLICIT_LEVEL 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org but we need one more entry as base */ 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t stackLast=0; 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t overflowIsolateCount=0; 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t overflowEmbeddingCount=0; 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t validIsolateCount=0; 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org BracketData bracketData; 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketInit(pBiDi, &bracketData); 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stack[0]=level; /* initialize base entry to para level, no override, no isolate */ 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* recalculate the flags */ 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags=0; 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<length; ++i) { 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=dirProps[i]; 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(dirProp) { 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case LRE: 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case RLE: 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case LRO: 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case RLO: 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* (X2, X3, X4, X5) */ 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(BN); 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (dirProp==LRE || dirProp==LRO) 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newLevel=(UBiDiLevel)((embeddingLevel+2)&~(UBIDI_LEVEL_OVERRIDE|1)); /* least greater even level */ 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newLevel=(UBiDiLevel)(((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)+1)|1); /* least greater odd level */ 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL && overflowIsolateCount==0 && 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount==0) { 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastCcPos=i; 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org embeddingLevel=newLevel; 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==LRO || dirProp==RLO) 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org embeddingLevel|=UBIDI_LEVEL_OVERRIDE; 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast++; 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stack[stackLast]=embeddingLevel; 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we don't need to set UBIDI_LEVEL_OVERRIDE off for LRE and RLE 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org since this has already been done for newLevel which is 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the source for embeddingLevel. 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(overflowIsolateCount==0) 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount++; 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case PDF: 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* (X7) */ 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(BN); 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* handle all the overflow cases first */ 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(overflowIsolateCount) { 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(overflowEmbeddingCount) { 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount--; 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackLast>0 && stack[stackLast]<ISOLATE) { /* not an isolate entry */ 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastCcPos=i; 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast--; 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org embeddingLevel=(UBiDiLevel)stack[stackLast]; 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case LRI: 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case RLI: 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(embeddingLevel!=previousLevel) { 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessBoundary(&bracketData, lastCcPos, 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel, embeddingLevel); 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel=embeddingLevel; 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* (X5a, X5b) */ 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|= DIRPROP_FLAG(ON) | DIRPROP_FLAG(BN) | DIRPROP_FLAG_LR(embeddingLevel); 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=embeddingLevel; 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==LRI) 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newLevel=(UBiDiLevel)((embeddingLevel+2)&~(UBIDI_LEVEL_OVERRIDE|1)); /* least greater even level */ 11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newLevel=(UBiDiLevel)(((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)+1)|1); /* least greater odd level */ 11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL && overflowIsolateCount==0 && 11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount==0) { 11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastCcPos=i; 11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel=embeddingLevel; 11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org validIsolateCount++; 11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(validIsolateCount>pBiDi->isolateCount) 11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount=validIsolateCount; 11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org embeddingLevel=newLevel; 11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast++; 11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stack[stackLast]=embeddingLevel+ISOLATE; 11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessLRI_RLI(&bracketData, embeddingLevel); 11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowIsolateCount++; 11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case PDI: 11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(embeddingLevel!=previousLevel) { 11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessBoundary(&bracketData, lastCcPos, 11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel, embeddingLevel); 11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* (X6a) */ 11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(overflowIsolateCount) { 11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowIsolateCount--; 11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(validIsolateCount) { 11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastCcPos=i; 11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount=0; 11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(stack[stackLast]<ISOLATE) /* pop embedding entries */ 11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast--; /* until the last isolate entry */ 11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast--; /* pop also the last isolate entry */ 11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org validIsolateCount--; 11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessPDI(&bracketData); 11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else 11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProps[i]|=IGNORE_CC; 11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org embeddingLevel=(UBiDiLevel)stack[stackLast]&~ISOLATE; 11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel=level=embeddingLevel; 11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|= DIRPROP_FLAG(ON) | DIRPROP_FLAG(BN) | DIRPROP_FLAG_LR(embeddingLevel); 11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case B: 11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=GET_PARALEVEL(pBiDi, i); 11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((i+1)<length) { 11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(text[i]==CR && text[i+1]==LF) 11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; /* skip CR when followed by LF */ 11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflowEmbeddingCount=overflowIsolateCount=0; 11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org validIsolateCount=0; 11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackLast=0; 11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stack[0]=level; /* initialize base entry to para level, no override, no isolate */ 11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel=embeddingLevel=GET_PARALEVEL(pBiDi, i+1); 12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessB(&bracketData, embeddingLevel); 12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(B); 12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case BN: 12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* BN, LRE, RLE, and PDF are supposed to be removed (X9) */ 12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* they will get their levels set correctly in adjustWSLevels() */ 12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(BN); 12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all other types get the "real" level */ 12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=embeddingLevel; 12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(embeddingLevel!=previousLevel) { 12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bracketProcessBoundary(&bracketData, lastCcPos, 12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel, embeddingLevel); 12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org previousLevel=embeddingLevel; 12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(level&UBIDI_LEVEL_OVERRIDE) 12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_LR(level); 12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(dirProp); 12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!bracketProcessChar(&bracketData, i, dirProp)) 12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to set reasonable levels even on BN codes and 12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * explicit codes because we will later look at same-level runs (X10). 12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=level; 12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i>0 && levels[i-1]!=level) { 12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_MULTI_RUNS; 12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(level&UBIDI_LEVEL_OVERRIDE) 12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_O(level); 12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_E(level); 12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(DIRPROP_FLAG(dirProp)&MASK_ISO) 12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=embeddingLevel; 12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flags&MASK_EMBEDDING) { 12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel); 12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->orderParagraphsLTR && (flags&DIRPROP_FLAG(B))) { 12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG(L); 12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* subsequently, ignore the explicit codes and BN (X9) */ 12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* again, determine if the text is mixed-directional or single-directional */ 12516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->flags=flags; 12526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction=directionFromFlags(pBiDi); 12536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return direction; 12556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 12586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Use a pre-specified embedding levels array: 12596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Adjust the directional properties for overrides (->LEVEL_OVERRIDE), 12616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ignore all explicit codes (X9), 12626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and check all the preset levels. 12636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Recalculate the flags to have them reflect the real properties 12656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after taking the explicit embeddings into account. 12666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBiDiDirection 12686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcheckExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) { 12696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=pBiDi->dirProps; 12706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 12716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *levels=pBiDi->levels; 12726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t isolateCount=0; 12736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, length=pBiDi->length; 12756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Flags flags=0; /* collect all directionalities in the text */ 12766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel level; 12776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount=0; 12786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<length; ++i) { 12806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=levels[i]; 12816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=dirProps[i]; 12826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==LRI || dirProp==RLI) { 12836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateCount++; 12846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isolateCount>pBiDi->isolateCount) 12856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount=isolateCount; 12866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(dirProp==PDI) 12886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateCount--; 12896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if(dirProp==B) 12906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateCount=0; 12916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(level&UBIDI_LEVEL_OVERRIDE) { 12926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* keep the override flag in levels[i] but adjust the flags */ 12936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level&=~UBIDI_LEVEL_OVERRIDE; /* make the range check below simpler */ 12946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_O(level); 12956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 12966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the flags */ 12976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG(dirProp); 12986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((level<GET_PARALEVEL(pBiDi, i) && 13006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org !((0==level)&&(dirProp==B))) || 13016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (UBIDI_MAX_EXPLICIT_LEVEL<level)) { 13026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* level out of bounds */ 13036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 13046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_LTR; 13056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flags&MASK_EMBEDDING) { 13086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel); 13096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* determine if the text is mixed-directional or single-directional */ 13126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->flags=flags; 13136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return directionFromFlags(pBiDi); 13146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/****************************************************************** 13176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org The Properties state machine table 13186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 13196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org All table cells are 8 bits: 13216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bits 0..4: next state 13226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bits 5..7: action to perform (if > 0) 13236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Cells may be of format "n" where n represents the next state 13256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (except for the rightmost column). 13266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Cells may also be of format "s(x,y)" where x represents an action 13276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org to perform and y represents the next state. 13286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 13306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Definitions and type for properties state table 13316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 13326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 13336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IMPTABPROPS_COLUMNS 16 13346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IMPTABPROPS_RES (IMPTABPROPS_COLUMNS - 1) 13356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_STATEPROPS(cell) ((cell)&0x1f) 13366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_ACTIONPROPS(cell) ((cell)>>5) 13376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define s(action, newState) ((uint8_t)(newState+(action<<5))) 13386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const uint8_t groupProp[] = /* dirProp regrouped */ 13406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 13416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN FSI LRI RLI PDI ENL ENR */ 13426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0, 1, 2, 7, 8, 3, 9, 6, 5, 4, 4, 10, 10, 12, 10, 10, 10, 11, 10, 4, 4, 4, 4, 13, 14 13436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 13446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgenum { DirProp_L=0, DirProp_R=1, DirProp_EN=2, DirProp_AN=3, DirProp_ON=4, DirProp_S=5, DirProp_B=6 }; /* reduced dirProp */ 13456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/****************************************************************** 13476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PROPERTIES STATE TABLE 13496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org In table impTabProps, 13516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org - the ON column regroups ON and WS, FSI, RLI, LRI and PDI 13526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org - the BN column regroups BN, LRE, RLE, LRO, RLO, PDF 13536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org - the Res column is the reduced property assigned to a run 13546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Action 1: process current run1, init new run1 13566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2: init new run2 13576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3: process run1, process run2, init new run1 13586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4: process run1, set run1=run2, init new run2 13596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Notes: 13616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1) This table is used in resolveImplicitLevels(). 13626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2) This table triggers actions when there is a change in the Bidi 13636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org property of incoming characters (action 1). 13646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3) Most such property sequences are processed immediately (in 13656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fact, passed to processPropertySeq(). 13666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4) However, numbers are assembled as one sequence. This means 13676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org that undefined situations (like CS following digits, until 13686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org it is known if the next char will be a digit) are held until 13696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org following chars define them. 13706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Example: digits followed by CS, then comes another CS or ON; 13716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the digits will be processed, then the CS assigned 13726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org as the start of an ON sequence (action 3). 13736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5) There are cases where more than one sequence must be 13746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processed, for instance digits followed by CS followed by L: 13756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the digits must be processed as one sequence, and the CS 13766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org must be processed as an ON sequence, all this before starting 13776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org assembling chars for the opening L sequence. 13786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 13816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const uint8_t impTabProps[][IMPTABPROPS_COLUMNS] = 13826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 13836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , ES , ET , CS , BN , NSM , AL , ENL , ENR , Res */ 13846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 Init */ { 1 , 2 , 4 , 5 , 7 , 15 , 17 , 7 , 9 , 7 , 0 , 7 , 3 , 18 , 21 , DirProp_ON }, 13856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 L */ { 1 , s(1,2), s(1,4), s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), s(1,9), s(1,7), 1 , 1 , s(1,3),s(1,18),s(1,21), DirProp_L }, 13866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 R */ { s(1,1), 2 , s(1,4), s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), s(1,9), s(1,7), 2 , 2 , s(1,3),s(1,18),s(1,21), DirProp_R }, 13876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 AL */ { s(1,1), s(1,2), s(1,6), s(1,6), s(1,8),s(1,16),s(1,17), s(1,8), s(1,8), s(1,8), 3 , 3 , 3 ,s(1,18),s(1,21), DirProp_R }, 13886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 EN */ { s(1,1), s(1,2), 4 , s(1,5), s(1,7),s(1,15),s(1,17),s(2,10), 11 ,s(2,10), 4 , 4 , s(1,3), 18 , 21 , DirProp_EN }, 13896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 AN */ { s(1,1), s(1,2), s(1,4), 5 , s(1,7),s(1,15),s(1,17), s(1,7), s(1,9),s(2,12), 5 , 5 , s(1,3),s(1,18),s(1,21), DirProp_AN }, 13906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6 AL:EN/AN */ { s(1,1), s(1,2), 6 , 6 , s(1,8),s(1,16),s(1,17), s(1,8), s(1,8),s(2,13), 6 , 6 , s(1,3), 18 , 21 , DirProp_AN }, 13916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 7 ON */ { s(1,1), s(1,2), s(1,4), s(1,5), 7 ,s(1,15),s(1,17), 7 ,s(2,14), 7 , 7 , 7 , s(1,3),s(1,18),s(1,21), DirProp_ON }, 13926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 8 AL:ON */ { s(1,1), s(1,2), s(1,6), s(1,6), 8 ,s(1,16),s(1,17), 8 , 8 , 8 , 8 , 8 , s(1,3),s(1,18),s(1,21), DirProp_ON }, 13936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 9 ET */ { s(1,1), s(1,2), 4 , s(1,5), 7 ,s(1,15),s(1,17), 7 , 9 , 7 , 9 , 9 , s(1,3), 18 , 21 , DirProp_ON }, 13946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*10 EN+ES/CS */ { s(3,1), s(3,2), 4 , s(3,5), s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7), 10 , s(4,7), s(3,3), 18 , 21 , DirProp_EN }, 13956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*11 EN+ET */ { s(1,1), s(1,2), 4 , s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), 11 , s(1,7), 11 , 11 , s(1,3), 18 , 21 , DirProp_EN }, 13966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*12 AN+CS */ { s(3,1), s(3,2), s(3,4), 5 , s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7), 12 , s(4,7), s(3,3),s(3,18),s(3,21), DirProp_AN }, 13976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*13 AL:EN/AN+CS */ { s(3,1), s(3,2), 6 , 6 , s(4,8),s(3,16),s(3,17), s(4,8), s(4,8), s(4,8), 13 , s(4,8), s(3,3), 18 , 21 , DirProp_AN }, 13986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*14 ON+ET */ { s(1,1), s(1,2), s(4,4), s(1,5), 7 ,s(1,15),s(1,17), 7 , 14 , 7 , 14 , 14 , s(1,3),s(4,18),s(4,21), DirProp_ON }, 13996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*15 S */ { s(1,1), s(1,2), s(1,4), s(1,5), s(1,7), 15 ,s(1,17), s(1,7), s(1,9), s(1,7), 15 , s(1,7), s(1,3),s(1,18),s(1,21), DirProp_S }, 14006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*16 AL:S */ { s(1,1), s(1,2), s(1,6), s(1,6), s(1,8), 16 ,s(1,17), s(1,8), s(1,8), s(1,8), 16 , s(1,8), s(1,3),s(1,18),s(1,21), DirProp_S }, 14016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*17 B */ { s(1,1), s(1,2), s(1,4), s(1,5), s(1,7),s(1,15), 17 , s(1,7), s(1,9), s(1,7), 17 , s(1,7), s(1,3),s(1,18),s(1,21), DirProp_B }, 14026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*18 ENL */ { s(1,1), s(1,2), 18 , s(1,5), s(1,7),s(1,15),s(1,17),s(2,19), 20 ,s(2,19), 18 , 18 , s(1,3), 18 , 21 , DirProp_L }, 14036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*19 ENL+ES/CS */ { s(3,1), s(3,2), 18 , s(3,5), s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7), 19 , s(4,7), s(3,3), 18 , 21 , DirProp_L }, 14046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*20 ENL+ET */ { s(1,1), s(1,2), 18 , s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), 20 , s(1,7), 20 , 20 , s(1,3), 18 , 21 , DirProp_L }, 14056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*21 ENR */ { s(1,1), s(1,2), 21 , s(1,5), s(1,7),s(1,15),s(1,17),s(2,22), 23 ,s(2,22), 21 , 21 , s(1,3), 18 , 21 , DirProp_AN }, 14066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*22 ENR+ES/CS */ { s(3,1), s(3,2), 21 , s(3,5), s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7), 22 , s(4,7), s(3,3), 18 , 21 , DirProp_AN }, 14076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*23 ENR+ET */ { s(1,1), s(1,2), 21 , s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), 23 , s(1,7), 23 , 23 , s(1,3), 18 , 21 , DirProp_AN } 14086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 14096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* we must undef macro s because the levels table have a different 14116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * structure (4 bits for action and 4 bits for next state. 14126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#undef s 14146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/****************************************************************** 14166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org The levels state machine tables 14176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 14186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org All table cells are 8 bits: 14206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bits 0..3: next state 14216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bits 4..7: action to perform (if > 0) 14226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Cells may be of format "n" where n represents the next state 14246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (except for the rightmost column). 14256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Cells may also be of format "s(x,y)" where x represents an action 14266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org to perform and y represents the next state. 14276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This format limits each table to 16 states each and to 15 actions. 14296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 14316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Definitions and type for levels state tables 14326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************* 14336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 14346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IMPTABLEVELS_COLUMNS (DirProp_B + 2) 14356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IMPTABLEVELS_RES (IMPTABLEVELS_COLUMNS - 1) 14366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_STATE(cell) ((cell)&0x0f) 14376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_ACTION(cell) ((cell)>>4) 14386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define s(action, newState) ((uint8_t)(newState+(action<<4))) 14396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef uint8_t ImpTab[][IMPTABLEVELS_COLUMNS]; 14416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef uint8_t ImpAct[]; 14426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* FOOD FOR THOUGHT: each ImpTab should have its associated ImpAct, 14446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * instead of having a pair of ImpTab and a pair of ImpAct. 14456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct ImpTabPair { 14476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void * pImpTab[2]; 14486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void * pImpAct[2]; 14496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} ImpTabPair; 14506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/****************************************************************** 14526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LEVELS STATE TABLES 14546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org In all levels state tables, 14566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org - state 0 is the initial state 14576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org - the Res column is the increment to add to the text level 14586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for this property sequence. 14596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org The impAct arrays for each table of a pair map the local action 14616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org numbers of the table to the total list of actions. For instance, 14626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org action 2 in a given table corresponds to the action number which 14636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appears in entry [2] of the impAct array for that table. 14646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org The first entry of all impAct arrays must be 0. 14656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Action 1: init conditional sequence 14676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2: prepend conditional sequence to current sequence 14686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3: set ON sequence to new level - 1 14696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4: init EN/AN/ON sequence 14706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5: fix EN/AN/ON sequence followed by R 14716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6: set previous level sequence to level 2 14726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Notes: 14746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1) These tables are used in processPropertySeq(). The input 14756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org is property sequences as determined by resolveImplicitLevels. 14766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2) Most such property sequences are processed immediately 14776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (levels are assigned). 14786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3) However, some sequences cannot be assigned a final level till 14796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org one or more following sequences are received. For instance, 14806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ON following an R sequence within an even-level paragraph. 14816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org If the following sequence is R, the ON sequence will be 14826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org assigned basic run level+1, and so will the R sequence. 14836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4) S is generally handled like ON, since its level will be fixed 14846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org to paragraph level in adjustWSLevels(). 14856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 14876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_DEFAULT = /* Even paragraph level */ 14896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, conditional sequences receive the higher possible level 14906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven otherwise. 14916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 14926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 14936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 14946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 0 , 1 , 0 , 2 , 0 , 0 , 0 , 0 }, 14956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : R */ { 0 , 1 , 3 , 3 , s(1,4), s(1,4), 0 , 1 }, 14966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : AN */ { 0 , 1 , 0 , 2 , s(1,5), s(1,5), 0 , 2 }, 14976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : R+EN/AN */ { 0 , 1 , 3 , 3 , s(1,4), s(1,4), 0 , 2 }, 14986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : R+ON */ { s(2,0), 1 , 3 , 3 , 4 , 4 , s(2,0), 1 }, 14996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : AN+ON */ { s(2,0), 1 , s(2,0), 2 , 5 , 5 , s(2,0), 1 } 15006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabR_DEFAULT = /* Odd paragraph level */ 15026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, conditional sequences receive the lower possible level 15036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven otherwise. 15046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 1 , 0 , 2 , 2 , 0 , 0 , 0 , 0 }, 15086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L */ { 1 , 0 , 1 , 3 , s(1,4), s(1,4), 0 , 1 }, 15096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : EN/AN */ { 1 , 0 , 2 , 2 , 0 , 0 , 0 , 1 }, 15106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : L+AN */ { 1 , 0 , 1 , 3 , 5 , 5 , 0 , 1 }, 15116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : L+ON */ { s(2,1), 0 , s(2,1), 3 , 4 , 4 , 0 , 0 }, 15126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : L+AN+ON */ { 1 , 0 , 1 , 3 , 5 , 5 , 0 , 0 } 15136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpAct impAct0 = {0,1,2,3,4,5,6}; 15156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_DEFAULT = {{&impTabL_DEFAULT, 15166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_DEFAULT}, 15176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct0}}; 15186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_NUMBERS_SPECIAL = /* Even paragraph level */ 15206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, conditional sequences receive the higher possible level 15216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven otherwise. 15226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 0 , 2 , 1 , 1 , 0 , 0 , 0 , 0 }, 15266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L+EN/AN */ { 0 , 2 , 1 , 1 , 0 , 0 , 0 , 2 }, 15276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : R */ { 0 , 2 , 4 , 4 , s(1,3), 0 , 0 , 1 }, 15286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : R+ON */ { s(2,0), 2 , 4 , 4 , 3 , 3 , s(2,0), 1 }, 15296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : R+EN/AN */ { 0 , 2 , 4 , 4 , s(1,3), s(1,3), 0 , 2 } 15306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 15316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_NUMBERS_SPECIAL = {{&impTabL_NUMBERS_SPECIAL, 15326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_DEFAULT}, 15336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct0}}; 15346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_GROUP_NUMBERS_WITH_R = 15366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, EN/AN+ON sequences receive levels as if associated with R 15376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven that there is L or sor/eor on both sides. AN is handled like EN. 15386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 init */ { 0 , 3 , s(1,1), s(1,1), 0 , 0 , 0 , 0 }, 15426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 EN/AN */ { s(2,0), 3 , 1 , 1 , 2 , s(2,0), s(2,0), 2 }, 15436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 EN/AN+ON */ { s(2,0), 3 , 1 , 1 , 2 , s(2,0), s(2,0), 1 }, 15446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 R */ { 0 , 3 , 5 , 5 , s(1,4), 0 , 0 , 1 }, 15456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 R+ON */ { s(2,0), 3 , 5 , 5 , 4 , s(2,0), s(2,0), 1 }, 15466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 R+EN/AN */ { 0 , 3 , 5 , 5 , s(1,4), 0 , 0 , 2 } 15476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabR_GROUP_NUMBERS_WITH_R = 15496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, EN/AN+ON sequences receive levels as if associated with R 15506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven that there is L on both sides. AN is handled like EN. 15516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 init */ { 2 , 0 , 1 , 1 , 0 , 0 , 0 , 0 }, 15556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 EN/AN */ { 2 , 0 , 1 , 1 , 0 , 0 , 0 , 1 }, 15566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 L */ { 2 , 0 , s(1,4), s(1,4), s(1,3), 0 , 0 , 1 }, 15576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 L+ON */ { s(2,2), 0 , 4 , 4 , 3 , 0 , 0 , 0 }, 15586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 L+EN/AN */ { s(2,2), 0 , 4 , 4 , 3 , 0 , 0 , 1 } 15596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_GROUP_NUMBERS_WITH_R = { 15616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_GROUP_NUMBERS_WITH_R, 15626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_GROUP_NUMBERS_WITH_R}, 15636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct0}}; 15646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_INVERSE_NUMBERS_AS_L = 15676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* This table is identical to the Default LTR table except that EN and AN are 15686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handled like L. 15696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, 15736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : R */ { 0 , 1 , 0 , 0 , s(1,4), s(1,4), 0 , 1 }, 15746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : AN */ { 0 , 1 , 0 , 0 , s(1,5), s(1,5), 0 , 2 }, 15756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : R+EN/AN */ { 0 , 1 , 0 , 0 , s(1,4), s(1,4), 0 , 2 }, 15766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : R+ON */ { s(2,0), 1 , s(2,0), s(2,0), 4 , 4 , s(2,0), 1 }, 15776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : AN+ON */ { s(2,0), 1 , s(2,0), s(2,0), 5 , 5 , s(2,0), 1 } 15786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabR_INVERSE_NUMBERS_AS_L = 15806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* This table is identical to the Default RTL table except that EN and AN are 15816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handled like L. 15826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 15836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 15856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 }, 15866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L */ { 1 , 0 , 1 , 1 , s(1,4), s(1,4), 0 , 1 }, 15876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : EN/AN */ { 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 }, 15886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : L+AN */ { 1 , 0 , 1 , 1 , 5 , 5 , 0 , 1 }, 15896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : L+ON */ { s(2,1), 0 , s(2,1), s(2,1), 4 , 4 , 0 , 0 }, 15906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : L+AN+ON */ { 1 , 0 , 1 , 1 , 5 , 5 , 0 , 0 } 15916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 15926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_INVERSE_NUMBERS_AS_L = { 15936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_INVERSE_NUMBERS_AS_L, 15946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_INVERSE_NUMBERS_AS_L}, 15956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct0}}; 15966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabR_INVERSE_LIKE_DIRECT = /* Odd paragraph level */ 15986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* In this table, conditional sequences receive the lower possible level 15996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org until proven otherwise. 16006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 16016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 16026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 16036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 1 , 0 , 2 , 2 , 0 , 0 , 0 , 0 }, 16046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L */ { 1 , 0 , 1 , 2 , s(1,3), s(1,3), 0 , 1 }, 16056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : EN/AN */ { 1 , 0 , 2 , 2 , 0 , 0 , 0 , 1 }, 16066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : L+ON */ { s(2,1), s(3,0), 6 , 4 , 3 , 3 , s(3,0), 0 }, 16076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : L+ON+AN */ { s(2,1), s(3,0), 6 , 4 , 5 , 5 , s(3,0), 3 }, 16086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : L+AN+ON */ { s(2,1), s(3,0), 6 , 4 , 5 , 5 , s(3,0), 2 }, 16096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6 : L+ON+EN */ { s(2,1), s(3,0), 6 , 4 , 3 , 3 , s(3,0), 1 } 16106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 16116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpAct impAct1 = {0,1,11,12}; 16126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* FOOD FOR THOUGHT: in LTR table below, check case "JKL 123abc" 16136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 16146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_INVERSE_LIKE_DIRECT = { 16156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_DEFAULT, 16166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_INVERSE_LIKE_DIRECT}, 16176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct1}}; 16186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS = 16206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The case handled in this table is (visually): R EN L 16216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 16226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 16236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 16246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 0 , s(6,3), 0 , 1 , 0 , 0 , 0 , 0 }, 16256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L+AN */ { 0 , s(6,3), 0 , 1 , s(1,2), s(3,0), 0 , 4 }, 16266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : L+AN+ON */ { s(2,0), s(6,3), s(2,0), 1 , 2 , s(3,0), s(2,0), 3 }, 16276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : R */ { 0 , s(6,3), s(5,5), s(5,6), s(1,4), s(3,0), 0 , 3 }, 16286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : R+ON */ { s(3,0), s(4,3), s(5,5), s(5,6), 4 , s(3,0), s(3,0), 3 }, 16296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : R+EN */ { s(3,0), s(4,3), 5 , s(5,6), s(1,4), s(3,0), s(3,0), 4 }, 16306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6 : R+AN */ { s(3,0), s(4,3), s(5,5), 6 , s(1,4), s(3,0), s(3,0), 4 } 16316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 16326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS = 16336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The cases handled in this table are (visually): R EN L 16346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org R L AN L 16356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 16366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 16376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 16386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { s(1,3), 0 , 1 , 1 , 0 , 0 , 0 , 0 }, 16396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : R+EN/AN */ { s(2,3), 0 , 1 , 1 , 2 , s(4,0), 0 , 1 }, 16406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : R+EN/AN+ON */ { s(2,3), 0 , 1 , 1 , 2 , s(4,0), 0 , 0 }, 16416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : L */ { 3 , 0 , 3 , s(3,6), s(1,4), s(4,0), 0 , 1 }, 16426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : L+ON */ { s(5,3), s(4,0), 5 , s(3,6), 4 , s(4,0), s(4,0), 0 }, 16436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 5 : L+ON+EN */ { s(5,3), s(4,0), 5 , s(3,6), 4 , s(4,0), s(4,0), 1 }, 16446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6 : L+AN */ { s(5,3), s(4,0), 6 , 6 , 4 , s(4,0), s(4,0), 3 } 16456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 16466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpAct impAct2 = {0,1,7,8,9,10}; 16476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_INVERSE_LIKE_DIRECT_WITH_MARKS = { 16486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS, 16496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS}, 16506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct2}}; 16516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL = { 16536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_NUMBERS_SPECIAL, 16546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_INVERSE_LIKE_DIRECT}, 16556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct1}}; 16566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTab impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS = 16586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The case handled in this table is (visually): R EN L 16596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 16606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 16616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* L , R , EN , AN , ON , S , B , Res */ 16626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 0 : init */ { 0 , s(6,2), 1 , 1 , 0 , 0 , 0 , 0 }, 16636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1 : L+EN/AN */ { 0 , s(6,2), 1 , 1 , 0 , s(3,0), 0 , 4 }, 16646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 2 : R */ { 0 , s(6,2), s(5,4), s(5,4), s(1,3), s(3,0), 0 , 3 }, 16656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 3 : R+ON */ { s(3,0), s(4,2), s(5,4), s(5,4), 3 , s(3,0), s(3,0), 3 }, 16666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4 : R+EN/AN */ { s(3,0), s(4,2), 4 , 4 , s(1,3), s(3,0), s(3,0), 4 } 16676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 16686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS = { 16696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS, 16706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS}, 16716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {&impAct0, &impAct2}}; 16726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#undef s 16746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct { 16766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const ImpTab * pImpTab; /* level table pointer */ 16776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const ImpAct * pImpAct; /* action map array */ 16786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t startON; /* start of ON sequence */ 16796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t startL2EN; /* start of level 2 sequence */ 16806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t lastStrongRTL; /* index of last found R or AL */ 16816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t state; /* current state */ 16826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t runStart; /* start position of the run */ 16836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel runLevel; /* run level before implicit solving */ 16846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} LevState; 16856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*------------------------------------------------------------------------*/ 16876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 16896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgaddPoint(UBiDi *pBiDi, int32_t pos, int32_t flag) 16906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* param pos: position where to insert 16916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org param flag: one of LRM_BEFORE, LRM_AFTER, RLM_BEFORE, RLM_AFTER 16926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 16936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 16946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define FIRSTALLOC 10 16956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Point point; 16966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org InsertPoints * pInsertPoints=&(pBiDi->insertPoints); 16976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pInsertPoints->capacity == 0) 16996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->points=uprv_malloc(sizeof(Point)*FIRSTALLOC); 17016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pInsertPoints->points == NULL) 17026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->errorCode=U_MEMORY_ALLOCATION_ERROR; 17046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 17056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->capacity=FIRSTALLOC; 17076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pInsertPoints->size >= pInsertPoints->capacity) /* no room for new point */ 17096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void * savePoints=pInsertPoints->points; 17116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->points=uprv_realloc(pInsertPoints->points, 17126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->capacity*2*sizeof(Point)); 17136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pInsertPoints->points == NULL) 17146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->points=savePoints; 17166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->errorCode=U_MEMORY_ALLOCATION_ERROR; 17176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 17186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else pInsertPoints->capacity*=2; 17206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org point.pos=pos; 17226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org point.flag=flag; 17236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->points[pInsertPoints->size]=point; 17246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->size++; 17256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#undef FIRSTALLOC 17266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* perform rules (Wn), (Nn), and (In) on a run of the text ------------------ */ 17296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 17316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This implementation of the (Wn) rules applies all rules in one pass. 17326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In order to do so, it needs a look-ahead of typically 1 character 17336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (except for W5: sequences of ET) and keeps track of changes 17346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in a rule Wp that affect a later Wq (p<q). 17356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 17366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The (Nn) and (In) rules are also performed in that same single loop, 17376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * but effectively one iteration behind for white space. 17386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 17396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Since all implicit rules are performed in one step, it is not necessary 17406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to actually store the intermediate directional properties in dirProps[]. 17416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 17426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 17446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprocessPropertySeq(UBiDi *pBiDi, LevState *pLevState, uint8_t _prop, 17456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start, int32_t limit) { 17466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t cell, oldStateSeq, actionSeq; 17476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const ImpTab * pImpTab=pLevState->pImpTab; 17486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const ImpAct * pImpAct=pLevState->pImpAct; 17496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel * levels=pBiDi->levels; 17506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel level, addLevel; 17516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org InsertPoints * pInsertPoints; 17526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start0, k; 17536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start0=start; /* save original start position */ 17556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org oldStateSeq=(uint8_t)pLevState->state; 17566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cell=(*pImpTab)[oldStateSeq][_prop]; 17576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->state=GET_STATE(cell); /* isolate the new state */ 17586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org actionSeq=(*pImpAct)[GET_ACTION(cell)]; /* isolate the action */ 17596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addLevel=(*pImpTab)[pLevState->state][IMPTABLEVELS_RES]; 17606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(actionSeq) { 17626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(actionSeq) { 17636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 1: /* init ON seq */ 17646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startON=start0; 17656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 2: /* prepend ON seq to current seq */ 17686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=pLevState->startON; 17696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 3: /* L or S after possible relevant EN/AN */ 17726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check if we had EN after R/AL */ 17736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pLevState->startL2EN >= 0) { 17746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, pLevState->startL2EN, LRM_BEFORE); 17756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startL2EN=-1; /* not within previous if since could also be -2 */ 17776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check if we had any relevant EN/AN after R/AL */ 17786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints=&(pBiDi->insertPoints); 17796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((pInsertPoints->capacity == 0) || 17806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pInsertPoints->size <= pInsertPoints->confirmed)) 17816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* nothing, just clean up */ 17836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->lastStrongRTL=-1; 17846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check if we have a pending conditional segment */ 17856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=(*pImpTab)[oldStateSeq][IMPTABLEVELS_RES]; 17866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((level & 1) && (pLevState->startON > 0)) { /* after ON */ 17876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=pLevState->startON; /* reset to basic run level */ 17886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (_prop == DirProp_S) /* add LRM before S */ 17906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, LRM_BEFORE); 17926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; 17936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset previous RTL cont to level for LTR text */ 17976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (k=pLevState->lastStrongRTL+1; k<start0; k++) 17986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 17996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset odd level, leave runLevel+2 as is */ 18006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=(levels[k] - 2) & ~1; 18016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* mark insert points as confirmed */ 18036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; 18046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->lastStrongRTL=-1; 18056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (_prop == DirProp_S) /* add LRM before S */ 18066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, LRM_BEFORE); 18086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; 18096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 4: /* R/AL after possible relevant EN/AN */ 18136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* just clean up */ 18146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints=&(pBiDi->insertPoints); 18156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pInsertPoints->capacity > 0) 18166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remove all non confirmed insert points */ 18176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->size=pInsertPoints->confirmed; 18186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startON=-1; 18196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startL2EN=-1; 18206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->lastStrongRTL=limit - 1; 18216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 5: /* EN/AN after R/AL + possible cont */ 18246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check for real AN */ 18256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((_prop == DirProp_AN) && (pBiDi->dirProps[start0] == AN) && 18266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pBiDi->reorderingMode!=UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL)) 18276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* real AN */ 18296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pLevState->startL2EN == -1) /* if no relevant EN already found */ 18306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* just note the righmost digit as a strong RTL */ 18326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->lastStrongRTL=limit - 1; 18336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pLevState->startL2EN >= 0) /* after EN, no AN */ 18366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, pLevState->startL2EN, LRM_BEFORE); 18386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startL2EN=-2; 18396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* note AN */ 18416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, LRM_BEFORE); 18426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if first EN/AN after R/AL */ 18456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pLevState->startL2EN == -1) { 18466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startL2EN=start0; 18476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 6: /* note location of latest R/AL */ 18516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->lastStrongRTL=limit - 1; 18526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startON=-1; 18536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 7: /* L after R+ON/EN/AN */ 18566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* include possible adjacent number on the left */ 18576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (k=start0-1; k>=0 && !(levels[k]&1); k--); 18586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(k>=0) { 18596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, k, RLM_BEFORE); /* add RLM before */ 18606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints=&(pBiDi->insertPoints); 18616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; /* confirm it */ 18626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startON=start0; 18646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 8: /* AN after L */ 18676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* AN numbers between L text on both sides may be trouble. */ 18686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* tentatively bracket with LRMs; will be confirmed if followed by L */ 18696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, LRM_BEFORE); /* add LRM before */ 18706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, LRM_AFTER); /* add LRM after */ 18716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 9: /* R after L+ON/EN/AN */ 18746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* false alert, infirm LRMs around previous AN */ 18756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints=&(pBiDi->insertPoints); 18766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->size=pInsertPoints->confirmed; 18776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (_prop == DirProp_S) /* add RLM before S */ 18786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, start0, RLM_BEFORE); 18806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; 18816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 10: /* L after L+ON/AN */ 18856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pLevState->runLevel + addLevel; 18866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=pLevState->startON; k<start0; k++) { 18876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (levels[k]<level) 18886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=level; 18896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints=&(pBiDi->insertPoints); 18916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInsertPoints->confirmed=pInsertPoints->size; /* confirm inserts */ 18926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pLevState->startON=start0; 18936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 18946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 11: /* L after L+ON+EN/AN/ON */ 18966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pLevState->runLevel; 18976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=start0-1; k>=pLevState->startON; k--) { 18986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(levels[k]==level+3) { 18996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(levels[k]==level+3) { 19006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k--]-=2; 19016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(levels[k]==level) { 19036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org k--; 19046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(levels[k]==level+2) { 19076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=level; 19086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 19096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=level+1; 19116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 19136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 12: /* R after L+ON+EN/AN/ON */ 19156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pLevState->runLevel+1; 19166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=start0-1; k>=pLevState->startON; k--) { 19176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(levels[k]>level) { 19186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]-=2; 19196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 19226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: /* we should never get here */ 19246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(FALSE); 19256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 19266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((addLevel) || (start < start0)) { 19296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pLevState->runLevel + addLevel; 19306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start>=pLevState->runStart) { 19316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=start; k<limit; k++) { 19326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=level; 19336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 19356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp *dirProps=pBiDi->dirProps, dirProp; 19366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t isolateCount=0; 19376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(k=start; k<limit; k++) { 19386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=dirProps[k]; 19396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==PDI) 19406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateCount--; 19416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(isolateCount==0) 19426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[k]=level; 19436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==LRI || dirProp==RLI) 19446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isolateCount++; 19456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 19516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the directionality of the last strong character at the end of the prologue, if any. 19526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Requires prologue!=null. 19536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic DirProp 19556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orglastL_R_AL(UBiDi *pBiDi) { 19566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *text=pBiDi->prologue; 19576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=pBiDi->proLength; 19586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 19596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 uchar; 19606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 19616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=length; i>0; ) { 19626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* i is decremented by U16_PREV */ 19636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_PREV(text, 0, i, uchar); 19646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=(DirProp)ubidi_getCustomizedClass(pBiDi, uchar); 19656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L) { 19666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_L; 19676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==R || dirProp==AL) { 19696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_R; 19706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==B) { 19726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_ON; 19736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_ON; 19766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 19796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the directionality of the first strong character, or digit, in the epilogue, if any. 19806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Requires epilogue!=null. 19816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic DirProp 19836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgfirstL_R_AL_EN_AN(UBiDi *pBiDi) { 19846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *text=pBiDi->epilogue; 19856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=pBiDi->epiLength; 19866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 19876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 uchar; 19886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 19896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<length; ) { 19906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* i is incremented by U16_NEXT */ 19916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_NEXT(text, i, length, uchar); 19926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=(DirProp)ubidi_getCustomizedClass(pBiDi, uchar); 19936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L) { 19946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_L; 19956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==R || dirProp==AL) { 19976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_R; 19986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==EN) { 20006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_EN; 20016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==AN) { 20036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_AN; 20046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return DirProp_ON; 20076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 20086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 20106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgresolveImplicitLevels(UBiDi *pBiDi, 20116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start, int32_t limit, 20126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp sor, DirProp eor) { 20136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DirProp *dirProps=pBiDi->dirProps; 20146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 20156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LevState levState; 20166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, start1, start2; 20176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t oldStateImp, stateImp, actionImp; 20186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t gprop, resProp, cell; 20196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool inverseRTL; 20206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp nextStrongProp=R; 20216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t nextStrongPos=-1; 20226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check for RTL inverse BiDi mode */ 20246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* FOOD FOR THOUGHT: in case of RTL inverse BiDi, it would make sense to 20256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop on the text characters from end to start. 20266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This would need a different properties state table (at least different 20276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * actions) and different levels state tables (maybe very similar to the 20286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * LTR corresponding ones. 20296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 20306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org inverseRTL=(UBool) 20316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((start<pBiDi->lastArabicPos) && (GET_PARALEVEL(pBiDi, start) & 1) && 20326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT || 20336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL)); 20346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize for property and levels state tables */ 20366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.startON=-1; 20376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.startL2EN=-1; /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */ 20386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.lastStrongRTL=-1; /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */ 20396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.runStart=start; 20406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.runLevel=pBiDi->levels[start]; 20416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.pImpTab=(const ImpTab*)((pBiDi->pImpTabPair)->pImpTab)[levState.runLevel&1]; 20426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.pImpAct=(const ImpAct*)((pBiDi->pImpTabPair)->pImpAct)[levState.runLevel&1]; 20436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start==0 && pBiDi->proLength>0) { 20446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp lastStrong=lastL_R_AL(pBiDi); 20456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(lastStrong!=DirProp_ON) { 20466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sor=lastStrong; 20476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The isolates[] entries contain enough information to 20506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resume the bidi algorithm in the same state as it was 20516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org when it was interrupted by an isolate sequence. */ 20526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProps[start]==PDI) { 20536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start1=pBiDi->isolates[pBiDi->isolateCount].start1; 20546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stateImp=pBiDi->isolates[pBiDi->isolateCount].stateImp; 20556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.state=pBiDi->isolates[pBiDi->isolateCount].state; 20566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount--; 20576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 20586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start1=start; 20596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProps[start]==NSM) 20606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stateImp = 1 + sor; 20616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 20626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stateImp=0; 20636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levState.state=0; 20646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, sor, start, start); 20656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start2=start; 20676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=start; i<=limit; i++) { 20696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i>=limit) { 20706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(limit>start) { 20716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=pBiDi->dirProps[limit-1]; 20726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==LRI || dirProp==RLI) 20736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; /* no forced closing for sequence ending with LRI/RLI */ 20746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gprop=eor; 20766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 20776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp prop, prop1; 20786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop=PURE_DIRPROP(dirProps[i]); 20796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(inverseRTL) { 20806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prop==AL) { 20816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* AL before EN does not make it AN */ 20826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop=R; 20836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(prop==EN) { 20846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(nextStrongPos<=i) { 20856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* look for next strong char (L/R/AL) */ 20866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j; 20876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextStrongProp=R; /* set default */ 20886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextStrongPos=limit; 20896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=i+1; j<limit; j++) { 20906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop1=dirProps[j]; 20916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prop1==L || prop1==R || prop1==AL) { 20926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextStrongProp=prop1; 20936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextStrongPos=j; 20946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 20956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(nextStrongProp==AL) { 20996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop=AN; 21006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gprop=groupProp[prop]; 21046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org oldStateImp=stateImp; 21066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cell=impTabProps[oldStateImp][gprop]; 21076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stateImp=GET_STATEPROPS(cell); /* isolate the new state */ 21086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org actionImp=GET_ACTIONPROPS(cell); /* isolate the action */ 21096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((i==limit) && (actionImp==0)) { 21106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* there is an unprocessed sequence if its property == eor */ 21116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org actionImp=1; /* process the last sequence */ 21126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(actionImp) { 21146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resProp=impTabProps[oldStateImp][IMPTABPROPS_RES]; 21156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(actionImp) { 21166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 1: /* process current seq1, init new seq1 */ 21176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, resProp, start1, i); 21186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start1=i; 21196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 2: /* init new seq2 */ 21216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start2=i; 21226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 3: /* process seq1, process seq2, init new seq1 */ 21246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, resProp, start1, start2); 21256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, DirProp_ON, start2, i); 21266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start1=i; 21276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 4: /* process seq1, set seq1=seq2, init new seq2 */ 21296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, resProp, start1, start2); 21306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start1=start2; 21316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start2=i; 21326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: /* we should never get here */ 21346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(FALSE); 21356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* flush possible pending sequence, e.g. ON */ 21416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(limit==pBiDi->length && pBiDi->epiLength>0) { 21426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp firstStrong=firstL_R_AL_EN_AN(pBiDi); 21436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(firstStrong!=DirProp_ON) { 21446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org eor=firstStrong; 21456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=dirProps[limit-1]; 21496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((dirProp==LRI || dirProp==RLI) && limit<pBiDi->length) { 21506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount++; 21516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates[pBiDi->isolateCount].stateImp=stateImp; 21526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates[pBiDi->isolateCount].state=levState.state; 21536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates[pBiDi->isolateCount].start1=start1; 21546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 21566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org processPropertySeq(pBiDi, &levState, eor, limit, limit); 21576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 21586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* perform (L1) and (X9) ---------------------------------------------------- */ 21606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 21626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Reset the embedding levels for some non-graphic characters (L1). 21636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This function also sets appropriate levels for BN, and 21646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * explicit embedding types that are supposed to have been removed 21656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * from the paragraph in (X9). 21666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 21676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 21686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgadjustWSLevels(UBiDi *pBiDi) { 21696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DirProp *dirProps=pBiDi->dirProps; 21706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *levels=pBiDi->levels; 21716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 21726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->flags&MASK_WS) { 21746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool orderParagraphsLTR=pBiDi->orderParagraphsLTR; 21756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Flags flag; 21766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=pBiDi->trailingWSStart; 21786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i>0) { 21796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset a sequence of WS/BN before eop and B/S to the paragraph paraLevel */ 21806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i>0 && (flag=DIRPROP_FLAG(PURE_DIRPROP(dirProps[--i])))&MASK_WS) { 21816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(orderParagraphsLTR&&(flag&DIRPROP_FLAG(B))) { 21826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=0; 21836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 21846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=GET_PARALEVEL(pBiDi, i); 21856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset BN to the next character's paraLevel until B/S, which restarts above loop */ 21896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* here, i+1 is guaranteed to be <length */ 21906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i>0) { 21916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org flag=DIRPROP_FLAG(PURE_DIRPROP(dirProps[--i])); 21926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flag&MASK_BN_EXPLICIT) { 21936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=levels[i+1]; 21946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(orderParagraphsLTR&&(flag&DIRPROP_FLAG(B))) { 21956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=0; 21966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 21976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(flag&MASK_B_S) { 21986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[i]=GET_PARALEVEL(pBiDi, i); 21996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 22006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 22056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 22076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setContext(UBiDi *pBiDi, 22086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *prologue, int32_t proLength, 22096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *epilogue, int32_t epiLength, 22106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 22116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the argument values */ 22126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 22136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi==NULL || proLength<-1 || epiLength<-1 || 22146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (prologue==NULL && proLength!=0) || (epilogue==NULL && epiLength!=0)) { 22156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 22166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 22176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(proLength==-1) { 22206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->proLength=u_strlen(prologue); 22216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 22226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->proLength=proLength; 22236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(epiLength==-1) { 22256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->epiLength=u_strlen(epilogue); 22266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 22276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->epiLength=epiLength; 22286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->prologue=prologue; 22306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->epilogue=epilogue; 22316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 22326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 22346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgsetParaSuccess(UBiDi *pBiDi) { 22356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->proLength=0; /* forget the last context */ 22366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->epiLength=0; 22376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pParaBiDi=pBiDi; /* mark successful setPara */ 22386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 22396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define BIDI_MIN(x, y) ((x)<(y) ? (x) : (y)) 22416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define BIDI_ABS(x) ((x)>=0 ? (x) : (-(x))) 22426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 22446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgsetParaRunsOnly(UBiDi *pBiDi, const UChar *text, int32_t length, 22456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel paraLevel, UErrorCode *pErrorCode) { 22466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *runsOnlyMemory; 22476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *visualMap; 22486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *visualText; 22496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t saveLength, saveTrailingWSStart; 22506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UBiDiLevel *levels; 22516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *saveLevels; 22526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiDirection saveDirection; 22536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool saveMayAllocateText; 22546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Run *runs; 22556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t visualLength, i, j, visualStart, logicalStart, 22566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runCount, runLength, addedRuns, insertRemove, 22576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start, limit, step, indexOddBit, logicalPos, 22586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index0, index1; 22596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t saveOptions; 22606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode=UBIDI_REORDER_DEFAULT; 22626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==0) { 22636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_setPara(pBiDi, text, length, paraLevel, NULL, pErrorCode); 22646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup3; 22656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* obtain memory for mapping table and visual text */ 22676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runsOnlyMemory=uprv_malloc(length*(sizeof(int32_t)+sizeof(UChar)+sizeof(UBiDiLevel))); 22686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(runsOnlyMemory==NULL) { 22696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 22706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup3; 22716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org visualMap=runsOnlyMemory; 22736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org visualText=(UChar *)&visualMap[length]; 22746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLevels=(UBiDiLevel *)&visualText[length]; 22756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveOptions=pBiDi->reorderingOptions; 22766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(saveOptions & UBIDI_OPTION_INSERT_MARKS) { 22776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingOptions&=~UBIDI_OPTION_INSERT_MARKS; 22786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingOptions|=UBIDI_OPTION_REMOVE_CONTROLS; 22796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org paraLevel&=1; /* accept only 0 or 1 */ 22816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_setPara(pBiDi, text, length, paraLevel, NULL, pErrorCode); 22826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 22836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup3; 22846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we cannot access directly pBiDi->levels since it is not yet set if 22866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * direction is not MIXED 22876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels=ubidi_getLevels(pBiDi, pErrorCode); 22896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(saveLevels, levels, pBiDi->length*sizeof(UBiDiLevel)); 22906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveTrailingWSStart=pBiDi->trailingWSStart; 22916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLength=pBiDi->length; 22926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveDirection=pBiDi->direction; 22936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* FOOD FOR THOUGHT: instead of writing the visual text, we could use 22956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the visual map and the dirProps array to drive the second call 22966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to ubidi_setPara (but must make provision for possible removal of 22976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * BiDi controls. Alternatively, only use the dirProps array via 22986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * customized classifier callback. 22996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org visualLength=ubidi_writeReordered(pBiDi, visualText, length, 23016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBIDI_DO_MIRRORING, pErrorCode); 23026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_getVisualMap(pBiDi, visualMap, pErrorCode); 23036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 23046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup2; 23056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingOptions=saveOptions; 23076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode=UBIDI_REORDER_INVERSE_LIKE_DIRECT; 23096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org paraLevel^=1; 23106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Because what we did with reorderingOptions, visualText may be shorter 23116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * than the original text. But we don't want the levels memory to be 23126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * reallocated shorter than the original length, since we need to restore 23136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the levels as after the first call to ubidi_setpara() before returning. 23146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We will force mayAllocateText to FALSE before the second call to 23156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ubidi_setpara(), and will restore it afterwards. 23166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveMayAllocateText=pBiDi->mayAllocateText; 23186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->mayAllocateText=FALSE; 23196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_setPara(pBiDi, visualText, visualLength, paraLevel, NULL, pErrorCode); 23206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->mayAllocateText=saveMayAllocateText; 23216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_getRuns(pBiDi, pErrorCode); 23226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 23236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup1; 23246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check if some runs must be split, count how many splits */ 23266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addedRuns=0; 23276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runCount=pBiDi->runCount; 23286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs=pBiDi->runs; 23296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org visualStart=0; 23306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<runCount; i++, visualStart+=runLength) { 23316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runLength=runs[i].visualLimit-visualStart; 23326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(runLength<2) { 23336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 23346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalStart=GET_INDEX(runs[i].logicalStart); 23366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=logicalStart+1; j<logicalStart+runLength; j++) { 23376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index0=visualMap[j]; 23386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index1=visualMap[j-1]; 23396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((BIDI_ABS(index0-index1)!=1) || (saveLevels[index0]!=saveLevels[index1])) { 23406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addedRuns++; 23416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(addedRuns) { 23456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(getRunsMemory(pBiDi, runCount+addedRuns)) { 23466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(runCount==1) { 23476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* because we switch from UBiDi.simpleRuns to UBiDi.runs */ 23486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runsMemory[0]=runs[0]; 23496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs=pBiDi->runs=pBiDi->runsMemory; 23516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runCount+=addedRuns; 23526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 23536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto cleanup1; 23546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split runs which are not consecutive in source text */ 23576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=runCount-1; i>=0; i--) { 23586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runLength= i==0 ? runs[0].visualLimit : 23596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i].visualLimit-runs[i-1].visualLimit; 23606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalStart=runs[i].logicalStart; 23616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexOddBit=GET_ODD_BIT(logicalStart); 23626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalStart=GET_INDEX(logicalStart); 23636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(runLength<2) { 23646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(addedRuns) { 23656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns]=runs[i]; 23666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalPos=visualMap[logicalStart]; 23686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos, 23696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLevels[logicalPos]^indexOddBit); 23706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 23716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexOddBit) { 23736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=logicalStart; 23746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=logicalStart+runLength-1; 23756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org step=1; 23766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 23776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=logicalStart+runLength-1; 23786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=logicalStart; 23796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org step=-1; 23806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=start; j!=limit; j+=step) { 23826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index0=visualMap[j]; 23836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index1=visualMap[j+step]; 23846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((BIDI_ABS(index0-index1)!=1) || (saveLevels[index0]!=saveLevels[index1])) { 23856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalPos=BIDI_MIN(visualMap[start], index0); 23866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos, 23876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLevels[logicalPos]^indexOddBit); 23886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns].visualLimit=runs[i].visualLimit; 23896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i].visualLimit-=BIDI_ABS(j-start)+1; 23906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org insertRemove=runs[i].insertRemove&(LRM_AFTER|RLM_AFTER); 23916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns].insertRemove=insertRemove; 23926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i].insertRemove&=~insertRemove; 23936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=j+step; 23946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addedRuns--; 23956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(addedRuns) { 23986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns]=runs[i]; 23996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org logicalPos=BIDI_MIN(visualMap[start], visualMap[limit]); 24016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos, 24026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLevels[logicalPos]^indexOddBit); 24036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup1: 24066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* restore initial paraLevel */ 24076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel^=1; 24086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup2: 24096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* restore real text */ 24106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->text=text; 24116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->length=saveLength; 24126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->originalLength=length; 24136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->direction=saveDirection; 24146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the saved levels should never excess levelsSize, but we check anyway */ 24156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(saveLength>pBiDi->levelsSize) { 24166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org saveLength=pBiDi->levelsSize; 24176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(pBiDi->levels, saveLevels, saveLength*sizeof(UBiDiLevel)); 24196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->trailingWSStart=saveTrailingWSStart; 24206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* free memory for mapping table and visual text */ 24216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(runsOnlyMemory); 24226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->runCount>1) { 24236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->direction=UBIDI_MIXED; 24246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup3: 24266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->reorderingMode=UBIDI_REORDER_RUNS_ONLY; 24276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 24286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ubidi_setPara ------------------------------------------------------------ */ 24306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 24326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length, 24336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels, 24346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 24356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiDirection direction; 24366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the argument values */ 24386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 24396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi==NULL || text==NULL || length<-1 || 24406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (paraLevel>UBIDI_MAX_EXPLICIT_LEVEL && paraLevel<UBIDI_DEFAULT_LTR)) { 24416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 24426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 24436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==-1) { 24466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=u_strlen(text); 24476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* special treatment for RUNS_ONLY mode */ 24506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingMode==UBIDI_REORDER_RUNS_ONLY) { 24516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setParaRunsOnly(pBiDi, text, length, paraLevel, pErrorCode); 24526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 24536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize the UBiDi structure */ 24566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pParaBiDi=NULL; /* mark unfinished setPara */ 24576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->text=text; 24586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->length=pBiDi->originalLength=pBiDi->resultLength=length; 24596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel=paraLevel; 24606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->direction=paraLevel&1; 24616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraCount=1; 24626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->dirProps=NULL; 24646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->levels=NULL; 24656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runs=NULL; 24666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->insertPoints.size=0; /* clean up from last call */ 24676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->insertPoints.confirmed=0; /* clean up from last call */ 24686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 24706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Save the original paraLevel if contextual; otherwise, set to 0. 24716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 24726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->defaultParaLevel=IS_DEFAULT_LEVEL(paraLevel); 24736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length==0) { 24756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 24766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For an empty paragraph, create a UBiDi object with the paraLevel and 24776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the flags and the direction set but without allocating zero-length arrays. 24786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * There is nothing more to do. 24796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 24806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_DEFAULT_LEVEL(paraLevel)) { 24816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel&=1; 24826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->defaultParaLevel=0; 24836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->flags=DIRPROP_FLAG_LR(paraLevel); 24856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runCount=0; 24866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraCount=0; 24876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setParaSuccess(pBiDi); /* mark successful setPara */ 24886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 24896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->runCount=-1; 24926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate paras memory */ 24946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->parasMemory) 24956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras=pBiDi->parasMemory; 24966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 24976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paras=pBiDi->simpleParas; 24986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 25006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Get the directional properties, 25016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the flags bit-set, and 25026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * determine the paragraph level if necessary. 25036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 25046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(getDirPropsMemory(pBiDi, length)) { 25056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->dirProps=pBiDi->dirPropsMemory; 25066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!getDirProps(pBiDi)) { 25076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 25086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 25126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the processed length may have changed if UBIDI_OPTION_STREAMING */ 25156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length= pBiDi->length; 25166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->trailingWSStart=length; /* the levels[] will reflect the WS run */ 25176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* are explicit levels specified? */ 25196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(embeddingLevels==NULL) { 25206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no: determine explicit levels according to the (Xn) rules */\ 25216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(getLevelsMemory(pBiDi, length)) { 25226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->levels=pBiDi->levelsMemory; 25236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction=resolveExplicitLevels(pBiDi, pErrorCode); 25246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 25256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 25296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set BN for all explicit codes, check that all levels are 0 or paraLevel..UBIDI_MAX_EXPLICIT_LEVEL */ 25336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->levels=embeddingLevels; 25346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org direction=checkExplicitLevels(pBiDi, pErrorCode); 25356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 25366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate isolate memory */ 25416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->isolateCount<=SIMPLE_ISOLATES_SIZE) 25426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates=pBiDi->simpleIsolates; 25436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 25446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->isolateCount<=pBiDi->isolatesSize) 25456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates=pBiDi->isolatesMemory; 25466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 25476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(getInitialIsolatesMemory(pBiDi, pBiDi->isolateCount)) { 25486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolates=pBiDi->isolatesMemory; 25496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 25516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 25526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->isolateCount=-1; /* current isolates stack entry == none */ 25556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 25576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The steps after (X9) in the UBiDi algorithm are performed only if 25586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the paragraph text has mixed directionality! 25596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 25606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->direction=direction; 25616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(direction) { 25626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_LTR: 25636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* make sure paraLevel is even */ 25646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel=(UBiDiLevel)((pBiDi->paraLevel+1)&~1); 25656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */ 25676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->trailingWSStart=0; 25686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_RTL: 25706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* make sure paraLevel is odd */ 25716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->paraLevel|=1; 25726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */ 25746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->trailingWSStart=0; 25756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 25776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 25786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Choose the right implicit state table 25796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 25806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(pBiDi->reorderingMode) { 25816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_DEFAULT: 25826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_DEFAULT; 25836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_NUMBERS_SPECIAL: 25856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_NUMBERS_SPECIAL; 25866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_GROUP_NUMBERS_WITH_R: 25886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_GROUP_NUMBERS_WITH_R; 25896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_INVERSE_NUMBERS_AS_L: 25916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_INVERSE_NUMBERS_AS_L; 25926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 25936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_INVERSE_LIKE_DIRECT: 25946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) { 25956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_INVERSE_LIKE_DIRECT_WITH_MARKS; 25966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_INVERSE_LIKE_DIRECT; 25986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 26006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL: 26016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) { 26026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS; 26036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->pImpTabPair=&impTab_INVERSE_FOR_NUMBERS_SPECIAL; 26056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 26076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 26086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we should never get here */ 26096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(FALSE); 26106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 26116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 26136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If there are no external levels specified and there 26146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * are no significant explicit level codes in the text, 26156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * then we can treat the entire paragraph as one run. 26166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Otherwise, we need to perform the following rules on runs of 26176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the text with the same embedding levels. (X10) 26186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * "Significant" explicit level codes are ones that actually 26196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * affect non-BN characters. 26206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Examples for "insignificant" ones are empty embeddings 26216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * LRE-PDF, LRE-RLE-PDF-PDF, etc. 26226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 26236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(embeddingLevels==NULL && pBiDi->paraCount<=1 && 26246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org !(pBiDi->flags&DIRPROP_FLAG_MULTI_RUNS)) { 26256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resolveImplicitLevels(pBiDi, 0, length, 26266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, 0)), 26276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, length-1))); 26286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* sor, eor: start and end types of same-level-run */ 26306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *levels=pBiDi->levels; 26316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start, limit=0; 26326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel level, nextLevel; 26336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp sor, eor; 26346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* determine the first sor and set eor to it because of the loop body (sor=eor there) */ 26366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=GET_PARALEVEL(pBiDi, 0); 26376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextLevel=levels[0]; 26386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(level<nextLevel) { 26396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org eor=GET_LR_FROM_LEVEL(nextLevel); 26406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org eor=GET_LR_FROM_LEVEL(level); 26426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 26456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* determine start and limit of the run (end points just behind the run) */ 26466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the values for this run's start are the same as for the previous run's end */ 26486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=limit; 26496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=nextLevel; 26506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((start>0) && (pBiDi->dirProps[start-1]==B)) { 26516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* except if this is a new paragraph, then set sor = para level */ 26526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sor=GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, start)); 26536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sor=eor; 26556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* search for the limit of this run */ 26586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(++limit<length && levels[limit]==level) {} 26596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get the correct level of the next run */ 26616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(limit<length) { 26626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextLevel=levels[limit]; 26636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextLevel=GET_PARALEVEL(pBiDi, length-1); 26656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* determine eor from max(level, nextLevel); sor is last run's eor */ 26686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((level&~UBIDI_LEVEL_OVERRIDE)<(nextLevel&~UBIDI_LEVEL_OVERRIDE)) { 26696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org eor=GET_LR_FROM_LEVEL(nextLevel); 26706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org eor=GET_LR_FROM_LEVEL(level); 26726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if the run consists of overridden directional types, then there 26756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org are no implicit types to be resolved */ 26766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(level&UBIDI_LEVEL_OVERRIDE)) { 26776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resolveImplicitLevels(pBiDi, start, limit, sor, eor); 26786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remove the UBIDI_LEVEL_OVERRIDE flags */ 26806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 26816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org levels[start++]&=~UBIDI_LEVEL_OVERRIDE; 26826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(start<limit); 26836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(limit<length); 26856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check if we got any memory shortage while adding insert points */ 26876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(pBiDi->insertPoints.errorCode)) 26886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 26896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=pBiDi->insertPoints.errorCode; 26906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 26916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the embedding levels for some non-graphic characters (L1), (X9) */ 26936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org adjustWSLevels(pBiDi); 26946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 26956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* add RLM for inverse Bidi with contextual orientation resolving 26976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to RTL which would not round-trip otherwise 26986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 26996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((pBiDi->defaultParaLevel>0) && 27006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) && 27016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT) || 27026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL))) { 27036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, j, start, last; 27046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel level; 27056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DirProp dirProp; 27066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<pBiDi->paraCount; i++) { 27076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org last=(pBiDi->paras[i].limit)-1; 27086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org level=pBiDi->paras[i].level; 27096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(level==0) 27106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; /* LTR paragraph */ 27116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start= i==0 ? 0 : pBiDi->paras[i-1].limit; 27126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(j=last; j>=start; j--) { 27136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dirProp=pBiDi->dirProps[j]; 27146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dirProp==L) { 27156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(j<last) { 27166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(pBiDi->dirProps[last]==B) { 27176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org last--; 27186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org addPoint(pBiDi, last, RLM_BEFORE); 27216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 27226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(DIRPROP_FLAG(dirProp) & MASK_R_AL) { 27246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 27256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi->reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) { 27316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->resultLength -= pBiDi->controlCount; 27326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->resultLength += pBiDi->insertPoints.size; 27346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setParaSuccess(pBiDi); /* mark successful setPara */ 27366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 27396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR) { 27406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi!=NULL) { 27416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->orderParagraphsLTR=orderParagraphsLTR; 27426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2 27466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_isOrderParagraphsLTR(UBiDi *pBiDi) { 27476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi!=NULL) { 27486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->orderParagraphsLTR; 27496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 27516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDiDirection U_EXPORT2 27556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getDirection(const UBiDi *pBiDi) { 27566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 27576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->direction; 27586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UBIDI_LTR; 27606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const UChar * U_EXPORT2 27646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getText(const UBiDi *pBiDi) { 27656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 27666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->text; 27676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 27696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 27736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getLength(const UBiDi *pBiDi) { 27746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 27756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->originalLength; 27766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 27786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 27826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getProcessedLength(const UBiDi *pBiDi) { 27836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 27846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->length; 27856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 27876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 27916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getResultLength(const UBiDi *pBiDi) { 27926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 27936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->resultLength; 27946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 27956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 27966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* paragraphs API functions ------------------------------------------------- */ 28006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBiDiLevel U_EXPORT2 28026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getParaLevel(const UBiDi *pBiDi) { 28036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(IS_VALID_PARA_OR_LINE(pBiDi)) { 28046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->paraLevel; 28056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 28066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 28076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 28116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_countParagraphs(UBiDi *pBiDi) { 28126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!IS_VALID_PARA_OR_LINE(pBiDi)) { 28136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 28146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 28156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pBiDi->paraCount; 28166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 28206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex, 28216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *pParaStart, int32_t *pParaLimit, 28226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *pParaLevel, UErrorCode *pErrorCode) { 28236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t paraStart; 28246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the argument values */ 28266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 28276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode); 28286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_BAD_RANGE(paraIndex, 0, pBiDi->paraCount, *pErrorCode); 28296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi=pBiDi->pParaBiDi; /* get Para object if Line object */ 28316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(paraIndex) { 28326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org paraStart=pBiDi->paras[paraIndex-1].limit; 28336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 28346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org paraStart=0; 28356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pParaStart!=NULL) { 28376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pParaStart=paraStart; 28386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pParaLimit!=NULL) { 28406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pParaLimit=pBiDi->paras[paraIndex].limit; 28416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pParaLevel!=NULL) { 28436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pParaLevel=GET_PARALEVEL(pBiDi, paraStart); 28446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 28486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex, 28496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *pParaStart, int32_t *pParaLimit, 28506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBiDiLevel *pParaLevel, UErrorCode *pErrorCode) { 28516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t paraIndex; 28526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the argument values */ 28546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* pErrorCode will be checked by the call to ubidi_getParagraphByIndex */ 28556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1); 28566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1); 28576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi=pBiDi->pParaBiDi; /* get Para object if Line object */ 28586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_IF_BAD_RANGE(charIndex, 0, pBiDi->length, *pErrorCode, -1); 28596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(paraIndex=0; charIndex>=pBiDi->paras[paraIndex].limit; paraIndex++); 28616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ubidi_getParagraphByIndex(pBiDi, paraIndex, pParaStart, pParaLimit, pParaLevel, pErrorCode); 28626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return paraIndex; 28636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 28666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn, 28676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void *newContext, UBiDiClassCallback **oldFn, 28686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void **oldContext, UErrorCode *pErrorCode) 28696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 28706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 28716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi==NULL) { 28726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 28736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 28746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( oldFn ) 28766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 28776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *oldFn = pBiDi->fnClassCallback; 28786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( oldContext ) 28806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 28816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *oldContext = pBiDi->coClassCallback; 28826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->fnClassCallback = newFn; 28846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBiDi->coClassCallback = newContext; 28856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 28886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context) 28896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 28906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pBiDi==NULL) { 28916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 28926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( fn ) 28946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 28956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *fn = pBiDi->fnClassCallback; 28966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( context ) 28986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 28996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *context = pBiDi->coClassCallback; 29006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 29016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 29026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 29036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UCharDirection U_EXPORT2 29046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c) 29056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 29066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UCharDirection dir; 29076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 29086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( pBiDi->fnClassCallback == NULL || 29096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (dir = (*pBiDi->fnClassCallback)(pBiDi->coClassCallback, c)) == U_BIDI_CLASS_DEFAULT ) 29106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 29116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dir = ubidi_getClass(pBiDi->bdp, c); 29126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 29136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dir >= U_CHAR_DIRECTION_COUNT) { 29146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dir = ON; 29156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 29166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return dir; 29176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2918