FontPlatformDataCGWin.cpp [plain text]
#include "config.h"
#include "FontPlatformData.h"
#include "SharedGDIObject.h"
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <wtf/HashMap.h>
#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
using std::min;
namespace WebCore {
static inline USHORT readBigEndianWord(const BYTE* word) { return (word[0] << 8) | word[1]; }
static CFStringRef getPostScriptName(CFStringRef faceName, HDC dc)
{
const DWORD cMaxNameTableSize = 1024 * 1024;
static HashMap<String, RetainPtr<CFStringRef> > nameMap;
String faceString(faceName);
RetainPtr<CFStringRef> result = nameMap.get(faceString);
if (result)
return result.get();
DWORD bufferSize = GetFontData(dc, 'eman', 0, NULL, 0); if (bufferSize == 0 || bufferSize == GDI_ERROR || bufferSize > cMaxNameTableSize)
return NULL;
Vector<BYTE> bufferVector(bufferSize);
BYTE* buffer = bufferVector.data();
if (GetFontData(dc, 'eman', 0, buffer, bufferSize) == GDI_ERROR)
return NULL;
if (bufferSize < 6)
return NULL;
USHORT numberOfRecords = readBigEndianWord(buffer + 2);
UINT stringsOffset = readBigEndianWord(buffer + 4);
if (bufferSize < stringsOffset)
return NULL;
BYTE* strings = buffer + stringsOffset;
UINT offset = 6;
for (int i = 0; i < numberOfRecords; i++) {
if (bufferSize < offset + 12)
return NULL;
USHORT platformID = readBigEndianWord(buffer + offset);
USHORT encodingID = readBigEndianWord(buffer + offset + 2);
USHORT languageID = readBigEndianWord(buffer + offset + 4);
USHORT nameID = readBigEndianWord(buffer + offset + 6);
USHORT length = readBigEndianWord(buffer + offset + 8);
USHORT nameOffset = readBigEndianWord(buffer + offset + 10);
if (platformID == 3 && encodingID == 1 && languageID == 0x409 && nameID == 6) {
if (bufferSize < stringsOffset + nameOffset + length)
return NULL;
result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingUTF16BE, false));
break;
} else if (platformID == 1 && encodingID == 0 && languageID == 0 && nameID == 6) {
if (bufferSize < stringsOffset + nameOffset + length)
return NULL;
result = adoptCF(CFStringCreateWithBytes(NULL, strings + nameOffset, length, kCFStringEncodingASCII, false));
break;
}
offset += 12;
}
if (result)
nameMap.set(faceString, result);
return result.get();
}
void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR* faceName)
{
LOGFONT logfont;
GetObject(font, sizeof(logfont), &logfont);
m_cgFont = adoptCF(CGFontCreateWithPlatformFont(&logfont));
if (!m_useGDI)
m_isSystemFont = !wcscmp(faceName, L"Lucida Grande");
}
FontPlatformData::FontPlatformData(GDIObject<HFONT> hfont, CGFontRef font, float size, bool bold, bool oblique, bool useGDI)
: m_syntheticBold(bold)
, m_syntheticOblique(oblique)
, m_orientation(Horizontal)
, m_size(size)
, m_widthVariant(RegularWidth)
, m_font(SharedGDIObject<HFONT>::create(WTFMove(hfont)))
, m_cgFont(font)
, m_isColorBitmapFont(false)
, m_useGDI(useGDI)
{
}
bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
{
return m_font == other.m_font
&& m_cgFont == other.m_cgFont
&& m_useGDI == other.m_useGDI;
}
}