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