a39a926ff8b3b765028605419bdd0e8c7d7e5b18
[WebKit-https.git] / Source / WebCore / css / CSSFontFace.h
1 /*
2  * Copyright (C) 2007, 2008, 2016 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 "StyleRule.h"
31 #include "TextFlags.h"
32 #include "Timer.h"
33 #include <memory>
34 #include <wtf/Forward.h>
35 #include <wtf/HashSet.h>
36 #include <wtf/RefCounted.h>
37 #include <wtf/Vector.h>
38 #include <wtf/WeakPtr.h>
39
40 namespace JSC {
41 class ExecState;
42 }
43
44 namespace WebCore {
45
46 class CSSFontFaceSource;
47 class CSSFontSelector;
48 class CSSSegmentedFontFace;
49 class CSSValue;
50 class CSSValueList;
51 class Document;
52 class FontDescription;
53 class Font;
54 class FontFace;
55 enum class ExternalResourceDownloadPolicy;
56
57 class CSSFontFace final : public RefCounted<CSSFontFace> {
58 public:
59     static Ref<CSSFontFace> create(CSSFontSelector* fontSelector, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false)
60     {
61         return adoptRef(*new CSSFontFace(fontSelector, cssConnection, wrapper, isLocalFallback));
62     }
63     virtual ~CSSFontFace();
64
65     // FIXME: These functions don't need to have boolean return values.
66     // Callers only call this with known-valid CSS values.
67     bool setFamilies(CSSValue&);
68     void setStyle(CSSValue&);
69     void setWeight(CSSValue&);
70     void setStretch(CSSValue&);
71     bool setUnicodeRange(CSSValue&);
72     bool setVariantLigatures(CSSValue&);
73     bool setVariantPosition(CSSValue&);
74     bool setVariantCaps(CSSValue&);
75     bool setVariantNumeric(CSSValue&);
76     bool setVariantAlternates(CSSValue&);
77     bool setVariantEastAsian(CSSValue&);
78     void setFeatureSettings(CSSValue&);
79     void setLoadingBehavior(CSSValue&);
80
81     enum class Status : uint8_t;
82     struct UnicodeRange;
83     const CSSValueList* families() const { return m_families.get(); }
84     FontSelectionRange weight() const { return m_fontSelectionCapabilities.computeWeight(); }
85     FontSelectionRange stretch() const { return m_fontSelectionCapabilities.computeWidth(); }
86     FontSelectionRange italic() const { return m_fontSelectionCapabilities.computeSlope(); }
87     FontSelectionCapabilities fontSelectionCapabilities() const { return m_fontSelectionCapabilities.computeFontSelectionCapabilities(); }
88     const Vector<UnicodeRange>& ranges() const { return m_ranges; }
89     const FontFeatureSettings& featureSettings() const { return m_featureSettings; }
90     const FontVariantSettings& variantSettings() const { return m_variantSettings; }
91     FontLoadingBehavior loadingBehavior() const { return m_loadingBehavior; }
92     void setVariantSettings(const FontVariantSettings& variantSettings) { m_variantSettings = variantSettings; }
93     void setWeight(FontSelectionRange weight) { m_fontSelectionCapabilities.weight = weight; }
94     void setStretch(FontSelectionRange stretch) { m_fontSelectionCapabilities.width = stretch; }
95     void setStyle(FontSelectionRange italic) { m_fontSelectionCapabilities.slope = italic; }
96     void setFontSelectionCapabilities(FontSelectionCapabilities capabilities) { m_fontSelectionCapabilities = capabilities; }
97     bool isLocalFallback() const { return m_isLocalFallback; }
98     Status status() const { return m_status; }
99     StyleRuleFontFace* cssConnection() const { return m_cssConnection.get(); }
100
101     class Client;
102     void addClient(Client&);
103     void removeClient(Client&);
104
105     bool computeFailureState() const;
106
107     void opportunisticallyStartFontDataURLLoading(CSSFontSelector&);
108
109     void adoptSource(std::unique_ptr<CSSFontFaceSource>&&);
110     void sourcesPopulated() { m_sourcesPopulated = true; }
111
112     void fontLoaded(CSSFontFaceSource&);
113
114     void load();
115
116     RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, ExternalResourceDownloadPolicy);
117
118     static void appendSources(CSSFontFace&, CSSValueList&, Document*, bool isInitiatingElementInUserAgentShadowTree);
119
120     class Client {
121     public:
122         virtual ~Client() = default;
123         virtual void fontLoaded(CSSFontFace&) { }
124         virtual void fontStateChanged(CSSFontFace&, Status /*oldState*/, Status /*newState*/) { }
125         virtual void fontPropertyChanged(CSSFontFace&, CSSValueList* /*oldFamilies*/ = nullptr) { }
126         virtual void ref() = 0;
127         virtual void deref() = 0;
128     };
129
130     // Pending => Loading  => TimedOut
131     //              ||  \\    //  ||
132     //              ||   \\  //   ||
133     //              ||    \\//    ||
134     //              ||     //     ||
135     //              ||    //\\    ||
136     //              ||   //  \\   ||
137     //              \/  \/    \/  \/
138     //             Success    Failure
139     enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
140
141     struct UnicodeRange {
142         UChar32 from;
143         UChar32 to;
144         bool operator==(const UnicodeRange& other) const { return from == other.from && to == other.to; }
145         bool operator!=(const UnicodeRange& other) const { return !(*this == other); }
146     };
147
148     bool rangesMatchCodePoint(UChar32) const;
149
150     // We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
151     Ref<FontFace> wrapper();
152     void setWrapper(FontFace&);
153     FontFace* existingWrapper();
154
155     struct FontLoadTiming {
156         Seconds blockPeriod;
157         Seconds swapPeriod;
158     };
159     FontLoadTiming fontLoadTiming() const;
160     bool shouldIgnoreFontLoadCompletions() const;
161
162     bool purgeable() const;
163
164     AllowUserInstalledFonts allowUserInstalledFonts() const;
165
166     void updateStyleIfNeeded();
167
168 #if ENABLE(SVG_FONTS)
169     bool hasSVGFontFaceSource() const;
170 #endif
171
172 private:
173     CSSFontFace(CSSFontSelector*, StyleRuleFontFace*, FontFace*, bool isLocalFallback);
174
175     size_t pump(ExternalResourceDownloadPolicy);
176     void setStatus(Status);
177     void notifyClientsOfFontPropertyChange();
178
179     void initializeWrapper();
180
181     void fontLoadEventOccurred();
182     void timeoutFired();
183
184     RefPtr<CSSValueList> m_families;
185     Vector<UnicodeRange> m_ranges;
186
187     FontFeatureSettings m_featureSettings;
188     FontVariantSettings m_variantSettings;
189     FontLoadingBehavior m_loadingBehavior { FontLoadingBehavior::Auto };
190
191     Vector<std::unique_ptr<CSSFontFaceSource>, 0, CrashOnOverflow, 0> m_sources;
192     RefPtr<CSSFontSelector> m_fontSelector; // FIXME: https://bugs.webkit.org/show_bug.cgi?id=196437 There's a retain cycle: CSSFontSelector -> CSSFontFaceSet -> CSSFontFace -> CSSFontSelector
193     RefPtr<StyleRuleFontFace> m_cssConnection;
194     HashSet<Client*> m_clients;
195     WeakPtr<FontFace> m_wrapper;
196     FontSelectionSpecifiedCapabilities m_fontSelectionCapabilities;
197     
198     Status m_status { Status::Pending };
199     bool m_isLocalFallback { false };
200     bool m_sourcesPopulated { false };
201     bool m_mayBePurged { true };
202
203     Timer m_timeoutTimer;
204 };
205
206 }