[GDIPLUS_WINETEST]

* Sync to Wine 1.5.4.

svn path=/trunk/; revision=56614
This commit is contained in:
Amine Khaldi 2012-05-19 10:03:49 +00:00
parent a87a379620
commit 7838d7f3cd
5 changed files with 1385 additions and 71 deletions

View file

@ -11,6 +11,7 @@ list(APPEND SOURCE
graphicspath.c
image.c
matrix.c
metafile.c
pathiterator.c
pen.c
region.c

View file

@ -773,22 +773,59 @@ static void test_gradientsurroundcolorcount(void)
{
GpStatus status;
GpPathGradient *grad;
ARGB *color;
INT count = 3;
ARGB color[3];
INT count;
status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad);
expect(Ok, status);
color = GdipAlloc(sizeof(ARGB[3]));
count = 0;
status = GdipGetPathGradientSurroundColorCount(grad, &count);
expect(Ok, status);
expect(2, count);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 3;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
expect(0xffffffff, color[0]);
expect(0xffffffff, color[1]);
expect(0xdeadbeef, color[2]);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 2;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
expect(0xffffffff, color[0]);
expect(0xffffffff, color[1]);
expect(0xdeadbeef, color[2]);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 1;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(InvalidParameter, status);
expect(1, count);
expect(0xdeadbeef, color[0]);
expect(0xdeadbeef, color[1]);
expect(0xdeadbeef, color[2]);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 0;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(InvalidParameter, status);
expect(0, count);
expect(0xdeadbeef, color[0]);
expect(0xdeadbeef, color[1]);
expect(0xdeadbeef, color[2]);
count = 3;
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(InvalidParameter, status);
GdipFree(color);
count = 2;
color = GdipAlloc(sizeof(ARGB[2]));
color[0] = 0x00ff0000;
color[1] = 0x0000ff00;
@ -806,7 +843,7 @@ static void test_gradientsurroundcolorcount(void)
}
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
todo_wine expect(Ok, status);
expect(Ok, status);
expect(2, count);
status = GdipGetPathGradientSurroundColorCount(NULL, &count);
@ -817,11 +854,418 @@ static void test_gradientsurroundcolorcount(void)
count = 0;
status = GdipGetPathGradientSurroundColorCount(grad, &count);
todo_wine expect(Ok, status);
todo_wine expect(2, count);
expect(Ok, status);
expect(2, count);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 2;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(2, count);
expect(0x00ff0000, color[0]);
expect(0x0000ff00, color[1]);
expect(0xdeadbeef, color[2]);
count = 1;
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
count = 0;
status = GdipGetPathGradientSurroundColorCount(grad, &count);
expect(Ok, status);
expect(2, count);
/* If all colors are the same, count is set to 1. */
color[0] = color[1] = 0;
count = 2;
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(2, count);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 2;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
expect(0x00000000, color[0]);
expect(0x00000000, color[1]);
expect(0xdeadbeef, color[2]);
color[0] = color[1] = 0xff00ff00;
count = 2;
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(2, count);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 2;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
expect(0xff00ff00, color[0]);
expect(0xff00ff00, color[1]);
expect(0xdeadbeef, color[2]);
count = 0;
status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(InvalidParameter, status);
expect(0, count);
GdipFree(color);
GdipDeleteBrush((GpBrush*)grad);
status = GdipCreatePathGradient(getbounds_ptf, 3, WrapModeClamp, &grad);
expect(Ok, status);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 3;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(Ok, status);
expect(1, count);
expect(0xffffffff, color[0]);
expect(0xffffffff, color[1]);
expect(0xffffffff, color[2]);
color[0] = color[1] = color[2] = 0xdeadbeef;
count = 2;
status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
expect(InvalidParameter, status);
expect(2, count);
expect(0xdeadbeef, color[0]);
expect(0xdeadbeef, color[1]);
expect(0xdeadbeef, color[2]);
count = 0;
status = GdipGetPathGradientSurroundColorCount(grad, &count);
expect(Ok, status);
expect(3, count);
GdipDeleteBrush((GpBrush*)grad);
}
static void test_pathgradientpath(void)
{
GpStatus status;
GpPath *path=NULL;
GpPathGradient *grad=NULL;
status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad);
expect(Ok, status);
status = GdipGetPathGradientPath(grad, NULL);
expect(NotImplemented, status);
status = GdipCreatePath(FillModeWinding, &path);
expect(Ok, status);
status = GdipGetPathGradientPath(NULL, path);
expect(NotImplemented, status);
status = GdipGetPathGradientPath(grad, path);
expect(NotImplemented, status);
status = GdipDeletePath(path);
expect(Ok, status);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
}
static void test_pathgradientcenterpoint(void)
{
static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
GpStatus status;
GpPathGradient *grad;
GpPointF point;
status = GdipCreatePathGradient(path_points+1, 2, WrapModeClamp, &grad);
expect(Ok, status);
status = GdipGetPathGradientCenterPoint(NULL, &point);
expect(InvalidParameter, status);
status = GdipGetPathGradientCenterPoint(grad, NULL);
expect(InvalidParameter, status);
status = GdipGetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
expectf(1.5, point.X);
expectf(2.0, point.Y);
status = GdipSetPathGradientCenterPoint(NULL, &point);
expect(InvalidParameter, status);
status = GdipSetPathGradientCenterPoint(grad, NULL);
expect(InvalidParameter, status);
point.X = 10.0;
point.Y = 15.0;
status = GdipSetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
point.X = point.Y = -1;
status = GdipGetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
expectf(10.0, point.X);
expectf(15.0, point.Y);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
status = GdipCreatePathGradient(path_points, 3, WrapModeClamp, &grad);
expect(Ok, status);
status = GdipGetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
todo_wine expectf(1.0, point.X);
todo_wine expectf(4.0/3.0, point.Y);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
}
static void test_pathgradientpresetblend(void)
{
static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
GpStatus status;
GpPathGradient *grad;
INT count;
int i;
const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
const REAL two_positions[2] = {0.0f, 1.0f};
const ARGB colors[5] = {0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffffffff};
REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
ARGB res_colors[6] = {0xdeadbeef, 0, 0, 0, 0};
status = GdipCreatePathGradient(path_points+1, 2, WrapModeClamp, &grad);
expect(Ok, status);
status = GdipGetPathGradientPresetBlendCount(NULL, &count);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlendCount(grad, NULL);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlendCount(grad, &count);
expect(Ok, status);
expect(0, count);
status = GdipGetPathGradientPresetBlend(NULL, res_colors, res_positions, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, NULL, res_positions, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, NULL, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 0);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, -1);
expect(OutOfMemory, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 2);
expect(GenericError, status);
status = GdipSetPathGradientPresetBlend(NULL, colors, positions, 5);
expect(InvalidParameter, status);
status = GdipSetPathGradientPresetBlend(grad, NULL, positions, 5);
expect(InvalidParameter, status);
if (0)
{
/* crashes on windows xp */
status = GdipSetPathGradientPresetBlend(grad, colors, NULL, 5);
expect(InvalidParameter, status);
}
status = GdipSetPathGradientPresetBlend(grad, colors, positions, 0);
expect(InvalidParameter, status);
status = GdipSetPathGradientPresetBlend(grad, colors, positions, -1);
expect(InvalidParameter, status);
status = GdipSetPathGradientPresetBlend(grad, colors, positions, 1);
expect(InvalidParameter, status);
/* leave off the 0.0 position */
status = GdipSetPathGradientPresetBlend(grad, &colors[1], &positions[1], 4);
expect(InvalidParameter, status);
/* leave off the 1.0 position */
status = GdipSetPathGradientPresetBlend(grad, colors, positions, 4);
expect(InvalidParameter, status);
status = GdipSetPathGradientPresetBlend(grad, colors, positions, 5);
expect(Ok, status);
status = GdipGetPathGradientPresetBlendCount(grad, &count);
expect(Ok, status);
expect(5, count);
if (0)
{
/* Native GdipGetPathGradientPresetBlend seems to copy starting from
* the end of each array and do no bounds checking. This is so braindead
* I'm not going to copy it. */
res_colors[0] = 0xdeadbeef;
res_positions[0] = 0.3;
status = GdipGetPathGradientPresetBlend(grad, &res_colors[1], &res_positions[1], 4);
expect(Ok, status);
expect(0xdeadbeef, res_colors[0]);
expectf(0.3, res_positions[0]);
for (i=1; i<5; i++)
{
expect(colors[i], res_colors[i]);
expectf(positions[i], res_positions[i]);
}
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 6);
expect(Ok, status);
for (i=0; i<5; i++)
{
expect(colors[i], res_colors[i+1]);
expectf(positions[i], res_positions[i+1]);
}
}
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 5);
expect(Ok, status);
for (i=0; i<5; i++)
{
expect(colors[i], res_colors[i]);
expectf(positions[i], res_positions[i]);
}
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 0);
expect(InvalidParameter, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, -1);
expect(OutOfMemory, status);
status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 1);
expect(InvalidParameter, status);
status = GdipSetPathGradientPresetBlend(grad, colors, two_positions, 2);
expect(Ok, status);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
}
static void test_pathgradientblend(void)
{
static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
GpPathGradient *brush;
GpStatus status;
INT count, i;
const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f};
const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
status = GdipCreatePathGradient(path_points, 3, WrapModeClamp, &brush);
expect(Ok, status);
status = GdipGetPathGradientBlendCount(NULL, &count);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlendCount(brush, NULL);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlendCount(brush, &count);
expect(Ok, status);
expect(1, count);
status = GdipGetPathGradientBlend(NULL, res_factors, res_positions, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlend(brush, NULL, res_positions, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlend(brush, res_factors, NULL, 1);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 0);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, -1);
expect(InvalidParameter, status);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 1);
expect(Ok, status);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 2);
expect(Ok, status);
status = GdipSetPathGradientBlend(NULL, factors, positions, 5);
expect(InvalidParameter, status);
status = GdipSetPathGradientBlend(brush, NULL, positions, 5);
expect(InvalidParameter, status);
status = GdipSetPathGradientBlend(brush, factors, NULL, 5);
expect(InvalidParameter, status);
status = GdipSetPathGradientBlend(brush, factors, positions, 0);
expect(InvalidParameter, status);
status = GdipSetPathGradientBlend(brush, factors, positions, -1);
expect(InvalidParameter, status);
/* leave off the 0.0 position */
status = GdipSetPathGradientBlend(brush, &factors[1], &positions[1], 4);
expect(InvalidParameter, status);
/* leave off the 1.0 position */
status = GdipSetPathGradientBlend(brush, factors, positions, 4);
expect(InvalidParameter, status);
status = GdipSetPathGradientBlend(brush, factors, positions, 5);
expect(Ok, status);
status = GdipGetPathGradientBlendCount(brush, &count);
expect(Ok, status);
expect(5, count);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 4);
expect(InsufficientBuffer, status);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 5);
expect(Ok, status);
for (i=0; i<5; i++)
{
expectf(factors[i], res_factors[i]);
expectf(positions[i], res_positions[i]);
}
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 6);
expect(Ok, status);
status = GdipSetPathGradientBlend(brush, factors, positions, 1);
expect(Ok, status);
status = GdipGetPathGradientBlendCount(brush, &count);
expect(Ok, status);
expect(1, count);
status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 1);
expect(Ok, status);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok, status);
}
START_TEST(brush)
@ -848,6 +1292,10 @@ START_TEST(brush)
test_lineblend();
test_linelinearblend();
test_gradientsurroundcolorcount();
test_pathgradientpath();
test_pathgradientcenterpoint();
test_pathgradientpresetblend();
test_pathgradientblend();
GdiplusShutdown(gdiplusToken);
}

View file

@ -2,6 +2,7 @@
* Unit test suite for fonts
*
* Copyright (C) 2007 Google (Evan Stade)
* Copyright (C) 2012 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -24,10 +25,9 @@
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %f, got %f\n", expected, got)
static const WCHAR arial[] = {'A','r','i','a','l','\0'};
static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'};
static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
@ -50,12 +50,7 @@ static void test_createfont(void)
expect (FontFamilyNotFound, stat);
stat = GdipDeleteFont(font);
expect (InvalidParameter, stat);
stat = GdipCreateFontFamilyFromName(arial, NULL, &fontfamily);
if(stat == FontFamilyNotFound)
{
skip("Arial not installed\n");
return;
}
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
expect (Ok, stat);
stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
expect (Ok, stat);
@ -67,7 +62,7 @@ static void test_createfont(void)
expect(Ok, stat);
stat = GdipGetFamilyName(fontfamily2, familyname, 0);
expect(Ok, stat);
ok (lstrcmpiW(arial, familyname) == 0, "Expected arial, got %s\n",
ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
wine_dbgstr_w(familyname));
stat = GdipDeleteFontFamily(fontfamily2);
expect(Ok, stat);
@ -96,12 +91,17 @@ static void test_logfont(void)
{
LOGFONTA lfa, lfa2;
GpFont *font;
GpFontFamily *family;
GpStatus stat;
GpGraphics *graphics;
HDC hdc = GetDC(0);
INT style;
REAL rval;
UINT16 em_height, line_spacing;
Unit unit;
GdipCreateFromHDC(hdc, &graphics);
memset(&lfa, 0, sizeof(LOGFONTA));
memset(&lfa2, 0xff, sizeof(LOGFONTA));
@ -110,14 +110,9 @@ static void test_logfont(void)
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
expect(NotTrueTypeFont, stat);
lstrcpyA(lfa.lfFaceName, "Arial");
lstrcpyA(lfa.lfFaceName, "Tahoma");
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
if (stat == FileNotFound)
{
skip("Arial not installed.\n");
return;
}
expect(Ok, stat);
stat = GdipGetLogFontA(font, graphics, &lfa2);
expect(Ok, stat);
@ -146,7 +141,7 @@ static void test_logfont(void)
lfa.lfItalic = lfa.lfUnderline = lfa.lfStrikeOut = TRUE;
memset(&lfa2, 0xff, sizeof(LOGFONTA));
lstrcpyA(lfa.lfFaceName, "Arial");
lstrcpyA(lfa.lfFaceName, "Tahoma");
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
expect(Ok, stat);
@ -173,6 +168,60 @@ static void test_logfont(void)
ok (style == (FontStyleItalic | FontStyleUnderline | FontStyleStrikeout),
"Expected , got %d\n", style);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitWorld, unit);
stat = GdipGetFontHeight(font, graphics, &rval);
expect(Ok, stat);
expectf(25.347656, rval);
stat = GdipGetFontSize(font, &rval);
expect(Ok, stat);
expectf(21.0, rval);
stat = GdipGetFamily(font, &family);
expect(Ok, stat);
stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
expect(Ok, stat);
expect(2048, em_height);
stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
expect(Ok, stat);
expect(2472, line_spacing);
GdipDeleteFontFamily(family);
GdipDeleteFont(font);
memset(&lfa, 0, sizeof(lfa));
lfa.lfHeight = -25;
lstrcpyA(lfa.lfFaceName, "Tahoma");
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
expect(Ok, stat);
memset(&lfa2, 0xff, sizeof(lfa2));
stat = GdipGetLogFontA(font, graphics, &lfa2);
expect(Ok, stat);
expect(lfa.lfHeight, lfa2.lfHeight);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitWorld, unit);
stat = GdipGetFontHeight(font, graphics, &rval);
expect(Ok, stat);
expectf(30.175781, rval);
stat = GdipGetFontSize(font, &rval);
expect(Ok, stat);
expectf(25.0, rval);
stat = GdipGetFamily(font, &family);
expect(Ok, stat);
stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
expect(Ok, stat);
expect(2048, em_height);
stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
expect(Ok, stat);
expect(2472, line_spacing);
GdipDeleteFontFamily(family);
GdipDeleteFont(font);
GdipDeleteGraphics(graphics);
@ -186,7 +235,7 @@ static void test_fontfamily (void)
GpStatus stat;
/* FontFamily cannot be NULL */
stat = GdipCreateFontFamilyFromName (arial , NULL, NULL);
stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
expect (InvalidParameter, stat);
/* FontFamily must be able to actually find the family.
@ -200,17 +249,12 @@ static void test_fontfamily (void)
expect (FontFamilyNotFound, stat);
if(stat == Ok) GdipDeleteFontFamily(family);
stat = GdipCreateFontFamilyFromName (arial, NULL, &family);
if(stat == FontFamilyNotFound)
{
skip("Arial not installed\n");
return;
}
stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
expect (Ok, stat);
stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
expect (Ok, stat);
expect (0, lstrcmpiW(itsName, arial));
expect (0, lstrcmpiW(itsName, Tahoma));
if (0)
{
@ -226,7 +270,7 @@ static void test_fontfamily (void)
GdipDeleteFontFamily(family);
stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
expect(Ok, stat);
expect(0, lstrcmpiW(itsName, arial));
expect(0, lstrcmpiW(itsName, Tahoma));
GdipDeleteFontFamily(clonedFontFamily);
}
@ -237,28 +281,25 @@ static void test_fontfamily_properties (void)
GpStatus stat;
UINT16 result = 0;
stat = GdipCreateFontFamilyFromName(arial, NULL, &FontFamily);
if(stat == FontFamilyNotFound)
skip("Arial not installed\n");
else
{
stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok (result == 2355, "Expected 2355, got %d\n", result);
result = 0;
stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 2048, "Expected 2048, got %d\n", result);
result = 0;
stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 1854, "Expected 1854, got %d\n", result);
result = 0;
stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 434, "Expected 434, got %d\n", result);
GdipDeleteFontFamily(FontFamily);
}
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
expect(Ok, stat);
stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok (result == 2472, "Expected 2472, got %d\n", result);
result = 0;
stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 2048, "Expected 2048, got %d\n", result);
result = 0;
stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 2049, "Expected 2049, got %d\n", result);
result = 0;
stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
expect(Ok, stat);
ok(result == 423, "Expected 423, got %d\n", result);
GdipDeleteFontFamily(FontFamily);
stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
if(stat == FontFamilyNotFound)
@ -362,13 +403,9 @@ static void test_heightgivendpi(void)
GpFont* font = NULL;
GpFontFamily* fontfamily = NULL;
REAL height;
Unit unit;
stat = GdipCreateFontFamilyFromName(arial, NULL, &fontfamily);
if(stat == FontFamilyNotFound)
{
skip("Arial not installed\n");
return;
}
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
expect(Ok, stat);
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
@ -382,15 +419,20 @@ static void test_heightgivendpi(void)
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)34.497070, height);
expectf(36.210938, height);
GdipDeleteFont(font);
height = 12345;
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitWorld, unit);
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)34.497070, height);
expectf(36.210938, height);
GdipDeleteFont(font);
height = 12345;
@ -398,36 +440,288 @@ static void test_heightgivendpi(void)
expect(Ok, stat);
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)45.996094, height);
expectf(48.281250, height);
GdipDeleteFont(font);
height = 12345;
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitInch, unit);
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)3311.718750, height);
expectf(3476.250000, height);
GdipDeleteFont(font);
height = 12345;
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitDocument, unit);
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)11.039062, height);
expectf(11.587500, height);
GdipDeleteFont(font);
height = 12345;
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitMillimeter, unit);
stat = GdipGetFontHeightGivenDPI(font, 96, &height);
expect(Ok, stat);
expectf((REAL)130.382614, height);
expectf(136.860245, height);
GdipDeleteFont(font);
GdipDeleteFontFamily(fontfamily);
}
static int CALLBACK font_enum_proc(const LOGFONTW *lfe, const TEXTMETRICW *ntme,
DWORD type, LPARAM lparam)
{
NEWTEXTMETRICW *ntm = (NEWTEXTMETRICW *)lparam;
if (type != TRUETYPE_FONTTYPE) return 1;
*ntm = *(NEWTEXTMETRICW *)ntme;
return 0;
}
struct font_metrics
{
UINT16 em_height, line_spacing, ascent, descent;
REAL font_height, font_size;
INT lfHeight;
};
static void gdi_get_font_metrics(LOGFONTW *lf, struct font_metrics *fm)
{
HDC hdc;
HFONT hfont;
NEWTEXTMETRICW ntm;
OUTLINETEXTMETRICW otm;
int ret;
hdc = CreateCompatibleDC(0);
/* it's the only way to get extended NEWTEXTMETRIC fields */
ret = EnumFontFamiliesExW(hdc, lf, font_enum_proc, (LPARAM)&ntm, 0);
ok(!ret, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf->lfFaceName));
hfont = CreateFontIndirectW(lf);
SelectObject(hdc, hfont);
otm.otmSize = sizeof(otm);
ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
ok(ret, "GetOutlineTextMetrics failed\n");
DeleteDC(hdc);
DeleteObject(hfont);
fm->lfHeight = -otm.otmTextMetrics.tmAscent;
fm->line_spacing = ntm.ntmCellHeight;
fm->font_size = (REAL)otm.otmTextMetrics.tmAscent;
fm->font_height = (REAL)fm->line_spacing * fm->font_size / (REAL)ntm.ntmSizeEM;
fm->em_height = ntm.ntmSizeEM;
fm->ascent = ntm.ntmSizeEM;
fm->descent = ntm.ntmCellHeight - ntm.ntmSizeEM;
}
static void gdip_get_font_metrics(GpFont *font, struct font_metrics *fm)
{
INT style;
GpFontFamily *family;
GpStatus stat;
stat = GdipGetFontStyle(font, &style);
expect(Ok, stat);
stat = GdipGetFontHeight(font, NULL, &fm->font_height);
expect(Ok, stat);
stat = GdipGetFontSize(font, &fm->font_size);
expect(Ok, stat);
fm->lfHeight = (INT)(fm->font_size * -1.0);
stat = GdipGetFamily(font, &family);
expect(Ok, stat);
stat = GdipGetEmHeight(family, style, &fm->em_height);
expect(Ok, stat);
stat = GdipGetLineSpacing(family, style, &fm->line_spacing);
expect(Ok, stat);
stat = GdipGetCellAscent(family, style, &fm->ascent);
expect(Ok, stat);
stat = GdipGetCellDescent(family, style, &fm->descent);
expect(Ok, stat);
GdipDeleteFontFamily(family);
}
static void cmp_font_metrics(struct font_metrics *fm1, struct font_metrics *fm2, int line)
{
ok_(__FILE__, line)(fm1->lfHeight == fm2->lfHeight, "lfHeight %d != %d\n", fm1->lfHeight, fm2->lfHeight);
ok_(__FILE__, line)(fm1->em_height == fm2->em_height, "em_height %u != %u\n", fm1->em_height, fm2->em_height);
ok_(__FILE__, line)(fm1->line_spacing == fm2->line_spacing, "line_spacing %u != %u\n", fm1->line_spacing, fm2->line_spacing);
ok_(__FILE__, line)(abs(fm1->ascent - fm2->ascent) <= 1, "ascent %u != %u\n", fm1->ascent, fm2->ascent);
ok_(__FILE__, line)(abs(fm1->descent - fm2->descent) <= 1, "descent %u != %u\n", fm1->descent, fm2->descent);
ok(fm1->font_height > 0.0, "fm1->font_height should be positive, got %f\n", fm1->font_height);
ok(fm2->font_height > 0.0, "fm2->font_height should be positive, got %f\n", fm2->font_height);
ok_(__FILE__, line)(fm1->font_height == fm2->font_height, "font_height %f != %f\n", fm1->font_height, fm2->font_height);
ok(fm1->font_size > 0.0, "fm1->font_size should be positive, got %f\n", fm1->font_size);
ok(fm2->font_size > 0.0, "fm2->font_size should be positive, got %f\n", fm2->font_size);
ok_(__FILE__, line)(fm1->font_size == fm2->font_size, "font_size %f != %f\n", fm1->font_size, fm2->font_size);
}
static void test_font_metrics(void)
{
LOGFONTW lf;
GpFont *font;
GpFontFamily *family;
GpGraphics *graphics;
GpStatus stat;
Unit unit;
struct font_metrics fm_gdi, fm_gdip;
HDC hdc;
hdc = CreateCompatibleDC(0);
stat = GdipCreateFromHDC(hdc, &graphics);
expect(Ok, stat);
memset(&lf, 0, sizeof(lf));
/* Tahoma,-13 */
lstrcpyW(lf.lfFaceName, Tahoma);
lf.lfHeight = -13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitWorld, unit);
gdip_get_font_metrics(font, &fm_gdip);
trace("gdiplus:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
fm_gdip.font_height, fm_gdip.font_size);
gdi_get_font_metrics(&lf, &fm_gdi);
trace("gdi:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
fm_gdi.font_height, fm_gdi.font_size);
cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
gdi_get_font_metrics(&lf, &fm_gdi);
trace("gdi:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
fm_gdi.font_height, fm_gdi.font_size);
ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
GdipDeleteFont(font);
/* Tahoma,13 */
lstrcpyW(lf.lfFaceName, Tahoma);
lf.lfHeight = 13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
stat = GdipGetFontUnit(font, &unit);
expect(Ok, stat);
expect(UnitWorld, unit);
gdip_get_font_metrics(font, &fm_gdip);
trace("gdiplus:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
fm_gdip.font_height, fm_gdip.font_size);
gdi_get_font_metrics(&lf, &fm_gdi);
trace("gdi:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
fm_gdi.font_height, fm_gdi.font_size);
cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
gdi_get_font_metrics(&lf, &fm_gdi);
trace("gdi:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
fm_gdi.font_height, fm_gdi.font_size);
ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
GdipDeleteFont(font);
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
expect(Ok, stat);
/* Tahoma,13 */
stat = GdipCreateFont(family, 13.0, FontStyleRegular, UnitPixel, &font);
expect(Ok, stat);
gdip_get_font_metrics(font, &fm_gdip);
trace("gdiplus:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
fm_gdip.font_height, fm_gdip.font_size);
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
gdi_get_font_metrics(&lf, &fm_gdi);
trace("gdi:\n");
trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
fm_gdi.font_height, fm_gdi.font_size);
ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
stat = GdipGetLogFontW(font, NULL, &lf);
expect(InvalidParameter, stat);
GdipDeleteFont(font);
stat = GdipCreateFont(family, -13.0, FontStyleRegular, UnitPixel, &font);
expect(InvalidParameter, stat);
GdipDeleteFontFamily(family);
GdipDeleteGraphics(graphics);
DeleteDC(hdc);
}
START_TEST(font)
{
struct GdiplusStartupInput gdiplusStartupInput;
@ -440,6 +734,7 @@ START_TEST(font)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
test_font_metrics();
test_createfont();
test_logfont();
test_fontfamily();

View file

@ -0,0 +1,568 @@
/*
* Unit test suite for metafiles
*
* Copyright (C) 2011 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "windows.h"
#include <stdio.h>
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
typedef struct emfplus_record
{
ULONG todo;
ULONG record_type;
ULONG playback_todo;
} emfplus_record;
typedef struct emfplus_check_state
{
const char *desc;
int count;
const struct emfplus_record *expected;
GpMetafile *metafile;
} emfplus_check_state;
static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual)
{
if (expected->todo)
todo_wine ok(expected->record_type == actual->record_type,
"%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
expected->record_type, actual->record_type);
else
ok(expected->record_type == actual->record_type,
"%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
expected->record_type, actual->record_type);
}
typedef struct EmfPlusRecordHeader
{
WORD Type;
WORD Flags;
DWORD Size;
DWORD DataSize;
} EmfPlusRecordHeader;
static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
int nObj, LPARAM lpData)
{
emfplus_check_state *state = (emfplus_check_state*)lpData;
emfplus_record actual;
if (lpEMFR->iType == EMR_GDICOMMENT)
{
const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
{
int offset = 4;
while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
{
const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
ok(record->Size == record->DataSize + sizeof(EmfPlusRecordHeader),
"%s: EMF+ record datasize %u and size %u mismatch\n", state->desc, record->DataSize, record->Size);
ok(offset + record->DataSize <= comment->cbData,
"%s: EMF+ record truncated\n", state->desc);
if (offset + record->DataSize > comment->cbData)
return 0;
if (state->expected[state->count].record_type)
{
actual.todo = 0;
actual.record_type = record->Type;
check_record(state->count, state->desc, &state->expected[state->count], &actual);
state->count++;
}
else
{
ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type);
}
offset += record->Size;
}
ok(offset == comment->cbData, "%s: truncated EMF+ record data?\n", state->desc);
return 1;
}
}
if (state->expected[state->count].record_type)
{
actual.todo = 0;
actual.record_type = lpEMFR->iType;
check_record(state->count, state->desc, &state->expected[state->count], &actual);
state->count++;
}
else
{
ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, lpEMFR->iType);
}
return 1;
}
static void check_emfplus(HENHMETAFILE hemf, const emfplus_record *expected, const char *desc)
{
emfplus_check_state state;
state.desc = desc;
state.count = 0;
state.expected = expected;
EnumEnhMetaFile(0, hemf, enum_emf_proc, &state, NULL);
if (expected[state.count].todo)
todo_wine ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
else
ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
}
static BOOL CALLBACK enum_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
unsigned int dataSize, const unsigned char *pStr, void *userdata)
{
emfplus_check_state *state = (emfplus_check_state*)userdata;
emfplus_record actual;
actual.todo = 0;
actual.record_type = record_type;
if (dataSize == 0)
ok(pStr == NULL, "non-NULL pStr\n");
if (state->expected[state->count].record_type)
{
check_record(state->count, state->desc, &state->expected[state->count], &actual);
state->count++;
}
else
{
ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, record_type);
}
return TRUE;
}
static void check_metafile(GpMetafile *metafile, const emfplus_record *expected, const char *desc,
const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
{
GpStatus stat;
HDC hdc;
GpGraphics *graphics;
emfplus_check_state state;
state.desc = desc;
state.count = 0;
state.expected = expected;
state.metafile = metafile;
hdc = CreateCompatibleDC(0);
stat = GdipCreateFromHDC(hdc, &graphics);
expect(Ok, stat);
stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
3, src_rect, src_unit, enum_metafile_proc, &state, NULL);
expect(Ok, stat);
if (expected[state.count].todo)
todo_wine ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
else
ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
GdipDeleteGraphics(graphics);
DeleteDC(hdc);
}
static BOOL CALLBACK play_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
unsigned int dataSize, const unsigned char *pStr, void *userdata)
{
emfplus_check_state *state = (emfplus_check_state*)userdata;
GpStatus stat;
stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr);
if (state->expected[state->count].record_type)
{
if (state->expected[state->count].playback_todo)
todo_wine ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
else
ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
state->count++;
}
else
{
if (state->expected[state->count].playback_todo)
todo_wine ok(0, "%s: too many records\n", state->desc);
else
ok(0, "%s: too many records\n", state->desc);
return FALSE;
}
return TRUE;
}
static void play_metafile(GpMetafile *metafile, GpGraphics *graphics, const emfplus_record *expected,
const char *desc, const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
{
GpStatus stat;
emfplus_check_state state;
state.desc = desc;
state.count = 0;
state.expected = expected;
state.metafile = metafile;
stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
3, src_rect, src_unit, play_metafile_proc, &state, NULL);
expect(Ok, stat);
}
static const emfplus_record empty_records[] = {
{0, EMR_HEADER},
{0, EmfPlusRecordTypeHeader},
{0, EmfPlusRecordTypeEndOfFile},
{0, EMR_EOF},
{0}
};
static void test_empty(void)
{
GpStatus stat;
GpMetafile *metafile;
GpGraphics *graphics;
HDC hdc;
HENHMETAFILE hemf, dummy;
BOOL ret;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
hdc = CreateCompatibleDC(0);
stat = GdipRecordMetafile(NULL, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, MetafileTypeInvalid, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, MetafileTypeWmf, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, MetafileTypeWmfPlaceable, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, MetafileTypeEmfPlusDual+1, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, NULL);
expect(InvalidParameter, stat);
stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(Ok, stat);
DeleteDC(hdc);
if (stat != Ok)
return;
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(InvalidParameter, stat);
stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
expect(Ok, stat);
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(InvalidParameter, stat);
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
check_metafile(metafile, empty_records, "empty metafile", dst_points, &frame, UnitPixel);
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(Ok, stat);
stat = GdipGetHemfFromMetafile(metafile, &dummy);
expect(InvalidParameter, stat);
stat = GdipDisposeImage((GpImage*)metafile);
expect(Ok, stat);
check_emfplus(hemf, empty_records, "empty emf");
ret = DeleteEnhMetaFile(hemf);
ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
}
static const emfplus_record getdc_records[] = {
{0, EMR_HEADER},
{0, EmfPlusRecordTypeHeader},
{0, EmfPlusRecordTypeGetDC},
{0, EMR_CREATEBRUSHINDIRECT},
{0, EMR_SELECTOBJECT},
{0, EMR_RECTANGLE},
{0, EMR_SELECTOBJECT},
{0, EMR_DELETEOBJECT},
{0, EmfPlusRecordTypeEndOfFile},
{0, EMR_EOF},
{0}
};
static void test_getdc(void)
{
GpStatus stat;
GpMetafile *metafile;
GpGraphics *graphics;
HDC hdc, metafile_dc;
HENHMETAFILE hemf;
BOOL ret;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
HBRUSH hbrush, holdbrush;
GpBitmap *bitmap;
ARGB color;
hdc = CreateCompatibleDC(0);
stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(Ok, stat);
DeleteDC(hdc);
if (stat != Ok)
return;
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(InvalidParameter, stat);
stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
expect(Ok, stat);
stat = GdipGetDC(graphics, &metafile_dc);
expect(Ok, stat);
if (stat != Ok)
{
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)metafile);
return;
}
hbrush = CreateSolidBrush(0xff0000);
holdbrush = SelectObject(metafile_dc, hbrush);
Rectangle(metafile_dc, 25, 25, 75, 75);
SelectObject(metafile_dc, holdbrush);
DeleteObject(hbrush);
stat = GdipReleaseDC(graphics, metafile_dc);
expect(Ok, stat);
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
check_metafile(metafile, getdc_records, "getdc metafile", dst_points, &frame, UnitPixel);
stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
expect(Ok, stat);
stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
expect(Ok, stat);
play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points, &frame, UnitPixel);
stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
expect(Ok, stat);
expect(0, color);
stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
expect(Ok, stat);
expect(0xff0000ff, color);
stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
expect(Ok, stat);
play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points_half, &frame, UnitPixel);
stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
expect(Ok, stat);
expect(0xff0000ff, color);
stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
expect(Ok, stat);
expect(0, color);
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
stat = GdipDisposeImage((GpImage*)bitmap);
expect(Ok, stat);
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(Ok, stat);
stat = GdipDisposeImage((GpImage*)metafile);
expect(Ok, stat);
check_emfplus(hemf, getdc_records, "getdc emf");
ret = DeleteEnhMetaFile(hemf);
ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
}
static const emfplus_record emfonly_records[] = {
{0, EMR_HEADER},
{0, EMR_CREATEBRUSHINDIRECT},
{0, EMR_SELECTOBJECT},
{0, EMR_RECTANGLE},
{0, EMR_SELECTOBJECT},
{0, EMR_DELETEOBJECT},
{0, EMR_EOF},
{0}
};
static void test_emfonly(void)
{
GpStatus stat;
GpMetafile *metafile;
GpGraphics *graphics;
HDC hdc, metafile_dc;
HENHMETAFILE hemf;
BOOL ret;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
HBRUSH hbrush, holdbrush;
GpBitmap *bitmap;
ARGB color;
hdc = CreateCompatibleDC(0);
stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
expect(Ok, stat);
DeleteDC(hdc);
if (stat != Ok)
return;
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(InvalidParameter, stat);
stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
expect(Ok, stat);
stat = GdipGetDC(graphics, &metafile_dc);
expect(Ok, stat);
if (stat != Ok)
{
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)metafile);
return;
}
hbrush = CreateSolidBrush(0xff0000);
holdbrush = SelectObject(metafile_dc, hbrush);
Rectangle(metafile_dc, 25, 25, 75, 75);
SelectObject(metafile_dc, holdbrush);
DeleteObject(hbrush);
stat = GdipReleaseDC(graphics, metafile_dc);
expect(Ok, stat);
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
check_metafile(metafile, emfonly_records, "emfonly metafile", dst_points, &frame, UnitPixel);
stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
expect(Ok, stat);
stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
expect(Ok, stat);
play_metafile(metafile, graphics, emfonly_records, "emfonly playback", dst_points, &frame, UnitPixel);
stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
expect(Ok, stat);
expect(0, color);
stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
expect(Ok, stat);
expect(0xff0000ff, color);
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
stat = GdipDisposeImage((GpImage*)bitmap);
expect(Ok, stat);
stat = GdipGetHemfFromMetafile(metafile, &hemf);
expect(Ok, stat);
stat = GdipDisposeImage((GpImage*)metafile);
expect(Ok, stat);
check_emfplus(hemf, emfonly_records, "emfonly emf");
ret = DeleteEnhMetaFile(hemf);
ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
}
START_TEST(metafile)
{
struct GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
gdiplusStartupInput.GdiplusVersion = 1;
gdiplusStartupInput.DebugEventCallback = NULL;
gdiplusStartupInput.SuppressBackgroundThread = 0;
gdiplusStartupInput.SuppressExternalCodecs = 0;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
test_empty();
test_getdc();
test_emfonly();
GdiplusShutdown(gdiplusToken);
}

View file

@ -13,6 +13,7 @@ extern void func_graphics(void);
extern void func_graphicspath(void);
extern void func_image(void);
extern void func_matrix(void);
extern void func_metafile(void);
extern void func_pathiterator(void);
extern void func_pen(void);
extern void func_region(void);
@ -21,12 +22,13 @@ extern void func_stringformat(void);
const struct test winetest_testlist[] =
{
{ "brush", func_brush },
{ "customlinecap", func_customlinecap },
{ "customlinecap", func_customlinecap },
{ "font", func_font },
{ "graphics", func_graphics },
{ "graphicspath", func_graphicspath },
{ "image", func_image },
{ "matrix", func_matrix },
{ "metafile", func_metafile },
{ "pathiterator", func_pathiterator },
{ "pen", func_pen },
{ "region", func_region },