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

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

Issue 1819753003: Allow various font weights in gfx. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a lost comment and modify a render text unittest to not test black because of test env font con… Created 4 years, 6 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
« no previous file with comments | « ui/gfx/platform_font_win.h ('k') | ui/gfx/platform_font_win_unittest.cc » ('j') | 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 <dwrite.h> 8 #include <dwrite.h>
9 #include <limits.h> 9 #include <limits.h>
10 #include <math.h> 10 #include <math.h>
(...skipping 17 matching lines...) Expand all
28 #include "third_party/skia/include/core/SkFontLCDConfig.h" 28 #include "third_party/skia/include/core/SkFontLCDConfig.h"
29 #include "third_party/skia/include/core/SkRefCnt.h" 29 #include "third_party/skia/include/core/SkRefCnt.h"
30 #include "third_party/skia/include/core/SkTypeface.h" 30 #include "third_party/skia/include/core/SkTypeface.h"
31 #include "ui/gfx/canvas.h" 31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/font.h" 32 #include "ui/gfx/font.h"
33 #include "ui/gfx/font_render_params.h" 33 #include "ui/gfx/font_render_params.h"
34 #include "ui/gfx/win/scoped_set_map_mode.h" 34 #include "ui/gfx/win/scoped_set_map_mode.h"
35 35
36 namespace { 36 namespace {
37 37
38 // If the tmWeight field of a TEXTMETRIC structure has a value >= this, the
39 // font is bold.
40 const int kTextMetricWeightBold = 700;
41
42 // Returns the minimum font size, using the minimum size callback, if set. 38 // Returns the minimum font size, using the minimum size callback, if set.
43 int GetMinimumFontSize() { 39 int GetMinimumFontSize() {
44 int min_font_size = 0; 40 int min_font_size = 0;
45 if (gfx::PlatformFontWin::get_minimum_font_size_callback) 41 if (gfx::PlatformFontWin::get_minimum_font_size_callback)
46 min_font_size = gfx::PlatformFontWin::get_minimum_font_size_callback(); 42 min_font_size = gfx::PlatformFontWin::get_minimum_font_size_callback();
47 return min_font_size; 43 return min_font_size;
48 } 44 }
49 45
50 // Returns either minimum font allowed for a current locale or 46 // Returns either minimum font allowed for a current locale or
51 // lf_height + size_delta value. 47 // lf_height + size_delta value.
(...skipping 10 matching lines...) Expand all
62 return lf_height < 0 ? -min_font_size : min_font_size; 58 return lf_height < 0 ? -min_font_size : min_font_size;
63 } else { 59 } else {
64 return lf_height; 60 return lf_height;
65 } 61 }
66 } 62 }
67 63
68 // Sets style properties on |font_info| based on |font_style|. 64 // Sets style properties on |font_info| based on |font_style|.
69 void SetLogFontStyle(int font_style, LOGFONT* font_info) { 65 void SetLogFontStyle(int font_style, LOGFONT* font_info) {
70 font_info->lfUnderline = (font_style & gfx::Font::UNDERLINE) != 0; 66 font_info->lfUnderline = (font_style & gfx::Font::UNDERLINE) != 0;
71 font_info->lfItalic = (font_style & gfx::Font::ITALIC) != 0; 67 font_info->lfItalic = (font_style & gfx::Font::ITALIC) != 0;
72 font_info->lfWeight = (font_style & gfx::Font::BOLD) ? FW_BOLD : FW_NORMAL; 68 }
69
70 gfx::Font::Weight ToGfxFontWeight(int weight) {
71 return static_cast<gfx::Font::Weight>(weight);
73 } 72 }
74 73
75 // Returns the family name for the |IDWriteFont| interface passed in. 74 // Returns the family name for the |IDWriteFont| interface passed in.
76 // The family name is returned in the |family_name_ret| parameter. 75 // The family name is returned in the |family_name_ret| parameter.
77 // Returns S_OK on success. 76 // Returns S_OK on success.
78 // TODO(ananta) 77 // TODO(ananta)
79 // Remove the CHECKs in this function once this stabilizes on the field. 78 // Remove the CHECKs in this function once this stabilizes on the field.
80 HRESULT GetFamilyNameFromDirectWriteFont(IDWriteFont* dwrite_font, 79 HRESULT GetFamilyNameFromDirectWriteFont(IDWriteFont* dwrite_font,
81 base::string16* family_name_ret) { 80 base::string16* family_name_ret) {
82 base::win::ScopedComPtr<IDWriteFontFamily> font_family; 81 base::win::ScopedComPtr<IDWriteFontFamily> font_family;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 return hr; 152 return hr;
154 } 153 }
155 154
156 // Returns a matching IDWriteFont for the |font_info| passed in. If we fail 155 // Returns a matching IDWriteFont for the |font_info| passed in. If we fail
157 // to find a matching font, then we return the IDWriteFont corresponding to 156 // to find a matching font, then we return the IDWriteFont corresponding to
158 // the default font on the system. 157 // the default font on the system.
159 // Returns S_OK on success. 158 // Returns S_OK on success.
160 // The contents of the LOGFONT pointer |font_info| may be modified on 159 // The contents of the LOGFONT pointer |font_info| may be modified on
161 // return. 160 // return.
162 HRESULT GetMatchingDirectWriteFont(LOGFONT* font_info, 161 HRESULT GetMatchingDirectWriteFont(LOGFONT* font_info,
163 int font_style, 162 bool italic,
164 IDWriteFactory* factory, 163 IDWriteFactory* factory,
165 IDWriteFont** dwrite_font) { 164 IDWriteFont** dwrite_font) {
166 // First try the GDI compat route to get a matching DirectWrite font. 165 // First try the GDI compat route to get a matching DirectWrite font.
167 // If that succeeds then we are good. If that fails then try and find a 166 // If that succeeds then we are good. If that fails then try and find a
168 // match from the DirectWrite font collection. 167 // match from the DirectWrite font collection.
169 HRESULT hr = FindDirectWriteFontForLOGFONT(factory, font_info, dwrite_font); 168 HRESULT hr = FindDirectWriteFontForLOGFONT(factory, font_info, dwrite_font);
170 if (SUCCEEDED(hr)) 169 if (SUCCEEDED(hr))
171 return hr; 170 return hr;
172 171
173 // Get a matching font from the system font collection exposed by 172 // Get a matching font from the system font collection exposed by
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 // If we fail to find a matching font, then fallback to the first font in 231 // If we fail to find a matching font, then fallback to the first font in
233 // the list. This is what skia does as well. 232 // the list. This is what skia does as well.
234 hr = font_collection->GetFontFamily(0, font_family.Receive()); 233 hr = font_collection->GetFontFamily(0, font_family.Receive());
235 } 234 }
236 235
237 if (FAILED(hr)) { 236 if (FAILED(hr)) {
238 CHECK(false); 237 CHECK(false);
239 return hr; 238 return hr;
240 } 239 }
241 240
242 DWRITE_FONT_WEIGHT weight = (font_style & SkTypeface::kBold) 241 DWRITE_FONT_WEIGHT weight =
243 ? DWRITE_FONT_WEIGHT_BOLD 242 static_cast<DWRITE_FONT_WEIGHT>(font_info->lfWeight);
244 : DWRITE_FONT_WEIGHT_NORMAL;
245 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL; 243 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
246 DWRITE_FONT_STYLE italic = (font_style & SkTypeface::kItalic) 244 DWRITE_FONT_STYLE style =
247 ? DWRITE_FONT_STYLE_ITALIC 245 (italic) ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
248 : DWRITE_FONT_STYLE_NORMAL;
249 246
250 // The IDWriteFontFamily::GetFirstMatchingFont call fails on certain machines 247 // The IDWriteFontFamily::GetFirstMatchingFont call fails on certain machines
251 // for fonts like MS UI Gothic, Segoe UI, etc. It is not clear why these 248 // for fonts like MS UI Gothic, Segoe UI, etc. It is not clear why these
252 // fonts could be accessible to GDI and not to DirectWrite. 249 // fonts could be accessible to GDI and not to DirectWrite.
253 // The code below adds some debug fields to help track down these failures. 250 // The code below adds some debug fields to help track down these failures.
254 // 1. We get the matching font list for the font attributes passed in. 251 // 1. We get the matching font list for the font attributes passed in.
255 // 2. We get the font count in the family with a debug alias variable. 252 // 2. We get the font count in the family with a debug alias variable.
256 // 3. If GetFirstMatchingFont fails then we CHECK as before. 253 // 3. If GetFirstMatchingFont fails then we CHECK as before.
257 // Next step would be to remove the CHECKs in this function and fallback to 254 // Next step would be to remove the CHECKs in this function and fallback to
258 // GDI. 255 // GDI.
259 // http://crbug.com/434425 256 // http://crbug.com/434425
260 // TODO(ananta) 257 // TODO(ananta)
261 // Remove the GetMatchingFonts and related code here once we get to a stable 258 // Remove the GetMatchingFonts and related code here once we get to a stable
262 // state in canary. 259 // state in canary.
263 base::win::ScopedComPtr<IDWriteFontList> matching_font_list; 260 base::win::ScopedComPtr<IDWriteFontList> matching_font_list;
264 hr = font_family->GetMatchingFonts(weight, stretch, italic, 261 hr = font_family->GetMatchingFonts(weight, stretch, style,
265 matching_font_list.Receive()); 262 matching_font_list.Receive());
266 uint32_t matching_font_count = 0; 263 uint32_t matching_font_count = 0;
267 if (SUCCEEDED(hr)) 264 if (SUCCEEDED(hr))
268 matching_font_count = matching_font_list->GetFontCount(); 265 matching_font_count = matching_font_list->GetFontCount();
269 266
270 hr = font_family->GetFirstMatchingFont(weight, stretch, italic, 267 hr = font_family->GetFirstMatchingFont(weight, stretch, style, dwrite_font);
271 dwrite_font);
272 if (FAILED(hr)) { 268 if (FAILED(hr)) {
273 base::debug::Alias(&matching_font_count); 269 base::debug::Alias(&matching_font_count);
274 CHECK(false); 270 CHECK(false);
275 } 271 }
276 272
277 base::string16 font_name; 273 base::string16 font_name;
278 GetFamilyNameFromDirectWriteFont(*dwrite_font, &font_name); 274 GetFamilyNameFromDirectWriteFont(*dwrite_font, &font_name);
279 wcscpy_s(font_info->lfFaceName, arraysize(font_info->lfFaceName), 275 wcscpy_s(font_info->lfFaceName, arraysize(font_info->lfFaceName),
280 font_name.c_str()); 276 font_name.c_str());
281 return hr; 277 return hr;
(...skipping 22 matching lines...) Expand all
304 300
305 PlatformFontWin::PlatformFontWin(NativeFont native_font) { 301 PlatformFontWin::PlatformFontWin(NativeFont native_font) {
306 InitWithCopyOfHFONT(native_font); 302 InitWithCopyOfHFONT(native_font);
307 } 303 }
308 304
309 PlatformFontWin::PlatformFontWin(const std::string& font_name, 305 PlatformFontWin::PlatformFontWin(const std::string& font_name,
310 int font_size) { 306 int font_size) {
311 InitWithFontNameAndSize(font_name, font_size); 307 InitWithFontNameAndSize(font_name, font_size);
312 } 308 }
313 309
314 Font PlatformFontWin::DeriveFontWithHeight(int height, int style) {
315 DCHECK_GE(height, 0);
316
317 // Create a font with a height near that of the target height.
318 LOGFONT font_info;
319 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info);
320 font_info.lfHeight = height;
321 SetLogFontStyle(style, &font_info);
322
323 HFONT hfont = CreateFontIndirect(&font_info);
324 Font font(new PlatformFontWin(CreateHFontRef(hfont)));
325
326 // Respect the minimum font size constraint.
327 const int min_font_size = GetMinimumFontSize();
328
329 // Used to avoid shrinking the font and expanding it.
330 bool ran_shrink_loop = false;
331
332 // Iterate to find the largest font with a height <= |height|.
333 while ((font.GetHeight() > height) &&
334 (font.GetFontSize() >= min_font_size)) {
335 ran_shrink_loop = true;
336 Font derived_font = font.Derive(-1, style);
337 // Break the loop if the derived font is too small or hasn't shrunk at all.
338 if ((derived_font.GetFontSize() < min_font_size) ||
339 ((derived_font.GetFontSize() == font.GetFontSize()) &&
340 (derived_font.GetHeight() == font.GetHeight())))
341 break;
342 font = derived_font;
343 }
344
345 while ((!ran_shrink_loop && font.GetHeight() <= height) ||
346 (font.GetFontSize() < min_font_size)) {
347 Font derived_font = font.Derive(1, style);
348 // Break the loop if the derived font is too large or hasn't grown at all.
349 if (((derived_font.GetHeight() > height) &&
350 (font.GetFontSize() >= min_font_size)) ||
351 ((derived_font.GetFontSize() == font.GetFontSize()) &&
352 (derived_font.GetHeight() == font.GetHeight())))
353 break;
354 font = derived_font;
355 }
356 return font;
357 }
358
359 //////////////////////////////////////////////////////////////////////////////// 310 ////////////////////////////////////////////////////////////////////////////////
360 // PlatformFontWin, PlatformFont implementation: 311 // PlatformFontWin, PlatformFont implementation:
361 312
362 Font PlatformFontWin::DeriveFont(int size_delta, int style) const { 313 Font PlatformFontWin::DeriveFont(int size_delta,
314 int style,
315 Font::Weight weight) const {
363 LOGFONT font_info; 316 LOGFONT font_info;
364 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info); 317 GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info);
365 const int requested_font_size = font_ref_->requested_font_size(); 318 const int requested_font_size = font_ref_->requested_font_size();
366 font_info.lfHeight = AdjustFontSize(-requested_font_size, size_delta); 319 font_info.lfHeight = AdjustFontSize(-requested_font_size, size_delta);
320 font_info.lfWeight = static_cast<LONG>(weight);
367 SetLogFontStyle(style, &font_info); 321 SetLogFontStyle(style, &font_info);
368 322
369 HFONT hfont = CreateFontIndirect(&font_info); 323 HFONT hfont = CreateFontIndirect(&font_info);
370 return Font(new PlatformFontWin(CreateHFontRef(hfont))); 324 return Font(new PlatformFontWin(CreateHFontRef(hfont)));
371 } 325 }
372 326
373 int PlatformFontWin::GetHeight() { 327 int PlatformFontWin::GetHeight() {
374 return font_ref_->height(); 328 return font_ref_->height();
375 } 329 }
376 330
331 Font::Weight PlatformFontWin::GetWeight() const {
332 return font_ref_->weight();
333 }
334
377 int PlatformFontWin::GetBaseline() { 335 int PlatformFontWin::GetBaseline() {
378 return font_ref_->baseline(); 336 return font_ref_->baseline();
379 } 337 }
380 338
381 int PlatformFontWin::GetCapHeight() { 339 int PlatformFontWin::GetCapHeight() {
382 return font_ref_->cap_height(); 340 return font_ref_->cap_height();
383 } 341 }
384 342
385 int PlatformFontWin::GetExpectedTextWidth(int length) { 343 int PlatformFontWin::GetExpectedTextWidth(int length) {
386 return length * std::min(font_ref_->GetDluBaseX(), 344 return length * std::min(font_ref_->GetDluBaseX(),
(...skipping 29 matching lines...) Expand all
416 if (length <= 0) 374 if (length <= 0)
417 return GetFontName(); 375 return GetFontName();
418 return base::SysWideToUTF8(localized_font_name); 376 return base::SysWideToUTF8(localized_font_name);
419 } 377 }
420 378
421 int PlatformFontWin::GetFontSize() const { 379 int PlatformFontWin::GetFontSize() const {
422 return font_ref_->font_size(); 380 return font_ref_->font_size();
423 } 381 }
424 382
425 const FontRenderParams& PlatformFontWin::GetFontRenderParams() { 383 const FontRenderParams& PlatformFontWin::GetFontRenderParams() {
426 CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, 384 CR_DEFINE_STATIC_LOCAL(const FontRenderParams, params,
427 (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL))); 385 (gfx::GetFontRenderParams(FontRenderParamsQuery(), NULL)));
428 return params; 386 return params;
429 } 387 }
430 388
431 NativeFont PlatformFontWin::GetNativeFont() const { 389 NativeFont PlatformFontWin::GetNativeFont() const {
432 return font_ref_->hfont(); 390 return font_ref_->hfont();
433 } 391 }
434 392
435 // static 393 // static
436 void PlatformFontWin::SetDirectWriteFactory(IDWriteFactory* factory) { 394 void PlatformFontWin::SetDirectWriteFactory(IDWriteFactory* factory) {
437 // We grab a reference on the DirectWrite factory. This reference is 395 // We grab a reference on the DirectWrite factory. This reference is
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 base_font_ref_->AddRef(); 458 base_font_ref_->AddRef();
501 } 459 }
502 return base_font_ref_; 460 return base_font_ref_;
503 } 461 }
504 462
505 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { 463 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) {
506 TEXTMETRIC font_metrics; 464 TEXTMETRIC font_metrics;
507 465
508 { 466 {
509 base::win::ScopedGetDC screen_dc(NULL); 467 base::win::ScopedGetDC screen_dc(NULL);
510 gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); 468 ScopedSetMapMode mode(screen_dc, MM_TEXT);
511 GetTextMetricsForFont(screen_dc, font, &font_metrics); 469 GetTextMetricsForFont(screen_dc, font, &font_metrics);
512 } 470 }
513 471
514 if (direct_write_factory_) 472 if (direct_write_factory_)
515 return CreateHFontRefFromSkia(font, font_metrics); 473 return CreateHFontRefFromSkia(font, font_metrics);
516 474
517 return CreateHFontRefFromGDI(font, font_metrics); 475 return CreateHFontRefFromGDI(font, font_metrics);
518 } 476 }
519 477
520 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromGDI( 478 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromGDI(
521 HFONT font, 479 HFONT font,
522 const TEXTMETRIC& font_metrics) { 480 const TEXTMETRIC& font_metrics) {
523 const int height = std::max<int>(1, font_metrics.tmHeight); 481 const int height = std::max<int>(1, font_metrics.tmHeight);
524 const int baseline = std::max<int>(1, font_metrics.tmAscent); 482 const int baseline = std::max<int>(1, font_metrics.tmAscent);
525 const int cap_height = 483 const int cap_height =
526 std::max<int>(1, font_metrics.tmAscent - font_metrics.tmInternalLeading); 484 std::max<int>(1, font_metrics.tmAscent - font_metrics.tmInternalLeading);
527 const int ave_char_width = std::max<int>(1, font_metrics.tmAveCharWidth); 485 const int ave_char_width = std::max<int>(1, font_metrics.tmAveCharWidth);
528 const int font_size = 486 const int font_size =
529 std::max<int>(1, font_metrics.tmHeight - font_metrics.tmInternalLeading); 487 std::max<int>(1, font_metrics.tmHeight - font_metrics.tmInternalLeading);
530 int style = 0; 488 int style = 0;
531 if (font_metrics.tmItalic) 489 if (font_metrics.tmItalic)
532 style |= Font::ITALIC; 490 style |= Font::ITALIC;
533 if (font_metrics.tmUnderlined) 491 if (font_metrics.tmUnderlined)
534 style |= Font::UNDERLINE; 492 style |= Font::UNDERLINE;
535 if (font_metrics.tmWeight >= kTextMetricWeightBold)
536 style |= Font::BOLD;
537 493
538 return new HFontRef(font, font_size, height, baseline, cap_height, 494 return new HFontRef(font, font_size, height, baseline, cap_height,
539 ave_char_width, style); 495 ave_char_width, ToGfxFontWeight(font_metrics.tmWeight),
496 style);
540 } 497 }
541 498
542 // static 499 // static
543 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia( 500 PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia(
544 HFONT gdi_font, 501 HFONT gdi_font,
545 const TEXTMETRIC& font_metrics) { 502 const TEXTMETRIC& font_metrics) {
546 LOGFONT font_info = {0}; 503 LOGFONT font_info = {0};
547 GetObject(gdi_font, sizeof(LOGFONT), &font_info); 504 GetObject(gdi_font, sizeof(LOGFONT), &font_info);
548 505
549 // If the font height is passed in as 0, assume the height to be -1 to ensure 506 // If the font height is passed in as 0, assume the height to be -1 to ensure
550 // that we return the metrics for a 1 point font. 507 // that we return the metrics for a 1 point font.
551 // If the font height is positive it represents the rasterized font's cell 508 // If the font height is positive it represents the rasterized font's cell
552 // height. Calculate the actual height accordingly. 509 // height. Calculate the actual height accordingly.
553 if (font_info.lfHeight > 0) { 510 if (font_info.lfHeight > 0) {
554 font_info.lfHeight = 511 font_info.lfHeight =
555 font_metrics.tmInternalLeading - font_metrics.tmHeight; 512 font_metrics.tmInternalLeading - font_metrics.tmHeight;
556 } else if (font_info.lfHeight == 0) { 513 } else if (font_info.lfHeight == 0) {
557 font_info.lfHeight = -1; 514 font_info.lfHeight = -1;
558 } 515 }
559 516
560 int skia_style = SkTypeface::kNormal; 517 if (font_info.lfWeight == 0) {
561 if (font_info.lfWeight >= FW_SEMIBOLD && 518 font_info.lfWeight = static_cast<LONG>(Font::Weight::NORMAL);
562 font_info.lfWeight <= FW_ULTRABOLD) {
563 skia_style |= SkTypeface::kBold;
564 } 519 }
565 if (font_info.lfItalic) 520
566 skia_style |= SkTypeface::kItalic; 521 const bool italic = font_info.lfItalic != 0;
567 522
568 // Skia does not return all values we need for font metrics. For e.g. 523 // Skia does not return all values we need for font metrics. For e.g.
569 // the cap height which indicates the height of capital letters is not 524 // the cap height which indicates the height of capital letters is not
570 // returned even though it is returned by DirectWrite. 525 // returned even though it is returned by DirectWrite.
571 // TODO(ananta) 526 // TODO(ananta)
572 // Fix SkScalerContext_win_dw.cpp to return all metrics we need from 527 // Fix SkScalerContext_win_dw.cpp to return all metrics we need from
573 // DirectWrite and remove the code here which retrieves metrics from 528 // DirectWrite and remove the code here which retrieves metrics from
574 // DirectWrite to calculate the cap height. 529 // DirectWrite to calculate the cap height.
575 base::win::ScopedComPtr<IDWriteFont> dwrite_font; 530 base::win::ScopedComPtr<IDWriteFont> dwrite_font;
576 HRESULT hr = GetMatchingDirectWriteFont(&font_info, 531 HRESULT hr = GetMatchingDirectWriteFont(
577 skia_style, 532 &font_info, italic, direct_write_factory_, dwrite_font.Receive());
578 direct_write_factory_,
579 dwrite_font.Receive());
580 if (FAILED(hr)) { 533 if (FAILED(hr)) {
581 CHECK(false); 534 CHECK(false);
582 return nullptr; 535 return nullptr;
583 } 536 }
584 537
585 DWRITE_FONT_METRICS dwrite_font_metrics = {0}; 538 DWRITE_FONT_METRICS dwrite_font_metrics = {0};
586 dwrite_font->GetMetrics(&dwrite_font_metrics); 539 dwrite_font->GetMetrics(&dwrite_font_metrics);
587 540
541 SkFontStyle skia_font_style(font_info.lfWeight, SkFontStyle::kNormal_Width,
542 font_info.lfItalic ? SkFontStyle::kItalic_Slant
543 : SkFontStyle::kUpright_Slant);
588 sk_sp<SkTypeface> skia_face( 544 sk_sp<SkTypeface> skia_face(
589 SkTypeface::CreateFromName( 545 SkTypeface::MakeFromName(
590 base::SysWideToUTF8(font_info.lfFaceName).c_str(), 546 base::SysWideToUTF8(font_info.lfFaceName).c_str(),
591 static_cast<SkTypeface::Style>(skia_style))); 547 skia_font_style));
592 548
593 gfx::FontRenderParams font_params = 549 FontRenderParams font_params =
594 gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr); 550 gfx::GetFontRenderParams(FontRenderParamsQuery(), nullptr);
595 SkFontLCDConfig::SetSubpixelOrder( 551 SkFontLCDConfig::SetSubpixelOrder(
596 gfx::FontRenderParams::SubpixelRenderingToSkiaLCDOrder( 552 FontRenderParams::SubpixelRenderingToSkiaLCDOrder(
597 font_params.subpixel_rendering)); 553 font_params.subpixel_rendering));
598 SkFontLCDConfig::SetSubpixelOrientation( 554 SkFontLCDConfig::SetSubpixelOrientation(
599 gfx::FontRenderParams::SubpixelRenderingToSkiaLCDOrientation( 555 FontRenderParams::SubpixelRenderingToSkiaLCDOrientation(
600 font_params.subpixel_rendering)); 556 font_params.subpixel_rendering));
601 557
602 SkPaint paint; 558 SkPaint paint;
603 paint.setAntiAlias(font_params.antialiasing); 559 paint.setAntiAlias(font_params.antialiasing);
604 paint.setTypeface(std::move(skia_face)); 560 paint.setTypeface(std::move(skia_face));
605 paint.setTextSize(-font_info.lfHeight); 561 paint.setTextSize(-font_info.lfHeight);
606 SkPaint::FontMetrics skia_metrics; 562 SkPaint::FontMetrics skia_metrics;
607 paint.getFontMetrics(&skia_metrics); 563 paint.getFontMetrics(&skia_metrics);
608 564
609 // The calculations below are similar to those in the CreateHFontRef 565 // The calculations below are similar to those in the CreateHFontRef
610 // function. The height, baseline and cap height are rounded up to ensure 566 // function. The height, baseline and cap height are rounded up to ensure
611 // that they match up closely with GDI. 567 // that they match up closely with GDI.
612 const int height = std::ceil(skia_metrics.fDescent - skia_metrics.fAscent); 568 const int height = std::ceil(skia_metrics.fDescent - skia_metrics.fAscent);
613 const int baseline = std::max<int>(1, std::ceil(-skia_metrics.fAscent)); 569 const int baseline = std::max<int>(1, std::ceil(-skia_metrics.fAscent));
614 const int cap_height = std::ceil(paint.getTextSize() * 570 const int cap_height = std::ceil(paint.getTextSize() *
615 static_cast<double>(dwrite_font_metrics.capHeight) / 571 static_cast<double>(dwrite_font_metrics.capHeight) /
616 dwrite_font_metrics.designUnitsPerEm); 572 dwrite_font_metrics.designUnitsPerEm);
617 573
618 // The metrics retrieved from skia don't have the average character width. In 574 // The metrics retrieved from skia don't have the average character width. In
619 // any case if we get the average character width from skia then use that or 575 // any case if we get the average character width from skia then use that or
620 // the average character width in the TEXTMETRIC structure. 576 // the average character width in the TEXTMETRIC structure.
621 // TODO(ananta): Investigate whether it is possible to retrieve this value 577 // TODO(ananta): Investigate whether it is possible to retrieve this value
622 // from DirectWrite. 578 // from DirectWrite.
623 const int ave_char_width = 579 const int ave_char_width =
624 skia_metrics.fAvgCharWidth == 0 ? font_metrics.tmAveCharWidth 580 skia_metrics.fAvgCharWidth == 0 ? font_metrics.tmAveCharWidth
625 : skia_metrics.fAvgCharWidth; 581 : skia_metrics.fAvgCharWidth;
626 582
627 int style = 0; 583 int style = 0;
628 if (skia_style & SkTypeface::kItalic) 584 if (italic)
629 style |= Font::ITALIC; 585 style |= Font::ITALIC;
630 if (font_info.lfUnderline) 586 if (font_info.lfUnderline)
631 style |= Font::UNDERLINE; 587 style |= Font::UNDERLINE;
632 if (font_info.lfWeight >= kTextMetricWeightBold)
633 style |= Font::BOLD;
634 588
635 // DirectWrite may have substituted the GDI font name with a fallback 589 // DirectWrite may have substituted the GDI font name with a fallback
636 // font. Ensure that it is updated here. 590 // font. Ensure that it is updated here.
637 DeleteObject(gdi_font); 591 DeleteObject(gdi_font);
638 gdi_font = ::CreateFontIndirect(&font_info); 592 gdi_font = ::CreateFontIndirect(&font_info);
639 return new HFontRef(gdi_font, -font_info.lfHeight, height, baseline, 593 return new HFontRef(gdi_font, -font_info.lfHeight, height, baseline,
640 cap_height, ave_char_width, style); 594 cap_height, ave_char_width,
595 ToGfxFontWeight(font_info.lfWeight), style);
641 } 596 }
642 597
643 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { 598 PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) {
644 } 599 }
645 600
646 PlatformFontWin::~PlatformFontWin() { 601 PlatformFontWin::~PlatformFontWin() {
647 } 602 }
648 603
649 //////////////////////////////////////////////////////////////////////////////// 604 ////////////////////////////////////////////////////////////////////////////////
650 // PlatformFontWin::HFontRef: 605 // PlatformFontWin::HFontRef:
651 606
652 PlatformFontWin::HFontRef::HFontRef(HFONT hfont, 607 PlatformFontWin::HFontRef::HFontRef(HFONT hfont,
653 int font_size, 608 int font_size,
654 int height, 609 int height,
655 int baseline, 610 int baseline,
656 int cap_height, 611 int cap_height,
657 int ave_char_width, 612 int ave_char_width,
613 Font::Weight weight,
658 int style) 614 int style)
659 : hfont_(hfont), 615 : hfont_(hfont),
660 font_size_(font_size), 616 font_size_(font_size),
661 height_(height), 617 height_(height),
662 baseline_(baseline), 618 baseline_(baseline),
663 cap_height_(cap_height), 619 cap_height_(cap_height),
664 ave_char_width_(ave_char_width), 620 ave_char_width_(ave_char_width),
621 weight_(weight),
665 style_(style), 622 style_(style),
666 dlu_base_x_(-1), 623 dlu_base_x_(-1),
667 requested_font_size_(font_size) { 624 requested_font_size_(font_size) {
668 DLOG_ASSERT(hfont); 625 DLOG_ASSERT(hfont);
669 626
670 LOGFONT font_info; 627 LOGFONT font_info;
671 GetObject(hfont_, sizeof(LOGFONT), &font_info); 628 GetObject(hfont_, sizeof(LOGFONT), &font_info);
672 font_name_ = base::UTF16ToUTF8(base::string16(font_info.lfFaceName)); 629 font_name_ = base::UTF16ToUTF8(base::string16(font_info.lfFaceName));
673 630
674 // Retrieve the font size from the GetTextMetrics API instead of referencing 631 // Retrieve the font size from the GetTextMetrics API instead of referencing
(...skipping 13 matching lines...) Expand all
688 645
689 dlu_base_x_ = GetAverageCharWidthInDialogUnits(hfont_); 646 dlu_base_x_ = GetAverageCharWidthInDialogUnits(hfont_);
690 return dlu_base_x_; 647 return dlu_base_x_;
691 } 648 }
692 649
693 // static 650 // static
694 int PlatformFontWin::HFontRef::GetAverageCharWidthInDialogUnits( 651 int PlatformFontWin::HFontRef::GetAverageCharWidthInDialogUnits(
695 HFONT gdi_font) { 652 HFONT gdi_font) {
696 base::win::ScopedGetDC screen_dc(NULL); 653 base::win::ScopedGetDC screen_dc(NULL);
697 base::win::ScopedSelectObject font(screen_dc, gdi_font); 654 base::win::ScopedSelectObject font(screen_dc, gdi_font);
698 gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); 655 ScopedSetMapMode mode(screen_dc, MM_TEXT);
699 656
700 // Yes, this is how Microsoft recommends calculating the dialog unit 657 // Yes, this is how Microsoft recommends calculating the dialog unit
701 // conversions. See: http://support.microsoft.com/kb/125681 658 // conversions. See: http://support.microsoft.com/kb/125681
702 SIZE ave_text_size; 659 SIZE ave_text_size;
703 GetTextExtentPoint32(screen_dc, 660 GetTextExtentPoint32(screen_dc,
704 L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 661 L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
705 52, &ave_text_size); 662 52, &ave_text_size);
706 int dlu_base_x = (ave_text_size.cx / 26 + 1) / 2; 663 int dlu_base_x = (ave_text_size.cx / 26 + 1) / 2;
707 664
708 DCHECK_NE(dlu_base_x, -1); 665 DCHECK_NE(dlu_base_x, -1);
(...skipping 17 matching lines...) Expand all
726 return new PlatformFontWin(native_font); 683 return new PlatformFontWin(native_font);
727 } 684 }
728 685
729 // static 686 // static
730 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 687 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
731 int font_size) { 688 int font_size) {
732 return new PlatformFontWin(font_name, font_size); 689 return new PlatformFontWin(font_name, font_size);
733 } 690 }
734 691
735 } // namespace gfx 692 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/platform_font_win.h ('k') | ui/gfx/platform_font_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698