2c79815b16a6a084c598d540d1cda4f9a4480c41
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / FontCacheChromiumWin.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Computer, Inc.
3  * Copyright (c) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
4  * 
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  * 
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33 #include "FontCache.h"
34
35 #include "ChromiumBridge.h"
36 #include "Font.h"
37 #include "FontUtilsChromiumWin.h"
38 #include "HashMap.h"
39 #include "HashSet.h"
40 #include "SimpleFontData.h"
41 #include <unicode/uniset.h>
42 #include <wtf/text/StringHash.h>
43
44 #include <windows.h>
45 #include <objidl.h>
46 #include <mlang.h>
47
48 using std::min;
49
50 namespace WebCore
51 {
52
53 // FIXME: consider adding to WebKit String class
54 static bool charactersAreAllASCII(const String& s)
55 {
56     return WTF::charactersAreAllASCII(s.characters(), s.length());
57 }
58
59 // When asked for a CJK font with a native name under a non-CJK locale or
60 // asked for a CJK font with a Romanized name under a CJK locale,
61 // |GetTextFace| (after |CreateFont*|) returns a 'bogus' value (e.g. Arial).
62 // This is not consistent with what MSDN says !!
63 // Therefore, before we call |CreateFont*|, we have to map a Romanized name to 
64 // the corresponding native name under a CJK locale and vice versa 
65 // under a non-CJK locale.
66 // See the corresponding gecko bugs at 
67 // https://bugzilla.mozilla.org/show_bug.cgi?id=373952
68 // https://bugzilla.mozilla.org/show_bug.cgi?id=231426
69 static bool LookupAltName(const String& name, String& altName)
70 {
71     struct FontCodepage {
72         WCHAR* name;
73         int codePage;
74     };
75
76     struct NamePair {
77         WCHAR* name;
78         FontCodepage altNameCodepage;
79     };
80
81     const int japaneseCodepage = 932;
82     const int simplifiedChineseCodepage = 936;
83     const int koreanCodepage = 949;
84     const int traditionalChineseCodepage = 950;
85
86     // FIXME(jungshik) : This list probably covers 99% of cases.
87     // To cover the remaining 1% and cut down the file size,
88     // consider accessing 'NAME' table of a truetype font
89     // using |GetFontData| and caching the mapping.
90     // In the table below, the ASCII keys are all lower-cased for
91     // case-insensitive matching.
92     static const NamePair namePairs[] = {
93         // MS Pゴシック, MS PGothic
94         {L"\xFF2D\xFF33 \xFF30\x30B4\x30B7\x30C3\x30AF", {L"MS PGothic", japaneseCodepage}},
95         {L"ms pgothic", {L"\xFF2D\xFF33 \xFF30\x30B4\x30B7\x30C3\x30AF", japaneseCodepage}},
96         // MS P明朝, MS PMincho
97         {L"\xFF2D\xFF33 \xFF30\x660E\x671D", {L"MS PMincho", japaneseCodepage}},
98         {L"ms pmincho", {L"\xFF2D\xFF33 \xFF30\x660E\x671D", japaneseCodepage}},
99         // MSゴシック, MS Gothic
100         {L"\xFF2D\xFF33 \x30B4\x30B7\x30C3\x30AF", {L"MS Gothic", japaneseCodepage}},
101         {L"ms gothic", {L"\xFF2D\xFF33 \x30B4\x30B7\x30C3\x30AF", japaneseCodepage}},
102         // MS 明朝, MS Mincho
103         {L"\xFF2D\xFF33 \x660E\x671D", {L"MS Mincho", japaneseCodepage}},
104         {L"ms mincho", {L"\xFF2D\xFF33 \x660E\x671D", japaneseCodepage}},
105         // メイリオ, Meiryo
106         {L"\x30E1\x30A4\x30EA\x30AA", {L"Meiryo", japaneseCodepage}},
107         {L"meiryo", {L"\x30E1\x30A4\x30EA\x30AA", japaneseCodepage}},
108         // 바탕, Batang
109         {L"\xBC14\xD0D5", {L"Batang", koreanCodepage}},
110         {L"batang", {L"\xBC14\xD0D5", koreanCodepage}},
111         // 바탕체, Batangche
112         {L"\xBC14\xD0D5\xCCB4", {L"Batangche", koreanCodepage}},
113         {L"batangche", {L"\xBC14\xD0D5\xCCB4", koreanCodepage}},
114         // 굴림, Gulim
115         {L"\xAD74\xB9BC", {L"Gulim", koreanCodepage}},
116         {L"gulim", {L"\xAD74\xB9BC", koreanCodepage}},
117         // 굴림체, Gulimche
118         {L"\xAD74\xB9BC\xCCB4", {L"Gulimche", koreanCodepage}},
119         {L"gulimche", {L"\xAD74\xB9BC\xCCB4", koreanCodepage}},
120         // 돋움, Dotum
121         {L"\xB3CB\xC6C0", {L"Dotum", koreanCodepage}},
122         {L"dotum", {L"\xB3CB\xC6C0", koreanCodepage}},
123         // 돋움체, Dotumche
124         {L"\xB3CB\xC6C0\xCCB4", {L"Dotumche", koreanCodepage}},
125         {L"dotumche", {L"\xB3CB\xC6C0\xCCB4", koreanCodepage}},
126         // 궁서, Gungsuh
127         {L"\xAD81\xC11C", {L"Gungsuh", koreanCodepage}},
128         {L"gungsuh", {L"\xAD81\xC11C", koreanCodepage}},
129         // 궁서체, Gungsuhche
130         {L"\xAD81\xC11C\xCCB4", {L"Gungsuhche", koreanCodepage}},
131         {L"gungsuhche", {L"\xAD81\xC11C\xCCB4", koreanCodepage}},
132         // 맑은 고딕, Malgun Gothic
133         {L"\xB9D1\xC740 \xACE0\xB515", {L"Malgun Gothic", koreanCodepage}},
134         {L"malgun gothic", {L"\xB9D1\xC740 \xACE0\xB515", koreanCodepage}},
135         // 宋体, SimSun
136         {L"\x5B8B\x4F53", {L"SimSun", simplifiedChineseCodepage}},
137         {L"simsun", {L"\x5B8B\x4F53", simplifiedChineseCodepage}},
138         // 宋体-ExtB, SimSun-ExtB
139         {L"\x5B8B\x4F53-ExtB", {L"SimSun-ExtB", simplifiedChineseCodepage}},
140         {L"simsun-extb", {L"\x5B8B\x4F53-extb", simplifiedChineseCodepage}},
141         // 黑体, SimHei
142         {L"\x9ED1\x4F53", {L"SimHei", simplifiedChineseCodepage}},
143         {L"simhei", {L"\x9ED1\x4F53", simplifiedChineseCodepage}},
144         // 新宋体, NSimSun
145         {L"\x65B0\x5B8B\x4F53", {L"NSimSun", simplifiedChineseCodepage}},
146         {L"nsimsun", {L"\x65B0\x5B8B\x4F53", simplifiedChineseCodepage}},
147         // 微软雅黑, Microsoft Yahei
148         {L"\x5FAE\x8F6F\x96C5\x9ED1", {L"Microsoft Yahei", simplifiedChineseCodepage}},
149         {L"microsoft yahei", {L"\x5FAE\x8F6F\x96C5\x9ED1", simplifiedChineseCodepage}},
150         // 仿宋, FangSong
151         {L"\x4EFF\x5B8B",  {L"FangSong", simplifiedChineseCodepage}},
152         {L"fangsong", {L"\x4EFF\x5B8B", simplifiedChineseCodepage}},
153         // 楷体, KaiTi
154         {L"\x6977\x4F53", {L"KaiTi", simplifiedChineseCodepage}},
155         {L"kaiti", {L"\x6977\x4F53", simplifiedChineseCodepage}},
156         // 仿宋_GB2312, FangSong_GB2312
157         {L"\x4EFF\x5B8B_GB2312",  {L"FangSong_GB2312", simplifiedChineseCodepage}},
158         {L"fangsong_gb2312", {L"\x4EFF\x5B8B_gb2312", simplifiedChineseCodepage}},
159         // 楷体_GB2312, KaiTi_GB2312
160         {L"\x6977\x4F53", {L"KaiTi_GB2312", simplifiedChineseCodepage}},
161         {L"kaiti_gb2312", {L"\x6977\x4F53_gb2312", simplifiedChineseCodepage}},
162         // 新細明體, PMingLiu
163         {L"\x65B0\x7D30\x660E\x9AD4", {L"PMingLiu", traditionalChineseCodepage}},
164         {L"pmingliu", {L"\x65B0\x7D30\x660E\x9AD4", traditionalChineseCodepage}},
165         // 新細明體-ExtB, PMingLiu-ExtB
166         {L"\x65B0\x7D30\x660E\x9AD4-ExtB", {L"PMingLiu-ExtB", traditionalChineseCodepage}},
167         {L"pmingliu-extb", {L"\x65B0\x7D30\x660E\x9AD4-extb", traditionalChineseCodepage}},
168         // 細明體, MingLiu
169         {L"\x7D30\x660E\x9AD4", {L"MingLiu", traditionalChineseCodepage}},
170         {L"mingliu", {L"\x7D30\x660E\x9AD4", traditionalChineseCodepage}},
171         // 細明體-ExtB, MingLiu-ExtB
172         {L"\x7D30\x660E\x9AD4-ExtB", {L"MingLiu-ExtB", traditionalChineseCodepage}},
173         {L"mingliu-extb", {L"x65B0\x7D30\x660E\x9AD4-extb", traditionalChineseCodepage}},
174         // 微軟正黑體, Microsoft JhengHei
175         {L"\x5FAE\x8EDF\x6B63\x9ED1\x9AD4", {L"Microsoft JhengHei", traditionalChineseCodepage}},
176         {L"microsoft jhengHei", {L"\x5FAE\x8EDF\x6B63\x9ED1\x9AD4", traditionalChineseCodepage}},
177         // 標楷體, DFKai-SB
178         {L"\x6A19\x6977\x9AD4", {L"DFKai-SB", traditionalChineseCodepage}},
179         {L"dfkai-sb", {L"\x6A19\x6977\x9AD4", traditionalChineseCodepage}},
180         // WenQuanYi Zen Hei
181         {L"\x6587\x6cc9\x9a5b\x6b63\x9ed1", {L"WenQuanYi Zen Hei", traditionalChineseCodepage}},
182         {L"wenquanyi zen hei", {L"\x6587\x6cc9\x9a5b\x6b63\x9ed1", traditionalChineseCodepage}},
183         // WenQuanYi Zen Hei
184         {L"\x6587\x6cc9\x9a7f\x6b63\x9ed1", {L"WenQuanYi Zen Hei", simplifiedChineseCodepage}},
185         {L"wenquanyi zen hei", {L"\x6587\x6cc9\x9a7f\x6b63\x9ed1", simplifiedChineseCodepage}},
186         // AR PL ShanHeiSun Uni,
187         {L"\x6587\x9f0e\x0050\x004c\x7d30\x4e0a\x6d77\x5b8b\x0055\x006e\x0069",
188          {L"AR PL ShanHeiSun Uni", traditionalChineseCodepage}},
189         {L"ar pl shanheisun uni",
190          {L"\x6587\x9f0e\x0050\x004c\x7d30\x4e0a\x6d77\x5b8b\x0055\x006e\x0069", traditionalChineseCodepage}},
191         // AR PL ShanHeiSun Uni,
192         {L"\x6587\x9f0e\x0050\x004c\x7ec6\x4e0a\x6d77\x5b8b\x0055\x006e\x0069",
193          {L"AR PL ShanHeiSun Uni", simplifiedChineseCodepage}},
194         {L"ar pl shanheisun uni",
195          {L"\x6587\x9f0e\x0050\x004c\x7ec6\x4e0a\x6d77\x5b8b\x0055\x006e\x0069", simplifiedChineseCodepage}},
196         // AR PL ZenKai Uni
197         // Traditional Chinese and Simplified Chinese names are
198         // identical.
199         {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x0069", {L"AR PL ZenKai Uni", traditionalChineseCodepage}},
200         {L"ar pl zenkai uni", {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x0069", traditionalChineseCodepage}},
201         {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x0069", {L"AR PL ZenKai Uni", simplifiedChineseCodepage}},
202         {L"ar pl zenkai uni", {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x0069", simplifiedChineseCodepage}},
203     };
204
205     typedef HashMap<String, const FontCodepage*> NameMap;
206     static NameMap* fontNameMap = 0;
207
208     if (!fontNameMap) {
209         fontNameMap = new NameMap;
210         for (size_t i = 0; i < WTF_ARRAY_LENGTH(namePairs); ++i)
211             fontNameMap->set(String(namePairs[i].name), &(namePairs[i].altNameCodepage));
212     }
213
214     bool isAscii = false; 
215     String n;
216     // use |lower| only for ASCII names 
217     // For non-ASCII names, we don't want to invoke an expensive 
218     // and unnecessary |lower|. 
219     if (charactersAreAllASCII(name)) {
220         isAscii = true;
221         n = name.lower();
222     } else
223         n = name;
224
225     NameMap::iterator iter = fontNameMap->find(n);
226     if (iter == fontNameMap->end())
227         return false;
228
229     static int systemCp = ::GetACP();
230     int fontCp = iter->second->codePage;
231
232     if ((isAscii && systemCp == fontCp) || (!isAscii && systemCp != fontCp)) {
233         altName = String(iter->second->name);
234         return true;
235     }
236
237     return false;
238 }
239
240 static HFONT createFontIndirectAndGetWinName(const String& family, LOGFONT* winfont, String* winName)
241 {
242     int len = min(static_cast<int>(family.length()), LF_FACESIZE - 1);
243     memcpy(winfont->lfFaceName, family.characters(), len * sizeof(WORD));
244     winfont->lfFaceName[len] = '\0';
245
246     HFONT hfont = CreateFontIndirect(winfont);
247     if (!hfont)
248         return 0;
249
250     HDC dc = GetDC(0);
251     HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont));
252     WCHAR name[LF_FACESIZE];
253     unsigned resultLength = GetTextFace(dc, LF_FACESIZE, name);
254     if (resultLength > 0)
255         resultLength--; // ignore the null terminator
256
257     SelectObject(dc, oldFont);
258     ReleaseDC(0, dc);
259     *winName = String(name, resultLength);
260     return hfont;
261 }
262
263 // This maps font family names to their repertoires of supported Unicode
264 // characters. Because it's family names rather than font faces we use
265 // as keys, there might be edge cases where one face of a font family
266 // has a different repertoire from another face of the same family. 
267 typedef HashMap<const wchar_t*, icu::UnicodeSet*> FontCmapCache;
268
269 static bool fontContainsCharacter(const FontPlatformData* fontData,
270                                   const wchar_t* family, UChar32 character)
271 {
272     // FIXME: For non-BMP characters, GetFontUnicodeRanges is of
273     // no use. We have to read directly from the cmap table of a font.
274     // Return true for now.
275     if (character > 0xFFFF)
276         return true;
277
278     // This cache is just leaked on shutdown.
279     static FontCmapCache* fontCmapCache = 0;
280     if (!fontCmapCache)
281         fontCmapCache = new FontCmapCache;
282
283     HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find(family);
284     if (it != fontCmapCache->end()) 
285         return it->second->contains(character);
286     
287     HFONT hfont = fontData->hfont(); 
288     HDC hdc = GetDC(0);
289     HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(hdc, hfont));
290     int count = GetFontUnicodeRanges(hdc, 0);
291     if (count == 0 && ChromiumBridge::ensureFontLoaded(hfont))
292         count = GetFontUnicodeRanges(hdc, 0);
293     if (count == 0) {
294         LOG_ERROR("Unable to get the font unicode range after second attempt");
295         SelectObject(hdc, oldFont);
296         ReleaseDC(0, hdc);
297         return true;
298     }
299
300     static Vector<char, 512> glyphsetBuffer;
301     glyphsetBuffer.resize(GetFontUnicodeRanges(hdc, 0));
302     GLYPHSET* glyphset = reinterpret_cast<GLYPHSET*>(glyphsetBuffer.data());
303     // In addition, refering to the OS/2 table and converting the codepage list
304     // to the coverage map might be faster. 
305     count = GetFontUnicodeRanges(hdc, glyphset);
306     ASSERT(count > 0);
307     SelectObject(hdc, oldFont);
308     ReleaseDC(0, hdc);
309
310     // FIXME: consider doing either of the following two:
311     // 1) port back ICU 4.0's faster look-up code for UnicodeSet
312     // 2) port Mozilla's CompressedCharMap or gfxSparseBitset
313     unsigned i = 0;
314     icu::UnicodeSet* cmap = new icu::UnicodeSet;
315     while (i < glyphset->cRanges) {
316         WCHAR start = glyphset->ranges[i].wcLow; 
317         cmap->add(start, start + glyphset->ranges[i].cGlyphs - 1);
318         i++;
319     }
320     cmap->freeze();
321     // We don't lowercase |family| because all of them are under our control
322     // and they're already lowercased. 
323     fontCmapCache->set(family, cmap); 
324     return cmap->contains(character);
325 }
326
327 // Tries the given font and save it |outFontFamilyName| if it succeeds.
328 static SimpleFontData* fontDataFromDescriptionAndLogFont(FontCache* fontCache, const FontDescription& fontDescription, const LOGFONT& font, wchar_t* outFontFamilyName)
329 {
330     SimpleFontData* fontData = fontCache->getCachedFontData(fontDescription, font.lfFaceName);
331     if (fontData)
332         memcpy(outFontFamilyName, font.lfFaceName, sizeof(font.lfFaceName));
333     return fontData;
334 }
335
336 static LONG toGDIFontWeight(FontWeight fontWeight)
337 {
338     static LONG gdiFontWeights[] = {
339         FW_THIN, // FontWeight100
340         FW_EXTRALIGHT, // FontWeight200
341         FW_LIGHT, // FontWeight300
342         FW_NORMAL, // FontWeight400
343         FW_MEDIUM, // FontWeight500
344         FW_SEMIBOLD, // FontWeight600
345         FW_BOLD, // FontWeight700
346         FW_EXTRABOLD, // FontWeight800
347         FW_HEAVY // FontWeight900
348     };
349     return gdiFontWeights[fontWeight];
350 }
351
352 static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont)
353 {
354     // The size here looks unusual.  The negative number is intentional.
355     // Unlike WebKit trunk, we don't multiply the size by 32.  That seems to be
356     // some kind of artifact of their CG backend, or something.
357     winfont->lfHeight = -fontDescription.computedPixelSize();
358     winfont->lfWidth = 0;
359     winfont->lfEscapement = 0;
360     winfont->lfOrientation = 0;
361     winfont->lfUnderline = false;
362     winfont->lfStrikeOut = false;
363     winfont->lfCharSet = DEFAULT_CHARSET;
364     winfont->lfOutPrecision = OUT_TT_ONLY_PRECIS;
365     winfont->lfQuality = ChromiumBridge::layoutTestMode() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY; // Honor user's desktop settings.
366     winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
367     winfont->lfItalic = fontDescription.italic();
368     winfont->lfWeight = toGDIFontWeight(fontDescription.weight());
369 }
370
371 struct TraitsInFamilyProcData {
372     TraitsInFamilyProcData(const AtomicString& familyName)
373         : m_familyName(familyName)
374     {
375     }
376
377     const AtomicString& m_familyName;
378     HashSet<unsigned> m_traitsMasks;
379 };
380
381 static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam)
382 {
383     TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam);
384
385     unsigned traitsMask = 0;
386     traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask;
387     traitsMask |= FontVariantNormalMask;
388     LONG weight = logFont->lfWeight;
389     traitsMask |= weight == FW_THIN ? FontWeight100Mask :
390         weight == FW_EXTRALIGHT ? FontWeight200Mask :
391         weight == FW_LIGHT ? FontWeight300Mask :
392         weight == FW_NORMAL ? FontWeight400Mask :
393         weight == FW_MEDIUM ? FontWeight500Mask :
394         weight == FW_SEMIBOLD ? FontWeight600Mask :
395         weight == FW_BOLD ? FontWeight700Mask :
396         weight == FW_EXTRABOLD ? FontWeight800Mask :
397                                  FontWeight900Mask;
398     procData->m_traitsMasks.add(traitsMask);
399     return 1;
400 }
401
402 void FontCache::platformInit()
403 {
404     // Not needed on Windows.
405 }
406
407 // Given the desired base font, this will create a SimpleFontData for a specific
408 // font that can be used to render the given range of characters.
409 const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
410 {
411     // FIXME: Consider passing fontDescription.dominantScript()
412     // to GetFallbackFamily here.
413     FontDescription fontDescription = font.fontDescription();
414     UChar32 c;
415     UScriptCode script;
416     const wchar_t* family = getFallbackFamily(characters, length,
417         fontDescription.genericFamily(), &c, &script);
418     FontPlatformData* data = 0;
419     if (family)
420         data = getCachedFontPlatformData(font.fontDescription(),  AtomicString(family, wcslen(family)), false); 
421
422     // Last resort font list : PanUnicode. CJK fonts have a pretty
423     // large repertoire. Eventually, we need to scan all the fonts
424     // on the system to have a Firefox-like coverage.
425     // Make sure that all of them are lowercased.
426     const static wchar_t* const cjkFonts[] = {
427         L"arial unicode ms",
428         L"ms pgothic",
429         L"simsun",
430         L"gulim",
431         L"pmingliu",
432         L"wenquanyi zen hei", // partial CJK Ext. A coverage but more
433                               // widely known to Chinese users.
434         L"ar pl shanheisun uni",
435         L"ar pl zenkai uni",
436         L"han nom a",  // Complete CJK Ext. A coverage
437         L"code2000",   // Complete CJK Ext. A coverage
438         // CJK Ext. B fonts are not listed here because it's of no use
439         // with our current non-BMP character handling because we use
440         // Uniscribe for it and that code path does not go through here.
441     };
442
443     const static wchar_t* const commonFonts[] = {
444         L"tahoma",
445         L"arial unicode ms",
446         L"lucida sans unicode",
447         L"microsoft sans serif",
448         L"palatino linotype",
449         // Six fonts below (and code2000 at the end) are not from MS, but
450         // once installed, cover a very wide range of characters.
451         L"dejavu serif",
452         L"dejavu sasns",
453         L"freeserif",
454         L"freesans",
455         L"gentium",
456         L"gentiumalt",
457         L"ms pgothic",
458         L"simsun",
459         L"gulim",
460         L"pmingliu",
461         L"code2000",
462     };
463
464     const wchar_t* const* panUniFonts = 0;
465     int numFonts = 0;
466     if (script == USCRIPT_HAN) {
467         panUniFonts = cjkFonts;
468         numFonts = WTF_ARRAY_LENGTH(cjkFonts);
469     } else {
470         panUniFonts = commonFonts;
471         numFonts = WTF_ARRAY_LENGTH(commonFonts);
472     }
473     // Font returned from GetFallbackFamily may not cover |characters|
474     // because it's based on script to font mapping. This problem is
475     // critical enough for non-Latin scripts (especially Han) to
476     // warrant an additional (real coverage) check with fontCotainsCharacter.
477     int i;
478     for (i = 0; (!data || !fontContainsCharacter(data, family, c)) && i < numFonts; ++i) {
479         family = panUniFonts[i]; 
480         data = getCachedFontPlatformData(font.fontDescription(), AtomicString(family, wcslen(family)));
481     }
482     // When i-th font (0-base) in |panUniFonts| contains a character and
483     // we get out of the loop, |i| will be |i + 1|. That is, if only the
484     // last font in the array covers the character, |i| will be numFonts.
485     // So, we have to use '<=" rather than '<' to see if we found a font
486     // covering the character.
487     if (i <= numFonts) 
488        return getCachedFontData(data);
489
490     return 0;
491
492 }
493
494 SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
495 {
496     return 0;
497 }
498
499 SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description)
500 {
501     FontDescription::GenericFamilyType generic = description.genericFamily();
502
503     // FIXME: Would be even better to somehow get the user's default font here.
504     // For now we'll pick the default that the user would get without changing
505     // any prefs.
506     static AtomicString timesStr("Times New Roman");
507     static AtomicString courierStr("Courier New");
508     static AtomicString arialStr("Arial");
509
510     AtomicString& fontStr = timesStr;
511     if (generic == FontDescription::SansSerifFamily)
512         fontStr = arialStr;
513     else if (generic == FontDescription::MonospaceFamily)
514         fontStr = courierStr;
515
516     SimpleFontData* simpleFont = getCachedFontData(description, fontStr);
517     if (simpleFont)
518         return simpleFont;
519
520     // Fall back to system fonts as Win Safari does because this function must
521     // return a valid font. Once we find a valid system font, we save its name
522     // to a static variable and use it to prevent trying system fonts again.
523     static wchar_t fallbackFontName[LF_FACESIZE] = {0};
524     if (fallbackFontName[0])
525         return getCachedFontData(description, fallbackFontName);
526
527     // Fall back to the DEFAULT_GUI_FONT if no known Unicode fonts are available.
528     if (HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT))) {
529         LOGFONT defaultGUILogFont;
530         GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont);
531         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, defaultGUILogFont, fallbackFontName))
532             return simpleFont;
533     }
534
535     // Fall back to Non-client metrics fonts.
536     NONCLIENTMETRICS nonClientMetrics = {0};
537     nonClientMetrics.cbSize = sizeof(nonClientMetrics);
538     if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
539         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfMessageFont, fallbackFontName))
540             return simpleFont;
541         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfMenuFont, fallbackFontName))
542             return simpleFont;
543         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfStatusFont, fallbackFontName))
544             return simpleFont;
545         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfCaptionFont, fallbackFontName))
546             return simpleFont;
547         if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
548             return simpleFont;
549     }
550
551     ASSERT_NOT_REACHED();
552     return 0;
553 }
554
555 void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
556 {
557     HDC hdc = GetDC(0);
558
559     LOGFONT logFont;
560     logFont.lfCharSet = DEFAULT_CHARSET;
561     unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1));
562     memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar));
563     logFont.lfFaceName[familyLength] = 0;
564     logFont.lfPitchAndFamily = 0;
565
566     TraitsInFamilyProcData procData(familyName);
567     EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0);
568     copyToVector(procData.m_traitsMasks, traitsMasks);
569
570     ReleaseDC(0, hdc);
571 }
572
573 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
574 {
575     LOGFONT winfont = {0};
576     FillLogFont(fontDescription, &winfont);
577
578     // Windows will always give us a valid pointer here, even if the face name 
579     // is non-existent.  We have to double-check and see if the family name was 
580     // really used.
581     String winName;
582     HFONT hfont = createFontIndirectAndGetWinName(family, &winfont, &winName);
583     if (!hfont)
584         return 0;
585
586     // FIXME: Do we need to use predefined fonts "guaranteed" to exist
587     // when we're running in layout-test mode?
588     if (!equalIgnoringCase(family, winName)) {
589         // For CJK fonts with both English and native names, 
590         // GetTextFace returns a native name under the font's "locale"
591         // and an English name under other locales regardless of 
592         // lfFaceName field of LOGFONT. As a result, we need to check
593         // if a font has an alternate name. If there is, we need to
594         // compare it with what's requested in the first place.
595         String altName;
596         if (!LookupAltName(family, altName) || 
597             !equalIgnoringCase(altName, winName)) {
598             DeleteObject(hfont);
599             return 0;
600         }
601     }
602
603     return new FontPlatformData(hfont,
604                                 fontDescription.computedPixelSize());
605 }
606
607 }