[PATCH 1/2] dwrite/tests: Test underline/strikethrough metrics for all system fonts
Nikolay Sivov
nsivov at codeweavers.com
Sun Apr 10 15:59:10 CDT 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/tests/font.c | 224 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 217 insertions(+), 7 deletions(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index ec631bd..0c060b8 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -1,7 +1,7 @@
/*
* Font related tests
*
- * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
+ * Copyright 2012, 2014-2016 Nikolay Sivov for CodeWeavers
* Copyright 2014 Aric Stewart for CodeWeavers
*
* This library is free software; you can redistribute it and/or
@@ -40,6 +40,16 @@
#define MS_VDMX_TAG MS_MAKE_TAG('V','D','M','X')
#define MS_GASP_TAG MS_MAKE_TAG('g','a','s','p')
#define MS_CPAL_TAG MS_MAKE_TAG('C','P','A','L')
+#define MS_0S2_TAG MS_MAKE_TAG('O','S','/','2')
+#define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
+#define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
+#define MS_POST_TAG MS_MAKE_TAG('p','o','s','t')
+
+#ifdef WORDS_BIGENDIAN
+#define GET_BE_WORD(x) (x)
+#else
+#define GET_BE_WORD(x) RtlUshortByteSwap(x)
+#endif
#define EXPECT_HR(hr,hr_exp) \
ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
@@ -100,6 +110,90 @@ static const WCHAR tahomaStrangecaseW[] = {'t','A','h','O','m','A',0};
static const WCHAR blahW[] = {'B','l','a','h','!',0};
static const WCHAR emojiW[] = {'S','e','g','o','e',' ','U','I',' ','E','m','o','j','i',0};
+/* PANOSE is 10 bytes in size, need to pack the structure properly */
+#include "pshpack2.h"
+typedef struct
+{
+ ULONG version;
+ ULONG revision;
+ ULONG checksumadj;
+ ULONG magic;
+ USHORT flags;
+ USHORT unitsPerEm;
+ ULONGLONG created;
+ ULONGLONG modified;
+ SHORT xMin;
+ SHORT yMin;
+ SHORT xMax;
+ SHORT yMax;
+ USHORT macStyle;
+ USHORT lowestRecPPEM;
+ SHORT direction_hint;
+ SHORT index_format;
+ SHORT glyphdata_format;
+} TT_HEAD;
+
+typedef struct
+{
+ USHORT version;
+ SHORT xAvgCharWidth;
+ USHORT usWeightClass;
+ USHORT usWidthClass;
+ SHORT fsType;
+ SHORT ySubscriptXSize;
+ SHORT ySubscriptYSize;
+ SHORT ySubscriptXOffset;
+ SHORT ySubscriptYOffset;
+ SHORT ySuperscriptXSize;
+ SHORT ySuperscriptYSize;
+ SHORT ySuperscriptXOffset;
+ SHORT ySuperscriptYOffset;
+ SHORT yStrikeoutSize;
+ SHORT yStrikeoutPosition;
+ SHORT sFamilyClass;
+ PANOSE panose;
+ ULONG ulUnicodeRange1;
+ ULONG ulUnicodeRange2;
+ ULONG ulUnicodeRange3;
+ ULONG ulUnicodeRange4;
+ CHAR achVendID[4];
+ USHORT fsSelection;
+ USHORT usFirstCharIndex;
+ USHORT usLastCharIndex;
+ /* According to the Apple spec, original version didn't have the below fields,
+ * version numbers were taken from the OpenType spec.
+ */
+ /* version 0 (TrueType 1.5) */
+ USHORT sTypoAscender;
+ USHORT sTypoDescender;
+ USHORT sTypoLineGap;
+ USHORT usWinAscent;
+ USHORT usWinDescent;
+ /* version 1 (TrueType 1.66) */
+ ULONG ulCodePageRange1;
+ ULONG ulCodePageRange2;
+ /* version 2 (OpenType 1.2) */
+ SHORT sxHeight;
+ SHORT sCapHeight;
+ USHORT usDefaultChar;
+ USHORT usBreakChar;
+ USHORT usMaxContext;
+} TT_OS2_V2;
+
+typedef struct {
+ ULONG Version;
+ ULONG italicAngle;
+ SHORT underlinePosition;
+ SHORT underlineThickness;
+ ULONG fixed_pitch;
+ ULONG minmemType42;
+ ULONG maxmemType42;
+ ULONG minmemType1;
+ ULONG maxmemType1;
+} TT_POST;
+
+#include "poppack.h"
+
static IDWriteFactory *create_factory(void)
{
IDWriteFactory *factory;
@@ -1425,9 +1519,92 @@ todo_wine
DELETE_FONTFILE(path);
}
+static void get_expected_font_metrics(IDWriteFontFace *fontface, DWRITE_FONT_METRICS *metrics)
+{
+ void *os2_context, *head_context, *post_context;
+ const TT_OS2_V2 *tt_os2;
+ const TT_HEAD *tt_head;
+ const TT_POST *tt_post;
+ UINT32 size;
+ BOOL exists;
+ HRESULT hr;
+
+ memset(metrics, 0, sizeof(*metrics));
+
+ hr = IDWriteFontFace_TryGetFontTable(fontface, MS_0S2_TAG, (const void**)&tt_os2, &size, &os2_context, &exists);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IDWriteFontFace_TryGetFontTable(fontface, MS_HEAD_TAG, (const void**)&tt_head, &size, &head_context, &exists);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IDWriteFontFace_TryGetFontTable(fontface, MS_POST_TAG, (const void**)&tt_post, &size, &post_context, &exists);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ if (tt_head)
+ metrics->designUnitsPerEm = GET_BE_WORD(tt_head->unitsPerEm);
+
+ if (tt_os2) {
+ metrics->strikethroughPosition = GET_BE_WORD(tt_os2->yStrikeoutPosition);
+ metrics->strikethroughThickness = GET_BE_WORD(tt_os2->yStrikeoutSize);
+ }
+
+ if (tt_post) {
+ metrics->underlinePosition = GET_BE_WORD(tt_post->underlinePosition);
+ metrics->underlineThickness = GET_BE_WORD(tt_post->underlineThickness);
+ }
+
+ if (metrics->strikethroughThickness || metrics->underlineThickness) {
+ if (!metrics->strikethroughThickness)
+ metrics->strikethroughThickness = metrics->underlineThickness;
+ if (!metrics->underlineThickness)
+ metrics->underlineThickness = metrics->strikethroughThickness;
+ }
+ else {
+ metrics->strikethroughThickness = metrics->designUnitsPerEm / 14;
+ metrics->underlineThickness = metrics->designUnitsPerEm / 14;
+ }
+
+ if (tt_os2)
+ IDWriteFontFace_ReleaseFontTable(fontface, os2_context);
+ if (tt_head)
+ IDWriteFontFace_ReleaseFontTable(fontface, head_context);
+ if (tt_post)
+ IDWriteFontFace_ReleaseFontTable(fontface, post_context);
+}
+
+static void check_font_metrics(const WCHAR *nameW, const DWRITE_FONT_METRICS *got, const DWRITE_FONT_METRICS *expected)
+{
+ ok(got->designUnitsPerEm == expected->designUnitsPerEm, "font %s: designUnitsPerEm %u, expected %u\n",
+ wine_dbgstr_w(nameW), got->designUnitsPerEm, expected->designUnitsPerEm);
+ ok(got->underlinePosition == expected->underlinePosition, "font %s: underlinePosition %d, expected %d\n",
+ wine_dbgstr_w(nameW), got->underlinePosition, expected->underlinePosition);
+todo_wine_if(got->underlineThickness == 0)
+ ok(got->underlineThickness == expected->underlineThickness, "font %s: underlineThickness %u, "
+ "expected %u\n", wine_dbgstr_w(nameW), got->underlineThickness, expected->underlineThickness);
+ ok(got->strikethroughPosition == expected->strikethroughPosition, "font %s: strikethroughPosition %d, expected %d\n",
+ wine_dbgstr_w(nameW), got->strikethroughPosition, expected->strikethroughPosition);
+todo_wine_if(got->strikethroughThickness == 0)
+ ok(got->strikethroughThickness == expected->strikethroughThickness, "font %s: strikethroughThickness %u, "
+ "expected %u\n", wine_dbgstr_w(nameW), got->strikethroughThickness, expected->strikethroughThickness);
+}
+
+static void get_enus_string(IDWriteLocalizedStrings *strings, WCHAR *buff, UINT32 size)
+{
+ static const WCHAR enusW[] = {'e','n','-','u','s',0};
+ BOOL exists = FALSE;
+ UINT32 index;
+ HRESULT hr;
+
+ hr = IDWriteLocalizedStrings_FindLocaleName(strings, enusW, &index, &exists);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(exists, "got %d\n", exists);
+
+ hr = IDWriteLocalizedStrings_GetString(strings, index, buff, size);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+}
+
static void test_GetMetrics(void)
{
DWRITE_FONT_METRICS metrics, metrics2;
+ IDWriteFontCollection *syscollection;
IDWriteGdiInterop *interop;
IDWriteFontFace *fontface;
IDWriteFactory *factory;
@@ -1436,7 +1613,7 @@ static void test_GetMetrics(void)
IDWriteFont1 *font1;
IDWriteFont *font;
LOGFONTW logfont;
- UINT32 count;
+ UINT32 count, i;
HRESULT hr;
HDC hdc;
HFONT hfont;
@@ -1607,6 +1784,44 @@ if (0) /* crashes on native */
IDWriteFontFile_Release(file);
IDWriteFont_Release(font);
+ /* test metrics for whole system collection */
+ hr = IDWriteFactory_GetSystemFontCollection(factory, &syscollection, FALSE);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = IDWriteFontCollection_GetFontFamilyCount(syscollection);
+
+ for (i = 0; i < count; i++) {
+ DWRITE_FONT_METRICS expected_metrics;
+ IDWriteLocalizedStrings *names;
+ IDWriteFontFamily *family;
+ IDWriteFont *font;
+ WCHAR nameW[256];
+
+ hr = IDWriteFontCollection_GetFontFamily(syscollection, i, &family);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL,
+ DWRITE_FONT_STYLE_NORMAL, &font);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFont_CreateFontFace(font, &fontface);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFontFamily_GetFamilyNames(family, &names);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ get_enus_string(names, nameW, sizeof(nameW)/sizeof(nameW[0]));
+
+ IDWriteLocalizedStrings_Release(names);
+ IDWriteFont_Release(font);
+
+ IDWriteFontFace_GetMetrics(fontface, &metrics);
+ get_expected_font_metrics(fontface, &expected_metrics);
+ check_font_metrics(nameW, &metrics, &expected_metrics);
+
+ IDWriteFontFace_Release(fontface);
+ IDWriteFontFamily_Release(family);
+ }
+ IDWriteFontCollection_Release(syscollection);
IDWriteFactory_Release(factory);
}
@@ -4036,11 +4251,6 @@ struct VDMX_vTable
SHORT yMin;
};
-#ifdef WORDS_BIGENDIAN
-#define GET_BE_WORD(x) (x)
-#else
-#define GET_BE_WORD(x) RtlUshortByteSwap(x)
-#endif
static const struct VDMX_group *find_vdmx_group(const struct VDMX_Header *hdr)
{
--
2.8.0.rc3
More information about the wine-patches
mailing list