SimpleFontDataCGWin.cpp [plain text]
#include "config.h"
#include "Font.h"
#include "FloatRect.h"
#include "FontCache.h"
#include "FontDescription.h"
#include "GlyphPage.h"
#include "HWndDC.h"
#include "OpenTypeCG.h"
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <mlang.h>
#include <unicode/uchar.h>
#include <unicode/unorm.h>
#include <winsock2.h>
#include <wtf/MathExtras.h>
#include <wtf/RetainPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
using namespace std;
void Font::platformInit()
{
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
m_scriptCache = 0;
m_scriptFontProperties = 0;
if (m_platformData.useGDI())
return initGDIFont();
CGFontRef font = m_platformData.cgFont();
int iAscent = CGFontGetAscent(font);
int iDescent = CGFontGetDescent(font);
int iLineGap = CGFontGetLeading(font);
int iCapHeight = CGFontGetCapHeight(font);
short typoAscent, typoDescent, typoLineGap;
if (OpenType::tryGetTypoMetrics(m_platformData.cgFont(), typoAscent, typoDescent, typoLineGap)) {
iAscent = typoAscent;
iDescent = typoDescent;
iLineGap = typoLineGap;
}
unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
float pointSize = m_platformData.size();
float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
float fCapHeight = scaleEmToUnits(iCapHeight, unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
if (!isCustomFont()) {
HWndDC dc(0);
HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
int faceLength = GetTextFace(dc, 0, 0);
Vector<WCHAR> faceName(faceLength);
GetTextFace(dc, faceLength, faceName.data());
SelectObject(dc, oldFont);
fAscent = ascentConsideringMacAscentHack(faceName.data(), fAscent, fDescent);
}
m_fontMetrics.setAscent(fAscent);
m_fontMetrics.setDescent(fDescent);
m_fontMetrics.setCapHeight(fCapHeight);
m_fontMetrics.setLineGap(fLineGap);
m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap));
Glyph xGlyph = glyphDataForCharacter('x').glyph;
if (xGlyph) {
CGRect xBox;
CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
m_fontMetrics.setXHeight(scaleEmToUnits(CGRectGetMaxY(xBox), unitsPerEm) * pointSize);
} else {
int iXHeight = CGFontGetXHeight(font);
m_fontMetrics.setXHeight(scaleEmToUnits(iXHeight, unitsPerEm) * pointSize);
}
m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
FloatRect Font::platformBoundsForGlyph(Glyph glyph) const
{
if (!platformData().size())
return FloatRect();
if (m_platformData.useGDI())
return boundsForGDIGlyph(glyph);
CGRect box;
CGFontGetGlyphBBoxes(m_platformData.cgFont(), &glyph, 1, &box);
float pointSize = m_platformData.size();
CGFloat scale = pointSize / fontMetrics().unitsPerEm();
FloatRect boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale));
if (m_syntheticBoldOffset)
boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
return boundingBox;
}
float Font::platformWidthForGlyph(Glyph glyph) const
{
if (!platformData().size())
return 0;
if (m_platformData.useGDI())
return widthForGDIGlyph(glyph);
CGFontRef font = m_platformData.cgFont();
float pointSize = m_platformData.size();
CGSize advance;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
bool isPrinterFont = false;
wkGetGlyphAdvances(font, m, m_platformData.isSystemFont(), isPrinterFont, glyph, advance);
return advance.width + m_syntheticBoldOffset;
}
}