12016-01-26 Myles C. Maxfield <mmaxfield@apple.com>
2
3 Modularize CSSFontFaceSource
4 https://bugs.webkit.org/show_bug.cgi?id=153414
5
6 Reviewed by NOBODY (OOPS!).
7
8 CSSFontFaceSource has a few supported use cases:
9 - Downloading remote fonts
10 - Downloading remote SVG fonts and converting them
11 - Downloading remote SVG fonts without converting them (Only for ports which haven't enabled the SVG -> OTF converter)
12 - Local fonts
13 - In-document SVG fonts and converting them
14 - In-document SVG fonts without converting them (Only for ports which haven't enabled the SVG -> OTF converter)
15
16 In addition, the CSS Font Loading spec adds another use case:
17 - A font where the backing bytes are provided by JavaScript (in an ArrayBuffer). I call this "immediate data."
18
19 All of these use cases have their own needs and requirements:
20 - Downloading fonts requires a URL and associated loading infrastructure
21 - Converting fonts requires the SVG -> OTF Converter
22 - Local fonts require a family name string to look up
23 - Immediate fonts require an array buffer to hold the bytes
24 - In-document fonts require a reference to an SVGFontElement
25
26 Previously, CSSFontFaceSource supported all of these use cases. Given that each use case has its own data requirements,
27 along with the fact that these requirements are known at object creation time, this is a great opportunity for subclassing.
28
29 There is an added benefit that, because there is a single base class for FontFaceSource, it has a uniform API, and changes
30 to the object can be deliberately and specifically tracked as explicit state changes. This makes the mapping to the CSS Font
31 Loading spec's "status" object much easier to understand.
32
33 This patch migrates all these use cases to the following heirarchy of classes:
34 - FontFaceSource
35 - LocalFontFaceSource
36 - InDocumentSVGFontFaceSource (when the SVG converter is not enabled; otherwise, this class does not exist)
37 - ByteBasedFontFaceSource
38 - ImmediateFontFaceSource
39 - InDocumentSVGFontFaceSource (when the SVG converter is enabled; otherwise, this class does not exist)
40 - RemoteFontFaceSource
41 - DeprecatedRemoteSVGFontFaceSource (Only used when the SVG converter is not enabled; otherwise,
42 ByteBasedFontFaceSource handles this case)
43
44 FontFaceSource is the base class, and is modelled as a state machine. The state diagram looks like this:
45 => Succeeded
46 //
47 Pending => Loading
48 \\
49 => Failed
50
51 Note that in this model, there is no distinction between a download failure, encoding failure, conversion failure, or any
52 other kind of failure. This is a feature.
53
54 FontFaceSource exposes two API functions:
55 - load() can be called when in the Pending state, and will take you to any of the downstream states.
56 - font() can be called when in the Succeeded state only. This function will try to create a Font object, but it may
57 still fail (even though we're in the Succeeded state). This means that, even if you're in the Succeeded state, you
58 aren't guaranteed to be able to create a Font.
59
60 FontFaceSources are owned by a FontFace, and FontFaceSources maintain a raw pointer to their owner. Fonts internally handle
61 the transition from the Loading to Succeeded / Failed state (possibly asynchronously, in the case of RemoteFontFaceSource).
62 If any state transition occurred asynchronously, the owning FontFace has a kick() method which simply notifies it that something
63 happened. It is then up to the FontFace to figure out what happened (since the FontFaceSource could be in eiter the Succeeded
64 or Failed state).
65
66 A possible future implementation of font downloading timeouts fits this model well, by adding a new state between Loading and
67 Succeeded / Failed.
68
69 FontFaceSource (the base class) also handles caching the result of the font() function. This is elegant because the result of
70 this function should be cached for all the subclasses.
71
72 No new tests because there is no behavior change.
73
74 * CMakeLists.txt: Add all the new files.
75 * WebCore.vcxproj/WebCore.vcxproj: Ditto.
76 * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
77 * WebCore.xcodeproj/project.pbxproj: Ditto.
78 * css/ByteBasedFontFaceSource.cpp: Added. This class handles the following things:
79 a) Calling the SVG -> OTF font converter on bytes that we have received
80 b) Transcodint WOFF fonts to TTF/OTF (on ports which require this)
81 b) Interacting with FontCustomPlatformData in order to create the real underlying platform font object which represents
82 the downloaded bytes
83 (WebCore::ByteBasedFontFaceSource::ByteBasedFontFaceSource):
84 (WebCore::ByteBasedFontFaceSource::getSVGFontById): Used for performing SVG -> OTF font conversion
85 (WebCore::ByteBasedFontFaceSource::bufferProvided): Subclasses call this function when they have their buffer of bytes. This
86 function performs as much processing as possible on that buffer (now, as opposed to later, so we can enter the failure state
87 early).
88 (WebCore::ByteBasedFontFaceSource::createFont): Use the FontCustomPlatformData.
89 * css/ByteBasedFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
90 * css/CSSAllInOne.cpp: Add all the new files.
91 * css/CSSFontFace.cpp: Update to use the new API of FontFaceSource.
92 (WebCore::CSSFontFace::allSourcesHaveFailed):
93 (WebCore::CSSFontFace::addSource):
94 (WebCore::CSSFontFace::kick):
95 (WebCore::CSSFontFace::font): Pump the state machines of the underlying FontFaceSources.
96 (WebCore::CSSFontFace::isValid): Deleted.
97 (WebCore::CSSFontFace::fontLoaded): Deleted.
98 (WebCore::CSSFontFace::notifyFontLoader): Deleted.
99 (WebCore::CSSFontFace::notifyLoadingDone): Deleted.
100 (WebCore::CSSFontFace::hasSVGFontFaceSource): Deleted.
101 * css/CSSFontFace.h: Update to use the new API of FontFaceSource.
102 (WebCore::CSSFontFace::create):
103 (WebCore::CSSFontFace::CSSFontFace):
104 (WebCore::CSSFontFace::loadState): Deleted.
105 * css/CSSFontFaceSource.cpp: Removed. Out with the old, in with the new
106 * css/CSSFontFaceSource.h: Removed.
107 * css/CSSFontSelector.cpp: Update to create the new FontFaceSource objects.
108 (WebCore::createFontFace):
109 (WebCore::registerLocalFontFacesForFamily):
110 (WebCore::CSSFontSelector::addFontFaceRule):
111 * css/CSSSegmentedFontFace.cpp:
112 (WebCore::CSSSegmentedFontFace::fontRanges): Update to new API.
113 * css/DeprecatedInDocumentSVGFontFaceSource.cpp: Copied from Source/WebCore/loader/cache/CachedFontClient.h. Used on platforms
114 which don't use the SVG -> OTF font converter.
115 (WebCore::InDocumentSVGFontFaceSource::InDocumentSVGFontFaceSource):
116 (WebCore::InDocumentSVGFontFaceSource::initiateLoad):
117 (WebCore::InDocumentSVGFontFaceSource::createFont):
118 * css/DeprecatedInDocumentSVGFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h. Used on platforms
119 which don't use the SVG -> OTF font converter.
120 * css/DeprecatedRemoteSVGFontFaceSource.cpp: Added.
121 (WebCore::DeprecatedRemoteSVGFontFaceSource::DeprecatedRemoteSVGFontFaceSource):
122 (WebCore::DeprecatedRemoteSVGFontFaceSource::bufferProvided):
123 (WebCore::DeprecatedRemoteSVGFontFaceSource::createFont):
124 * css/DeprecatedRemoteSVGFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
125 * css/FontFaceSource.cpp: Added. Base class, explained above. Handles caching.
126 (WebCore::FontFaceSource::HashKey::HashKey):
127 (WebCore::FontFaceSource::HashKey::isHashTableDeletedValue):
128 (WebCore::FontFaceSource::HashKey::operator==):
129 (WebCore::FontFaceSource::HashKey::operator!=):
130 (WebCore::FontFaceSource::HashKey::hash):
131 (WebCore::FontFaceSource::HashKey::equal):
132 (WebCore::FontFaceSource::FontFaceSource):
133 (WebCore::FontFaceSource::load):
134 (WebCore::FontFaceSource::font):
135 * css/FontFaceSource.h: Added.
136 (WebCore::FontFaceSource::~FontFaceSource):
137 (WebCore::FontFaceSource::state):
138 (WebCore::FontFaceSource::owner):
139 (WebCore::FontFaceSource::setState):
140 (WebCore::FontFaceSource::shouldCache):
141 * css/FontLoader.cpp:
142 * css/ImmediateFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h. Supporting the new use case in the
143 CSS FontLoading spec.
144 * css/InDocumentSVGFontFaceSource.cpp: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
145 (WebCore::InDocumentSVGFontFaceSource::InDocumentSVGFontFaceSource):
146 (WebCore::InDocumentSVGFontFaceSource::initiateLoad):
147 * css/InDocumentSVGFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
148 * css/LocalFontFaceSource.cpp: Copied from Source/WebCore/loader/cache/CachedFontClient.h. Represents local(Helvetica) or something
149 like that.
150 (WebCore::LocalFontFaceSource::LocalFontFaceSource):
151 (WebCore::LocalFontFaceSource::initiateLoad):
152 (WebCore::LocalFontFaceSource::createFont):
153 * css/LocalFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
154 * css/RemoteFontFaceSource.cpp: Added. Uses the existing CachedResourceLoader infrastructure, but simply puts the new FontFaceSource
155 API on top of it. Kicks the owner if something asynchronous happened.
156 (WebCore::RemoteFontFaceSource::RemoteFontFaceSource):
157 (WebCore::RemoteFontFaceSource::~RemoteFontFaceSource):
158 (WebCore::RemoteFontFaceSource::initiateLoad):
159 (WebCore::RemoteFontFaceSource::fontLoaded):
160 * css/RemoteFontFaceSource.h: Copied from Source/WebCore/loader/cache/CachedFontClient.h.
161 * loader/cache/CachedFont.cpp: Update to new API.
162 (WebCore::CachedFont::didAddClient):
163 (WebCore::CachedFont::checkNotify):
164 * loader/cache/CachedFont.h: Ditto.
165 (WebCore::CachedFont::setHasCreatedFontDataWrappingResource):
166 * loader/cache/CachedFontClient.h: Ditto.
167 (WebCore::CachedFontClient::fontLoaded):
168 * platform/graphics/FontCache.h: Cleanup.
169 (WebCore::FontDescriptionKey::makeFlagsKey):
170 * platform/graphics/mac/FontCustomPlatformData.cpp: Helpful comment.
171 (WebCore::FontCustomPlatformData::fontPlatformData):
172 * platform/text/TextFlags.h: Cleanup.
173 (WebCore::FontVariantSettings::operator==):
174 (WebCore::FontVariantSettings::uniqueValue):
175 (WebCore::FontVariantSettings::hash):
176 * svg/SVGFontData.h: Updating comment.
177