X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..57a6839dcb3bba09e8228b822b290604668416fe:/icuSources/common/unicode/ubidi.h diff --git a/icuSources/common/unicode/ubidi.h b/icuSources/common/unicode/ubidi.h index a0528d21..27042ed7 100644 --- a/icuSources/common/unicode/ubidi.h +++ b/icuSources/common/unicode/ubidi.h @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 1999-2004, International Business Machines +* Copyright (C) 1999-2013, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -11,7 +11,7 @@ * indentation:4 * * created on: 1999jul27 -* created by: Markus W. Scherer +* created by: Markus W. Scherer, updated by Matitiahu Allouche */ #ifndef UBIDI_H @@ -19,35 +19,21 @@ #include "unicode/utypes.h" #include "unicode/uchar.h" - -/* - * javadoc-style comments are intended to be transformed into HTML - * using DOC++ - see - * http://www.zib.de/Visual/software/doc++/index.html . - * - * The HTML documentation is created with - * doc++ -H ubidi.h - * - * The following #define trick allows us to do it all in one file - * and still be able to compile it. - */ -/*#define DOCXX_TAG*/ -/*#define BIDI_SAMPLE_CODE*/ +#include "unicode/localpointer.h" /** *\file - * \brief C API: BIDI algorithm + * \brief C API: Bidi algorithm * - *

BIDI algorithm for ICU

+ *

Bidi algorithm for ICU

* - * This is an implementation of the Unicode Bidirectional algorithm. + * This is an implementation of the Unicode Bidirectional Algorithm. * The algorithm is defined in the - * Unicode Standard Annex #9, - * version 13, also described in The Unicode Standard, Version 4.0 .

+ * Unicode Standard Annex #9.

* * Note: Libraries that perform a bidirectional algorithm and * reorder strings accordingly are sometimes called "Storage Layout Engines". - * ICU's BiDi and shaping (u_shapeArabic()) APIs can be used at the core of such + * ICU's Bidi and shaping (u_shapeArabic()) APIs can be used at the core of such * "Storage Layout Engines". * *

General remarks about the API:

@@ -64,18 +50,18 @@ * Some of the API functions provide access to "runs". * Such a "run" is defined as a sequence of characters * that are at the same embedding level - * after performing the BIDI algorithm.

+ * after performing the Bidi algorithm.

* * @author Markus W. Scherer * @version 1.0 * * - *

Sample code for the ICU BIDI API

+ *

Sample code for the ICU Bidi API

* - *
Rendering a paragraph with the ICU BiDi API
+ *
Rendering a paragraph with the ICU Bidi API
* * This is (hypothetical) sample code that illustrates - * how the ICU BiDi API could be used to render a paragraph of text. + * how the ICU Bidi API could be used to render a paragraph of text. * Rendering code depends highly on the graphics system, * therefore this sample code must make a lot of assumptions, * which may or may not match any existing graphics system's properties. @@ -303,7 +289,7 @@ /** * UBiDiLevel is the type of the level values in this - * BiDi implementation. + * Bidi implementation. * It holds an embedding level and indicates the visual direction * by its bit 0 (even/odd value).

* @@ -314,7 +300,7 @@ *

  • bit 7 of an embeddingLevels[] * value indicates whether the using application is * specifying the level of a character to override whatever the - * BiDi implementation would resolve it to.
  • + * Bidi implementation would resolve it to. *
  • paraLevel can be set to the * pseudo-level values UBIDI_DEFAULT_LTR * and UBIDI_DEFAULT_RTL.
  • @@ -343,14 +329,55 @@ */ typedef uint8_t UBiDiLevel; -/** Paragraph level setting. - * If there is no strong character, then set the paragraph level to 0 (left-to-right). +/** Paragraph level setting.

    + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 0 (left-to-right).

    + * + * If this value is used in conjunction with reordering modes + * UBIDI_REORDER_INVERSE_LIKE_DIRECT or + * UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, the direction will be LTR otherwise.

    + * + * If reordering option UBIDI_OPTION_INSERT_MARKS is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT + * @see UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL * @stable ICU 2.0 */ #define UBIDI_DEFAULT_LTR 0xfe -/** Paragraph level setting. - * If there is no strong character, then set the paragraph level to 1 (right-to-left). +/** Paragraph level setting.

    + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 1 (right-to-left).

    + * + * If this value is used in conjunction with reordering modes + * UBIDI_REORDER_INVERSE_LIKE_DIRECT or + * UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, or if the text contains no strong character; + * the direction will be LTR otherwise.

    + * + * If reordering option UBIDI_OPTION_INSERT_MARKS is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT + * @see UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL * @stable ICU 2.0 */ #define UBIDI_DEFAULT_RTL 0xff @@ -360,7 +387,7 @@ typedef uint8_t UBiDiLevel; * (The maximum resolved level can be up to UBIDI_MAX_EXPLICIT_LEVEL+1). * @stable ICU 2.0 */ -#define UBIDI_MAX_EXPLICIT_LEVEL 61 +#define UBIDI_MAX_EXPLICIT_LEVEL 125 /** Bit flag for level input. * Overrides directional properties. @@ -368,17 +395,64 @@ typedef uint8_t UBiDiLevel; */ #define UBIDI_LEVEL_OVERRIDE 0x80 +/** + * Special value which can be returned by the mapping functions when a logical + * index has no corresponding visual index or vice-versa. This may happen + * for the logical-to-visual mapping of a Bidi control when option + * #UBIDI_OPTION_REMOVE_CONTROLS is specified. This can also happen + * for the visual-to-logical mapping of a Bidi mark (LRM or RLM) inserted + * by option #UBIDI_OPTION_INSERT_MARKS. + * @see ubidi_getVisualIndex + * @see ubidi_getVisualMap + * @see ubidi_getLogicalIndex + * @see ubidi_getLogicalMap + * @stable ICU 3.6 + */ +#define UBIDI_MAP_NOWHERE (-1) + /** * UBiDiDirection values indicate the text direction. * @stable ICU 2.0 */ enum UBiDiDirection { - /** All left-to-right text. This is a 0 value. @stable ICU 2.0 */ - UBIDI_LTR, - /** All right-to-left text. This is a 1 value. @stable ICU 2.0 */ - UBIDI_RTL, - /** Mixed-directional text. @stable ICU 2.0 */ - UBIDI_MIXED + /** Left-to-right text. This is a 0 value. + *

    + * @stable ICU 2.0 + */ + UBIDI_LTR, + /** Right-to-left text. This is a 1 value. + * + * @stable ICU 2.0 + */ + UBIDI_RTL, + /** Mixed-directional text. + *

    As return value for ubidi_getDirection(), it means + * that the source string contains both left-to-right and + * right-to-left characters. + * @stable ICU 2.0 + */ + UBIDI_MIXED, + /** No strongly directional text. + *

    As return value for ubidi_getBaseDirection(), it means + * that the source string is missing or empty, or contains neither left-to-right + * nor right-to-left characters. + * @stable ICU 4.6 + */ + UBIDI_NEUTRAL }; /** @stable ICU 2.0 */ @@ -387,11 +461,11 @@ typedef enum UBiDiDirection UBiDiDirection; /** * Forward declaration of the UBiDi structure for the declaration of * the API functions. Its fields are implementation-specific.

    - * This structure holds information about a paragraph of text - * with BiDi-algorithm-related details, or about one line of + * This structure holds information about a paragraph (or multiple paragraphs) + * of text with Bidi-algorithm-related details, or about one line of * such a paragraph.

    - * Reordering can be done on a line, or on a paragraph which is - * then interpreted as one single line. + * Reordering can be done on a line, or on one or more paragraphs which are + * then interpreted each as one single line. * @stable ICU 2.0 */ struct UBiDi; @@ -402,13 +476,14 @@ typedef struct UBiDi UBiDi; /** * Allocate a UBiDi structure. * Such an object is initially empty. It is assigned - * the BiDi properties of a paragraph by ubidi_setPara() - * or the BiDi properties of a line of a paragraph by + * the Bidi properties of a piece of text containing one or more paragraphs + * by ubidi_setPara() + * or the Bidi properties of a line within a paragraph by * ubidi_setLine().

    * This object can be reused for as long as it is not deallocated * by calling ubidi_close().

    - * ubidi_set() will allocate additional memory for - * internal structures as necessary. + * ubidi_setPara() and ubidi_setLine() will allocate + * additional memory for internal structures as necessary. * * @return An empty UBiDi object. * @stable ICU 2.0 @@ -432,7 +507,7 @@ ubidi_open(void); * and the internal structures that are associated with it will be allocated * on demand, just like with ubidi_open(). * - * @param maxLength is the maximum paragraph or line length that internal memory + * @param maxLength is the maximum text or line length that internal memory * will be preallocated for. An attempt to associate this object with a * longer text will fail, unless this value is 0, which leaves the allocation * up to the implementation. @@ -441,12 +516,11 @@ ubidi_open(void); * that internal memory will be preallocated for. An attempt to access * visual runs on an object that was not preallocated for as many runs * as the text was actually resolved to will fail, - * unless this value is 0, which leaves the allocation up to the implementation.

    + * unless this value is 0, which leaves the allocation up to the implementation.

    * The number of runs depends on the actual text and maybe anywhere between - * 1 and maxLength. It is typically small.

    + * 1 and maxLength. It is typically small. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return An empty UBiDi object with preallocated memory. * @stable ICU 2.0 @@ -461,8 +535,8 @@ ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode); * Important: * A parent UBiDi object must not be destroyed or reused if * it still has children. - * If a UBiDi object is the child - * of another one (its parent), after calling + * If a UBiDi object has become the child + * of another one (its parent) by calling * ubidi_setLine(), then the child object must * be destroyed (closed) or reused (by calling * ubidi_setPara() or ubidi_setLine()) @@ -477,68 +551,600 @@ ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode); U_STABLE void U_EXPORT2 ubidi_close(UBiDi *pBiDi); +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN + /** - * Modify the operation of the BiDi algorithm such that it - * approximates an "inverse BiDi" algorithm. This function + * \class LocalUBiDiPointer + * "Smart pointer" class, closes a UBiDi via ubidi_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 4.4 + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUBiDiPointer, UBiDi, ubidi_close); + +U_NAMESPACE_END + +#endif + +/** + * Modify the operation of the Bidi algorithm such that it + * approximates an "inverse Bidi" algorithm. This function * must be called before ubidi_setPara(). * - *

    The normal operation of the BiDi algorithm as described + *

    The normal operation of the Bidi algorithm as described * in the Unicode Technical Report is to take text stored in logical * (keyboard, typing) order and to determine the reordering of it for visual * rendering. * Some legacy systems store text in visual order, and for operations * with standard, Unicode-based algorithms, the text needs to be transformed * to logical order. This is effectively the inverse algorithm of the - * described BiDi algorithm. Note that there is no standard algorithm for - * this "inverse BiDi" and that the current implementation provides only an - * approximation of "inverse BiDi".

    + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi" and that the current implementation provides only an + * approximation of "inverse Bidi".

    * *

    With isInverse set to TRUE, * this function changes the behavior of some of the subsequent functions - * in a way that they can be used for the inverse BiDi algorithm. + * in a way that they can be used for the inverse Bidi algorithm. * Specifically, runs of text with numeric characters will be treated in a * special way and may need to be surrounded with LRM characters when they are * written in reordered sequence.

    * *

    Output runs should be retrieved using ubidi_getVisualRun(). - * Since the actual input for "inverse BiDi" is visually ordered text and + * Since the actual input for "inverse Bidi" is visually ordered text and * ubidi_getVisualRun() gets the reordered runs, these are actually * the runs of the logically ordered output.

    * + *

    Calling this function with argument isInverse set to + * TRUE is equivalent to calling + * ubidi_setReorderingMode with argument + * reorderingMode + * set to #UBIDI_REORDER_INVERSE_NUMBERS_AS_L.
    + * Calling this function with argument isInverse set to + * FALSE is equivalent to calling + * ubidi_setReorderingMode with argument + * reorderingMode + * set to #UBIDI_REORDER_DEFAULT. + * * @param pBiDi is a UBiDi object. * - * @param isInverse specifies "forward" or "inverse" BiDi operation + * @param isInverse specifies "forward" or "inverse" Bidi operation. * * @see ubidi_setPara * @see ubidi_writeReordered + * @see ubidi_setReorderingMode * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 ubidi_setInverse(UBiDi *pBiDi, UBool isInverse); /** - * Is this BiDi object set to perform the inverse BiDi algorithm? + * Is this Bidi object set to perform the inverse Bidi algorithm? + *

    Note: calling this function after setting the reordering mode with + * ubidi_setReorderingMode will return TRUE if the + * reordering mode was set to #UBIDI_REORDER_INVERSE_NUMBERS_AS_L, + * FALSE for all other values.

    * * @param pBiDi is a UBiDi object. - * @return TRUE if the BiDi object set to perform the inverse BiDi algorithm + * @return TRUE if the Bidi object is set to perform the inverse Bidi algorithm + * by handling numbers as L. * * @see ubidi_setInverse + * @see ubidi_setReorderingMode * @stable ICU 2.0 */ + U_STABLE UBool U_EXPORT2 ubidi_isInverse(UBiDi *pBiDi); /** - * Perform the Unicode BiDi algorithm. It is defined in the + * Specify whether block separators must be allocated level zero, + * so that successive paragraphs will progress from left to right. + * This function must be called before ubidi_setPara(). + * Paragraph separators (B) may appear in the text. Setting them to level zero + * means that all paragraph separators (including one possibly appearing + * in the last text position) are kept in the reordered text after the text + * that they follow in the source text. + * When this feature is not enabled, a paragraph separator at the last + * position of the text before reordering will go to the first position + * of the reordered text when the paragraph level is odd. + * + * @param pBiDi is a UBiDi object. + * + * @param orderParagraphsLTR specifies whether paragraph separators (B) must + * receive level 0, so that successive paragraphs progress from left to right. + * + * @see ubidi_setPara + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR); + +/** + * Is this Bidi object set to allocate level 0 to block separators so that + * successive paragraphs progress from left to right? + * + * @param pBiDi is a UBiDi object. + * @return TRUE if the Bidi object is set to allocate level 0 to block + * separators. + * + * @see ubidi_orderParagraphsLTR + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +ubidi_isOrderParagraphsLTR(UBiDi *pBiDi); + +/** + * UBiDiReorderingMode values indicate which variant of the Bidi + * algorithm to use. + * + * @see ubidi_setReorderingMode + * @stable ICU 3.6 + */ +typedef enum UBiDiReorderingMode { + /** Regular Logical to Visual Bidi algorithm according to Unicode. + * This is a 0 value. + * @stable ICU 3.6 */ + UBIDI_REORDER_DEFAULT = 0, + /** Logical to Visual algorithm which handles numbers in a way which + * mimicks the behavior of Windows XP. + * @stable ICU 3.6 */ + UBIDI_REORDER_NUMBERS_SPECIAL, + /** Logical to Visual algorithm grouping numbers with adjacent R characters + * (reversible algorithm). + * @stable ICU 3.6 */ + UBIDI_REORDER_GROUP_NUMBERS_WITH_R, + /** Reorder runs only to transform a Logical LTR string to the Logical RTL + * string with the same display, or vice-versa.
    + * If this mode is set together with option + * #UBIDI_OPTION_INSERT_MARKS, some Bidi controls in the source + * text may be removed and other controls may be added to produce the + * minimum combination which has the required display. + * @stable ICU 3.6 */ + UBIDI_REORDER_RUNS_ONLY, + /** Visual to Logical algorithm which handles numbers like L + * (same algorithm as selected by ubidi_setInverse(TRUE). + * @see ubidi_setInverse + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_NUMBERS_AS_L, + /** Visual to Logical algorithm equivalent to the regular Logical to Visual + * algorithm. + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_LIKE_DIRECT, + /** Inverse Bidi (Visual to Logical) algorithm for the + * UBIDI_REORDER_NUMBERS_SPECIAL Bidi algorithm. + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL, + /** Number of values for reordering mode. + * @stable ICU 3.6 */ + UBIDI_REORDER_COUNT +} UBiDiReorderingMode; + +/** + * Modify the operation of the Bidi algorithm such that it implements some + * variant to the basic Bidi algorithm or approximates an "inverse Bidi" + * algorithm, depending on different values of the "reordering mode". + * This function must be called before ubidi_setPara(), and stays + * in effect until called again with a different argument. + * + *

    The normal operation of the Bidi algorithm as described + * in the Unicode Standard Annex #9 is to take text stored in logical + * (keyboard, typing) order and to determine how to reorder it for visual + * rendering.

    + * + *

    With the reordering mode set to a value other than + * #UBIDI_REORDER_DEFAULT, this function changes the behavior of + * some of the subsequent functions in a way such that they implement an + * inverse Bidi algorithm or some other algorithm variants.

    + * + *

    Some legacy systems store text in visual order, and for operations + * with standard, Unicode-based algorithms, the text needs to be transformed + * into logical order. This is effectively the inverse algorithm of the + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi", so a number of variants are implemented here.

    + * + *

    In other cases, it may be desirable to emulate some variant of the + * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a + * Logical to Logical transformation.

    + * + * + * + *

    In all the reordering modes specifying an "inverse Bidi" algorithm + * (i.e. those with a name starting with UBIDI_REORDER_INVERSE), + * output runs should be retrieved using + * ubidi_getVisualRun(), and the output text with + * ubidi_writeReordered(). The caller should keep in mind that in + * "inverse Bidi" modes the input is actually visually ordered text and + * reordered output returned by ubidi_getVisualRun() or + * ubidi_writeReordered() are actually runs or character string + * of logically ordered output.
    + * For all the "inverse Bidi" modes, the source text should not contain + * Bidi control characters other than LRM or RLM.

    + * + *

    Note that option #UBIDI_OUTPUT_REVERSE of + * ubidi_writeReordered has no useful meaning and should not be + * used in conjunction with any value of the reordering mode specifying + * "inverse Bidi" or with value UBIDI_REORDER_RUNS_ONLY. + * + * @param pBiDi is a UBiDi object. + * @param reorderingMode specifies the required variant of the Bidi algorithm. + * + * @see UBiDiReorderingMode + * @see ubidi_setInverse + * @see ubidi_setPara + * @see ubidi_writeReordered + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode); + +/** + * What is the requested reordering mode for a given Bidi object? + * + * @param pBiDi is a UBiDi object. + * @return the current reordering mode of the Bidi object + * @see ubidi_setReorderingMode + * @stable ICU 3.6 + */ +U_STABLE UBiDiReorderingMode U_EXPORT2 +ubidi_getReorderingMode(UBiDi *pBiDi); + +/** + * UBiDiReorderingOption values indicate which options are + * specified to affect the Bidi algorithm. + * + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ +typedef enum UBiDiReorderingOption { + /** + * option value for ubidi_setReorderingOptions: + * disable all the options which can be set with this function + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_DEFAULT = 0, + + /** + * option bit for ubidi_setReorderingOptions: + * insert Bidi marks (LRM or RLM) when needed to ensure correct result of + * a reordering to a Logical order + * + *

    This option must be set or reset before calling + * ubidi_setPara.

    + * + *

    This option is significant only with reordering modes which generate + * a result with Logical order, specifically:

    + * + * + *

    If this option is set in conjunction with reordering mode + * #UBIDI_REORDER_INVERSE_NUMBERS_AS_L or with calling + * ubidi_setInverse(TRUE), it implies + * option #UBIDI_INSERT_LRM_FOR_NUMERIC + * in calls to function ubidi_writeReordered().

    + * + *

    For other reordering modes, a minimum number of LRM or RLM characters + * will be added to the source text after reordering it so as to ensure + * round trip, i.e. when applying the inverse reordering mode on the + * resulting logical text with removal of Bidi marks + * (option #UBIDI_OPTION_REMOVE_CONTROLS set before calling + * ubidi_setPara() or option #UBIDI_REMOVE_BIDI_CONTROLS + * in ubidi_writeReordered), the result will be identical to the + * source text in the first transformation. + * + *

    This option will be ignored if specified together with option + * #UBIDI_OPTION_REMOVE_CONTROLS. It inhibits option + * UBIDI_REMOVE_BIDI_CONTROLS in calls to function + * ubidi_writeReordered() and it implies option + * #UBIDI_INSERT_LRM_FOR_NUMERIC in calls to function + * ubidi_writeReordered() if the reordering mode is + * #UBIDI_REORDER_INVERSE_NUMBERS_AS_L.

    + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_INSERT_MARKS = 1, + + /** + * option bit for ubidi_setReorderingOptions: + * remove Bidi control characters + * + *

    This option must be set or reset before calling + * ubidi_setPara.

    + * + *

    This option nullifies option #UBIDI_OPTION_INSERT_MARKS. + * It inhibits option #UBIDI_INSERT_LRM_FOR_NUMERIC in calls + * to function ubidi_writeReordered() and it implies option + * #UBIDI_REMOVE_BIDI_CONTROLS in calls to that function.

    + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_REMOVE_CONTROLS = 2, + + /** + * option bit for ubidi_setReorderingOptions: + * process the output as part of a stream to be continued + * + *

    This option must be set or reset before calling + * ubidi_setPara.

    + * + *

    This option specifies that the caller is interested in processing large + * text object in parts. + * The results of the successive calls are expected to be concatenated by the + * caller. Only the call for the last part will have this option bit off.

    + * + *

    When this option bit is on, ubidi_setPara() may process + * less than the full source text in order to truncate the text at a meaningful + * boundary. The caller should call ubidi_getProcessedLength() + * immediately after calling ubidi_setPara() in order to + * determine how much of the source text has been processed. + * Source text beyond that length should be resubmitted in following calls to + * ubidi_setPara. The processed length may be less than + * the length of the source text if a character preceding the last character of + * the source text constitutes a reasonable boundary (like a block separator) + * for text to be continued.
    + * If the last character of the source text constitutes a reasonable + * boundary, the whole text will be processed at once.
    + * If nowhere in the source text there exists + * such a reasonable boundary, the processed length will be zero.
    + * The caller should check for such an occurrence and do one of the following: + *

    + * In all cases, this option should be turned off before processing the last + * part of the text.

    + * + *

    When the UBIDI_OPTION_STREAMING option is used, + * it is recommended to call ubidi_orderParagraphsLTR() with + * argument orderParagraphsLTR set to TRUE before + * calling ubidi_setPara so that later paragraphs may be + * concatenated to previous paragraphs on the right.

    + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @see ubidi_getProcessedLength + * @see ubidi_orderParagraphsLTR + * @stable ICU 3.6 + */ + UBIDI_OPTION_STREAMING = 4 +} UBiDiReorderingOption; + +/** + * Specify which of the reordering options + * should be applied during Bidi transformations. + * + * @param pBiDi is a UBiDi object. + * @param reorderingOptions is a combination of zero or more of the following + * options: + * #UBIDI_OPTION_DEFAULT, #UBIDI_OPTION_INSERT_MARKS, + * #UBIDI_OPTION_REMOVE_CONTROLS, #UBIDI_OPTION_STREAMING. + * + * @see ubidi_getReorderingOptions + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions); + +/** + * What are the reordering options applied to a given Bidi object? + * + * @param pBiDi is a UBiDi object. + * @return the current reordering options of the Bidi object + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ +U_STABLE uint32_t U_EXPORT2 +ubidi_getReorderingOptions(UBiDi *pBiDi); + +/** + * Set the context before a call to ubidi_setPara().

    + * + * ubidi_setPara() computes the left-right directionality for a given piece + * of text which is supplied as one of its arguments. Sometimes this piece + * of text (the "main text") should be considered in context, because text + * appearing before ("prologue") and/or after ("epilogue") the main text + * may affect the result of this computation.

    + * + * This function specifies the prologue and/or the epilogue for the next + * call to ubidi_setPara(). The characters specified as prologue and + * epilogue should not be modified by the calling program until the call + * to ubidi_setPara() has returned. If successive calls to ubidi_setPara() + * all need specification of a context, ubidi_setContext() must be called + * before each call to ubidi_setPara(). In other words, a context is not + * "remembered" after the following successful call to ubidi_setPara().

    + * + * If a call to ubidi_setPara() specifies UBIDI_DEFAULT_LTR or + * UBIDI_DEFAULT_RTL as paraLevel and is preceded by a call to + * ubidi_setContext() which specifies a prologue, the paragraph level will + * be computed taking in consideration the text in the prologue.

    + * + * When ubidi_setPara() is called without a previous call to + * ubidi_setContext, the main text is handled as if preceded and followed + * by strong directional characters at the current paragraph level. + * Calling ubidi_setContext() with specification of a prologue will change + * this behavior by handling the main text as if preceded by the last + * strong character appearing in the prologue, if any. + * Calling ubidi_setContext() with specification of an epilogue will change + * the behavior of ubidi_setPara() by handling the main text as if followed + * by the first strong character or digit appearing in the epilogue, if any.

    + * + * Note 1: if ubidi_setContext is called repeatedly without + * calling ubidi_setPara, the earlier calls have no effect, + * only the last call will be remembered for the next call to + * ubidi_setPara.

    + * + * Note 2: calling ubidi_setContext(pBiDi, NULL, 0, NULL, 0, &errorCode) + * cancels any previous setting of non-empty prologue or epilogue. + * The next call to ubidi_setPara() will process no + * prologue or epilogue.

    + * + * Note 3: users must be aware that even after setting the context + * before a call to ubidi_setPara() to perform e.g. a logical to visual + * transformation, the resulting string may not be identical to what it + * would have been if all the text, including prologue and epilogue, had + * been processed together.
    + * Example (upper case letters represent RTL characters):
    + *   prologue = "abc DE"
    + *   epilogue = none
    + *   main text = "FGH xyz"
    + *   paraLevel = UBIDI_LTR
    + *   display without prologue = "HGF xyz" + * ("HGF" is adjacent to "xyz")
    + *   display with prologue = "abc HGFED xyz" + * ("HGF" is not adjacent to "xyz")
    + * + * @param pBiDi is a paragraph UBiDi object. + * + * @param prologue is a pointer to the text which precedes the text that + * will be specified in a coming call to ubidi_setPara(). + * If there is no prologue to consider, then proLength + * must be zero and this pointer can be NULL. + * + * @param proLength is the length of the prologue; if proLength==-1 + * then the prologue must be zero-terminated. + * Otherwise proLength must be >= 0. If proLength==0, it means + * that there is no prologue to consider. + * + * @param epilogue is a pointer to the text which follows the text that + * will be specified in a coming call to ubidi_setPara(). + * If there is no epilogue to consider, then epiLength + * must be zero and this pointer can be NULL. + * + * @param epiLength is the length of the epilogue; if epiLength==-1 + * then the epilogue must be zero-terminated. + * Otherwise epiLength must be >= 0. If epiLength==0, it means + * that there is no epilogue to consider. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_setPara + * @stable ICU 4.8 + */ +U_STABLE void U_EXPORT2 +ubidi_setContext(UBiDi *pBiDi, + const UChar *prologue, int32_t proLength, + const UChar *epilogue, int32_t epiLength, + UErrorCode *pErrorCode); + +/** + * Perform the Unicode Bidi algorithm. It is defined in the * Unicode Standard Anned #9, * version 13, * also described in The Unicode Standard, Version 4.0 .

    * - * This function takes a single plain text paragraph with or without - * externally specified embedding levels from styled text - * and computes the left-right-directionality of each character.

    + * This function takes a piece of plain text containing one or more paragraphs, + * with or without externally specified embedding levels from styled + * text and computes the left-right-directionality of each character.

    * - * If the entire paragraph consists of text of only one direction, then + * If the entire text is all of the same directionality, then * the function may not perform all the steps described by the algorithm, * i.e., some levels may not be the same as if all steps were performed. * This is not relevant for unidirectional text.
    @@ -547,56 +1153,64 @@ ubidi_isInverse(UBiDi *pBiDi); * the algorithm. This implementation may set all resolved levels to * the same value in such a case.

    * - * The text must be externally split into separate paragraphs (rule P1). - * Paragraph separators (B) should appear at most at the very end. + * The text can be composed of multiple paragraphs. Occurrence of a block + * separator in the text terminates a paragraph, and whatever comes next starts + * a new paragraph. The exception to this rule is when a Carriage Return (CR) + * is followed by a Line Feed (LF). Both CR and LF are block separators, but + * in that case, the pair of characters is considered as terminating the + * preceding paragraph, and a new paragraph will be started by a character + * coming after the LF. * * @param pBiDi A UBiDi object allocated with ubidi_open() * which will be set to contain the reordering information, * especially the resolved levels for all the characters in text. * - * @param text is a pointer to the single-paragraph text that the - * BiDi algorithm will be performed on - * (step (P1) of the algorithm is performed externally). - * The text must be (at least) length long. + * @param text is a pointer to the text that the Bidi algorithm will be performed on. * This pointer is stored in the UBiDi object and can be retrieved - * with ubidi_getText(). + * with ubidi_getText().
    + * Note: the text must be (at least) length long. * * @param length is the length of the text; if length==-1 then * the text must be zero-terminated. * - * @param paraLevel specifies the default level for the paragraph; + * @param paraLevel specifies the default level for the text; * it is typically 0 (LTR) or 1 (RTL). * If the function shall determine the paragraph level from the text, * then paraLevel can be set to - * either UBIDI_DEFAULT_LTR - * or UBIDI_DEFAULT_RTL; - * if there is no strongly typed character, then - * the desired default is used (0 for LTR or 1 for RTL). - * Any other value between 0 and UBIDI_MAX_EXPLICIT_LEVEL is also valid, - * with odd levels indicating RTL. + * either #UBIDI_DEFAULT_LTR + * or #UBIDI_DEFAULT_RTL; if the text contains multiple + * paragraphs, the paragraph level shall be determined separately for + * each paragraph; if a paragraph does not include any strongly typed + * character, then the desired default is used (0 for LTR or 1 for RTL). + * Any other value between 0 and #UBIDI_MAX_EXPLICIT_LEVEL + * is also valid, with odd levels indicating RTL. * * @param embeddingLevels (in) may be used to preset the embedding and override levels, * ignoring characters like LRE and PDF in the text. * A level overrides the directional property of its corresponding * (same index) character if the level has the - * UBIDI_LEVEL_OVERRIDE bit set.

    + * #UBIDI_LEVEL_OVERRIDE bit set.

    * Except for that bit, it must be - * paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL.

    + * paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL, + * with one exception: a level of zero may be specified for a paragraph + * separator even if paraLevel>0 when multiple paragraphs + * are submitted in the same call to ubidi_setPara().

    * Caution: A copy of this pointer, not of the levels, * will be stored in the UBiDi object; * the embeddingLevels array must not be * deallocated before the UBiDi structure is destroyed or reused, * and the embeddingLevels - * should not be modified to avoid unexpected results on subsequent BiDi operations. + * should not be modified to avoid unexpected results on subsequent Bidi operations. * However, the ubidi_setPara() and - * ubidi_setLine() functions may modify some or all of the levels.

    + * ubidi_setLine() functions may modify some or all of the levels.

    * After the UBiDi object is reused or destroyed, the caller - * must take care of the deallocation of the embeddingLevels array.

    - * The embeddingLevels array must be - * at least length long. + * must take care of the deallocation of the embeddingLevels array.

    + * Note: the embeddingLevels array must be + * at least length long. + * This pointer can be NULL if this + * value is not necessary. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 @@ -609,13 +1223,13 @@ ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length, * contain the reordering information, especially the resolved levels, * for all the characters in a line of text. This line of text is * specified by referring to a UBiDi object representing - * this information for a paragraph of text, and by specifying - * a range of indexes in this paragraph.

    + * this information for a piece of text containing one or more paragraphs, + * and by specifying a range of indexes in this text.

    * In the new line object, the indexes will range from 0 to limit-start-1.

    * * This is used after calling ubidi_setPara() - * for a paragraph, and after line-breaking on that paragraph. - * It is not necessary if the paragraph is treated as a single line.

    + * for a piece of text, and after line-breaking on that text. + * It is not necessary if each paragraph is treated as a single line.

    * * After line-breaking, rules (L1) and (L2) for the treatment of * trailing WS and for reordering are performed on @@ -631,20 +1245,23 @@ ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length, * and start is added to it so that it points to the beginning of the * line for this object. * - * @param pParaBiDi is the parent paragraph object. + * @param pParaBiDi is the parent paragraph object. It must have been set + * by a successful call to ubidi_setPara. * - * @param start is the line's first index into the paragraph text. + * @param start is the line's first index into the text. * - * @param limit is just behind the line's last index into the paragraph text + * @param limit is just behind the line's last index into the text * (its last index +1).
    - * It must be 0<=start<=limit<=paragraph length. + * It must be 0<=startcontaining paragraph limit. + * If the specified line crosses a paragraph boundary, the function + * will terminate with error code U_ILLEGAL_ARGUMENT_ERROR. * - * @param pLineBiDi is the object that will now represent a line of the paragraph. + * @param pLineBiDi is the object that will now represent a line of the text. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @see ubidi_setPara + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 @@ -658,9 +1275,12 @@ ubidi_setLine(const UBiDi *pParaBiDi, * * @param pBiDi is the paragraph or line UBiDi object. * - * @return A UBIDI_XXX value that indicates if the entire text + * @return a value of UBIDI_LTR, UBIDI_RTL + * or UBIDI_MIXED + * that indicates if the entire text * represented by this object is unidirectional, * and which direction, or if it is mixed-directional. + * Note - The value UBIDI_NEUTRAL is never returned from this method. * * @see UBiDiDirection * @stable ICU 2.0 @@ -668,6 +1288,36 @@ ubidi_setLine(const UBiDi *pParaBiDi, U_STABLE UBiDiDirection U_EXPORT2 ubidi_getDirection(const UBiDi *pBiDi); +/** + * Gets the base direction of the text provided according + * to the Unicode Bidirectional Algorithm. The base direction + * is derived from the first character in the string with bidirectional + * character type L, R, or AL. If the first such character has type L, + * UBIDI_LTR is returned. If the first such character has + * type R or AL, UBIDI_RTL is returned. If the string does + * not contain any character of these types, then + * UBIDI_NEUTRAL is returned. + * + * This is a lightweight function for use when only the base direction + * is needed and no further bidi processing of the text is needed. + * + * @param text is a pointer to the text whose base + * direction is needed. + * Note: the text must be (at least) @c length long. + * + * @param length is the length of the text; + * if length==-1 then the text + * must be zero-terminated. + * + * @return UBIDI_LTR, UBIDI_RTL, + * UBIDI_NEUTRAL + * + * @see UBiDiDirection + * @stable ICU 4.6 + */ +U_STABLE UBiDiDirection U_EXPORT2 +ubidi_getBaseDirection(const UChar *text, int32_t length ); + /** * Get the pointer to the text. * @@ -698,24 +1348,114 @@ ubidi_getLength(const UBiDi *pBiDi); * * @param pBiDi is the paragraph or line UBiDi object. * - * @return The paragraph level. + * @return The paragraph level. If there are multiple paragraphs, their + * level may vary if the required paraLevel is UBIDI_DEFAULT_LTR or + * UBIDI_DEFAULT_RTL. In that case, the level of the first paragraph + * is returned. * * @see UBiDiLevel + * @see ubidi_getParagraph + * @see ubidi_getParagraphByIndex * @stable ICU 2.0 */ U_STABLE UBiDiLevel U_EXPORT2 ubidi_getParaLevel(const UBiDi *pBiDi); +/** + * Get the number of paragraphs. + * + * @param pBiDi is the paragraph or line UBiDi object. + * + * @return The number of paragraphs. + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_countParagraphs(UBiDi *pBiDi); + +/** + * Get a paragraph, given a position within the text. + * This function returns information about a paragraph.
    + * Note: if the paragraph index is known, it is more efficient to + * retrieve the paragraph information using ubidi_getParagraphByIndex().

    + * + * @param pBiDi is the paragraph or line UBiDi object. + * + * @param charIndex is the index of a character within the text, in the + * range [0..ubidi_getProcessedLength(pBiDi)-1]. + * + * @param pParaStart will receive the index of the first character of the + * paragraph in the text. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pParaLimit will receive the limit of the paragraph. + * The l-value that you point to here may be the + * same expression (variable) as the one for + * charIndex. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pParaLevel will receive the level of the paragraph. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The index of the paragraph containing the specified position. + * + * @see ubidi_getProcessedLength + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex, int32_t *pParaStart, + int32_t *pParaLimit, UBiDiLevel *pParaLevel, + UErrorCode *pErrorCode); + +/** + * Get a paragraph, given the index of this paragraph. + * + * This function returns information about a paragraph.

    + * + * @param pBiDi is the paragraph UBiDi object. + * + * @param paraIndex is the number of the paragraph, in the + * range [0..ubidi_countParagraphs(pBiDi)-1]. + * + * @param pParaStart will receive the index of the first character of the + * paragraph in the text. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pParaLimit will receive the limit of the paragraph. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pParaLevel will receive the level of the paragraph. + * This pointer can be NULL if this + * value is not necessary. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex, + int32_t *pParaStart, int32_t *pParaLimit, + UBiDiLevel *pParaLevel, UErrorCode *pErrorCode); + /** * Get the level for one character. * * @param pBiDi is the paragraph or line UBiDi object. * - * @param charIndex the index of a character. + * @param charIndex the index of a character. It must be in the range + * [0..ubidi_getProcessedLength(pBiDi)]. * - * @return The level for the character at charIndex. + * @return The level for the character at charIndex (0 if charIndex is not + * in the valid range). * * @see UBiDiLevel + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE UBiDiLevel U_EXPORT2 @@ -727,15 +1467,16 @@ ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex); * Note that this function may allocate memory under some * circumstances, unlike ubidi_getLevelAt(). * - * @param pBiDi is the paragraph or line UBiDi object. + * @param pBiDi is the paragraph or line UBiDi object, whose + * text length must be strictly positive. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The levels array for the text, * or NULL if an error occurs. * * @see UBiDiLevel + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE const UBiDiLevel * U_EXPORT2 @@ -749,22 +1490,24 @@ ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode); * * @param pBiDi is the paragraph or line UBiDi object. * - * @param logicalStart is the first character of the run. + * @param logicalPosition is a logical position within the source text. * - * @param pLogicalLimit will receive the limit of the run. + * @param pLogicalLimit will receive the limit of the corresponding run. * The l-value that you point to here may be the * same expression (variable) as the one for - * logicalStart. + * logicalPosition. * This pointer can be NULL if this * value is not necessary. * - * @param pLevel will receive the level of the run. + * @param pLevel will receive the level of the corresponding run. * This pointer can be NULL if this * value is not necessary. + * + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 -ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalStart, +ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalPosition, int32_t *pLogicalLimit, UBiDiLevel *pLevel); /** @@ -777,8 +1520,7 @@ ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalStart, * * @param pBiDi is the paragraph or line UBiDi object. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The number of runs. * @stable ICU 2.0 @@ -808,7 +1550,8 @@ ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode); * * @return the directionality of the run, * UBIDI_LTR==0 or UBIDI_RTL==1, - * never UBIDI_MIXED. + * never UBIDI_MIXED, + * never UBIDI_NEUTRAL. * * @see ubidi_countRuns * @@ -833,8 +1576,12 @@ ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode); * * * Note that in right-to-left runs, code like this places - * modifier letters before base characters and second surrogates - * before first ones. + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + *

    + * Use of ubidi_writeReordered(), optionally with the + * #UBIDI_KEEP_BASE_COMBINING option, can be considered in order + * to avoid these issues. * @stable ICU 2.0 */ U_STABLE UBiDiDirection U_EXPORT2 @@ -847,21 +1594,35 @@ ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex, * UBiDi object, then calling * ubidi_getLogicalMap() is more efficient.

    * + * The value returned may be #UBIDI_MAP_NOWHERE if there is no + * visual position because the corresponding text character is a Bidi control + * removed from output by the option #UBIDI_OPTION_REMOVE_CONTROLS. + *

    + * When the visual output is altered by using options of + * ubidi_writeReordered() such as UBIDI_INSERT_LRM_FOR_NUMERIC, + * UBIDI_KEEP_BASE_COMBINING, UBIDI_OUTPUT_REVERSE, + * UBIDI_REMOVE_BIDI_CONTROLS, the visual position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as UBIDI_OPTION_INSERT_MARKS and UBIDI_OPTION_REMOVE_CONTROLS. + *

    * Note that in right-to-left runs, this mapping places - * modifier letters before base characters and second surrogates - * before first ones. + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of ubidi_writeReordered(), optionally with the + * #UBIDI_KEEP_BASE_COMBINING option can be considered instead + * of using the mapping, in order to avoid these issues. * * @param pBiDi is the paragraph or line UBiDi object. * * @param logicalIndex is the index of a character in the text. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The visual position of this character. * * @see ubidi_getLogicalMap * @see ubidi_getLogicalIndex + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE int32_t U_EXPORT2 @@ -873,19 +1634,30 @@ ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) * UBiDi object, then calling * ubidi_getVisualMap() is more efficient.

    * + * The value returned may be #UBIDI_MAP_NOWHERE if there is no + * logical position because the corresponding text character is a Bidi mark + * inserted in the output by option #UBIDI_OPTION_INSERT_MARKS. + *

    * This is the inverse function to ubidi_getVisualIndex(). + *

    + * When the visual output is altered by using options of + * ubidi_writeReordered() such as UBIDI_INSERT_LRM_FOR_NUMERIC, + * UBIDI_KEEP_BASE_COMBINING, UBIDI_OUTPUT_REVERSE, + * UBIDI_REMOVE_BIDI_CONTROLS, the logical position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as UBIDI_OPTION_INSERT_MARKS and UBIDI_OPTION_REMOVE_CONTROLS. * * @param pBiDi is the paragraph or line UBiDi object. * * @param visualIndex is the visual position of a character. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The index of this character in the text. * * @see ubidi_getVisualMap * @see ubidi_getVisualIndex + * @see ubidi_getResultLength * @stable ICU 2.0 */ U_STABLE int32_t U_EXPORT2 @@ -894,19 +1666,41 @@ ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode) /** * Get a logical-to-visual index map (array) for the characters in the UBiDi * (paragraph or line) object. + *

    + * Some values in the map may be #UBIDI_MAP_NOWHERE if the + * corresponding text characters are Bidi controls removed from the visual + * output by the option #UBIDI_OPTION_REMOVE_CONTROLS. + *

    + * When the visual output is altered by using options of + * ubidi_writeReordered() such as UBIDI_INSERT_LRM_FOR_NUMERIC, + * UBIDI_KEEP_BASE_COMBINING, UBIDI_OUTPUT_REVERSE, + * UBIDI_REMOVE_BIDI_CONTROLS, the visual positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as UBIDI_OPTION_INSERT_MARKS and UBIDI_OPTION_REMOVE_CONTROLS. + *

    + * Note that in right-to-left runs, this mapping places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of ubidi_writeReordered(), optionally with the + * #UBIDI_KEEP_BASE_COMBINING option can be considered instead + * of using the mapping, in order to avoid these issues. * * @param pBiDi is the paragraph or line UBiDi object. * - * @param indexMap is a pointer to an array of ubidi_getLength() + * @param indexMap is a pointer to an array of ubidi_getProcessedLength() * indexes which will reflect the reordering of the characters. - * The array does not need to be initialized.

    - * The index map will result in indexMap[logicalIndex]==visualIndex.

    + * If option #UBIDI_OPTION_INSERT_MARKS is set, the number + * of elements allocated in indexMap must be no less than + * ubidi_getResultLength(). + * The array does not need to be initialized.

    + * The index map will result in indexMap[logicalIndex]==visualIndex. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @see ubidi_getVisualMap * @see ubidi_getVisualIndex + * @see ubidi_getProcessedLength + * @see ubidi_getResultLength * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 @@ -915,19 +1709,34 @@ ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode); /** * Get a visual-to-logical index map (array) for the characters in the UBiDi * (paragraph or line) object. + *

    + * Some values in the map may be #UBIDI_MAP_NOWHERE if the + * corresponding text characters are Bidi marks inserted in the visual output + * by the option #UBIDI_OPTION_INSERT_MARKS. + *

    + * When the visual output is altered by using options of + * ubidi_writeReordered() such as UBIDI_INSERT_LRM_FOR_NUMERIC, + * UBIDI_KEEP_BASE_COMBINING, UBIDI_OUTPUT_REVERSE, + * UBIDI_REMOVE_BIDI_CONTROLS, the logical positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as UBIDI_OPTION_INSERT_MARKS and UBIDI_OPTION_REMOVE_CONTROLS. * * @param pBiDi is the paragraph or line UBiDi object. * - * @param indexMap is a pointer to an array of ubidi_getLength() + * @param indexMap is a pointer to an array of ubidi_getResultLength() * indexes which will reflect the reordering of the characters. - * The array does not need to be initialized.

    - * The index map will result in indexMap[visualIndex]==logicalIndex.

    + * If option #UBIDI_OPTION_REMOVE_CONTROLS is set, the number + * of elements allocated in indexMap must be no less than + * ubidi_getProcessedLength(). + * The array does not need to be initialized.

    + * The index map will result in indexMap[visualIndex]==logicalIndex. * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @see ubidi_getLogicalMap * @see ubidi_getLogicalIndex + * @see ubidi_getProcessedLength + * @see ubidi_getResultLength * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 @@ -937,7 +1746,7 @@ ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode); * This is a convenience function that does not use a UBiDi object. * It is intended to be used for when an application has determined the levels * of objects (character sequences) and just needs to have them reordered (L2). - * This is equivalent to using ubidi_getLogicalMap on a + * This is equivalent to using ubidi_getLogicalMap() on a * UBiDi object. * * @param levels is an array with length levels that have been determined by @@ -960,7 +1769,7 @@ ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap * This is a convenience function that does not use a UBiDi object. * It is intended to be used for when an application has determined the levels * of objects (character sequences) and just needs to have them reordered (L2). - * This is equivalent to using ubidi_getVisualMap on a + * This is equivalent to using ubidi_getVisualMap() on a * UBiDi object. * * @param levels is an array with length levels that have been determined by @@ -981,16 +1790,34 @@ ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) /** * Invert an index map. - * The one-to-one index mapping of the first map is inverted and written to + * The index mapping of the first map is inverted and written to * the second one. * - * @param srcMap is an array with length indexes - * which define the original mapping. - * - * @param destMap is an array with length indexes - * which will be filled with the inverse mapping. + * @param srcMap is an array with length elements + * which defines the original mapping from a source array containing + * length elements to a destination array. + * Some elements of the source array may have no mapping in the + * destination array. In that case, their value will be + * the special value UBIDI_MAP_NOWHERE. + * All elements must be >=0 or equal to UBIDI_MAP_NOWHERE. + * Some elements may have a value >= length, if the + * destination array has more elements than the source array. + * There must be no duplicate indexes (two or more elements with the + * same value except UBIDI_MAP_NOWHERE). + * + * @param destMap is an array with a number of elements equal to 1 + the highest + * value in srcMap. + * destMap will be filled with the inverse mapping. + * If element with index i in srcMap has a value k different + * from UBIDI_MAP_NOWHERE, this means that element i of + * the source array maps to element k in the destination array. + * The inverse map will have value i in its k-th element. + * For all elements of the destination array which do not map to + * an element in the source array, the corresponding element in the + * inverse map will have a value equal to UBIDI_MAP_NOWHERE. * * @param length is the length of each array. + * @see UBIDI_MAP_NOWHERE * @stable ICU 2.0 */ U_STABLE void U_EXPORT2 @@ -1020,7 +1847,10 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); /** * option bit for ubidi_writeReordered(): * surround the run with LRMs if necessary; - * this is part of the approximate "inverse BiDi" algorithm + * this is part of the approximate "inverse Bidi" algorithm + * + *

    This option does not imply corresponding adjustment of the index + * mappings.

    * * @see ubidi_setInverse * @see ubidi_writeReordered @@ -1030,8 +1860,11 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); /** * option bit for ubidi_writeReordered(): - * remove BiDi control characters - * (this does not affect UBIDI_INSERT_LRM_FOR_NUMERIC) + * remove Bidi control characters + * (this does not affect #UBIDI_INSERT_LRM_FOR_NUMERIC) + * + *

    This option does not imply corresponding adjustment of the index + * mappings.

    * * @see ubidi_writeReordered * @stable ICU 2.0 @@ -1054,37 +1887,202 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); */ #define UBIDI_OUTPUT_REVERSE 16 +/** + * Get the length of the source text processed by the last call to + * ubidi_setPara(). This length may be different from the length + * of the source text if option #UBIDI_OPTION_STREAMING + * has been set. + *
    + * Note that whenever the length of the text affects the execution or the + * result of a function, it is the processed length which must be considered, + * except for ubidi_setPara (which receives unprocessed source + * text) and ubidi_getLength (which returns the original length + * of the source text).
    + * In particular, the processed length is the one to consider in the following + * cases: + * + * + * @param pBiDi is the paragraph UBiDi object. + * + * @return The length of the part of the source text processed by + * the last call to ubidi_setPara. + * @see ubidi_setPara + * @see UBIDI_OPTION_STREAMING + * @stable ICU 3.6 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getProcessedLength(const UBiDi *pBiDi); + +/** + * Get the length of the reordered text resulting from the last call to + * ubidi_setPara(). This length may be different from the length + * of the source text if option #UBIDI_OPTION_INSERT_MARKS + * or option #UBIDI_OPTION_REMOVE_CONTROLS has been set. + *
    + * This resulting length is the one to consider in the following cases: + * + * Note that this length stays identical to the source text length if + * Bidi marks are inserted or removed using option bits of + * ubidi_writeReordered, or if option + * #UBIDI_REORDER_INVERSE_NUMBERS_AS_L has been set. + * + * @param pBiDi is the paragraph UBiDi object. + * + * @return The length of the reordered text resulting from + * the last call to ubidi_setPara. + * @see ubidi_setPara + * @see UBIDI_OPTION_INSERT_MARKS + * @see UBIDI_OPTION_REMOVE_CONTROLS + * @stable ICU 3.6 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getResultLength(const UBiDi *pBiDi); + +U_CDECL_BEGIN +/** + * value returned by UBiDiClassCallback callbacks when + * there is no need to override the standard Bidi class for a given code point. + * @see UBiDiClassCallback + * @stable ICU 3.6 + */ +#define U_BIDI_CLASS_DEFAULT U_CHAR_DIRECTION_COUNT + +/** + * Callback type declaration for overriding default Bidi class values with + * custom ones. + *

    Usually, the function pointer will be propagated to a UBiDi + * object by calling the ubidi_setClassCallback() function; + * then the callback will be invoked by the UBA implementation any time the + * class of a character is to be determined.

    + * + * @param context is a pointer to the callback private data. + * + * @param c is the code point to get a Bidi class for. + * + * @return The directional property / Bidi class for the given code point + * c if the default class has been overridden, or + * #U_BIDI_CLASS_DEFAULT if the standard Bidi class value + * for c is to be used. + * @see ubidi_setClassCallback + * @see ubidi_getClassCallback + * @stable ICU 3.6 + */ +typedef UCharDirection U_CALLCONV +UBiDiClassCallback(const void *context, UChar32 c); + +U_CDECL_END + +/** + * Retrieve the Bidi class for a given code point. + *

    If a #UBiDiClassCallback callback is defined and returns a + * value other than #U_BIDI_CLASS_DEFAULT, that value is used; + * otherwise the default class determination mechanism is invoked.

    + * + * @param pBiDi is the paragraph UBiDi object. + * + * @param c is the code point whose Bidi class must be retrieved. + * + * @return The Bidi class for character c based + * on the given pBiDi instance. + * @see UBiDiClassCallback + * @stable ICU 3.6 + */ +U_STABLE UCharDirection U_EXPORT2 +ubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c); + +/** + * Set the callback function and callback data used by the UBA + * implementation for Bidi class determination. + *

    This may be useful for assigning Bidi classes to PUA characters, or + * for special application needs. For instance, an application may want to + * handle all spaces like L or R characters (according to the base direction) + * when creating the visual ordering of logical lines which are part of a report + * organized in columns: there should not be interaction between adjacent + * cells.

    + * + * @param pBiDi is the paragraph UBiDi object. + * + * @param newFn is the new callback function pointer. + * + * @param newContext is the new callback context pointer. This can be NULL. + * + * @param oldFn fillin: Returns the old callback function pointer. This can be + * NULL. + * + * @param oldContext fillin: Returns the old callback's context. This can be + * NULL. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_getClassCallback + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn, + const void *newContext, UBiDiClassCallback **oldFn, + const void **oldContext, UErrorCode *pErrorCode); + +/** + * Get the current callback function used for Bidi class determination. + * + * @param pBiDi is the paragraph UBiDi object. + * + * @param fn fillin: Returns the callback function pointer. + * + * @param context fillin: Returns the callback's private context. + * + * @see ubidi_setClassCallback + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context); + /** * Take a UBiDi object containing the reordering - * information for one paragraph or line of text as set by - * ubidi_setPara() or ubidi_setLine() and - * write a reordered string to the destination buffer. + * information for a piece of text (one or more paragraphs) set by + * ubidi_setPara() or for a line of text set by + * ubidi_setLine() and write a reordered string to the + * destination buffer. * * This function preserves the integrity of characters with multiple - * code units and (optionally) modifier letters. + * code units and (optionally) combining characters. * Characters in RTL runs can be replaced by mirror-image characters * in the destination buffer. Note that "real" mirroring has * to be done in a rendering engine by glyph selection * and that for many "mirrored" characters there are no * Unicode characters as mirror-image equivalents. - * There are also options to insert or remove BiDi control + * There are also options to insert or remove Bidi control * characters; see the description of the destSize * and options parameters and of the option bit flags. * - * @see UBIDI_DO_MIRRORING - * @see UBIDI_INSERT_LRM_FOR_NUMERIC - * @see UBIDI_KEEP_BASE_COMBINING - * @see UBIDI_OUTPUT_REVERSE - * @see UBIDI_REMOVE_BIDI_CONTROLS - * * @param pBiDi A pointer to a UBiDi object that * is set by ubidi_setPara() or * ubidi_setLine() and contains the reordering * information for the text that it was defined for, - * as well as a pointer to that text. - *

    The text was aliased (only the pointer was stored + * as well as a pointer to that text.

    + * The text was aliased (only the pointer was stored * without copying the contents) and must not have been modified - * since the ubidi_setPara() call.

    + * since the ubidi_setPara() call. * * @param dest A pointer to where the reordered text is to be copied. * The source text and dest[destSize] @@ -1100,7 +2098,7 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); * is set, then the destination length may be less than * ubidi_getLength(pBiDi). * If none of these options is set, then the destination length - * will be exactly ubidi_getLength(pBiDi). + * will be exactly ubidi_getProcessedLength(pBiDi). * * @param options A bit set of options for the reordering that control * how the reordered text is written. @@ -1108,8 +2106,8 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); * point basis and inserting LRM characters, which is used * especially for transforming visually stored text * to logically stored text (although this is still an - * imperfect implementation of an "inverse BiDi" algorithm - * because it uses the "forward BiDi" algorithm at its core). + * imperfect implementation of an "inverse Bidi" algorithm + * because it uses the "forward Bidi" algorithm at its core). * The available options are: * #UBIDI_DO_MIRRORING, * #UBIDI_INSERT_LRM_FOR_NUMERIC, @@ -1117,10 +2115,11 @@ ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); * #UBIDI_OUTPUT_REVERSE, * #UBIDI_REMOVE_BIDI_CONTROLS * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The length of the output string. + * + * @see ubidi_getProcessedLength * @stable ICU 2.0 */ U_STABLE int32_t U_EXPORT2 @@ -1133,19 +2132,19 @@ ubidi_writeReordered(UBiDi *pBiDi, * Reverse a Right-To-Left run of Unicode text. * * This function preserves the integrity of characters with multiple - * code units and (optionally) modifier letters. + * code units and (optionally) combining characters. * Characters can be replaced by mirror-image characters * in the destination buffer. Note that "real" mirroring has * to be done in a rendering engine by glyph selection * and that for many "mirrored" characters there are no * Unicode characters as mirror-image equivalents. - * There are also options to insert or remove BiDi control + * There are also options to insert or remove Bidi control * characters. * * This function is the implementation for reversing RTL runs as part * of ubidi_writeReordered(). For detailed descriptions * of the parameters, see there. - * Since no BiDi controls are inserted here, the output string length + * Since no Bidi controls are inserted here, the output string length * will never exceed srcLength. * * @see ubidi_writeReordered @@ -1170,8 +2169,7 @@ ubidi_writeReordered(UBiDi *pBiDi, * how the reordered text is written. * See the options parameter in ubidi_writeReordered(). * - * @param pErrorCode must be a valid pointer to an error code value, - * which must not indicate a failure before the function call. + * @param pErrorCode must be a valid pointer to an error code value. * * @return The length of the output string. * @stable ICU 2.0