SimpleFontDataCGWin.cpp [plain text]
#include "config.h"
#include "SimpleFontData.h"
#include <winsock2.h>
#include "Font.h"
#include "FontCache.h"
#include "FloatRect.h"
#include "FontDescription.h"
#include <wtf/MathExtras.h>
#include <unicode/uchar.h>
#include <unicode/unorm.h>
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <mlang.h>
#include <tchar.h>
namespace WebCore {
using std::max;
static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / static_cast<float>(unitsPerEm) : x; }
void SimpleFontData::platformInit()
{
m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
m_scriptCache = 0;
m_scriptFontProperties = 0;
m_isSystemFont = false;
if (m_font.useGDI()) {
HDC hdc = GetDC(0);
HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
OUTLINETEXTMETRIC metrics;
GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
m_ascent = textMetrics.tmAscent;
m_descent = textMetrics.tmDescent;
m_lineGap = textMetrics.tmExternalLeading;
m_lineSpacing = m_ascent + m_descent + m_lineGap;
m_xHeight = m_ascent * 0.56f;
GLYPHMETRICS gm;
MAT2 mat = { 1, 0, 0, 1 };
DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
m_xHeight = gm.gmptGlyphOrigin.y;
m_unitsPerEm = metrics.otmEMSquare;
SelectObject(hdc, oldFont);
ReleaseDC(0, hdc);
return;
}
CGFontRef font = m_font.cgFont();
int iAscent = CGFontGetAscent(font);
int iDescent = CGFontGetDescent(font);
int iLineGap = CGFontGetLeading(font);
m_unitsPerEm = CGFontGetUnitsPerEm(font);
float pointSize = m_font.size();
float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
if (!isCustomFont()) {
HDC dc = GetDC(0);
HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
int faceLength = GetTextFace(dc, 0, 0);
Vector<TCHAR> faceName(faceLength);
GetTextFace(dc, faceLength, faceName.data());
m_isSystemFont = !_tcscmp(faceName.data(), _T("Lucida Grande"));
SelectObject(dc, oldFont);
ReleaseDC(0, dc);
if (shouldApplyMacAscentHack()) {
if (!_tcscmp(faceName.data(), _T("Times")) || !_tcscmp(faceName.data(), _T("Helvetica")) || !_tcscmp(faceName.data(), _T("Courier")))
fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
}
}
m_ascent = lroundf(fAscent);
m_descent = lroundf(fDescent);
m_lineGap = lroundf(fLineGap);
m_lineSpacing = m_ascent + m_descent + m_lineGap;
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
if (xGlyph) {
CGRect xBox;
CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
m_xHeight = scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), m_unitsPerEm) * pointSize;
} else {
int iXHeight = CGFontGetXHeight(font);
m_xHeight = scaleEmToUnits(iXHeight, m_unitsPerEm) * pointSize;
}
}
void SimpleFontData::platformDestroy()
{
if (!isCustomFont()) {
DeleteObject(m_font.hfont());
CGFontRelease(m_font.cgFont());
}
delete m_smallCapsFontData;
ScriptFreeCache(&m_scriptCache);
delete m_scriptFontProperties;
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
if (m_font.useGDI()) {
HDC hdc = GetDC(0);
HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
int width;
GetCharWidthI(hdc, glyph, 1, 0, &width);
SelectObject(hdc, oldFont);
ReleaseDC(0, hdc);
return width;
}
CGFontRef font = m_font.cgFont();
float pointSize = m_font.size();
CGSize advance;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
bool isPrinterFont = false;
wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
return advance.width + m_syntheticBoldOffset;
}
}