1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 427f654740f2a26ad62a5c155af9199af9e69b889claireho* Copyright (C) 1999-2010, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: ubidiln.c 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created on: 1999aug06 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created by: Markus W. Scherer, updated by Matitiahu Allouche 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ubidi.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ubidiimp.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * General remarks about the functions in this file: 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * These functions deal with the aspects of potentially mixed-directional 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * text in a single paragraph or in a line of a single paragraph 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * which has already been processed according to 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the Unicode 3.0 BiDi algorithm as defined in 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.unicode.org/unicode/reports/tr9/ , version 13, 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * also described in The Unicode Standard, Version 4.0.1 . 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This means that there is a UBiDi object with a levels 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and a dirProps array. 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * paraLevel and direction are also set. 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Only if the length of the text is zero, then levels==dirProps==NULL. 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The overall directionality of the paragraph 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or line is used to bypass the reordering steps if possible. 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Even purely RTL text does not need reordering there because 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the ubidi_getLogical/VisualIndex() functions can compute the 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * index on the fly in such a case. 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The implementation of the access to same-level-runs and of the reordering 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * do attempt to provide better performance and less memory usage compared to 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * a direct implementation of especially rule (L2) with an array of 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one (32-bit) integer per text character. 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Here, the levels array is scanned as soon as necessary, and a vector of 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * same-level-runs is created. Reordering then is done on this vector. 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For each run of text positions that were resolved to the same level, 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * only 8 bytes are stored: the first text position of the run and the visual 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * position behind the run after reordering. 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * One sign bit is used to hold the directionality of the run. 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is inefficient if there are many very short runs. If the average run 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * length is <2, then this uses more memory. 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * In a further attempt to save memory, the levels array is never changed 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * after all the resolution rules (Xn, Wn, Nn, In). 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Many functions have to consider the field trailingWSStart: 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if it is less than length, then there is an implicit trailing run 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * at the paraLevel, 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * which is not reflected in the levels array. 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This allows a line UBiDi object to use the same levels array as 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * its paragraph parent object. 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * When a UBiDi object is created for a line of a paragraph, then the 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * paragraph's levels and dirProps arrays are reused by way of setting 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * a pointer into them, not by copying. This again saves memory and forbids to 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * change the now shared levels for (L1). 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* handle trailing WS (L1) -------------------------------------------------- */ 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * setTrailingWSStart() sets the start index for a trailing 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * run of WS in the line. This is necessary because we do not modify 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the paragraph's levels array that we just point into. 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Using trailingWSStart is another form of performing (L1). 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * To make subsequent operations easier, we also include the run 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * before the WS if it is at the paraLevel - we merge the two here. 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This function is called only from ubidi_setLine(), so pBiDi->paraLevel is 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * set correctly for the line even when contextual multiple paragraphs. 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerusetTrailingWSStart(UBiDi *pBiDi) { 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* pBiDi->direction!=UBIDI_MIXED */ 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const DirProp *dirProps=pBiDi->dirProps; 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel *levels=pBiDi->levels; 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start=pBiDi->length; 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel paraLevel=pBiDi->paraLevel; 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* If the line is terminated by a block separator, all preceding WS etc... 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru are already set to paragraph level. 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Setting trailingWSStart to pBidi->length will avoid changing the 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru level of B chars from 0 to paraLevel in ubidi_getLevels when 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru orderParagraphsLTR==TRUE. 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(NO_CONTEXT_RTL(dirProps[start-1])==B) { 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->trailingWSStart=start; /* currently == pBiDi->length */ 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* go backwards across all WS, BN, explicit codes */ 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start>0 && DIRPROP_FLAG_NC(dirProps[start-1])&MASK_WS) { 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --start; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if the WS run can be merged with the previous run then do so here */ 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start>0 && levels[start-1]==paraLevel) { 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --start; 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->trailingWSStart=start; 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ubidi_setLine ------------------------------------------------------------ */ 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_setLine(const UBiDi *pParaBiDi, 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, int32_t limit, 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDi *pLineBiDi, 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length; 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check the argument values */ 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_NOT_VALID_PARA(pParaBiDi, *pErrorCode); 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_BAD_RANGE(start, 0, limit, *pErrorCode); 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_BAD_RANGE(limit, 0, pParaBiDi->length+1, *pErrorCode); 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pLineBiDi==NULL) { 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(ubidi_getParagraph(pParaBiDi, start, NULL, NULL, NULL, pErrorCode) != 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_getParagraph(pParaBiDi, limit-1, NULL, NULL, NULL, pErrorCode)) { 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the line crosses a paragraph boundary */ 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set the values in pLineBiDi from its pParaBiDi parent */ 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->pParaBiDi=NULL; /* mark unfinished setLine */ 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->text=pParaBiDi->text+start; 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=pLineBiDi->length=limit-start; 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->resultLength=pLineBiDi->originalLength=length; 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->paraLevel=GET_PARALEVEL(pParaBiDi, start); 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->paraCount=pParaBiDi->paraCount; 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->runs=NULL; 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->flags=0; 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->reorderingMode=pParaBiDi->reorderingMode; 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->reorderingOptions=pParaBiDi->reorderingOptions; 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->controlCount=0; 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pParaBiDi->controlCount>0) { 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t j; 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=start; j<limit; j++) { 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(pParaBiDi->text[j])) { 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->controlCount++; 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->resultLength-=pLineBiDi->controlCount; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->dirProps=pParaBiDi->dirProps+start; 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->levels=pParaBiDi->levels+start; 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->runCount=-1; 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pParaBiDi->direction!=UBIDI_MIXED) { 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the parent is already trivial */ 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->direction=pParaBiDi->direction; 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The parent's levels are all either 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * implicitly or explicitly ==paraLevel; 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * do the same here. 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pParaBiDi->trailingWSStart<=start) { 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->trailingWSStart=0; 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(pParaBiDi->trailingWSStart<limit) { 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->trailingWSStart=pParaBiDi->trailingWSStart-start; 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->trailingWSStart=length; 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UBiDiLevel *levels=pLineBiDi->levels; 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, trailingWSStart; 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel level; 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTrailingWSStart(pLineBiDi); 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trailingWSStart=pLineBiDi->trailingWSStart; 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recalculate pLineBiDi->direction */ 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(trailingWSStart==0) { 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all levels are at paraLevel */ 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->direction=(UBiDiDirection)(pLineBiDi->paraLevel&1); 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get the level of the first character */ 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru level=(UBiDiLevel)(levels[0]&1); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there is anything of a different level, then the line is mixed */ 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(trailingWSStart<length && (pLineBiDi->paraLevel&1)!=level) { 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the trailing WS is at paraLevel, which differs from levels[0] */ 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->direction=UBIDI_MIXED; 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* see if levels[1..trailingWSStart-1] have the same direction as levels[0] and paraLevel */ 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=1; 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==trailingWSStart) { 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the direction values match those in level */ 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->direction=(UBiDiDirection)level; 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if((levels[i]&1)!=level) { 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->direction=UBIDI_MIXED; 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(pLineBiDi->direction) { 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UBIDI_LTR: 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make sure paraLevel is even */ 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->paraLevel=(UBiDiLevel)((pLineBiDi->paraLevel+1)&~1); 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */ 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->trailingWSStart=0; 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UBIDI_RTL: 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make sure paraLevel is odd */ 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->paraLevel|=1; 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */ 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->trailingWSStart=0; 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pLineBiDi->pParaBiDi=pParaBiDi; /* mark successful setLine */ 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBiDiLevel U_EXPORT2 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex) { 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* return paraLevel if in the trailing WS run, otherwise the real level */ 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!IS_VALID_PARA_OR_LINE(pBiDi) || charIndex<0 || pBiDi->length<=charIndex) { 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(pBiDi->direction!=UBIDI_MIXED || charIndex>=pBiDi->trailingWSStart) { 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return GET_PARALEVEL(pBiDi, charIndex); 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return pBiDi->levels[charIndex]; 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const UBiDiLevel * U_EXPORT2 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) { 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, length; 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, NULL); 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, NULL); 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((length=pBiDi->length)<=0) { 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((start=pBiDi->trailingWSStart)==length) { 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the current levels array reflects the WS run */ 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return pBiDi->levels; 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * After the previous if(), we know that the levels array 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * has an implicit trailing WS run and therefore does not fully 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * reflect itself all the levels. 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This must be a UBiDi object for a line, and 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we need to create a new levels array. 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(getLevelsMemory(pBiDi, length)) { 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel *levels=pBiDi->levelsMemory; 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(start>0 && levels!=pBiDi->levels) { 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(levels, pBiDi->levels, start); 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* pBiDi->paraLevel is ok even if contextual multiple paragraphs, 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru since pBidi is a line object */ 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(levels+start, pBiDi->paraLevel, length-start); 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this new levels array is set for the line and reflects the WS run */ 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->trailingWSStart=length; 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return pBiDi->levels=levels; 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* out of memory */ 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalPosition, 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *pLogicalLimit, UBiDiLevel *pLevel) { 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode errorCode; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runCount, visualStart, logicalLimit, logicalFirst, i; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run iRun; 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_BAD_RANGE(logicalPosition, 0, pBiDi->length, errorCode); 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ubidi_countRuns will check VALID_PARA_OR_LINE */ 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runCount=ubidi_countRuns((UBiDi *)pBiDi, &errorCode); 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this is done based on runs rather than on levels since levels have 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru a special interpretation when UBIDI_REORDER_RUNS_ONLY 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=logicalLimit=0; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru iRun=pBiDi->runs[0]; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++) { 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru iRun = pBiDi->runs[i]; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalFirst=GET_INDEX(iRun.logicalStart); 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalLimit=logicalFirst+iRun.visualLimit-visualStart; 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((logicalPosition>=logicalFirst) && 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (logicalPosition<logicalLimit)) { 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart = iRun.visualLimit; 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pLogicalLimit) { 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLogicalLimit=logicalLimit; 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pLevel) { 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->reorderingMode==UBIDI_REORDER_RUNS_ONLY) { 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLevel=(UBiDiLevel)GET_ODD_BIT(iRun.logicalStart); 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->direction!=UBIDI_MIXED || logicalPosition>=pBiDi->trailingWSStart) { 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLevel=GET_PARALEVEL(pBiDi, logicalPosition); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLevel=pBiDi->levels[logicalPosition]; 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* runs API functions ------------------------------------------------------- */ 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) { 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1); 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1); 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_getRuns(pBiDi, pErrorCode); 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return pBiDi->runCount; 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBiDiDirection U_EXPORT2 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex, 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *pLogicalStart, int32_t *pLength) 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, errorCode, UBIDI_LTR); 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_getRuns(pBiDi, &errorCode); 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return UBIDI_LTR; 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_BAD_RANGE(runIndex, 0, pBiDi->runCount, errorCode, UBIDI_LTR); 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=pBiDi->runs[runIndex].logicalStart; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pLogicalStart!=NULL) { 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLogicalStart=GET_INDEX(start); 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pLength!=NULL) { 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(runIndex>0) { 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLength=pBiDi->runs[runIndex].visualLimit- 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[runIndex-1].visualLimit; 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLength=pBiDi->runs[0].visualLimit; 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBiDiDirection)GET_ODD_BIT(start); 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* in trivial cases there is only one trivial run; called by ubidi_getRuns() */ 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetSingleRun(UBiDi *pBiDi, UBiDiLevel level) { 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* simple, single-run case */ 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs=pBiDi->simpleRuns; 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runCount=1; 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* fill and reorder the single run */ 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[0].logicalStart=MAKE_INDEX_ODD_PAIR(0, level); 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[0].visualLimit=pBiDi->length; 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[0].insertRemove=0; 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* reorder the runs array (L2) ---------------------------------------------- */ 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Reorder the same-level runs in the runs array. 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Here, runCount>1 and maxLevel>=minLevel>=paraLevel. 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * All the visualStart fields=logical start before reordering. 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The "odd" bits are not set yet. 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Reordering with this data structure lends itself to some handy shortcuts: 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Since each run is moved but not modified, and since at the initial maxLevel 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * each sequence of same-level runs consists of only one run each, we 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * don't need to do anything there and can predecrement maxLevel. 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * In many simple cases, the reordering is thus done entirely in the 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * index mapping. 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Also, reordering occurs only down to the lowest odd level that occurs, 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * which is minLevel|1. However, if the lowest level itself is odd, then 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in the last reordering the sequence of the runs at this level or higher 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * will be all runs, and we don't need the elaborate loop to search for them. 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is covered by ++minLevel instead of minLevel|=1 followed 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * by an extra reorder-all after the reorder-some loop. 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * About a trailing WS run: 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Such a run would need special treatment because its level is not 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * reflected in levels[] if this is not a paragraph object. 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Instead, all characters from trailingWSStart on are implicitly at 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * paraLevel. 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * However, for all maxLevel>paraLevel, this run will never be reordered 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and does not need to be taken into account. maxLevel==paraLevel is only reordered 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if minLevel==paraLevel is odd, which is done in the extra segment. 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This means that for the main reordering loop we don't need to consider 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * this run and can --runCount. If it is later part of the all-runs 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * reordering, then runCount is adjusted accordingly. 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerureorderLine(UBiDi *pBiDi, UBiDiLevel minLevel, UBiDiLevel maxLevel) { 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs, tempRun; 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel *levels; 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t firstRun, endRun, limitRun, runCount; 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* nothing to do? */ 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(maxLevel<=(minLevel|1)) { 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Reorder only down to the lowest odd level 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and reorder at an odd minLevel in a separate, simpler loop. 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * See comments above for why minLevel is always incremented. 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++minLevel; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runs; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru levels=pBiDi->levels; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runCount=pBiDi->runCount; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* do not include the WS run at paraLevel<=old minLevel except in the simple loop */ 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->trailingWSStart<pBiDi->length) { 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --runCount; 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(--maxLevel>=minLevel) { 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstRun=0; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop for all sequences of runs */ 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for a sequence of runs that are all at >=maxLevel */ 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the first run of such a sequence */ 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(firstRun<runCount && levels[runs[firstRun].logicalStart]<maxLevel) { 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++firstRun; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(firstRun>=runCount) { 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such runs */ 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the limit run of such a sequence (the run behind it) */ 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(limitRun=firstRun; ++limitRun<runCount && levels[runs[limitRun].logicalStart]>=maxLevel;) {} 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Swap the entire sequence of runs from firstRun to limitRun-1. */ 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru endRun=limitRun-1; 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(firstRun<endRun) { 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempRun = runs[firstRun]; 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[firstRun]=runs[endRun]; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[endRun]=tempRun; 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++firstRun; 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --endRun; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(limitRun==runCount) { 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such runs */ 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstRun=limitRun+1; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now do maxLevel==old minLevel (==odd!), see above */ 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!(minLevel&1)) { 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstRun=0; 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* include the trailing WS run in this complete reordering */ 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->trailingWSStart==pBiDi->length) { 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --runCount; 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Swap the entire sequence of all runs. (endRun==runCount) */ 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(firstRun<runCount) { 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempRun=runs[firstRun]; 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[firstRun]=runs[runCount]; 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runCount]=tempRun; 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++firstRun; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --runCount; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* compute the runs array --------------------------------------------------- */ 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t getRunFromLogicalIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) { 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs; 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runCount=pBiDi->runCount, visualStart=0, i, length, logicalStart; 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++) { 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=GET_INDEX(runs[i].logicalStart); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((logicalIndex>=logicalStart) && (logicalIndex<(logicalStart+length))) { 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart+=length; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we should never get here */ 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(FALSE); 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_INVALID_STATE_ERROR; 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Compute the runs array from the levels array. 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * After ubidi_getRuns() returns TRUE, runCount is guaranteed to be >0 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and the runs are reordered. 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Odd-level runs have visualStart on their visual right edge and 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * they progress visually to the left. 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If option UBIDI_OPTION_INSERT_MARKS is set, insertRemove will contain the 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sum of appropriate LRM/RLM_BEFORE/AFTER flags. 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If option UBIDI_OPTION_REMOVE_CONTROLS is set, insertRemove will contain the 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * negative number of BiDi control characters within this run. 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC UBool 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) { 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This method returns immediately if the runs are already set. This 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * includes the case of length==0 (handled in setPara).. 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBiDi->runCount>=0) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->direction!=UBIDI_MIXED) { 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* simple, single-run case - this covers length==0 */ 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* pBiDi->paraLevel is ok even for contextual multiple paragraphs */ 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getSingleRun(pBiDi, pBiDi->paraLevel); 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else /* UBIDI_MIXED, length>0 */ { 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* mixed directionality */ 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length=pBiDi->length, limit; 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel *levels=pBiDi->levels; 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, runCount; 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel level=UBIDI_DEFAULT_LTR; /* initialize with no valid level */ 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If there are WS characters at the end of the line 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and the run preceding them has a level different from 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * paraLevel, then they will form their own run at paraLevel (L1). 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Count them separately. 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need some special treatment for this in order to not 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * modify the levels array which a line UBiDi object shares 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with its paragraph parent and its other line siblings. 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * In other words, for the trailing WS, it may be 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * levels[]!=paraLevel but we have to treat it like it were so. 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=pBiDi->trailingWSStart; 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* count the runs, there is at least one non-WS run, and limit>0 */ 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runCount=0; 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<limit; ++i) { 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* increment runCount at the start of each run */ 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(levels[i]!=level) { 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++runCount; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru level=levels[i]; 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We don't need to see if the last run can be merged with a trailing 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * WS run because setTrailingWSStart() would have done that. 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(runCount==1 && limit==length) { 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* There is only one non-WS run and no trailing WS-run. */ 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getSingleRun(pBiDi, levels[0]); 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else /* runCount>1 || limit<length */ { 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* allocate and set the runs */ 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs; 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runIndex, start; 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1, maxLevel=0; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now, count a (non-mergeable) WS run */ 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(limit<length) { 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++runCount; 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* runCount>1 */ 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(getRunsMemory(pBiDi, runCount)) { 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runsMemory; 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set the runs */ 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* FOOD FOR THOUGHT: this could be optimized, e.g.: 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 464->444, 484->444, 575->555, 595->555 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * However, that would take longer. Check also how it would 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * interact with BiDi control removal and inserting Marks. 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runIndex=0; 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* search for the run limits and initialize visualLimit values with the run lengths */ 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=0; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* prepare this run */ 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=i; 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru level=levels[i]; 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(level<minLevel) { 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel=level; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(level>maxLevel) { 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxLevel=level; 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the run limit */ 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(++i<limit && levels[i]==level) {} 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* i is another run limit */ 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runIndex].logicalStart=start; 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runIndex].visualLimit=i-start; 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runIndex].insertRemove=0; 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++runIndex; 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(i<limit); 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(limit<length) { 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* there is a separate WS run */ 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runIndex].logicalStart=limit; 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs[runIndex].visualLimit=length-limit; 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* For the trailing WS run, pBiDi->paraLevel is ok even 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if contextual multiple paragraphs. */ 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->paraLevel<minLevel) { 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel=pBiDi->paraLevel; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set the object fields */ 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs=runs; 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runCount=runCount; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru reorderLine(pBiDi, minLevel, maxLevel); 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now add the direction flags and adjust the visualLimit's to be just that */ 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this loop will also handle the trailing WS run */ 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=0; 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; ++i) { 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ADD_ODD_BIT_FROM_LEVEL(runs[i].logicalStart, levels[runs[i].logicalStart]); 66727f654740f2a26ad62a5c155af9199af9e69b889claireho limit+=runs[i].visualLimit; 66827f654740f2a26ad62a5c155af9199af9e69b889claireho runs[i].visualLimit=limit; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Set the "odd" bit for the trailing WS run. */ 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* For a RTL paragraph, it will be the *first* run in visual order. */ 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* For the trailing WS run, pBiDi->paraLevel is ok even if 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru contextual multiple paragraphs. */ 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(runIndex<runCount) { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t trailingRun = ((pBiDi->paraLevel & 1) != 0)? 0 : runIndex; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ADD_ODD_BIT_FROM_LEVEL(runs[trailingRun].logicalStart, pBiDi->paraLevel); 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* handle insert LRM/RLM BEFORE/AFTER run */ 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size>0) { 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Point *point, *start=pBiDi->insertPoints.points, 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *limit=start+pBiDi->insertPoints.size; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runIndex; 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(point=start; point<limit; point++) { 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runIndex=getRunFromLogicalIndex(pBiDi, point->pos, pErrorCode); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[runIndex].insertRemove|=point->flag; 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* handle remove BiDi control characters */ 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->controlCount>0) { 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runIndex; 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *start=pBiDi->text, *limit=start+pBiDi->length, *pu; 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(pu=start; pu<limit; pu++) { 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(*pu)) { 70050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho runIndex=getRunFromLogicalIndex(pBiDi, (int32_t)(pu-start), pErrorCode); 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pBiDi->runs[runIndex].insertRemove--; 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruprepareReorder(const UBiDiLevel *levels, int32_t length, 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *indexMap, 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel *pMinLevel, UBiDiLevel *pMaxLevel) { 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start; 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBiDiLevel level, minLevel, maxLevel; 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(levels==NULL || length<=0) { 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* determine minLevel and maxLevel */ 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1; 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxLevel=0; 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(start=length; start>0;) { 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru level=levels[--start]; 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(level>UBIDI_MAX_EXPLICIT_LEVEL+1) { 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(level<minLevel) { 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel=level; 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(level>maxLevel) { 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxLevel=level; 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pMinLevel=minLevel; 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pMaxLevel=maxLevel; 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* initialize the index map */ 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(start=length; start>0;) { 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --start; 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[start]=start; 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* reorder a line based on a levels array (L2) ------------------------------ */ 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) { 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, limit, sumOfSosEos; 75250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBiDiLevel minLevel = 0, maxLevel = 0; 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) { 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* nothing to do? */ 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLevel==maxLevel && (minLevel&1)==0) { 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reorder only down to the lowest odd level */ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel|=1; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop maxLevel..minLevel */ 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=0; 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop for all sequences of levels to reorder at the current maxLevel */ 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for a sequence of levels that are all at >=maxLevel */ 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the first index of such a sequence */ 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<length && levels[start]<maxLevel) { 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(start>=length) { 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such sequences */ 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the limit of such a sequence (the index behind it) */ 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {} 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sos=start of sequence, eos=end of sequence 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The closed (inclusive) interval from sos to eos includes all the logical 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and visual indexes within this sequence. They are logically and 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * visually contiguous and in the same range. 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For each run, the new visual index=sos+eos-old visual index; 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we pre-add sos+eos into sumOfSosEos -> 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * new visual index=sumOfSosEos-old visual index; 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sumOfSosEos=start+limit-1; 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reorder each index in the sequence */ 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[start]=sumOfSosEos-indexMap[start]; 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(++start<limit); 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* start==limit */ 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(limit==length) { 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such sequences */ 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=limit+1; 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--maxLevel>=minLevel); 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) { 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, end, limit, temp; 81550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBiDiLevel minLevel = 0, maxLevel = 0; 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) { 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* nothing to do? */ 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLevel==maxLevel && (minLevel&1)==0) { 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reorder only down to the lowest odd level */ 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLevel|=1; 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop maxLevel..minLevel */ 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=0; 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop for all sequences of levels to reorder at the current maxLevel */ 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for a sequence of levels that are all at >=maxLevel */ 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the first index of such a sequence */ 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<length && levels[start]<maxLevel) { 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(start>=length) { 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such runs */ 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* look for the limit of such a sequence (the index behind it) */ 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {} 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Swap the entire interval of indexes from start to limit-1. 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We don't need to swap the levels for the purpose of this 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * algorithm: the sequence of levels that we look at does not 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * move anyway. 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end=limit-1; 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<end) { 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru temp=indexMap[start]; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[start]=indexMap[end]; 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[end]=temp; 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --end; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(limit==length) { 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* no more such sequences */ 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=limit+1; 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--maxLevel>=minLevel); 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* API functions for logical<->visual mapping ------------------------------- */ 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) { 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t visualIndex=UBIDI_MAP_NOWHERE; 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1); 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1); 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_BAD_RANGE(logicalIndex, 0, pBiDi->length, *pErrorCode, -1); 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we can do the trivial cases without the runs array */ 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(pBiDi->direction) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UBIDI_LTR: 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex=logicalIndex; 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UBIDI_RTL: 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex=pBiDi->length-logicalIndex-1; 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!ubidi_getRuns(pBiDi, pErrorCode)) { 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, visualStart=0, offset, length; 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* linear search for the run, search on the visual runs */ 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<pBiDi->runCount; ++i) { 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=logicalIndex-GET_INDEX(runs[i].logicalStart); 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset>=0 && offset<length) { 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_EVEN_RUN(runs[i].logicalStart)) { 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* LTR */ 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex=visualStart+offset; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* RTL */ 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex=visualStart+length-offset-1; 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; /* exit for loop */ 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart+=length; 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i>=pBiDi->runCount) { 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return UBIDI_MAP_NOWHERE; 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size>0) { 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* add the number of added marks until the calculated visual index */ 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs; 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, length, insertRemove; 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t visualStart=0, markFound=0; 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; ; i++, visualStart+=length) { 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove & (LRM_BEFORE|RLM_BEFORE)) { 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* is it the run containing the visual index? */ 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex<runs[i].visualLimit) { 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return visualIndex+markFound; 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove & (LRM_AFTER|RLM_AFTER)) { 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->controlCount>0) { 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* subtract the number of controls until the calculated visual index */ 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs; 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, j, start, limit, length, insertRemove; 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t visualStart=0, controlFound=0; 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar uchar=pBiDi->text[logicalIndex]; 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* is the logical index pointing to a control ? */ 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(uchar)) { 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return UBIDI_MAP_NOWHERE; 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* loop on runs */ 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; ; i++, visualStart+=length) { 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* calculated visual index is beyond this run? */ 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex>=runs[i].visualLimit) { 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru controlFound-=insertRemove; 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* calculated visual index must be within current run */ 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove==0) { 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return visualIndex-controlFound; 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_EVEN_RUN(runs[i].logicalStart)) { 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* LTR: check from run start to logical index */ 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=runs[i].logicalStart; 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=logicalIndex; 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* RTL: check from logical index to run end */ 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=logicalIndex+1; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=GET_INDEX(runs[i].logicalStart)+length; 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=start; j<limit; j++) { 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uchar=pBiDi->text[j]; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(uchar)) { 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru controlFound++; 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return visualIndex-controlFound; 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return visualIndex; 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode) { 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, runCount, start; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1); 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1); 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_BAD_RANGE(visualIndex, 0, pBiDi->resultLength, *pErrorCode, -1); 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we can do the trivial cases without the runs array */ 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size==0 && pBiDi->controlCount==0) { 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->direction==UBIDI_LTR) { 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return visualIndex; 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->direction==UBIDI_RTL) { 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return pBiDi->length-visualIndex-1; 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!ubidi_getRuns(pBiDi, pErrorCode)) { 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runs; 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runCount=pBiDi->runCount; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size>0) { 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* handle inserted LRM/RLM */ 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t markFound=0, insertRemove; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t visualStart=0, length; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runs; 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* subtract number of marks until visual index */ 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; ; i++, visualStart+=length) { 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) { 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex<=(visualStart+markFound)) { 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return UBIDI_MAP_NOWHERE; 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* is adjusted visual index within this run? */ 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex<(runs[i].visualLimit+markFound)) { 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex-=markFound; 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_AFTER|RLM_AFTER)) { 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex==(visualStart+length+markFound)) { 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return UBIDI_MAP_NOWHERE; 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->controlCount>0) { 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* handle removed BiDi control characters */ 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t controlFound=0, insertRemove, length; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t logicalStart, logicalEnd, visualStart=0, j, k; 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar uchar; 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool evenRun; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* add number of controls until visual index */ 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; ; i++, visualStart+=length) { 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* is adjusted visual index beyond current run? */ 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex>=(runs[i].visualLimit-controlFound+insertRemove)) { 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru controlFound-=insertRemove; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* adjusted visual index is within current run */ 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove==0) { 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex+=controlFound; 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* count non-control chars until visualIndex */ 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=runs[i].logicalStart; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru evenRun=IS_EVEN_RUN(logicalStart); 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru REMOVE_ODD_BIT(logicalStart); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalEnd=logicalStart+length-1; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0; j<length; j++) { 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k= evenRun ? logicalStart+j : logicalEnd-j; 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uchar=pBiDi->text[k]; 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(uchar)) { 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru controlFound++; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((visualIndex+controlFound)==(visualStart+j)) { 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex+=controlFound; 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* handle all cases */ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(runCount<=10) { 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* linear search for the run */ 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; visualIndex>=runs[i].visualLimit; ++i) {} 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* binary search for the run */ 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t begin=0, limit=runCount; 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the middle if() is guaranteed to find the run, we don't need a loop limit */ 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=(begin+limit)/2; 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(visualIndex>=runs[i].visualLimit) { 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru begin=i+1; 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(i==0 || visualIndex>=runs[i-1].visualLimit) { 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=i; 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=runs[i].logicalStart; 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_EVEN_RUN(start)) { 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* LTR */ 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the offset in runs[i] is visualIndex-runs[i-1].visualLimit */ 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i>0) { 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualIndex-=runs[i-1].visualLimit; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return start+visualIndex; 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* RTL */ 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return GET_INDEX(start)+runs[i].visualLimit-visualIndex-1; 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) { 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ubidi_countRuns() checks for VALID_PARA_OR_LINE */ 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_countRuns(pBiDi, pErrorCode); 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no op */ 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(indexMap==NULL) { 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* fill a logical-to-visual index map using the runs[] */ 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t visualStart, visualLimit, i, j, k; 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t logicalStart, logicalLimit; 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs; 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBiDi->length<=0) { 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBiDi->length>pBiDi->resultLength) { 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(indexMap, 0xFF, pBiDi->length*sizeof(int32_t)); 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=0; 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0; j<pBiDi->runCount; ++j) { 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=GET_INDEX(runs[j].logicalStart); 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualLimit=runs[j].visualLimit; 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_EVEN_RUN(runs[j].logicalStart)) { 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { /* LTR */ 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[logicalStart++]=visualStart++; 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(visualStart<visualLimit); 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart+=visualLimit-visualStart; /* logicalLimit */ 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { /* RTL */ 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[--logicalStart]=visualStart++; 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(visualStart<visualLimit); 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* visualStart==visualLimit; */ 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size>0) { 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t markFound=0, runCount=pBiDi->runCount; 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, insertRemove; 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=0; 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* add number of marks found until each index */ 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++, visualStart+=length) { 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) { 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(markFound>0) { 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=GET_INDEX(runs[i].logicalStart); 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalLimit=logicalStart+length; 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=logicalStart; j<logicalLimit; j++) { 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[j]+=markFound; 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_AFTER|RLM_AFTER)) { 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->controlCount>0) { 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t controlFound=0, runCount=pBiDi->runCount; 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, insertRemove; 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool evenRun; 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar uchar; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=0; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* subtract number of controls found until each index */ 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++, visualStart+=length) { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no control found within previous runs nor within this run */ 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((controlFound-insertRemove)==0) { 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=runs[i].logicalStart; 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru evenRun=IS_EVEN_RUN(logicalStart); 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru REMOVE_ODD_BIT(logicalStart); 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalLimit=logicalStart+length; 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if no control within this run */ 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove==0) { 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=logicalStart; j<logicalLimit; j++) { 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[j]-=controlFound; 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0; j<length; j++) { 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k= evenRun ? logicalStart+j : logicalLimit-j-1; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uchar=pBiDi->text[k]; 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_BIDI_CONTROL_CHAR(uchar)) { 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru controlFound++; 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[k]=UBIDI_MAP_NOWHERE; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[k]-=controlFound; 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) { 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode); 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(indexMap==NULL) { 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ubidi_countRuns() checks for VALID_PARA_OR_LINE */ 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ubidi_countRuns(pBiDi, pErrorCode); 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(*pErrorCode)) { 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* fill a visual-to-logical index map using the runs[] */ 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Run *runs=pBiDi->runs, *runsLimit=runs+pBiDi->runCount; 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t logicalStart, visualStart, visualLimit, *pi=indexMap; 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (pBiDi->resultLength<=0) { 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=0; 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(; runs<runsLimit; ++runs) { 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=runs->logicalStart; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualLimit=runs->visualLimit; 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(IS_EVEN_RUN(logicalStart)) { 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { /* LTR */ 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pi++ = logicalStart++; 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(++visualStart<visualLimit); 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru REMOVE_ODD_BIT(logicalStart); 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart+=visualLimit-visualStart; /* logicalLimit */ 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { /* RTL */ 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pi++ = --logicalStart; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(++visualStart<visualLimit); 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* visualStart==visualLimit; */ 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBiDi->insertPoints.size>0) { 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t markFound=0, runCount=pBiDi->runCount; 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t insertRemove, i, j, k; 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runs; 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* count all inserted marks */ 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++) { 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) { 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_AFTER|RLM_AFTER)) { 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound++; 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* move back indexes by number of preceding marks */ 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k=pBiDi->resultLength; 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=runCount-1; i>=0 && markFound>0; i--) { 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_AFTER|RLM_AFTER)) { 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[--k]= UBIDI_MAP_NOWHERE; 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound--; 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart= i>0 ? runs[i-1].visualLimit : 0; 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=runs[i].visualLimit-1; j>=visualStart && markFound>0; j--) { 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[--k]=indexMap[j]; 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) { 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[--k]= UBIDI_MAP_NOWHERE; 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru markFound--; 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(pBiDi->controlCount>0) { 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t runCount=pBiDi->runCount, logicalEnd; 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t insertRemove, length, i, j, k, m; 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar uchar; 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool evenRun; 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru runs=pBiDi->runs; 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualStart=0; 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* move forward indexes by number of preceding controls */ 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k=0; 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<runCount; i++, visualStart+=length) { 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=runs[i].visualLimit-visualStart; 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru insertRemove=runs[i].insertRemove; 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if no control found yet, nothing to do in this run */ 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((insertRemove==0)&&(k==visualStart)) { 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru k+=length; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if no control in this run */ 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(insertRemove==0) { 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru visualLimit=runs[i].visualLimit; 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=visualStart; j<visualLimit; j++) { 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[k++]=indexMap[j]; 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalStart=runs[i].logicalStart; 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru evenRun=IS_EVEN_RUN(logicalStart); 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru REMOVE_ODD_BIT(logicalStart); 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logicalEnd=logicalStart+length-1; 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j=0; j<length; j++) { 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru m= evenRun ? logicalStart+j : logicalEnd-j; 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uchar=pBiDi->text[m]; 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(uchar)) { 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexMap[k++]=m; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length) { 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcMap!=NULL && destMap!=NULL && length>0) { 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *pi; 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t destLength=-1, count=0; 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* find highest value and count positive indexes in srcMap */ 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pi=srcMap+length; 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(pi>srcMap) { 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*--pi>destLength) { 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destLength=*pi; 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*pi>=0) { 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destLength++; /* add 1 for origin 0 */ 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count<destLength) { 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we must fill unmatched destMap entries with -1 */ 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(destMap, 0xFF, destLength*sizeof(int32_t)); 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pi=srcMap+length; 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(length>0) { 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*--pi>=0) { 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destMap[*pi]=--length; 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --length; 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1348