1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 2000-2011, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file name: ubidiwrt.c 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* encoding: US-ASCII 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* tab size: 8 (not used) 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* indentation:4 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 1999aug06 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Markus W. Scherer, updated by Matitiahu Allouche 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* This file contains implementations for BiDi functions that use 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* the core algorithm and core API to write reordered text. 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* set import/export definitions */ 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifndef U_COMMON_IMPLEMENTATION 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define U_COMMON_IMPLEMENTATION 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ubidi.h" 2983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf16.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustr_imp.h" 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ubidiimp.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The function implementations in this file are designed 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * for UTF-16 and UTF-32, not for UTF-8. 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Assumptions that are not true for UTF-8: 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - Any code point always needs the same number of code units 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ("minimum-length-problem" of UTF-8) 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - The BiDi control characters need only one code unit each 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Further assumptions for all UTFs: 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - u_charMirror(c) needs the same number of code units as c 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UTF_SIZE==8 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# error reimplement ubidi_writeReordered() for UTF-8, see comment above 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define IS_COMBINING(type) ((1UL<<(type))&(1UL<<U_NON_SPACING_MARK|1UL<<U_COMBINING_SPACING_MARK|1UL<<U_ENCLOSING_MARK)) 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * When we have UBIDI_OUTPUT_REVERSE set on ubidi_writeReordered(), then we 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * semantically write RTL runs in reverse and later reverse them again. 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Instead, we actually write them in forward order to begin with. 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * However, if the RTL run was to be mirrored, we need to mirror here now 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * since the implicit second reversal must not do it. 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It looks strange to do mirroring in LTR output, but it is only because 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * we are writing RTL output in reverse. 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerudoWriteForward(const UChar *src, int32_t srcLength, 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *dest, int32_t destSize, 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t options, 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* optimize for several combinations of options */ 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING)) { 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 0: { 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* simply copy the LTR run to the destination */ 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=srcLength; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize<length) { 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=*src++; 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(--length>0); 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UBIDI_DO_MIRRORING: { 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do mirroring */ 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i=0, j=0; 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 c; 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize<srcLength) { 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 9083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_NEXT(src, i, srcLength, c); 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=u_charMirror(c); 9283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_APPEND_UNSAFE(dest, j, c); 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(i<srcLength); 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UBIDI_REMOVE_BIDI_CONTROLS: { 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the LTR run and remove any BiDi control characters */ 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t remaining=destSize; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar c; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=*src++; 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(c)) { 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(--remaining<0) { 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preflight the length */ 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(--srcLength>0) { 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=*src++; 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(c)) { 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --remaining; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return destSize-remaining; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=c; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(--srcLength>0); 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return destSize-remaining; 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: { 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* remove BiDi control characters and do mirroring */ 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t remaining=destSize; 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, j=0; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 c; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 12783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_NEXT(src, i, srcLength, c); 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru src+=i; 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength-=i; 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(c)) { 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remaining-=i; 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(remaining<0) { 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preflight the length */ 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcLength>0) { 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=*src++; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(c)) { 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --remaining; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --srcLength; 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return destSize-remaining; 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=u_charMirror(c); 14683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_APPEND_UNSAFE(dest, j, c); 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(srcLength>0); 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return j; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } /* end of switch */ 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerudoWriteReverse(const UChar *src, int32_t srcLength, 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *dest, int32_t destSize, 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t options, 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * RTL run - 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * RTL runs need to be copied to the destination in reverse order 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of code points, not code units, to keep Unicode characters intact. 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The general strategy for this is to read the source text 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in backward order, collect all code units for a code point 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (and optionally following combining characters, see below), 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and copy all these code units in ascending order 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to the destination for this run. 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Several options request whether combining characters 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * should be kept after their base characters, 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * whether BiDi control characters should be removed, and 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * whether characters should be replaced by their mirror-image 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * equivalent Unicode characters. 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, j; 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 c; 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* optimize for several combinations of options */ 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING)) { 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 0: 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * With none of the "complicated" options set, the destination 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * run will have the same length as the source run, 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and there is no mirroring and no keeping combining characters 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * with their base characters. 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize<srcLength) { 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize=srcLength; 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preserve character integrity */ 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* i is always after the last code unit known to need to be kept in this segment */ 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=srcLength; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* collect code units for one base character */ 20183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_BACK_1(src, 0, srcLength); 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy this base character */ 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru j=srcLength; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=src[j++]; 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(j<i); 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(srcLength>0); 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UBIDI_KEEP_BASE_COMBINING: 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Here, too, the destination 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * run will have the same length as the source run, 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and there is no mirroring. 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We do need to keep combining characters with their base characters. 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize<srcLength) { 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return srcLength; 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize=srcLength; 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preserve character integrity */ 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* i is always after the last code unit known to need to be kept in this segment */ 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=srcLength; 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* collect code units and modifier letters for one base character */ 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 23083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_PREV(src, 0, srcLength, c); 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(srcLength>0 && IS_COMBINING(u_charType(c))); 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy this "user character" */ 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru j=srcLength; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=src[j++]; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(j<i); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(srcLength>0); 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * With several "complicated" options set, this is the most 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * general and the slowest copying of an RTL run. 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We will do mirroring, remove BiDi controls, and 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * keep combining characters with their base characters 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * as requested. 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!(options&UBIDI_REMOVE_BIDI_CONTROLS)) { 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=srcLength; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we need to find out the destination length of the run, 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru which will not include the BiDi control characters */ 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=srcLength; 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar ch; 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ch=*src++; 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!IS_BIDI_CONTROL_CHAR(ch)) { 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++i; 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(--length>0); 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru src-=srcLength; 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize<i) { 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize=i; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preserve character integrity */ 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* i is always after the last code unit known to need to be kept in this segment */ 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=srcLength; 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* collect code units for one base character */ 27883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_PREV(src, 0, srcLength, c); 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(options&UBIDI_KEEP_BASE_COMBINING) { 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* collect modifier letters for this base character */ 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcLength>0 && IS_COMBINING(u_charType(c))) { 28283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_PREV(src, 0, srcLength, c); 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(options&UBIDI_REMOVE_BIDI_CONTROLS && IS_BIDI_CONTROL_CHAR(c)) { 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not copy this BiDi control character */ 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy this "user character" */ 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru j=srcLength; 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(options&UBIDI_DO_MIRRORING) { 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mirror only the base character */ 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t k=0; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=u_charMirror(c); 29783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius U16_APPEND_UNSAFE(dest, k, c); 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest+=k; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru j+=k; 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(j<i) { 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=src[j++]; 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(srcLength>0); 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } /* end of switch */ 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return destSize; 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruubidi_writeReverse(const UChar *src, int32_t srcLength, 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *dest, int32_t destSize, 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t options, 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t destLength; 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* more error checking */ 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( src==NULL || srcLength<-1 || 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize<0 || (destSize>0 && dest==NULL)) 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do input and output overlap? */ 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( dest!=NULL && 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((src>=dest && src<dest+destSize) || 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (dest>=src && dest<src+srcLength))) 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength==-1) { 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength=u_strlen(src); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength>0) { 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=doWriteReverse(src, srcLength, dest, destSize, options, pErrorCode); 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* nothing to do */ 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=0; 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateUChars(dest, destSize, destLength, pErrorCode); 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruubidi_writeReordered(UBiDi *pBiDi, 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *dest, int32_t destSize, 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t options, 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *text; 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *saveDest; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length, destCapacity; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t run, runCount, logicalStart, runLength; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* more error checking */ 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( pBiDi==NULL || 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (text=pBiDi->text)==NULL || (length=pBiDi->length)<0 || 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize<0 || (destSize>0 && dest==NULL)) 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do input and output overlap? */ 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( dest!=NULL && 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((text>=dest && text<dest+destSize) || 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (dest>=text && dest<text+pBiDi->originalLength))) 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length==0) { 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* nothing to do */ 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateUChars(dest, destSize, 0, pErrorCode); 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runCount=ubidi_countRuns(pBiDi, pErrorCode); 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* destSize shrinks, later destination length=destCapacity-destSize */ 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru saveDest=dest; 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destCapacity=destSize; 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Option "insert marks" implies UBIDI_INSERT_LRM_FOR_NUMERIC if the 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * reordering mode (checked below) is appropriate. 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) { 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options|=UBIDI_INSERT_LRM_FOR_NUMERIC; 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options&=~UBIDI_REMOVE_BIDI_CONTROLS; 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Option "remove controls" implies UBIDI_REMOVE_BIDI_CONTROLS 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and cancels UBIDI_INSERT_LRM_FOR_NUMERIC. 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pBiDi->reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) { 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options|=UBIDI_REMOVE_BIDI_CONTROLS; 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options&=~UBIDI_INSERT_LRM_FOR_NUMERIC; 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If we do not perform the "inverse BiDi" algorithm, then we 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * don't need to insert any LRMs, and don't need to test for it. 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_NUMBERS_AS_L) && 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_LIKE_DIRECT) && 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL) && 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (pBiDi->reorderingMode != UBIDI_REORDER_RUNS_ONLY)) { 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options&=~UBIDI_INSERT_LRM_FOR_NUMERIC; 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Iterate through all visual runs and copy the run text segments to 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the destination, according to the options. 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The tests for where to insert LRMs ignore the fact that there may be 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * BN codes or non-BMP code points at the beginning and end of a run; 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * they may insert LRMs unnecessarily but the tests are faster this way 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (this would have to be improved for UTF-8). 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Note that the only errors that are set by doWriteXY() are buffer overflow 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * errors. Ignore them until the end, and continue for preflighting. 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!(options&UBIDI_OUTPUT_REVERSE)) { 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* forward output */ 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!(options&UBIDI_INSERT_LRM_FOR_NUMERIC)) { 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not insert BiDi controls */ 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(run=0; run<runCount; ++run) { 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength)) { 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteForward(text+logicalStart, runLength, 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode); 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteReverse(text+logicalStart, runLength, 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options, pErrorCode); 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 45083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 45183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 45283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* insert BiDi controls for "inverse BiDi" */ 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const DirProp *dirProps=pBiDi->dirProps; 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *src; 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar uc; 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBiDiDirection dir; 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t markFlag; 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(run=0; run<runCount; ++run) { 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dir=ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength); 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru src=text+logicalStart; 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check if something relevant in insertPoints */ 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag=pBiDi->runs[run].insertRemove; 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(markFlag<0) { /* BiDi controls count */ 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag=0; 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(UBIDI_LTR==dir) { 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pBiDi->isInverse) && 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (/*run>0 &&*/ dirProps[logicalStart]!=L)) { 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag |= LRM_BEFORE; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFlag & LRM_BEFORE) { 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=LRM_CHAR; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (markFlag & RLM_BEFORE) { 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=RLM_CHAR; 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else uc=0; 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uc) { 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=uc; 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteForward(src, runLength, 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode); 49483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 49583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 49683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pBiDi->isInverse) && 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (/*run<runCount-1 &&*/ dirProps[logicalStart+runLength-1]!=L)) { 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag |= LRM_AFTER; 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFlag & LRM_AFTER) { 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=LRM_CHAR; 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (markFlag & RLM_AFTER) { 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=RLM_CHAR; 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else uc=0; 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uc) { 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=uc; 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { /* RTL run */ 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pBiDi->isInverse) && 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (/*run>0 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart+runLength-1])))) { 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag |= RLM_BEFORE; 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFlag & LRM_BEFORE) { 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=LRM_CHAR; 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (markFlag & RLM_BEFORE) { 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=RLM_CHAR; 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else uc=0; 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uc) { 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=uc; 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteReverse(src, runLength, 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options, pErrorCode); 53883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 53983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 54083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pBiDi->isInverse) && 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (/*run<runCount-1 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart])))) { 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru markFlag |= RLM_AFTER; 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFlag & LRM_AFTER) { 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=LRM_CHAR; 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (markFlag & RLM_AFTER) { 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uc=RLM_CHAR; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else uc=0; 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uc) { 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=uc; 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reverse output */ 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!(options&UBIDI_INSERT_LRM_FOR_NUMERIC)) { 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not insert BiDi controls */ 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(run=runCount; --run>=0;) { 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength)) { 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteReverse(text+logicalStart, runLength, 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode); 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteForward(text+logicalStart, runLength, 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options, pErrorCode); 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 57783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 57883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 57983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* insert BiDi controls for "inverse BiDi" */ 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const DirProp *dirProps=pBiDi->dirProps; 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *src; 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBiDiDirection dir; 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(run=runCount; --run>=0;) { 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reverse output */ 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dir=ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength); 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru src=text+logicalStart; 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(UBIDI_LTR==dir) { 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(/*run<runCount-1 &&*/ dirProps[logicalStart+runLength-1]!=L) { 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=LRM_CHAR; 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteReverse(src, runLength, 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode); 60483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 60583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 60683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(/*run>0 &&*/ dirProps[logicalStart]!=L) { 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=LRM_CHAR; 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(/*run<runCount-1 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart]))) { 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=RLM_CHAR; 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru runLength=doWriteForward(src, runLength, 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest, destSize, 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru options, pErrorCode); 62683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(dest!=NULL) { 62783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius dest+=runLength; 62883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destSize-=runLength; 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(/*run>0 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart+runLength-1]))) { 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destSize>0) { 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=RLM_CHAR; 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --destSize; 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateUChars(saveDest, destCapacity, destCapacity-destSize, pErrorCode); 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 644