OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/platform_font_win.h" | 5 #include "ui/gfx/platform_font_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <math.h> | 8 #include <math.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "base/strings/sys_string_conversions.h" | 16 #include "base/strings/sys_string_conversions.h" |
17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
18 #include "base/win/scoped_comptr.h" | 18 #include "base/win/scoped_comptr.h" |
19 #include "base/win/scoped_gdi_object.h" | 19 #include "base/win/scoped_gdi_object.h" |
20 #include "base/win/scoped_hdc.h" | 20 #include "base/win/scoped_hdc.h" |
21 #include "base/win/scoped_select_object.h" | 21 #include "base/win/scoped_select_object.h" |
22 #include "base/win/win_util.h" | 22 #include "base/win/win_util.h" |
23 #include "third_party/skia/include/core/SkTypeface.h" | |
23 #include "ui/gfx/canvas.h" | 24 #include "ui/gfx/canvas.h" |
24 #include "ui/gfx/font.h" | 25 #include "ui/gfx/font.h" |
25 #include "ui/gfx/font_render_params.h" | 26 #include "ui/gfx/font_render_params.h" |
26 #include "ui/gfx/win/scoped_set_map_mode.h" | 27 #include "ui/gfx/win/scoped_set_map_mode.h" |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 // If the tmWeight field of a TEXTMETRIC structure has a value >= this, the | 31 // If the tmWeight field of a TEXTMETRIC structure has a value >= this, the |
31 // font is bold. | 32 // font is bold. |
32 const int kTextMetricWeightBold = 700; | 33 const int kTextMetricWeightBold = 700; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 | 76 |
76 // static | 77 // static |
77 PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_; | 78 PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_; |
78 | 79 |
79 // static | 80 // static |
80 PlatformFontWin::AdjustFontCallback | 81 PlatformFontWin::AdjustFontCallback |
81 PlatformFontWin::adjust_font_callback = NULL; | 82 PlatformFontWin::adjust_font_callback = NULL; |
82 PlatformFontWin::GetMinimumFontSizeCallback | 83 PlatformFontWin::GetMinimumFontSizeCallback |
83 PlatformFontWin::get_minimum_font_size_callback = NULL; | 84 PlatformFontWin::get_minimum_font_size_callback = NULL; |
84 | 85 |
85 IDWriteFactory* PlatformFontWin::direct_write_factory_ = NULL; | 86 bool PlatformFontWin::use_skia_for_font_metrics_ = false; |
86 | 87 |
87 //////////////////////////////////////////////////////////////////////////////// | 88 //////////////////////////////////////////////////////////////////////////////// |
88 // PlatformFontWin, public | 89 // PlatformFontWin, public |
89 | 90 |
90 PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) { | 91 PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) { |
91 } | 92 } |
92 | 93 |
93 PlatformFontWin::PlatformFontWin(NativeFont native_font) { | 94 PlatformFontWin::PlatformFontWin(NativeFont native_font) { |
94 InitWithCopyOfHFONT(native_font); | 95 InitWithCopyOfHFONT(native_font); |
95 } | 96 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 base_font_ref_ = PlatformFontWin::CreateHFontRef(font); | 244 base_font_ref_ = PlatformFontWin::CreateHFontRef(font); |
244 // base_font_ref_ is global, up the ref count so it's never deleted. | 245 // base_font_ref_ is global, up the ref count so it's never deleted. |
245 base_font_ref_->AddRef(); | 246 base_font_ref_->AddRef(); |
246 } | 247 } |
247 return base_font_ref_; | 248 return base_font_ref_; |
248 } | 249 } |
249 | 250 |
250 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { | 251 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { |
251 TEXTMETRIC font_metrics; | 252 TEXTMETRIC font_metrics; |
252 | 253 |
253 if (direct_write_factory_) { | 254 if (use_skia_for_font_metrics_) |
254 base::win::ScopedGDIObject<HFONT> gdi_font(font); | 255 return CreateHFontRefFromSkia(font); |
255 font = ConvertGDIFontToDirectWriteFont(gdi_font); | |
256 } | |
257 | 256 |
258 { | 257 { |
259 base::win::ScopedGetDC screen_dc(NULL); | 258 base::win::ScopedGetDC screen_dc(NULL); |
260 gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); | 259 gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); |
261 GetTextMetricsForFont(screen_dc, font, &font_metrics); | 260 GetTextMetricsForFont(screen_dc, font, &font_metrics); |
262 } | 261 } |
263 | 262 |
264 return CreateHFontRef(font, font_metrics); | 263 return CreateHFontRef(font, font_metrics); |
265 } | 264 } |
266 | 265 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 if (font_metrics.tmHeight > best_font_metrics.tmHeight) | 310 if (font_metrics.tmHeight > best_font_metrics.tmHeight) |
312 break; | 311 break; |
313 best_font.Set(font.release()); | 312 best_font.Set(font.release()); |
314 best_font_metrics = font_metrics; | 313 best_font_metrics = font_metrics; |
315 } while (true); | 314 } while (true); |
316 | 315 |
317 return Font(new PlatformFontWin(CreateHFontRef(best_font.release()))); | 316 return Font(new PlatformFontWin(CreateHFontRef(best_font.release()))); |
318 } | 317 } |
319 | 318 |
320 // static | 319 // static |
321 HFONT PlatformFontWin::ConvertGDIFontToDirectWriteFont(HFONT gdi_font) { | 320 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia( |
322 // This function uses the DirectWrite Gdi interop interfaces to convert the | 321 HFONT gdi_font) { |
323 // gdi font passed in to a HFONT which is compatible with DirectWrite font | 322 LOGFONT font_info = {0}; |
324 // metrics which could be different from GDI font metrics. This ensures that | 323 GetObject(gdi_font, sizeof(LOGFONT), &font_info); |
325 // widgets like labels which use font metrics to calculate bounds have the | 324 |
326 // same calculations as skia which uses DirectWrite. | 325 int skia_style = SkTypeface::kNormal; |
327 DCHECK(direct_write_factory_); | 326 if (font_info.lfWeight >= FW_SEMIBOLD && |
328 base::win::ScopedComPtr<IDWriteGdiInterop> gdi_interop; | 327 font_info.lfWeight <= FW_ULTRABOLD) { |
329 HRESULT hr = direct_write_factory_->GetGdiInterop(gdi_interop.Receive()); | 328 skia_style |= SkTypeface::kBold; |
330 if (FAILED(hr)) { | |
331 CHECK(false); | |
332 return NULL; | |
333 } | 329 } |
330 if (font_info.lfItalic) | |
331 skia_style |= SkTypeface::kItalic; | |
334 | 332 |
335 base::win::ScopedGetDC screen_dc(NULL); | 333 skia::RefPtr<SkTypeface> skia_face = skia::AdoptRef( |
336 gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); | 334 SkTypeface::CreateFromName( |
335 base::SysWideToUTF8(font_info.lfFaceName).c_str(), | |
336 static_cast<SkTypeface::Style>(skia_style))); | |
337 SkPaint paint; | |
338 paint.setAntiAlias(true); | |
scottmg
2014/11/01 00:39:15
is there anywhere these can be tied back to where
ananta
2014/11/01 00:56:13
Used the SystemParametersInfo function on the same
| |
339 paint.setTypeface(skia_face.get()); | |
340 SkPaint::FontMetrics skia_metrics; | |
341 paint.getFontMetrics(&skia_metrics); | |
337 | 342 |
338 base::win::ScopedSelectObject scoped_font(screen_dc, gdi_font); | 343 const int height = |
scottmg
2014/11/01 00:39:15
are all the max(1, ...) necessary? I'm not familia
ananta
2014/11/01 00:56:13
This is similar to the CreateHFontRef function whi
| |
344 std::max<int>(1, std::ceil(fabs(skia_metrics.fAscent)) + | |
345 std::ceil(skia_metrics.fDescent)); | |
346 const int baseline = std::max<int>(1, std::ceil(fabs(skia_metrics.fAscent))); | |
347 const int cap_height = std::max<int>(1, | |
348 std::ceil(fabs(skia_metrics.fAscent)) - skia_metrics.fLeading); | |
349 const int ave_char_width = std::max<int>(1, skia_metrics.fAvgCharWidth); | |
350 const int font_size = std::max<int>(1, height - skia_metrics.fLeading); | |
339 | 351 |
340 base::win::ScopedComPtr<IDWriteFontFace> font_face_gdi; | 352 int style = 0; |
341 hr = gdi_interop->CreateFontFaceFromHdc(screen_dc, font_face_gdi.Receive()); | 353 if (skia_style & SkTypeface::kItalic) |
342 if (FAILED(hr)) { | 354 style |= Font::ITALIC; |
343 CHECK(false); | 355 if (font_info.lfUnderline) |
344 return NULL; | 356 style |= Font::UNDERLINE; |
345 } | 357 if (font_info.lfWeight >= kTextMetricWeightBold) |
346 | 358 style |= Font::BOLD; |
347 LOGFONT dwrite_to_gdi_log_font = {0}; | 359 return new HFontRef(gdi_font, font_size, height, baseline, cap_height, |
348 hr = gdi_interop->ConvertFontFaceToLOGFONT(font_face_gdi, | 360 ave_char_width, style); |
349 &dwrite_to_gdi_log_font); | |
350 if (FAILED(hr)) { | |
351 CHECK(false); | |
352 return NULL; | |
353 } | |
354 return CreateFontIndirect(&dwrite_to_gdi_log_font); | |
355 } | 361 } |
356 | 362 |
357 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { | 363 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { |
358 } | 364 } |
359 | 365 |
360 //////////////////////////////////////////////////////////////////////////////// | 366 //////////////////////////////////////////////////////////////////////////////// |
361 // PlatformFontWin::HFontRef: | 367 // PlatformFontWin::HFontRef: |
362 | 368 |
363 PlatformFontWin::HFontRef::HFontRef(HFONT hfont, | 369 PlatformFontWin::HFontRef::HFontRef(HFONT hfont, |
364 int font_size, | 370 int font_size, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
422 return new PlatformFontWin(native_font); | 428 return new PlatformFontWin(native_font); |
423 } | 429 } |
424 | 430 |
425 // static | 431 // static |
426 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, | 432 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, |
427 int font_size) { | 433 int font_size) { |
428 return new PlatformFontWin(font_name, font_size); | 434 return new PlatformFontWin(font_name, font_size); |
429 } | 435 } |
430 | 436 |
431 } // namespace gfx | 437 } // namespace gfx |
OLD | NEW |