| 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( |   16 PassRefPtr<FontFallbackIterator> FontFallbackIterator::create(const FontDescript
     ion& description, PassRefPtr<FontFallbackList> fallbackList) | 
|   17     const FontDescription& description, |  | 
|   18     PassRefPtr<FontFallbackList> fallbackList, |  | 
|   19     FontFallbackPriority fontFallbackPriority) |  | 
|   20 { |   17 { | 
|   21     return adoptRef(new FontFallbackIterator( |   18     return adoptRef(new FontFallbackIterator(description, fallbackList)); | 
|   22         description, fallbackList, fontFallbackPriority)); |  | 
|   23 } |   19 } | 
|   24  |   20  | 
|   25 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, |   21 FontFallbackIterator::FontFallbackIterator(const FontDescription& description, P
     assRefPtr<FontFallbackList> fallbackList) | 
|   26     PassRefPtr<FontFallbackList> fallbackList, |  | 
|   27     FontFallbackPriority fontFallbackPriority) |  | 
|   28     : m_fontDescription(description) |   22     : m_fontDescription(description) | 
|   29     , m_fontFallbackList(fallbackList) |   23     , m_fontFallbackList(fallbackList) | 
|   30     , m_currentFontDataIndex(0) |   24     , m_currentFontDataIndex(0) | 
|   31     , m_segmentedIndex(0) |   25     , m_segmentedIndex(0) | 
|   32     , m_fallbackStage(FontGroupFonts) |   26     , m_fallbackStage(FontGroupFonts) | 
|   33     , m_fontFallbackPriority(fontFallbackPriority) |  | 
|   34 { |   27 { | 
|   35 } |   28 } | 
|   36  |   29  | 
|   37 bool FontFallbackIterator::needsHintList() const |   30 bool FontFallbackIterator::needsHintList() const | 
|   38 { |   31 { | 
|   39     if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { |   32     if (m_fallbackStage != FontGroupFonts && m_fallbackStage != SegmentedFace) { | 
|   40         return false; |   33         return false; | 
|   41     } |   34     } | 
|   42  |   35  | 
|   43     const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
      m_currentFontDataIndex); |   36     const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
      m_currentFontDataIndex); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   71         return; |   64         return; | 
|   72  |   65  | 
|   73     selector->willUseRange(m_fontDescription, family, range); |   66     selector->willUseRange(m_fontDescription, family, range); | 
|   74 } |   67 } | 
|   75  |   68  | 
|   76 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) |   69 const FontDataRange FontFallbackIterator::next(const Vector<UChar32>& hintList) | 
|   77 { |   70 { | 
|   78     if (m_fallbackStage == OutOfLuck) |   71     if (m_fallbackStage == OutOfLuck) | 
|   79         return FontDataRange(); |   72         return FontDataRange(); | 
|   80  |   73  | 
|   81     if (m_fallbackStage == FallbackPriorityFonts) { |   74     const FontData* fontData = m_fontFallbackList->fontDataAt(m_fontDescription,
      m_currentFontDataIndex); | 
|   82         // Only try one fallback priority font, |   75  | 
|   83         // then proceed to regular system fallback. |   76     // If there is no fontData coming from the fallback list, it means | 
 |   77     // we have reached the system fallback stage. | 
 |   78     if (!fontData) { | 
|   84         m_fallbackStage = SystemFonts; |   79         m_fallbackStage = SystemFonts; | 
|   85         FontDataRange fallbackPriorityFontRange(fallbackPriorityFont(hintList[0]
     )); |  | 
|   86         if (fallbackPriorityFontRange.hasFontData()) |  | 
|   87             return fallbackPriorityFontRange; |  | 
|   88         return next(hintList); |  | 
|   89     } |  | 
|   90  |  | 
|   91     if (m_fallbackStage == SystemFonts) { |  | 
|   92         // We've reached pref + system fallback. |   80         // We've reached pref + system fallback. | 
|   93         ASSERT(hintList.size()); |   81         ASSERT(hintList.size()); | 
|   94         RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0])
     ; |   82         RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0])
     ; | 
|   95         if (systemFont) |   83         if (systemFont) | 
|   96             return FontDataRange(systemFont); |   84             return FontDataRange(systemFont); | 
|   97  |   85  | 
|   98         // If we don't have options from the system fallback anymore or had |   86         // If we don't have options from the system fallback anymore or had | 
|   99         // previously returned them, we only have the last resort font left. |   87         // previously returned them, we only have the last resort font left. | 
|  100         // TODO: crbug.com/42217 Improve this by doing the last run with a last |   88         // TODO: crbug.com/42217 Improve this by doing the last run with a last | 
|  101         // resort font that has glyphs for everything, for example the Unicode |   89         // resort font that has glyphs for everything, for example the Unicode | 
|  102         // LastResort font, not just Times or Arial. |   90         // LastResort font, not just Times or Arial. | 
|  103         FontCache* fontCache = FontCache::fontCache(); |   91         FontCache* fontCache = FontCache::fontCache(); | 
|  104         m_fallbackStage = OutOfLuck; |   92         m_fallbackStage = OutOfLuck; | 
|  105         RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont
     (m_fontDescription).get(); |   93         RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont
     (m_fontDescription).get(); | 
|  106         RELEASE_ASSERT(lastResort); |   94         RELEASE_ASSERT(lastResort); | 
|  107         return FontDataRange(lastResort); |   95         return FontDataRange(lastResort); | 
|  108     } |   96     } | 
|  109  |   97  | 
|  110     ASSERT(m_fallbackStage == FontGroupFonts |  | 
|  111         || m_fallbackStage == SegmentedFace); |  | 
|  112     const FontData* fontData = m_fontFallbackList->fontDataAt( |  | 
|  113         m_fontDescription, m_currentFontDataIndex); |  | 
|  114  |  | 
|  115     if (!fontData) { |  | 
|  116         // If there is no fontData coming from the fallback list, it means |  | 
|  117         // we are now looking at system fonts, either for prioritized symbol |  | 
|  118         // or emoji fonts or by calling system fallback API. |  | 
|  119         m_fallbackStage = isNonTextFallbackPriority(m_fontFallbackPriority) |  | 
|  120             ? FallbackPriorityFonts |  | 
|  121             : SystemFonts; |  | 
|  122         return next(hintList); |  | 
|  123     } |  | 
|  124  |  | 
|  125     // Otherwise we've received a fontData from the font-family: set of fonts, |   98     // Otherwise we've received a fontData from the font-family: set of fonts, | 
|  126     // and a non-segmented one in this case. |   99     // and a non-segmented one in this case. | 
|  127     if (!fontData->isSegmented()) { |  100     if (!fontData->isSegmented()) { | 
|  128         // Skip forward to the next font family for the next call to next(). |  101         // Skip forward to the next font family for the next call to next(). | 
|  129         m_currentFontDataIndex++; |  102         m_currentFontDataIndex++; | 
|  130         if (!fontData->isLoading()) { |  103         if (!fontData->isLoading()) { | 
|  131             RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to
     SimpleFontData(fontData)); |  104             RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(to
     SimpleFontData(fontData)); | 
|  132             return FontDataRange(nonSegmented); |  105             return FontDataRange(nonSegmented); | 
|  133         } |  106         } | 
|  134         return next(hintList); |  107         return next(hintList); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  157         if (currentRange.fontData()->customFontData()) |  130         if (currentRange.fontData()->customFontData()) | 
|  158             currentRange.fontData()->customFontData()->beginLoadIfNeeded(); |  131             currentRange.fontData()->customFontData()->beginLoadIfNeeded(); | 
|  159         if (!currentRange.fontData()->isLoading()) |  132         if (!currentRange.fontData()->isLoading()) | 
|  160             return currentRange; |  133             return currentRange; | 
|  161         m_loadingCustomFontForRanges.append(currentRange); |  134         m_loadingCustomFontForRanges.append(currentRange); | 
|  162     } |  135     } | 
|  163  |  136  | 
|  164     return next(hintList); |  137     return next(hintList); | 
|  165 } |  138 } | 
|  166  |  139  | 
|  167 const PassRefPtr<SimpleFontData> FontFallbackIterator::fallbackPriorityFont( |  | 
|  168     UChar32 hint) |  | 
|  169 { |  | 
|  170     return FontCache::fontCache()->fallbackFontForCharacter( |  | 
|  171         m_fontDescription, |  | 
|  172         hint, |  | 
|  173         m_fontFallbackList->primarySimpleFontData(m_fontDescription), |  | 
|  174         m_fontFallbackPriority); |  | 
|  175 } |  | 
|  176  |  | 
|  177 const PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint(U
     Char32 hint) |  140 const PassRefPtr<SimpleFontData> FontFallbackIterator::uniqueSystemFontForHint(U
     Char32 hint) | 
|  178 { |  141 { | 
|  179     FontCache* fontCache = FontCache::fontCache(); |  142     FontCache* fontCache = FontCache::fontCache(); | 
|  180  |  143  | 
|  181     // When we're asked for a fallback for the same characters again, we give up |  144     // When we're asked for a fallback for the same characters again, we give up | 
|  182     // because the shaper must have previously tried shaping with the font |  145     // because the shaper must have previously tried shaping with the font | 
|  183     // already. |  146     // already. | 
|  184     if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { |  147     if (m_visitedSystemFonts.find(hint) != m_visitedSystemFonts.end()) { | 
|  185         return nullptr; |  148         return nullptr; | 
|  186     } |  149     } | 
|  187  |  150  | 
|  188     RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
     fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
     on)); |  151     RefPtr<SimpleFontData> fallbackFont = fontCache->fallbackFontForCharacter(m_
     fontDescription, hint, m_fontFallbackList->primarySimpleFontData(m_fontDescripti
     on)); | 
|  189  |  152  | 
|  190     return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; |  153     return m_visitedSystemFonts.add(hint, fallbackFont).storedValue->value; | 
|  191 } |  154 } | 
|  192  |  155  | 
|  193 } // namespace blink |  156 } // namespace blink | 
| OLD | NEW |