| 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 |