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

Side by Side Diff: ui/gfx/platform_font_win.cc

Issue 696913002: Retrieve font metrics from skia if DirectWrite is enabled for font metrics calculations in the chro… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed comment Created 6 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
« ui/gfx/platform_font_win.h ('K') | « ui/gfx/platform_font_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« ui/gfx/platform_font_win.h ('K') | « ui/gfx/platform_font_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698