Changeset 200601 in webkit
- Timestamp:
- May 9, 2016, 5:13:01 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r200590 r200601 1 2016-05-09 Myles C. Maxfield <mmaxfield@apple.com> 2 3 Web Font is downloaded even when all the characters in the document are outside its unicode-range 4 https://bugs.webkit.org/show_bug.cgi?id=42154 5 <rdar://problem/17779042> 6 7 Reviewed by Darin Adler. 8 9 * fast/text/unicode-range-download-expected.txt: Added. 10 * fast/text/unicode-range-download.html: Added. 11 * fast/text/resources/unicode-range-download-Ahem.otf: Added. 12 * fast/text/resources/unicode-range-download-Ahem.ttf: Added. 13 * fast/text/resources/unicode-range-download-Ahem.woff: Added. 14 * imported/blink/svg/custom/resources/graffiti.svg: Added. 15 imported/blink/svg/custom/svg-fonts-unloaded-segment.html requires this font. 16 1 17 2016-05-09 Simon Fraser <simon.fraser@apple.com> 2 18 -
trunk/Source/WebCore/ChangeLog
r200598 r200601 1 2016-05-09 Myles C. Maxfield <mmaxfield@apple.com> 2 3 Web Font is downloaded even when all the characters in the document are outside its unicode-range 4 https://bugs.webkit.org/show_bug.cgi?id=42154 5 <rdar://problem/17779042> 6 7 Reviewed by Darin Adler. 8 9 Fonts are requested in two stages: 10 - For a given font family, all the relevant @font-face rules are consulted. We build up a 11 mapping of unicode-range -> Font object. This result is cached. 12 - Then, when we have the mapping, we look up the character we are trying to render to 13 find the appropriate Font object. 14 15 However, we are not supposed to create any Font objects (because that causes a download to 16 be triggered) until we consult with the character we're trying to render. Therefore, this 17 patch swaps out the Font objects with a FontAccessor. This FontAccessor is essentially a 18 lazily-created Font. When step 2 starts looking up the appropriate character, the 19 FontAccessor will be asked to start the download. 20 21 Test: fast/text/unicode-range-download.html 22 23 * css/CSSFontFace.cpp: 24 (WebCore::CSSFontFace::removeClient): 25 as a client from all its CSSFontFaces. 26 * css/CSSFontFaceSet.cpp: 27 (WebCore::CSSFontFaceSet::clear): Clearing the CSSFontFaceSet needs to remove itself as a 28 client from all its CSSFontFaces. 29 * css/CSSSegmentedFontFace.cpp: 30 (WebCore::CSSFontAccessor::create): The lazy Font object. 31 (WebCore::CSSFontAccessor::CSSFontAccessor): Ditto. 32 (WebCore::appendFontWithInvalidUnicodeRangeIfLoading): Appends a FontAccessor. 33 (WebCore::CSSSegmentedFontFace::fontRanges): Create the FontAccessor and use it instead. 34 * platform/graphics/FontCascadeFonts.cpp: 35 (WebCore::FontCascadeFonts::determinePitch): Use the fontForFirstRange() convenience 36 function. 37 (WebCore::glyphPageFromFontRanges): font() may now return nullptr. Update this function to 38 handle that. 39 * platform/graphics/FontRanges.cpp: 40 (WebCore::FontRanges::Range::font): Trigger the lazy initialization. 41 (WebCore::TrivialFontAccessor::create): Used in the case where there is only one font in 42 the Ranges object and it has a full unicode-range. 43 (WebCore::TrivialFontAccessor::TrivialFontAccessor): 44 (WebCore::FontRanges::FontRanges): Use TrivialFontAccessor. 45 (WebCore::FontRanges::glyphDataForCharacter): font() may now return nullptr. Update this 46 function to handle that. This is where the magic happens: this is where we trigger 47 downloads only if the character falls within the unicode-range. 48 (WebCore::FontRanges::fontForFirstRange): Add ASSERT. 49 (WebCore::FontRanges::isLoading): Update to use the new FontAccessor. 50 * platform/graphics/FontRanges.h: Ditto. 51 (WebCore::FontRanges::Range::Range): 52 (WebCore::FontRanges::Range::fontAccessor): 53 (WebCore::FontRanges::appendRange): 54 (WebCore::FontRanges::Range::font): Deleted. 55 * platform/graphics/FontSelector.h: The virtual base class of FontAccessor. This is 56 necessary because it must be shared between platform code and non-platform code. 57 (WebCore::FontAccessor::~FontAccessor): 58 1 59 2016-05-09 Brady Eidson <beidson@apple.com> 2 60 -
trunk/Source/WebCore/css/CSSFontFaceSet.cpp
r197804 r200601 239 239 void CSSFontFaceSet::clear() 240 240 { 241 for (auto& face : m_faces) 242 face->removeClient(*this); 241 243 m_faces.clear(); 242 244 m_facesLookupTable.clear(); -
trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp
r200547 r200601 60 60 } 61 61 62 static void appendFontWithInvalidUnicodeRangeIfLoading(FontRanges& ranges, Ref<Font>&& font, const Vector<CSSFontFace::UnicodeRange>& unicodeRanges) 62 class CSSFontAccessor final : public FontAccessor { 63 public: 64 static Ref<CSSFontAccessor> create(CSSFontFace& fontFace, const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) 65 { 66 return adoptRef(*new CSSFontAccessor(fontFace, fontDescription, syntheticBold, syntheticItalic)); 67 } 68 69 const Font* font() const final 70 { 71 if (!m_result) 72 m_result = m_fontFace->font(m_fontDescription, m_syntheticBold, m_syntheticItalic); 73 return m_result.value().get(); 74 } 75 76 private: 77 CSSFontAccessor(CSSFontFace& fontFace, const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) 78 : m_fontFace(fontFace) 79 , m_fontDescription(fontDescription) 80 , m_syntheticBold(syntheticBold) 81 , m_syntheticItalic(syntheticItalic) 82 { 83 } 84 85 bool isLoading() const final 86 { 87 return m_result && m_result.value()->isLoading(); 88 } 89 90 mutable Optional<RefPtr<Font>> m_result; // Caches nullptr too 91 mutable Ref<CSSFontFace> m_fontFace; 92 FontDescription m_fontDescription; 93 bool m_syntheticBold; 94 bool m_syntheticItalic; 95 }; 96 97 static void appendFontWithInvalidUnicodeRangeIfLoading(FontRanges& ranges, Ref<FontAccessor>&& fontAccessor, const Vector<CSSFontFace::UnicodeRange>& unicodeRanges) 63 98 { 64 if (font ->isLoading()) {65 ranges.appendRange({ 0, 0, WTFMove(font ) });99 if (fontAccessor->isLoading()) { 100 ranges.appendRange({ 0, 0, WTFMove(fontAccessor) }); 66 101 return; 67 102 } 68 103 69 104 if (unicodeRanges.isEmpty()) { 70 ranges.appendRange({ 0, 0x7FFFFFFF, WTFMove(font ) });105 ranges.appendRange({ 0, 0x7FFFFFFF, WTFMove(fontAccessor) }); 71 106 return; 72 107 } 73 108 74 109 for (auto& range : unicodeRanges) 75 ranges.appendRange({ range.from, range.to, font .copyRef() });110 ranges.appendRange({ range.from, range.to, fontAccessor.copyRef() }); 76 111 } 77 112 … … 81 116 82 117 auto addResult = m_cache.add(FontDescriptionKey(fontDescription), FontRanges()); 83 auto& fontRanges= addResult.iterator->value;118 auto& result = addResult.iterator->value; 84 119 85 120 if (addResult.isNewEntry) { … … 92 127 bool syntheticItalic = (fontDescription.fontSynthesis() & FontSynthesisStyle) && !(traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask); 93 128 94 if (RefPtr<Font> faceFont = face->font(fontDescription, syntheticBold, syntheticItalic)) 95 appendFontWithInvalidUnicodeRangeIfLoading(fontRanges, faceFont.releaseNonNull(), face->ranges()); 129 // This doesn't trigger an unnecessary download because every element styled with this family will need font metrics in order to run layout. 130 // Metrics used for layout come from FontRanges::fontForFirstRange(), which assumes that the first font is non-null. 131 // We're kicking off this necessary first download now. 132 auto fontAccessor = CSSFontAccessor::create(face, fontDescription, syntheticBold, syntheticItalic); 133 if (result.isNull() && !fontAccessor->font()) 134 continue; 135 appendFontWithInvalidUnicodeRangeIfLoading(result, WTFMove(fontAccessor), face->ranges()); 96 136 } 97 137 } 98 return fontRanges;138 return result; 99 139 } 100 140 -
trunk/Source/WebCore/platform/graphics/FontCascadeFonts.cpp
r194496 r200601 123 123 unsigned numRanges = primaryRanges.size(); 124 124 if (numRanges == 1) 125 m_pitch = primaryRanges. rangeAt(0).font().pitch();125 m_pitch = primaryRanges.fontForFirstRange().pitch(); 126 126 else 127 127 m_pitch = VariablePitch; … … 411 411 if (range.to()) { 412 412 if (range.from() <= pageRangeFrom && pageRangeTo <= range.to()) 413 font = &range.font();413 font = range.font(); 414 414 break; 415 415 } 416 416 } 417 if (!font) 418 return nullptr; 419 420 if (font->platformData().orientation() == Vertical) 417 if (!font || font->platformData().orientation() == Vertical) 421 418 return nullptr; 422 419 -
trunk/Source/WebCore/platform/graphics/FontRanges.cpp
r186827 r200601 28 28 29 29 #include "Font.h" 30 #include "FontSelector.h" 30 31 #include <wtf/Assertions.h> 31 32 #include <wtf/text/WTFString.h> … … 33 34 namespace WebCore { 34 35 36 const Font* FontRanges::Range::font() const 37 { 38 return m_fontAccessor->font(); 39 } 40 35 41 FontRanges::FontRanges() 36 42 { 37 43 } 38 44 45 class TrivialFontAccessor final : public FontAccessor { 46 public: 47 static Ref<TrivialFontAccessor> create(Ref<Font>&& font) 48 { 49 return adoptRef(*new TrivialFontAccessor(WTFMove(font))); 50 } 51 52 private: 53 TrivialFontAccessor(RefPtr<Font>&& font) 54 : m_font(WTFMove(font)) 55 { 56 } 57 58 const Font* font() const final 59 { 60 return m_font.get(); 61 } 62 63 bool isLoading() const final 64 { 65 return m_font->isLoading(); 66 } 67 68 RefPtr<Font> m_font; 69 }; 70 39 71 FontRanges::FontRanges(RefPtr<Font>&& font) 40 72 { 41 73 if (font) 42 m_ranges.append(Range { 0, 0x7FFFFFFF, font.releaseNonNull() });74 m_ranges.append(Range { 0, 0x7FFFFFFF, TrivialFontAccessor::create(font.releaseNonNull()) }); 43 75 } 44 76 … … 51 83 for (auto& range : m_ranges) { 52 84 if (range.from() <= character && character <= range.to()) { 53 auto glyphData = range.font().glyphDataForCharacter(character); 54 if (glyphData.glyph) 55 return glyphData; 85 if (auto* font = range.font()) { 86 auto glyphData = font->glyphDataForCharacter(character); 87 if (glyphData.glyph) 88 return glyphData; 89 } 56 90 } 57 91 } … … 66 100 const Font& FontRanges::fontForFirstRange() const 67 101 { 68 return m_ranges[0].font(); 102 auto* font = m_ranges[0].font(); 103 ASSERT(font); 104 return *font; 69 105 } 70 106 … … 72 108 { 73 109 for (auto& range : m_ranges) { 74 if (range.font ().isLoading())110 if (range.fontAccessor().isLoading()) 75 111 return true; 76 112 } -
trunk/Source/WebCore/platform/graphics/FontRanges.h
r194496 r200601 33 33 namespace WebCore { 34 34 35 class FontAccessor; 36 35 37 class FontRanges { 36 38 public: 37 39 struct Range { 38 Range(UChar32 from, UChar32 to, Ref<Font >&& font)40 Range(UChar32 from, UChar32 to, Ref<FontAccessor>&& fontAccessor) 39 41 : m_from(from) 40 42 , m_to(to) 41 , m_font (WTFMove(font))43 , m_fontAccessor(WTFMove(fontAccessor)) 42 44 { 43 45 } 44 46 47 Range(const Range& range) 48 : m_from(range.m_from) 49 , m_to(range.m_to) 50 , m_fontAccessor(range.m_fontAccessor.copyRef()) 51 { 52 } 53 54 Range(Range&&) = default; 55 Range& operator=(const Range&) = delete; 56 Range& operator=(Range&&) = default; 57 45 58 UChar32 from() const { return m_from; } 46 59 UChar32 to() const { return m_to; } 47 const Font& font() const { return *m_font; } 60 const Font* font() const; 61 const FontAccessor& fontAccessor() const { return m_fontAccessor; } 48 62 49 63 private: 50 64 UChar32 m_from; 51 65 UChar32 m_to; 52 Ref Ptr<Font> m_font;66 Ref<FontAccessor> m_fontAccessor; 53 67 }; 54 68 … … 57 71 ~FontRanges(); 58 72 73 FontRanges(const FontRanges&) = default; 74 FontRanges& operator=(FontRanges&&) = default; 75 59 76 bool isNull() const { return m_ranges.isEmpty(); } 60 77 61 void appendRange( const Range& range) { m_ranges.append(range); }78 void appendRange(Range&& range) { m_ranges.append(WTFMove(range)); } 62 79 unsigned size() const { return m_ranges.size(); } 63 80 const Range& rangeAt(unsigned i) const { return m_ranges[i]; } -
trunk/Source/WebCore/platform/graphics/FontSelector.h
r199722 r200601 37 37 class FontSelectorClient; 38 38 39 class FontAccessor : public RefCounted<FontAccessor> { 40 public: 41 virtual ~FontAccessor() { } 42 43 virtual const Font* font() const = 0; 44 virtual bool isLoading() const = 0; 45 }; 46 39 47 class FontSelector : public RefCounted<FontSelector> { 40 48 public:
Note:
See TracChangeset
for help on using the changeset viewer.