gdi32: Add a test for outline text metrics.
This commit is contained in:
parent
e02168791e
commit
6f7457d8ad
|
@ -159,6 +159,30 @@ static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DW
|
||||||
return 1; /* continue enumeration */
|
return 1; /* continue enumeration */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void compare_tm(const TEXTMETRICA *tm, const TEXTMETRICA *otm)
|
||||||
|
{
|
||||||
|
ok(tm->tmHeight == otm->tmHeight, "tmHeight %d != %d\n", tm->tmHeight, otm->tmHeight);
|
||||||
|
ok(tm->tmAscent == otm->tmAscent, "tmAscent %d != %d\n", tm->tmAscent, otm->tmAscent);
|
||||||
|
ok(tm->tmDescent == otm->tmDescent, "tmDescent %d != %d\n", tm->tmDescent, otm->tmDescent);
|
||||||
|
ok(tm->tmInternalLeading == otm->tmInternalLeading, "tmInternalLeading %d != %d\n", tm->tmInternalLeading, otm->tmInternalLeading);
|
||||||
|
ok(tm->tmExternalLeading == otm->tmExternalLeading, "tmExternalLeading %d != %d\n", tm->tmExternalLeading, otm->tmExternalLeading);
|
||||||
|
ok(tm->tmAveCharWidth == otm->tmAveCharWidth, "tmAveCharWidth %d != %d\n", tm->tmAveCharWidth, otm->tmAveCharWidth);
|
||||||
|
ok(tm->tmMaxCharWidth == otm->tmMaxCharWidth, "tmMaxCharWidth %d != %d\n", tm->tmMaxCharWidth, otm->tmMaxCharWidth);
|
||||||
|
ok(tm->tmWeight == otm->tmWeight, "tmWeight %d != %d\n", tm->tmWeight, otm->tmWeight);
|
||||||
|
ok(tm->tmOverhang == otm->tmOverhang, "tmOverhang %d != %d\n", tm->tmOverhang, otm->tmOverhang);
|
||||||
|
ok(tm->tmDigitizedAspectX == otm->tmDigitizedAspectX, "tmDigitizedAspectX %d != %d\n", tm->tmDigitizedAspectX, otm->tmDigitizedAspectX);
|
||||||
|
ok(tm->tmDigitizedAspectY == otm->tmDigitizedAspectY, "tmDigitizedAspectY %d != %d\n", tm->tmDigitizedAspectY, otm->tmDigitizedAspectY);
|
||||||
|
ok(tm->tmFirstChar == otm->tmFirstChar, "tmFirstChar %d != %d\n", tm->tmFirstChar, otm->tmFirstChar);
|
||||||
|
ok(tm->tmLastChar == otm->tmLastChar, "tmLastChar %d != %d\n", tm->tmLastChar, otm->tmLastChar);
|
||||||
|
ok(tm->tmDefaultChar == otm->tmDefaultChar, "tmDefaultChar %d != %d\n", tm->tmDefaultChar, otm->tmDefaultChar);
|
||||||
|
ok(tm->tmBreakChar == otm->tmBreakChar, "tmBreakChar %d != %d\n", tm->tmBreakChar, otm->tmBreakChar);
|
||||||
|
ok(tm->tmItalic == otm->tmItalic, "tmItalic %d != %d\n", tm->tmItalic, otm->tmItalic);
|
||||||
|
ok(tm->tmUnderlined == otm->tmUnderlined, "tmUnderlined %d != %d\n", tm->tmUnderlined, otm->tmUnderlined);
|
||||||
|
ok(tm->tmStruckOut == otm->tmStruckOut, "tmStruckOut %d != %d\n", tm->tmStruckOut, otm->tmStruckOut);
|
||||||
|
ok(tm->tmPitchAndFamily == otm->tmPitchAndFamily, "tmPitchAndFamily %d != %d\n", tm->tmPitchAndFamily, otm->tmPitchAndFamily);
|
||||||
|
ok(tm->tmCharSet == otm->tmCharSet, "tmCharSet %d != %d\n", tm->tmCharSet, otm->tmCharSet);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
|
static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
|
||||||
LONG lfWidth, const char *test_str,
|
LONG lfWidth, const char *test_str,
|
||||||
INT test_str_len, const TEXTMETRICA *tm_orig,
|
INT test_str_len, const TEXTMETRICA *tm_orig,
|
||||||
|
@ -167,9 +191,11 @@ static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
|
||||||
{
|
{
|
||||||
HFONT old_hfont;
|
HFONT old_hfont;
|
||||||
LOGFONTA lf;
|
LOGFONTA lf;
|
||||||
|
OUTLINETEXTMETRIC otm;
|
||||||
TEXTMETRICA tm;
|
TEXTMETRICA tm;
|
||||||
SIZE size;
|
SIZE size;
|
||||||
INT width_of_A, cx, cy;
|
INT width_of_A, cx, cy;
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
if (!hfont)
|
if (!hfont)
|
||||||
return;
|
return;
|
||||||
|
@ -178,35 +204,75 @@ static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
|
||||||
|
|
||||||
old_hfont = SelectObject(hdc, hfont);
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
|
||||||
GetTextMetricsA(hdc, &tm);
|
if (GetOutlineTextMetricsA(hdc, 0, NULL))
|
||||||
|
{
|
||||||
|
otm.otmSize = sizeof(otm) / 2;
|
||||||
|
ret = GetOutlineTextMetricsA(hdc, otm.otmSize, &otm);
|
||||||
|
ok(ret == sizeof(otm)/2 /* XP */ ||
|
||||||
|
ret == 1 /* Win9x */, "expected sizeof(otm)/2, got %u\n", ret);
|
||||||
|
|
||||||
|
memset(&otm, 0x1, sizeof(otm));
|
||||||
|
otm.otmSize = sizeof(otm);
|
||||||
|
ret = GetOutlineTextMetricsA(hdc, otm.otmSize, &otm);
|
||||||
|
ok(ret == sizeof(otm) /* XP */ ||
|
||||||
|
ret == 1 /* Win9x */, "expected sizeof(otm), got %u\n", ret);
|
||||||
|
|
||||||
|
memset(&tm, 0x2, sizeof(tm));
|
||||||
|
ret = GetTextMetricsA(hdc, &tm);
|
||||||
|
ok(ret, "GetTextMetricsA failed\n");
|
||||||
|
/* the structure size is aligned */
|
||||||
|
if (memcmp(&tm, &otm.otmTextMetrics, FIELD_OFFSET(TEXTMETRICA, tmCharSet) + 1))
|
||||||
|
{
|
||||||
|
ok(0, "tm != otm\n");
|
||||||
|
compare_tm(&tm, &otm.otmTextMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
tm = otm.otmTextMetrics;
|
||||||
|
if (0) /* these metrics are scaled too, but with rounding errors */
|
||||||
|
{
|
||||||
|
ok(otm.otmAscent == tm.tmAscent, "ascent %d != %d\n", otm.otmAscent, tm.tmAscent);
|
||||||
|
ok(otm.otmDescent == -tm.tmDescent, "descent %d != %d\n", otm.otmDescent, -tm.tmDescent);
|
||||||
|
}
|
||||||
|
ok(otm.otmMacAscent == tm.tmAscent, "ascent %d != %d\n", otm.otmMacAscent, tm.tmAscent);
|
||||||
|
ok(otm.otmDescent < 0, "otm.otmDescent should be < 0\n");
|
||||||
|
ok(otm.otmMacDescent < 0, "otm.otmMacDescent should be < 0\n");
|
||||||
|
ok(tm.tmDescent > 0, "tm.tmDescent should be > 0\n");
|
||||||
|
ok(otm.otmMacDescent == -tm.tmDescent, "descent %d != %d\n", otm.otmMacDescent, -tm.tmDescent);
|
||||||
|
ok(otm.otmEMSquare == 2048, "expected 2048, got %d\n", otm.otmEMSquare);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = GetTextMetricsA(hdc, &tm);
|
||||||
|
ok(ret, "GetTextMetricsA failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
cx = tm.tmAveCharWidth / tm_orig->tmAveCharWidth;
|
cx = tm.tmAveCharWidth / tm_orig->tmAveCharWidth;
|
||||||
cy = tm.tmHeight / tm_orig->tmHeight;
|
cy = tm.tmHeight / tm_orig->tmHeight;
|
||||||
ok(cx == scale_x && cy == scale_y, "expected scale_x %d, scale_y %d, got cx %d, cy %d\n",
|
ok(cx == scale_x && cy == scale_y, "expected scale_x %d, scale_y %d, got cx %d, cy %d\n",
|
||||||
scale_x, scale_y, cx, cy);
|
scale_x, scale_y, cx, cy);
|
||||||
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "height %d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
||||||
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "ascent %d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
||||||
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "descent %d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
||||||
ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
ok(near_match(tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x), "ave width %d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
||||||
ok(tm.tmMaxCharWidth == tm_orig->tmMaxCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
ok(near_match(tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x), "max width %d != %d\n", tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
||||||
|
|
||||||
ok(lf.lfHeight == lfHeight, "lf %d != %d\n", lf.lfHeight, lfHeight);
|
ok(lf.lfHeight == lfHeight, "lfHeight %d != %d\n", lf.lfHeight, lfHeight);
|
||||||
if (lf.lfHeight)
|
if (lf.lfHeight)
|
||||||
{
|
{
|
||||||
if (lf.lfWidth)
|
if (lf.lfWidth)
|
||||||
ok(lf.lfWidth == tm.tmAveCharWidth, "lf %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
ok(lf.lfWidth == tm.tmAveCharWidth, "lfWidth %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ok(lf.lfWidth == lfWidth, "lf %d != %d\n", lf.lfWidth, lfWidth);
|
ok(lf.lfWidth == lfWidth, "lfWidth %d != %d\n", lf.lfWidth, lfWidth);
|
||||||
|
|
||||||
GetTextExtentPoint32A(hdc, test_str, test_str_len, &size);
|
GetTextExtentPoint32A(hdc, test_str, test_str_len, &size);
|
||||||
|
|
||||||
ok(size.cx == size_orig->cx * scale_x, "%d != %d\n", size.cx, size_orig->cx * scale_x);
|
ok(near_match(size.cx, size_orig->cx * scale_x), "cx %d != %d\n", size.cx, size_orig->cx * scale_x);
|
||||||
ok(size.cy == size_orig->cy * scale_y, "%d != %d\n", size.cy, size_orig->cy * scale_y);
|
ok(size.cy == size_orig->cy * scale_y, "cy %d != %d\n", size.cy, size_orig->cy * scale_y);
|
||||||
|
|
||||||
GetCharWidthA(hdc, 'A', 'A', &width_of_A);
|
GetCharWidthA(hdc, 'A', 'A', &width_of_A);
|
||||||
|
|
||||||
ok(width_of_A == width_of_A_orig * scale_x, "%d != %d\n", width_of_A, width_of_A_orig * scale_x);
|
ok(near_match(width_of_A, width_of_A_orig * scale_x), "width A %d != %d\n", width_of_A, width_of_A_orig * scale_x);
|
||||||
|
|
||||||
SelectObject(hdc, old_hfont);
|
SelectObject(hdc, old_hfont);
|
||||||
}
|
}
|
||||||
|
@ -287,6 +353,216 @@ static void test_bitmap_font(void)
|
||||||
ReleaseDC(0, hdc);
|
ReleaseDC(0, hdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test how GDI scales outline font metrics */
|
||||||
|
static void test_outline_font(void)
|
||||||
|
{
|
||||||
|
static const char test_str[11] = "Test String";
|
||||||
|
HDC hdc;
|
||||||
|
LOGFONTA lf;
|
||||||
|
HFONT hfont, old_hfont;
|
||||||
|
OUTLINETEXTMETRICA otm;
|
||||||
|
SIZE size_orig;
|
||||||
|
INT width_orig, height_orig, lfWidth;
|
||||||
|
XFORM xform;
|
||||||
|
GLYPHMETRICS gm;
|
||||||
|
MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
|
||||||
|
MAT2 mat2 = { {0x8000,0}, {0,0}, {0,0}, {0x8000,0} };
|
||||||
|
POINT pt;
|
||||||
|
INT ret;
|
||||||
|
|
||||||
|
if (!is_truetype_font_installed("Arial"))
|
||||||
|
{
|
||||||
|
skip("Arial is not installed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdc = CreateCompatibleDC(0);
|
||||||
|
|
||||||
|
memset(&lf, 0, sizeof(lf));
|
||||||
|
strcpy(lf.lfFaceName, "Arial");
|
||||||
|
lf.lfHeight = 72;
|
||||||
|
hfont = create_font("outline", &lf);
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
otm.otmSize = sizeof(otm);
|
||||||
|
ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
|
||||||
|
ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
|
||||||
|
ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, otm.otmTextMetrics.tmAveCharWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
DeleteObject(hfont);
|
||||||
|
|
||||||
|
/* font of otmEMSquare height helps to avoid a lot of rounding errors */
|
||||||
|
lf.lfHeight = otm.otmEMSquare;
|
||||||
|
lf.lfHeight = -lf.lfHeight;
|
||||||
|
hfont = create_font("outline", &lf);
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
otm.otmSize = sizeof(otm);
|
||||||
|
ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
|
||||||
|
ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
|
||||||
|
ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
DeleteObject(hfont);
|
||||||
|
|
||||||
|
height_orig = otm.otmTextMetrics.tmHeight;
|
||||||
|
lfWidth = otm.otmTextMetrics.tmAveCharWidth;
|
||||||
|
|
||||||
|
/* test integer scaling 3x2 */
|
||||||
|
lf.lfHeight = height_orig * 2;
|
||||||
|
lf.lfWidth = lfWidth * 3;
|
||||||
|
hfont = create_font("3x2", &lf);
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 2);
|
||||||
|
DeleteObject(hfont);
|
||||||
|
|
||||||
|
/* test integer scaling 3x3 */
|
||||||
|
lf.lfHeight = height_orig * 3;
|
||||||
|
lf.lfWidth = lfWidth * 3;
|
||||||
|
hfont = create_font("3x3", &lf);
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 3);
|
||||||
|
DeleteObject(hfont);
|
||||||
|
|
||||||
|
/* test integer scaling 1x1 */
|
||||||
|
lf.lfHeight = height_orig * 1;
|
||||||
|
lf.lfWidth = lfWidth * 1;
|
||||||
|
hfont = create_font("1x1", &lf);
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
DeleteObject(hfont);
|
||||||
|
|
||||||
|
/* test integer scaling 1x1 */
|
||||||
|
lf.lfHeight = height_orig;
|
||||||
|
lf.lfWidth = 0;
|
||||||
|
hfont = create_font("1x1", &lf);
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
/* with an identity matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
ok(gm.gmCellIncX == width_orig, "incX %d != %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
/* with a custom matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
ok(gm.gmCellIncX == width_orig/2, "incX %d != %d\n", gm.gmCellIncX, width_orig/2);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
|
||||||
|
if (!SetGraphicsMode(hdc, GM_ADVANCED))
|
||||||
|
{
|
||||||
|
DeleteObject(hfont);
|
||||||
|
DeleteDC(hdc);
|
||||||
|
skip("GM_ADVANCED is not supported on this platform\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xform.eM11 = 20.0f;
|
||||||
|
xform.eM12 = 0.0f;
|
||||||
|
xform.eM21 = 0.0f;
|
||||||
|
xform.eM22 = 20.0f;
|
||||||
|
xform.eDx = 0.0f;
|
||||||
|
xform.eDy = 0.0f;
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = SetWorldTransform(hdc, &xform);
|
||||||
|
ok(ret, "SetWorldTransform error %u\n", GetLastError());
|
||||||
|
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
/* with an identity matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == pt.x, "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||||
|
ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
/* with a custom matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == pt.x/2, "incX %d != %d\n", gm.gmCellIncX, pt.x/2);
|
||||||
|
ok(gm.gmCellIncX == 10 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = SetMapMode(hdc, MM_LOMETRIC);
|
||||||
|
ok(ret == MM_TEXT, "expected MM_TEXT, got %d, error %u\n", ret, GetLastError());
|
||||||
|
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
/* with an identity matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == pt.x, "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
/* with a custom matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == (pt.x + 1)/2, "incX %d != %d\n", gm.gmCellIncX, (pt.x + 1)/2);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = SetMapMode(hdc, MM_TEXT);
|
||||||
|
ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d, error %u\n", ret, GetLastError());
|
||||||
|
|
||||||
|
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||||
|
|
||||||
|
old_hfont = SelectObject(hdc, hfont);
|
||||||
|
/* with an identity matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == pt.x, "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||||
|
ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
/* with a custom matrix */
|
||||||
|
memset(&gm, 0, sizeof(gm));
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||||
|
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||||
|
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||||
|
pt.x = width_orig; pt.y = 0;
|
||||||
|
LPtoDP(hdc, &pt, 1);
|
||||||
|
ok(gm.gmCellIncX == pt.x/2, "incX %d != %d\n", gm.gmCellIncX, pt.x/2);
|
||||||
|
ok(gm.gmCellIncX == 10 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
|
||||||
|
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||||
|
SelectObject(hdc, old_hfont);
|
||||||
|
|
||||||
|
DeleteObject(hfont);
|
||||||
|
DeleteDC(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
|
static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LOGFONT *lf = (LOGFONT *)lParam;
|
LOGFONT *lf = (LOGFONT *)lParam;
|
||||||
|
@ -2049,6 +2325,7 @@ START_TEST(font)
|
||||||
|
|
||||||
test_logfont();
|
test_logfont();
|
||||||
test_bitmap_font();
|
test_bitmap_font();
|
||||||
|
test_outline_font();
|
||||||
test_bitmap_font_metrics();
|
test_bitmap_font_metrics();
|
||||||
test_GdiGetCharDimensions();
|
test_GdiGetCharDimensions();
|
||||||
test_GetCharABCWidths();
|
test_GetCharABCWidths();
|
||||||
|
|
Loading…
Reference in New Issue