1 /* 2 ****************************************************************************** 3 * 4 * Copyright (C) 2016 and later: Unicode, Inc. and others. 5 * License & terms of use: http://www.unicode.org/copyright.html 6 * 7 ****************************************************************************** 8 * file name: ubiditransform.h 9 * encoding: US-ASCII 10 * tab size: 8 (not used) 11 * indentation:4 12 * 13 * created on: 2016jul24 14 * created by: Lina Kemmel 15 * 16 */ 17 18 #ifndef UBIDITRANSFORM_H 19 #define UBIDITRANSFORM_H 20 21 #include "unicode/utypes.h" 22 #include "unicode/ubidi.h" 23 #include "unicode/uchar.h" 24 #include "unicode/localpointer.h" 25 26 #ifndef U_HIDE_DRAFT_API 27 28 /** 29 * \file 30 * \brief Bidi Transformations 31 * 32 * <code>UBiDiOrder</code> indicates the order of text.<p> 33 * This bidi transformation engine supports all possible combinations (4 in 34 * total) of input and output text order: 35 * <ul> 36 * <li><logical input, visual output>: unless the output direction is RTL, this 37 * corresponds to a normal operation of the Bidi algorithm as described in the 38 * Unicode Technical Report and implemented by <code>UBiDi</code> when the 39 * reordering mode is set to <code>UBIDI_REORDER_DEFAULT</code>. Visual RTL 40 * mode is not supported by <code>UBiDi</code> and is accomplished through 41 * reversing a visual LTR string,</li> 42 * <li><visual input, logical output>: unless the input direction is RTL, this 43 * corresponds to an "inverse bidi algorithm" in <code>UBiDi</code> with the 44 * reordering mode set to <code>UBIDI_REORDER_INVERSE_LIKE_DIRECT</code>. 45 * Visual RTL mode is not not supported by <code>UBiDi</code> and is 46 * accomplished through reversing a visual LTR string,</li> 47 * <li><logical input, logical output>: if the input and output base directions 48 * mismatch, this corresponds to the <code>UBiDi</code> implementation with the 49 * reordering mode set to <code>UBIDI_REORDER_RUNS_ONLY</code>; and if the 50 * input and output base directions are identical, the transformation engine 51 * will only handle character mirroring and Arabic shaping operations without 52 * reordering,</li> 53 * <li><visual input, visual output>: this reordering mode is not supported by 54 * the <code>UBiDi</code> engine; it implies character mirroring, Arabic 55 * shaping, and - if the input/output base directions mismatch - string 56 * reverse operations.</li> 57 * </ul> 58 * @see ubidi_setInverse 59 * @see ubidi_setReorderingMode 60 * @see UBIDI_REORDER_DEFAULT 61 * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT 62 * @see UBIDI_REORDER_RUNS_ONLY 63 * @draft ICU 58 64 */ 65 typedef enum { 66 /** 0: Constant indicating a logical order. 67 * This is the default for input text. 68 * @draft ICU 58 69 */ 70 UBIDI_LOGICAL = 0, 71 /** 1: Constant indicating a visual order. 72 * This is a default for output text. 73 * @draft ICU 58 74 */ 75 UBIDI_VISUAL 76 } UBiDiOrder; 77 78 /** 79 * <code>UBiDiMirroring</code> indicates whether or not characters with the 80 * "mirrored" property in RTL runs should be replaced with their mirror-image 81 * counterparts. 82 * @see UBIDI_DO_MIRRORING 83 * @see ubidi_setReorderingOptions 84 * @see ubidi_writeReordered 85 * @see ubidi_writeReverse 86 * @draft ICU 58 87 */ 88 typedef enum { 89 /** 0: Constant indicating that character mirroring should not be 90 * performed. 91 * This is the default. 92 * @draft ICU 58 93 */ 94 UBIDI_MIRRORING_OFF = 0, 95 /** 1: Constant indicating that character mirroring should be performed. 96 * This corresponds to calling <code>ubidi_writeReordered</code> or 97 * <code>ubidi_writeReverse</code> with the 98 * <code>UBIDI_DO_MIRRORING</code> option bit set. 99 * @draft ICU 58 100 */ 101 UBIDI_MIRRORING_ON 102 } UBiDiMirroring; 103 104 /** 105 * Forward declaration of the <code>UBiDiTransform</code> structure that stores 106 * information used by the layout transformation engine. 107 * @draft ICU 58 108 */ 109 typedef struct UBiDiTransform UBiDiTransform; 110 111 /** 112 * Performs transformation of text from the bidi layout defined by the input 113 * ordering scheme to the bidi layout defined by the output ordering scheme, 114 * and applies character mirroring and Arabic shaping operations.<p> 115 * In terms of <code>UBiDi</code>, such a transformation implies: 116 * <ul> 117 * <li>calling <code>ubidi_setReorderingMode</code> as needed (when the 118 * reordering mode is other than normal),</li> 119 * <li>calling <code>ubidi_setInverse</code> as needed (when text should be 120 * transformed from a visual to a logical form),</li> 121 * <li>resolving embedding levels of each character in the input text by 122 * calling <code>ubidi_setPara</code>,</li> 123 * <li>reordering the characters based on the computed embedding levels, also 124 * performing character mirroring as needed, and streaming the result to the 125 * output, by calling <code>ubidi_writeReordered</code>,</li> 126 * <li>performing Arabic digit and letter shaping on the output text by calling 127 * <code>u_shapeArabic</code>.</li> 128 * </ul> 129 * An "ordering scheme" encompasses the base direction and the order of text, 130 * and these characteristics must be defined by the caller for both input and 131 * output explicitly .<p> 132 * There are 36 possible combinations of <input, output> ordering schemes, 133 * which are partially supported by <code>UBiDi</code> already. Examples of the 134 * currently supported combinations: 135 * <ul> 136 * <li><Logical LTR, Visual LTR>: this is equivalent to calling 137 * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_LTR</code>,</li> 138 * <li><Logical RTL, Visual LTR>: this is equivalent to calling 139 * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_RTL</code>,</li> 140 * <li><Logical Default ("Auto") LTR, Visual LTR>: this is equivalent to 141 * calling <code>ubidi_setPara</code> with 142 * <code>paraLevel == UBIDI_DEFAULT_LTR</code>,</li> 143 * <li><Logical Default ("Auto") RTL, Visual LTR>: this is equivalent to 144 * calling <code>ubidi_setPara</code> with 145 * <code>paraLevel == UBIDI_DEFAULT_RTL</code>,</li> 146 * <li><Visual LTR, Logical LTR>: this is equivalent to 147 * calling <code>ubidi_setInverse(UBiDi*, TRUE)</code> and then 148 * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_LTR</code>,</li> 149 * <li><Visual LTR, Logical RTL>: this is equivalent to 150 * calling <code>ubidi_setInverse(UBiDi*, TRUE)</code> and then 151 * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_RTL</code>.</li> 152 * </ul> 153 * All combinations that involve the Visual RTL scheme are unsupported by 154 * <code>UBiDi</code>, for instance: 155 * <ul> 156 * <li><Logical LTR, Visual RTL>,</li> 157 * <li><Visual RTL, Logical RTL>.</li> 158 * </ul> 159 * <p>Example of usage of the transformation engine:<br> 160 * <pre> 161 * \code 162 * UChar text1[] = {'a', 'b', 'c', 0x0625, '1', 0}; 163 * UChar text2[] = {'a', 'b', 'c', 0x0625, '1', 0}; 164 * UErrorCode errorCode = U_ZERO_ERROR; 165 * // Run a transformation. 166 * ubiditransform_transform(pBidiTransform, 167 * text1, -1, text2, -1, 168 * UBIDI_LTR, UBIDI_VISUAL, 169 * UBIDI_RTL, UBIDI_LOGICAL, 170 * UBIDI_MIRRORING_OFF, 171 * U_SHAPE_DIGITS_AN2EN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED, 172 * &errorCode); 173 * // Do something with text2. 174 * text2[4] = '2'; 175 * // Run a reverse transformation. 176 * ubiditransform_transform(pBidiTransform, 177 * text2, -1, text1, -1, 178 * UBIDI_RTL, UBIDI_LOGICAL, 179 * UBIDI_LTR, UBIDI_VISUAL, 180 * UBIDI_MIRRORING_OFF, 181 * U_SHAPE_DIGITS_EN2AN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED, 182 * &errorCode); 183 *\endcode 184 * </pre> 185 * </p> 186 * 187 * @param pBiDiTransform A pointer to a <code>UBiDiTransform</code> object 188 * allocated with <code>ubiditransform_open()</code> or 189 * <code>NULL</code>.<p> 190 * This object serves for one-time setup to amortize initialization 191 * overheads. Use of this object is not thread-safe. All other threads 192 * should allocate a new <code>UBiDiTransform</code> object by calling 193 * <code>ubiditransform_open()</code> before using it. Alternatively, 194 * a caller can set this parameter to <code>NULL</code>, in which case 195 * the object will be allocated by the engine on the fly.</p> 196 * @param src A pointer to the text that the Bidi layout transformations will 197 * be performed on. 198 * <p><strong>Note:</strong> the text must be (at least) 199 * <code>srcLength</code> long.</p> 200 * @param srcLength The length of the text, in number of UChars. If 201 * <code>length == -1</code> then the text must be zero-terminated. 202 * @param dest A pointer to where the processed text is to be copied. 203 * @param destSize The size of the <code>dest</code> buffer, in number of 204 * UChars. If the <code>U_SHAPE_LETTERS_UNSHAPE</code> option is set, 205 * then the destination length could be as large as 206 * <code>srcLength * 2</code>. Otherwise, the destination length will 207 * not exceed <code>srcLength</code>. If the caller reserves the last 208 * position for zero-termination, it should be excluded from 209 * <code>destSize</code>. 210 * <p><code>destSize == -1</code> is allowed and makes sense when 211 * <code>dest</code> was holds some meaningful value, e.g. that of 212 * <code>src</code>. In this case <code>dest</code> must be 213 * zero-terminated.</p> 214 * @param inParaLevel A base embedding level of the input as defined in 215 * <code>ubidi_setPara</code> documentation for the 216 * <code>paraLevel</code> parameter. 217 * @param inOrder An order of the input, which can be one of the 218 * <code>UBiDiOrder</code> values. 219 * @param outParaLevel A base embedding level of the output as defined in 220 * <code>ubidi_setPara</code> documentation for the 221 * <code>paraLevel</code> parameter. 222 * @param outOrder An order of the output, which can be one of the 223 * <code>UBiDiOrder</code> values. 224 * @param doMirroring Indicates whether or not to perform character mirroring, 225 * and can accept one of the <code>UBiDiMirroring</code> values. 226 * @param shapingOptions Arabic digit and letter shaping options defined in the 227 * ushape.h documentation. 228 * <p><strong>Note:</strong> Direction indicator options are computed by 229 * the transformation engine based on the effective ordering schemes, so 230 * user-defined direction indicators will be ignored.</p> 231 * @param pErrorCode A pointer to an error code value. 232 * 233 * @return The destination length, i.e. the number of UChars written to 234 * <code>dest</code>. If the transformation fails, the return value 235 * will be 0 (and the error code will be written to 236 * <code>pErrorCode</code>). 237 * 238 * @see UBiDiLevel 239 * @see UBiDiOrder 240 * @see UBiDiMirroring 241 * @see ubidi_setPara 242 * @see u_shapeArabic 243 * @draft ICU 58 244 */ 245 U_DRAFT uint32_t U_EXPORT2 246 ubiditransform_transform(UBiDiTransform *pBiDiTransform, 247 const UChar *src, int32_t srcLength, 248 UChar *dest, int32_t destSize, 249 UBiDiLevel inParaLevel, UBiDiOrder inOrder, 250 UBiDiLevel outParaLevel, UBiDiOrder outOrder, 251 UBiDiMirroring doMirroring, uint32_t shapingOptions, 252 UErrorCode *pErrorCode); 253 254 /** 255 * Allocates a <code>UBiDiTransform</code> object. This object can be reused, 256 * e.g. with different ordering schemes, mirroring or shaping options.<p> 257 * <strong>Note:</strong>The object can only be reused in the same thread. 258 * All other threads should allocate a new <code>UBiDiTransform</code> object 259 * before using it.<p> 260 * Example of usage:<p> 261 * <pre> 262 * \code 263 * UErrorCode errorCode = U_ZERO_ERROR; 264 * // Open a new UBiDiTransform. 265 * UBiDiTransform* transform = ubiditransform_open(&errorCode); 266 * // Run a transformation. 267 * ubiditransform_transform(transform, 268 * text1, -1, text2, -1, 269 * UBIDI_RTL, UBIDI_LOGICAL, 270 * UBIDI_LTR, UBIDI_VISUAL, 271 * UBIDI_MIRRORING_ON, 272 * U_SHAPE_DIGITS_EN2AN, 273 * &errorCode); 274 * // Do something with the output text and invoke another transformation using 275 * // that text as input. 276 * ubiditransform_transform(transform, 277 * text2, -1, text3, -1, 278 * UBIDI_LTR, UBIDI_VISUAL, 279 * UBIDI_RTL, UBIDI_VISUAL, 280 * UBIDI_MIRRORING_ON, 281 * 0, &errorCode); 282 *\endcode 283 * </pre> 284 * <p> 285 * The <code>UBiDiTransform</code> object must be deallocated by calling 286 * <code>ubiditransform_close()</code>. 287 * 288 * @return An empty <code>UBiDiTransform</code> object. 289 * @draft ICU 58 290 */ 291 U_DRAFT UBiDiTransform* U_EXPORT2 292 ubiditransform_open(UErrorCode *pErrorCode); 293 294 /** 295 * Deallocates the given <code>UBiDiTransform</code> object. 296 * @draft ICU 58 297 */ 298 U_DRAFT void U_EXPORT2 299 ubiditransform_close(UBiDiTransform *pBidiTransform); 300 301 #if U_SHOW_CPLUSPLUS_API 302 303 U_NAMESPACE_BEGIN 304 305 /** 306 * \class LocalUBiDiTransformPointer 307 * "Smart pointer" class, closes a UBiDiTransform via ubiditransform_close(). 308 * For most methods see the LocalPointerBase base class. 309 * 310 * @see LocalPointerBase 311 * @see LocalPointer 312 * @draft ICU 58 313 */ 314 U_DEFINE_LOCAL_OPEN_POINTER(LocalUBiDiTransformPointer, UBiDiTransform, ubiditransform_close); 315 316 U_NAMESPACE_END 317 318 #endif 319 320 #endif /* U_HIDE_DRAFT_API */ 321 #endif 322