| 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/fonts/FontCache.h" |    7 #include "platform/fonts/FontCache.h" | 
|    8 #include "platform/fonts/FontDescription.h" |    8 #include "platform/fonts/FontDescription.h" | 
|    9 #include "platform/fonts/FontFallbackList.h" |    9 #include "platform/fonts/FontFallbackList.h" | 
|   10 #include "platform/fonts/SegmentedFontData.h" |   10 #include "platform/fonts/SegmentedFontData.h" | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   92     m_fallbackStage = SystemFonts; |   92     m_fallbackStage = SystemFonts; | 
|   93     RefPtr<FontDataForRangeSet> fallbackPriorityFontRange = |   93     RefPtr<FontDataForRangeSet> fallbackPriorityFontRange = | 
|   94         adoptRef(new FontDataForRangeSet(fallbackPriorityFont(hintList[0]))); |   94         adoptRef(new FontDataForRangeSet(fallbackPriorityFont(hintList[0]))); | 
|   95     if (fallbackPriorityFontRange->hasFontData()) |   95     if (fallbackPriorityFontRange->hasFontData()) | 
|   96       return uniqueOrNext(fallbackPriorityFontRange.release(), hintList); |   96       return uniqueOrNext(fallbackPriorityFontRange.release(), hintList); | 
|   97     return next(hintList); |   97     return next(hintList); | 
|   98   } |   98   } | 
|   99  |   99  | 
|  100   if (m_fallbackStage == SystemFonts) { |  100   if (m_fallbackStage == SystemFonts) { | 
|  101     // We've reached pref + system fallback. |  101     // We've reached pref + system fallback. | 
|  102     ASSERT(hintList.size()); |  102     RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHintList(hintList); | 
|  103     RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0]); |  | 
|  104     if (systemFont) { |  103     if (systemFont) { | 
|  105       // Fallback fonts are not retained in the FontDataCache. |  104       // Fallback fonts are not retained in the FontDataCache. | 
|  106       return uniqueOrNext(adoptRef(new FontDataForRangeSet(systemFont)), |  105       return uniqueOrNext(adoptRef(new FontDataForRangeSet(systemFont)), | 
|  107                           hintList); |  106                           hintList); | 
|  108     } |  107     } | 
|  109  |  108  | 
|  110     // If we don't have options from the system fallback anymore or had |  109     // If we don't have options from the system fallback anymore or had | 
|  111     // previously returned them, we only have the last resort font left. |  110     // previously returned them, we only have the last resort font left. | 
|  112     // TODO: crbug.com/42217 Improve this by doing the last run with a last |  111     // TODO: crbug.com/42217 Improve this by doing the last run with a last | 
|  113     // resort font that has glyphs for everything, for example the Unicode |  112     // resort font that has glyphs for everything, for example the Unicode | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  186 } |  185 } | 
|  187  |  186  | 
|  188 PassRefPtr<SimpleFontData> FontFallbackIterator::fallbackPriorityFont( |  187 PassRefPtr<SimpleFontData> FontFallbackIterator::fallbackPriorityFont( | 
|  189     UChar32 hint) { |  188     UChar32 hint) { | 
|  190   return FontCache::fontCache()->fallbackFontForCharacter( |  189   return FontCache::fontCache()->fallbackFontForCharacter( | 
|  191       m_fontDescription, hint, |  190       m_fontDescription, hint, | 
|  192       m_fontFallbackList->primarySimpleFontData(m_fontDescription), |  191       m_fontFallbackList->primarySimpleFontData(m_fontDescription), | 
|  193       m_fontFallbackPriority); |  192       m_fontFallbackPriority); | 
|  194 } |  193 } | 
|  195  |  194  | 
|  196 PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint( |  195 static inline unsigned chooseHintIndex(const Vector<UChar32>& hintList) { | 
|  197     UChar32 hint) { |  196   // crbug.com/618178 has a test case where no Myanmar font is ever found, | 
 |  197   // because the run starts with a punctuation character with a script value of | 
 |  198   // common. Our current font fallback code does not find a very meaningful | 
 |  199   // result for this. | 
 |  200   // TODO crbug.com/668706 - Improve this situation. | 
 |  201   // So if we have multiple hint characters (which indicates that a | 
 |  202   // multi-character grapheme or more failed to shape, then we can try to be | 
 |  203   // smarter and select the first character that has an actual script value. | 
 |  204   DCHECK(hintList.size()); | 
 |  205   if (hintList.size() <= 1) | 
 |  206     return 0; | 
 |  207  | 
 |  208   UErrorCode err = U_ZERO_ERROR; | 
 |  209   UScriptCode hintCharScript = uscript_getScript(hintList[0], &err); | 
 |  210   if (!U_SUCCESS(err) || hintCharScript > USCRIPT_INHERITED) | 
 |  211     return 0; | 
 |  212  | 
 |  213   for (size_t i = 1; i < hintList.size(); ++i) { | 
 |  214     UScriptCode newHintScript = uscript_getScript(hintList[i], &err); | 
 |  215     if (!U_SUCCESS(err)) | 
 |  216       return 0; | 
 |  217     if (newHintScript > USCRIPT_INHERITED) | 
 |  218       return i; | 
 |  219   } | 
 |  220   return 0; | 
 |  221 } | 
 |  222  | 
 |  223 PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHintList( | 
 |  224     const Vector<UChar32>& hintList) { | 
|  198   // When we're asked for a fallback for the same characters again, we give up |  225   // When we're asked for a fallback for the same characters again, we give up | 
|  199   // because the shaper must have previously tried shaping with the font |  226   // because the shaper must have previously tried shaping with the font | 
|  200   // already. |  227   // already. | 
|  201   if (!hint || m_previouslyAskedForHint.contains(hint)) |  228   if (!hintList.size()) | 
|  202     return nullptr; |  229     return nullptr; | 
|  203  |  230  | 
|  204   FontCache* fontCache = FontCache::fontCache(); |  231   FontCache* fontCache = FontCache::fontCache(); | 
 |  232   UChar32 hint = hintList[chooseHintIndex(hintList)]; | 
 |  233  | 
 |  234   if (!hint || m_previouslyAskedForHint.contains(hint)) | 
 |  235     return nullptr; | 
|  205   m_previouslyAskedForHint.add(hint); |  236   m_previouslyAskedForHint.add(hint); | 
|  206   return fontCache->fallbackFontForCharacter( |  237   return fontCache->fallbackFontForCharacter( | 
|  207       m_fontDescription, hint, |  238       m_fontDescription, hint, | 
|  208       m_fontFallbackList->primarySimpleFontData(m_fontDescription)); |  239       m_fontFallbackList->primarySimpleFontData(m_fontDescription)); | 
|  209 } |  240 } | 
|  210  |  241  | 
|  211 }  // namespace blink |  242 }  // namespace blink | 
| OLD | NEW |