[Win] Add support for the USE_TYPO_METRICS flag
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Nov 2015 18:12:21 +0000 (18:12 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Nov 2015 18:12:21 +0000 (18:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150451

Reviewed by Darin Adler.

Source/WebCore:

Make the Windows backend use the typo metrics when the OS/2 USE_TYPO_METRICS flag is set.

No new tests because this is already tested by fonts/use-typo-metrics-1.html

* platform/graphics/win/SimpleFontDataCGWin.cpp:
(WebCore::Font::platformInit):
* platform/graphics/win/SimpleFontDataCairoWin.cpp:
(WebCore::Font::platformInit):
* platform/graphics/win/SimpleFontDataWin.cpp:
(WebCore::Font::initGDIFont):

LayoutTests:

Remove failure expectation for fonts/use-typo-metrics-1.html on Windows.

* platform/win/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191893 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp

index c827d6cc0fa3ab2fb4901613f75feab2b079ee15..1fdfaca04bb0ac03adc5e3dddc73d0a241480c39 100644 (file)
@@ -1,3 +1,14 @@
+2015-11-02  Frederic Wang  <fred.wang@free.fr>
+
+        [Win] Add support for the USE_TYPO_METRICS flag
+        https://bugs.webkit.org/show_bug.cgi?id=150451
+
+        Reviewed by Darin Adler.
+
+        Remove failure expectation for fonts/use-typo-metrics-1.html on Windows.
+
+        * platform/win/TestExpectations:
+
 2015-11-02  Ryan Haddad  <ryanhaddad@apple.com>
 
         Marking the following tests as flaky on win
index 98c31bda681ca6de2d9eb52ce130cbea0017fcf3..ecc29ffa8198ecc6569a1b988c4d827d30f09e21 100644 (file)
@@ -3268,9 +3268,6 @@ webkit.org/b/150040 js/dom/dfg-custom-getter.html [ Failure ]
 # The following tests are not relevant on the Windows platform:
 fast/forms/hidpi-textfield-background-bleeding.html [ Skip ]
 
-# USE_TYPO_METRICS is not implemented on the Windows platform
-webkit.org/b/131839 fonts/use-typo-metrics-1.html [ ImageOnlyFailure ]
-
 # [Win] Newly imported W3C XMLHttpRequest tests failing
 webkit.org/b/150594 imported/w3c/web-platform-tests/XMLHttpRequest/send-conditional.htm [ Pass Failure ]
 webkit.org/b/150594 imported/w3c/web-platform-tests/XMLHttpRequest/send-data-unexpected-tostring.htm [ Pass Failure ]
index 7e7f53f935700bebb2a37d0bf3def2edc226b376..28450fa20b4bf14cf671a37980ed6606c3743871 100644 (file)
@@ -1,3 +1,21 @@
+2015-11-02  Frederic Wang  <fred.wang@free.fr>
+
+        [Win] Add support for the USE_TYPO_METRICS flag
+        https://bugs.webkit.org/show_bug.cgi?id=150451
+
+        Reviewed by Darin Adler.
+
+        Make the Windows backend use the typo metrics when the OS/2 USE_TYPO_METRICS flag is set.
+
+        No new tests because this is already tested by fonts/use-typo-metrics-1.html
+
+        * platform/graphics/win/SimpleFontDataCGWin.cpp:
+        (WebCore::Font::platformInit):
+        * platform/graphics/win/SimpleFontDataCairoWin.cpp:
+        (WebCore::Font::platformInit):
+        * platform/graphics/win/SimpleFontDataWin.cpp:
+        (WebCore::Font::initGDIFont):
+
 2015-11-02  Hyunduk Kim  <hyunduk.kim@samsung.com>
 
         Enable MediaSource::isTypeSupported() to handle the upper-cased MIME type & Codec
index fb7e0ec0cb9927fe1a584789e951a4345d978dac..240593635446c2166e7295ed33e62624f428556f 100644 (file)
@@ -34,6 +34,7 @@
 #include "FontDescription.h"
 #include "GlyphPage.h"
 #include "HWndDC.h"
+#include "OpenTypeTypes.h"
 #include <ApplicationServices/ApplicationServices.h>
 #include <WebKitSystemInterface/WebKitSystemInterface.h>
 #include <mlang.h>
@@ -63,6 +64,28 @@ void Font::platformInit()
     int iDescent = CGFontGetDescent(font);
     int iLineGap = CGFontGetLeading(font);
     int iCapHeight = CGFontGetCapHeight(font);
+
+    // The Open Font Format describes the OS/2 USE_TYPO_METRICS flag as follows:
+    // "If set, it is strongly recommended to use OS/2.sTypoAscender - OS/2.sTypoDescender+ OS/2.sTypoLineGap as a value for default line spacing for this font."
+    if (CFDataRef os2Table = CGFontCopyTableForTag(m_platformData.cgFont(), 'OS/2')) {
+        // For the structure of the OS/2 table, see
+        // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6OS2.html
+        const CFIndex fsSelectionOffset = 16 * 2 + 10 + 4 * 4 + 4 * 1;
+        const CFIndex sTypoAscenderOffset = fsSelectionOffset + 3 * 2;
+        const CFIndex sTypoDescenderOffset = sTypoAscenderOffset + 2;
+        const CFIndex sTypoLineGapOffset = sTypoDescenderOffset + 2;
+        if (CFDataGetLength(os2Table) >= sTypoLineGapOffset + 2) {
+            const UInt8* os2Data = CFDataGetBytePtr(os2Table);
+            const unsigned short useTypoMetricsMask = 1 << 7;
+            if (*(reinterpret_cast<const OpenType::UInt16*>(os2Data + fsSelectionOffset)) & useTypoMetricsMask) {
+                iAscent = *(reinterpret_cast<const OpenType::Int16*>(os2Data + sTypoAscenderOffset));
+                iDescent = *(reinterpret_cast<const OpenType::Int16*>(os2Data + sTypoDescenderOffset));
+                iLineGap = *(reinterpret_cast<const OpenType::Int16*>(os2Data + sTypoLineGapOffset));
+            }
+        }
+        CFRelease(os2Table);
+    }
+
     unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
     float pointSize = m_platformData.size();
     float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
index 1645db1dfb092ef18ffec2a8726ad3dd4c999202..638594ff31c70b2c58bdc21d8bb002667fe53b7e 100644 (file)
@@ -69,12 +69,23 @@ void Font::platformInit()
 
     cairo_win32_scaled_font_select_font(scaledFont, dc);
 
-    TEXTMETRIC textMetrics;
-    GetTextMetrics(dc, &textMetrics);
-    float ascent = textMetrics.tmAscent * metricsMultiplier;
-    float descent = textMetrics.tmDescent * metricsMultiplier;
+    OUTLINETEXTMETRIC metrics;
+    GetOutlineTextMetrics(dc, sizeof(metrics), &metrics);
+    TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
+    float ascent, descent, lineGap;
+    // The Open Font Format describes the OS/2 USE_TYPO_METRICS flag as follows:
+    // "If set, it is strongly recommended to use OS/2.sTypoAscender - OS/2.sTypoDescender+ OS/2.sTypoLineGap as a value for default line spacing for this font."
+    const UINT useTypoMetricsMask = 1 << 7;
+    if (metrics.otmfsSelection & useTypoMetricsMask) {
+        ascent = metrics.otmAscent * metricsMultiplier;
+        descent = metrics.otmDescent * metricsMultiplier;
+        lineGap = metrics.otmLineGap * metricsMultiplier;
+    } else {
+        ascent = textMetrics.tmAscent * metricsMultiplier;
+        descent = textMetrics.tmDescent * metricsMultiplier;
+        lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
+    }
     float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
-    float lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
 
     int faceLength = ::GetTextFace(dc, 0, 0);
     Vector<WCHAR> faceName(faceLength);
index fb6c345c1c76e5e171b06f5758137fed94af38e5..00544b74fee187fe74e11a88e8cb8b4d28a97c1a 100644 (file)
@@ -85,9 +85,19 @@ void Font::initGDIFont()
     OUTLINETEXTMETRIC metrics;
     GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
     TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
-    float ascent = textMetrics.tmAscent;
-    float descent = textMetrics.tmDescent;
-    float lineGap = textMetrics.tmExternalLeading;
+    float ascent, descent, lineGap;
+    // The Open Font Format describes the OS/2 USE_TYPO_METRICS flag as follows:
+    // "If set, it is strongly recommended to use OS/2.sTypoAscender - OS/2.sTypoDescender+ OS/2.sTypoLineGap as a value for default line spacing for this font."
+    const UINT useTypoMetricsMask = 1 << 7;
+    if (metrics.otmfsSelection & useTypoMetricsMask) {
+        ascent = metrics.otmAscent;
+        descent = metrics.otmDescent;
+        lineGap = metrics.otmLineGap;
+    } else {
+        ascent = textMetrics.tmAscent;
+        descent = textMetrics.tmDescent;
+        lineGap = textMetrics.tmExternalLeading;
+    }
     m_fontMetrics.setAscent(ascent);
     m_fontMetrics.setDescent(descent);
     m_fontMetrics.setLineGap(lineGap);