Chromium Code Reviews| 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" |
| 11 #include "platform/fonts/SegmentedFontData.h" | 11 #include "platform/fonts/SegmentedFontData.h" |
| 12 #include "platform/fonts/SimpleFontData.h" | 12 #include "platform/fonts/SimpleFontData.h" |
| 13 | 13 |
| 14 namespace blink { | 14 namespace blink { |
| 15 | 15 |
| 16 PassRefPtr<FontFallbackIterator> FontFallbackIterator::create(const FontDescript ion& description, PassRefPtr<FontFallbackList> fallbackList) | 16 PassRefPtr<FontFallbackIterator> FontFallbackIterator::create( |
| 17 const FontDescription& description, | |
| 18 PassRefPtr<FontFallbackList> fallbackList, | |
| 19 FontFallbackPriority fontFallbackPriority) | |
| 17 { | 20 { |
| 18 return adoptRef(new FontFallbackIterator(description, fallbackList)); | 21 return adoptRef(new FontFallbackIterator( |
| 22 description, fallbackList, fontFallbackPriority)); | |
| 19 } | 23 } |
| 20 | 24 |
| 21 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, P assRefPtr<FontFallbackList> fallbackList) | 25 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, |
| 26 PassRefPtr<FontFallbackList> fallbackList, | |
| 27 FontFallbackPriority fontFallbackPriority) | |
| 22 : m_fontDescription(description) | 28 : m_fontDescription(description) |
| 23 , m_fontFallbackList(fallbackList) | 29 , m_fontFallbackList(fallbackList) |
| 24 , m_currentFontDataIndex(0) | 30 , m_currentFontDataIndex(0) |
| 25 , m_segmentedIndex(0) | 31 , m_segmentedIndex(0) |
| 26 , m_fallbackStage(FontGroupFonts) | 32 , m_fallbackStage( |
| 33 // Due to crbug.com/322658 we cannot reliably select Emoji fonts on Android at | |
| 34 // the moment. Disabling this functionality on Android to avoid reports of | |
| 35 // unreliable behavior until this issue is solved. | |
| 36 #if !OS(ANDROID) | |
| 37 // Currently we have to push the Emoji font to the top of the list | |
|
drott
2016/02/05 13:29:18
Looks like the windows failures indicate there is
| |
| 38 // due to https://github.com/behdad/harfbuzz/issues/217 | |
| 39 isNonTextFallbackPriority(fontFallbackPriority) | |
| 40 ? FallbackPriorityFonts | |
|
eae
2016/02/17 18:55:17
Indent line 40 and 41 one more level.
isNonTextFa
| |
| 41 : FontGroupFonts | |
| 42 #else | |
| 43 FontGroupFonts | |
| 44 #endif | |
| 45 ) | |
| 46 , m_fontFallbackPriority(fontFallbackPriority) | |
| 47 , m_symbolsFontCursor(0) | |
| 27 { | 48 { |
| 28 } | 49 } |
| 29 | 50 |
| 30 bool FontFallbackIterator::needsHintList() const | 51 bool FontFallbackIterator::needsHintList() const |
| 31 { | 52 { |
| 32 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { | 53 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { |
| 33 return false; | 54 return false; |
| 34 } | 55 } |
| 35 | 56 |
| 36 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription, m_currentFontDataIndex); | 57 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription, m_currentFontDataIndex); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 64 return; | 85 return; |
| 65 | 86 |
| 66 selector->willUseRange(m_fontDescription, family, range); | 87 selector->willUseRange(m_fontDescription, family, range); |
| 67 } | 88 } |
| 68 | 89 |
| 69 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) | 90 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) |
| 70 { | 91 { |
| 71 if (m_fallbackStage == OutOfLuck) | 92 if (m_fallbackStage == OutOfLuck) |
| 72 return FontDataRange(); | 93 return FontDataRange(); |
| 73 | 94 |
| 74 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription, m_currentFontDataIndex); | 95 if (m_fallbackStage == FallbackPriorityFonts) { |
| 96 FontDataRange fallbackPriorityFont = nextFallbackPriorityFont(); | |
| 97 if (!fallbackPriorityFont.isNull()) | |
| 98 return fallbackPriorityFont; | |
| 99 // No more prioritized fallback fonts, proceed to processing the CSS | |
| 100 // defined fonts. | |
| 101 m_fallbackStage = FontGroupFonts; | |
| 102 return next(hintList); | |
| 103 } | |
| 75 | 104 |
| 76 // If there is no fontData coming from the fallback list, it means | 105 if (m_fallbackStage == SystemFonts) { |
| 77 // we have reached the system fallback stage. | |
| 78 if (!fontData) { | |
| 79 m_fallbackStage = SystemFonts; | |
| 80 // We've reached pref + system fallback. | 106 // We've reached pref + system fallback. |
| 81 ASSERT(hintList.size()); | 107 ASSERT(hintList.size()); |
| 82 RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0]) ; | 108 RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0]) ; |
| 83 if (systemFont) | 109 if (systemFont) |
| 84 return FontDataRange(systemFont); | 110 return FontDataRange(systemFont); |
| 85 | 111 |
| 86 // If we don't have options from the system fallback anymore or had | 112 // If we don't have options from the system fallback anymore or had |
| 87 // previously returned them, we only have the last resort font left. | 113 // previously returned them, we only have the last resort font left. |
| 88 // TODO: crbug.com/42217 Improve this by doing the last run with a last | 114 // TODO: crbug.com/42217 Improve this by doing the last run with a last |
| 89 // resort font that has glyphs for everything, for example the Unicode | 115 // resort font that has glyphs for everything, for example the Unicode |
| 90 // LastResort font, not just Times or Arial. | 116 // LastResort font, not just Times or Arial. |
| 91 FontCache* fontCache = FontCache::fontCache(); | 117 FontCache* fontCache = FontCache::fontCache(); |
| 92 m_fallbackStage = OutOfLuck; | 118 m_fallbackStage = OutOfLuck; |
| 93 RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont (m_fontDescription).get(); | 119 RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont (m_fontDescription).get(); |
| 94 RELEASE_ASSERT(lastResort); | 120 RELEASE_ASSERT(lastResort); |
| 95 return FontDataRange(lastResort); | 121 return FontDataRange(lastResort); |
| 96 } | 122 } |
| 97 | 123 |
| 124 ASSERT(m_fallbackStage == FontGroupFonts | |
| 125 || m_fallbackStage == SegmentedFace); | |
| 126 const FontData* fontData = m_fontFallbackList->fontDataAt( | |
| 127 m_fontDescription, m_currentFontDataIndex); | |
| 128 | |
| 129 if (!fontData) { | |
| 130 // If there is no fontData coming from the fallback list, it means | |
| 131 // we are now looking at system fonts, either for prioritized symbol | |
| 132 // or emoji fonts or by calling system fallback API. | |
| 133 m_fallbackStage = SystemFonts; | |
| 134 return next(hintList); | |
| 135 } | |
| 136 | |
| 98 // Otherwise we've received a fontData from the font-family: set of fonts, | 137 // Otherwise we've received a fontData from the font-family: set of fonts, |
| 99 // and a non-segmented one in this case. | 138 // and a non-segmented one in this case. |
| 100 if (!fontData->isSegmented()) { | 139 if (!fontData->isSegmented()) { |
| 101 // Skip forward to the next font family for the next call to next(). | 140 // Skip forward to the next font family for the next call to next(). |
| 102 m_currentFontDataIndex++; | 141 m_currentFontDataIndex++; |
| 103 if (!fontData->isLoading()) { | 142 if (!fontData->isLoading()) { |
| 104 RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to SimpleFontData(fontData)); | 143 RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to SimpleFontData(fontData)); |
| 105 return FontDataRange(nonSegmented); | 144 return FontDataRange(nonSegmented); |
| 106 } | 145 } |
| 107 return next(hintList); | 146 return next(hintList); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 130 if (currentRange.fontData()->customFontData()) | 169 if (currentRange.fontData()->customFontData()) |
| 131 currentRange.fontData()->customFontData()->beginLoadIfNeeded(); | 170 currentRange.fontData()->customFontData()->beginLoadIfNeeded(); |
| 132 if (!currentRange.fontData()->isLoading()) | 171 if (!currentRange.fontData()->isLoading()) |
| 133 return currentRange; | 172 return currentRange; |
| 134 m_loadingCustomFontForRanges.append(currentRange); | 173 m_loadingCustomFontForRanges.append(currentRange); |
| 135 } | 174 } |
| 136 | 175 |
| 137 return next(hintList); | 176 return next(hintList); |
| 138 } | 177 } |
| 139 | 178 |
| 179 FontDataRange FontFallbackIterator::nextFallbackPriorityFont() | |
| 180 { | |
| 181 ASSERT(m_fontFallbackPriority != FontFallbackPriority::Invalid); | |
| 182 FontCache* fontCache = FontCache::fontCache(); | |
| 183 | |
| 184 const Vector<AtomicString>* priorityFontList = | |
| 185 fontCache->fontListForFallbackPriority( | |
| 186 m_fontDescription, m_fontFallbackPriority); | |
| 187 | |
| 188 if (m_symbolsFontCursor == priorityFontList->size()) | |
| 189 return FontDataRange(); | |
| 190 | |
| 191 RefPtr<SimpleFontData> priorityFont = fontCache->getFontData( | |
| 192 m_fontDescription, | |
| 193 priorityFontList->at(m_symbolsFontCursor)); | |
| 194 m_symbolsFontCursor++; | |
| 195 return FontDataRange(priorityFont); | |
| 196 } | |
| 197 | |
| 140 const PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint(U Char32 hint) | 198 const PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint(U Char32 hint) |
| 141 { | 199 { |
| 142 FontCache* fontCache = FontCache::fontCache(); | 200 FontCache* fontCache = FontCache::fontCache(); |
| 143 | 201 |
| 144 // When we're asked for a fallback for the same characters again, we give up | 202 // When we're asked for a fallback for the same characters again, we give up |
| 145 // because the shaper must have previously tried shaping with the font | 203 // because the shaper must have previously tried shaping with the font |
| 146 // already. | 204 // already. |
| 147 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { | 205 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { |
| 148 return nullptr; | 206 return nullptr; |
| 149 } | 207 } |
| 150 | 208 |
| 151 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_ fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti on)); | 209 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_ fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti on)); |
| 152 | 210 |
| 153 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; | 211 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; |
| 154 } | 212 } |
| 155 | 213 |
| 156 } // namespace blink | 214 } // namespace blink |
| OLD | NEW |