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