Get additional DW font metrics when available.

BUG=chromium:395043
R=eae@chromium.org, caryclark@google.com

Author: bungeman@google.com

Review URL: https://codereview.chromium.org/412993002
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
index 4cb983f..28d41c1 100644
--- a/src/ports/SkScalerContext_win_dw.cpp
+++ b/src/ports/SkScalerContext_win_dw.cpp
@@ -26,6 +26,7 @@
 #include "SkTypeface_win_dw.h"
 
 #include <dwrite.h>
+#include <dwrite_1.h>
 
 static bool isLCD(const SkScalerContext::Rec& rec) {
     return SkMask::kLCD16_Format == rec.fMaskFormat ||
@@ -493,10 +494,8 @@
     }
 
     if (my) {
-        my->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
-        my->fAscent = my->fTop;
+        my->fAscent = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
         my->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
-        my->fBottom = my->fDescent;
         my->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
         my->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
         my->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem;
@@ -504,6 +503,33 @@
 
         my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
         my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+
+        if (NULL != fTypeface->fDWriteFontFace1.get()) {
+            DWRITE_FONT_METRICS1 dwfm1;
+            fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1);
+            my->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / upem;
+            my->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom) / upem;
+            my->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / upem;
+            my->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) / upem;
+
+            my->fMaxCharWidth = my->fXMax - my->fXMin;
+        } else {
+            AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get());
+            if (head.fExists &&
+                head.fSize >= sizeof(SkOTTableHead) &&
+                head->version == SkOTTableHead::version1)
+            {
+                my->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax) / upem;
+                my->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMin) / upem;
+                my->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin) / upem;
+                my->fXMax = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMax) / upem;
+
+                my->fMaxCharWidth = my->fXMax - my->fXMin;
+            } else {
+                my->fTop = my->fAscent;
+                my->fBottom = my->fDescent;
+            }
+        }
     }
 }
 
diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h
index b064ce5..465db34 100644
--- a/src/ports/SkTypeface_win_dw.h
+++ b/src/ports/SkTypeface_win_dw.h
@@ -17,6 +17,7 @@
 #include "SkTypes.h"
 
 #include <dwrite.h>
+#include <dwrite_1.h>
 
 class SkFontDescriptor;
 struct SkScalerContextRec;
@@ -50,7 +51,13 @@
         , fDWriteFontFamily(SkRefComPtr(fontFamily))
         , fDWriteFont(SkRefComPtr(font))
         , fDWriteFontFace(SkRefComPtr(fontFace))
-    { }
+    {
+        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
+            // IUnknown::QueryInterface states that if it fails, punk will be set to NULL.
+            // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
+            SK_ALWAYSBREAK(NULL == fDWriteFontFace1.get());
+        }
+    }
 
 public:
     SkTScopedComPtr<IDWriteFactory> fFactory;
@@ -59,6 +66,7 @@
     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
     SkTScopedComPtr<IDWriteFont> fDWriteFont;
     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
+    SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
 
     static DWriteFontTypeface* Create(IDWriteFactory* factory,
                                       IDWriteFontFace* fontFace,