[GDIPLUS_WINETEST] Sync to Wine-10.0

This commit is contained in:
Timo Kreuzer
2026-05-16 10:43:08 +00:00
parent 632b09f55e
commit e6a61fb3c7
17 changed files with 6090 additions and 1323 deletions
@@ -27,7 +27,6 @@ add_executable(gdiplus_winetest
set_module_type(gdiplus_winetest win32cui)
add_importlibs(gdiplus_winetest gdiplus user32 gdi32 ole32 msvcrt kernel32)
add_pch(gdiplus_winetest precomp.h "${PCH_SKIP_SOURCE}")
add_rostests_file(TARGET gdiplus_winetest)
if(MSVC)
+327 -4
View File
@@ -18,13 +18,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <math.h>
#include "objbase.h"
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
#define expect(expected,got) expect_(__LINE__, expected, got)
static inline void expect_(unsigned line, DWORD expected, DWORD got)
{
ok_(__FILE__, line)(expected == got, "Expected %.8ld, got %.8ld\n", expected, got);
}
#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
static HWND hwnd;
@@ -274,6 +279,37 @@ static void test_transform(void)
GpPointF start, end;
GpRectF rectf;
REAL elements[6];
UINT buf[15];
HBITMAP hbmp,old;
HDC dcmem;
BITMAP bm;
GpImage *image;
IStream *stream;
HGLOBAL hglob;
VOID *data;
HRESULT hr;
LONG size;
/* 3*5 bmp 32bit*/
static const unsigned char bmpimage[] = {
0x42,0x4d,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,
0x00,0x00,0x28,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x05,0x00,
0x00,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,
0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0x11,0xff,0x00,0xff,0x11,0xff,0x00,0xff,0x11,0xff,0x00,
0xff,0x33,0xff,0x00,0xff,0x33,0xff,0x00,0xff,0x33,0xff,0x00,
0xff,0x55,0xff,0x00,0xff,0x55,0xff,0x00,0xff,0x55,0xff,0x00,
0xff,0xaa,0xff,0x00,0xff,0xaa,0xff,0x00,0xff,0xaa,0xff,0x00,
0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,
0x00,0x00,0x00,0x00};
static const UINT buf_rotate_180[15] = {
0xffffffff, 0xffffffff, 0xffffffff,
0xffff11ff, 0xffff11ff, 0xffff11ff,
0xffff33ff, 0xffff33ff, 0xffff33ff,
0xffff55ff, 0xffff55ff, 0xffff55ff,
0xffffaaff, 0xffffaaff, 0xffffaaff};
/* GpTexture */
status = GdipCreateMatrix2(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, &m);
@@ -556,6 +592,38 @@ static void test_transform(void)
expect(Ok, status);
status = GdipDeleteBrush((GpBrush*)line);
expect(Ok,status);
GdipDeleteGraphics(graphics);
dcmem = CreateCompatibleDC(hdc);
hbmp = CreateBitmap(3, 5, 1, 32, NULL);
old = SelectObject(dcmem, hbmp);
status = GdipCreateFromHDC(dcmem, &graphics);
expect(Ok, status);
hglob = GlobalAlloc(0, sizeof(bmpimage));
data = GlobalLock (hglob);
memcpy(data, bmpimage, sizeof(bmpimage));
GlobalUnlock(hglob);
hr = CreateStreamOnHGlobal(hglob, TRUE, &stream);
expect(S_OK, hr);
status = GdipLoadImageFromStream(stream, &image);
expect(Ok, status);
status = GdipCreateTexture(image, WrapModeTile, &texture);
expect(Ok, status);
status = GdipRotateTextureTransform(texture, 180.0f, MatrixOrderPrepend);
expect(Ok, status);
status = GdipFillRectangle(graphics, (GpBrush*)texture, .0f, .0f, (REAL)3, (REAL)5);
expect(Ok, status);
GdipDeleteBrush((GpBrush*)texture);
GdipDisposeImage(image);
GdipDeleteGraphics(graphics);
IStream_Release(stream);
hbmp = SelectObject(dcmem, old);
GetObjectW(hbmp, sizeof(bm), &bm);
size = GetBitmapBits(hbmp, sizeof(buf), buf);
expect(sizeof(buf), size);
DeleteObject(hbmp);
DeleteDC(dcmem);
ok(!memcmp(buf, buf_rotate_180, sizeof(buf)), "Failed to rotate image.\n");
if(0){
/* enable to visually compare with Windows */
@@ -567,7 +635,6 @@ static void test_transform(void)
}
GdipDeleteMatrix(m);
GdipDeleteGraphics(graphics);
ReleaseDC(0, hdc);
}
@@ -1299,6 +1366,7 @@ static void test_pathgradientcenterpoint(void)
{
static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
GpStatus status;
GpPath* path;
GpPathGradient *grad;
GpPointF point;
@@ -1341,8 +1409,28 @@ static void test_pathgradientcenterpoint(void)
status = GdipGetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
todo_wine expectf(1.0, point.X);
todo_wine expectf(4.0/3.0, point.Y);
expectf(1.0, point.X);
expectf(4.0/3.0, point.Y);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
status = GdipCreatePath(FillModeWinding, &path);
expect(Ok, status);
status = GdipAddPathEllipse(path, 0, 0, 100, 50);
expect(Ok, status);
status = GdipCreatePathGradientFromPath(path, &grad);
expect(Ok, status);
status = GdipGetPathGradientCenterPoint(grad, &point);
expect(Ok, status);
expectf(700.0/13.0, point.X);
expectf(25.0, point.Y);
status = GdipDeletePath(path);
expect(Ok, status);
status = GdipDeleteBrush((GpBrush*)grad);
expect(Ok, status);
@@ -1613,6 +1701,239 @@ static void test_getHatchStyle(void)
GdipDeleteBrush((GpBrush *)brush);
}
static ARGB COLORREF2ARGB(COLORREF color)
{
return 0xff000000 |
(color & 0xff) << 16 |
(color & 0xff00) |
(color & 0xff0000) >> 16;
}
extern BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff);
static void test_hatchBrushStyles(void)
{
static const struct
{
short pattern[8];
GpHatchStyle hs;
}
styles[] =
{
{ {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff}, HatchStyleHorizontal },
{ {0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000}, HatchStyleVertical },
{ {0x4006, 0x0019, 0x0064, 0x0190, 0x0640, 0x1900, 0x6400, 0x9001}, HatchStyleForwardDiagonal },
{ {0x9001, 0x6400, 0x1900, 0x0640, 0x0190, 0x0064, 0x0019, 0x4006}, HatchStyleBackwardDiagonal },
{ {0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xffff}, HatchStyleCross },
{ {0x9006, 0x6419, 0x1964, 0x0690, 0x0690, 0x1964, 0x6419, 0x9006}, HatchStyleDiagonalCross },
{ {0x0000, 0x0000, 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0xc000}, HatchStyle05Percent },
{ {0x0000, 0x00c0, 0x0000, 0xc000, 0x0000, 0x00c0, 0x0000, 0xc000}, HatchStyle10Percent },
{ {0x0000, 0x0c0c, 0x0000, 0xc0c0, 0x0000, 0x0c0c, 0x0000, 0xc0c0}, HatchStyle20Percent },
{ {0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0}, HatchStyle25Percent },
{ {0x0303, 0xcccc, 0x3030, 0xcccc, 0x0303, 0xcccc, 0x3030, 0xcccc}, HatchStyle30Percent },
{ {0x0333, 0xcccc, 0x3333, 0xcccc, 0x3303, 0xcccc, 0x3333, 0xcccc}, HatchStyle40Percent },
{ {0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc}, HatchStyle50Percent },
{ {0x3333, 0xcfcf, 0x3333, 0xfcfc, 0x3333, 0xcfcf, 0x3333, 0xfcfc}, HatchStyle60Percent },
{ {0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f}, HatchStyle70Percent },
{ {0xffff, 0xf3f3, 0xffff, 0x3f3f, 0xffff, 0xf3f3, 0xffff, 0x3f3f}, HatchStyle75Percent },
{ {0xffff, 0xfffc, 0xffff, 0xfcff, 0xffff, 0xfffc, 0xffff, 0xfcff}, HatchStyle80Percent },
{ {0x3fff, 0xffff, 0xffff, 0xffff, 0xff3f, 0xffff, 0xffff, 0xffff}, HatchStyle90Percent },
{ {0x0303, 0x0c0c, 0x3030, 0xc0c0, 0x0303, 0x0c0c, 0x3030, 0xc0c0}, HatchStyleLightDownwardDiagonal },
{ {0xc0c0, 0x3030, 0x0c0c, 0x0303, 0xc0c0, 0x3030, 0x0c0c, 0x0303}, HatchStyleLightUpwardDiagonal },
{ {0xc3c3, 0x0f0f, 0x3c3c, 0xf0f0, 0xc3c3, 0x0f0f, 0x3c3c, 0xf0f0}, HatchStyleDarkDownwardDiagonal },
{ {0xc3c3, 0xf0f0, 0x3c3c, 0x0f0f, 0xc3c3, 0xf0f0, 0x3c3c, 0x0f0f}, HatchStyleDarkUpwardDiagonal },
{ {0xc00f, 0x003f, 0x00fc, 0x03f0, 0x0fc0, 0x3f00, 0xfc00, 0xf003}, HatchStyleWideDownwardDiagonal },
{ {0xf003, 0xfc00, 0x3f00, 0x0fc0, 0x03f0, 0x00fc, 0x003f, 0xc00f}, HatchStyleWideUpwardDiagonal },
{ {0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0}, HatchStyleLightVertical },
{ {0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff}, HatchStyleLightHorizontal },
{ {0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333}, HatchStyleNarrowVertical },
{ {0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff}, HatchStyleNarrowHorizontal },
{ {0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0}, HatchStyleDarkVertical },
{ {0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff}, HatchStyleDarkHorizontal },
{ {0x0000, 0x0000, 0x0303, 0x0c0c, 0x3030, 0xc0c0, 0x0000, 0x0000}, HatchStyleDashedDownwardDiagonal },
{ {0x0000, 0x0000, 0xc0c0, 0x3030, 0x0c0c, 0x0303, 0x0000, 0x0000}, HatchStyleDashedUpwardDiagonal },
{ {0x0000, 0x0000, 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0xff00}, HatchStyleDashedHorizontal },
{ {0x00c0, 0x00c0, 0x00c0, 0x00c0, 0xc000, 0xc000, 0xc000, 0xc000}, HatchStyleDashedVertical },
{ {0x0030, 0x0c00, 0x0003, 0x0300, 0x000c, 0x3000, 0x00c0, 0xc000}, HatchStyleSmallConfetti },
{ {0xc0f3, 0x00f0, 0xf000, 0xf3c0, 0x03cf, 0x000f, 0x0f00, 0xcf03}, HatchStyleLargeConfetti },
{ {0x03c0, 0x0c30, 0x300c, 0xc003, 0x03c0, 0x0c30, 0x300c, 0xc003}, HatchStyleZigZag },
{ {0xf000, 0x0c33, 0x03c0, 0x0000, 0xf000, 0x0c33, 0x03c0, 0x0000}, HatchStyleWave },
{ {0xc003, 0x300c, 0x0c30, 0x03c0, 0x00c0, 0x0030, 0x000c, 0x0003}, HatchStyleDiagonalBrick },
{ {0x00c0, 0x00c0, 0x00c0, 0xffff, 0xc000, 0xc000, 0xc000, 0xffff}, HatchStyleHorizontalBrick },
{ {0x3303, 0x0c0c, 0x0330, 0xc0c0, 0x3033, 0x0c0c, 0x3330, 0xc0c0}, HatchStyleWeave },
{ {0xff00, 0xff00, 0xff00, 0xff00, 0x3333, 0xcccc, 0x3333, 0xcccc}, HatchStylePlaid },
{ {0xc000, 0x0003, 0xc000, 0x0000, 0x0300, 0x00c0, 0x0300, 0x0000}, HatchStyleDivot },
{ {0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xcccc}, HatchStyleDottedGrid },
{ {0x0000, 0x0c0c, 0x0000, 0x00c0, 0x0000, 0x0c0c, 0x0000, 0xc000}, HatchStyleDottedDiamond },
{ {0x0003, 0x0003, 0x000c, 0x00f0, 0x0f00, 0x30c0, 0xc030, 0x000f}, HatchStyleShingle },
{ {0xc3c3, 0xffff, 0x3c3c, 0xffff, 0xc3c3, 0xffff, 0x3c3c, 0xffff}, HatchStyleTrellis },
{ {0xffc0, 0xffc0, 0xc3c0, 0x3f3f, 0xc0ff, 0xc0ff, 0xc0c3, 0x3f3f}, HatchStyleSphere },
{ {0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff}, HatchStyleSmallGrid },
{ {0xc3c3, 0x3c3c, 0x3c3c, 0xc3c3, 0xc3c3, 0x3c3c, 0x3c3c, 0xc3c3}, HatchStyleSmallCheckerBoard },
{ {0x00ff, 0x00ff, 0x00ff, 0x00ff, 0xff00, 0xff00, 0xff00, 0xff00}, HatchStyleLargeCheckerBoard },
{ {0x0003, 0xc00c, 0x3030, 0x0cc0, 0x0300, 0x0cc0, 0x3030, 0xc00c}, HatchStyleOutlinedDiamond },
{ {0x0000, 0x0300, 0x0fc0, 0x3ff0, 0xfffc, 0x3ff0, 0x0fc0, 0x0300}, HatchStyleSolidDiamond },
};
static const ARGB exp_colors[] = { 0xffffffff, 0xffbfbfbf, 0xff151515, 0xff000000 };
static const ARGB fore_color = 0xff000000;
static const ARGB back_color = 0xffffffff;
static const int width = 16, height = 16;
GpStatus status;
HDC hdc;
GpGraphics *graphics_hdc;
GpGraphics *graphics_image;
GpBitmap *bitmap;
GpHatch *brush = NULL;
BOOL match_hdc;
BOOL match_image;
int x, y;
int i;
hdc = GetDC(hwnd);
status = GdipCreateFromHDC(hdc, &graphics_hdc);
expect(Ok, status);
ok(graphics_hdc != NULL, "Expected the graphics context to be initialized.\n");
status = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppRGB, NULL, &bitmap);
expect(Ok, status);
status = GdipGetImageGraphicsContext((GpImage *)bitmap, &graphics_image);
expect(Ok, status);
ok(graphics_image != NULL, "Expected the graphics context to be initialized.\n");
for (i = 0; i < ARRAY_SIZE(styles); i++)
{
status = GdipCreateHatchBrush(styles[i].hs, fore_color, back_color, &brush);
expect(Ok, status);
ok(brush != NULL, "Expected the brush to be initialized.\n");
status = GdipFillRectangleI(graphics_hdc, (GpBrush *)brush, 0, 0, width, height);
expect(Ok, status);
status = GdipFillRectangleI(graphics_image, (GpBrush *)brush, 0, 0, width, height);
expect(Ok, status);
status = GdipDeleteBrush((GpBrush *)brush);
expect(Ok, status);
brush = NULL;
match_hdc = TRUE;
match_image = TRUE;
for(y = 0; y < width && (match_hdc || match_image); y++)
{
for(x = 0; x < height && (match_hdc || match_image); x++)
{
ARGB color;
int cindex = (styles[i].pattern[7-(y%8)] >> (2*(7-(x%8)))) & 3;
color = COLORREF2ARGB(GetPixel(hdc, x, y));
if (!color_match(color, exp_colors[cindex], 1))
match_hdc = FALSE;
GdipBitmapGetPixel(bitmap, x, y, &color);
if (!color_match(color, exp_colors[cindex], 1))
match_image = FALSE;
}
}
ok(match_hdc, "Unexpected pattern for hatch style %#x with hdc.\n", styles[i].hs);
ok(match_image, "Unexpected pattern for hatch style %#x with image.\n", styles[i].hs);
}
status = GdipDeleteGraphics(graphics_image);
expect(Ok, status);
status = GdipDisposeImage((GpImage*)bitmap);
expect(Ok, status);
status = GdipDeleteGraphics(graphics_hdc);
expect(Ok, status);
ReleaseDC(hwnd, hdc);
}
static void test_renderingOrigin(void)
{
static const int width = 8, height = 8;
GpStatus status;
HDC hdc;
GpBitmap *bitmap;
GpGraphics *graphics_hdc;
GpGraphics *graphics_image;
GpHatch *brush;
BOOL match_hdc;
BOOL match_image;
static const INT tests[][2] = {{3, 6}, {-7, -4}};
static const ARGB fore_color = 0xff000000;
static const ARGB back_color = 0xffffffff;
INT x, y;
int i;
hdc = GetDC(hwnd);
GdipCreateFromHDC(hdc, &graphics_hdc);
GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppRGB, NULL, &bitmap);
GdipGetImageGraphicsContext((GpImage *)bitmap, &graphics_image);
GdipCreateHatchBrush(HatchStyleCross, fore_color, back_color, &brush);
x = y = 0xdeadbeef;
status = GdipGetRenderingOrigin(graphics_image, &x, &y);
expect(Ok, status);
ok(x == 0 && y == 0, "Expected (%d, %d) got (%d, %d)\n", 0, 0, x, y);
x = y = 0xdeadbeef;
status = GdipGetRenderingOrigin(graphics_image, &x, &y);
expect(Ok, status);
ok(x == 0 && y == 0, "Expected (%d, %d) got (%d, %d)\n", 0, 0, x, y);
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
const INT exp_x = tests[i][0] & 7;
const INT exp_y = tests[i][1] & 7;
status = GdipSetRenderingOrigin(graphics_image, tests[i][0], tests[i][1]);
expect(Ok, status);
status = GdipSetRenderingOrigin(graphics_hdc, tests[i][0], tests[i][1]);
expect(Ok, status);
status = GdipGetRenderingOrigin(graphics_image, &x, &y);
expect(Ok, status);
ok(x == tests[i][0] && y == tests[i][1], "Expected (%d, %d) got (%d, %d)\n",
tests[i][0], tests[i][1], x, y);
status = GdipGetRenderingOrigin(graphics_image, &x, &y);
expect(Ok, status);
ok(x == tests[i][0] && y == tests[i][1], "Expected (%d, %d) got (%d, %d)\n",
tests[i][0], tests[i][1], x, y);
GdipFillRectangleI(graphics_image, (GpBrush *)brush, 0, 0, width, height);
GdipFillRectangleI(graphics_hdc, (GpBrush *)brush, 0, 0, width, height);
match_hdc = TRUE;
match_image = TRUE;
for (y = 0; y < height && (match_hdc || match_image); y++)
{
for (x = 0; x < width && (match_hdc || match_image); x++)
{
ARGB color;
const ARGB exp_color = (x == exp_x || y == exp_y) ? fore_color : back_color;
color = COLORREF2ARGB(GetPixel(hdc, x, y));
if (color != exp_color)
match_hdc = FALSE;
GdipBitmapGetPixel(bitmap, x, y, &color);
if (color != exp_color)
match_image = FALSE;
}
}
ok(match_hdc, "Hatch brush rendered incorrectly on hdc with rendering origin (%d, %d).\n",
tests[i][0], tests[i][1]);
ok(match_image, "Hatch brush rendered incorrectly on image with rendering origin (%d, %d).\n",
tests[i][0], tests[i][1]);
}
GdipDeleteBrush((GpBrush *)brush);
GdipDeleteGraphics(graphics_image);
GdipDisposeImage((GpImage*)bitmap);
GdipDeleteGraphics(graphics_hdc);
ReleaseDC(hwnd, hdc);
}
START_TEST(brush)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -1665,6 +1986,8 @@ START_TEST(brush)
test_pathgradientpresetblend();
test_pathgradientblend();
test_getHatchStyle();
test_hatchBrushStyles();
test_renderingOrigin();
GdiplusShutdown(gdiplusToken);
DestroyWindow(hwnd);
@@ -26,6 +26,13 @@
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
#define expectf(expected, got) ok(got == expected, "Expected %.2f, got %.2f\n", expected, got)
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
{
unsigned int diff = x > y ? x - y : y - x;
return diff <= max_diff;
}
static BOOL compare_float(float f, float g, unsigned int ulps)
{
int x = *(int *)&f;
@@ -36,26 +43,28 @@ static BOOL compare_float(float f, float g, unsigned int ulps)
if (y < 0)
y = INT_MIN - y;
if (abs(x - y) > ulps)
return FALSE;
return TRUE;
return compare_uint(x, y, ulps);
}
static void test_constructor_destructor(void)
{
GpCustomLineCap *custom;
GpPath *path, *path2;
GpPath *path, *path2, *pathFarAway;
GpStatus stat;
stat = GdipCreatePath(FillModeAlternate, &path);
expect(Ok, stat);
stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0);
stat = GdipAddPathRectangle(path, -5.0, -4.0, 10.0, 8.0);
expect(Ok, stat);
stat = GdipCreatePath(FillModeAlternate, &path2);
expect(Ok, stat);
stat = GdipAddPathRectangle(path2, 5.0, 5.0, 10.0, 10.0);
stat = GdipAddPathRectangle(path2, -5.0, -5.0, 10.0, 10.0);
expect(Ok, stat);
stat = GdipCreatePath(FillModeAlternate, &pathFarAway);
expect(Ok, stat);
stat = GdipAddPathRectangle(pathFarAway, 5.0, 5.0, 10.0, 10.0);
expect(Ok, stat);
/* NULL args */
@@ -70,18 +79,39 @@ static void test_constructor_destructor(void)
stat = GdipDeleteCustomLineCap(NULL);
expect(InvalidParameter, stat);
/* valid args */
stat = GdipCreateCustomLineCap(NULL, path2, LineCapFlat, 0.0, &custom);
/* If both parameters are provided, then fillPath will be ignored. */
custom = NULL;
stat = GdipCreateCustomLineCap(path, path2, LineCapFlat, 0.0, &custom);
expect(Ok, stat);
ok(custom != NULL, "Custom line cap was not created\n");
stat = GdipDeleteCustomLineCap(custom);
expect(Ok, stat);
/* it's strange but native returns NotImplemented on stroke == NULL */
/* valid args */
custom = NULL;
stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 10.0, &custom);
stat = GdipCreateCustomLineCap(NULL, path2, LineCapFlat, 0.0, &custom);
expect(Ok, stat);
ok(custom != NULL, "Custom line cap was not created\n");
stat = GdipDeleteCustomLineCap(custom);
expect(Ok, stat);
custom = NULL;
stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 0.0, &custom);
expect(Ok, stat);
ok(custom != NULL, "Custom line cap was not created\n");
stat = GdipDeleteCustomLineCap(custom);
expect(Ok, stat);
/* Custom line cap position (0, 0) is a place corresponding to the end of line.
* If Custom Line Cap is too big and too far from position (0, 0),
* then NotImplemented will be returned, due to floating point precision limitation. */
custom = NULL;
stat = GdipCreateCustomLineCap(pathFarAway, NULL, LineCapFlat, 10.0, &custom);
todo_wine expect(NotImplemented, stat);
todo_wine ok(custom == NULL, "Expected a failure on creation\n");
if(stat == Ok) GdipDeleteCustomLineCap(custom);
GdipDeletePath(pathFarAway);
GdipDeletePath(path2);
GdipDeletePath(path);
}
@@ -165,6 +195,14 @@ static void test_inset(void)
expect(Ok, stat);
expectf(0.0, inset);
stat = GdipSetCustomLineCapBaseInset(custom, 2.0);
expect(Ok, stat);
inset = (REAL)0xdeadbeef;
stat = GdipGetCustomLineCapBaseInset(custom, &inset);
expect(Ok, stat);
ok(inset == 2.0, "Unexpected inset value %f\n", inset);
GdipDeleteCustomLineCap(custom);
GdipDeletePath(path);
}
@@ -283,14 +321,15 @@ static void test_create_adjustable_cap(void)
ok(base == LineCapTriangle, "Unexpected base cap %d\n", base);
stat = GdipSetCustomLineCapBaseCap((GpCustomLineCap*)cap, LineCapSquare);
todo_wine
ok(stat == Ok, "Unexpected return code, %d\n", stat);
stat = GdipGetCustomLineCapBaseCap((GpCustomLineCap*)cap, &base);
ok(stat == Ok, "Unexpected return code, %d\n", stat);
todo_wine
ok(base == LineCapSquare, "Unexpected base cap %d\n", base);
stat = GdipSetCustomLineCapBaseCap((GpCustomLineCap*)cap, LineCapSquareAnchor);
ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
/* Base inset */
stat = GdipGetAdjustableArrowCapWidth(cap, &width);
ok(stat == Ok, "Unexpected return code, %d\n", stat);
@@ -371,6 +410,33 @@ static void test_captype(void)
GdipDeleteCustomLineCap((GpCustomLineCap*)arrowcap);
}
static void test_strokecap(void)
{
GpCustomLineCap *cap;
GpStatus stat;
GpPath *path;
/* default cap */
stat = GdipCreatePath(FillModeAlternate, &path);
ok(stat == Ok, "Failed to create path, %d\n", stat);
stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0);
ok(stat == Ok, "AddPathRectangle failed, %d\n", stat);
stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, &cap);
ok(stat == Ok, "Failed to create cap, %d\n", stat);
stat = GdipSetCustomLineCapStrokeCaps(cap, LineCapSquare, LineCapFlat);
ok(stat == Ok, "Unexpected return code, %d\n", stat);
stat = GdipSetCustomLineCapStrokeCaps(cap, LineCapSquareAnchor, LineCapFlat);
ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
stat = GdipSetCustomLineCapStrokeCaps(cap, LineCapFlat, LineCapSquareAnchor);
ok(stat == InvalidParameter, "Unexpected return code, %d\n", stat);
GdipDeleteCustomLineCap(cap);
GdipDeletePath(path);
}
START_TEST(customlinecap)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -396,6 +462,7 @@ START_TEST(customlinecap)
test_scale();
test_create_adjustable_cap();
test_captype();
test_strokecap();
GdiplusShutdown(gdiplusToken);
}
+410 -95
View File
@@ -25,16 +25,16 @@
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
#define expect_(expected, got, precision) ok(abs((expected) - (got)) <= (precision), "Expected %d, got %d\n", (expected), (got))
#define expect(expected,got) expect_inline(__LINE__, expected, got)
static inline void expect_inline(unsigned line, DWORD expected, DWORD got)
{
ok_(__FILE__, line)(expected == got, "Expected %ld, got %ld\n", expected, got);
}
#define expect_(expected, got, precision) ok(abs((expected) - (got)) <= (precision), "Expected %d, got %ld\n", (expected), (got))
#define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
#define expectf(expected, got) expectf_((expected), (got), 0.001)
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 TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
static void set_rect_empty(RectF *rc)
{
rc->X = 0.0;
@@ -43,24 +43,32 @@ static void set_rect_empty(RectF *rc)
rc->Height = 0.0;
}
#define load_resource(a, b, c) _load_resource(__LINE__, a, b, c)
static void _load_resource(int line, const WCHAR *filename, BYTE **data, DWORD *size)
{
HRSRC resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA);
ok_(__FILE__, line)(!!resource, "FindResourceW failed, error %lu\n", GetLastError());
*data = LockResource(LoadResource(GetModuleHandleW(NULL), resource));
ok_(__FILE__, line)(!!*data, "LockResource failed, error %lu\n", GetLastError());
*size = SizeofResource(GetModuleHandleW(NULL), resource);
ok_(__FILE__, line)(*size > 0, "SizeofResource failed, error %lu\n", GetLastError());
}
static void create_testfontfile(const WCHAR *filename, int resource, WCHAR pathW[MAX_PATH])
{
DWORD written;
DWORD written, length;
HANDLE file;
HRSRC res;
void *ptr;
GetTempPathW(MAX_PATH, pathW);
lstrcatW(pathW, filename);
file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), GetLastError());
ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n", wine_dbgstr_w(pathW), GetLastError());
res = FindResourceA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(resource), (LPCSTR)RT_RCDATA);
ok(res != 0, "couldn't find resource\n");
ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res), &written, NULL);
ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n");
load_resource(MAKEINTRESOURCEW(resource), (BYTE **)&ptr, &length);
WriteFile(file, ptr, length, &written, NULL);
ok(written == length, "couldn't write resource\n");
CloseHandle(file);
}
@@ -68,27 +76,38 @@ static void create_testfontfile(const WCHAR *filename, int resource, WCHAR pathW
static void _delete_testfontfile(const WCHAR *filename, int line)
{
BOOL ret = DeleteFileW(filename);
ok_(__FILE__,line)(ret, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename), GetLastError());
ok_(__FILE__,line)(ret, "failed to delete file %s, error %ld\n", wine_dbgstr_w(filename), GetLastError());
}
static void test_long_name(void)
{
WCHAR path[MAX_PATH];
static const WCHAR path_longname[] = {'w','i','n','e','_','l','o','n','g','n','a','m','e','.','t','t','f',0};
GpStatus stat;
GpFontCollection *fonts;
HANDLE file;
INT num_families;
GpFontFamily *family;
GpFontFamily *family, *cloned_family;
WCHAR family_name[LF_FACESIZE];
GpFont *font;
stat = GdipNewPrivateFontCollection(&fonts);
ok(stat == Ok, "GdipNewPrivateFontCollection failed: %d\n", stat);
create_testfontfile(path_longname, 1, path);
create_testfontfile(L"wine_longname.ttf", 1, path);
file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFileW failed: %ld\n", GetLastError());
stat = GdipPrivateAddFontFile(fonts, path);
ok(stat == Ok, "GdipPrivateAddFontFile failed: %d\n", stat);
ok(stat == Ok, "GdipPrivateAddFontFile failed with open file handle: %d\n", stat);
CloseHandle(file);
if (stat != Ok) {
/* try again without opened file handle */
stat = GdipPrivateAddFontFile(fonts, path);
ok(stat == Ok, "GdipPrivateAddFontFile failed: %d\n", stat);
}
stat = GdipGetFontCollectionFamilyCount(fonts, &num_families);
ok(stat == Ok, "GdipGetFontCollectionFamilyCount failed: %d\n", stat);
@@ -104,6 +123,10 @@ static void test_long_name(void)
stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font);
ok(stat == Ok, "GdipCreateFont failed: %d\n", stat);
stat = GdipCloneFontFamily(family, &cloned_family);
ok(stat == Ok, "GdipCloneFontFamily failed: %d\n", stat);
ok(family == cloned_family, "GdipCloneFontFamily returned new object\n");
/* Cleanup */
stat = GdipDeleteFont(font);
@@ -112,6 +135,13 @@ static void test_long_name(void)
stat = GdipDeletePrivateFontCollection(&fonts);
ok(stat == Ok, "GdipDeletePrivateFontCollection failed: %d\n", stat);
/* Cloned family survives after collection is deleted */
stat = GdipGetFamilyName(cloned_family, family_name, LANG_NEUTRAL);
ok(stat == Ok, "GdipGetFamilyName failed: %d\n", stat);
stat = GdipDeleteFontFamily(cloned_family);
ok(stat == Ok, "GdipDeleteFontFamily failed: %d\n", stat);
DELETE_FONTFILE(path);
}
@@ -125,11 +155,11 @@ static void test_createfont(void)
REAL size;
WCHAR familyname[LF_FACESIZE];
stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily);
stat = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &fontfamily);
expect (FontFamilyNotFound, stat);
stat = GdipDeleteFont(font);
expect (InvalidParameter, stat);
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &fontfamily);
expect (Ok, stat);
stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
expect (Ok, stat);
@@ -141,7 +171,8 @@ static void test_createfont(void)
expect(Ok, stat);
stat = GdipGetFamilyName(fontfamily2, familyname, 0);
expect(Ok, stat);
ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
ok (fontfamily == fontfamily2, "Unexpected family instance.\n");
ok (lstrcmpiW(L"Tahoma", familyname) == 0, "Expected Tahoma, got %s\n",
wine_dbgstr_w(familyname));
stat = GdipDeleteFontFamily(fontfamily2);
expect(Ok, stat);
@@ -168,6 +199,76 @@ static void test_createfont(void)
GdipDeleteFontFamily(fontfamily);
}
static void test_createfont_charset(void)
{
GpFontFamily* fontfamily = NULL;
GpGraphics *graphics;
GpFont* font = NULL;
GpStatus stat;
LOGFONTW lf;
HDC hdc;
UINT i;
static const struct {
LPCWSTR family_name;
BYTE char_set;
} td[] =
{
{L"Tahoma", ANSI_CHARSET},
{L"Symbol", SYMBOL_CHARSET},
{L"Marlett", SYMBOL_CHARSET},
{L"Wingdings", SYMBOL_CHARSET},
};
hdc = CreateCompatibleDC(0);
stat = GdipCreateFromHDC(hdc, &graphics);
expect (Ok, stat);
for (i = 0; i < ARRAY_SIZE(td); i++)
{
winetest_push_context("%u", i);
stat = GdipCreateFontFamilyFromName(td[i].family_name, NULL, &fontfamily);
expect (Ok, stat);
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font);
expect (Ok, stat);
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
if (lstrcmpiW(lf.lfFaceName, td[i].family_name) != 0)
{
skip("%s not installed\n", wine_dbgstr_w(td[i].family_name));
}
else
{
ok(lf.lfHeight < 0, "Expected negative height, got %ld\n", lf.lfHeight);
expect(0, lf.lfWidth);
expect(0, lf.lfEscapement);
expect(0, lf.lfOrientation);
ok((lf.lfWeight >= 100) && (lf.lfWeight <= 900), "Expected weight to be set\n");
expect(0, lf.lfItalic);
expect(0, lf.lfUnderline);
expect(0, lf.lfStrikeOut);
ok(td[i].char_set == lf.lfCharSet ||
(td[i].char_set == ANSI_CHARSET && lf.lfCharSet == GetTextCharset(hdc)),
"got %#x\n", lf.lfCharSet);
expect(0, lf.lfOutPrecision);
expect(0, lf.lfClipPrecision);
expect(0, lf.lfQuality);
expect(0, lf.lfPitchAndFamily);
}
GdipDeleteFont(font);
GdipDeleteFontFamily(fontfamily);
winetest_pop_context();
}
GdipDeleteGraphics(graphics);
DeleteDC(hdc);
}
static void test_logfont(void)
{
LOGFONTA lfa, lfa2;
@@ -299,6 +400,56 @@ static void test_logfont(void)
GdipDeleteFontFamily(family);
GdipDeleteFont(font);
font = NULL;
/* The next test must be done with a font where tmHeight -
tmInternalLeading != tmAscent. Times New Roman is such a font,
so make sure we really have it before continuing. */
memset(&lfa, 0, sizeof(lfa));
lstrcpyA(lfa.lfFaceName, "Times New Roman");
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
expect(Ok, stat);
memset(&lfa2, 0, sizeof(lfa2));
stat = GdipGetLogFontA(font, graphics, &lfa2);
expect(Ok, stat);
GdipDeleteFont(font);
font = NULL;
if (!lstrlenA(lfa.lfFaceName) || lstrcmpA(lfa.lfFaceName, lfa2.lfFaceName))
{
skip("Times New Roman not installed\n");
}
else
{
static const struct
{
INT input;
REAL expected;
} test_sizes[] = {{12, 9.0}, {36, 32.0}, {48, 42.0}, {72, 63.0}, {144, 127.0}};
UINT i;
memset(&lfa, 0, sizeof(lfa));
lstrcpyA(lfa.lfFaceName, "Times New Roman");
for (i = 0; i < ARRAY_SIZE(test_sizes); ++i)
{
lfa.lfHeight = test_sizes[i].input;
stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
expect(Ok, stat);
stat = GdipGetFontSize(font, &rval);
expect(Ok, stat);
expectf(test_sizes[i].expected, rval);
GdipDeleteFont(font);
font = NULL;
}
}
GdipDeleteGraphics(graphics);
ReleaseDC(0, hdc);
@@ -311,42 +462,40 @@ static void test_fontfamily (void)
GpStatus stat;
/* FontFamily cannot be NULL */
stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
stat = GdipCreateFontFamilyFromName (L"Tahoma" , NULL, NULL);
expect (InvalidParameter, stat);
/* FontFamily must be able to actually find the family.
* If it can't, any subsequent calls should fail.
*/
stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
stat = GdipCreateFontFamilyFromName (L"ThisFontShouldNotExist", NULL, &family);
expect (FontFamilyNotFound, stat);
/* Bitmap fonts are not found */
stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
stat = GdipCreateFontFamilyFromName (L"MS Sans Serif", NULL, &family);
expect (FontFamilyNotFound, stat);
if(stat == Ok) GdipDeleteFontFamily(family);
stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
stat = GdipCreateFontFamilyFromName (L"Tahoma", NULL, &family);
expect (Ok, stat);
stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
expect (Ok, stat);
expect (0, lstrcmpiW(itsName, Tahoma));
expect (0, lstrcmpiW(itsName, L"Tahoma"));
if (0)
{
/* Crashes on Windows XP SP2, Vista, and so Wine as well */
stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL);
expect (Ok, stat);
}
/* Crashes on Windows XP SP2 and Vista */
stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL);
expect (Ok, stat);
/* Make sure we don't read old data */
ZeroMemory (itsName, sizeof(itsName));
stat = GdipCloneFontFamily(family, &clonedFontFamily);
expect (Ok, stat);
ok (family == clonedFontFamily, "Unexpected family instance.\n");
GdipDeleteFontFamily(family);
stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
expect(Ok, stat);
expect(0, lstrcmpiW(itsName, Tahoma));
expect(0, lstrcmpiW(itsName, L"Tahoma"));
GdipDeleteFontFamily(clonedFontFamily);
}
@@ -357,7 +506,7 @@ static void test_fontfamily_properties (void)
GpStatus stat;
UINT16 result = 0;
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &FontFamily);
expect(Ok, stat);
stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
@@ -377,7 +526,7 @@ static void test_fontfamily_properties (void)
ok(result == 423, "Expected 423, got %d\n", result);
GdipDeleteFontFamily(FontFamily);
stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
stat = GdipCreateFontFamilyFromName(L"Times New Roman", NULL, &FontFamily);
if(stat == FontFamilyNotFound)
skip("Times New Roman not installed\n");
else
@@ -481,7 +630,7 @@ static void test_heightgivendpi(void)
REAL height;
Unit unit;
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &fontfamily);
expect(Ok, stat);
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
@@ -682,7 +831,7 @@ static void test_font_metrics(void)
memset(&lf, 0, sizeof(lf));
/* Tahoma,-13 */
lstrcpyW(lf.lfFaceName, Tahoma);
lstrcpyW(lf.lfFaceName, L"Tahoma");
lf.lfHeight = -13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
@@ -693,14 +842,14 @@ static void test_font_metrics(void)
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",
trace("%s,%ld: 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",
trace("%s,%ld: 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);
@@ -709,10 +858,10 @@ static void test_font_metrics(void)
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %ld\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",
trace("%s,%ld: 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);
@@ -723,7 +872,7 @@ static void test_font_metrics(void)
GdipDeleteFont(font);
/* Tahoma,13 */
lstrcpyW(lf.lfFaceName, Tahoma);
lstrcpyW(lf.lfFaceName, L"Tahoma");
lf.lfHeight = 13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
@@ -734,14 +883,14 @@ static void test_font_metrics(void)
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",
trace("%s,%ld: 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",
trace("%s,%ld: 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);
@@ -750,10 +899,10 @@ static void test_font_metrics(void)
stat = GdipGetLogFontW(font, graphics, &lf);
expect(Ok, stat);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %ld\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",
trace("%s,%ld: 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);
@@ -763,7 +912,7 @@ static void test_font_metrics(void)
GdipDeleteFont(font);
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, stat);
/* Tahoma,13 */
@@ -772,17 +921,17 @@ static void test_font_metrics(void)
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",
trace("%s,%ld: 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);
ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %ld\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",
trace("%s,%ld: 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);
@@ -806,52 +955,43 @@ static void test_font_metrics(void)
static void test_font_substitution(void)
{
WCHAR ms_shell_dlg[LF_FACESIZE];
char fallback_font[LF_FACESIZE];
HDC hdc;
HFONT hfont;
LOGFONTA lf;
GpStatus status;
GpGraphics *graphics;
GpFont *font;
GpFontFamily *family;
int ret;
hdc = CreateCompatibleDC(0);
status = GdipCreateFromHDC(hdc, &graphics);
expect(Ok, status);
hfont = GetStockObject(DEFAULT_GUI_FONT);
ok(hfont != 0, "GetStockObject(DEFAULT_GUI_FONT) failed\n");
memset(&lf, 0xfe, sizeof(lf));
ret = GetObjectA(hfont, sizeof(lf), &lf);
ok(ret == sizeof(lf), "GetObject failed\n");
ok(!lstrcmpA(lf.lfFaceName, "MS Shell Dlg"), "wrong face name %s\n", lf.lfFaceName);
MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, -1, ms_shell_dlg, LF_FACESIZE);
memset(&lf, 0, sizeof(lf));
lstrcpyA(lf.lfFaceName, "MS Shell Dlg");
status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
expect(Ok, status);
memset(&lf, 0xfe, sizeof(lf));
status = GdipGetLogFontA(font, graphics, &lf);
expect(Ok, status);
ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") ||
!lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
ok(lstrcmpA(lf.lfFaceName, "MS Shell Dlg") != 0, "expected substitution of MS Shell Dlg\n");
GdipDeleteFont(font);
status = GdipCreateFontFamilyFromName(ms_shell_dlg, NULL, &family);
family = NULL;
status = GdipCreateFontFamilyFromName(L"MS Shell Dlg", NULL, &family);
expect(Ok, status);
font = NULL;
status = GdipCreateFont(family, 12, FontStyleRegular, UnitPoint, &font);
expect(Ok, status);
memset(&lf, 0xfe, sizeof(lf));
status = GdipGetLogFontA(font, graphics, &lf);
expect(Ok, status);
ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") ||
!lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
ok(lstrcmpA(lf.lfFaceName, "MS Shell Dlg") != 0, "expected substitution of MS Shell Dlg\n");
GdipDeleteFont(font);
GdipDeleteFontFamily(family);
status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family);
status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &family);
ok(status == FontFamilyNotFound, "expected FontFamilyNotFound, got %d\n", status);
/* nonexistent fonts fallback to Arial, or something else if it's missing */
@@ -889,7 +1029,7 @@ static void test_font_substitution(void)
lstrcpyA(lf.lfFaceName, "ThisFontShouldNotExist");
font = NULL;
status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
todo_wine
todo_wine
ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
"expected NotTrueTypeFont, got %d\n", status);
/* FIXME: remove when wine is fixed */
@@ -899,7 +1039,7 @@ todo_wine
lf.lfFaceName[0] = 0;
font = NULL;
status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
todo_wine
todo_wine
ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
"expected NotTrueTypeFont, got %d\n", status);
/* FIXME: remove when wine is fixed */
@@ -911,7 +1051,7 @@ todo_wine
static void test_font_transform(void)
{
static const WCHAR string[] = { 'A',0 };
static const WCHAR string[] = L"A";
GpStatus status;
HDC hdc;
LOGFONTA lf;
@@ -964,7 +1104,7 @@ static void test_font_transform(void)
expect(Ok, status);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
todo_wine
todo_wine
expectf(height + margin_y, bounds.Height);
set_rect_empty(&rect);
set_rect_empty(&bounds);
@@ -1008,7 +1148,7 @@ todo_wine
expect(Ok, status);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
todo_wine
todo_wine
expectf(height + margin_y, bounds.Height);
set_rect_empty(&rect);
set_rect_empty(&bounds);
@@ -1029,9 +1169,9 @@ todo_wine
DriverStringOptionsCmapLookup, matrix, &bounds);
expect(Ok, status);
expectf(0.0, bounds.X);
todo_wine
todo_wine
expectf_(-300.0, bounds.Y, 0.15);
todo_wine
todo_wine
expectf(height * 3.0, bounds.Height);
/* scale + ratate matrix */
@@ -1054,7 +1194,7 @@ todo_wine
expect(Ok, status);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
todo_wine
todo_wine
expectf(height + margin_y, bounds.Height);
set_rect_empty(&rect);
set_rect_empty(&bounds);
@@ -1074,11 +1214,11 @@ todo_wine
status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
DriverStringOptionsCmapLookup, matrix, &bounds);
expect(Ok, status);
todo_wine
todo_wine
expectf_(-43.814377, bounds.X, 0.05);
todo_wine
todo_wine
expectf_(-212.235611, bounds.Y, 0.05);
todo_wine
todo_wine
expectf_(340.847534, bounds.Height, 0.05);
/* scale + ratate + shear matrix */
@@ -1088,7 +1228,7 @@ todo_wine
expect(Ok, status);
status = GdipGetLogFontA(font, graphics, &lf);
expect(Ok, status);
todo_wine
todo_wine
expect(1032, lf.lfHeight);
expect(0, lf.lfWidth);
expect_(3099, lf.lfEscapement, 1);
@@ -1102,7 +1242,7 @@ todo_wine
expect(Ok, status);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
todo_wine
todo_wine
expectf(height + margin_y, bounds.Height);
set_rect_empty(&rect);
set_rect_empty(&bounds);
@@ -1122,11 +1262,11 @@ todo_wine
status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
DriverStringOptionsCmapLookup, matrix, &bounds);
expect(Ok, status);
todo_wine
todo_wine
expectf_(-636.706848, bounds.X, 0.05);
todo_wine
todo_wine
expectf_(-175.257523, bounds.Y, 0.05);
todo_wine
todo_wine
expectf_(1532.984985, bounds.Height, 0.05);
/* scale + ratate + shear + translate matrix */
@@ -1136,7 +1276,7 @@ todo_wine
expect(Ok, status);
status = GdipGetLogFontA(font, graphics, &lf);
expect(Ok, status);
todo_wine
todo_wine
expect(1032, lf.lfHeight);
expect(0, lf.lfWidth);
expect_(3099, lf.lfEscapement, 1);
@@ -1150,7 +1290,7 @@ todo_wine
expect(Ok, status);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
todo_wine
todo_wine
expectf(height + margin_y, bounds.Height);
set_rect_empty(&rect);
set_rect_empty(&bounds);
@@ -1170,13 +1310,27 @@ todo_wine
status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
DriverStringOptionsCmapLookup, matrix, &bounds);
expect(Ok, status);
todo_wine
todo_wine
expectf_(-626.706848, bounds.X, 0.05);
todo_wine
todo_wine
expectf_(-155.257523, bounds.Y, 0.05);
todo_wine
todo_wine
expectf_(1532.984985, bounds.Height, 0.05);
GdipDeleteGraphics(graphics);
SetMapMode( hdc, MM_ISOTROPIC);
SetWindowExtEx(hdc, 200, 200, NULL);
SetViewportExtEx(hdc, 100, 100, NULL);
status = GdipCreateFromHDC(hdc, &graphics);
expect(Ok, status);
status = GdipGetLogFontA(font, graphics, &lf);
expect(Ok, status);
expect(-50, lf.lfHeight);
expect(0, lf.lfWidth);
expect(0, lf.lfEscapement);
expect(0, lf.lfOrientation);
GdipDeleteMatrix(matrix);
GdipDeleteFont(font);
GdipDeleteGraphics(graphics);
@@ -1187,8 +1341,9 @@ todo_wine
static void test_GdipGetFontCollectionFamilyList(void)
{
GpFontFamily *family, *family2;
GpFontFamily *family, *family2, **families;
GpFontCollection *collection;
UINT i;
INT found, count;
GpStatus status;
@@ -1228,15 +1383,31 @@ static void test_GdipGetFontCollectionFamilyList(void)
ok(found == 1, "Unexpected list count %d.\n", found);
ok(family != NULL, "Expected family instance.\n");
family = NULL;
family2 = NULL;
found = 0;
status = GdipGetFontCollectionFamilyList(collection, 1, &family2, &found);
ok(status == Ok, "Failed to get family list, status %d.\n", status);
ok(found == 1, "Unexpected list count %d.\n", found);
ok(family2 != family, "Unexpected family instance.\n");
ok(family2 == family, "Unexpected family instance.\n");
GdipDeleteFontFamily(family);
GdipDeleteFontFamily(family2);
status = GdipDeleteFontFamily(family);
expect(Ok, status);
status = GdipDeleteFontFamily(family2);
expect(Ok, status);
families = GdipAlloc((count + 1) * sizeof(*families));
found = 0;
status = GdipGetFontCollectionFamilyList(collection, count + 1, families, &found);
ok(status == Ok, "Failed to get family list, status %d.\n", status);
ok(found == count, "Unexpected list count %d, extected %d.\n", found, count);
for (i = 0; i < found; i++)
{
status = GdipDeleteFontFamily(families[i]);
expect(Ok, status);
}
GdipFree(families);
}
static void test_GdipGetFontCollectionFamilyCount(void)
@@ -1260,6 +1431,147 @@ static void test_GdipGetFontCollectionFamilyCount(void)
ok(status == InvalidParameter, "Unexpected status %d.\n", status);
}
static BOOL is_family_in_collection(GpFontCollection *collection, GpFontFamily *family)
{
GpStatus status;
GpFontFamily **list;
int count, i;
BOOL found = FALSE;
status = GdipGetFontCollectionFamilyCount(collection, &count);
expect(Ok, status);
list = GdipAlloc(count * sizeof(GpFontFamily *));
status = GdipGetFontCollectionFamilyList(collection, count, list, &count);
expect(Ok, status);
for (i = 0; i < count; i++)
{
if (list[i] == family)
{
found = TRUE;
break;
}
}
GdipFree(list);
return found;
}
static void test_CloneFont(void)
{
GpStatus status;
GpFontCollection *collection, *collection2;
GpFont *font, *font2;
GpFontFamily *family, *family2;
REAL height;
Unit unit;
int style;
BOOL ret;
status = GdipNewInstalledFontCollection(&collection);
expect(Ok, status);
status = GdipNewInstalledFontCollection(&collection2);
expect(Ok, status);
ok(collection == collection2, "got %p\n", collection2);
status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &family);
expect(FontFamilyNotFound, status);
status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", collection, &family);
expect(FontFamilyNotFound, status);
status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
ret = is_family_in_collection(collection, family);
ok(ret, "family is not in collection\n");
status = GdipCreateFont(family, 30.0f, FontStyleRegular, UnitPixel, &font);
expect(Ok, status);
status = GdipGetFontUnit(font, &unit);
expect(Ok, status);
ok(unit == UnitPixel, "got %u\n", unit);
status = GdipGetFontSize(font, &height);
expect(Ok, status);
ok(height == 30.0f, "got %f\n", height);
status = GdipGetFontStyle(font, &style);
expect(Ok, status);
ok(style == FontStyleRegular, "got %d\n", style);
status = GdipGetFamily(font, &family2);
expect(Ok, status);
ok(family == family2, "got %p\n", family2);
status = GdipCloneFont(font, &font2);
expect(Ok, status);
status = GdipGetFontUnit(font2, &unit);
expect(Ok, status);
ok(unit == UnitPixel, "got %u\n", unit);
status = GdipGetFontSize(font2, &height);
expect(Ok, status);
ok(height == 30.0f, "got %f\n", height);
status = GdipGetFontStyle(font2, &style);
expect(Ok, status);
ok(style == FontStyleRegular, "got %d\n", style);
status = GdipGetFamily(font2, &family2);
expect(Ok, status);
ok(family == family2, "got %p\n", family2);
GdipDeleteFont(font2);
GdipDeleteFont(font);
GdipDeleteFontFamily(family);
}
static void test_GdipPrivateAddMemoryFont(void)
{
static const WORD resource_ids[] =
{
3, /* A font that has an invalid full name on Mac platform and a valid full name on Microsoft platform */
4, /* A font that has an invalid full name on Unicode platform and a valid full name on Mac platform */
};
GpFontCollection *fonts;
GpStatus stat;
int count, i;
void *buffer;
DWORD size;
for (i = 0; i < ARRAY_SIZE(resource_ids); i++)
{
winetest_push_context("test %d", i);
stat = GdipNewPrivateFontCollection(&fonts);
ok(stat == Ok, "GdipNewPrivateFontCollection failed, error %d\n", stat);
load_resource(MAKEINTRESOURCEW(resource_ids[i]), (BYTE **)&buffer, &size);
stat = GdipPrivateAddMemoryFont(fonts, buffer, size);
if (stat == Ok)
{
stat = GdipGetFontCollectionFamilyCount(fonts, &count);
ok(stat == Ok, "GdipGetFontCollectionFamilyCount failed, error %d\n", stat);
ok(count == 1, "Expected count 1, got %d\n", count);
}
else if (i == 1 && stat == FileNotFound)
win_skip("Fonts without Microsoft platform names are unsupported on win7.\n");
else
ok(0, "GdipPrivateAddMemoryFont failed, error %d\n", stat);
stat = GdipDeletePrivateFontCollection(&fonts);
ok(stat == Ok, "GdipDeletePrivateFontCollection failed, error %d\n", stat);
winetest_pop_context();
}
}
START_TEST(font)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -1279,11 +1591,13 @@ START_TEST(font)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
test_CloneFont();
test_long_name();
test_font_transform();
test_font_substitution();
test_font_metrics();
test_createfont();
test_createfont_charset();
test_logfont();
test_fontfamily();
test_fontfamily_properties();
@@ -1292,6 +1606,7 @@ START_TEST(font)
test_heightgivendpi();
test_GdipGetFontCollectionFamilyList();
test_GdipGetFontCollectionFamilyCount();
test_GdipPrivateAddMemoryFont();
GdiplusShutdown(gdiplusToken);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-13
View File
@@ -11,17 +11,4 @@
#include <initguid.h>
#include <gdiplus.h>
/* FIXME: They belong to gdipluseffects.h */
DEFINE_GUID(BlurEffectGuid, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
DEFINE_GUID(SharpenEffectGuid, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
DEFINE_GUID(ColorMatrixEffectGuid, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
DEFINE_GUID(ColorLUTEffectGuid, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
DEFINE_GUID(BrightnessContrastEffectGuid, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
DEFINE_GUID(HueSaturationLightnessEffectGuid, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
DEFINE_GUID(LevelsEffectGuid, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
DEFINE_GUID(TintEffectGuid, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
DEFINE_GUID(ColorBalanceEffectGuid, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
DEFINE_GUID(RedEyeCorrectionEffectGuid, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
DEFINE_GUID(ColorCurveEffectGuid, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
File diff suppressed because it is too large Load Diff
+89 -4
View File
@@ -28,6 +28,13 @@
#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)
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
{
unsigned int diff = x > y ? x - y : y - x;
return diff <= max_diff;
}
static BOOL compare_float(float f, float g, unsigned int ulps)
{
int x = *(int *)&f;
@@ -38,10 +45,7 @@ static BOOL compare_float(float f, float g, unsigned int ulps)
if (y < 0)
y = INT_MIN - y;
if (abs(x - y) > ulps)
return FALSE;
return TRUE;
return compare_uint(x, y, ulps);
}
static void test_constructor_destructor(void)
@@ -110,6 +114,85 @@ static void test_transform(void)
GdipDeleteMatrix(matrix);
}
static void test_translate(void)
{
GpStatus status;
GpMatrix *matrix = NULL;
REAL elems[6];
static const REAL expected_elem_append[] = {1.0, -2.0, 30.0, 40.0, -470.0, 620.0};
static const REAL expected_elem_prepend[] = {1.0, -2.0, 30.0, 40.0, 130.0, 1340.0};
GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
status = GdipTranslateMatrix(NULL, 30.0, 20.0, MatrixOrderAppend);
expect(InvalidParameter, status);
status = GdipTranslateMatrix(matrix, 30.0, 20.0, MatrixOrderAppend);
expect(Ok, status);
status = GdipGetMatrixElements(matrix, elems);
expect(Ok, status);
GdipDeleteMatrix(matrix);
for(INT i = 0; i < 6; i++)
ok(expected_elem_append[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
expected_elem_append[i], elems[i]);
GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
status = GdipTranslateMatrix(matrix, 30.0, 20.0, MatrixOrderPrepend);
expect(Ok, status);
status = GdipGetMatrixElements(matrix, elems);
expect(Ok, status);
GdipDeleteMatrix(matrix);
for(INT i = 0; i < 6; i++)
ok(expected_elem_prepend[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
expected_elem_prepend[i], elems[i]);
}
static void test_scale(void)
{
GpStatus status;
GpMatrix *matrix = NULL;
REAL elems[6];
int i;
static const REAL expected_elem[] = {3.0, -4.0, 90.0, 80.0, -1500.0, 1200.0};
static const REAL expected_elem2[] = {3.0, -6.0, 60.0, 80.0, -500.0, 600.0};
GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
status = GdipScaleMatrix(NULL, 3, 2, MatrixOrderAppend);
expect(InvalidParameter, status);
status = GdipScaleMatrix(matrix, 3, 2, MatrixOrderAppend);
expect(Ok, status);
status = GdipGetMatrixElements(matrix, elems);
expect(Ok, status);
GdipDeleteMatrix(matrix);
for(i = 0; i < 6; i++)
ok(expected_elem[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
expected_elem[i], elems[i]);
GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
status = GdipScaleMatrix(matrix, 3, 2, MatrixOrderPrepend);
expect(Ok, status);
status = GdipGetMatrixElements(matrix, elems);
expect(Ok, status);
GdipDeleteMatrix(matrix);
for(i = 0; i < 6; i++)
ok(expected_elem2[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
expected_elem2[i], elems[i]);
}
static void test_isinvertible(void)
{
GpStatus status;
@@ -390,6 +473,8 @@ START_TEST(matrix)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
test_constructor_destructor();
test_translate();
test_scale();
test_transform();
test_isinvertible();
test_invert();
File diff suppressed because it is too large Load Diff
+258 -32
View File
@@ -464,18 +464,38 @@ static void test_nextsubpath(void)
GpPath *path;
GpPathIterator *iter;
GpStatus stat;
INT start, end, result;
INT result, start, end;
BOOL closed;
/* empty path */
GdipCreatePath(FillModeAlternate, &path);
GdipCreatePathIter(&iter, path);
result = -2;
closed = TRUE;
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(0, result);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
expect((INT)0xdeadbeef, closed);
/* four points figure */
GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
GdipAddPathLine(path, -10.0, 5.0, 15.0, 8.0);
GdipCreatePathIter(&iter, path);
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(4, result);
expect(0, start);
expect(3, end);
expect(FALSE, closed);
/* No more subpaths*/
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(0, result);
expect(0, start);
expect(0, end);
expect(TRUE, closed);
GdipDeletePathIter(iter);
@@ -487,8 +507,10 @@ static void test_nextpathtype(void)
GpPath *path;
GpPathIterator *iter;
GpStatus stat;
INT start, end, result;
INT count, result, start, end;
BYTE type;
BOOL closed;
GpPointF point;
GdipCreatePath(FillModeAlternate, &path);
GdipCreatePathIter(&iter, path);
@@ -510,53 +532,257 @@ static void test_nextpathtype(void)
expect(InvalidParameter, stat);
/* empty path */
start = end = result = (INT)0xdeadbeef;
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
todo_wine expect(Ok, stat);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
todo_wine expect(0, result);
GdipDeletePathIter(iter);
/* single figure */
GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
GdipCreatePathIter(&iter, path);
start = end = result = (INT)0xdeadbeef;
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
todo_wine expect(Ok, stat);
expect(Ok, stat);
expect(0, result);
expect(255, type);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
expect(255, type);
todo_wine expect(0, result);
GdipDeletePathIter(iter);
/* Single PathPointTypeStart point */
point.X = 1.0;
point.Y = 2.0;
stat = GdipAddPathLine2(path, &point, 1);
expect(Ok, stat);
stat = GdipCreatePathIter(&iter, path);
expect(Ok, stat);
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(1, result);
expect(0, start);
expect(0, end);
expect(FALSE, closed);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(1, result);
expect(255, type);
expect(0, start);
expect(0, end);
GdipDeletePathIter(iter);
GdipDeletePath(path);
/* Figure with three subpaths */
GdipCreatePath(FillModeAlternate, &path);
stat = GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
expect(Ok, stat);
stat = GdipAddPathRectangle(path, 1.0, 2.0, 3.0, 4.0);
expect(Ok, stat);
stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0);
expect(Ok, stat);
GdipCreatePathIter(&iter, path);
stat = GdipCreatePathIter(&iter, path);
expect(Ok, stat);
/* When subPath is not set,
it is not possible to get Path Type */
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(0, result);
expect(255, type);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
/* When subPath is not set,
it is possible to get number of path points */
stat = GdipPathIterGetCount(iter, &count);
expect(Ok, stat);
expect(19, count);
/* Set subPath (Line) */
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(2, result);
expect(0, start);
expect(1, end);
expect(FALSE, closed);
/* When subPath is set (Line), return position of points with the same type */
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(2, result);
expect(PathPointTypeLine, type);
expect(0, start);
expect(1, end);
/* When NextSubpath is running twice, without invocation NextPathType
(skipping Rectangle figure), make sure that PathType index is updated */
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(4, result);
expect(2, start);
expect(5, end);
expect(TRUE, closed);
/* Increment subPath (to Ellipse figure) */
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(13, result);
expect(6, start);
expect(18, end);
expect(TRUE, closed);
/* When subPath is set to Ellipse figure, the type is PathPointTypeBezier */
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(13, result);
expect(PathPointTypeBezier, type);
expect(6, start);
expect(18, end);
/* As there is no more subpaths, when subPath is incremented,
it returns zeros */
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(0, result);
expect(0, start);
expect(0, end);
expect(TRUE, closed);
/* When no more elements, after invoking NextPathType
the output numbers are not changed */
start = end = result = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
todo_wine expect(Ok, stat);
expect(Ok, stat);
expect(0, result);
expect(255, type);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
expect(255, type);
todo_wine expect(0, result);
GdipDeletePathIter(iter);
/* closed */
GdipClosePathFigure(path);
GdipCreatePathIter(&iter, path);
start = end = result = (INT)0xdeadbeef;
GdipDeletePathIter(iter);
GdipDeletePath(path);
/* Single PathPointTypeStart point */
GdipCreatePath(FillModeAlternate, &path);
point.X = 1.0;
point.Y = 2.0;
stat = GdipAddPathLine2(path, &point, 1);
expect(Ok, stat);
stat = GdipCreatePathIter(&iter, path);
expect(Ok, stat);
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(1, result);
expect(0, start);
expect(0, end);
expect(FALSE, closed);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
todo_wine expect(Ok, stat);
expect(Ok, stat);
expect(1, result);
expect(255, type);
expect(0, start);
expect(0, end);
GdipDeletePathIter(iter);
GdipDeletePath(path);
/* Mixed PathPointTypeLine and PathPointTypeBezier points */
GdipCreatePath(FillModeAlternate, &path);
stat = GdipAddPathLine(path, -1.0, 1.0, 10.0, 15.0);
expect(Ok, stat);
/* Starting point of Bezier figure, is the same
as ending point of previous figure (10.0, 15.0) */
stat = GdipAddPathBezier(path, 10.0, 15.0, 9.0, 9.0, 6.0, 7.0, 9.0, 0.0);
expect(Ok, stat);
/* Starting point of figure, is different that ending point of previous figure */
stat = GdipAddPathLine(path, -1.0, -1.0, 7.5, 12.0);
expect(Ok, stat);
stat = GdipStartPathFigure(path);
expect(Ok, stat);
stat = GdipAddPathLine(path, 50.0, 50.0, 110.0, 40.0);
expect(Ok, stat);
stat = GdipCreatePathIter(&iter, path);
expect(Ok, stat);
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(7, result);
expect(0, start);
expect(6, end);
expect(FALSE, closed);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(2, result);
expect(PathPointTypeLine, type);
expect(0, start);
expect(1, end);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(4, result);
expect(PathPointTypeBezier, type);
expect(1, start);
expect(4, end);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(3, result);
expect(PathPointTypeLine, type);
expect(4, start);
expect(6, end);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(0, result);
expect(255, type);
expect((INT)0xdeadbeef, start);
expect((INT)0xdeadbeef, end);
expect(255, type);
todo_wine expect(0, result);
GdipDeletePathIter(iter);
result = start = end = closed = (INT)0xdeadbeef;
stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
expect(Ok, stat);
expect(2, result);
expect(7, start);
expect(8, end);
expect(FALSE, closed);
result = start = end = (INT)0xdeadbeef;
type = 255; /* out of range */
stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
expect(Ok, stat);
expect(2, result);
expect(PathPointTypeLine, type);
expect(7, start);
expect(8, end);
GdipDeletePathIter(iter);
GdipDeletePath(path);
}
+66 -9
View File
@@ -24,7 +24,11 @@
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
#define expect(expected,got) expect_(__LINE__, expected, got)
static inline void expect_(unsigned line, DWORD expected, DWORD got)
{
ok_(__FILE__, line)(expected == got, "Expected %.8ld, got %.8ld\n", expected, got);
}
#define expectf(expected, got) ok(fabs(got - expected) < 0.1, "Expected %.2f, got %.2f\n", expected, got)
static void test_startup(void)
@@ -175,7 +179,7 @@ static void test_dasharray(void)
dashes[4] = 14.0;
dashes[5] = -100.0;
dashes[6] = -100.0;
dashes[7] = dashes[8] = dashes[9] = dashes[10] = dashes[11] = 0.0;
dashes[7] = dashes[8] = dashes[9] = dashes[10] = dashes[11] = 1.0;
/* setting the array sets the type to custom */
GdipGetPenDashStyle(pen, &style);
@@ -218,10 +222,13 @@ static void test_dasharray(void)
/* Some invalid array values. */
status = GdipSetPenDashArray(pen, &dashes[7], 5);
expect(InvalidParameter, status);
expect(Ok, status);
dashes[9] = -1.0;
status = GdipSetPenDashArray(pen, &dashes[7], 5);
expect(InvalidParameter, status);
dashes[9] = 0.0;
status = GdipSetPenDashArray(pen, &dashes[7], 5);
expect(InvalidParameter, status);
/* Try to set with count = 0. */
GdipSetPenDashStyle(pen, DashStyleDot);
@@ -343,7 +350,11 @@ static void test_compoundarray(void)
{
GpStatus status;
GpPen *pen;
REAL *returnvalues;
static const REAL testvalues[] = {0.2, 0.4, 0.6, 0.8};
static const REAL notSortedValues[] = {0.2, 0.6, 0.4, 0.8};
static const REAL negativeValues[] = {-1.2, 0.4, 0.6, 0.8};
static const REAL tooLargeValues[] = {0.2, 0.4, 0.6, 2.8};
INT count;
status = GdipSetPenCompoundArray(NULL, testvalues, 4);
@@ -360,10 +371,9 @@ static void test_compoundarray(void)
count = 10;
status = GdipGetPenCompoundCount(pen, &count);
todo_wine {
expect(Ok, status);
ok(count == 0, "Unexpected compound count %d\n", count);
}
status = GdipSetPenCompoundArray(pen, NULL, 0);
expect(InvalidParameter, status);
status = GdipSetPenCompoundArray(pen, NULL, 4);
@@ -375,17 +385,43 @@ todo_wine {
status = GdipSetPenCompoundArray(pen, testvalues, -2);
expect(InvalidParameter, status);
status = GdipSetPenCompoundArray(pen, notSortedValues, 4);
expect(InvalidParameter, status);
status = GdipSetPenCompoundArray(pen, negativeValues, 4);
expect(InvalidParameter, status);
status = GdipSetPenCompoundArray(pen, tooLargeValues, 4);
expect(InvalidParameter, status);
status = GdipSetPenCompoundArray(pen, testvalues, 4);
todo_wine expect(Ok, status);
expect(Ok, status);
status = GdipSetPenCompoundArray(pen, NULL, 0);
expect(InvalidParameter, status);
count = 0;
status = GdipGetPenCompoundCount(pen, &count);
todo_wine {
expect(Ok, status);
ok(count == 4, "Unexpected compound count %d\n", count);
}
returnvalues = calloc(5, sizeof(REAL));
/* When count larger than stored array return error */
status = GdipGetPenCompoundArray(pen, returnvalues, 40);
expect(InvalidParameter, status);
status = GdipGetPenCompoundArray(NULL, returnvalues, 4);
expect(InvalidParameter, status);
/* When count is zero, it should do nothing */
status = GdipGetPenCompoundArray(pen, returnvalues, 0);
expect(Ok, status);
ok(returnvalues[0] == 0.0, "Unexpected compound array %f\n", returnvalues[0]);
status = GdipGetPenCompoundArray(pen, returnvalues, 4);
expect(Ok, status);
ok(memcmp(returnvalues, testvalues, 4 * sizeof(REAL)) == 0, "Unexpected compound array\n");
status = GdipGetPenCompoundArray(pen, returnvalues, -10);
expect(Ok, status);
ok(memcmp(returnvalues, testvalues, 4 * sizeof(REAL)) == 0, "Unexpected compound array\n");
free(returnvalues);
GdipDeletePen(pen);
}
@@ -409,9 +445,10 @@ static void test_transform(void)
{
GpStatus status;
GpPen *pen;
GpMatrix *matrix, *matrix2;
GpMatrix *matrix, *matrix2, *not_invertible_matrix;
REAL values[6];
/* Check default Pen Transformation */
status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
expect(Ok, status);
@@ -431,6 +468,26 @@ static void test_transform(void)
expectf(0.0, values[4]);
expectf(0.0, values[5]);
/* Setting Pen Tranformation to Not invertible matrix, should return InvalidParameter */
GdipCreateMatrix2(3.0, 3.0, 2.0, 2.0, 6.0, 3.0, &not_invertible_matrix);
status = GdipSetPenTransform(pen, not_invertible_matrix);
expect(InvalidParameter, status);
GdipDeleteMatrix(not_invertible_matrix);
status = GdipGetPenTransform(pen, matrix);
expect(Ok, status);
status = GdipGetMatrixElements(matrix, values);
expect(Ok, status);
expectf(1.0, values[0]);
expectf(0.0, values[1]);
expectf(0.0, values[2]);
expectf(1.0, values[3]);
expectf(0.0, values[4]);
expectf(0.0, values[5]);
/* Setting Pen Tranformation to invertible matrix, should be successfull */
GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix2);
status = GdipSetPenTransform(pen, matrix2);
expect(Ok, status);
+283 -42
View File
@@ -33,11 +33,15 @@
#define RGNDATA_MAGIC 0xdbc01001
#define RGNDATA_MAGIC2 0xdbc01002
#define expect(expected, got) ok((got) == (expected), "Expected %.8x, got %.8x\n", (expected), (got))
#define expect(expected,got) expect_(__LINE__, expected, got)
static inline void expect_(unsigned line, DWORD expected, DWORD got)
{
ok_(__FILE__, line)(expected == got, "Expected %ld, got %ld\n", expected, got);
}
#define expectf_(expected, got, precision) ok(fabs((expected) - (got)) < (precision), "Expected %f, got %f\n", (expected), (got))
#define expectf(expected, got) expectf_((expected), (got), 0.001)
#define expect_magic(value) ok(broken(*(value) == RGNDATA_MAGIC) || *(value) == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *(value))
#define expect_magic(value) ok(broken(*(value) == RGNDATA_MAGIC) || *(value) == RGNDATA_MAGIC2, "Expected a known magic value, got %8lx\n", *(value))
#define expect_dword(value, expected) expect((expected), *(value))
#define expect_float(value, expected) expectf((expected), *(FLOAT *)(value))
@@ -59,19 +63,19 @@ static void verify_region(HRGN hrgn, const RECT *rc)
ret = GetRegionData(hrgn, 0, NULL);
if (IsRectEmpty(rc))
ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %lu\n", ret);
else
ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %lu\n", ret);
if (!ret) return;
ret = GetRegionData(hrgn, sizeof(rgn), &rgn.data);
if (IsRectEmpty(rc))
ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %lu\n", ret);
else
ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %lu\n", ret);
trace("size %u, type %u, count %u, rgn size %u, bound %s\n",
trace("size %lu, type %lu, count %lu, rgn size %lu, bound %s\n",
rgn.data.rdh.dwSize, rgn.data.rdh.iType,
rgn.data.rdh.nCount, rgn.data.rdh.nRgnSize,
wine_dbgstr_rect(&rgn.data.rdh.rcBound));
@@ -83,17 +87,17 @@ static void verify_region(HRGN hrgn, const RECT *rc)
wine_dbgstr_rect(rc), wine_dbgstr_rect(rect));
}
ok(rgn.data.rdh.dwSize == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", rgn.data.rdh.dwSize);
ok(rgn.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn.data.rdh.iType);
ok(rgn.data.rdh.dwSize == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %lu\n", rgn.data.rdh.dwSize);
ok(rgn.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %lu\n", rgn.data.rdh.iType);
if (IsRectEmpty(rc))
{
ok(rgn.data.rdh.nCount == 0, "expected 0, got %u\n", rgn.data.rdh.nCount);
ok(rgn.data.rdh.nRgnSize == 0, "expected 0, got %u\n", rgn.data.rdh.nRgnSize);
ok(rgn.data.rdh.nCount == 0, "expected 0, got %lu\n", rgn.data.rdh.nCount);
ok(rgn.data.rdh.nRgnSize == 0, "expected 0, got %lu\n", rgn.data.rdh.nRgnSize);
}
else
{
ok(rgn.data.rdh.nCount == 1, "expected 1, got %u\n", rgn.data.rdh.nCount);
ok(rgn.data.rdh.nRgnSize == sizeof(RECT), "expected sizeof(RECT), got %u\n", rgn.data.rdh.nRgnSize);
ok(rgn.data.rdh.nCount == 1, "expected 1, got %lu\n", rgn.data.rdh.nCount);
ok(rgn.data.rdh.nRgnSize == sizeof(RECT), "expected sizeof(RECT), got %lu\n", rgn.data.rdh.nRgnSize);
}
ok(EqualRect(&rgn.data.rdh.rcBound, rc), "expected %s, got %s\n",
wine_dbgstr_rect(rc), wine_dbgstr_rect(&rgn.data.rdh.rcBound));
@@ -142,11 +146,11 @@ static void test_region_data(DWORD *data, UINT size, INT line)
for (i = 0; i < size - 1; i++)
{
if (i == 1) continue; /* data[1] never matches */
ok_(__FILE__, line)(data[i] == buf[i], "off %u: %#x != %#x\n", i, data[i], buf[i]);
ok_(__FILE__, line)(data[i] == buf[i], "off %u: %#lx != %#lx\n", i, data[i], buf[i]);
}
/* some Windows versions fail to properly clear the aligned DWORD */
ok_(__FILE__, line)(data[size - 1] == buf[size - 1] || broken(data[size - 1] != buf[size - 1]),
"off %u: %#x != %#x\n", size - 1, data[size - 1], buf[size - 1]);
"off %u: %#lx != %#lx\n", size - 1, data[size - 1], buf[size - 1]);
GdipDeleteRegion(region);
}
@@ -187,7 +191,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(20, needed);
expect_dword(buf, 12);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
@@ -205,7 +209,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(20, needed);
expect_dword(buf, 12);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_EMPTY_RECT);
@@ -223,7 +227,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(20, needed);
expect_dword(buf, 12);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
@@ -248,7 +252,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(36, needed);
expect_dword(buf, 28);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_RECT);
@@ -304,7 +308,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(156, needed);
expect_dword(buf, 148);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 10);
expect_dword(buf + 4, CombineModeExclude);
@@ -367,7 +371,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(72, needed);
expect_dword(buf, 64);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -402,7 +406,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(96, needed);
expect_dword(buf, 88);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 2);
expect_dword(buf + 4, CombineModeIntersect);
@@ -447,7 +451,7 @@ static void test_getregiondata(void)
expect(Ok, status);
expect(36, needed);
expect_dword(buf, 28);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -457,7 +461,7 @@ static void test_getregiondata(void)
expect_dword(buf + 7, 0);
/* flags 0 means that a path is an array of FLOATs */
ok(*(buf + 8) == 0x4000 /* before win7 */ || *(buf + 8) == 0,
"expected 0x4000 or 0, got %08x\n", *(buf + 8));
"expected 0x4000 or 0, got %08lx\n", *(buf + 8));
expect_dword(buf + 10, 0xeeeeeeee);
test_region_data(buf, needed, __LINE__);
@@ -489,7 +493,7 @@ static void test_getregiondata(void)
expect(Ok, status);
expect(56, needed);
expect_dword(buf, 48);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3 , 0);
expect_dword(buf + 4 , RGNDATA_PATH);
@@ -563,7 +567,7 @@ static void test_getregiondata(void)
expect(Ok, status);
expect(72, needed);
expect_dword(buf, 64);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -614,7 +618,7 @@ static void test_getregiondata(void)
expect(Ok, status);
expect(116, needed);
expect_dword(buf, 108);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 2);
expect_dword(buf + 4, CombineModeUnion);
@@ -641,8 +645,8 @@ static void test_getregiondata(void)
expect_float(buf + 25, 50.0);
expect_float(buf + 26, 70.2);
expect_dword(buf + 27, 0x01010100);
ok(*(buf + 28) == 0x00000101 || *(buf + 28) == 0x43050101 /* Win 7 */,
"expected 00000101 or 43050101 got %08x\n", *(buf + 28));
ok((*(buf + 28) & 0xffff) == 0x0101,
"expected ????0101 got %08lx\n", *(buf + 28));
expect_dword(buf + 29, 0xeeeeeeee);
test_region_data(buf, needed, __LINE__);
@@ -668,7 +672,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(56, needed);
expect_dword(buf, 48);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -712,7 +716,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(72, needed);
expect_dword(buf, 64);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -758,7 +762,7 @@ static void test_getregiondata(void)
ok(status == Ok, "status %08x\n", status);
expect(136, needed);
expect_dword(buf, 128);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -791,9 +795,8 @@ static void test_getregiondata(void)
expect_float(buf + 30, 789.799561);
expect_dword(buf + 31, 0x03030300);
expect_dword(buf + 32, 0x03030301);
ok(*(buf + 33) == 0x00030303 /* before win7 */ ||
*(buf + 33) == 0x43030303 /* 32-bit win7 */ || *(buf + 33) == 0x4c030303 /* 64-bit win7 */,
"expected 0x00030303 or 0x43030303 or 0x4c030303 got %08x\n", *(buf + 33));
ok((*(buf + 33) & 0xffffff) == 0x030303,
"expected 0x??030303 got %08lx\n", *(buf + 33));
expect_dword(buf + 34, 0xeeeeeeee);
test_region_data(buf, needed, __LINE__);
@@ -921,7 +924,7 @@ static void test_combinereplace(void)
expect(Ok, status);
expect(36, needed);
expect_dword(buf, 28);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_RECT);
@@ -941,7 +944,7 @@ static void test_combinereplace(void)
expect(Ok, status);
expect(156, needed);
expect_dword(buf, 148);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_PATH);
@@ -960,7 +963,7 @@ static void test_combinereplace(void)
expect(Ok, status);
expect(20, needed);
expect_dword(buf, 12);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 0);
expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
@@ -987,7 +990,7 @@ static void test_combinereplace(void)
expect(Ok, status);
expect(180, needed);
expect_dword(buf, 172);
trace("buf[1] = %08x\n", buf[1]);
trace("buf[1] = %08lx\n", buf[1]);
expect_magic(buf + 2);
expect_dword(buf + 3, 2);
expect_dword(buf + 4, CombineModeUnion);
@@ -1446,14 +1449,14 @@ static void test_translate(void)
static DWORD get_region_type(GpRegion *region)
{
DWORD *data;
DWORD size;
UINT size;
DWORD result;
DWORD status;
status = GdipGetRegionDataSize(region, &size);
expect(Ok, status);
data = GdipAlloc(size);
status = GdipGetRegionData(region, (BYTE*)data, size, NULL);
ok(status == Ok || status == InsufficientBuffer, "unexpected status 0x%x\n", status);
ok(status == Ok || status == InsufficientBuffer, "unexpected status 0x%lx\n", status);
result = data[4];
GdipFree(data);
return result;
@@ -1594,7 +1597,7 @@ static void test_scans(void)
GpMatrix *matrix;
GpRectF rectf;
GpStatus status;
ULONG count=80085;
UINT count=80085;
INT icount;
GpRectF scans[2];
GpRect scansi[2];
@@ -1729,6 +1732,7 @@ static void test_scans(void)
static void test_getbounds(void)
{
GpRegion *region;
GpPath *path;
GpGraphics *graphics;
GpStatus status;
GpRectF rectf;
@@ -1804,6 +1808,44 @@ static void test_getbounds(void)
ok(rectf.Width == 100.0, "Expected width = 0.0, got %.2f\n", rectf.Width);
ok(rectf.Height == 100.0, "Expected height = 0.0, got %.2f\n", rectf.Height);
/* coordinates are not rounded */
status = GdipResetWorldTransform(graphics);
ok(status == Ok, "status %08x\n", status);
status = GdipResetPageTransform(graphics);
ok(status == Ok, "status %08x\n", status);
rectf.X = 0.125;
rectf.Y = 1.125;
rectf.Width = 2.125;
rectf.Height = 3.125;
status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
ok(status == Ok, "status %08x\n", status);
rectf.X = rectf.Y = 0.0;
rectf.Height = rectf.Width = 0.0;
status = GdipGetRegionBounds(region, graphics, &rectf);
ok(status == Ok, "status %08x\n", status);
ok(rectf.X == 0.125, "Expected X = 0.0, got %.2f\n", rectf.X);
ok(rectf.Y == 1.125, "Expected Y = 0.0, got %.2f\n", rectf.Y);
ok(rectf.Width == 2.125, "Expected width = 0.0, got %.2f\n", rectf.Width);
ok(rectf.Height == 3.125, "Expected height = 0.0, got %.2f\n", rectf.Height);
/* test path */
status = GdipCreatePath(FillModeAlternate, &path);
ok(status == Ok, "status %08x\n", status);
status = GdipAddPathRectangle(path, 0.125, 1.125, 2.125, 3.125);
ok(status == Ok, "status %08x\n", status);
status = GdipCombineRegionPath(region, path, CombineModeReplace);
ok(status == Ok, "status %08x\n", status);
status = GdipDeletePath(path);
ok(status == Ok, "status %08x\n", status);
rectf.X = rectf.Y = 0.0;
rectf.Height = rectf.Width = 0.0;
status = GdipGetRegionBounds(region, graphics, &rectf);
ok(status == Ok, "status %08x\n", status);
ok(rectf.X == 0.125, "Expected X = 0.0, got %.2f\n", rectf.X);
ok(rectf.Y == 1.125, "Expected Y = 0.0, got %.2f\n", rectf.Y);
ok(rectf.Width == 2.125, "Expected width = 0.0, got %.2f\n", rectf.Width);
ok(rectf.Height == 3.125, "Expected height = 0.0, got %.2f\n", rectf.Height);
status = GdipDeleteRegion(region);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteGraphics(graphics);
@@ -2330,6 +2372,204 @@ static void test_GdipCreateRegionRgnData(void)
ReleaseDC(0, hdc);
}
static void test_incombinedregion(void)
{
struct testrgn
{
const char* desc;
BOOL origin_in_region;
GpRegion *region;
};
struct testrgn test_regions[] = {
{ "infinite region", TRUE },
{ "infinite region inverted", FALSE },
{ "empty region", FALSE },
{ "empty region inverted", TRUE },
{ "inside rectangle", TRUE },
{ "inside rectangle inverted", FALSE },
{ "outside rectangle", FALSE },
{ "outside rectangle inverted", TRUE },
{ "inside path", TRUE },
{ "inside path inverted", FALSE },
{ "outside path but in bounding rect", FALSE },
{ "outside path but in bounding rect inverted", TRUE },
{ "outside path", FALSE },
{ "outside path inverted", TRUE },
};
GpStatus stat;
GpRectF rect;
const GpPointF inside_path_points[] = { { -1, -2 }, { 2, 1 }, { -1, 1 } };
const GpPointF outside_path_bounding_points[] = { { -2, -1 }, { 1, 2 }, { -2, 2 } };
const GpPointF outside_path_points[] = { { 5, 5 }, { 5, 10 }, { 10, 10 } };
GpPath *path;
int i, j;
BOOL in_region;
/* Prepare test regions: */
/* infinite */
stat = GdipCreateRegion(&test_regions[0].region);
expect(Ok, stat);
/* empty */
stat = GdipCreateRegion(&test_regions[2].region);
expect(Ok, stat);
stat = GdipSetEmpty(test_regions[2].region);
expect(Ok, stat);
/* inside rectangle */
rect.X = -5;
rect.Y = -2;
rect.Width = 10;
rect.Height = 4;
stat = GdipCreateRegionRect(&rect, &test_regions[4].region);
expect(Ok, stat);
/* outside rectangle */
rect.X = -10;
rect.Y = -10;
rect.Width = 7;
rect.Height = 7;
stat = GdipCreateRegionRect(&rect, &test_regions[6].region);
expect(Ok, stat);
/* inside path */
stat = GdipCreatePath(FillModeAlternate, &path);
expect(Ok, stat);
stat = GdipAddPathPolygon(path, inside_path_points, ARRAY_SIZE(inside_path_points));
expect(Ok, stat);
stat = GdipCreateRegion(&test_regions[8].region);
expect(Ok, stat);
stat = GdipCombineRegionPath(test_regions[8].region, path, CombineModeReplace);
expect(Ok, stat);
stat = GdipDeletePath(path);
expect(Ok, stat);
/* outside path but in bounding rect */
stat = GdipCreatePath(FillModeAlternate, &path);
expect(Ok, stat);
stat = GdipAddPathPolygon(path, outside_path_bounding_points, ARRAY_SIZE(outside_path_bounding_points));
expect(Ok, stat);
stat = GdipCreateRegion(&test_regions[10].region);
expect(Ok, stat);
stat = GdipCombineRegionPath(test_regions[10].region, path, CombineModeReplace);
expect(Ok, stat);
stat = GdipDeletePath(path);
expect(Ok, stat);
/* outside path */
stat = GdipCreatePath(FillModeAlternate, &path);
expect(Ok, stat);
stat = GdipAddPathPolygon(path, outside_path_points, ARRAY_SIZE(outside_path_points));
expect(Ok, stat);
stat = GdipCreateRegion(&test_regions[12].region);
expect(Ok, stat);
stat = GdipCombineRegionPath(test_regions[12].region, path, CombineModeReplace);
expect(Ok, stat);
stat = GdipDeletePath(path);
expect(Ok, stat);
for (i = 1; i < ARRAY_SIZE(test_regions); i += 2)
{
winetest_push_context("%s", test_regions[i].desc);
stat = GdipCreateRegion(&test_regions[i].region);
expect(Ok, stat);
stat = GdipCombineRegionRegion(test_regions[i].region, test_regions[i-1].region, CombineModeExclude);
expect(Ok, stat);
winetest_pop_context();
}
/* Check regions individually */
for (i = 0; i < ARRAY_SIZE(test_regions); i++)
{
winetest_push_context("%s", test_regions[i].desc);
stat = GdipIsVisibleRegionPoint(test_regions[i].region, 0, 0, NULL, &in_region);
expect(Ok, stat);
expect(test_regions[i].origin_in_region, in_region);
winetest_pop_context();
}
/* Check combined regions */
for (i = 0; i < ARRAY_SIZE(test_regions); i++)
{
for (j = 0; j < ARRAY_SIZE(test_regions); j++)
{
GpRegion *region;
BOOL expected_result;
winetest_push_context("%s + %s", test_regions[i].desc, test_regions[j].desc);
stat = GdipCreateRegion(&region);
expect(Ok, stat);
/* CombineModeIntersect */
stat = GdipCombineRegionRegion(region, test_regions[i].region, CombineModeReplace);
expect(Ok, stat);
stat = GdipCombineRegionRegion(region, test_regions[j].region, CombineModeIntersect);
expect(Ok, stat);
expected_result = test_regions[i].origin_in_region & test_regions[j].origin_in_region;
stat = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &in_region);
expect(Ok, stat);
ok(expected_result == in_region, "CombineModeIntersect: expected %i, got %i\n", expected_result, in_region);
/* CombineModeUnion */
stat = GdipCombineRegionRegion(region, test_regions[i].region, CombineModeReplace);
expect(Ok, stat);
stat = GdipCombineRegionRegion(region, test_regions[j].region, CombineModeUnion);
expect(Ok, stat);
expected_result = test_regions[i].origin_in_region | test_regions[j].origin_in_region;
stat = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &in_region);
expect(Ok, stat);
ok(expected_result == in_region, "CombineModeUnion: expected %i, got %i\n", expected_result, in_region);
/* CombineModeXor */
stat = GdipCombineRegionRegion(region, test_regions[i].region, CombineModeReplace);
expect(Ok, stat);
stat = GdipCombineRegionRegion(region, test_regions[j].region, CombineModeXor);
expect(Ok, stat);
expected_result = test_regions[i].origin_in_region ^ test_regions[j].origin_in_region;
stat = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &in_region);
expect(Ok, stat);
ok(expected_result == in_region, "CombineModeXor: expected %i, got %i\n", expected_result, in_region);
/* CombineModeExclude */
stat = GdipCombineRegionRegion(region, test_regions[i].region, CombineModeReplace);
expect(Ok, stat);
stat = GdipCombineRegionRegion(region, test_regions[j].region, CombineModeExclude);
expect(Ok, stat);
expected_result = test_regions[i].origin_in_region & !test_regions[j].origin_in_region;
stat = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &in_region);
expect(Ok, stat);
ok(expected_result == in_region, "CombineModeExclude: expected %i, got %i\n", expected_result, in_region);
/* CombineModeComplement */
stat = GdipCombineRegionRegion(region, test_regions[i].region, CombineModeReplace);
expect(Ok, stat);
stat = GdipCombineRegionRegion(region, test_regions[j].region, CombineModeComplement);
expect(Ok, stat);
expected_result = (!test_regions[i].origin_in_region) & test_regions[j].origin_in_region;
stat = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &in_region);
expect(Ok, stat);
ok(expected_result == in_region, "CombineModeComplement: expected %i, got %i\n", expected_result, in_region);
winetest_pop_context();
}
}
for (i = 0; i < ARRAY_SIZE(test_regions); i++)
{
stat = GdipDeleteRegion(test_regions[i].region);
expect(Ok, stat);
}
}
START_TEST(region)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -2364,6 +2604,7 @@ START_TEST(region)
test_isvisiblerect();
test_excludeinfinite();
test_GdipCreateRegionRgnData();
test_incombinedregion();
GdiplusShutdown(gdiplusToken);
}
@@ -20,3 +20,14 @@
/* @makedep: wine_longname.ttf */
1 RCDATA wine_longname.ttf
/* @makedep: wine_testfont0.ttf */
2 RCDATA wine_testfont0.ttf
/* Generated with: fonttools ttx wine_mac_win.ttx */
/* @makedep: wine_mac_win.ttf */
3 RCDATA wine_mac_win.ttf
/* Generated with: fonttools ttx wine_unicode_mac.ttx */
/* @makedep: wine_unicode_mac.ttf */
4 RCDATA wine_unicode_mac.ttf
Binary file not shown.