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 <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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |