summaryrefslogtreecommitdiffstats
path: root/intl/components/src/BidiEmbeddingLevel.h
diff options
context:
space:
mode:
Diffstat (limited to 'intl/components/src/BidiEmbeddingLevel.h')
-rw-r--r--intl/components/src/BidiEmbeddingLevel.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/intl/components/src/BidiEmbeddingLevel.h b/intl/components/src/BidiEmbeddingLevel.h
new file mode 100644
index 0000000000..1628b6392f
--- /dev/null
+++ b/intl/components/src/BidiEmbeddingLevel.h
@@ -0,0 +1,113 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef intl_components_BidiEmbeddingLevel_h_
+#define intl_components_BidiEmbeddingLevel_h_
+
+#include <cstdint>
+
+/**
+ * This file has the BidiEmbeddingLevel and BidiDirection enum broken out from
+ * the main Bidi class for faster includes. This code is used in Layout which
+ * could trigger long build times when changing core mozilla::intl files.
+ */
+namespace mozilla::intl {
+
+/**
+ * This enum unambiguously classifies text runs as either being left to right,
+ * or right to left.
+ */
+enum class BidiDirection : uint8_t {
+ // Left to right text.
+ LTR = 0,
+ // Right to left text.
+ RTL = 1,
+};
+
+/**
+ * Embedding levels are numbers that indicate how deeply the bidi text is
+ * embedded, and the direction of text on that embedding level. When switching
+ * between strongly LTR code points and strongly RTL code points the embedding
+ * level normally switches between an embedding level of 0 (LTR) and 1 (RTL).
+ * The only time the embedding level increases is if the embedding code points
+ * are used. This is the Left-to-Right Embedding (LRE) code point (U+202A), or
+ * the Right-to-Left Embedding (RLE) code point (U+202B). The minimum
+ * embedding level of text is zero, and the maximum explicit depth is 125.
+ *
+ * The most significant bit is reserved for additional meaning. It can be used
+ * to signify in certain APIs that the text should by default be LTR or RTL if
+ * no strongly directional code points are found.
+ *
+ * Bug 1736595: At the time of this writing, some places in Gecko code use a 1
+ * in the most significant bit to indicate that an embedding level has not
+ * been set. This leads to an ambiguous understanding of what the most
+ * significant bit actually means.
+ */
+class BidiEmbeddingLevel {
+ public:
+ explicit BidiEmbeddingLevel(uint8_t aValue) : mValue(aValue) {}
+ explicit BidiEmbeddingLevel(int aValue)
+ : mValue(static_cast<uint8_t>(aValue)) {}
+
+ BidiEmbeddingLevel() = default;
+
+ // Enable the copy operators, but disable move as this is only a uint8_t.
+ BidiEmbeddingLevel(const BidiEmbeddingLevel& other) = default;
+ BidiEmbeddingLevel& operator=(const BidiEmbeddingLevel& other) = default;
+
+ /**
+ * Determine the direction of the embedding level by looking at the least
+ * significant bit. If it is 0, then it is LTR. If it is 1, then it is RTL.
+ */
+ BidiDirection Direction();
+
+ /**
+ * Create a left-to-right embedding level.
+ */
+ static BidiEmbeddingLevel LTR();
+
+ /**
+ * Create an right-to-left embedding level.
+ */
+ static BidiEmbeddingLevel RTL();
+
+ /**
+ * When passed into `SetParagraph`, the direction is determined by first
+ * strongly directional character, with the default set to left-to-right if
+ * none is found.
+ *
+ * This is encoded with the highest bit set to 1.
+ */
+ static BidiEmbeddingLevel DefaultLTR();
+
+ /**
+ * When passed into `SetParagraph`, the direction is determined by first
+ * strongly directional character, with the default set to right-to-left if
+ * none is found.
+ *
+ * * This is encoded with the highest and lowest bits set to 1.
+ */
+ static BidiEmbeddingLevel DefaultRTL();
+
+ bool IsDefaultLTR() const;
+ bool IsDefaultRTL() const;
+ bool IsLTR() const;
+ bool IsRTL() const;
+ bool IsSameDirection(BidiEmbeddingLevel aOther) const;
+
+ /**
+ * Get the underlying value as a uint8_t.
+ */
+ uint8_t Value() const;
+
+ /**
+ * Implicitly convert to the underlying value.
+ */
+ operator uint8_t() const { return mValue; }
+
+ private:
+ uint8_t mValue = 0;
+};
+
+} // namespace mozilla::intl
+#endif