SimpleFontDataFreeType.cpp [plain text]
#include "config.h"
#include "SimpleFontData.h"
#include "FloatRect.h"
#include "Font.h"
#include "FontCache.h"
#include "FontDescription.h"
#include "GlyphBuffer.h"
#include <cairo-ft.h>
#include <cairo.h>
#include <fontconfig/fcfreetype.h>
#include <wtf/MathExtras.h>
namespace WebCore {
void SimpleFontData::platformInit()
{
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
cairo_scaled_font_extents(m_platformData.scaledFont(), &font_extents);
m_fontMetrics.setAscent(font_extents.ascent);
m_fontMetrics.setDescent(font_extents.descent);
float lineSpacing = font_extents.height;
if (lineSpacing < font_extents.ascent + font_extents.descent)
lineSpacing = font_extents.ascent + font_extents.descent;
m_fontMetrics.setLineSpacing(lroundf(lineSpacing));
m_fontMetrics.setLineGap(lineSpacing - font_extents.ascent - font_extents.descent);
cairo_scaled_font_text_extents(m_platformData.scaledFont(), "x", &text_extents);
m_fontMetrics.setXHeight(text_extents.height);
cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &text_extents);
m_spaceWidth = static_cast<float>(text_extents.x_advance);
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
}
void SimpleFontData::platformCharWidthInit()
{
m_avgCharWidth = 0.f;
m_maxCharWidth = 0.f;
initCharWidths();
}
void SimpleFontData::platformDestroy()
{
}
PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
return adoptPtr(new SimpleFontData(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
scaleFactor * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()),
isCustomFont(), false));
}
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
return m_derivedFontData->smallCaps.get();
}
SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
return m_derivedFontData->emphasisMark.get();
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.scaledFont());
if (!face)
return false;
for (int i = 0; i < length; i++) {
if (FcFreeTypeCharIndex(face, characters[i]) == 0) {
cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont());
return false;
}
}
cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont());
return true;
}
void SimpleFontData::determinePitch()
{
m_treatAsFixedPitch = m_platformData.isFixedPitch();
}
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
{
return FloatRect();
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
ASSERT(m_platformData.scaledFont());
cairo_glyph_t cglyph = { glyph, 0, 0 };
cairo_text_extents_t extents;
cairo_scaled_font_glyph_extents(m_platformData.scaledFont(), &cglyph, 1, &extents);
float w = (float)m_spaceWidth;
if (cairo_scaled_font_status(m_platformData.scaledFont()) == CAIRO_STATUS_SUCCESS && extents.x_advance)
w = (float)extents.x_advance;
return w;
}
}