// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifdef UNSAFE_BUFFERS_BUILD // TODO(crbug.com/351564777): Remove this and convert code to safer constructs. #pragma allow_unsafe_buffers #endif #include "third_party/blink/renderer/platform/fonts/script_run_iterator.h" #include <algorithm> #include "base/containers/contains.h" #include "base/logging.h" #include "base/notreached.h" #include "base/ranges/algorithm.h" #include "third_party/blink/renderer/platform/text/icu_error.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { namespace { // UScriptCode and OpenType script are not 1:1; specifically, both Hiragana and // Katakana map to 'kana' in OpenType. They will be mapped correctly in // HarfBuzz, but normalizing earlier helps to reduce splitting runs between // these scripts. // https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags inline UScriptCode GetScriptForOpenType(UChar32 ch, UErrorCode* status) { … } inline bool IsHanScript(UScriptCode script) { … } inline UScriptCode FirstHanScript( const ScriptRunIterator::UScriptCodeList& list) { … } ScriptRunIterator::UScriptCodeList GetHanScriptExtensions() { … } // This function updates the script list to the Han ideographic-based scripts if // the East Asian Width property[1] indicates it is an East Asian character. // // Most East Asian punctuation characters have East Asian scripts in the script // extensions. However, not all of them are so. For example, when they are // halfwidth/fullwidth forms, they must have the same properties as their // canonical equivalent[2] code points that are not East Asian. Such code points // can split runs in the middle of consecutive CJK punctuation characters when // they are preceded by non-CJK characters, and prevent applying font features // to consecutive CJK punctuation characters. // // TODO(crbug.com/1273998): This function is not needed if Unicode changes the // script extension for these code points. // // [1]: https://www.unicode.org/reports/tr11/ // [2]: https://unicode.org/reports/tr15/#Canon_Compat_Equivalence void FixScriptsByEastAsianWidth(UChar32 ch, ScriptRunIterator::UScriptCodeList* set) { … } } // namespace PairedBracketType; constexpr int ScriptRunIterator::kMaxScriptCount; constexpr int ScriptData::kMaxScriptCount; ScriptData::~ScriptData() = default; void ICUScriptData::GetScripts(UChar32 ch, UScriptCodeList& dst) const { … } UChar32 ICUScriptData::GetPairedBracket(UChar32 ch) const { … } PairedBracketType ICUScriptData::GetPairedBracketType(UChar32 ch) const { … } const ICUScriptData* ICUScriptData::Instance() { … } ScriptRunIterator::ScriptRunIterator(const UChar* text, wtf_size_t length, const ScriptData* data) : … { … } ScriptRunIterator::ScriptRunIterator(const UChar* text, wtf_size_t length) : … { … } bool ScriptRunIterator::Consume(unsigned* limit, UScriptCode* script) { … } void ScriptRunIterator::OpenBracket(UChar32 ch) { … } void ScriptRunIterator::CloseBracket(UChar32 ch) { … } // Keep items in current_set_ that are in next_set_. // // If the sets are disjoint, return false and leave current_set_ unchanged. Else // return true and make current set the intersection. Make sure to maintain // current priority script as priority if it remains, else retain next priority // script if it remains. // // Also maintain a common preferred script. If current and next are both // common, and there is no common preferred script and next has a preferred // script, set the common preferred script to that of next. bool ScriptRunIterator::MergeSets() { … } // When we hit the end of the run, and resolve the script, we now know the // resolved script of any open bracket that was pushed on the stack since // the start of the run. Fixup depth records how many of these there // were. We've maintained this count during pushes, and taken care to // adjust it if the stack got overfull and open brackets were pushed off // the bottom. This sets the script of the fixup_depth topmost entries of the // stack to the resolved script. void ScriptRunIterator::FixupStack(UScriptCode resolved_script, bool exclude_last) { … } bool ScriptRunIterator::Fetch(wtf_size_t* pos, UChar32* ch) { … } UScriptCode ScriptRunIterator::ResolveCurrentScript() const { … } } // namespace blink