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

Side by Side Diff: Source/WebCore/platform/graphics/win/FontCacheWin.cpp

Issue 13642009: WebCore: Remove PLATFORM(WIN) files we do not use. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30 #include <winsock2.h>
31 #include "FontCache.h"
32 #include "Font.h"
33 #include "HWndDC.h"
34 #include "SimpleFontData.h"
35 #include "UnicodeRange.h"
36 #include <mlang.h>
37 #include <windows.h>
38 #include <wtf/StdLibExtras.h>
39 #include <wtf/text/StringHash.h>
40
41 using std::min;
42
43 namespace WebCore
44 {
45
46 void FontCache::platformInit()
47 {
48 }
49
50 IMLangFontLinkType* FontCache::getFontLinkInterface()
51 {
52 static IMultiLanguage *multiLanguage;
53 if (!multiLanguage) {
54 if (CoCreateInstance(CLSID_CMultiLanguage, 0, CLSCTX_ALL, IID_IMultiLang uage, (void**)&multiLanguage) != S_OK)
55 return 0;
56 }
57
58 static IMLangFontLinkType* langFontLink;
59 if (!langFontLink) {
60 if (multiLanguage->QueryInterface(&langFontLink) != S_OK)
61 return 0;
62 }
63
64 return langFontLink;
65 }
66
67 static int CALLBACK metaFileEnumProc(HDC hdc, HANDLETABLE* table, CONST ENHMETAR ECORD* record, int tableEntries, LPARAM logFont)
68 {
69 if (record->iType == EMR_EXTCREATEFONTINDIRECTW) {
70 const EMREXTCREATEFONTINDIRECTW* createFontRecord = reinterpret_cast<con st EMREXTCREATEFONTINDIRECTW*>(record);
71 *reinterpret_cast<LOGFONT*>(logFont) = createFontRecord->elfw.elfLogFont ;
72 }
73 return true;
74 }
75
76 static int CALLBACK linkedFontEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM hfont)
77 {
78 *reinterpret_cast<HFONT*>(hfont) = CreateFontIndirect(logFont);
79 return false;
80 }
81
82 static const Vector<String>* getLinkedFonts(String& family)
83 {
84 static HashMap<String, Vector<String>*> systemLinkMap;
85 Vector<String>* result = systemLinkMap.get(family);
86 if (result)
87 return result;
88
89 result = new Vector<String>;
90 systemLinkMap.set(family, result);
91 HKEY fontLinkKey;
92 if (FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows N T\\CurrentVersion\\FontLink\\SystemLink", 0, KEY_READ, &fontLinkKey)))
93 return result;
94
95 DWORD linkedFontsBufferSize = 0;
96 RegQueryValueEx(fontLinkKey, family.charactersWithNullTermination(), 0, NULL , NULL, &linkedFontsBufferSize);
97 WCHAR* linkedFonts = reinterpret_cast<WCHAR*>(malloc(linkedFontsBufferSize)) ;
98 if (SUCCEEDED(RegQueryValueEx(fontLinkKey, family.charactersWithNullTerminat ion(), 0, NULL, reinterpret_cast<BYTE*>(linkedFonts), &linkedFontsBufferSize))) {
99 unsigned i = 0;
100 unsigned length = linkedFontsBufferSize / sizeof(*linkedFonts);
101 while (i < length) {
102 while (i < length && linkedFonts[i] != ',')
103 i++;
104 i++;
105 unsigned j = i;
106 while (j < length && linkedFonts[j])
107 j++;
108 result->append(String(linkedFonts + i, j - i));
109 i = j + 1;
110 }
111 }
112 free(linkedFonts);
113 RegCloseKey(fontLinkKey);
114 return result;
115 }
116
117 static const Vector<DWORD, 4>& getCJKCodePageMasks()
118 {
119 // The default order in which we look for a font for a CJK character. If the user's default code page is
120 // one of these, we will use it first.
121 static const UINT CJKCodePages[] = {
122 932, /* Japanese */
123 936, /* Simplified Chinese */
124 950, /* Traditional Chinese */
125 949 /* Korean */
126 };
127
128 static Vector<DWORD, 4> codePageMasks;
129 static bool initialized;
130 if (!initialized) {
131 initialized = true;
132 IMLangFontLinkType* langFontLink = fontCache()->getFontLinkInterface();
133 if (!langFontLink)
134 return codePageMasks;
135
136 UINT defaultCodePage;
137 DWORD defaultCodePageMask = 0;
138 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_RETURN_NUMBER | LOCALE_IDE FAULTANSICODEPAGE, reinterpret_cast<LPWSTR>(&defaultCodePage), sizeof(defaultCod ePage)))
139 langFontLink->CodePageToCodePages(defaultCodePage, &defaultCodePageM ask);
140
141 if (defaultCodePage == CJKCodePages[0] || defaultCodePage == CJKCodePage s[1] || defaultCodePage == CJKCodePages[2] || defaultCodePage == CJKCodePages[3] )
142 codePageMasks.append(defaultCodePageMask);
143 for (unsigned i = 0; i < 4; ++i) {
144 if (defaultCodePage != CJKCodePages[i]) {
145 DWORD codePageMask;
146 langFontLink->CodePageToCodePages(CJKCodePages[i], &codePageMask );
147 codePageMasks.append(codePageMask);
148 }
149 }
150 }
151 return codePageMasks;
152 }
153
154 static bool currentFontContainsCharacter(HDC hdc, UChar character)
155 {
156 static Vector<char, 512> glyphsetBuffer;
157 glyphsetBuffer.resize(GetFontUnicodeRanges(hdc, 0));
158 GLYPHSET* glyphset = reinterpret_cast<GLYPHSET*>(glyphsetBuffer.data());
159 GetFontUnicodeRanges(hdc, glyphset);
160
161 // FIXME: Change this to a binary search.
162 unsigned i = 0;
163 while (i < glyphset->cRanges && glyphset->ranges[i].wcLow <= character)
164 i++;
165
166 return i && glyphset->ranges[i - 1].wcLow + glyphset->ranges[i - 1].cGlyphs > character;
167 }
168
169 static HFONT createMLangFont(IMLangFontLinkType* langFontLink, HDC hdc, DWORD co dePageMask, UChar character = 0)
170 {
171 HFONT MLangFont;
172 HFONT hfont = 0;
173 if (SUCCEEDED(langFontLink->MapFont(hdc, codePageMask, character, &MLangFont )) && MLangFont) {
174 LOGFONT lf;
175 GetObject(MLangFont, sizeof(LOGFONT), &lf);
176 langFontLink->ReleaseFont(MLangFont);
177 hfont = CreateFontIndirect(&lf);
178 }
179 return hfont;
180 }
181
182 PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
183 {
184 UChar character = characters[0];
185 RefPtr<SimpleFontData> fontData;
186 HWndDC hdc(0);
187 HFONT primaryFont = font.primaryFont()->fontDataForCharacter(character)->pla tformData().hfont();
188 HGDIOBJ oldFont = SelectObject(hdc, primaryFont);
189 HFONT hfont = 0;
190
191 if (IMLangFontLinkType* langFontLink = getFontLinkInterface()) {
192 // Try MLang font linking first.
193 DWORD codePages = 0;
194 langFontLink->GetCharCodePages(character, &codePages);
195
196 if (codePages && findCharUnicodeRange(character) == cRangeSetCJK) {
197 // The CJK character may belong to multiple code pages. We want to
198 // do font linking against a single one of them, preferring the defa ult
199 // code page for the user's locale.
200 const Vector<DWORD, 4>& CJKCodePageMasks = getCJKCodePageMasks();
201 unsigned numCodePages = CJKCodePageMasks.size();
202 for (unsigned i = 0; i < numCodePages && !hfont; ++i) {
203 hfont = createMLangFont(langFontLink, hdc, CJKCodePageMasks[i]);
204 if (hfont && !(codePages & CJKCodePageMasks[i])) {
205 // We asked about a code page that is not one of the code pa ges
206 // returned by MLang, so the font might not contain the char acter.
207 SelectObject(hdc, hfont);
208 if (!currentFontContainsCharacter(hdc, character)) {
209 DeleteObject(hfont);
210 hfont = 0;
211 }
212 SelectObject(hdc, primaryFont);
213 }
214 }
215 } else
216 hfont = createMLangFont(langFontLink, hdc, codePages, character);
217 }
218
219 // A font returned from MLang is trusted to contain the character.
220 bool containsCharacter = hfont;
221
222 if (!hfont) {
223 // To find out what font Uniscribe would use, we make it draw into a met afile and intercept
224 // calls to CreateFontIndirect().
225 HDC metaFileDc = CreateEnhMetaFile(hdc, NULL, NULL, NULL);
226 SelectObject(metaFileDc, primaryFont);
227
228 bool scriptStringOutSucceeded = false;
229 SCRIPT_STRING_ANALYSIS ssa;
230
231 // FIXME: If length is greater than 1, we actually return the font for t he last character.
232 // This function should be renamed getFontDataForCharacter and take a si ngle 32-bit character.
233 if (SUCCEEDED(ScriptStringAnalyse(metaFileDc, characters, length, 0, -1, SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK,
234 0, NULL, NULL, NULL, NULL, NULL, &ssa))) {
235 scriptStringOutSucceeded = SUCCEEDED(ScriptStringOut(ssa, 0, 0, 0, N ULL, 0, 0, FALSE));
236 ScriptStringFree(&ssa);
237 }
238 HENHMETAFILE metaFile = CloseEnhMetaFile(metaFileDc);
239 if (scriptStringOutSucceeded) {
240 LOGFONT logFont;
241 logFont.lfFaceName[0] = 0;
242 EnumEnhMetaFile(0, metaFile, metaFileEnumProc, &logFont, NULL);
243 if (logFont.lfFaceName[0])
244 hfont = CreateFontIndirect(&logFont);
245 }
246 DeleteEnhMetaFile(metaFile);
247 }
248
249 String familyName;
250 const Vector<String>* linkedFonts = 0;
251 unsigned linkedFontIndex = 0;
252 while (hfont) {
253 SelectObject(hdc, hfont);
254 WCHAR name[LF_FACESIZE];
255 GetTextFace(hdc, LF_FACESIZE, name);
256 familyName = name;
257
258 if (containsCharacter || currentFontContainsCharacter(hdc, character))
259 break;
260
261 if (!linkedFonts)
262 linkedFonts = getLinkedFonts(familyName);
263 SelectObject(hdc, oldFont);
264 DeleteObject(hfont);
265 hfont = 0;
266
267 if (linkedFonts->size() <= linkedFontIndex)
268 break;
269
270 LOGFONT logFont;
271 logFont.lfCharSet = DEFAULT_CHARSET;
272 memcpy(logFont.lfFaceName, linkedFonts->at(linkedFontIndex).characters() , linkedFonts->at(linkedFontIndex).length() * sizeof(WCHAR));
273 logFont.lfFaceName[linkedFonts->at(linkedFontIndex).length()] = 0;
274 EnumFontFamiliesEx(hdc, &logFont, linkedFontEnumProc, reinterpret_cast<L PARAM>(&hfont), 0);
275 linkedFontIndex++;
276 }
277
278 if (hfont) {
279 if (!familyName.isEmpty()) {
280 FontPlatformData* result = getCachedFontPlatformData(font.fontDescri ption(), familyName);
281 if (result)
282 fontData = getCachedFontData(result, DoNotRetain);
283 }
284
285 SelectObject(hdc, oldFont);
286 DeleteObject(hfont);
287 }
288
289 return fontData.release();
290 }
291
292 PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& fon t)
293 {
294 return 0;
295 }
296
297 PassRefPtr<SimpleFontData> FontCache::fontDataFromDescriptionAndLogFont(const Fo ntDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, AtomicString& outFontFamilyName)
298 {
299 AtomicString familyName = String(font.lfFaceName, wcsnlen(font.lfFaceName, L F_FACESIZE));
300 RefPtr<SimpleFontData> fontData = getCachedFontData(fontDescription, familyN ame, false, shouldRetain);
301 if (fontData)
302 outFontFamilyName = familyName;
303 return fontData.release();
304 }
305
306 PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescri ption& fontDescription, ShouldRetain shouldRetain)
307 {
308 DEFINE_STATIC_LOCAL(AtomicString, fallbackFontName, ());
309 if (!fallbackFontName.isEmpty())
310 return getCachedFontData(fontDescription, fallbackFontName, false, shoul dRetain);
311
312 // FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
313 // the default that the user would get without changing any prefs.
314
315 // Search all typical Windows-installed full Unicode fonts.
316 // Sorted by most to least glyphs according to http://en.wikipedia.org/wiki/ Unicode_typefaces
317 // Start with Times New Roman also since it is the default if the user doesn 't change prefs.
318 static AtomicString fallbackFonts[] = {
319 AtomicString("Times New Roman", AtomicString::ConstructFromLiteral),
320 AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral) ,
321 AtomicString("Tahoma", AtomicString::ConstructFromLiteral),
322 AtomicString("Lucida Sans Unicode", AtomicString::ConstructFromLiteral),
323 AtomicString("Arial", AtomicString::ConstructFromLiteral)
324 };
325 RefPtr<SimpleFontData> simpleFont;
326 for (size_t i = 0; i < WTF_ARRAY_LENGTH(fallbackFonts); ++i) {
327 if (simpleFont = getCachedFontData(fontDescription, fallbackFonts[i], fa lse, shouldRetain)) {
328 fallbackFontName = fallbackFonts[i];
329 return simpleFont.release();
330 }
331 }
332
333 // Fall back to the DEFAULT_GUI_FONT if no known Unicode fonts are available .
334 if (HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FON T))) {
335 LOGFONT defaultGUILogFont;
336 GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont) ;
337 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, defaultGUILogFont, fallbackFontName))
338 return simpleFont.release();
339 }
340
341 // Fall back to Non-client metrics fonts.
342 NONCLIENTMETRICS nonClientMetrics = {0};
343 nonClientMetrics.cbSize = sizeof(nonClientMetrics);
344 if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
345 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, nonClientMetrics.lfMessageFont, fallbackFontName))
346 return simpleFont.release();
347 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, nonClientMetrics.lfMenuFont, fallbackFontName))
348 return simpleFont.release();
349 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, nonClientMetrics.lfStatusFont, fallbackFontName))
350 return simpleFont.release();
351 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, nonClientMetrics.lfCaptionFont, fallbackFontName))
352 return simpleFont.release();
353 if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shou ldRetain, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
354 return simpleFont.release();
355 }
356
357 ASSERT_NOT_REACHED();
358 return 0;
359 }
360
361 static LONG toGDIFontWeight(FontWeight fontWeight)
362 {
363 static LONG gdiFontWeights[] = {
364 FW_THIN, // FontWeight100
365 FW_EXTRALIGHT, // FontWeight200
366 FW_LIGHT, // FontWeight300
367 FW_NORMAL, // FontWeight400
368 FW_MEDIUM, // FontWeight500
369 FW_SEMIBOLD, // FontWeight600
370 FW_BOLD, // FontWeight700
371 FW_EXTRABOLD, // FontWeight800
372 FW_HEAVY // FontWeight900
373 };
374 return gdiFontWeights[fontWeight];
375 }
376
377 static inline bool isGDIFontWeightBold(LONG gdiFontWeight)
378 {
379 return gdiFontWeight >= FW_SEMIBOLD;
380 }
381
382 static LONG adjustedGDIFontWeight(LONG gdiFontWeight, const String& family)
383 {
384 static AtomicString lucidaStr("Lucida Grande");
385 if (equalIgnoringCase(family, lucidaStr)) {
386 if (gdiFontWeight == FW_NORMAL)
387 return FW_MEDIUM;
388 if (gdiFontWeight == FW_BOLD)
389 return FW_SEMIBOLD;
390 }
391 return gdiFontWeight;
392 }
393
394 struct MatchImprovingProcData {
395 MatchImprovingProcData(LONG desiredWeight, bool desiredItalic)
396 : m_desiredWeight(desiredWeight)
397 , m_desiredItalic(desiredItalic)
398 , m_hasMatched(false)
399 {
400 }
401
402 LONG m_desiredWeight;
403 bool m_desiredItalic;
404 bool m_hasMatched;
405 LOGFONT m_chosen;
406 };
407
408 static int CALLBACK matchImprovingEnumProc(CONST LOGFONT* candidate, CONST TEXTM ETRIC* metrics, DWORD fontType, LPARAM lParam)
409 {
410 MatchImprovingProcData* matchData = reinterpret_cast<MatchImprovingProcData* >(lParam);
411
412 if (!matchData->m_hasMatched) {
413 matchData->m_hasMatched = true;
414 matchData->m_chosen = *candidate;
415 return 1;
416 }
417
418 if (!candidate->lfItalic != !matchData->m_chosen.lfItalic) {
419 if (!candidate->lfItalic == !matchData->m_desiredItalic)
420 matchData->m_chosen = *candidate;
421
422 return 1;
423 }
424
425 unsigned chosenWeightDeltaMagnitude = abs(matchData->m_chosen.lfWeight - mat chData->m_desiredWeight);
426 unsigned candidateWeightDeltaMagnitude = abs(candidate->lfWeight - matchData ->m_desiredWeight);
427
428 // If both are the same distance from the desired weight, prefer the candida te if it is further from regular.
429 if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude && abs(candi date->lfWeight - FW_NORMAL) > abs(matchData->m_chosen.lfWeight - FW_NORMAL)) {
430 matchData->m_chosen = *candidate;
431 return 1;
432 }
433
434 // Otherwise, prefer the one closer to the desired weight.
435 if (candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude)
436 matchData->m_chosen = *candidate;
437
438 return 1;
439 }
440
441 static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool desiredItalic, int size, bool synthesizeItalic)
442 {
443 HWndDC hdc(0);
444
445 LOGFONT logFont;
446 logFont.lfCharSet = DEFAULT_CHARSET;
447 unsigned familyLength = min(family.length(), static_cast<unsigned>(LF_FACESI ZE - 1));
448 memcpy(logFont.lfFaceName, family.characters(), familyLength * sizeof(UChar) );
449 logFont.lfFaceName[familyLength] = 0;
450 logFont.lfPitchAndFamily = 0;
451
452 MatchImprovingProcData matchData(desiredWeight, desiredItalic);
453 EnumFontFamiliesEx(hdc, &logFont, matchImprovingEnumProc, reinterpret_cast<L PARAM>(&matchData), 0);
454
455 if (!matchData.m_hasMatched)
456 return 0;
457
458 matchData.m_chosen.lfHeight = -size;
459 matchData.m_chosen.lfWidth = 0;
460 matchData.m_chosen.lfEscapement = 0;
461 matchData.m_chosen.lfOrientation = 0;
462 matchData.m_chosen.lfUnderline = false;
463 matchData.m_chosen.lfStrikeOut = false;
464 matchData.m_chosen.lfCharSet = DEFAULT_CHARSET;
465 matchData.m_chosen.lfOutPrecision = OUT_TT_PRECIS;
466 matchData.m_chosen.lfQuality = DEFAULT_QUALITY;
467 matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
468
469 if (desiredItalic && !matchData.m_chosen.lfItalic && synthesizeItalic)
470 matchData.m_chosen.lfItalic = 1;
471
472 HFONT result = CreateFontIndirect(&matchData.m_chosen);
473 if (!result)
474 return 0;
475
476 HWndDC dc(0);
477 SaveDC(dc);
478 SelectObject(dc, result);
479 WCHAR actualName[LF_FACESIZE];
480 GetTextFace(dc, LF_FACESIZE, actualName);
481 RestoreDC(dc, -1);
482
483 if (wcsicmp(matchData.m_chosen.lfFaceName, actualName)) {
484 DeleteObject(result);
485 result = 0;
486 }
487
488 return result;
489 }
490
491 struct TraitsInFamilyProcData {
492 TraitsInFamilyProcData(const AtomicString& familyName)
493 : m_familyName(familyName)
494 {
495 }
496
497 const AtomicString& m_familyName;
498 HashSet<unsigned> m_traitsMasks;
499 };
500
501 static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMET RIC* metrics, DWORD fontType, LPARAM lParam)
502 {
503 TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*> (lParam);
504
505 unsigned traitsMask = 0;
506 traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask;
507 traitsMask |= FontVariantNormalMask;
508 LONG weight = adjustedGDIFontWeight(logFont->lfWeight, procData->m_familyNam e);
509 traitsMask |= weight == FW_THIN ? FontWeight100Mask :
510 weight == FW_EXTRALIGHT ? FontWeight200Mask :
511 weight == FW_LIGHT ? FontWeight300Mask :
512 weight == FW_NORMAL ? FontWeight400Mask :
513 weight == FW_MEDIUM ? FontWeight500Mask :
514 weight == FW_SEMIBOLD ? FontWeight600Mask :
515 weight == FW_BOLD ? FontWeight700Mask :
516 weight == FW_EXTRABOLD ? FontWeight800Mask :
517 FontWeight900Mask;
518 procData->m_traitsMasks.add(traitsMask);
519 return 1;
520 }
521 void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne d>& traitsMasks)
522 {
523 HWndDC hdc(0);
524
525 LOGFONT logFont;
526 logFont.lfCharSet = DEFAULT_CHARSET;
527 unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FA CESIZE - 1));
528 memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UC har));
529 logFont.lfFaceName[familyLength] = 0;
530 logFont.lfPitchAndFamily = 0;
531
532 TraitsInFamilyProcData procData(familyName);
533 EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<L PARAM>(&procData), 0);
534 copyToVector(procData.m_traitsMasks, traitsMasks);
535 }
536
537 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD escription, const AtomicString& family)
538 {
539 bool isLucidaGrande = false;
540 static AtomicString lucidaStr("Lucida Grande");
541 if (equalIgnoringCase(family, lucidaStr))
542 isLucidaGrande = true;
543
544 bool useGDI = fontDescription.renderingMode() == AlternateRenderingMode && ! isLucidaGrande;
545
546 // The logical size constant is 32. We do this for subpixel precision when r endering using Uniscribe.
547 // This masks rounding errors related to the HFONT metrics being different from the CGFont metrics.
548 // FIXME: We will eventually want subpixel precision for GDI mode, but the s caled rendering doesn't
549 // look as nice. That may be solvable though.
550 LONG weight = adjustedGDIFontWeight(toGDIFontWeight(fontDescription.weight() ), family);
551 HFONT hfont = createGDIFont(family, weight, fontDescription.italic(),
552 fontDescription.computedPixelSize() * (useGDI ? 1 : 32), useGDI);
553
554 if (!hfont)
555 return 0;
556
557 if (isLucidaGrande)
558 useGDI = false; // Never use GDI for Lucida Grande.
559
560 LOGFONT logFont;
561 GetObject(hfont, sizeof(LOGFONT), &logFont);
562
563 bool synthesizeBold = isGDIFontWeightBold(weight) && !isGDIFontWeightBold(lo gFont.lfWeight);
564 bool synthesizeItalic = fontDescription.italic() && !logFont.lfItalic;
565
566 FontPlatformData* result = new FontPlatformData(hfont, fontDescription.compu tedPixelSize(), synthesizeBold, synthesizeItalic, useGDI);
567
568 if (fontCreationFailed) {
569 // The creation of the CGFontRef failed for some reason. We already ass erted in debug builds, but to make
570 // absolutely sure that we don't use this font, go ahead and return 0 so that we can fall back to the next
571 // font.
572 delete result;
573 DeleteObject(hfont);
574 return 0;
575 }
576
577 return result;
578 }
579
580 }
581
OLDNEW
« no previous file with comments | « Source/WebCore/platform/graphics/win/FontCGWin.cpp ('k') | Source/WebCore/platform/graphics/win/FontCustomPlatformData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698