CSSFontFaceSource.cpp [plain text]
#include "config.h"
#include "CSSFontFaceSource.h"
#include "CachedFont.h"
#include "CSSFontFace.h"
#include "CSSFontSelector.h"
#include "CachedResourceLoader.h"
#include "Document.h"
#include "FontCache.h"
#include "FontDescription.h"
#include "SimpleFontData.h"
#if ENABLE(SVG_FONTS)
#include "FontCustomPlatformData.h"
#include "SVGFontData.h"
#include "SVGFontElement.h"
#include "SVGFontFaceElement.h"
#include "SVGNames.h"
#include "SVGURIReference.h"
#endif
namespace WebCore {
CSSFontFaceSource::CSSFontFaceSource(const String& str, CachedFont* font)
: m_string(str)
, m_font(font)
, m_face(0)
#if ENABLE(SVG_FONTS)
, m_hasExternalSVGFont(false)
#endif
{
if (m_font)
m_font->addClient(this);
}
CSSFontFaceSource::~CSSFontFaceSource()
{
if (m_font)
m_font->removeClient(this);
pruneTable();
}
void CSSFontFaceSource::pruneTable()
{
if (m_fontDataTable.isEmpty())
return;
m_fontDataTable.clear();
}
bool CSSFontFaceSource::isLoaded() const
{
if (m_font)
return m_font->isLoaded();
return true;
}
bool CSSFontFaceSource::isValid() const
{
if (m_font)
return !m_font->errorOccurred();
return true;
}
void CSSFontFaceSource::fontLoaded(CachedFont*)
{
pruneTable();
if (m_face)
m_face->fontLoaded(this);
}
PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector)
{
if (!isValid())
return 0;
if (!m_font
#if ENABLE(SVG_FONTS)
&& !m_svgFontFaceElement
#endif
) {
return fontCache()->getCachedFontData(fontDescription, m_string, true);
}
unsigned hashKey = (fontDescription.computedPixelSize() + 1) << 5 | fontDescription.widthVariant() << 3
| (fontDescription.orientation() == Vertical ? 4 : 0) | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0);
RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(hashKey, 0).iterator->value;
if (fontData)
return fontData;
if (isLoaded()) {
if (m_font) {
#if ENABLE(SVG_FONTS)
if (m_hasExternalSVGFont) {
if (!m_font->ensureSVGFontData())
return 0;
if (!m_externalSVGFontElement) {
String fragmentIdentifier;
size_t start = m_string.find('#');
if (start != notFound)
fragmentIdentifier = m_string.string().substring(start + 1);
m_externalSVGFontElement = m_font->getSVGFontById(fragmentIdentifier);
}
if (!m_externalSVGFontElement)
return 0;
SVGFontFaceElement* fontFaceElement = 0;
for (Node* fontChild = m_externalSVGFontElement->firstChild(); fontChild; fontChild = fontChild->nextSibling()) {
if (fontChild->hasTagName(SVGNames::font_faceTag)) {
fontFaceElement = static_cast<SVGFontFaceElement*>(fontChild);
break;
}
}
if (fontFaceElement) {
if (!m_svgFontFaceElement) {
m_svgFontFaceElement = fontFaceElement;
}
fontData = SimpleFontData::create(SVGFontData::create(fontFaceElement), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
}
} else
#endif
{
if (!m_font->ensureCustomFontData())
return 0;
fontData = SimpleFontData::create(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic,
fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.renderingMode()), true, false);
}
} else {
#if ENABLE(SVG_FONTS)
if (m_svgFontFaceElement)
fontData = SimpleFontData::create(SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
#endif
}
} else {
fontSelector->beginLoadingFontSoon(m_font.get());
FontCachePurgePreventer fontCachePurgePreventer;
SimpleFontData* temporaryFont = fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
fontData = SimpleFontData::create(temporaryFont->platformData(), true, true);
}
return fontData; }
#if ENABLE(SVG_FONTS)
SVGFontFaceElement* CSSFontFaceSource::svgFontFaceElement() const
{
return m_svgFontFaceElement.get();
}
void CSSFontFaceSource::setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement> element)
{
m_svgFontFaceElement = element;
}
bool CSSFontFaceSource::isSVGFontFaceSource() const
{
return m_svgFontFaceElement || m_hasExternalSVGFont;
}
#endif
#if ENABLE(FONT_LOAD_EVENTS)
bool CSSFontFaceSource::isDecodeError() const
{
if (m_font)
return m_font->status() == CachedResource::DecodeError;
return false;
}
bool CSSFontFaceSource::ensureFontData()
{
if (!m_font)
return false;
#if ENABLE(SVG_FONTS)
if (m_hasExternalSVGFont)
return m_font->ensureSVGFontData();
#endif
return m_font->ensureCustomFontData();
}
#endif
}