Unreviewed, rolling out r245857.
[WebKit-https.git] / Source / WebCore / css / CSSFontFace.h
index 2def0b9..ad06d19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef CSSFontFace_h
-#define CSSFontFace_h
+#pragma once
 
-#include "CSSFontFaceRule.h"
-#include "CSSFontFaceSource.h"
-#include "FontFeatureSettings.h"
+#include "FontSelectionValueInlines.h"
+#include "FontTaggedSettings.h"
+#include "StyleRule.h"
 #include "TextFlags.h"
+#include "Timer.h"
 #include <memory>
 #include <wtf/Forward.h>
 #include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+namespace JSC {
+class ExecState;
+}
 
 namespace WebCore {
 
+class CSSFontFaceSource;
+class CSSFontSelector;
 class CSSSegmentedFontFace;
 class CSSValue;
 class CSSValueList;
+class Document;
 class FontDescription;
 class Font;
+class FontFace;
+enum class ExternalResourceDownloadPolicy;
 
-class CSSFontFace : public RefCounted<CSSFontFace> {
+class CSSFontFace final : public RefCounted<CSSFontFace> {
 public:
-    static Ref<CSSFontFace> create(bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(isLocalFallback)); }
+    static Ref<CSSFontFace> create(CSSFontSelector* fontSelector, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false)
+    {
+        return adoptRef(*new CSSFontFace(fontSelector, cssConnection, wrapper, isLocalFallback));
+    }
     virtual ~CSSFontFace();
 
+    // FIXME: These functions don't need to have boolean return values.
+    // Callers only call this with known-valid CSS values.
     bool setFamilies(CSSValue&);
-    bool setStyle(CSSValue&);
-    bool setWeight(CSSValue&);
+    void setStyle(CSSValue&);
+    void setWeight(CSSValue&);
+    void setStretch(CSSValue&);
     bool setUnicodeRange(CSSValue&);
     bool setVariantLigatures(CSSValue&);
     bool setVariantPosition(CSSValue&);
@@ -60,61 +75,132 @@ public:
     bool setVariantNumeric(CSSValue&);
     bool setVariantAlternates(CSSValue&);
     bool setVariantEastAsian(CSSValue&);
-    bool setFeatureSettings(CSSValue&);
+    void setFeatureSettings(CSSValue&);
+    void setLoadingBehavior(CSSValue&);
 
+    enum class Status : uint8_t;
     struct UnicodeRange;
     const CSSValueList* families() const { return m_families.get(); }
-    FontTraitsMask traitsMask() const { return m_traitsMask; }
+    FontSelectionRange weight() const { return m_fontSelectionCapabilities.computeWeight(); }
+    FontSelectionRange stretch() const { return m_fontSelectionCapabilities.computeWidth(); }
+    FontSelectionRange italic() const { return m_fontSelectionCapabilities.computeSlope(); }
+    FontSelectionCapabilities fontSelectionCapabilities() const { return m_fontSelectionCapabilities.computeFontSelectionCapabilities(); }
     const Vector<UnicodeRange>& ranges() const { return m_ranges; }
     const FontFeatureSettings& featureSettings() const { return m_featureSettings; }
     const FontVariantSettings& variantSettings() const { return m_variantSettings; }
+    FontLoadingBehavior loadingBehavior() const { return m_loadingBehavior; }
     void setVariantSettings(const FontVariantSettings& variantSettings) { m_variantSettings = variantSettings; }
-    void setTraitsMask(FontTraitsMask traitsMask) { m_traitsMask = traitsMask; }
+    void setWeight(FontSelectionRange weight) { m_fontSelectionCapabilities.weight = weight; }
+    void setStretch(FontSelectionRange stretch) { m_fontSelectionCapabilities.width = stretch; }
+    void setStyle(FontSelectionRange italic) { m_fontSelectionCapabilities.slope = italic; }
+    void setFontSelectionCapabilities(FontSelectionCapabilities capabilities) { m_fontSelectionCapabilities = capabilities; }
     bool isLocalFallback() const { return m_isLocalFallback; }
+    Status status() const { return m_status; }
+    StyleRuleFontFace* cssConnection() const { return m_cssConnection.get(); }
+
+    class Client;
+    void addClient(Client&);
+    void removeClient(Client&);
 
-    void addedToSegmentedFontFace(CSSSegmentedFontFace&);
-    void removedFromSegmentedFontFace(CSSSegmentedFontFace&);
+    bool computeFailureState() const;
 
-    bool allSourcesFailed() const;
+    void opportunisticallyStartFontDataURLLoading(CSSFontSelector&);
 
     void adoptSource(std::unique_ptr<CSSFontFaceSource>&&);
+    void sourcesPopulated() { m_sourcesPopulated = true; }
 
     void fontLoaded(CSSFontFaceSource&);
 
-    RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic);
+    void load();
+
+    RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, ExternalResourceDownloadPolicy);
+
+    static void appendSources(CSSFontFace&, CSSValueList&, Document*, bool isInitiatingElementInUserAgentShadowTree);
+
+    class Client {
+    public:
+        virtual ~Client() = default;
+        virtual void fontLoaded(CSSFontFace&) { }
+        virtual void fontStateChanged(CSSFontFace&, Status /*oldState*/, Status /*newState*/) { }
+        virtual void fontPropertyChanged(CSSFontFace&, CSSValueList* /*oldFamilies*/ = nullptr) { }
+        virtual void ref() = 0;
+        virtual void deref() = 0;
+    };
+
+    // Pending => Loading  => TimedOut
+    //              ||  \\    //  ||
+    //              ||   \\  //   ||
+    //              ||    \\//    ||
+    //              ||     //     ||
+    //              ||    //\\    ||
+    //              ||   //  \\   ||
+    //              \/  \/    \/  \/
+    //             Success    Failure
+    enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
 
     struct UnicodeRange {
-        UnicodeRange(UChar32 from, UChar32 to)
-            : m_from(from)
-            , m_to(to)
-        {
-        }
-
-        UChar32 from() const { return m_from; }
-        UChar32 to() const { return m_to; }
-
-    private:
-        UChar32 m_from;
-        UChar32 m_to;
+        UChar32 from;
+        UChar32 to;
+        bool operator==(const UnicodeRange& other) const { return from == other.from && to == other.to; }
+        bool operator!=(const UnicodeRange& other) const { return !(*this == other); }
     };
 
+    bool rangesMatchCodePoint(UChar32) const;
+
+    // We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
+    Ref<FontFace> wrapper();
+    void setWrapper(FontFace&);
+    FontFace* existingWrapper() { return m_wrapper.get(); }
+
+    struct FontLoadTiming {
+        Seconds blockPeriod;
+        Seconds swapPeriod;
+    };
+    FontLoadTiming fontLoadTiming() const;
+    bool shouldIgnoreFontLoadCompletions() const;
+
+    bool purgeable() const;
+
+    AllowUserInstalledFonts allowUserInstalledFonts() const;
+
+    void updateStyleIfNeeded();
+
 #if ENABLE(SVG_FONTS)
     bool hasSVGFontFaceSource() const;
 #endif
 
 private:
-    CSSFontFace(bool isLocalFallback);
+    CSSFontFace(CSSFontSelector*, StyleRuleFontFace*, FontFace*, bool isLocalFallback);
+
+    size_t pump(ExternalResourceDownloadPolicy);
+    void setStatus(Status);
+    void notifyClientsOfFontPropertyChange();
+
+    void initializeWrapper();
+
+    void fontLoadEventOccurred();
+    void timeoutFired();
 
     RefPtr<CSSValueList> m_families;
-    FontTraitsMask m_traitsMask;
     Vector<UnicodeRange> m_ranges;
-    HashSet<CSSSegmentedFontFace*> m_segmentedFontFaces;
+
     FontFeatureSettings m_featureSettings;
     FontVariantSettings m_variantSettings;
-    Vector<std::unique_ptr<CSSFontFaceSource>> m_sources;
-    bool m_isLocalFallback;
+    FontLoadingBehavior m_loadingBehavior { FontLoadingBehavior::Auto };
+
+    Vector<std::unique_ptr<CSSFontFaceSource>, 0, CrashOnOverflow, 0> m_sources;
+    RefPtr<CSSFontSelector> m_fontSelector; // FIXME: https://bugs.webkit.org/show_bug.cgi?id=196437 There's a retain cycle: CSSFontSelector -> CSSFontFaceSet -> CSSFontFace -> CSSFontSelector
+    RefPtr<StyleRuleFontFace> m_cssConnection;
+    HashSet<Client*> m_clients;
+    WeakPtr<FontFace> m_wrapper;
+    FontSelectionSpecifiedCapabilities m_fontSelectionCapabilities;
+    
+    Status m_status { Status::Pending };
+    bool m_isLocalFallback { false };
+    bool m_sourcesPopulated { false };
+    bool m_mayBePurged { true };
+
+    Timer m_timeoutTimer;
 };
 
 }
-
-#endif