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 |