CSSFontFaceSource.cpp [plain text]
#include "config.h"
#include "CSSFontFaceSource.h"
#include "CSSFontFace.h"
#include "CSSFontSelector.h"
#include "CachedFont.h"
#include "CachedResourceLoader.h"
#include "Document.h"
#include "ElementIterator.h"
#include "Font.h"
#include "FontCache.h"
#include "FontDescription.h"
#if ENABLE(SVG_OTF_CONVERTER)
#include "FontCustomPlatformData.h"
#include "SVGToOTFFontConversion.h"
#endif
#if ENABLE(SVG_FONTS)
#include "CachedSVGFont.h"
#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_fontTable.isEmpty())
return;
m_fontTable.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);
}
RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings)
{
if (!isValid())
return nullptr;
if (!m_font
#if ENABLE(SVG_FONTS)
&& !m_svgFontFaceElement
#endif
) {
return FontCache::singleton().fontForFamily(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<Font> font = m_fontTable.add(hashKey, nullptr).iterator->value;
if (font)
return font.release();
if (isLoaded()) {
if (m_font) {
bool hasExternalSVGFont = false;
#if ENABLE(SVG_FONTS)
hasExternalSVGFont = m_hasExternalSVGFont;
#endif
if (!m_font->ensureCustomFontData(hasExternalSVGFont, m_string))
return nullptr;
font = m_font->createFont(fontDescription, m_string, syntheticBold, syntheticItalic, hasExternalSVGFont, fontFaceFeatures, fontFaceVariantSettings);
} else {
#if ENABLE(SVG_FONTS)
if (m_svgFontFaceElement) {
#if ENABLE(SVG_OTF_CONVERTER)
if (!m_svgFontFaceElement->parentNode() || !is<SVGFontElement>(m_svgFontFaceElement->parentNode()))
return nullptr;
SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode());
Vector<char> otfFont = convertSVGToOTFFont(fontElement);
m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont);
if (!m_generatedOTFBuffer)
return nullptr;
auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer);
if (!customPlatformData)
return nullptr;
font = Font::create(customPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false);
#else
font = Font::create(std::make_unique<SVGFontData>(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
#endif
}
#endif
}
} else {
fontSelector->beginLoadingFontSoon(m_font.get());
Ref<Font> placeholderFont = FontCache::singleton().lastResortFallbackFont(fontDescription);
Ref<Font> placeholderFontCopyInLoadingState = Font::create(placeholderFont->platformData(), true, true);
return WTF::move(placeholderFontCopyInLoadingState);
}
return font.release();
}
#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;
return m_font->ensureCustomFontData(m_hasExternalSVGFont, m_string);
}
#endif
}