#ifndef FontFaceSet_h
#define FontFaceSet_h
#include "bindings/v8/ScriptPromise.h"
#include "core/css/FontFace.h"
#include "core/css/FontFaceSetForEachCallback.h"
#include "core/dom/ActiveDOMObject.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
#include "platform/AsyncMethodRunner.h"
#include "platform/RefCountedSupplement.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
#ifdef check
#undef check
#endif
namespace WebCore {
class CSSFontFace;
class CSSFontFaceSource;
class CSSFontSelector;
class Dictionary;
class Document;
class ExceptionState;
class Font;
class FontFaceCache;
class FontResource;
class FontsReadyPromiseResolver;
class ExecutionContext;
class FontFaceSet FINAL : public RefCountedSupplement<Document, FontFaceSet>, public ActiveDOMObject, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(FontFaceSet);
public:
virtual ~FontFaceSet();
DEFINE_ATTRIBUTE_EVENT_LISTENER(loading);
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone);
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror);
bool check(const String& font, const String& text, ExceptionState&);
ScriptPromise load(const String& font, const String& text);
ScriptPromise ready();
void add(FontFace*, ExceptionState&);
void clear();
bool remove(FontFace*, ExceptionState&);
void forEach(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue& thisArg) const;
void forEach(PassOwnPtr<FontFaceSetForEachCallback>) const;
bool has(FontFace*, ExceptionState&) const;
unsigned long size() const;
AtomicString status() const;
virtual ExecutionContext* executionContext() const OVERRIDE;
virtual const AtomicString& interfaceName() const OVERRIDE;
Document* document() const;
void didLayout();
void beginFontLoading(FontFace*);
void fontLoaded(FontFace*);
void loadError(FontFace*);
virtual void suspend() OVERRIDE;
virtual void resume() OVERRIDE;
virtual void stop() OVERRIDE;
static PassRefPtr<FontFaceSet> from(Document&);
static void didLayout(Document&);
void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*);
private:
typedef RefCountedSupplement<Document, FontFaceSet> SupplementType;
static PassRefPtr<FontFaceSet> create(Document& document)
{
return adoptRef<FontFaceSet>(new FontFaceSet(document));
}
class FontLoadHistogram {
public:
enum Status { NoWebFonts, HadBlankText, DidNotHaveBlankText, Reported };
FontLoadHistogram() : m_status(NoWebFonts), m_count(0), m_recorded(false) { }
void incrementCount() { m_count++; }
void updateStatus(FontFace*);
void record();
private:
Status m_status;
int m_count;
bool m_recorded;
};
FontFaceSet(Document&);
bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); }
bool inActiveDocumentContext() const;
void forEachInternal(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue* thisArg) const;
void addToLoadingFonts(PassRefPtr<FontFace>);
void removeFromLoadingFonts(PassRefPtr<FontFace>);
void fireLoadingEvent();
void fireDoneEventIfPossible();
bool resolveFontStyle(const String&, Font&);
void handlePendingEventsAndPromisesSoon();
void handlePendingEventsAndPromises();
const ListHashSet<RefPtr<FontFace> >& cssConnectedFontFaceList() const;
bool isCSSConnectedFontFace(FontFace*) const;
HashSet<RefPtr<FontFace> > m_loadingFonts;
bool m_shouldFireLoadingEvent;
Vector<OwnPtr<FontsReadyPromiseResolver> > m_readyResolvers;
FontFaceArray m_loadedFonts;
FontFaceArray m_failedFonts;
ListHashSet<RefPtr<FontFace> > m_nonCSSConnectedFaces;
AsyncMethodRunner<FontFaceSet> m_asyncRunner;
FontLoadHistogram m_histogram;
};
}
#endif