Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "SymbolsIterator.h" | |
| 6 | |
| 7 #include <unicode/uchar.h> | |
| 8 #include <unicode/uniset.h> | |
| 9 | |
| 10 namespace blink { | |
| 11 | |
| 12 using namespace WTF::Unicode; | |
| 13 | |
| 14 SymbolsIterator::SymbolsIterator(const UChar* buffer, unsigned bufferSize) | |
| 15 : m_utf16Iterator(adoptPtr(new UTF16TextIterator(buffer, bufferSize))) | |
| 16 , m_bufferSize(bufferSize) | |
| 17 , m_nextChar(0) | |
| 18 , m_atEnd(bufferSize == 0) | |
| 19 , m_currentFontFallbackPriority(FontFallbackPriority::Invalid) | |
| 20 { | |
| 21 } | |
| 22 | |
| 23 FontFallbackPriority SymbolsIterator::fontFallbackPriorityForCharacter(UChar32 c odepoint) | |
| 24 { | |
| 25 | |
| 26 // Those should only be Emoji presentation as combinations of two. | |
| 27 if (Character::isEmojiKeycapBase(codepoint) || Character::isRegionalIndicato r(codepoint)) | |
| 28 return FontFallbackPriority::Text; | |
| 29 | |
| 30 if (codepoint == 0x20E3 || codepoint == 0x20E0) | |
|
eae
2016/01/22 00:38:32
Could you please add these codepoints to Character
| |
| 31 return FontFallbackPriority::EmojiEmoji; | |
| 32 | |
| 33 // There are overlaps between isEmojiTextpresentation and isEmojiEmojiPresen tation. | |
| 34 // We want to prioritize emoji presentation if the character has such a prop erty. | |
| 35 if (Character::isEmojiEmojiPresentation(codepoint) | |
| 36 || Character::isEmojiModifierBase(codepoint) | |
| 37 || Character::isModifier(codepoint)) | |
| 38 return FontFallbackPriority::EmojiEmoji; | |
| 39 | |
| 40 if (Character::isEmojiTextPresentation(codepoint)) | |
| 41 return FontFallbackPriority::EmojiText; | |
| 42 | |
| 43 UBlockCode block = ublock_getCode(codepoint); | |
| 44 | |
| 45 switch (block) { | |
| 46 case UBLOCK_PLAYING_CARDS: | |
| 47 case UBLOCK_MISCELLANEOUS_SYMBOLS: | |
| 48 case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS: | |
| 49 case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS: | |
| 50 case UBLOCK_TRANSPORT_AND_MAP_SYMBOLS: | |
| 51 case UBLOCK_ALCHEMICAL_SYMBOLS: | |
| 52 case UBLOCK_RUNIC: | |
| 53 case UBLOCK_DINGBATS: | |
| 54 case UBLOCK_GOTHIC: | |
| 55 return FontFallbackPriority::Symbols; | |
| 56 case UBLOCK_ARROWS: | |
| 57 case UBLOCK_MATHEMATICAL_OPERATORS: | |
| 58 case UBLOCK_MISCELLANEOUS_TECHNICAL: | |
| 59 case UBLOCK_GEOMETRIC_SHAPES: | |
| 60 case UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A: | |
| 61 case UBLOCK_SUPPLEMENTAL_ARROWS_A: | |
| 62 case UBLOCK_SUPPLEMENTAL_ARROWS_B: | |
| 63 case UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B: | |
| 64 case UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS: | |
| 65 case UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS: | |
| 66 case UBLOCK_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS: | |
| 67 case UBLOCK_GEOMETRIC_SHAPES_EXTENDED: | |
| 68 return FontFallbackPriority::Math; | |
| 69 default: | |
| 70 return FontFallbackPriority::Text; | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 bool SymbolsIterator::consume(unsigned *symbolsLimit, FontFallbackPriority* font FallbackPriority) | |
| 75 { | |
| 76 if (m_atEnd) | |
| 77 return false; | |
| 78 | |
| 79 while (m_utf16Iterator->consume(m_nextChar)) { | |
| 80 m_previousFontFallbackPriority = m_currentFontFallbackPriority; | |
| 81 unsigned iteratorOffset = m_utf16Iterator->offset(); | |
| 82 m_utf16Iterator->advance(); | |
| 83 | |
| 84 // ZWJ just carries over the emoji or neutral text type, VS15 & VS16 we just carry over as well, since we | |
| 85 // are resolved those through lookahead - except at the beginning. | |
| 86 // Also, the text presentation Keep ZWJ joiner pairs in Emoji presentati on. See below. | |
| 87 // Example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech bubble | |
| 88 if ((!(m_nextChar == zeroWidthJoinerCharacter && m_previousFontFallbackP riority == FontFallbackPriority::EmojiEmoji) | |
| 89 && m_nextChar != variationSelector15Character | |
| 90 && m_nextChar != variationSelector16Character | |
| 91 && !Character::isRegionalIndicator(m_nextChar) | |
| 92 && !(m_nextChar == 0x1F5E8 && m_previousFontFallbackPriority == Font FallbackPriority::EmojiEmoji)) | |
| 93 || m_currentFontFallbackPriority == FontFallbackPriority::Invalid) { | |
| 94 m_currentFontFallbackPriority = fontFallbackPriorityForCharacter(m_n extChar); | |
| 95 } | |
| 96 | |
| 97 UChar32 peekChar = 0; | |
| 98 if (m_utf16Iterator->consume(peekChar) | |
| 99 && peekChar != 0) { | |
| 100 | |
| 101 // Variation Selectors | |
| 102 if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiEmoj i && peekChar == variationSelector15Character) { | |
| 103 m_currentFontFallbackPriority = FontFallbackPriority::EmojiText; | |
| 104 } | |
| 105 | |
| 106 if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiText && peekChar == variationSelector16Character) { | |
| 107 m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji ; | |
| 108 } | |
| 109 | |
| 110 // Combining characters Keycap... | |
| 111 if (Character::isEmojiKeycapBase(m_nextChar) && peekChar == 0x20E3) { | |
| 112 m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji ; | |
| 113 }; | |
| 114 | |
| 115 // ...and Combining Enclosing Circle Backslash. | |
| 116 if (m_currentFontFallbackPriority == FontFallbackPriority::EmojiText && peekChar == 0x20E0) { | |
| 117 m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji ; | |
| 118 } | |
| 119 | |
| 120 // Regional indicators | |
| 121 if (Character::isRegionalIndicator(m_nextChar) && Character::isRegio nalIndicator(peekChar)) { | |
| 122 m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji ; | |
| 123 } | |
| 124 | |
| 125 // Upgrade text presentation emoji to emoji presentation when follow ed by ZWJ, | |
| 126 // Example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech bubble | |
| 127 if (m_nextChar == 0x1F441 && peekChar == zeroWidthJoinerCharacter) { | |
| 128 m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji ; | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 if (m_previousFontFallbackPriority != m_currentFontFallbackPriority | |
| 133 && (m_previousFontFallbackPriority != FontFallbackPriority::Invalid) ) { | |
| 134 *symbolsLimit = iteratorOffset; | |
| 135 *fontFallbackPriority = m_previousFontFallbackPriority; | |
| 136 return true; | |
| 137 } | |
| 138 } | |
| 139 *symbolsLimit = m_bufferSize; | |
| 140 *fontFallbackPriority = m_currentFontFallbackPriority; | |
| 141 m_atEnd = true; | |
| 142 return true; | |
| 143 } | |
| 144 | |
| 145 } | |
| OLD | NEW |