Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Unified Diff: third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp

Issue 1613153002: Add a SymbolsIterator to aid with Symbols Segmentation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Magic constants moved, EmojiEmoji enum value explained, formatting Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp
diff --git a/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp b/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4375944176753e12ecd1f5c6fdc1d7f5c4057baa
--- /dev/null
+++ b/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp
@@ -0,0 +1,156 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "SymbolsIterator.h"
+
+#include <unicode/uchar.h>
+#include <unicode/uniset.h>
+
+namespace blink {
+
+using namespace WTF::Unicode;
+
+SymbolsIterator::SymbolsIterator(const UChar* buffer, unsigned bufferSize)
+ : m_utf16Iterator(adoptPtr(new UTF16TextIterator(buffer, bufferSize)))
+ , m_bufferSize(bufferSize)
+ , m_nextChar(0)
+ , m_atEnd(bufferSize == 0)
+ , m_currentFontFallbackPriority(FontFallbackPriority::Invalid)
+{
+}
+
+FontFallbackPriority SymbolsIterator::fontFallbackPriorityForCharacter(UChar32 codepoint)
+{
+
+ // Those should only be Emoji presentation as combinations of two.
+ if (Character::isEmojiKeycapBase(codepoint)
+ || Character::isRegionalIndicator(codepoint))
+ return FontFallbackPriority::Text;
+
+ if (codepoint == combiningEnclosingKeycapCharacter
+ || codepoint == combiningEnclosingCircleBackslashCharacter)
+ return FontFallbackPriority::EmojiEmoji;
+
+ // There are overlaps between isEmojiTextpresentation and isEmojiEmojiPresentation.
+ // We want to prioritize emoji presentation if the character has such a property.
+ if (Character::isEmojiEmojiPresentation(codepoint)
+ || Character::isEmojiModifierBase(codepoint)
+ || Character::isModifier(codepoint))
+ return FontFallbackPriority::EmojiEmoji;
+
+ if (Character::isEmojiTextPresentation(codepoint))
+ return FontFallbackPriority::EmojiText;
+
+ UBlockCode block = ublock_getCode(codepoint);
+
+ switch (block) {
+ case UBLOCK_PLAYING_CARDS:
+ case UBLOCK_MISCELLANEOUS_SYMBOLS:
+ case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS:
+ case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS:
+ case UBLOCK_TRANSPORT_AND_MAP_SYMBOLS:
+ case UBLOCK_ALCHEMICAL_SYMBOLS:
+ case UBLOCK_RUNIC:
+ case UBLOCK_DINGBATS:
+ case UBLOCK_GOTHIC:
+ return FontFallbackPriority::Symbols;
+ case UBLOCK_ARROWS:
+ case UBLOCK_MATHEMATICAL_OPERATORS:
+ case UBLOCK_MISCELLANEOUS_TECHNICAL:
+ case UBLOCK_GEOMETRIC_SHAPES:
+ case UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A:
+ case UBLOCK_SUPPLEMENTAL_ARROWS_A:
+ case UBLOCK_SUPPLEMENTAL_ARROWS_B:
+ case UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B:
+ case UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS:
+ case UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS:
+ case UBLOCK_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS:
+ case UBLOCK_GEOMETRIC_SHAPES_EXTENDED:
+ return FontFallbackPriority::Math;
+ default:
+ return FontFallbackPriority::Text;
+ }
+}
+
+bool SymbolsIterator::consume(unsigned *symbolsLimit, FontFallbackPriority* fontFallbackPriority)
+{
+ if (m_atEnd)
+ return false;
+
+ while (m_utf16Iterator->consume(m_nextChar)) {
+ m_previousFontFallbackPriority = m_currentFontFallbackPriority;
+ unsigned iteratorOffset = m_utf16Iterator->offset();
+ m_utf16Iterator->advance();
+
+ // Except at the beginning, ZWJ just carries over the emoji or neutral
+ // text type, VS15 & VS16 we just carry over as well, since we already
+ // resolved those through lookahead. Also, the text presentation emoji
+ // are upgraded to emoji presentation when combined through ZWJ in the
+ // case of example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech
+ // bubble, see below.
+ if ((!(m_nextChar == zeroWidthJoinerCharacter
+ && m_previousFontFallbackPriority == FontFallbackPriority::EmojiEmoji)
+ && m_nextChar != variationSelector15Character
+ && m_nextChar != variationSelector16Character
+ && !Character::isRegionalIndicator(m_nextChar)
+ && !(m_nextChar == leftSpeechBubbleCharacter
+ && m_previousFontFallbackPriority == FontFallbackPriority::EmojiEmoji))
+ || m_currentFontFallbackPriority == FontFallbackPriority::Invalid) {
+ m_currentFontFallbackPriority = fontFallbackPriorityForCharacter(m_nextChar);
+ }
+
+ UChar32 peekChar = 0;
+ if (m_utf16Iterator->consume(peekChar)
+ && peekChar != 0) {
+
+ // Variation Selectors
+ if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiEmoji
+ && peekChar == variationSelector15Character) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiText;
+ }
+
+ if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiText
+ && peekChar == variationSelector16Character) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji;
+ }
+
+ // Combining characters Keycap...
+ if (Character::isEmojiKeycapBase(m_nextChar)
+ && peekChar == combiningEnclosingKeycapCharacter) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji;
+ };
+
+ // ...and Combining Enclosing Circle Backslash.
+ if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiText
+ && peekChar == combiningEnclosingCircleBackslashCharacter) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji;
+ }
+
+ // Regional indicators
+ if (Character::isRegionalIndicator(m_nextChar)
+ && Character::isRegionalIndicator(peekChar)) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji;
+ }
+
+ // Upgrade text presentation emoji to emoji presentation when followed by ZWJ,
+ // Example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech bubble.
+ if (m_nextChar == eyeCharacter && peekChar == zeroWidthJoinerCharacter) {
+ m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji;
+ }
+ }
+
+ if (m_previousFontFallbackPriority != m_currentFontFallbackPriority
+ && (m_previousFontFallbackPriority != FontFallbackPriority::Invalid)) {
+ *symbolsLimit = iteratorOffset;
+ *fontFallbackPriority = m_previousFontFallbackPriority;
+ return true;
+ }
+ }
+ *symbolsLimit = m_bufferSize;
+ *fontFallbackPriority = m_currentFontFallbackPriority;
+ m_atEnd = true;
+ return true;
+}
+
+}

Powered by Google App Engine
This is Rietveld 408576698