| 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 "config.h" | 5 #include "config.h" |
| 6 #include "platform/fonts/FontFallbackIterator.h" | 6 #include "platform/fonts/FontFallbackIterator.h" |
| 7 | 7 |
| 8 #include "platform/Logging.h" | 8 #include "platform/Logging.h" |
| 9 #include "platform/fonts/FontCache.h" | 9 #include "platform/fonts/FontCache.h" |
| 10 #include "platform/fonts/FontDescription.h" | 10 #include "platform/fonts/FontDescription.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 bool FontFallbackIterator::needsHintList() const | 32 bool FontFallbackIterator::needsHintList() const |
| 33 { | 33 { |
| 34 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { | 34 if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { |
| 35 return false; | 35 return false; |
| 36 } | 36 } |
| 37 | 37 |
| 38 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); | 38 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); |
| 39 return fontData && fontData->isSegmented(); | 39 return fontData && fontData->isSegmented(); |
| 40 } | 40 } |
| 41 | 41 |
| 42 static bool rangeContributesForHint(const Vector<UChar32> hintList, const FontDa
taRange& fontDataRange) | 42 bool FontFallbackIterator::alreadyLoadingRangeForHintChar(UChar32 hintChar) |
| 43 { |
| 44 for (auto it = m_loadingCustomFontForRanges.begin(); it != m_loadingCustomFo
ntForRanges.end(); ++it) { |
| 45 if (it->contains(hintChar)) |
| 46 return true; |
| 47 } |
| 48 return false; |
| 49 } |
| 50 |
| 51 bool FontFallbackIterator::rangeContributesForHint(const Vector<UChar32> hintLis
t, const FontDataRange& fontDataRange) |
| 43 { | 52 { |
| 44 for (auto it = hintList.begin(); it != hintList.end(); ++it) { | 53 for (auto it = hintList.begin(); it != hintList.end(); ++it) { |
| 45 if (*it >= fontDataRange.from() && *it <= fontDataRange.to()) { | 54 if (*it >= fontDataRange.from() && *it <= fontDataRange.to()) { |
| 46 return true; | 55 if (!alreadyLoadingRangeForHintChar(*it)) |
| 56 return true; |
| 47 } | 57 } |
| 48 } | 58 } |
| 49 return false; | 59 return false; |
| 50 } | 60 } |
| 51 | 61 |
| 52 void FontFallbackIterator::willUseRange(const AtomicString& family, const FontDa
taRange& range) | 62 void FontFallbackIterator::willUseRange(const AtomicString& family, const FontDa
taRange& range) |
| 53 { | 63 { |
| 54 FontSelector* selector = m_fontFallbackList->fontSelector(); | 64 FontSelector* selector = m_fontFallbackList->fontSelector(); |
| 55 if (!selector) | 65 if (!selector) |
| 56 return; | 66 return; |
| 57 | 67 |
| 58 selector->willUseRange(m_fontDescription, family, range); | 68 selector->willUseRange(m_fontDescription, family, range); |
| 59 } | 69 } |
| 60 | 70 |
| 61 const SimpleFontData* FontFallbackIterator::next(const Vector<UChar32>& hintList
) | 71 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) |
| 62 { | 72 { |
| 63 if (m_fallbackStage == OutOfLuck) | 73 if (m_fallbackStage == OutOfLuck) |
| 64 return nullptr; | 74 return FontDataRange(); |
| 65 | 75 |
| 66 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); | 76 const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
m_currentFontDataIndex); |
| 67 | 77 |
| 78 // If there is no fontData coming from the fallback list, it means |
| 79 // we have reached the system fallback stage. |
| 68 if (!fontData) { | 80 if (!fontData) { |
| 69 m_fallbackStage = SystemFonts; | 81 m_fallbackStage = SystemFonts; |
| 70 // We've reached pref + system fallback. | 82 // We've reached pref + system fallback. |
| 71 ASSERT(hintList.size()); | 83 ASSERT(hintList.size()); |
| 72 const SimpleFontData* systemFont = uniqueSystemFontForHint(hintList[0]); | 84 RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0])
; |
| 73 if (systemFont) | 85 if (systemFont) |
| 74 return systemFont; | 86 return FontDataRange(systemFont); |
| 75 | 87 |
| 76 // If we don't have options from the system fallback anymore or had | 88 // If we don't have options from the system fallback anymore or had |
| 77 // previously returned them, we only have the last resort font left. | 89 // previously returned them, we only have the last resort font left. |
| 78 // TODO: crbug.com/42217 Improve this by doing the last run with a last | 90 // TODO: crbug.com/42217 Improve this by doing the last run with a last |
| 79 // resort font that has glyphs for everything, for example the Unicode | 91 // resort font that has glyphs for everything, for example the Unicode |
| 80 // LastResort font, not just Times or Arial. | 92 // LastResort font, not just Times or Arial. |
| 81 FontCache* fontCache = FontCache::fontCache(); | 93 FontCache* fontCache = FontCache::fontCache(); |
| 82 m_fallbackStage = OutOfLuck; | 94 m_fallbackStage = OutOfLuck; |
| 83 SimpleFontData* lastResort = fontCache->getLastResortFallbackFont(m_font
Description).get(); | 95 RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont
(m_fontDescription).get(); |
| 84 RELEASE_ASSERT(lastResort); | 96 RELEASE_ASSERT(lastResort); |
| 85 return lastResort; | 97 return FontDataRange(lastResort); |
| 86 } | 98 } |
| 87 | 99 |
| 100 // Otherwise we've received a fontData from the font-family: set of fonts, |
| 101 // and a non-segmented one in this case. |
| 88 if (!fontData->isSegmented()) { | 102 if (!fontData->isSegmented()) { |
| 89 // Skip forward to the next font family for the next call to next(). | 103 // Skip forward to the next font family for the next call to next(). |
| 90 m_currentFontDataIndex++; | 104 m_currentFontDataIndex++; |
| 91 m_currentFamily = m_currentFamily->next(); | 105 m_currentFamily = m_currentFamily->next(); |
| 92 return toSimpleFontData(fontData); | 106 if (!fontData->isLoading()) { |
| 107 RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to
SimpleFontData(fontData)); |
| 108 // TODO crbug.com/546465: Investigate if we might need to do |
| 109 // something like |
| 110 // toSimpleFontData(fontData)->customFontData()->beginLoadIfNeeded() |
| 111 // here to trigger loading. |
| 112 return FontDataRange(nonSegmented); |
| 113 } |
| 114 return next(hintList); |
| 93 } | 115 } |
| 94 | 116 |
| 95 // Iterate over ranges of a segmented font below. | 117 // Iterate over ranges of a segmented font below. |
| 96 | 118 |
| 97 const SegmentedFontData* segmented = toSegmentedFontData(fontData); | 119 const SegmentedFontData* segmented = toSegmentedFontData(fontData); |
| 98 if (m_fallbackStage != SegmentedFace) { | 120 if (m_fallbackStage != SegmentedFace) { |
| 99 m_segmentedIndex = 0; | 121 m_segmentedIndex = 0; |
| 100 m_fallbackStage = SegmentedFace; | 122 m_fallbackStage = SegmentedFace; |
| 101 } | 123 } |
| 102 | 124 |
| 103 ASSERT(m_segmentedIndex < segmented->numRanges()); | 125 ASSERT(m_segmentedIndex < segmented->numRanges()); |
| 104 FontDataRange currentRange = segmented->rangeAt(m_segmentedIndex); | 126 FontDataRange currentRange = segmented->rangeAt(m_segmentedIndex); |
| 105 m_segmentedIndex++; | 127 m_segmentedIndex++; |
| 106 AtomicString segmentedFamily = m_currentFamily->family(); | 128 AtomicString segmentedFamily = m_currentFamily->family(); |
| 107 | 129 |
| 108 if (m_segmentedIndex == segmented->numRanges()) { | 130 if (m_segmentedIndex == segmented->numRanges()) { |
| 109 // Switch from iterating over a segmented face to the next family from | 131 // Switch from iterating over a segmented face to the next family from |
| 110 // the font-family: group of fonts. | 132 // the font-family: group of fonts. |
| 111 m_fallbackStage = FontGroupFonts; | 133 m_fallbackStage = FontGroupFonts; |
| 112 m_currentFontDataIndex++; | 134 m_currentFontDataIndex++; |
| 113 m_currentFamily = m_currentFamily->next(); | 135 m_currentFamily = m_currentFamily->next(); |
| 114 } | 136 } |
| 115 | 137 |
| 116 if (rangeContributesForHint(hintList, currentRange)) { | 138 if (rangeContributesForHint(hintList, currentRange)) { |
| 117 willUseRange(segmentedFamily, currentRange); | 139 willUseRange(segmentedFamily, currentRange); |
| 118 return currentRange.fontData().get(); | 140 if (!currentRange.fontData()->isLoading()) |
| 141 return currentRange; |
| 142 m_loadingCustomFontForRanges.append(currentRange); |
| 119 } | 143 } |
| 120 | 144 |
| 121 return next(hintList); | 145 return next(hintList); |
| 122 } | 146 } |
| 123 | 147 |
| 124 const SimpleFontData* FontFallbackIterator::uniqueSystemFontForHint(UChar32 hint
) | 148 const PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint(U
Char32 hint) |
| 125 { | 149 { |
| 126 FontCache* fontCache = FontCache::fontCache(); | 150 FontCache* fontCache = FontCache::fontCache(); |
| 127 | 151 |
| 128 // When we're asked for a fallback for the same characters again, we give up | 152 // When we're asked for a fallback for the same characters again, we give up |
| 129 // because the shaper must have previously tried shaping with the font | 153 // because the shaper must have previously tried shaping with the font |
| 130 // already. | 154 // already. |
| 131 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { | 155 if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { |
| 132 return nullptr; | 156 return nullptr; |
| 133 } | 157 } |
| 134 | 158 |
| 135 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
on)); | 159 RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
on)); |
| 136 | 160 |
| 137 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value.get()
; | 161 return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; |
| 138 } | 162 } |
| 139 | 163 |
| 140 } // namespace blink | 164 } // namespace blink |
| OLD | NEW |