1808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato/*
2808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
4808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Redistribution and use in source and binary forms, with or without
5808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * modification, are permitted provided that the following conditions
6808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * are met:
7808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
8808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * 1.  Redistributions of source code must retain the above copyright
9808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *     notice, this list of conditions and the following disclaimer.
10808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * 2.  Redistributions in binary form must reproduce the above copyright
11808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *     notice, this list of conditions and the following disclaimer in the
12808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *     documentation and/or other materials provided with the distribution.
13808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *     its contributors may be used to endorse or promote products derived
15808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *     from this software without specific prior written permission.
16808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato */
28808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
29808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include "config.h"
30808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <winsock2.h>
31808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include "FontCache.h"
32808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include "Font.h"
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include "SimpleFontData.h"
34808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include "UnicodeRange.h"
35808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <mlang.h>
36808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <windows.h>
37808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <wtf/StdLibExtras.h>
38808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <wtf/text/StringHash.h>
39808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#if USE(CG)
40935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato#include <ApplicationServices/ApplicationServices.h>
41808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#include <WebKitSystemInterface/WebKitSystemInterface.h>
42808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#endif
43808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
44808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratousing std::min;
45808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
46808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratonamespace WebCore
47808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
48808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
49808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratovoid FontCache::platformInit()
50808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
51808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#if USE(CG)
52808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    wkSetUpFontCache(1536 * 1024 * 4); // This size matches Mac.
53808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#endif
54808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
55808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
56808182dc874e93582da38d013a4a790d6bc08fc9Joe OnoratoIMLangFontLink2* FontCache::getFontLinkInterface()
57808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static IMultiLanguage *multiLanguage;
59808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!multiLanguage) {
60808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (CoCreateInstance(CLSID_CMultiLanguage, 0, CLSCTX_ALL, IID_IMultiLanguage, (void**)&multiLanguage) != S_OK)
61808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return 0;
62808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
64808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static IMLangFontLink2* langFontLink;
65808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!langFontLink) {
66808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (multiLanguage->QueryInterface(&langFontLink) != S_OK)
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return 0;
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
69808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
70808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return langFontLink;
71808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
72808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
73808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic int CALLBACK metaFileEnumProc(HDC hdc, HANDLETABLE* table, CONST ENHMETARECORD* record, int tableEntries, LPARAM logFont)
74fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato{
75fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    if (record->iType == EMR_EXTCREATEFONTINDIRECTW) {
76fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        const EMREXTCREATEFONTINDIRECTW* createFontRecord = reinterpret_cast<const EMREXTCREATEFONTINDIRECTW*>(record);
77fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        *reinterpret_cast<LOGFONT*>(logFont) = createFontRecord->elfw.elfLogFont;
78808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
79808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return true;
80fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato}
81fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
82808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic int CALLBACK linkedFontEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM hfont)
83808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
84808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    *reinterpret_cast<HFONT*>(hfont) = CreateFontIndirect(logFont);
85808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return false;
86808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
87808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
88808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic const Vector<String>* getLinkedFonts(String& family)
89808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
90808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static HashMap<String, Vector<String>*> systemLinkMap;
91808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Vector<String>* result = systemLinkMap.get(family);
92808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (result)
93808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return result;
94808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
95808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    result = new Vector<String>;
96808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    systemLinkMap.set(family, result);
97808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HKEY fontLinkKey;
98fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    if (FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink", 0, KEY_READ, &fontLinkKey)))
99808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return result;
100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    DWORD linkedFontsBufferSize = 0;
102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    RegQueryValueEx(fontLinkKey, family.charactersWithNullTermination(), 0, NULL, NULL, &linkedFontsBufferSize);
103fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    WCHAR* linkedFonts = reinterpret_cast<WCHAR*>(malloc(linkedFontsBufferSize));
104808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (SUCCEEDED(RegQueryValueEx(fontLinkKey, family.charactersWithNullTermination(), 0, NULL, reinterpret_cast<BYTE*>(linkedFonts), &linkedFontsBufferSize))) {
105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        unsigned i = 0;
106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        unsigned length = linkedFontsBufferSize / sizeof(*linkedFonts);
107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        while (i < length) {
108808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            while (i < length && linkedFonts[i] != ',')
109808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                i++;
110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            i++;
111808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            unsigned j = i;
112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            while (j < length && linkedFonts[j])
113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                j++;
114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            result->append(String(linkedFonts + i, j - i));
115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            i = j + 1;
116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
118808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    free(linkedFonts);
119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    RegCloseKey(fontLinkKey);
120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return result;
121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
123808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic const Vector<DWORD, 4>& getCJKCodePageMasks()
124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // The default order in which we look for a font for a CJK character. If the user's default code page is
126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // one of these, we will use it first.
127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static const UINT CJKCodePages[] = {
128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        932, /* Japanese */
129808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        936, /* Simplified Chinese */
130808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        950, /* Traditional Chinese */
131808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        949  /* Korean */
132808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static Vector<DWORD, 4> codePageMasks;
135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static bool initialized;
136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!initialized) {
137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        initialized = true;
138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface();
139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!langFontLink)
140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return codePageMasks;
141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
142808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        UINT defaultCodePage;
143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DWORD defaultCodePageMask = 0;
144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE, reinterpret_cast<LPWSTR>(&defaultCodePage), sizeof(defaultCodePage)))
145808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            langFontLink->CodePageToCodePages(defaultCodePage, &defaultCodePageMask);
146808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (defaultCodePage == CJKCodePages[0] || defaultCodePage == CJKCodePages[1] || defaultCodePage == CJKCodePages[2] || defaultCodePage == CJKCodePages[3])
148808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            codePageMasks.append(defaultCodePageMask);
149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        for (unsigned i = 0; i < 4; ++i) {
150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (defaultCodePage != CJKCodePages[i]) {
151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                DWORD codePageMask;
152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                langFontLink->CodePageToCodePages(CJKCodePages[i], &codePageMask);
153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                codePageMasks.append(codePageMask);
154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return codePageMasks;
158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic bool currentFontContainsCharacter(HDC hdc, UChar character)
161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static Vector<char, 512> glyphsetBuffer;
163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    glyphsetBuffer.resize(GetFontUnicodeRanges(hdc, 0));
164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    GLYPHSET* glyphset = reinterpret_cast<GLYPHSET*>(glyphsetBuffer.data());
165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    GetFontUnicodeRanges(hdc, glyphset);
166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // FIXME: Change this to a binary search.
168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    unsigned i = 0;
169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    while (i < glyphset->cRanges && glyphset->ranges[i].wcLow <= character)
170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        i++;
171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return i && glyphset->ranges[i - 1].wcLow + glyphset->ranges[i - 1].cGlyphs > character;
173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic HFONT createMLangFont(IMLangFontLink2* langFontLink, HDC hdc, DWORD codePageMask, UChar character = 0)
176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT MLangFont;
178808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT hfont = 0;
179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (SUCCEEDED(langFontLink->MapFont(hdc, codePageMask, character, &MLangFont)) && MLangFont) {
180808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        LOGFONT lf;
181808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        GetObject(MLangFont, sizeof(LOGFONT), &lf);
182808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        langFontLink->ReleaseFont(MLangFont);
183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        hfont = CreateFontIndirect(&lf);
184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return hfont;
186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoconst SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    UChar character = characters[0];
191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    SimpleFontData* fontData = 0;
192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HDC hdc = GetDC(0);
193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT primaryFont = font.primaryFont()->fontDataForCharacter(character)->platformData().hfont();
194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HGDIOBJ oldFont = SelectObject(hdc, primaryFont);
195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT hfont = 0;
196f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
197f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    if (IMLangFontLink2* langFontLink = getFontLinkInterface()) {
198f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        // Try MLang font linking first.
199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DWORD codePages = 0;
200f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        langFontLink->GetCharCodePages(character, &codePages);
201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (codePages && findCharUnicodeRange(character) == cRangeSetCJK) {
203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // The CJK character may belong to multiple code pages. We want to
204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // do font linking against a single one of them, preferring the default
205fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            // code page for the user's locale.
206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            const Vector<DWORD, 4>& CJKCodePageMasks = getCJKCodePageMasks();
207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            unsigned numCodePages = CJKCodePageMasks.size();
208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (unsigned i = 0; i < numCodePages && !hfont; ++i) {
209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                hfont = createMLangFont(langFontLink, hdc, CJKCodePageMasks[i]);
210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (hfont && !(codePages & CJKCodePageMasks[i])) {
211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // We asked about a code page that is not one of the code pages
212f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    // returned by MLang, so the font might not contain the character.
213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    SelectObject(hdc, hfont);
214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    if (!currentFontContainsCharacter(hdc, character)) {
215808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        DeleteObject(hfont);
216808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        hfont = 0;
217808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    }
218808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    SelectObject(hdc, primaryFont);
219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else
222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            hfont = createMLangFont(langFontLink, hdc, codePages, character);
223808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
224808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
225808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // A font returned from MLang is trusted to contain the character.
226fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    bool containsCharacter = hfont;
227fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
228808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!hfont) {
229808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // To find out what font Uniscribe would use, we make it draw into a metafile and intercept
230808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // calls to CreateFontIndirect().
231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        HDC metaFileDc = CreateEnhMetaFile(hdc, NULL, NULL, NULL);
232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        SelectObject(metaFileDc, primaryFont);
233808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        bool scriptStringOutSucceeded = false;
235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        SCRIPT_STRING_ANALYSIS ssa;
236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // FIXME: If length is greater than 1, we actually return the font for the last character.
238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // This function should be renamed getFontDataForCharacter and take a single 32-bit character.
239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SUCCEEDED(ScriptStringAnalyse(metaFileDc, characters, length, 0, -1, SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK,
240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            0, NULL, NULL, NULL, NULL, NULL, &ssa))) {
241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            scriptStringOutSucceeded = SUCCEEDED(ScriptStringOut(ssa, 0, 0, 0, NULL, 0, 0, FALSE));
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            ScriptStringFree(&ssa);
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        HENHMETAFILE metaFile = CloseEnhMetaFile(metaFileDc);
245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (scriptStringOutSucceeded) {
246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            LOGFONT logFont;
247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            logFont.lfFaceName[0] = 0;
248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            EnumEnhMetaFile(0, metaFile, metaFileEnumProc, &logFont, NULL);
249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (logFont.lfFaceName[0])
250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                hfont = CreateFontIndirect(&logFont);
251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DeleteEnhMetaFile(metaFile);
253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    String familyName;
256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    const Vector<String>* linkedFonts = 0;
257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    unsigned linkedFontIndex = 0;
258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    while (hfont) {
259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        SelectObject(hdc, hfont);
260808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WCHAR name[LF_FACESIZE];
261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        GetTextFace(hdc, LF_FACESIZE, name);
262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        familyName = name;
263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (containsCharacter || currentFontContainsCharacter(hdc, character))
265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            break;
266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
267808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!linkedFonts)
268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            linkedFonts = getLinkedFonts(familyName);
269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        SelectObject(hdc, oldFont);
270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DeleteObject(hfont);
271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        hfont = 0;
272808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (linkedFonts->size() <= linkedFontIndex)
274808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            break;
275808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
276808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        LOGFONT logFont;
277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        logFont.lfCharSet = DEFAULT_CHARSET;
278808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        memcpy(logFont.lfFaceName, linkedFonts->at(linkedFontIndex).characters(), linkedFonts->at(linkedFontIndex).length() * sizeof(WCHAR));
279808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        logFont.lfFaceName[linkedFonts->at(linkedFontIndex).length()] = 0;
280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        EnumFontFamiliesEx(hdc, &logFont, linkedFontEnumProc, reinterpret_cast<LPARAM>(&hfont), 0);
281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        linkedFontIndex++;
282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
283808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
284808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (hfont) {
285808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!familyName.isEmpty()) {
286808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            FontPlatformData* result = getCachedFontPlatformData(font.fontDescription(), familyName);
287808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (result)
288808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                fontData = getCachedFontData(result);
289808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
290dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato
291f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        SelectObject(hdc, oldFont);
292dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato        DeleteObject(hfont);
293dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    }
294dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato
295dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    ReleaseDC(0, hdc);
296dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    return fontData;
297808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
299808182dc874e93582da38d013a4a790d6bc08fc9Joe OnoratoSimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
300808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
30129fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato    return 0;
302808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
303808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic SimpleFontData* fontDataFromDescriptionAndLogFont(FontCache* fontCache, const FontDescription& fontDescription, const LOGFONT& font, AtomicString& outFontFamilyName)
305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
30646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    AtomicString familyName = String(font.lfFaceName, wcsnlen(font.lfFaceName, LF_FACESIZE));
30746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    SimpleFontData* fontData = fontCache->getCachedFontData(fontDescription, familyName);
308808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (fontData)
309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        outFontFamilyName = familyName;
310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return fontData;
311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
313808182dc874e93582da38d013a4a790d6bc08fc9Joe OnoratoSimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    DEFINE_STATIC_LOCAL(AtomicString, fallbackFontName, ());
316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!fallbackFontName.isEmpty())
317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return getCachedFontData(fontDescription, fallbackFontName);
318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // FIXME: Would be even better to somehow get the user's default font here.  For now we'll pick
320f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    // the default that the user would get without changing any prefs.
321808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Search all typical Windows-installed full Unicode fonts.
323808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Sorted by most to least glyphs according to http://en.wikipedia.org/wiki/Unicode_typefaces
324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Start with Times New Roman also since it is the default if the user doesn't change prefs.
325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static AtomicString fallbackFonts[] = {
326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        AtomicString("Times New Roman"),
327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        AtomicString("Microsoft Sans Serif"),
328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        AtomicString("Tahoma"),
329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        AtomicString("Lucida Sans Unicode"),
330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        AtomicString("Arial")
331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
332808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    SimpleFontData* simpleFont;
333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    for (size_t i = 0; i < WTF_ARRAY_LENGTH(fallbackFonts); ++i) {
334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = getCachedFontData(fontDescription, fallbackFonts[i])) {
335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            fallbackFontName = fallbackFonts[i];
336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
340808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Fall back to the DEFAULT_GUI_FONT if no known Unicode fonts are available.
341808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT))) {
342808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        LOGFONT defaultGUILogFont;
343808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont);
344808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, defaultGUILogFont, fallbackFontName))
345808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
346808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
347808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
348808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Fall back to Non-client metrics fonts.
349808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    NONCLIENTMETRICS nonClientMetrics = {0};
350808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    nonClientMetrics.cbSize = sizeof(nonClientMetrics);
351379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
352808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, nonClientMetrics.lfMessageFont, fallbackFontName))
353808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
354808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, nonClientMetrics.lfMenuFont, fallbackFontName))
355808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
356808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, nonClientMetrics.lfStatusFont, fallbackFontName))
357808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, nonClientMetrics.lfCaptionFont, fallbackFontName))
359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (simpleFont = fontDataFromDescriptionAndLogFont(this, fontDescription, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return simpleFont;
362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ASSERT_NOT_REACHED();
365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return 0;
366808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
367808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
368808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic LONG toGDIFontWeight(FontWeight fontWeight)
369808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
370808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static LONG gdiFontWeights[] = {
371808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_THIN,        // FontWeight100
372808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_EXTRALIGHT,  // FontWeight200
373808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_LIGHT,       // FontWeight300
374808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_NORMAL,      // FontWeight400
375808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_MEDIUM,      // FontWeight500
376808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_SEMIBOLD,    // FontWeight600
377808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_BOLD,        // FontWeight700
378808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_EXTRABOLD,   // FontWeight800
379808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FW_HEAVY        // FontWeight900
380808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
381808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return gdiFontWeights[fontWeight];
382808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
383808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
384808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic inline bool isGDIFontWeightBold(LONG gdiFontWeight)
385808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
386808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return gdiFontWeight >= FW_SEMIBOLD;
387808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
388808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
389808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic LONG adjustedGDIFontWeight(LONG gdiFontWeight, const String& family)
390808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
391808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static AtomicString lucidaStr("Lucida Grande");
392808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (equalIgnoringCase(family, lucidaStr)) {
393808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (gdiFontWeight == FW_NORMAL)
394808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return FW_MEDIUM;
395808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (gdiFontWeight == FW_BOLD)
396808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return FW_SEMIBOLD;
397379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    }
398379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    return gdiFontWeight;
399808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
400808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
401379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandlerstruct MatchImprovingProcData {
402379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler    MatchImprovingProcData(LONG desiredWeight, bool desiredItalic)
403808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        : m_desiredWeight(desiredWeight)
404808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        , m_desiredItalic(desiredItalic)
405808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        , m_hasMatched(false)
406808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    {
407808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
408808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
409808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LONG m_desiredWeight;
410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool m_desiredItalic;
411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool m_hasMatched;
412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LOGFONT m_chosen;
413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato};
414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic int CALLBACK matchImprovingEnumProc(CONST LOGFONT* candidate, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam)
416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
417808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    MatchImprovingProcData* matchData = reinterpret_cast<MatchImprovingProcData*>(lParam);
418808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
419808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!matchData->m_hasMatched) {
420808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        matchData->m_hasMatched = true;
421808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        matchData->m_chosen = *candidate;
422808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 1;
423808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
424808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
425808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!candidate->lfItalic != !matchData->m_chosen.lfItalic) {
426808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!candidate->lfItalic == !matchData->m_desiredItalic)
427808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            matchData->m_chosen = *candidate;
428808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
429808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 1;
430808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
431808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
432808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    unsigned chosenWeightDeltaMagnitude = abs(matchData->m_chosen.lfWeight - matchData->m_desiredWeight);
433808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    unsigned candidateWeightDeltaMagnitude = abs(candidate->lfWeight - matchData->m_desiredWeight);
434808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
435808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // If both are the same distance from the desired weight, prefer the candidate if it is further from regular.
436808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude && abs(candidate->lfWeight - FW_NORMAL) > abs(matchData->m_chosen.lfWeight - FW_NORMAL)) {
437f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        matchData->m_chosen = *candidate;
438808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 1;
439808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
440808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
441808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Otherwise, prefer the one closer to the desired weight.
442808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude)
443184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        matchData->m_chosen = *candidate;
444184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato
445808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return 1;
446808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
447808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
448808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostatic HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool desiredItalic, int size, bool synthesizeItalic)
449808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato{
450808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HDC hdc = GetDC(0);
451808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LOGFONT logFont;
453808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    logFont.lfCharSet = DEFAULT_CHARSET;
454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    unsigned familyLength = min(family.length(), static_cast<unsigned>(LF_FACESIZE - 1));
455808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    memcpy(logFont.lfFaceName, family.characters(), familyLength * sizeof(UChar));
456808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    logFont.lfFaceName[familyLength] = 0;
457808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    logFont.lfPitchAndFamily = 0;
458808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
459808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    MatchImprovingProcData matchData(desiredWeight, desiredItalic);
460808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    EnumFontFamiliesEx(hdc, &logFont, matchImprovingEnumProc, reinterpret_cast<LPARAM>(&matchData), 0);
461808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
462808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ReleaseDC(0, hdc);
463808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
464808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!matchData.m_hasMatched)
465808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 0;
466808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
467808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfHeight = -size;
468935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato    matchData.m_chosen.lfWidth = 0;
469935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato    matchData.m_chosen.lfEscapement = 0;
470935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato    matchData.m_chosen.lfOrientation = 0;
471935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato    matchData.m_chosen.lfUnderline = false;
472935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato    matchData.m_chosen.lfStrikeOut = false;
473808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfCharSet = DEFAULT_CHARSET;
474808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#if USE(CG) || USE(CAIRO)
475808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfOutPrecision = OUT_TT_ONLY_PRECIS;
476808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#else
477808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfOutPrecision = OUT_TT_PRECIS;
478808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#endif
479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfQuality = DEFAULT_QUALITY;
480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
481808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato   if (desiredItalic && !matchData.m_chosen.lfItalic && synthesizeItalic)
483808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato       matchData.m_chosen.lfItalic = 1;
484808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
485808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT result = CreateFontIndirect(&matchData.m_chosen);
486808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!result)
487808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 0;
488808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
489808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HDC dc = GetDC(0);
490808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    SaveDC(dc);
491808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    SelectObject(dc, result);
492808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WCHAR actualName[LF_FACESIZE];
493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    GetTextFace(dc, LF_FACESIZE, actualName);
494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    RestoreDC(dc, -1);
495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ReleaseDC(0, dc);
496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (wcsicmp(matchData.m_chosen.lfFaceName, actualName)) {
498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DeleteObject(result);
499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        result = 0;
500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return result;
503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratostruct TraitsInFamilyProcData {
506808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TraitsInFamilyProcData(const AtomicString& familyName)
507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        : m_familyName(familyName)
508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    {
509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
510f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
511f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    const AtomicString& m_familyName;
512755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato    HashSet<unsigned> m_traitsMasks;
513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato};
514b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
515b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandlerstatic int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam)
516b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler{
517b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam);
518b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
519b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    unsigned traitsMask = 0;
520b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask;
521b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    traitsMask |= FontVariantNormalMask;
522b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    LONG weight = adjustedGDIFontWeight(logFont->lfWeight, procData->m_familyName);
523b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    traitsMask |= weight == FW_THIN ? FontWeight100Mask :
524b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_EXTRALIGHT ? FontWeight200Mask :
525b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_LIGHT ? FontWeight300Mask :
526b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_NORMAL ? FontWeight400Mask :
527b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_MEDIUM ? FontWeight500Mask :
528b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_SEMIBOLD ? FontWeight600Mask :
529b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_BOLD ? FontWeight700Mask :
530b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        weight == FW_EXTRABOLD ? FontWeight800Mask :
531b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                                 FontWeight900Mask;
532b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    procData->m_traitsMasks.add(traitsMask);
533b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    return 1;
534b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler}
535b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandlervoid FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
536b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler{
537b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    HDC hdc = GetDC(0);
538b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
539b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    LOGFONT logFont;
540b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    logFont.lfCharSet = DEFAULT_CHARSET;
541b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1));
542b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar));
543b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    logFont.lfFaceName[familyLength] = 0;
544b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler    logFont.lfPitchAndFamily = 0;
545b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TraitsInFamilyProcData procData(familyName);
547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0);
548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    copyToVector(procData.m_traitsMasks, traitsMasks);
549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ReleaseDC(0, hdc);
551808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
553808182dc874e93582da38d013a4a790d6bc08fc9Joe OnoratoFontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
554184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato{
555184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato    bool isLucidaGrande = false;
556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static AtomicString lucidaStr("Lucida Grande");
557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (equalIgnoringCase(family, lucidaStr))
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        isLucidaGrande = true;
559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool useGDI = fontDescription.renderingMode() == AlternateRenderingMode && !isLucidaGrande;
561f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // The logical size constant is 32. We do this for subpixel precision when rendering using Uniscribe.
563808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // This masks rounding errors related to the HFONT metrics being  different from the CGFont metrics.
564808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // FIXME: We will eventually want subpixel precision for GDI mode, but the scaled rendering doesn't
565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // look as nice. That may be solvable though.
566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LONG weight = adjustedGDIFontWeight(toGDIFontWeight(fontDescription.weight()), family);
567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    HFONT hfont = createGDIFont(family, weight, fontDescription.italic(),
568808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                fontDescription.computedPixelSize() * (useGDI ? 1 : 32), useGDI);
569808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
570808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (!hfont)
571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 0;
572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (isLucidaGrande)
574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        useGDI = false; // Never use GDI for Lucida Grande.
575808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LOGFONT logFont;
577808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    GetObject(hfont, sizeof(LOGFONT), &logFont);
578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
579808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool synthesizeBold = isGDIFontWeightBold(weight) && !isGDIFontWeightBold(logFont.lfWeight);
580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool synthesizeItalic = fontDescription.italic() && !logFont.lfItalic;
581808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
582808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), synthesizeBold, synthesizeItalic, useGDI);
583808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
584808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#if USE(CG)
585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool fontCreationFailed = !result->cgFont();
586808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#elif USE(CAIRO)
587808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    bool fontCreationFailed = !result->scaledFont();
588808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato#endif
589808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
590808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    if (fontCreationFailed) {
591808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // The creation of the CGFontRef failed for some reason.  We already asserted in debug builds, but to make
592808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // absolutely sure that we don't use this font, go ahead and return 0 so that we can fall back to the next
593808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // font.
594808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        delete result;
595808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        DeleteObject(hfont);
596808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return 0;
597808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
598808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
599808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    return result;
600f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato}
601808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
602808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
603808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato