Data URL fonts split in the middle of an alphabet cause random letters to disappear
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Jan 2018 00:45:26 +0000 (00:45 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Jan 2018 00:45:26 +0000 (00:45 +0000)
commit233c51f27e1de08a866a2e3b7521ce0b96b05f6b
tree809eca1a802748088854f78a60e223a8a45a975a
parent0de4f948ab669cdd87d36b50e76b74eeba138a85
Data URL fonts split in the middle of an alphabet cause random letters to disappear
https://bugs.webkit.org/show_bug.cgi?id=175845
<rdar://problem/33996578>

Reviewed by Brent Fulgham.

Source/WebCore:

It is fairly common practice for a font foundry to split a font up into two files such that a semi-random
half of the alphabet is present in one of the files, and the other half is present in the other file. This
practice involves representing the files as data URLs, so as to minimize the time it takes to load them.

Because resource loading is asynchronous (even for data URLs), it is possible today to get a paint after
the first file is loaded but before the second file is loaded. Indeed, because of the way font fallback
works, we will never start loading the second file until a layout has occurred with the first font.

Because a site usually only uses this pattern for a handful of fonts, and I've never seen this pattern
being used for CJK fonts, it isn't very expensive to opportunistically decode these data URLs eagerly.
Using this method doesn't actually guarantee that the two fonts will load in between successive paints,
but it at least makes this much more likely. This patch implements this strategy, along with a size
threshold to make sure that we won't decode any super large data URLs when it isn't necessary.

Test: fast/text/font-load-data-partitioned-alphabet.html

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::opportunisticallyStartFontDataURLLoading):
* css/CSSFontFace.h:
* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::opportunisticallyStartFontDataURLLoading):
* css/CSSFontFaceSource.h:
* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::opportunisticallyStartFontDataURLLoading):
* css/CSSFontSelector.h:
* platform/graphics/FontCascadeFonts.cpp:
(WebCore::opportunisticallyStartFontDataURLLoading):
(WebCore::FontCascadeFonts::glyphDataForVariant):
* platform/graphics/FontSelector.h:

LayoutTests:

Make sure that the requests for both fonts are sent before either of the responses are received.

* fast/text/font-load-data-partitioned-alphabet-expected.txt: Added.
* fast/text/font-load-data-partitioned-alphabet.html: Added.
* platform/mac-wk1/fast/text/font-load-data-partitioned-alphabet-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226930 268f45cc-cd09-0410-ab3c-d52691b4dbfc
13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text/font-load-data-partitioned-alphabet-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/font-load-data-partitioned-alphabet.html [new file with mode: 0644]
LayoutTests/platform/mac-wk1/fast/text/font-load-data-partitioned-alphabet-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontFace.cpp
Source/WebCore/css/CSSFontFace.h
Source/WebCore/css/CSSFontFaceSource.cpp
Source/WebCore/css/CSSFontFaceSource.h
Source/WebCore/css/CSSFontSelector.cpp
Source/WebCore/css/CSSFontSelector.h
Source/WebCore/platform/graphics/FontCascadeFonts.cpp
Source/WebCore/platform/graphics/FontSelector.h