OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "core/css/RemoteFontFaceSource.h" | 5 #include "core/css/RemoteFontFaceSource.h" |
6 | 6 |
7 #include "core/css/CSSCustomFontData.h" | 7 #include "core/css/CSSCustomFontData.h" |
8 #include "core/css/CSSFontFace.h" | 8 #include "core/css/CSSFontFace.h" |
9 #include "core/css/CSSFontSelector.h" | 9 #include "core/css/CSSFontSelector.h" |
10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
11 #include "core/inspector/ConsoleMessage.h" | 11 #include "core/inspector/ConsoleMessage.h" |
12 #include "core/loader/FrameLoaderClient.h" | 12 #include "core/loader/FrameLoaderClient.h" |
13 #include "core/page/NetworkStateNotifier.h" | 13 #include "core/page/NetworkStateNotifier.h" |
14 #include "platform/Histogram.h" | 14 #include "platform/Histogram.h" |
15 #include "platform/RuntimeEnabledFeatures.h" | 15 #include "platform/RuntimeEnabledFeatures.h" |
16 #include "platform/fonts/FontCache.h" | 16 #include "platform/fonts/FontCache.h" |
| 17 #include "platform/fonts/FontCustomPlatformData.h" |
17 #include "platform/fonts/FontDescription.h" | 18 #include "platform/fonts/FontDescription.h" |
18 #include "platform/fonts/SimpleFontData.h" | 19 #include "platform/fonts/SimpleFontData.h" |
19 #include "platform/loader/fetch/ResourceFetcher.h" | 20 #include "platform/loader/fetch/ResourceFetcher.h" |
20 #include "platform/network/ResourceLoadPriority.h" | 21 #include "platform/network/ResourceLoadPriority.h" |
21 #include "public/platform/WebEffectiveConnectionType.h" | 22 #include "public/platform/WebEffectiveConnectionType.h" |
22 #include "wtf/CurrentTime.h" | 23 #include "wtf/CurrentTime.h" |
23 | 24 |
24 namespace blink { | 25 namespace blink { |
25 | 26 |
26 namespace { | 27 namespace { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( | 73 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( |
73 OtherMessageSource, InfoMessageLevel, | 74 OtherMessageSource, InfoMessageLevel, |
74 "Slow network is detected. Fallback font will be used while loading: " + | 75 "Slow network is detected. Fallback font will be used while loading: " + |
75 m_font->url().elidedString())); | 76 m_font->url().elidedString())); |
76 } | 77 } |
77 } | 78 } |
78 | 79 |
79 RemoteFontFaceSource::~RemoteFontFaceSource() {} | 80 RemoteFontFaceSource::~RemoteFontFaceSource() {} |
80 | 81 |
81 void RemoteFontFaceSource::dispose() { | 82 void RemoteFontFaceSource::dispose() { |
82 m_font->removeClient(this); | 83 if (m_font) { |
83 m_font = nullptr; | 84 m_font->removeClient(this); |
| 85 m_font = nullptr; |
| 86 } |
84 pruneTable(); | 87 pruneTable(); |
85 } | 88 } |
86 | 89 |
87 void RemoteFontFaceSource::pruneTable() { | 90 void RemoteFontFaceSource::pruneTable() { |
88 if (m_fontDataTable.isEmpty()) | 91 if (m_fontDataTable.isEmpty()) |
89 return; | 92 return; |
90 | 93 |
91 for (const auto& item : m_fontDataTable) { | 94 for (const auto& item : m_fontDataTable) { |
92 SimpleFontData* fontData = item.value.get(); | 95 SimpleFontData* fontData = item.value.get(); |
93 if (fontData && fontData->customFontData()) | 96 if (fontData && fontData->customFontData()) |
94 fontData->customFontData()->clearFontFaceSource(); | 97 fontData->customFontData()->clearFontFaceSource(); |
95 } | 98 } |
96 m_fontDataTable.clear(); | 99 m_fontDataTable.clear(); |
97 } | 100 } |
98 | 101 |
99 bool RemoteFontFaceSource::isLoading() const { | 102 bool RemoteFontFaceSource::isLoading() const { |
100 return m_font->isLoading(); | 103 return m_font && m_font->isLoading(); |
101 } | 104 } |
102 | 105 |
103 bool RemoteFontFaceSource::isLoaded() const { | 106 bool RemoteFontFaceSource::isLoaded() const { |
104 return m_font->isLoaded(); | 107 return !m_font; |
105 } | 108 } |
106 | 109 |
107 bool RemoteFontFaceSource::isValid() const { | 110 bool RemoteFontFaceSource::isValid() const { |
108 return !m_font->errorOccurred(); | 111 return m_font || m_customFontData; |
109 } | 112 } |
110 | 113 |
111 void RemoteFontFaceSource::notifyFinished(Resource*) { | 114 void RemoteFontFaceSource::notifyFinished(Resource* unusedResource) { |
| 115 DCHECK_EQ(unusedResource, m_font); |
112 m_histograms.maySetDataSource(m_font->response().wasCached() | 116 m_histograms.maySetDataSource(m_font->response().wasCached() |
113 ? FontLoadHistograms::FromDiskCache | 117 ? FontLoadHistograms::FromDiskCache |
114 : FontLoadHistograms::FromNetwork); | 118 : FontLoadHistograms::FromNetwork); |
115 m_histograms.recordRemoteFont(m_font.get(), m_isInterventionTriggered); | 119 m_histograms.recordRemoteFont(m_font.get(), m_isInterventionTriggered); |
116 m_histograms.fontLoaded(m_font->isCORSFailed(), | 120 m_histograms.fontLoaded(m_font->isCORSFailed(), |
117 m_font->getStatus() == ResourceStatus::LoadError, | 121 m_font->getStatus() == ResourceStatus::LoadError, |
118 m_isInterventionTriggered); | 122 m_isInterventionTriggered); |
119 | 123 |
120 m_font->ensureCustomFontData(); | 124 m_customFontData = m_font->getCustomFontData(); |
| 125 |
121 // FIXME: Provide more useful message such as OTS rejection reason. | 126 // FIXME: Provide more useful message such as OTS rejection reason. |
122 // See crbug.com/97467 | 127 // See crbug.com/97467 |
123 if (m_font->getStatus() == ResourceStatus::DecodeError && | 128 if (m_font->getStatus() == ResourceStatus::DecodeError && |
124 m_fontSelector->document()) { | 129 m_fontSelector->document()) { |
125 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( | 130 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( |
126 OtherMessageSource, WarningMessageLevel, | 131 OtherMessageSource, WarningMessageLevel, |
127 "Failed to decode downloaded font: " + m_font->url().elidedString())); | 132 "Failed to decode downloaded font: " + m_font->url().elidedString())); |
128 if (m_font->otsParsingMessage().length() > 1) | 133 if (m_font->otsParsingMessage().length() > 1) |
129 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( | 134 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( |
130 OtherMessageSource, WarningMessageLevel, | 135 OtherMessageSource, WarningMessageLevel, |
131 "OTS parsing error: " + m_font->otsParsingMessage())); | 136 "OTS parsing error: " + m_font->otsParsingMessage())); |
132 } | 137 } |
133 | 138 |
| 139 m_font->removeClient(this); |
| 140 m_font = nullptr; |
| 141 |
134 pruneTable(); | 142 pruneTable(); |
135 if (m_face) { | 143 if (m_face) { |
136 m_fontSelector->fontFaceInvalidated(); | 144 m_fontSelector->fontFaceInvalidated(); |
137 m_face->fontLoaded(this); | 145 m_face->fontLoaded(this); |
138 } | 146 } |
139 } | 147 } |
140 | 148 |
141 void RemoteFontFaceSource::fontLoadShortLimitExceeded(FontResource*) { | 149 void RemoteFontFaceSource::fontLoadShortLimitExceeded(FontResource*) { |
142 if (m_font->isLoaded()) | 150 if (isLoaded()) |
143 return; | 151 return; |
144 | 152 |
145 if (m_display == FontDisplayFallback) | 153 if (m_display == FontDisplayFallback) |
146 switchToSwapPeriod(); | 154 switchToSwapPeriod(); |
147 else if (m_display == FontDisplayOptional) | 155 else if (m_display == FontDisplayOptional) |
148 switchToFailurePeriod(); | 156 switchToFailurePeriod(); |
149 } | 157 } |
150 | 158 |
151 void RemoteFontFaceSource::fontLoadLongLimitExceeded(FontResource*) { | 159 void RemoteFontFaceSource::fontLoadLongLimitExceeded(FontResource*) { |
152 if (m_font->isLoaded()) | 160 if (isLoaded()) |
153 return; | 161 return; |
154 | 162 |
155 if (m_display == FontDisplayBlock || | 163 if (m_display == FontDisplayBlock || |
156 (!m_isInterventionTriggered && m_display == FontDisplayAuto)) | 164 (!m_isInterventionTriggered && m_display == FontDisplayAuto)) |
157 switchToSwapPeriod(); | 165 switchToSwapPeriod(); |
158 else if (m_display == FontDisplayFallback) | 166 else if (m_display == FontDisplayFallback) |
159 switchToFailurePeriod(); | 167 switchToFailurePeriod(); |
160 | 168 |
161 m_histograms.longLimitExceeded(m_isInterventionTriggered); | 169 m_histograms.longLimitExceeded(m_isInterventionTriggered); |
162 } | 170 } |
163 | 171 |
164 void RemoteFontFaceSource::switchToSwapPeriod() { | 172 void RemoteFontFaceSource::switchToSwapPeriod() { |
165 ASSERT(m_period == BlockPeriod); | 173 ASSERT(m_period == BlockPeriod); |
166 m_period = SwapPeriod; | 174 m_period = SwapPeriod; |
167 | 175 |
168 pruneTable(); | 176 pruneTable(); |
169 if (m_face) { | 177 if (m_face) { |
170 m_fontSelector->fontFaceInvalidated(); | 178 m_fontSelector->fontFaceInvalidated(); |
171 m_face->didBecomeVisibleFallback(this); | 179 m_face->didBecomeVisibleFallback(this); |
172 } | 180 } |
173 | 181 |
174 m_histograms.recordFallbackTime(m_font.get()); | 182 m_histograms.recordFallbackTime(); |
175 } | 183 } |
176 | 184 |
177 void RemoteFontFaceSource::switchToFailurePeriod() { | 185 void RemoteFontFaceSource::switchToFailurePeriod() { |
178 if (m_period == BlockPeriod) | 186 if (m_period == BlockPeriod) |
179 switchToSwapPeriod(); | 187 switchToSwapPeriod(); |
180 ASSERT(m_period == SwapPeriod); | 188 ASSERT(m_period == SwapPeriod); |
181 m_period = FailurePeriod; | 189 m_period = FailurePeriod; |
182 } | 190 } |
183 | 191 |
184 bool RemoteFontFaceSource::shouldTriggerWebFontsIntervention() { | 192 bool RemoteFontFaceSource::shouldTriggerWebFontsIntervention() { |
(...skipping 14 matching lines...) Expand all Loading... |
199 | 207 |
200 return networkIsSlow && m_display == FontDisplayAuto; | 208 return networkIsSlow && m_display == FontDisplayAuto; |
201 } | 209 } |
202 | 210 |
203 bool RemoteFontFaceSource::isLowPriorityLoadingAllowedForRemoteFont() const { | 211 bool RemoteFontFaceSource::isLowPriorityLoadingAllowedForRemoteFont() const { |
204 return m_isInterventionTriggered; | 212 return m_isInterventionTriggered; |
205 } | 213 } |
206 | 214 |
207 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData( | 215 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData( |
208 const FontDescription& fontDescription) { | 216 const FontDescription& fontDescription) { |
| 217 if (m_period == FailurePeriod || !isValid()) |
| 218 return nullptr; |
209 if (!isLoaded()) | 219 if (!isLoaded()) |
210 return createLoadingFallbackFontData(fontDescription); | 220 return createLoadingFallbackFontData(fontDescription); |
| 221 DCHECK(m_customFontData); |
211 | 222 |
212 if (!m_font->ensureCustomFontData() || m_period == FailurePeriod) | 223 m_histograms.recordFallbackTime(); |
213 return nullptr; | |
214 | |
215 m_histograms.recordFallbackTime(m_font.get()); | |
216 | 224 |
217 return SimpleFontData::create( | 225 return SimpleFontData::create( |
218 m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(), | 226 m_customFontData->fontPlatformData(fontDescription.effectiveFontSize(), |
219 fontDescription.isSyntheticBold(), | 227 fontDescription.isSyntheticBold(), |
220 fontDescription.isSyntheticItalic(), | 228 fontDescription.isSyntheticItalic(), |
221 fontDescription.orientation(), | 229 fontDescription.orientation(), |
222 fontDescription.variationSettings()), | 230 fontDescription.variationSettings()), |
223 CustomFontData::create()); | 231 CustomFontData::create()); |
224 } | 232 } |
225 | 233 |
226 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData( | 234 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData( |
227 const FontDescription& fontDescription) { | 235 const FontDescription& fontDescription) { |
228 // This temporary font is not retained and should not be returned. | 236 // This temporary font is not retained and should not be returned. |
229 FontCachePurgePreventer fontCachePurgePreventer; | 237 FontCachePurgePreventer fontCachePurgePreventer; |
230 SimpleFontData* temporaryFont = | 238 SimpleFontData* temporaryFont = |
231 FontCache::fontCache()->getNonRetainedLastResortFallbackFont( | 239 FontCache::fontCache()->getNonRetainedLastResortFallbackFont( |
232 fontDescription); | 240 fontDescription); |
233 if (!temporaryFont) { | 241 if (!temporaryFont) { |
234 ASSERT_NOT_REACHED(); | 242 ASSERT_NOT_REACHED(); |
235 return nullptr; | 243 return nullptr; |
236 } | 244 } |
237 RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create( | 245 RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create( |
238 this, m_period == BlockPeriod ? CSSCustomFontData::InvisibleFallback | 246 this, m_period == BlockPeriod ? CSSCustomFontData::InvisibleFallback |
239 : CSSCustomFontData::VisibleFallback); | 247 : CSSCustomFontData::VisibleFallback); |
240 return SimpleFontData::create(temporaryFont->platformData(), cssFontData); | 248 return SimpleFontData::create(temporaryFont->platformData(), cssFontData); |
241 } | 249 } |
242 | 250 |
243 void RemoteFontFaceSource::beginLoadIfNeeded() { | 251 void RemoteFontFaceSource::beginLoadIfNeeded() { |
| 252 if (isLoaded()) |
| 253 return; |
| 254 DCHECK(m_font); |
| 255 |
244 if (m_fontSelector->document() && m_font->stillNeedsLoad()) { | 256 if (m_fontSelector->document() && m_font->stillNeedsLoad()) { |
245 if (!m_font->url().protocolIsData() && !m_font->isLoaded() && | 257 if (!m_font->url().protocolIsData() && !m_font->isLoaded() && |
246 m_display == FontDisplayAuto && | 258 m_display == FontDisplayAuto && |
247 m_font->isLowPriorityLoadingAllowedForRemoteFont()) { | 259 m_font->isLowPriorityLoadingAllowedForRemoteFont()) { |
248 // Set the loading priority to VeryLow since this font is not required | 260 // Set the loading priority to VeryLow since this font is not required |
249 // for painting the text. | 261 // for painting the text. |
250 m_font->didChangePriority(ResourceLoadPriorityVeryLow, 0); | 262 m_font->didChangePriority(ResourceLoadPriorityVeryLow, 0); |
251 } | 263 } |
252 if (m_fontSelector->document()->fetcher()->startLoad(m_font)) { | 264 if (m_fontSelector->document()->fetcher()->startLoad(m_font)) { |
253 // Start timers only when load is actually started asynchronously. | 265 // Start timers only when load is actually started asynchronously. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 } | 302 } |
291 | 303 |
292 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded( | 304 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded( |
293 bool isInterventionTriggered) { | 305 bool isInterventionTriggered) { |
294 m_isLongLimitExceeded = true; | 306 m_isLongLimitExceeded = true; |
295 maySetDataSource(FromNetwork); | 307 maySetDataSource(FromNetwork); |
296 if (m_fontDisplay == FontDisplayAuto) | 308 if (m_fontDisplay == FontDisplayAuto) |
297 recordInterventionResult(isInterventionTriggered); | 309 recordInterventionResult(isInterventionTriggered); |
298 } | 310 } |
299 | 311 |
300 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime( | 312 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime() { |
301 const FontResource* font) { | |
302 if (m_blankPaintTime <= 0) | 313 if (m_blankPaintTime <= 0) |
303 return; | 314 return; |
304 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime); | 315 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime); |
305 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram, | 316 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram, |
306 ("WebFont.BlankTextShownTime", 0, 10000, 50)); | 317 ("WebFont.BlankTextShownTime", 0, 10000, 50)); |
307 blankTextShownTimeHistogram.count(duration); | 318 blankTextShownTimeHistogram.count(duration); |
308 m_blankPaintTime = -1; | 319 m_blankPaintTime = -1; |
309 } | 320 } |
310 | 321 |
311 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont( | 322 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont( |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 return Miss; | 477 return Miss; |
467 case FromUnknown: | 478 case FromUnknown: |
468 // Fall through. | 479 // Fall through. |
469 default: | 480 default: |
470 NOTREACHED(); | 481 NOTREACHED(); |
471 } | 482 } |
472 return Miss; | 483 return Miss; |
473 } | 484 } |
474 | 485 |
475 } // namespace blink | 486 } // namespace blink |
OLD | NEW |