#include "config.h"
#include "CSSFontFace.h"
#include "CSSFontFaceSource.h"
#include "CSSFontSelector.h"
#include "CSSSegmentedFontFace.h"
#include "Document.h"
#include "FontDescription.h"
#include "FontLoader.h"
#include "RuntimeEnabledFeatures.h"
#include "SimpleFontData.h"
namespace WebCore {
bool CSSFontFace::isLoaded() const
{
size_t size = m_sources.size();
for (size_t i = 0; i < size; i++) {
if (!m_sources[i]->isLoaded())
return false;
}
return true;
}
bool CSSFontFace::isValid() const
{
size_t size = m_sources.size();
for (size_t i = 0; i < size; i++) {
if (m_sources[i]->isValid())
return true;
}
return false;
}
void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
{
m_segmentedFontFaces.add(segmentedFontFace);
}
void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
{
m_segmentedFontFaces.remove(segmentedFontFace);
}
void CSSFontFace::addSource(std::unique_ptr<CSSFontFaceSource> source)
{
source->setFontFace(this);
m_sources.append(WTF::move(source));
}
void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
{
if (source != m_activeSource)
return;
if (m_segmentedFontFaces.isEmpty())
return;
CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
fontSelector->fontLoaded();
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {
if (source->ensureFontData())
notifyFontLoader(Loaded);
else if (!isValid())
notifyFontLoader(Error);
}
#endif
HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end();
for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it)
(*it)->fontLoaded(this);
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
notifyLoadingDone();
#endif
}
PassRefPtr<SimpleFontData> CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic)
{
m_activeSource = 0;
if (!isValid())
return 0;
ASSERT(!m_segmentedFontFaces.isEmpty());
CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == NotLoaded)
notifyFontLoader(Loading);
#endif
size_t size = m_sources.size();
for (size_t i = 0; i < size; ++i) {
if (RefPtr<SimpleFontData> result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, fontSelector)) {
m_activeSource = m_sources[i].get();
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading && m_sources[i]->isLoaded()) {
notifyFontLoader(Loaded);
notifyLoadingDone();
}
#endif
return result.release();
}
}
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {
notifyFontLoader(Error);
notifyLoadingDone();
}
#endif
return 0;
}
#if ENABLE(FONT_LOAD_EVENTS)
void CSSFontFace::notifyFontLoader(LoadState newState)
{
m_loadState = newState;
Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();
if (!document)
return;
switch (newState) {
case Loading:
document->fontloader()->beginFontLoading(m_rule.get());
break;
case Loaded:
document->fontloader()->fontLoaded(m_rule.get());
break;
case Error:
document->fontloader()->loadError(m_rule.get(), m_activeSource);
break;
default:
break;
}
}
void CSSFontFace::notifyLoadingDone()
{
Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();
if (document)
document->fontloader()->loadingDone();
}
#endif
#if ENABLE(SVG_FONTS)
bool CSSFontFace::hasSVGFontFaceSource() const
{
size_t size = m_sources.size();
for (size_t i = 0; i < size; i++) {
if (m_sources[i]->isSVGFontFaceSource())
return true;
}
return false;
}
#endif
}