From e724c8e6ff1c4ef8d9f4ed6556c0749e326c4a3d Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 21 Oct 2024 10:32:41 +0000 Subject: [PATCH] Bug 1925854 - Make gfxScriptItemizer support both 16-bit and 8-bit text buffers. r=gfx-reviewers,lsalzman This does not change behavior yet, just prepares for the next patch which will actually use the 8-bit version. Differential Revision: https://phabricator.services.mozilla.com/D226286 --- gfx/thebes/gfxScriptItemizer.cpp | 7 +++++-- gfx/thebes/gfxScriptItemizer.h | 25 +++++++++++++++++++++---- gfx/thebes/gfxTextRun.cpp | 3 ++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gfx/thebes/gfxScriptItemizer.cpp b/gfx/thebes/gfxScriptItemizer.cpp index ce64692d40c9..3c6abdc6701c 100644 --- a/gfx/thebes/gfxScriptItemizer.cpp +++ b/gfx/thebes/gfxScriptItemizer.cpp @@ -122,6 +122,9 @@ static inline bool SameScript(Script runScript, Script currCharScript, } gfxScriptItemizer::Run gfxScriptItemizer::Next() { + MOZ_ASSERT(textLength == 0 || (textIs8bit && textPtr._1b) || + (!textIs8bit && textPtr._2b)); + /* if we've fallen off the end of the text, we're done */ if (scriptLimit >= textLength) { return Run{}; @@ -136,11 +139,11 @@ gfxScriptItemizer::Run gfxScriptItemizer::Next() { Script sc; uint32_t startOfChar = scriptLimit; - ch = textPtr[scriptLimit]; + ch = textIs8bit ? textPtr._1b[scriptLimit] : textPtr._2b[scriptLimit]; /* decode UTF-16 (may be surrogate pair) */ if (NS_IS_HIGH_SURROGATE(ch) && scriptLimit < textLength - 1) { - uint32_t low = textPtr[scriptLimit + 1]; + uint32_t low = textPtr._2b[scriptLimit + 1]; if (NS_IS_LOW_SURROGATE(low)) { ch = SURROGATE_TO_UCS4(ch, low); scriptLimit += 1; diff --git a/gfx/thebes/gfxScriptItemizer.h b/gfx/thebes/gfxScriptItemizer.h index 7417b0bf1981..1518655c0c26 100644 --- a/gfx/thebes/gfxScriptItemizer.h +++ b/gfx/thebes/gfxScriptItemizer.h @@ -60,8 +60,21 @@ class gfxScriptItemizer { public: using Script = mozilla::intl::Script; - gfxScriptItemizer(const char16_t* aText, uint32_t aLength) - : textPtr(aText), textLength(aLength) {} + gfxScriptItemizer() = default; + gfxScriptItemizer(const gfxScriptItemizer& aOther) = delete; + gfxScriptItemizer(gfxScriptItemizer&& aOther) = delete; + + void SetText(const char16_t* aText, uint32_t aLength) { + textPtr._2b = aText; + textLength = aLength; + textIs8bit = false; + } + + void SetText(const unsigned char* aText, uint32_t aLength) { + textPtr._1b = aText; + textLength = aLength; + textIs8bit = true; + } struct Run { uint32_t mOffset = 0; @@ -83,8 +96,12 @@ class gfxScriptItemizer { Script scriptCode; }; - const char16_t* const textPtr; - const uint32_t textLength; + union { + const char16_t* _2b; + const unsigned char* _1b; + } textPtr; + uint32_t textLength; + bool textIs8bit; uint32_t scriptStart = 0; uint32_t scriptLimit = 0; diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index d772145bdccd..b263d3e84418 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -2642,7 +2642,8 @@ void gfxFontGroup::InitTextRun(DrawTarget* aDrawTarget, gfxTextRun* aTextRun, // split into script runs so that script can potentially influence // the font matching process below - gfxScriptItemizer scriptRuns(textPtr, aLength); + gfxScriptItemizer scriptRuns; + scriptRuns.SetText(textPtr, aLength); while (gfxScriptItemizer::Run run = scriptRuns.Next()) { if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Warning))) {