OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/fonts/FontFallbackIterator.h" | 5 #include "platform/fonts/FontFallbackIterator.h" |
6 | 6 |
7 #include "platform/Logging.h" | 7 #include "platform/Logging.h" |
8 #include "platform/fonts/FontCache.h" | 8 #include "platform/fonts/FontCache.h" |
9 #include "platform/fonts/FontDescription.h" | 9 #include "platform/fonts/FontDescription.h" |
10 #include "platform/fonts/FontFallbackList.h" | 10 #include "platform/fonts/FontFallbackList.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 return adoptRef(new FontFallbackIterator( | 21 return adoptRef(new FontFallbackIterator( |
22 description, fallbackList, fontFallbackPriority)); | 22 description, fallbackList, fontFallbackPriority)); |
23 } | 23 } |
24 | 24 |
25 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, | 25 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, |
26 PassRefPtr<FontFallbackList> fallbackList, | 26 PassRefPtr<FontFallbackList> fallbackList, |
27 FontFallbackPriority fontFallbackPriority) | 27 FontFallbackPriority fontFallbackPriority) |
28 : m_fontDescription(description) | 28 : m_fontDescription(description) |
29 , m_fontFallbackList(fallbackList) | 29 , m_fontFallbackList(fallbackList) |
30 , m_currentFontDataIndex(0) | 30 , m_currentFontDataIndex(0) |
31 , m_segmentedIndex(0) | 31 , m_segmentedFaceIndex(0) |
32 , m_fallbackStage(FontGroupFonts) | 32 , m_fallbackStage(FontGroupFonts) |
33 , m_fontFallbackPriority(fontFallbackPriority) | 33 , m_fontFallbackPriority(fontFallbackPriority) |
34 { | 34 { |
35 } | 35 } |
36 | 36 |
37 bool FontFallbackIterator::needsHintList() const | 37 bool FontFallbackIterator::needsHintList() const |
38 { | 38 { |
39 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { | 39 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { |
40 return false; | 40 return false; |
41 } | 41 } |
42 | 42 |
43 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); | 43 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); |
44 return fontData && fontData->isSegmented(); | 44 return fontData && fontData->isSegmented(); |
45 } | 45 } |
46 | 46 |
47 bool FontFallbackIterator::alreadyLoadingRangeForHintChar(UChar32 hintChar) | 47 bool FontFallbackIterator::alreadyLoadingRangeForHintChar(UChar32 hintChar) |
48 { | 48 { |
49 for (auto it = m_loadingCustomFontForRanges.begin(); it != m_loadingCustomFo
ntForRanges.end(); ++it) { | 49 for (auto it = m_trackedLoadingRangeSets.begin(); it != m_trackedLoadingRang
eSets.end(); ++it) { |
50 if (it->contains(hintChar)) | 50 if (it->contains(hintChar)) |
51 return true; | 51 return true; |
52 } | 52 } |
53 return false; | 53 return false; |
54 } | 54 } |
55 | 55 |
56 bool FontFallbackIterator::rangeContributesForHint(const Vector<UChar32> hintLis
t, const FontDataRange& fontDataRange) | 56 bool FontFallbackIterator::rangeSetContributesForHint(const Vector<UChar32> hint
List, const FontDataForRangeSet& segmentedFace) |
57 { | 57 { |
58 for (auto it = hintList.begin(); it != hintList.end(); ++it) { | 58 for (auto it = hintList.begin(); it != hintList.end(); ++it) { |
59 if (*it >= fontDataRange.from() && *it <= fontDataRange.to()) { | 59 if (segmentedFace.contains(*it)) { |
60 if (!alreadyLoadingRangeForHintChar(*it)) | 60 if (!alreadyLoadingRangeForHintChar(*it)) |
61 return true; | 61 return true; |
62 } | 62 } |
63 } | 63 } |
64 return false; | 64 return false; |
65 } | 65 } |
66 | 66 |
67 void FontFallbackIterator::willUseRange(const AtomicString& family, const FontDa
taRange& range) | 67 void FontFallbackIterator::willUseRange(const AtomicString& family, const FontDa
taForRangeSet& rangeSet) |
68 { | 68 { |
69 FontSelector* selector = m_fontFallbackList->getFontSelector(); | 69 FontSelector* selector = m_fontFallbackList->getFontSelector(); |
70 if (!selector) | 70 if (!selector) |
71 return; | 71 return; |
72 | 72 |
73 selector->willUseRange(m_fontDescription, family, range); | 73 selector->willUseRange(m_fontDescription, family, rangeSet); |
74 } | 74 } |
75 | 75 |
76 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) | 76 const FontDataForRangeSet FontFallbackIterator::next(const Vector<UChar32>& hint
List) |
77 { | 77 { |
78 if (m_fallbackStage == OutOfLuck) | 78 if (m_fallbackStage == OutOfLuck) |
79 return FontDataRange(); | 79 return FontDataForRangeSet(); |
80 | 80 |
81 if (m_fallbackStage == FallbackPriorityFonts) { | 81 if (m_fallbackStage == FallbackPriorityFonts) { |
82 // Only try one fallback priority font, | 82 // Only try one fallback priority font, |
83 // then proceed to regular system fallback. | 83 // then proceed to regular system fallback. |
84 m_fallbackStage = SystemFonts; | 84 m_fallbackStage = SystemFonts; |
85 FontDataRange fallbackPriorityFontRange(fallbackPriorityFont(hintList[0]
)); | 85 FontDataForRangeSet fallbackPriorityFontRange(fallbackPriorityFont(hintL
ist[0])); |
86 if (fallbackPriorityFontRange.hasFontData()) | 86 if (fallbackPriorityFontRange.hasFontData()) |
87 return fallbackPriorityFontRange; | 87 return fallbackPriorityFontRange; |
88 return next(hintList); | 88 return next(hintList); |
89 } | 89 } |
90 | 90 |
91 if (m_fallbackStage == SystemFonts) { | 91 if (m_fallbackStage == SystemFonts) { |
92 // We've reached pref + system fallback. | 92 // We've reached pref + system fallback. |
93 ASSERT(hintList.size()); | 93 ASSERT(hintList.size()); |
94 RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0])
; | 94 RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0])
; |
95 if (systemFont) | 95 if (systemFont) |
96 return FontDataRange(systemFont); | 96 return FontDataForRangeSet(systemFont); |
97 | 97 |
98 // If we don't have options from the system fallback anymore or had | 98 // If we don't have options from the system fallback anymore or had |
99 // previously returned them, we only have the last resort font left. | 99 // previously returned them, we only have the last resort font left. |
100 // TODO: crbug.com/42217 Improve this by doing the last run with a last | 100 // TODO: crbug.com/42217 Improve this by doing the last run with a last |
101 // resort font that has glyphs for everything, for example the Unicode | 101 // resort font that has glyphs for everything, for example the Unicode |
102 // LastResort font, not just Times or Arial. | 102 // LastResort font, not just Times or Arial. |
103 FontCache* fontCache = FontCache::fontCache(); | 103 FontCache* fontCache = FontCache::fontCache(); |
104 m_fallbackStage = OutOfLuck; | 104 m_fallbackStage = OutOfLuck; |
105 RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont
(m_fontDescription).get(); | 105 RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont
(m_fontDescription).get(); |
106 RELEASE_ASSERT(lastResort); | 106 RELEASE_ASSERT(lastResort); |
107 return FontDataRange(lastResort); | 107 return FontDataForRangeSet(lastResort); |
108 } | 108 } |
109 | 109 |
110 ASSERT(m_fallbackStage == FontGroupFonts | 110 ASSERT(m_fallbackStage == FontGroupFonts |
111 || m_fallbackStage == SegmentedFace); | 111 || m_fallbackStage == SegmentedFace); |
112 const FontData* fontData = m_fontFallbackList->fontDataAt( | 112 const FontData* fontData = m_fontFallbackList->fontDataAt( |
113 m_fontDescription, m_currentFontDataIndex); | 113 m_fontDescription, m_currentFontDataIndex); |
114 | 114 |
115 if (!fontData) { | 115 if (!fontData) { |
116 // If there is no fontData coming from the fallback list, it means | 116 // If there is no fontData coming from the fallback list, it means |
117 // we are now looking at system fonts, either for prioritized symbol | 117 // we are now looking at system fonts, either for prioritized symbol |
118 // or emoji fonts or by calling system fallback API. | 118 // or emoji fonts or by calling system fallback API. |
119 m_fallbackStage = isNonTextFallbackPriority(m_fontFallbackPriority) | 119 m_fallbackStage = isNonTextFallbackPriority(m_fontFallbackPriority) |
120 ? FallbackPriorityFonts | 120 ? FallbackPriorityFonts |
121 : SystemFonts; | 121 : SystemFonts; |
122 return next(hintList); | 122 return next(hintList); |
123 } | 123 } |
124 | 124 |
125 // Otherwise we've received a fontData from the font-family: set of fonts, | 125 // Otherwise we've received a fontData from the font-family: set of fonts, |
126 // and a non-segmented one in this case. | 126 // and a non-segmented one in this case. |
127 if (!fontData->isSegmented()) { | 127 if (!fontData->isSegmented()) { |
128 // Skip forward to the next font family for the next call to next(). | 128 // Skip forward to the next font family for the next call to next(). |
129 m_currentFontDataIndex++; | 129 m_currentFontDataIndex++; |
130 if (!fontData->isLoading()) { | 130 if (!fontData->isLoading()) { |
131 RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to
SimpleFontData(fontData)); | 131 RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to
SimpleFontData(fontData)); |
132 return FontDataRange(nonSegmented); | 132 return FontDataForRangeSet(nonSegmented); |
133 } | 133 } |
134 return next(hintList); | 134 return next(hintList); |
135 } | 135 } |
136 | 136 |
137 // Iterate over ranges of a segmented font below. | 137 // Iterate over ranges of a segmented font below. |
138 | 138 |
139 const SegmentedFontData* segmented = toSegmentedFontData(fontData); | 139 const SegmentedFontData* segmented = toSegmentedFontData(fontData); |
140 if (m_fallbackStage != SegmentedFace) { | 140 if (m_fallbackStage != SegmentedFace) { |
141 m_segmentedIndex = 0; | 141 m_segmentedFaceIndex = 0; |
142 m_fallbackStage = SegmentedFace; | 142 m_fallbackStage = SegmentedFace; |
143 } | 143 } |
144 | 144 |
145 ASSERT(m_segmentedIndex < segmented->numRanges()); | 145 ASSERT(m_segmentedFaceIndex < segmented->numFaces()); |
146 FontDataRange currentRange = segmented->rangeAt(m_segmentedIndex); | 146 FontDataForRangeSet currentSegmentedFace = segmented->faceAt(m_segmentedFace
Index); |
147 m_segmentedIndex++; | 147 m_segmentedFaceIndex++; |
148 | 148 |
149 if (m_segmentedIndex == segmented->numRanges()) { | 149 if (m_segmentedFaceIndex == segmented->numFaces()) { |
150 // Switch from iterating over a segmented face to the next family from | 150 // Switch from iterating over a segmented face to the next family from |
151 // the font-family: group of fonts. | 151 // the font-family: group of fonts. |
152 m_fallbackStage = FontGroupFonts; | 152 m_fallbackStage = FontGroupFonts; |
153 m_currentFontDataIndex++; | 153 m_currentFontDataIndex++; |
154 } | 154 } |
155 | 155 |
156 if (rangeContributesForHint(hintList, currentRange)) { | 156 if (rangeSetContributesForHint(hintList, currentSegmentedFace)) { |
157 if (currentRange.fontData()->customFontData()) | 157 if (currentSegmentedFace.fontData()->customFontData()) |
158 currentRange.fontData()->customFontData()->beginLoadIfNeeded(); | 158 currentSegmentedFace.fontData()->customFontData()->beginLoadIfNeeded
(); |
159 if (!currentRange.fontData()->isLoading()) | 159 if (!currentSegmentedFace.fontData()->isLoading()) |
160 return currentRange; | 160 return currentSegmentedFace; |
161 m_loadingCustomFontForRanges.append(currentRange); | 161 m_trackedLoadingRangeSets.append(currentSegmentedFace); |
162 } | 162 } |
163 | 163 |
164 return next(hintList); | 164 return next(hintList); |
165 } | 165 } |
166 | 166 |
167 const PassRefPtr<SimpleFontData> FontFallbackIterator::fallbackPriorityFont( | 167 const PassRefPtr<SimpleFontData> FontFallbackIterator::fallbackPriorityFont( |
168 UChar32 hint) | 168 UChar32 hint) |
169 { | 169 { |
170 return FontCache::fontCache()->fallbackFontForCharacter( | 170 return FontCache::fontCache()->fallbackFontForCharacter( |
171 m_fontDescription, | 171 m_fontDescription, |
(...skipping 12 matching lines...) Expand all Loading... |
184 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { | 184 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { |
185 return nullptr; | 185 return nullptr; |
186 } | 186 } |
187 | 187 |
188 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
on)); | 188 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
on)); |
189 | 189 |
190 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; | 190 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; |
191 } | 191 } |
192 | 192 |
193 } // namespace blink | 193 } // namespace blink |
OLD | NEW |