BidiEmbeddingLevel.h (4227B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 #ifndef intl_components_BidiEmbeddingLevel_h_ 5 #define intl_components_BidiEmbeddingLevel_h_ 6 7 #include <cstdint> 8 9 /** 10 * This file has the BidiEmbeddingLevel and BidiDirection enum broken out from 11 * the main Bidi class for faster includes. This code is used in Layout which 12 * could trigger long build times when changing core mozilla::intl files. 13 */ 14 namespace mozilla::intl { 15 16 /** 17 * This enum unambiguously classifies text runs as either being left to right, 18 * or right to left. 19 */ 20 enum class BidiDirection : uint8_t { 21 // Left to right text. 22 LTR = 0, 23 // Right to left text. 24 RTL = 1, 25 }; 26 27 /** 28 * Embedding levels are numbers that indicate how deeply the bidi text is 29 * embedded, and the direction of text on that embedding level. When switching 30 * between strongly LTR code points and strongly RTL code points the embedding 31 * level normally switches between an embedding level of 0 (LTR) and 1 (RTL). 32 * The only time the embedding level increases is if the embedding code points 33 * are used. This is the Left-to-Right Embedding (LRE) code point (U+202A), or 34 * the Right-to-Left Embedding (RLE) code point (U+202B). The minimum 35 * embedding level of text is zero, and the maximum explicit depth is 125. 36 * 37 * The most significant bit is reserved for additional meaning. It can be used 38 * to signify in certain APIs that the text should by default be LTR or RTL if 39 * no strongly directional code points are found. 40 * 41 * Bug 1736595: At the time of this writing, some places in Gecko code use a 1 42 * in the most significant bit to indicate that an embedding level has not 43 * been set. This leads to an ambiguous understanding of what the most 44 * significant bit actually means. 45 */ 46 class BidiEmbeddingLevel { 47 public: 48 constexpr explicit BidiEmbeddingLevel(uint8_t aValue) : mValue(aValue) {} 49 constexpr explicit BidiEmbeddingLevel(int aValue) 50 : mValue(static_cast<uint8_t>(aValue)) {} 51 52 BidiEmbeddingLevel() = default; 53 54 // Enable the copy operators, but disable move as this is only a uint8_t. 55 BidiEmbeddingLevel(const BidiEmbeddingLevel& other) = default; 56 BidiEmbeddingLevel& operator=(const BidiEmbeddingLevel& other) = default; 57 58 /** 59 * Determine the direction of the embedding level by looking at the least 60 * significant bit. If it is 0, then it is LTR. If it is 1, then it is RTL. 61 */ 62 BidiDirection Direction(); 63 64 /** 65 * Create a left-to-right embedding level. 66 */ 67 static BidiEmbeddingLevel LTR(); 68 69 /** 70 * Create an right-to-left embedding level. 71 */ 72 static BidiEmbeddingLevel RTL(); 73 74 /** 75 * When passed into `SetParagraph`, the direction is determined by first 76 * strongly directional character, with the default set to left-to-right if 77 * none is found. 78 * 79 * This is encoded with the highest bit set to 1. 80 */ 81 static BidiEmbeddingLevel DefaultLTR(); 82 83 /** 84 * When passed into `SetParagraph`, the direction is determined by first 85 * strongly directional character, with the default set to right-to-left if 86 * none is found. 87 * 88 * * This is encoded with the highest and lowest bits set to 1. 89 */ 90 static BidiEmbeddingLevel DefaultRTL(); 91 92 bool IsDefaultLTR() const; 93 bool IsDefaultRTL() const; 94 bool IsLTR() const; 95 bool IsRTL() const; 96 bool IsSameDirection(BidiEmbeddingLevel aOther) const; 97 98 /** 99 * Get the underlying value as a uint8_t. 100 */ 101 uint8_t Value() const; 102 103 /** 104 * Implicitly convert to the underlying value. 105 */ 106 operator uint8_t() const { return mValue; } 107 108 private: 109 uint8_t mValue = 0; 110 111 /** 112 * Constants indicating that the base direction depends on the first strong 113 * directional character in the text according to the Unicode Bidirectional 114 * Algorithm. 115 * If no strong directional character is present, then set the paragraph level 116 * to 0 (LTR) or 1 (RTL) respectively. 117 * (Compatible with ICU4C's UBIDI_DEFAULT_LTR / UBIDI_DEFAULT_RTL.) 118 */ 119 static constexpr uint8_t kDefaultLTR = 0xfe; 120 static constexpr uint8_t kDefaultRTL = 0xff; 121 }; 122 123 } // namespace mozilla::intl 124 #endif