SimpleFontData.cpp [plain text]
#include "config.h"
#include "SimpleFontData.h"
#include "Font.h"
#include "FontCache.h"
#if ENABLE(SVG_FONTS)
#include "SVGFontData.h"
#include "SVGFontFaceElement.h"
#include "SVGGlyphElement.h"
#endif
#include <wtf/MathExtras.h>
#include <wtf/UnusedParam.h>
namespace WebCore {
SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool loading, SVGFontData* svgFontData)
: m_unitsPerEm(defaultUnitsPerEm)
, m_platformData(f)
, m_treatAsFixedPitch(false)
#if ENABLE(SVG_FONTS)
, m_svgFontData(svgFontData)
#endif
, m_isCustomFont(customFont)
, m_isLoading(loading)
, m_smallCapsFontData(0)
{
#if !ENABLE(SVG_FONTS)
UNUSED_PARAM(svgFontData);
#else
if (SVGFontFaceElement* svgFontFaceElement = svgFontData ? svgFontData->svgFontFaceElement() : 0) {
m_unitsPerEm = svgFontFaceElement->unitsPerEm();
double scale = f.size();
if (m_unitsPerEm)
scale /= m_unitsPerEm;
m_ascent = static_cast<int>(svgFontFaceElement->ascent() * scale);
m_descent = static_cast<int>(svgFontFaceElement->descent() * scale);
m_xHeight = static_cast<int>(svgFontFaceElement->xHeight() * scale);
m_lineGap = 0.1f * f.size();
m_lineSpacing = m_ascent + m_descent + m_lineGap;
m_spaceGlyph = 0;
m_spaceWidth = 0;
m_adjustedSpaceWidth = 0;
determinePitch();
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
#endif
if (f.m_isImageFont) {
m_unitsPerEm = 1;
double scale = f.size();
if (m_unitsPerEm)
scale /= m_unitsPerEm;
m_ascent = static_cast<int>(scale / 3); m_descent = static_cast<int>(scale / 3); m_xHeight = static_cast<int>(scale / 3); m_lineGap = static_cast<int>(scale / 3); m_lineSpacing = 0;
m_spaceGlyph = 0;
m_spaceWidth = 0;
m_adjustedSpaceWidth = 0;
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
platformInit();
platformGlyphInit();
}
#if !PLATFORM(QT)
void SimpleFontData::platformGlyphInit()
{
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (!glyphPageZero) {
LOG_ERROR("Failed to get glyph page zero.");
m_spaceGlyph = 0;
m_spaceWidth = 0;
m_adjustedSpaceWidth = 0;
determinePitch();
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
float width = widthForGlyph(m_spaceGlyph);
m_spaceWidth = width;
determinePitch();
m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
if (zeroWidthSpaceGlyph) {
if (zeroWidthSpaceGlyph != m_spaceGlyph)
m_glyphToWidthMap.setWidthForGlyph(zeroWidthSpaceGlyph, 0);
else
LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden.");
}
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
}
#endif
SimpleFontData::~SimpleFontData()
{
#if ENABLE(SVG_FONTS)
if (!m_svgFontData || !m_svgFontData->svgFontFaceElement())
#endif
platformDestroy();
if (!isCustomFont()) {
if (m_smallCapsFontData)
fontCache()->releaseFontData(m_smallCapsFontData);
GlyphPageTreeNode::pruneTreeFontData(this);
}
}
const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
{
return this;
}
bool SimpleFontData::isSegmented() const
{
return false;
}
}