1 | /*
|
---|
2 | * Copyright (C) 2007-2021 Apple Inc. All rights reserved.
|
---|
3 | *
|
---|
4 | * Redistribution and use in source and binary forms, with or without
|
---|
5 | * modification, are permitted provided that the following conditions
|
---|
6 | * are met:
|
---|
7 | * 1. Redistributions of source code must retain the above copyright
|
---|
8 | * notice, this list of conditions and the following disclaimer.
|
---|
9 | * 2. Redistributions in binary form must reproduce the above copyright
|
---|
10 | * notice, this list of conditions and the following disclaimer in the
|
---|
11 | * documentation and/or other materials provided with the distribution.
|
---|
12 | *
|
---|
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
---|
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
---|
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
---|
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
---|
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
---|
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
---|
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
---|
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
---|
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
---|
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
24 | */
|
---|
25 |
|
---|
26 | #pragma once
|
---|
27 |
|
---|
28 | #include "FontSelectionValueInlines.h"
|
---|
29 | #include "FontTaggedSettings.h"
|
---|
30 | #include "Settings.h"
|
---|
31 | #include "StyleRule.h"
|
---|
32 | #include "TextFlags.h"
|
---|
33 | #include <memory>
|
---|
34 | #include <wtf/Forward.h>
|
---|
35 | #include <wtf/HashSet.h>
|
---|
36 | #include <wtf/WeakPtr.h>
|
---|
37 |
|
---|
38 | namespace JSC {
|
---|
39 | class CallFrame;
|
---|
40 | }
|
---|
41 |
|
---|
42 | namespace WebCore {
|
---|
43 |
|
---|
44 | class CSSFontFaceSource;
|
---|
45 | class CSSFontSelector;
|
---|
46 | class CSSSegmentedFontFace;
|
---|
47 | class CSSValue;
|
---|
48 | class CSSValueList;
|
---|
49 | class FontCreationContext;
|
---|
50 | class FontDescription;
|
---|
51 | class Font;
|
---|
52 | class FontFace;
|
---|
53 | class ScriptExecutionContext;
|
---|
54 | enum class ExternalResourceDownloadPolicy;
|
---|
55 |
|
---|
56 | DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSFontFace);
|
---|
57 | class CSSFontFace final : public RefCounted<CSSFontFace> {
|
---|
58 | WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSFontFace);
|
---|
59 | public:
|
---|
60 | static Ref<CSSFontFace> create(CSSFontSelector&, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false);
|
---|
61 | virtual ~CSSFontFace();
|
---|
62 |
|
---|
63 | // FIXME: These functions don't need to have boolean return values.
|
---|
64 | // Callers only call this with known-valid CSS values.
|
---|
65 | bool setFamilies(CSSValue&);
|
---|
66 | void setStyle(CSSValue&);
|
---|
67 | void setWeight(CSSValue&);
|
---|
68 | void setStretch(CSSValue&);
|
---|
69 | bool setUnicodeRange(CSSValue&);
|
---|
70 | void setFeatureSettings(CSSValue&);
|
---|
71 | void setLoadingBehavior(CSSValue&);
|
---|
72 |
|
---|
73 | // Pending => Loading => TimedOut
|
---|
74 | // || \\ // ||
|
---|
75 | // || \\ // ||
|
---|
76 | // || \\// ||
|
---|
77 | // || // ||
|
---|
78 | // || //\\ ||
|
---|
79 | // || // \\ ||
|
---|
80 | // \/ \/ \/ \/
|
---|
81 | // Success Failure
|
---|
82 | enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
|
---|
83 |
|
---|
84 | struct UnicodeRange;
|
---|
85 |
|
---|
86 | // Optional return values to represent default string for members of FontFace.h
|
---|
87 | const std::optional<CSSValueList*> families() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<CSSValueList*>>(m_families.get()); }
|
---|
88 | std::optional<FontSelectionRange> weight() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWeight()); }
|
---|
89 | std::optional<FontSelectionRange> stretch() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWidth()); }
|
---|
90 | std::optional<FontSelectionRange> italic() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeSlope()); }
|
---|
91 | std::optional<FontSelectionCapabilities> fontSelectionCapabilities() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionCapabilities>>(m_fontSelectionCapabilities.computeFontSelectionCapabilities()); }
|
---|
92 | const std::optional<Vector<UnicodeRange>> ranges() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<Vector<UnicodeRange>>>(m_ranges); }
|
---|
93 | const std::optional<FontFeatureSettings> featureSettings() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontFeatureSettings>>(m_featureSettings); }
|
---|
94 | std::optional<FontLoadingBehavior> loadingBehavior() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontLoadingBehavior>>(m_loadingBehavior); }
|
---|
95 | void setWeight(FontSelectionRange weight) { m_fontSelectionCapabilities.weight = weight; }
|
---|
96 | void setStretch(FontSelectionRange stretch) { m_fontSelectionCapabilities.width = stretch; }
|
---|
97 | void setStyle(FontSelectionRange italic) { m_fontSelectionCapabilities.slope = italic; }
|
---|
98 | void setFontSelectionCapabilities(FontSelectionCapabilities capabilities) { m_fontSelectionCapabilities = capabilities; }
|
---|
99 | bool isLocalFallback() const { return m_isLocalFallback; }
|
---|
100 | Status status() const { return m_status; }
|
---|
101 | StyleRuleFontFace* cssConnection() const { return m_cssConnection.get(); }
|
---|
102 |
|
---|
103 | class Client;
|
---|
104 | void addClient(Client&);
|
---|
105 | void removeClient(Client&);
|
---|
106 |
|
---|
107 | bool computeFailureState() const;
|
---|
108 |
|
---|
109 | void opportunisticallyStartFontDataURLLoading();
|
---|
110 |
|
---|
111 | void adoptSource(std::unique_ptr<CSSFontFaceSource>&&);
|
---|
112 | void sourcesPopulated() { m_sourcesPopulated = true; }
|
---|
113 |
|
---|
114 | void fontLoaded(CSSFontFaceSource&);
|
---|
115 |
|
---|
116 | void load();
|
---|
117 |
|
---|
118 | RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, ExternalResourceDownloadPolicy, const FontPaletteValues&);
|
---|
119 |
|
---|
120 | static void appendSources(CSSFontFace&, CSSValueList&, ScriptExecutionContext*, bool isInitiatingElementInUserAgentShadowTree);
|
---|
121 |
|
---|
122 | class Client {
|
---|
123 | public:
|
---|
124 | virtual ~Client() = default;
|
---|
125 | virtual void fontLoaded(CSSFontFace&) { }
|
---|
126 | virtual void fontStateChanged(CSSFontFace&, Status /*oldState*/, Status /*newState*/) { }
|
---|
127 | virtual void fontPropertyChanged(CSSFontFace&, CSSValueList* /*oldFamilies*/ = nullptr) { }
|
---|
128 | virtual void updateStyleIfNeeded(CSSFontFace&) { }
|
---|
129 | virtual void ref() = 0;
|
---|
130 | virtual void deref() = 0;
|
---|
131 | };
|
---|
132 |
|
---|
133 | struct UnicodeRange {
|
---|
134 | UChar32 from;
|
---|
135 | UChar32 to;
|
---|
136 | bool operator==(const UnicodeRange& other) const { return from == other.from && to == other.to; }
|
---|
137 | bool operator!=(const UnicodeRange& other) const { return !(*this == other); }
|
---|
138 | };
|
---|
139 |
|
---|
140 | bool rangesMatchCodePoint(UChar32) const;
|
---|
141 |
|
---|
142 | // We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
|
---|
143 | Ref<FontFace> wrapper(ScriptExecutionContext*);
|
---|
144 | void setWrapper(FontFace&);
|
---|
145 | FontFace* existingWrapper();
|
---|
146 |
|
---|
147 | struct FontLoadTiming {
|
---|
148 | Seconds blockPeriod;
|
---|
149 | Seconds swapPeriod;
|
---|
150 | };
|
---|
151 | FontLoadTiming fontLoadTiming() const;
|
---|
152 | bool shouldIgnoreFontLoadCompletions() const { return m_shouldIgnoreFontLoadCompletions; }
|
---|
153 |
|
---|
154 | bool purgeable() const;
|
---|
155 |
|
---|
156 | AllowUserInstalledFonts allowUserInstalledFonts() const { return m_allowUserInstalledFonts; }
|
---|
157 |
|
---|
158 | void updateStyleIfNeeded();
|
---|
159 |
|
---|
160 | bool hasSVGFontFaceSource() const;
|
---|
161 | void setErrorState();
|
---|
162 |
|
---|
163 | private:
|
---|
164 | CSSFontFace(const Settings::Values*, StyleRuleFontFace*, FontFace*, bool isLocalFallback);
|
---|
165 |
|
---|
166 | size_t pump(ExternalResourceDownloadPolicy);
|
---|
167 | void setStatus(Status);
|
---|
168 | void notifyClientsOfFontPropertyChange();
|
---|
169 |
|
---|
170 | void initializeWrapper();
|
---|
171 |
|
---|
172 | void fontLoadEventOccurred();
|
---|
173 | void timeoutFired();
|
---|
174 |
|
---|
175 | Document* document();
|
---|
176 |
|
---|
177 | RefPtr<CSSValueList> m_families;
|
---|
178 | Vector<UnicodeRange> m_ranges;
|
---|
179 |
|
---|
180 | FontFeatureSettings m_featureSettings;
|
---|
181 | FontLoadingBehavior m_loadingBehavior { FontLoadingBehavior::Auto };
|
---|
182 |
|
---|
183 | Vector<std::unique_ptr<CSSFontFaceSource>, 0, CrashOnOverflow, 0> m_sources;
|
---|
184 | RefPtr<StyleRuleFontFace> m_cssConnection;
|
---|
185 | HashSet<Client*> m_clients;
|
---|
186 | WeakPtr<FontFace> m_wrapper;
|
---|
187 | FontSelectionSpecifiedCapabilities m_fontSelectionCapabilities;
|
---|
188 |
|
---|
189 | Status m_status { Status::Pending };
|
---|
190 | bool m_isLocalFallback { false };
|
---|
191 | bool m_sourcesPopulated { false };
|
---|
192 | bool m_mayBePurged { true };
|
---|
193 | bool m_shouldIgnoreFontLoadCompletions { false };
|
---|
194 | FontLoadTimingOverride m_fontLoadTimingOverride { FontLoadTimingOverride::None };
|
---|
195 | AllowUserInstalledFonts m_allowUserInstalledFonts { AllowUserInstalledFonts::Yes };
|
---|
196 |
|
---|
197 | Timer m_timeoutTimer;
|
---|
198 | };
|
---|
199 |
|
---|
200 | }
|
---|