diff options
Diffstat (limited to 'WebCore/platform/graphics/win/FontPlatformDataWin.cpp')
-rw-r--r-- | WebCore/platform/graphics/win/FontPlatformDataWin.cpp | 170 |
1 files changed, 19 insertions, 151 deletions
diff --git a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp index a5fab36..4b4df5a 100644 --- a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp +++ b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp @@ -2,7 +2,8 @@ * This file is part of the internal font implementation. It should not be included by anyone other than * FontMac.cpp, FontWin.cpp and Font.cpp. * - * Copyright (C) 2006, 2007 Apple Inc. + * Copyright (C) 2006, 2007, 2008 Apple Inc. + * Copyright (C) 2008 Brent Fulgham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,7 +27,6 @@ #include "PlatformString.h" #include "StringHash.h" -#include <ApplicationServices/ApplicationServices.h> #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> #include <wtf/Vector.h> @@ -35,105 +35,17 @@ using std::min; namespace WebCore { -static const int Bold = (1 << 0); -static const int Italic = (1 << 1); -static const int BoldOblique = (1 << 2); - -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; - - // Check our hash first. - String faceString(faceName); - RetainPtr<CFStringRef> result = nameMap.get(faceString); - if (result) - return result.get(); - - // We need to obtain the PostScript name from the name table and use it instead,. - DWORD bufferSize = GetFontData(dc, 'eman', 0, NULL, 0); // "name" backwards - 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; - - // Now walk each name record looking for a Mac or Windows PostScript name. - 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) { - // This is a Windows PostScript name and is therefore UTF-16. - // Pass Big Endian as the encoding. - 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) { - // This is a Mac PostScript name and is therefore ASCII. - // See http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html - 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(); -} - -static int CALLBACK enumStylesCallback(const LOGFONT* logFont, const TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam) -{ - int *style = reinterpret_cast<int*>(lParam); - - // FIXME: In order to accommodate Lucida we go ahead and consider a weight of 600 to be bold. - // This does mean we'll consider demibold and semibold fonts on windows to also be bold. This - // is rare enough that it seems like an ok hack for now. - if (logFont->lfWeight >= 600) { - if (logFont->lfItalic) - *style |= BoldOblique; - else - *style |= Bold; - } else if (logFont->lfItalic) - *style |= Italic; - - return 1; -} - FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool oblique, bool useGDI) - : m_font(font) + : m_font(RefCountedHFONT::create(font)) , m_size(size) +#if PLATFORM(CG) , m_cgFont(0) - , m_syntheticBold(false) - , m_syntheticOblique(false) +#elif PLATFORM(CAIRO) + , m_fontFace(0) + , m_scaledFont(0) +#endif + , m_syntheticBold(bold) + , m_syntheticOblique(oblique) , m_useGDI(useGDI) { HDC hdc = GetDC(0); @@ -142,54 +54,16 @@ FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool obliq SelectObject(hdc, font); UINT bufferSize = GetOutlineTextMetrics(hdc, 0, NULL); - ASSERT_WITH_MESSAGE(bufferSize != 0, "Bitmap fonts not supported with CoreGraphics."); + ASSERT_WITH_MESSAGE(bufferSize, "Bitmap fonts not supported with CoreGraphics."); - if (bufferSize != 0) { + if (bufferSize) { OUTLINETEXTMETRICW* metrics = (OUTLINETEXTMETRICW*)malloc(bufferSize); GetOutlineTextMetricsW(hdc, bufferSize, metrics); WCHAR* faceName = (WCHAR*)((uintptr_t)metrics + (uintptr_t)metrics->otmpFaceName); - if (!useGDI && (bold || oblique)) { - LOGFONT logFont; - - int len = min((int)wcslen(faceName), LF_FACESIZE - 1); - memcpy(logFont.lfFaceName, faceName, len * sizeof(WORD)); - logFont.lfFaceName[len] = '\0'; - logFont.lfCharSet = metrics->otmTextMetrics.tmCharSet; - logFont.lfPitchAndFamily = 0; - - int styles = 0; - EnumFontFamiliesEx(hdc, &logFont, enumStylesCallback, reinterpret_cast<LPARAM>(&styles), 0); - - // Check if we need to synthesize bold or oblique. The rule that complicates things here - // is that if the requested font is bold and oblique, and both a bold font and an oblique font - // exist, the bold font should be used, and oblique synthesized. - if (bold && oblique) { - if (styles == 0) { - m_syntheticBold = true; - m_syntheticOblique = true; - } else if (styles & Bold) - m_syntheticOblique = true; - else if (styles & Italic) - m_syntheticBold = true; - } else if (bold && (!(styles & Bold))) - m_syntheticBold = true; - else if (oblique && !(styles & Italic)) - m_syntheticOblique = true; - } + platformDataInit(font, size, hdc, faceName); - // Try the face name first. Windows may end up localizing this name, and CG doesn't know about - // the localization. If the create fails, we'll try the PostScript name. - RetainPtr<CFStringRef> fullName(AdoptCF, CFStringCreateWithCharacters(NULL, (const UniChar*)faceName, wcslen(faceName))); - m_cgFont = CGFontCreateWithFontName(fullName.get()); - if (!m_cgFont) { - CFStringRef postScriptName = getPostScriptName(fullName.get(), hdc); - if (postScriptName) { - m_cgFont = CGFontCreateWithFontName(postScriptName); - ASSERT(m_cgFont); - } - } free(metrics); } @@ -198,19 +72,13 @@ FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool obliq } FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) - : m_font(0) - , m_size(size) + : m_size(size) +#if PLATFORM(CG) , m_cgFont(0) - , m_syntheticBold(bold) - , m_syntheticOblique(oblique) - , m_useGDI(false) -{ -} - -FontPlatformData::FontPlatformData(CGFontRef font, float size, bool bold, bool oblique) - : m_font(0) - , m_size(size) - , m_cgFont(font) +#elif PLATFORM(CAIRO) + , m_fontFace(0) + , m_scaledFont(0) +#endif , m_syntheticBold(bold) , m_syntheticOblique(oblique) , m_useGDI(false) |