summaryrefslogtreecommitdiffstats
path: root/ui/gfx/platform_font_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gfx/platform_font_win.cc')
-rw-r--r--ui/gfx/platform_font_win.cc66
1 files changed, 50 insertions, 16 deletions
diff --git a/ui/gfx/platform_font_win.cc b/ui/gfx/platform_font_win.cc
index 40fa24f..58876dd 100644
--- a/ui/gfx/platform_font_win.cc
+++ b/ui/gfx/platform_font_win.cc
@@ -4,11 +4,10 @@
#include "ui/gfx/platform_font_win.h"
-#include <windows.h>
-#include <math.h>
-
#include <algorithm>
-#include <string>
+#include <dwrite.h>
+#include <math.h>
+#include <windows.h>
#include "base/logging.h"
#include "base/macros.h"
@@ -79,11 +78,11 @@ PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_;
// static
PlatformFontWin::AdjustFontCallback
- PlatformFontWin::adjust_font_callback = NULL;
+ PlatformFontWin::adjust_font_callback = nullptr;
PlatformFontWin::GetMinimumFontSizeCallback
PlatformFontWin::get_minimum_font_size_callback = NULL;
-bool PlatformFontWin::use_skia_for_font_metrics_ = false;
+IDWriteFactory* PlatformFontWin::direct_write_factory_ = NULL;
////////////////////////////////////////////////////////////////////////////////
// PlatformFontWin, public
@@ -207,6 +206,13 @@ NativeFont PlatformFontWin::GetNativeFont() const {
return font_ref_->hfont();
}
+void PlatformFontWin::SetDirectWriteFactory(IDWriteFactory* factory) {
+ // We grab a reference on the DirectWrite factory. This reference is
+ // leaked, which is ok because skia leaks it as well.
+ factory->AddRef();
+ direct_write_factory_ = factory;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Font, private:
@@ -249,11 +255,11 @@ PlatformFontWin::HFontRef* PlatformFontWin::GetBaseFontRef() {
}
PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) {
- TEXTMETRIC font_metrics;
-
- if (use_skia_for_font_metrics_)
+ if (direct_write_factory_)
return CreateHFontRefFromSkia(font);
+ TEXTMETRIC font_metrics;
+
{
base::win::ScopedGetDC screen_dc(NULL);
gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT);
@@ -322,6 +328,30 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia(
LOGFONT font_info = {0};
GetObject(gdi_font, sizeof(LOGFONT), &font_info);
+ // Skia does not return all values we need for font metrics. For e.g.
+ // the cap height which indicates the height of capital letters is not
+ // returned even though it is returned by DirectWrite.
+ // TODO(ananta)
+ // Fix SkScalerContext_win_dw.cpp to return all metrics we need from
+ // DirectWrite and remove the code here which retrieves metrics from
+ // DirectWrite to calculate the cap height.
+ base::win::ScopedComPtr<IDWriteGdiInterop> gdi_interop;
+ HRESULT hr = direct_write_factory_->GetGdiInterop(gdi_interop.Receive());
+ if (FAILED(hr)) {
+ CHECK(false);
+ return NULL;
+ }
+
+ base::win::ScopedComPtr<IDWriteFont> dwrite_font;
+ hr = gdi_interop->CreateFontFromLOGFONT(&font_info, dwrite_font.Receive());
+ if (FAILED(hr)) {
+ CHECK(false);
+ return NULL;
+ }
+
+ DWRITE_FONT_METRICS dwrite_font_metrics = {0};
+ dwrite_font->GetMetrics(&dwrite_font_metrics);
+
int skia_style = SkTypeface::kNormal;
if (font_info.lfWeight >= FW_SEMIBOLD &&
font_info.lfWeight <= FW_ULTRABOLD) {
@@ -346,12 +376,11 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia(
// 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 height = std::round(skia_metrics.fDescent - skia_metrics.fAscent);
+ const int baseline = std::max<int>(1, std::round(-skia_metrics.fAscent));
+ const int cap_height = std::round(-font_info.lfHeight *
+ dwrite_font_metrics.capHeight / dwrite_font_metrics.designUnitsPerEm);
+
// The metrics retrieved from skia don't have the average character width. In
// any case if we get the average character width from skia then use that or
// use the text extent technique as documented by microsoft. See
@@ -360,7 +389,12 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia(
skia_metrics.fAvgCharWidth == 0 ?
HFontRef::GetAverageCharWidthInDialogUnits(gdi_font)
: skia_metrics.fAvgCharWidth;
- const int font_size = std::max<int>(1, height - skia_metrics.fLeading);
+
+ // tmAscent - tmInternalLeading in gdi font land gives us the cap height.
+ // We can use fAscent - cap_height in DirectWrite land to get the internal
+ // leading value.
+ const int internal_leading = -skia_metrics.fAscent - cap_height;
+ const int font_size = std::max<int>(1, height - internal_leading);
int style = 0;
if (skia_style & SkTypeface::kItalic)