Commit f2d0aaeb authored by ananta's avatar ananta Committed by Commit bot

Retrieve font metrics from skia if DirectWrite is enabled for font metrics...

Retrieve font metrics from skia if DirectWrite is enabled for font metrics calculations in the chrome browser UI.

The previous patch for getting the correct font metrics from DirectWrite https://codereview.chromium.org/692633003/
was wrong as it did not return the correct font metrics in all cases.

Getting the metrics from skia ensures that we get the same font metrics which would be used by skia for rendering.

Changes in this patch are as below:-
1. Removed DirectWrite factory code from PlatformFontWin. The PlatformFontWin::ConvertGDIFontToDirectWriteFont
   function has been replaced by the CreateHFontRefFromSkia function. This function is called if DirectWrite is
   enabled in the browser which sets a static bool on the PlatformFontWin class.

BUG=428645,427804,427802

Review URL: https://codereview.chromium.org/696913002

Cr-Commit-Position: refs/heads/master@{#302547}
parent fe89e5a5
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "ui/base/ime/input_method_initializer.h" #include "ui/base/ime/input_method_initializer.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include <dwrite.h>
#include "base/win/win_util.h" #include "base/win/win_util.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "net/cert/sha256_legacy_support_win.h" #include "net/cert/sha256_legacy_support_win.h"
...@@ -140,7 +141,7 @@ void MaybeEnableDirectWriteFontRendering() { ...@@ -140,7 +141,7 @@ void MaybeEnableDirectWriteFontRendering() {
__uuidof(IDWriteFactory), __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&factory)))); reinterpret_cast<IUnknown**>(&factory))));
SetDefaultSkiaFactory(SkFontMgr_New_DirectWrite(factory)); SetDefaultSkiaFactory(SkFontMgr_New_DirectWrite(factory));
gfx::PlatformFontWin::set_direct_write_factory(factory); gfx::PlatformFontWin::set_use_skia_for_font_metrics(true);
} }
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/win/scoped_hdc.h" #include "base/win/scoped_hdc.h"
#include "base/win/scoped_select_object.h" #include "base/win/scoped_select_object.h"
#include "base/win/win_util.h" #include "base/win/win_util.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/font.h" #include "ui/gfx/font.h"
#include "ui/gfx/font_render_params.h" #include "ui/gfx/font_render_params.h"
...@@ -82,7 +83,7 @@ PlatformFontWin::AdjustFontCallback ...@@ -82,7 +83,7 @@ PlatformFontWin::AdjustFontCallback
PlatformFontWin::GetMinimumFontSizeCallback PlatformFontWin::GetMinimumFontSizeCallback
PlatformFontWin::get_minimum_font_size_callback = NULL; PlatformFontWin::get_minimum_font_size_callback = NULL;
IDWriteFactory* PlatformFontWin::direct_write_factory_ = NULL; bool PlatformFontWin::use_skia_for_font_metrics_ = false;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// PlatformFontWin, public // PlatformFontWin, public
...@@ -250,10 +251,8 @@ PlatformFontWin::HFontRef* PlatformFontWin::GetBaseFontRef() { ...@@ -250,10 +251,8 @@ PlatformFontWin::HFontRef* PlatformFontWin::GetBaseFontRef() {
PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) {
TEXTMETRIC font_metrics; TEXTMETRIC font_metrics;
if (direct_write_factory_) { if (use_skia_for_font_metrics_)
base::win::ScopedGDIObject<HFONT> gdi_font(font); return CreateHFontRefFromSkia(font);
font = ConvertGDIFontToDirectWriteFont(gdi_font);
}
{ {
base::win::ScopedGetDC screen_dc(NULL); base::win::ScopedGetDC screen_dc(NULL);
...@@ -318,40 +317,52 @@ Font PlatformFontWin::DeriveWithCorrectedSize(HFONT base_font) { ...@@ -318,40 +317,52 @@ Font PlatformFontWin::DeriveWithCorrectedSize(HFONT base_font) {
} }
// static // static
HFONT PlatformFontWin::ConvertGDIFontToDirectWriteFont(HFONT gdi_font) { PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia(
// This function uses the DirectWrite Gdi interop interfaces to convert the HFONT gdi_font) {
// gdi font passed in to a HFONT which is compatible with DirectWrite font LOGFONT font_info = {0};
// metrics which could be different from GDI font metrics. This ensures that GetObject(gdi_font, sizeof(LOGFONT), &font_info);
// widgets like labels which use font metrics to calculate bounds have the
// same calculations as skia which uses DirectWrite. int skia_style = SkTypeface::kNormal;
DCHECK(direct_write_factory_); if (font_info.lfWeight >= FW_SEMIBOLD &&
base::win::ScopedComPtr<IDWriteGdiInterop> gdi_interop; font_info.lfWeight <= FW_ULTRABOLD) {
HRESULT hr = direct_write_factory_->GetGdiInterop(gdi_interop.Receive()); skia_style |= SkTypeface::kBold;
if (FAILED(hr)) {
CHECK(false);
return NULL;
}
base::win::ScopedGetDC screen_dc(NULL);
gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT);
base::win::ScopedSelectObject scoped_font(screen_dc, gdi_font);
base::win::ScopedComPtr<IDWriteFontFace> font_face_gdi;
hr = gdi_interop->CreateFontFaceFromHdc(screen_dc, font_face_gdi.Receive());
if (FAILED(hr)) {
CHECK(false);
return NULL;
} }
if (font_info.lfItalic)
skia_style |= SkTypeface::kItalic;
skia::RefPtr<SkTypeface> skia_face = skia::AdoptRef(
SkTypeface::CreateFromName(
base::SysWideToUTF8(font_info.lfFaceName).c_str(),
static_cast<SkTypeface::Style>(skia_style)));
BOOL antialiasing = TRUE;
SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &antialiasing, 0);
SkPaint paint;
paint.setAntiAlias(!!antialiasing);
paint.setTypeface(skia_face.get());
SkPaint::FontMetrics skia_metrics;
paint.getFontMetrics(&skia_metrics);
// The calculations below are similar to those in the CreateHFontRef
// function.
const int height =
std::max<int>(1, std::ceil(fabs(skia_metrics.fAscent)) +
std::ceil(skia_metrics.fDescent));
const int baseline = std::max<int>(1, std::ceil(fabs(skia_metrics.fAscent)));
const int cap_height = std::max<int>(1,
std::ceil(fabs(skia_metrics.fAscent)) - skia_metrics.fLeading);
const int ave_char_width = std::max<int>(1, skia_metrics.fAvgCharWidth);
const int font_size = std::max<int>(1, height - skia_metrics.fLeading);
LOGFONT dwrite_to_gdi_log_font = {0}; int style = 0;
hr = gdi_interop->ConvertFontFaceToLOGFONT(font_face_gdi, if (skia_style & SkTypeface::kItalic)
&dwrite_to_gdi_log_font); style |= Font::ITALIC;
if (FAILED(hr)) { if (font_info.lfUnderline)
CHECK(false); style |= Font::UNDERLINE;
return NULL; if (font_info.lfWeight >= kTextMetricWeightBold)
} style |= Font::BOLD;
return CreateFontIndirect(&dwrite_to_gdi_log_font); return new HFontRef(gdi_font, font_size, height, baseline, cap_height,
ave_char_width, style);
} }
PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef UI_GFX_PLATFORM_FONT_WIN_H_ #ifndef UI_GFX_PLATFORM_FONT_WIN_H_
#define UI_GFX_PLATFORM_FONT_WIN_H_ #define UI_GFX_PLATFORM_FONT_WIN_H_
#include <dwrite.h>
#include <string> #include <string>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
...@@ -68,9 +67,10 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { ...@@ -68,9 +67,10 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont {
virtual const FontRenderParams& GetFontRenderParams() const override; virtual const FontRenderParams& GetFontRenderParams() const override;
virtual NativeFont GetNativeFont() const override; virtual NativeFont GetNativeFont() const override;
// Called once during initialization if we are using DirectWrite for fonts. // Called once during initialization if should be retrieving font metrics
static void set_direct_write_factory(IDWriteFactory* factory) { // from skia.
direct_write_factory_ = factory; static void set_use_skia_for_font_metrics(bool use_skia_for_font_metrics) {
use_skia_for_font_metrics_ = use_skia_for_font_metrics;
} }
private: private:
...@@ -150,10 +150,10 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { ...@@ -150,10 +150,10 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont {
// UI thread. // UI thread.
static HFontRef* GetBaseFontRef(); static HFontRef* GetBaseFontRef();
// Creates and returns a new HFONTRef from the specified HFONT. // Creates and returns a new HFontRef from the specified HFONT.
static HFontRef* CreateHFontRef(HFONT font); static HFontRef* CreateHFontRef(HFONT font);
// Creates and returns a new HFONTRef from the specified HFONT. Uses provided // Creates and returns a new HFontRef from the specified HFONT. Uses provided
// |font_metrics| instead of calculating new one. // |font_metrics| instead of calculating new one.
static HFontRef* CreateHFontRef(HFONT font, const TEXTMETRIC& font_metrics); static HFontRef* CreateHFontRef(HFONT font, const TEXTMETRIC& font_metrics);
...@@ -161,12 +161,11 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { ...@@ -161,12 +161,11 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont {
// |base_font|. // |base_font|.
static Font DeriveWithCorrectedSize(HFONT base_font); static Font DeriveWithCorrectedSize(HFONT base_font);
// Converts the GDI font identified by the |gdi_font| parameter to a // Creates and returns a new HFontRef from the specified HFONT using metrics
// DirectWrite compatible HFONT, i.e with metrics compatible with // from skia. Currently this is only used if we use DirectWrite for font
// DirectWrite.
// Returns the HFONT which is created from DirectWrite compatible font
// metrics. // metrics.
static HFONT ConvertGDIFontToDirectWriteFont(HFONT gdi_font); static PlatformFontWin::HFontRef* CreateHFontRefFromSkia(
HFONT gdi_font);
// Creates a new PlatformFontWin with the specified HFontRef. Used when // Creates a new PlatformFontWin with the specified HFontRef. Used when
// constructing a Font from a HFONT we don't want to copy. // constructing a Font from a HFONT we don't want to copy.
...@@ -178,9 +177,9 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { ...@@ -178,9 +177,9 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont {
// Indirect reference to the HFontRef, which references the underlying HFONT. // Indirect reference to the HFontRef, which references the underlying HFONT.
scoped_refptr<HFontRef> font_ref_; scoped_refptr<HFontRef> font_ref_;
// Pointer to the global IDWriteFactory interface. This is only set if we are // Set to true if font metrics are to be retrieved from skia. Defaults to
// using DirectWrite for fonts. Defaults to NULL. // false.
static IDWriteFactory* direct_write_factory_; static bool use_skia_for_font_metrics_;
DISALLOW_COPY_AND_ASSIGN(PlatformFontWin); DISALLOW_COPY_AND_ASSIGN(PlatformFontWin);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment