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