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. | |
142 // http://crbug.com/434425 | |
143 | |
144 base::win::ScopedComPtr<IDWriteFontList> matching_font_list; | |
145 hr = font_family->GetMatchingFonts(weight, stretch, italic, | |
146 matching_font_list.Receive()); | |
147 uint32 matching_font_count = 0; | |
148 if (SUCCEEDED(hr)) | |
149 matching_font_count = matching_font_list->GetFontCount(); | |
150 base::debug::Alias(&matching_font_count); | |
151 | |
152 bool fallback_to_matching_font = false; | |
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; | |
161 } | |
162 } | |
163 base::debug::Alias(&fallback_to_matching_font); | |
sky
2014/11/19 22:33:01
Can you move the Alias calls to where you need it?
ananta
2014/11/19 22:35:02
Done.
| |
164 | |
130 if (FAILED(hr)) | 165 if (FAILED(hr)) |
131 CHECK(false); | 166 CHECK(false); |
132 return hr; | 167 return hr; |
133 } | 168 } |
134 | 169 |
135 } // namespace | 170 } // namespace |
136 | 171 |
137 namespace gfx { | 172 namespace gfx { |
138 | 173 |
139 // static | 174 // 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)); | 475 const int baseline = std::max<int>(1, std::round(-skia_metrics.fAscent)); |
441 const int cap_height = std::round(-font_info.lfHeight * | 476 const int cap_height = std::round(-font_info.lfHeight * |
442 dwrite_font_metrics.capHeight / dwrite_font_metrics.designUnitsPerEm); | 477 dwrite_font_metrics.capHeight / dwrite_font_metrics.designUnitsPerEm); |
443 | 478 |
444 // The metrics retrieved from skia don't have the average character width. In | 479 // 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 | 480 // 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 | 481 // use the text extent technique as documented by microsoft. See |
447 // GetAverageCharWidthInDialogUnits for details. | 482 // GetAverageCharWidthInDialogUnits for details. |
448 const int ave_char_width = | 483 const int ave_char_width = |
449 skia_metrics.fAvgCharWidth == 0 ? | 484 skia_metrics.fAvgCharWidth == 0 ? |
450 HFontRef::GetAverageCharWidthInDialogUnits(gdi_font) | 485 HFontRef::GetAverageCharWidthInDialogUnits(gdi_font) - 1 |
451 : skia_metrics.fAvgCharWidth; | 486 : skia_metrics.fAvgCharWidth; |
452 | 487 |
453 // tmAscent - tmInternalLeading in gdi font land gives us the cap height. | 488 // 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 | 489 // We can use fAscent - cap_height in DirectWrite land to get the internal |
455 // leading value. | 490 // leading value. |
456 const int internal_leading = -skia_metrics.fAscent - cap_height; | 491 const int internal_leading = -skia_metrics.fAscent - cap_height; |
457 const int font_size = std::max<int>(1, height - internal_leading); | 492 const int font_size = std::max<int>(1, height - internal_leading); |
458 | 493 |
459 int style = 0; | 494 int style = 0; |
460 if (skia_style & SkTypeface::kItalic) | 495 if (skia_style & SkTypeface::kItalic) |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 return new PlatformFontWin(native_font); | 577 return new PlatformFontWin(native_font); |
543 } | 578 } |
544 | 579 |
545 // static | 580 // static |
546 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, | 581 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, |
547 int font_size) { | 582 int font_size) { |
548 return new PlatformFontWin(font_name, font_size); | 583 return new PlatformFontWin(font_name, font_size); |
549 } | 584 } |
550 | 585 |
551 } // namespace gfx | 586 } // namespace gfx |
OLD | NEW |