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 <algorithm> | 7 #include <algorithm> |
8 #include <dwrite.h> | 8 #include <dwrite.h> |
9 #include <math.h> | 9 #include <math.h> |
10 #include <windows.h> | 10 #include <windows.h> |
11 | 11 |
12 #include "base/debug/alias.h" | |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
13 #include "base/macros.h" | 14 #include "base/macros.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "base/strings/sys_string_conversions.h" | 16 #include "base/strings/sys_string_conversions.h" |
16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
17 #include "base/win/scoped_comptr.h" | 18 #include "base/win/scoped_comptr.h" |
18 #include "base/win/scoped_gdi_object.h" | 19 #include "base/win/scoped_gdi_object.h" |
19 #include "base/win/scoped_hdc.h" | 20 #include "base/win/scoped_hdc.h" |
20 #include "base/win/scoped_select_object.h" | 21 #include "base/win/scoped_select_object.h" |
21 #include "base/win/win_util.h" | 22 #include "base/win/win_util.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 return hr; | 119 return hr; |
119 } | 120 } |
120 | 121 |
121 DWRITE_FONT_WEIGHT weight = (font_style & SkTypeface::kBold) | 122 DWRITE_FONT_WEIGHT weight = (font_style & SkTypeface::kBold) |
122 ? DWRITE_FONT_WEIGHT_BOLD | 123 ? DWRITE_FONT_WEIGHT_BOLD |
123 : DWRITE_FONT_WEIGHT_NORMAL; | 124 : DWRITE_FONT_WEIGHT_NORMAL; |
124 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL; | 125 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL; |
125 DWRITE_FONT_STYLE italic = (font_style & SkTypeface::kItalic) | 126 DWRITE_FONT_STYLE italic = (font_style & SkTypeface::kItalic) |
126 ? DWRITE_FONT_STYLE_ITALIC | 127 ? DWRITE_FONT_STYLE_ITALIC |
127 : DWRITE_FONT_STYLE_NORMAL; | 128 : DWRITE_FONT_STYLE_NORMAL; |
129 | |
130 // The IDWriteFontFamily::GetFirstMatchingFont call fails on certain machines | |
131 // for fonts like MS UI Gothic, Segoe UI, etc. It is not clear why these | |
132 // fonts could be accessible to GDI and not to DirectWrite. | |
133 // The code below adds some debug fields to help track down these failures. | |
134 // 1. We get the matching font list for the font attributes passed in. | |
135 // 2. We get the font count in the family with a debug alias variable. | |
136 // 3. If we fail to get the font via the GetFirstMatchingFont call then we | |
137 // try to get the first matching font in the IDWriteFontList. | |
138 // 4. If GetFirstMatchingFont and IDWriteFontList both fail then we CHECK as | |
139 // before. | |
140 // Next step would be to remove the CHECKs in this function and fallback to | |
141 // GDI. | |
scottmg
2014/11/19 22:15:36
add crbug link
ananta
2014/11/19 22:21:30
Done.
| |
142 uint32 matching_font_count = 0; | |
143 base::debug::Alias(&matching_font_count); | |
144 | |
145 base::win::ScopedComPtr<IDWriteFontList> matching_font_list; | |
146 hr = font_family->GetMatchingFonts(weight, stretch, italic, | |
147 matching_font_list.Receive()); | |
148 if (SUCCEEDED(hr)) | |
149 matching_font_count = matching_font_list->GetFontCount(); | |
scottmg
2014/11/19 22:15:36
is it necessary to debug::Alias again after the as
ananta
2014/11/19 22:21:30
Done.
| |
150 | |
151 bool fallback_to_matching_font = false; | |
152 base::debug::Alias(&fallback_to_matching_font); | |
153 | |
128 hr = font_family->GetFirstMatchingFont(weight, stretch, italic, | 154 hr = font_family->GetFirstMatchingFont(weight, stretch, italic, |
129 dwrite_font); | 155 dwrite_font); |
156 if (FAILED(hr)) { | |
157 if (matching_font_list) { | |
158 hr = matching_font_list->GetFont(0, dwrite_font); | |
159 if (SUCCEEDED(hr)) | |
160 fallback_to_matching_font = true; | |
scottmg
2014/11/19 22:15:36
same
ananta
2014/11/19 22:21:30
Done.
| |
161 } | |
162 } | |
130 if (FAILED(hr)) | 163 if (FAILED(hr)) |
131 CHECK(false); | 164 CHECK(false); |
132 return hr; | 165 return hr; |
133 } | 166 } |
134 | 167 |
135 } // namespace | 168 } // namespace |
136 | 169 |
137 namespace gfx { | 170 namespace gfx { |
138 | 171 |
139 // static | 172 // static |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
440 const int baseline = std::max<int>(1, std::round(-skia_metrics.fAscent)); | 473 const int baseline = std::max<int>(1, std::round(-skia_metrics.fAscent)); |
441 const int cap_height = std::round(-font_info.lfHeight * | 474 const int cap_height = std::round(-font_info.lfHeight * |
442 dwrite_font_metrics.capHeight / dwrite_font_metrics.designUnitsPerEm); | 475 dwrite_font_metrics.capHeight / dwrite_font_metrics.designUnitsPerEm); |
443 | 476 |
444 // The metrics retrieved from skia don't have the average character width. In | 477 // The metrics retrieved from skia don't have the average character width. In |
445 // any case if we get the average character width from skia then use that or | 478 // any case if we get the average character width from skia then use that or |
446 // use the text extent technique as documented by microsoft. See | 479 // use the text extent technique as documented by microsoft. See |
447 // GetAverageCharWidthInDialogUnits for details. | 480 // GetAverageCharWidthInDialogUnits for details. |
448 const int ave_char_width = | 481 const int ave_char_width = |
449 skia_metrics.fAvgCharWidth == 0 ? | 482 skia_metrics.fAvgCharWidth == 0 ? |
450 HFontRef::GetAverageCharWidthInDialogUnits(gdi_font) | 483 HFontRef::GetAverageCharWidthInDialogUnits(gdi_font) - 1 |
451 : skia_metrics.fAvgCharWidth; | 484 : skia_metrics.fAvgCharWidth; |
452 | 485 |
453 // tmAscent - tmInternalLeading in gdi font land gives us the cap height. | 486 // tmAscent - tmInternalLeading in gdi font land gives us the cap height. |
454 // We can use fAscent - cap_height in DirectWrite land to get the internal | 487 // We can use fAscent - cap_height in DirectWrite land to get the internal |
455 // leading value. | 488 // leading value. |
456 const int internal_leading = -skia_metrics.fAscent - cap_height; | 489 const int internal_leading = -skia_metrics.fAscent - cap_height; |
457 const int font_size = std::max<int>(1, height - internal_leading); | 490 const int font_size = std::max<int>(1, height - internal_leading); |
458 | 491 |
459 int style = 0; | 492 int style = 0; |
460 if (skia_style & SkTypeface::kItalic) | 493 if (skia_style & SkTypeface::kItalic) |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 return new PlatformFontWin(native_font); | 575 return new PlatformFontWin(native_font); |
543 } | 576 } |
544 | 577 |
545 // static | 578 // static |
546 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, | 579 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, |
547 int font_size) { | 580 int font_size) { |
548 return new PlatformFontWin(font_name, font_size); | 581 return new PlatformFontWin(font_name, font_size); |
549 } | 582 } |
550 | 583 |
551 } // namespace gfx | 584 } // namespace gfx |
OLD | NEW |