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

Side by Side Diff: Source/core/platform/graphics/chromium/FontPlatformDataChromiumWin.cpp

Issue 26679003: Move platform/graphics/chromium/* to platform/graphics/ (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rename fix Created 7 years, 1 month 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
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 #include "core/platform/graphics/FontPlatformData.h"
34
35 #include "RuntimeEnabledFeatures.h"
36 #include "SkPaint.h"
37 #include "SkTypeface.h"
38 #include "SkTypeface_win.h"
39 #include "core/platform/graphics/FontCache.h"
40 #include "core/platform/graphics/GraphicsContext.h"
41 #if USE(HARFBUZZ)
42 #include "core/platform/graphics/harfbuzz/HarfBuzzFace.h"
43 #endif
44 #include "core/platform/graphics/skia/SkiaFontWin.h"
45 #include "platform/LayoutTestSupport.h"
46 #include "platform/SharedBuffer.h"
47 #include "platform/win/HWndDC.h"
48 #include "public/platform/Platform.h"
49 #include "public/platform/win/WebSandboxSupport.h"
50 #include "wtf/PassOwnPtr.h"
51 #include "wtf/StdLibExtras.h"
52 #include <mlang.h>
53 #include <objidl.h>
54 #include <windows.h>
55
56 namespace WebCore {
57
58 void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext* context) cons t
59 {
60 const float ts = m_textSize >= 0 ? m_textSize : 12;
61 paint->setTextSize(SkFloatToScalar(m_textSize));
62 paint->setTypeface(typeface());
63 paint->setFakeBoldText(m_fakeBold);
64 paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0);
65 if (RuntimeEnabledFeatures::subpixelFontScalingEnabled())
66 paint->setSubpixelText(true);
67
68 int textFlags = paintTextFlags();
69 // Only set painting flags when we're actually painting.
70 if (context && !context->couldUseLCDRenderedText()) {
71 textFlags &= ~SkPaint::kLCDRenderText_Flag;
72 // If we *just* clear our request for LCD, then GDI seems to
73 // sometimes give us AA text, and sometimes give us BW text. Since the
74 // original intent was LCD, we want to force AA (rather than BW), so we
75 // add a special bit to tell Skia to do its best to avoid the BW: by
76 // drawing LCD offscreen and downsampling that to AA.
77 textFlags |= SkPaint::kGenA8FromLCD_Flag;
78 }
79
80 static const uint32_t textFlagsMask = SkPaint::kAntiAlias_Flag |
81 SkPaint::kLCDRenderText_Flag |
82 SkPaint::kGenA8FromLCD_Flag;
83
84 SkASSERT(!(textFlags & ~textFlagsMask));
85 uint32_t flags = paint->getFlags();
86 flags &= ~textFlagsMask;
87 flags |= textFlags;
88 paint->setFlags(flags);
89 }
90
91 // Lookup the current system settings for font smoothing.
92 // We cache these values for performance, but if the browser has a way to be
93 // notified when these change, we could re-query them at that time.
94 static uint32_t getDefaultGDITextFlags()
95 {
96 static bool gInited;
97 static uint32_t gFlags;
98 if (!gInited) {
99 BOOL enabled;
100 gFlags = 0;
101 if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &enabled, 0) && enable d) {
102 gFlags |= SkPaint::kAntiAlias_Flag;
103
104 UINT smoothType;
105 if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smoothType, 0 )) {
106 if (FE_FONTSMOOTHINGCLEARTYPE == smoothType)
107 gFlags |= SkPaint::kLCDRenderText_Flag;
108 }
109 }
110 gInited = true;
111 }
112 return gFlags;
113 }
114
115 static bool isWebFont(const LOGFONT& lf)
116 {
117 // web-fonts have artifical names constructed to always be
118 // 1. 24 characters, followed by a '\0'
119 // 2. the last two characters are '=='
120 return '=' == lf.lfFaceName[22] && '=' == lf.lfFaceName[23] && '\0' == lf.lf FaceName[24];
121 }
122
123 static int computePaintTextFlags(const LOGFONT& lf)
124 {
125 int textFlags = 0;
126 switch (lf.lfQuality) {
127 case NONANTIALIASED_QUALITY:
128 textFlags = 0;
129 break;
130 case ANTIALIASED_QUALITY:
131 textFlags = SkPaint::kAntiAlias_Flag;
132 break;
133 case CLEARTYPE_QUALITY:
134 textFlags = (SkPaint::kAntiAlias_Flag | SkPaint::kLCDRenderText_Flag);
135 break;
136 default:
137 textFlags = getDefaultGDITextFlags();
138 break;
139 }
140
141 // only allow features that SystemParametersInfo allows
142 textFlags &= getDefaultGDITextFlags();
143
144 /*
145 * FontPlatformData(...) will read our logfont, and try to honor the the lf Quality
146 * setting (computing the corresponding SkPaint flags for AA and LCD). Howe ver, it
147 * will limit the quality based on its query of SPI_GETFONTSMOOTHING. This could mean
148 * we end up drawing the text in BW, even though our lfQuality requested an tialiasing.
149 *
150 * Many web-fonts are so poorly hinted that they are terrible to read when drawn in BW.
151 * In these cases, we have decided to FORCE these fonts to be drawn with at least grayscale AA,
152 * even when the System (getDefaultGDITextFlags) tells us to draw only in B W.
153 */
154 if (isWebFont(lf) && !isRunningLayoutTest())
155 textFlags |= SkPaint::kAntiAlias_Flag;
156 return textFlags;
157 }
158
159 #if !USE(HARFBUZZ)
160 PassRefPtr<SkTypeface> CreateTypefaceFromHFont(HFONT hfont, int* size, int* pain tTextFlags)
161 {
162 LOGFONT info;
163 GetObject(hfont, sizeof(info), &info);
164 if (size) {
165 int height = info.lfHeight;
166 if (height < 0)
167 height = -height;
168 *size = height;
169 }
170 if (paintTextFlags)
171 *paintTextFlags = computePaintTextFlags(info);
172 return adoptRef(SkCreateTypefaceFromLOGFONT(info));
173 }
174 #endif
175
176 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
177 : m_textSize(-1)
178 , m_fakeBold(false)
179 , m_fakeItalic(false)
180 , m_orientation(Horizontal)
181 , m_typeface(adoptRef(SkTypeface::RefDefault()))
182 , m_paintTextFlags(0)
183 , m_isHashTableDeletedValue(true)
184 {
185 #if !USE(HARFBUZZ)
186 m_font = 0;
187 m_scriptCache = 0;
188 #endif
189 }
190
191 FontPlatformData::FontPlatformData()
192 : m_textSize(0)
193 , m_fakeBold(false)
194 , m_fakeItalic(false)
195 , m_orientation(Horizontal)
196 , m_typeface(adoptRef(SkTypeface::RefDefault()))
197 , m_paintTextFlags(0)
198 , m_isHashTableDeletedValue(false)
199 {
200 #if !USE(HARFBUZZ)
201 m_font = 0;
202 m_scriptCache = 0;
203 #endif
204 }
205
206 #if ENABLE(GDI_FONTS_ON_WINDOWS) && !USE(HARFBUZZ)
207 FontPlatformData::FontPlatformData(HFONT font, float size, FontOrientation orien tation)
208 : m_font(RefCountedHFONT::create(font))
209 , m_textSize(size)
210 , m_fakeBold(false)
211 , m_fakeItalic(false)
212 , m_orientation(orientation)
213 , m_scriptCache(0)
214 , m_typeface(CreateTypefaceFromHFont(font, 0, &m_paintTextFlags))
215 , m_isHashTableDeletedValue(false)
216 {
217 }
218 #endif
219
220 // FIXME: this constructor is needed for SVG fonts but doesn't seem to do much
221 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
222 : m_textSize(size)
223 , m_fakeBold(false)
224 , m_fakeItalic(false)
225 , m_orientation(Horizontal)
226 , m_typeface(adoptRef(SkTypeface::RefDefault()))
227 , m_paintTextFlags(0)
228 , m_isHashTableDeletedValue(false)
229 {
230 #if !USE(HARFBUZZ)
231 m_font = 0;
232 m_scriptCache = 0;
233 #endif
234 }
235
236 FontPlatformData::FontPlatformData(const FontPlatformData& data)
237 : m_textSize(data.m_textSize)
238 , m_fakeBold(data.m_fakeBold)
239 , m_fakeItalic(data.m_fakeItalic)
240 , m_orientation(data.m_orientation)
241 , m_typeface(data.m_typeface)
242 , m_paintTextFlags(data.m_paintTextFlags)
243 , m_isHashTableDeletedValue(false)
244 {
245 #if !USE(HARFBUZZ)
246 m_font = data.m_font;
247 m_scriptCache = 0;
248 #endif
249 }
250
251 FontPlatformData::FontPlatformData(const FontPlatformData& data, float textSize)
252 : m_textSize(textSize)
253 , m_fakeBold(data.m_fakeBold)
254 , m_fakeItalic(data.m_fakeItalic)
255 , m_orientation(data.m_orientation)
256 , m_typeface(data.m_typeface)
257 , m_paintTextFlags(data.m_paintTextFlags)
258 , m_isHashTableDeletedValue(false)
259 {
260 #if !USE(HARFBUZZ)
261 m_font = data.m_font;
262 m_scriptCache = 0;
263 #endif
264 }
265
266 FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family , float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation)
267 : m_textSize(textSize)
268 , m_fakeBold(fakeBold)
269 , m_fakeItalic(fakeItalic)
270 , m_orientation(orientation)
271 , m_typeface(tf)
272 , m_isHashTableDeletedValue(false)
273 {
274 // FIXME: This can be removed together with m_font once the last few
275 // uses of hfont() has been eliminated.
276 LOGFONT logFont;
277 SkLOGFONTFromTypeface(m_typeface.get(), &logFont);
278 logFont.lfHeight = -textSize;
279 m_paintTextFlags = computePaintTextFlags(logFont);
280
281 #if !USE(HARFBUZZ)
282 HFONT hFont = CreateFontIndirect(&logFont);
283 m_font = hFont ? RefCountedHFONT::create(hFont) : 0;
284 m_scriptCache = 0;
285 #endif
286 }
287
288 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& data)
289 {
290 if (this != &data) {
291 m_textSize = data.m_textSize;
292 m_fakeBold = data.m_fakeBold;
293 m_fakeItalic = data.m_fakeItalic;
294 m_orientation = data.m_orientation;
295 m_typeface = data.m_typeface;
296 m_paintTextFlags = data.m_paintTextFlags;
297
298 #if !USE(HARFBUZZ)
299 m_font = data.m_font;
300 // The following fields will get re-computed if necessary.
301 ScriptFreeCache(&m_scriptCache);
302 m_scriptCache = 0;
303 m_scriptFontProperties.clear();
304 #endif
305 }
306 return *this;
307 }
308
309 FontPlatformData::~FontPlatformData()
310 {
311 #if !USE(HARFBUZZ)
312 ScriptFreeCache(&m_scriptCache);
313 m_scriptCache = 0;
314 #endif
315 }
316
317 String FontPlatformData::fontFamilyName() const
318 {
319 #if ENABLE(GDI_FONTS_ON_WINDOWS)
320 HWndDC dc(0);
321 HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont()));
322 WCHAR name[LF_FACESIZE];
323 unsigned resultLength = GetTextFace(dc, LF_FACESIZE, name);
324 if (resultLength > 0)
325 resultLength--; // ignore the null terminator
326 SelectObject(dc, oldFont);
327 return String(name, resultLength);
328 #else
329 // FIXME: This returns the requested name, perhaps a better solution would b e to
330 // return the list of names provided by SkTypeface::createFamilyNameIterator .
331 ASSERT(typeface());
332 SkString familyName;
333 typeface()->getFamilyName(&familyName);
334 return String::fromUTF8(familyName.c_str());
335 #endif
336 }
337
338 bool FontPlatformData::isFixedPitch() const
339 {
340 #if ENABLE(GDI_FONTS_ON_WINDOWS)
341 // TEXTMETRICS have this. Set m_treatAsFixedPitch based off that.
342 HWndDC dc(0);
343 HGDIOBJ oldFont = SelectObject(dc, hfont());
344
345 // Yes, this looks backwards, but the fixed pitch bit is actually set if the font
346 // is *not* fixed pitch. Unbelievable but true.
347 TEXTMETRIC textMetric = { 0 };
348 if (!GetTextMetrics(dc, &textMetric)) {
349 if (ensureFontLoaded(hfont())) {
350 // Retry GetTextMetrics.
351 // FIXME: Handle gracefully the error if this call also fails.
352 // See http://crbug.com/6401.
353 if (!GetTextMetrics(dc, &textMetric))
354 LOG_ERROR("Unable to get the text metrics after second attempt") ;
355 }
356 }
357
358 bool treatAsFixedPitch = !(textMetric.tmPitchAndFamily & TMPF_FIXED_PITCH);
359
360 SelectObject(dc, oldFont);
361
362 return treatAsFixedPitch;
363 #else
364 return typeface() && typeface()->isFixedPitch();
365 #endif
366 }
367
368 bool FontPlatformData::operator==(const FontPlatformData& a) const
369 {
370 return SkTypeface::Equal(m_typeface.get(), a.m_typeface.get())
371 && m_textSize == a.m_textSize
372 && m_fakeBold == a.m_fakeBold
373 && m_fakeItalic == a.m_fakeItalic
374 && m_orientation == a.m_orientation
375 && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue;
376 }
377
378 #if USE(HARFBUZZ)
379 HarfBuzzFace* FontPlatformData::harfBuzzFace() const
380 {
381 if (!m_harfBuzzFace)
382 m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this ), uniqueID());
383
384 return m_harfBuzzFace.get();
385 }
386
387 #else
388 FontPlatformData::RefCountedHFONT::~RefCountedHFONT()
389 {
390 DeleteObject(m_hfont);
391 }
392
393 SCRIPT_FONTPROPERTIES* FontPlatformData::scriptFontProperties() const
394 {
395 if (!m_scriptFontProperties) {
396 m_scriptFontProperties = adoptPtr(new SCRIPT_FONTPROPERTIES);
397 memset(m_scriptFontProperties.get(), 0, sizeof(SCRIPT_FONTPROPERTIES));
398 m_scriptFontProperties->cBytes = sizeof(SCRIPT_FONTPROPERTIES);
399 HRESULT result = ScriptGetFontProperties(0, scriptCache(), m_scriptFontP roperties.get());
400 if (result == E_PENDING) {
401 HWndDC dc(0);
402 HGDIOBJ oldFont = SelectObject(dc, hfont());
403 HRESULT hr = ScriptGetFontProperties(dc, scriptCache(), m_scriptFont Properties.get());
404 if (S_OK != hr) {
405 if (FontPlatformData::ensureFontLoaded(hfont())) {
406 // FIXME: Handle gracefully the error if this call also fail s.
407 hr = ScriptGetFontProperties(dc, scriptCache(), m_scriptFont Properties.get());
408 if (S_OK != hr) {
409 LOG_ERROR("Unable to get the font properties after secon d attempt");
410 }
411 }
412 }
413
414 SelectObject(dc, oldFont);
415 }
416 }
417 return m_scriptFontProperties.get();
418 }
419
420 bool FontPlatformData::ensureFontLoaded(HFONT font)
421 {
422 blink::WebSandboxSupport* sandboxSupport = blink::Platform::current()->sandb oxSupport();
423 // if there is no sandbox, then we can assume the font
424 // was able to be loaded successfully already
425 return sandboxSupport ? sandboxSupport->ensureFontLoaded(font) : true;
426 }
427 #endif
428
429 #ifndef NDEBUG
430 String FontPlatformData::description() const
431 {
432 return String();
433 }
434 #endif
435
436 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698