示例#1
0
        /// <summary>
        /// Perform the Unicode Bidi algorithm.
        /// </summary>
        /// <param name="text">The text that the Bidi algorithm will be performed on</param>
        /// <param name="paraLevel">Specifies the default level for the text; it is typically 0 (LTR) or 1 (RTL)</param>
        /// <param name="embeddingLevels">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</param>
        /// <remarks>
        /// 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 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.
        ///
        /// For example, in pure LTR text with numbers the numbers would get a resolved level of 2 higher than the surrounding text according to the
        /// algorithm.This implementation may set all resolved levels to the same value in such a case.
        ///
        /// 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.
        /// </remarks>
        public void SetPara(string text, byte paraLevel, byte[] embeddingLevels)
        {
            if (_para != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(_para);
                _para = IntPtr.Zero;
            }

            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            // icu BiDi expects the para pointer to live for the life of the structure, so we have to stash it
            _para = Marshal.StringToHGlobalUni(text);
            NativeMethods.ubidi_setPara(_biDi, _para, text.Length, paraLevel, embeddingLevels, out var errorCode);
            ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi analysis failed! " + errorCode);
        }