Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(864)

Side by Side Diff: third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp

Issue 1397423004: Improve shaping segmentation for grapheme cluster based font fallback (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge TestExpectations with the HarfBuzz rebaselines Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698