Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: Source/platform/fonts/win/FontCacheWin.cpp

Issue 179723005: Remove GDI font rendering code for windows (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
34 #include <unicode/uniset.h>
35 #include "platform/fonts/FontDescription.h"
36 #include "platform/LayoutTestSupport.h"
37 #include "platform/fonts/FontCache.h"
38 #include "platform/fonts/FontFallbackWin.h"
39 #include "platform/fonts/SimpleFontData.h"
40 #include "platform/fonts/win/FontPlatformDataWin.h"
41 #include "platform/win/HWndDC.h"
42 #include "wtf/HashMap.h"
43 #include "wtf/text/StringHash.h"
44
45 #include <windows.h>
46 #include <mlang.h>
47 #include <objidl.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 const WCHAR* name;
68 int codePage;
69 };
70
71 struct NamePair {
72 const 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", japanes eCodepage}},
90 {L"ms pgothic", {L"\xFF2D\xFF33 \xFF30\x30B4\x30B7\x30C3\x30AF", japanes eCodepage}},
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", japaneseCodepa ge}},
96 {L"ms gothic", {L"\xFF2D\xFF33 \x30B4\x30B7\x30C3\x30AF", japaneseCodepa ge}},
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", simplifiedChineseCode page}},
144 {L"microsoft yahei", {L"\x5FAE\x8F6F\x96C5\x9ED1", simplifiedChineseCode page}},
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", traditionalChinese Codepage}},
162 {L"pmingliu-extb", {L"\x65B0\x7D30\x660E\x9AD4-extb", traditionalChinese Codepage}},
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", traditionalChineseCodepag e}},
168 {L"mingliu-extb", {L"x65B0\x7D30\x660E\x9AD4-extb", traditionalChineseCo depage}},
169 // 微軟正黑體, Microsoft JhengHei
170 {L"\x5FAE\x8EDF\x6B63\x9ED1\x9AD4", {L"Microsoft JhengHei", traditionalC hineseCodepage}},
171 {L"microsoft jhengHei", {L"\x5FAE\x8EDF\x6B63\x9ED1\x9AD4", traditionalC hineseCodepage}},
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", traditionalCh ineseCodepage}},
177 {L"wenquanyi zen hei", {L"\x6587\x6cc9\x9a5b\x6b63\x9ed1", traditionalCh ineseCodepage}},
178 // WenQuanYi Zen Hei
179 {L"\x6587\x6cc9\x9a7f\x6b63\x9ed1", {L"WenQuanYi Zen Hei", simplifiedChi neseCodepage}},
180 {L"wenquanyi zen hei", {L"\x6587\x6cc9\x9a7f\x6b63\x9ed1", simplifiedChi neseCodepage}},
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 Un i", traditionalChineseCodepage}},
195 {L"ar pl zenkai uni", {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x006 9", traditionalChineseCodepage}},
196 {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x0069", {L"AR PL ZenKai Un i", simplifiedChineseCodepage}},
197 {L"ar pl zenkai uni", {L"\x6587\x0050\x004C\x4E2D\x6977\x0055\x006E\x006 9", 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].altNameCo depage));
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->value->codePage;
226
227 if ((isAscii && systemCp == fontCp) || (!isAscii && systemCp != fontCp)) {
228 altName = String(iter->value->name);
229 return true;
230 }
231
232 return false;
233 }
234
235 static HFONT createFontIndirectAndGetWinName(const String& family, LOGFONT* winf ont, String* winName)
236 {
237 unsigned len = family.copyTo(winfont->lfFaceName, 0, LF_FACESIZE - 1);
238 winfont->lfFaceName[len] = '\0';
239
240 HFONT hfont = CreateFontIndirect(winfont);
241 if (!hfont)
242 return 0;
243
244 HWndDC dc(0);
245 HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont));
246 WCHAR name[LF_FACESIZE];
247 unsigned resultLength = GetTextFace(dc, LF_FACESIZE, name);
248 if (resultLength > 0)
249 resultLength--; // ignore the null terminator
250
251 SelectObject(dc, oldFont);
252 *winName = String(name, resultLength);
253 return hfont;
254 }
255
256 // This maps font family names to their repertoires of supported Unicode
257 // characters. Because it's family names rather than font faces we use
258 // as keys, there might be edge cases where one face of a font family
259 // has a different repertoire from another face of the same family.
260 typedef HashMap<const wchar_t*, icu::UnicodeSet*> FontCmapCache;
261
262 static bool fontContainsCharacter(const FontPlatformData* fontData,
263 const wchar_t* family, UChar32 character)
264 {
265 // FIXME: For non-BMP characters, GetFontUnicodeRanges is of
266 // no use. We have to read directly from the cmap table of a font.
267 // Return true for now.
268 if (character > 0xFFFF)
269 return true;
270
271 // This cache is just leaked on shutdown.
272 static FontCmapCache* fontCmapCache = 0;
273 if (!fontCmapCache)
274 fontCmapCache = new FontCmapCache;
275
276 HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find (family);
277 if (it != fontCmapCache->end())
278 return it->value->contains(character);
279
280 HFONT hfont = fontData->hfont();
281 HWndDC hdc(0);
282 HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(hdc, hfont));
283 int count = GetFontUnicodeRanges(hdc, 0);
284 if (!count && FontPlatformData::ensureFontLoaded(hfont))
285 count = GetFontUnicodeRanges(hdc, 0);
286 if (!count) {
287 WTF_LOG_ERROR("Unable to get the font unicode range after second attempt ");
288 SelectObject(hdc, oldFont);
289 return true;
290 }
291
292 static Vector<char, 512>* gGlyphsetBuffer = 0;
293 if (!gGlyphsetBuffer)
294 gGlyphsetBuffer = new Vector<char, 512>();
295 gGlyphsetBuffer->resize(GetFontUnicodeRanges(hdc, 0));
296 GLYPHSET* glyphset = reinterpret_cast<GLYPHSET*>(gGlyphsetBuffer->data());
297 // In addition, refering to the OS/2 table and converting the codepage list
298 // to the coverage map might be faster.
299 count = GetFontUnicodeRanges(hdc, glyphset);
300 ASSERT(count > 0);
301 SelectObject(hdc, oldFont);
302
303 // FIXME: consider doing either of the following two:
304 // 1) port back ICU 4.0's faster look-up code for UnicodeSet
305 // 2) port Mozilla's CompressedCharMap or gfxSparseBitset
306 unsigned i = 0;
307 icu::UnicodeSet* cmap = new icu::UnicodeSet;
308 while (i < glyphset->cRanges) {
309 WCHAR start = glyphset->ranges[i].wcLow;
310 cmap->add(start, start + glyphset->ranges[i].cGlyphs - 1);
311 i++;
312 }
313 cmap->freeze();
314 // We don't lowercase |family| because all of them are under our control
315 // and they're already lowercased.
316 fontCmapCache->set(family, cmap);
317 return cmap->contains(character);
318 }
319
320 // Tries the given font and save it |outFontFamilyName| if it succeeds.
321 PassRefPtr<SimpleFontData> FontCache::fontDataFromDescriptionAndLogFont(const Fo ntDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, wchar_t* outFontFamilyName)
322 {
323 RefPtr<SimpleFontData> fontData = getFontData(fontDescription, font.lfFaceNa me, false, shouldRetain);
324 if (fontData)
325 memcpy(outFontFamilyName, font.lfFaceName, sizeof(font.lfFaceName));
326 return fontData.release();
327 }
328
329 static LONG toGDIFontWeight(FontWeight fontWeight)
330 {
331 static LONG gdiFontWeights[] = {
332 FW_THIN, // FontWeight100
333 FW_EXTRALIGHT, // FontWeight200
334 FW_LIGHT, // FontWeight300
335 FW_NORMAL, // FontWeight400
336 FW_MEDIUM, // FontWeight500
337 FW_SEMIBOLD, // FontWeight600
338 FW_BOLD, // FontWeight700
339 FW_EXTRABOLD, // FontWeight800
340 FW_HEAVY // FontWeight900
341 };
342 return gdiFontWeights[fontWeight];
343 }
344
345 static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont )
346 {
347 // The size here looks unusual. The negative number is intentional.
348 // Unlike WebKit trunk, we don't multiply the size by 32. That seems to be
349 // some kind of artifact of their CG backend, or something.
350 winfont->lfHeight = -fontDescription.computedPixelSize();
351 winfont->lfWidth = 0;
352 winfont->lfEscapement = 0;
353 winfont->lfOrientation = 0;
354 winfont->lfUnderline = false;
355 winfont->lfStrikeOut = false;
356 winfont->lfCharSet = DEFAULT_CHARSET;
357 winfont->lfOutPrecision = OUT_TT_ONLY_PRECIS;
358 winfont->lfQuality = isRunningLayoutTest() ? NONANTIALIASED_QUALITY : DEFAUL T_QUALITY; // Honor user's desktop settings.
359 winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
360 winfont->lfItalic = fontDescription.italic();
361 winfont->lfWeight = toGDIFontWeight(fontDescription.weight());
362 }
363
364 struct GetLastResortFallbackFontProcData {
365 GetLastResortFallbackFontProcData(FontCache* fontCache, const FontDescriptio n* fontDescription, FontCache::ShouldRetain shouldRetain, wchar_t* fontName)
366 : m_fontCache(fontCache)
367 , m_fontDescription(fontDescription)
368 , m_shouldRetain(shouldRetain)
369 , m_fontName(fontName)
370 , m_fontData(0)
371 {
372 }
373
374 FontCache* m_fontCache;
375 const FontDescription* m_fontDescription;
376 FontCache::ShouldRetain m_shouldRetain;
377 wchar_t* m_fontName;
378 RefPtr<SimpleFontData> m_fontData;
379 };
380
381 static int CALLBACK getLastResortFallbackFontProc(const LOGFONT* logFont, const TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam)
382 {
383 GetLastResortFallbackFontProcData* procData = reinterpret_cast<GetLastResort FallbackFontProcData*>(lParam);
384 procData->m_fontData = procData->m_fontCache->fontDataFromDescriptionAndLogF ont(*procData->m_fontDescription, procData->m_shouldRetain, *logFont, procData-> m_fontName);
385 return !procData->m_fontData;
386 }
387
388 void FontCache::platformInit()
389 {
390 // Not needed on Windows.
391 }
392
393 // Given the desired base font, this will create a SimpleFontData for a specific
394 // font that can be used to render the given range of characters.
395 PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDes cription& fontDescription, UChar32 c, const SimpleFontData*)
396 {
397 // FIXME: We should fix getFallbackFamily to take a UChar32
398 // and remove this split-to-UChar16 code.
399 UChar codeUnits[2];
400 int codeUnitsLength;
401 if (inputC <= 0xFFFF) {
402 codeUnits[0] = inputC;
403 codeUnitsLength = 1;
404 } else {
405 codeUnits[0] = U16_LEAD(inputC);
406 codeUnits[1] = U16_TRAIL(inputC);
407 codeUnitsLength = 2;
408 }
409
410 // FIXME: Consider passing fontDescription.dominantScript()
411 // to GetFallbackFamily here.
412 FontDescription fontDescription = fontDescription;
413 UChar32 c;
414 UScriptCode script;
415 const wchar_t* family = getFallbackFamily(codeUnits, codeUnitsLength, fontDe scription.genericFamily(), &c, &script);
416 FontPlatformData* data = 0;
417 if (family)
418 data = getFontPlatformData(fontDescription, AtomicString(family, wcslen (family)));
419
420 // Last resort font list : PanUnicode. CJK fonts have a pretty
421 // large repertoire. Eventually, we need to scan all the fonts
422 // on the system to have a Firefox-like coverage.
423 // Make sure that all of them are lowercased.
424 const static wchar_t* const cjkFonts[] = {
425 L"arial unicode ms",
426 L"ms pgothic",
427 L"simsun",
428 L"gulim",
429 L"pmingliu",
430 L"wenquanyi zen hei", // partial CJK Ext. A coverage but more
431 // widely known to Chinese users.
432 L"ar pl shanheisun uni",
433 L"ar pl zenkai uni",
434 L"han nom a", // Complete CJK Ext. A coverage
435 L"code2000", // Complete CJK Ext. A coverage
436 // CJK Ext. B fonts are not listed here because it's of no use
437 // with our current non-BMP character handling because we use
438 // Uniscribe for it and that code path does not go through here.
439 };
440
441 const static wchar_t* const commonFonts[] = {
442 L"tahoma",
443 L"arial unicode ms",
444 L"lucida sans unicode",
445 L"microsoft sans serif",
446 L"palatino linotype",
447 // Six fonts below (and code2000 at the end) are not from MS, but
448 // once installed, cover a very wide range of characters.
449 L"dejavu serif",
450 L"dejavu sasns",
451 L"freeserif",
452 L"freesans",
453 L"gentium",
454 L"gentiumalt",
455 L"ms pgothic",
456 L"simsun",
457 L"gulim",
458 L"pmingliu",
459 L"code2000",
460 };
461
462 const wchar_t* const* panUniFonts = 0;
463 int numFonts = 0;
464 if (script == USCRIPT_HAN) {
465 panUniFonts = cjkFonts;
466 numFonts = WTF_ARRAY_LENGTH(cjkFonts);
467 } else {
468 panUniFonts = commonFonts;
469 numFonts = WTF_ARRAY_LENGTH(commonFonts);
470 }
471 // Font returned from GetFallbackFamily may not cover |characters|
472 // because it's based on script to font mapping. This problem is
473 // critical enough for non-Latin scripts (especially Han) to
474 // warrant an additional (real coverage) check with fontCotainsCharacter.
475 int i;
476 for (i = 0; (!data || !fontContainsCharacter(data, family, c)) && i < numFon ts; ++i) {
477 family = panUniFonts[i];
478 data = getFontPlatformData(fontDescription, AtomicString(family, wcslen( family)));
479 }
480 // When i-th font (0-base) in |panUniFonts| contains a character and
481 // we get out of the loop, |i| will be |i + 1|. That is, if only the
482 // last font in the array covers the character, |i| will be numFonts.
483 // So, we have to use '<=" rather than '<' to see if we found a font
484 // covering the character.
485 if (i <= numFonts)
486 return fontDataFromPlatformData(data, DoNotRetain);
487
488 return 0;
489
490 }
491
492 PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescri ption& description, ShouldRetain shouldRetain)
493 {
494 FontDescription::GenericFamilyType generic = description.genericFamily();
495
496 // FIXME: Would be even better to somehow get the user's default font here.
497 // For now we'll pick the default that the user would get without changing
498 // any prefs.
499 DEFINE_STATIC_LOCAL(AtomicString, timesStr, "Times New Roman");
500 DEFINE_STATIC_LOCAL(AtomicString, courierStr, "Courier New");
501 DEFINE_STATIC_LOCAL(AtomicString, arialStr, "Arial");
502
503 AtomicString& fontStr = timesStr;
504 if (generic == FontDescription::SansSerifFamily)
505 fontStr = arialStr;
506 else if (generic == FontDescription::MonospaceFamily)
507 fontStr = courierStr;
508
509 RefPtr<SimpleFontData> simpleFont = getFontData(description, fontStr, false, shouldRetain);
510 if (simpleFont)
511 return simpleFont.release();
512
513 // Fall back to system fonts as Win Safari does because this function must
514 // return a valid font. Once we find a valid system font, we save its name
515 // to a static variable and use it to prevent trying system fonts again.
516 static wchar_t fallbackFontName[LF_FACESIZE] = {0};
517 if (fallbackFontName[0])
518 return getFontData(description, fallbackFontName, false, shouldRetain);
519
520 // Fall back to the DEFAULT_GUI_FONT if no known Unicode fonts are available .
521 if (HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FON T))) {
522 LOGFONT defaultGUILogFont;
523 GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont) ;
524 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, defaultGUILogFont, fallbackFontName))
525 return simpleFont.release();
526 }
527
528 // Fall back to Non-client metrics fonts.
529 NONCLIENTMETRICS nonClientMetrics = {0};
530 nonClientMetrics.cbSize = sizeof(nonClientMetrics);
531 if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
532 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, nonClientMetrics.lfMessageFont, fallbackFontName))
533 return simpleFont.release();
534 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, nonClientMetrics.lfMenuFont, fallbackFontName))
535 return simpleFont.release();
536 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, nonClientMetrics.lfStatusFont, fallbackFontName))
537 return simpleFont.release();
538 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, nonClientMetrics.lfCaptionFont, fallbackFontName))
539 return simpleFont.release();
540 if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRe tain, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
541 return simpleFont.release();
542 }
543
544 // Fall back to all the fonts installed in this PC. When a font has a
545 // localized name according to the system locale as well as an English name,
546 // both GetTextFace() and EnumFontFamilies() return the localized name. So,
547 // FontCache::createFontPlatformData() does not filter out the fonts
548 // returned by this EnumFontFamilies() call.
549 HWndDC dc(0);
550 if (dc) {
551 GetLastResortFallbackFontProcData procData(this, &description, shouldRet ain, fallbackFontName);
552 EnumFontFamilies(dc, 0, getLastResortFallbackFontProc, reinterpret_cast< LPARAM>(&procData));
553
554 if (procData.m_fontData)
555 return procData.m_fontData.release();
556 }
557
558 ASSERT_NOT_REACHED();
559 return 0;
560 }
561
562 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD escription, const AtomicString& family, float fontSize)
563 {
564 LOGFONT winfont = {0};
565 FillLogFont(fontDescription, &winfont);
566
567 // Windows will always give us a valid pointer here, even if the face name
568 // is non-existent. We have to double-check and see if the family name was
569 // really used.
570 String winName;
571 HFONT hfont = createFontIndirectAndGetWinName(family, &winfont, &winName);
572 if (!hfont)
573 return 0;
574
575 // FIXME: Do we need to use predefined fonts "guaranteed" to exist
576 // when we're running in layout-test mode?
577 if (!equalIgnoringCase(family, winName)) {
578 // For CJK fonts with both English and native names,
579 // GetTextFace returns a native name under the font's "locale"
580 // and an English name under other locales regardless of
581 // lfFaceName field of LOGFONT. As a result, we need to check
582 // if a font has an alternate name. If there is, we need to
583 // compare it with what's requested in the first place.
584 String altName;
585 if (!LookupAltName(family, altName) || !equalIgnoringCase(altName, winNa me)) {
586 DeleteObject(hfont);
587 return 0;
588 }
589 }
590
591 return new FontPlatformData(hfont, fontSize, fontDescription.orientation());
592 }
593
594 }
OLDNEW
« no previous file with comments | « Source/platform/fonts/skia/FontPlatformDataSkia.cpp ('k') | Source/platform/fonts/win/FontCustomPlatformDataWin.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698