Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/tests/brush.c | 222 +++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+)
diff --git a/dlls/gdiplus/tests/brush.c b/dlls/gdiplus/tests/brush.c index b8067c735c..35f99524b0 100644 --- a/dlls/gdiplus/tests/brush.c +++ b/dlls/gdiplus/tests/brush.c @@ -1634,6 +1634,226 @@ static void test_getHatchStyle(void) GdipDeleteBrush((GpBrush *)brush); }
+static void test_hatchBrushStyles(void) +{ + static const struct + { + short pattern[8]; + GpHatchStyle hs; + BOOL todo; + } + styles[] = + { + { {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff}, HatchStyleHorizontal, TRUE }, + { {0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000}, HatchStyleVertical, TRUE }, + { {0x4006, 0x0019, 0x0064, 0x0190, 0x0640, 0x1900, 0x6400, 0x9001}, HatchStyleForwardDiagonal, TRUE }, + { {0x9001, 0x6400, 0x1900, 0x0640, 0x0190, 0x0064, 0x0019, 0x4006}, HatchStyleBackwardDiagonal, TRUE }, + { {0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xc000, 0xffff}, HatchStyleCross, TRUE }, + { {0x9006, 0x6419, 0x1964, 0x0690, 0x0690, 0x1964, 0x6419, 0x9006}, HatchStyleDiagonalCross, TRUE }, + { {0x0000, 0x0000, 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0xc000}, HatchStyle05Percent }, + { {0x0000, 0x00c0, 0x0000, 0xc000, 0x0000, 0x00c0, 0x0000, 0xc000}, HatchStyle10Percent, TRUE }, + { {0x0000, 0x0c0c, 0x0000, 0xc0c0, 0x0000, 0x0c0c, 0x0000, 0xc0c0}, HatchStyle20Percent, TRUE }, + { {0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0, 0x0c0c, 0xc0c0}, HatchStyle25Percent, TRUE }, + { {0x0303, 0xcccc, 0x3030, 0xcccc, 0x0303, 0xcccc, 0x3030, 0xcccc}, HatchStyle30Percent, TRUE }, + { {0x0333, 0xcccc, 0x3333, 0xcccc, 0x3303, 0xcccc, 0x3333, 0xcccc}, HatchStyle40Percent, TRUE }, + { {0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc}, HatchStyle50Percent, TRUE }, + { {0x3333, 0xcfcf, 0x3333, 0xfcfc, 0x3333, 0xcfcf, 0x3333, 0xfcfc}, HatchStyle60Percent, TRUE }, + { {0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f, 0xf3f3, 0x3f3f}, HatchStyle70Percent, TRUE }, + { {0xffff, 0xf3f3, 0xffff, 0x3f3f, 0xffff, 0xf3f3, 0xffff, 0x3f3f}, HatchStyle75Percent, TRUE }, + { {0xffff, 0xfffc, 0xffff, 0xfcff, 0xffff, 0xfffc, 0xffff, 0xfcff}, HatchStyle80Percent, TRUE }, + { {0x3fff, 0xffff, 0xffff, 0xffff, 0xff3f, 0xffff, 0xffff, 0xffff}, HatchStyle90Percent, TRUE }, + { {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, TRUE }, + { {0xc00f, 0x003f, 0x00fc, 0x03f0, 0x0fc0, 0x3f00, 0xfc00, 0xf003}, HatchStyleWideDownwardDiagonal, TRUE }, + { {0xf003, 0xfc00, 0x3f00, 0x0fc0, 0x03f0, 0x00fc, 0x003f, 0xc00f}, HatchStyleWideUpwardDiagonal, TRUE }, + { {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, TRUE }, + { {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, TRUE }, + { {0x0000, 0x0000, 0xc0c0, 0x3030, 0x0c0c, 0x0303, 0x0000, 0x0000}, HatchStyleDashedUpwardDiagonal, TRUE }, + { {0x0000, 0x0000, 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0xff00}, HatchStyleDashedHorizontal, TRUE }, + { {0x00c0, 0x00c0, 0x00c0, 0x00c0, 0xc000, 0xc000, 0xc000, 0xc000}, HatchStyleDashedVertical, TRUE }, + { {0x0030, 0x0c00, 0x0003, 0x0300, 0x000c, 0x3000, 0x00c0, 0xc000}, HatchStyleSmallConfetti, TRUE }, + { {0xc0f3, 0x00f0, 0xf000, 0xf3c0, 0x03cf, 0x000f, 0x0f00, 0xcf03}, HatchStyleLargeConfetti, TRUE }, + { {0x03c0, 0x0c30, 0x300c, 0xc003, 0x03c0, 0x0c30, 0x300c, 0xc003}, HatchStyleZigZag, TRUE }, + { {0xf000, 0x0c33, 0x03c0, 0x0000, 0xf000, 0x0c33, 0x03c0, 0x0000}, HatchStyleWave, TRUE }, + { {0xc003, 0x300c, 0x0c30, 0x03c0, 0x00c0, 0x0030, 0x000c, 0x0003}, HatchStyleDiagonalBrick, TRUE }, + { {0x00c0, 0x00c0, 0x00c0, 0xffff, 0xc000, 0xc000, 0xc000, 0xffff}, HatchStyleHorizontalBrick, TRUE }, + { {0x3303, 0x0c0c, 0x0330, 0xc0c0, 0x3033, 0x0c0c, 0x3330, 0xc0c0}, HatchStyleWeave, TRUE }, + { {0xff00, 0xff00, 0xff00, 0xff00, 0x3333, 0xcccc, 0x3333, 0xcccc}, HatchStylePlaid, TRUE }, + { {0xc000, 0x0003, 0xc000, 0x0000, 0x0300, 0x00c0, 0x0300, 0x0000}, HatchStyleDivot, TRUE }, + { {0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xcccc}, HatchStyleDottedGrid, TRUE }, + { {0x0000, 0x0c0c, 0x0000, 0x00c0, 0x0000, 0x0c0c, 0x0000, 0xc000}, HatchStyleDottedDiamond, TRUE }, + { {0x0003, 0x0003, 0x000c, 0x00f0, 0x0f00, 0x30c0, 0xc030, 0x000f}, HatchStyleShingle, TRUE }, + { {0xc3c3, 0xffff, 0x3c3c, 0xffff, 0xc3c3, 0xffff, 0x3c3c, 0xffff}, HatchStyleTrellis, TRUE }, + { {0xffc0, 0xffc0, 0xc3c0, 0x3f3f, 0xc0ff, 0xc0ff, 0xc0c3, 0x3f3f}, HatchStyleSphere, TRUE }, + { {0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff}, HatchStyleSmallGrid, TRUE }, + { {0xc3c3, 0x3c3c, 0x3c3c, 0xc3c3, 0xc3c3, 0x3c3c, 0x3c3c, 0xc3c3}, HatchStyleSmallCheckerBoard, TRUE }, + { {0x00ff, 0x00ff, 0x00ff, 0x00ff, 0xff00, 0xff00, 0xff00, 0xff00}, HatchStyleLargeCheckerBoard, TRUE }, + { {0x0003, 0xc00c, 0x3030, 0x0cc0, 0x0300, 0x0cc0, 0x3030, 0xc00c}, HatchStyleOutlinedDiamond, TRUE }, + { {0x0000, 0x0300, 0x0fc0, 0x3ff0, 0xfffc, 0x3ff0, 0x0fc0, 0x0300}, HatchStyleSolidDiamond, TRUE }, + }; + static const ARGB colors[] = { 0xffffffff, 0xffbfbfbf, 0xff151515, 0xff000000 }; + static const int width = 16, height = 16; + GpStatus status; + GpGraphics *graphics; + GpBitmap *bitmap; + GpHatch *brush = NULL; + BOOL match; + int x, y; + int i; + + status = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppRGB, NULL, &bitmap); + expect(Ok, status); + status = GdipGetImageGraphicsContext((GpImage *)bitmap, &graphics); + expect(Ok, status); + ok(graphics != NULL, "Expected the graphics context to be initialized.\n"); + status = GdipSetCompositingMode(graphics, CompositingModeSourceCopy); + expect(Ok, status); + + for (i = 0; i < ARRAY_SIZE(styles); i++) + { + status = GdipCreateHatchBrush(styles[i].hs, colors[3], colors[0], &brush); + expect(Ok, status); + ok(brush != NULL, "Expected the brush to be initialized.\n"); + status = GdipFillRectangleI(graphics, (GpBrush *)brush, 0, 0, width, height); + expect(Ok, status); + status = GdipDeleteBrush((GpBrush *)brush); + expect(Ok, status); + brush = NULL; + + match = TRUE; + for(y = 0; y < width && match; y++) + { + for(x = 0; x < height && match; x++) + { + ARGB color; + int cindex = (styles[i].pattern[7-(y%8)] >> (2*(7-(x%8)))) & 3; + + GdipBitmapGetPixel(bitmap, x, y, &color); + if (color != colors[cindex]) + match = FALSE; + } + } + todo_wine_if(styles[i].todo) ok(match, "Unexpected pattern for hatch style %#x.\n", styles[i].hs); + } + + status = GdipDeleteGraphics(graphics); + expect(Ok, status); + status = GdipDisposeImage((GpImage*)bitmap); + expect(Ok, status); +} + +static void test_hatchBrushColors(void) +{ + /* Foreground color, background color, + * resulting 4 colors with non-alpha surface, + * resulting 4 colors with alpha surface + */ + static const ARGB colors[][10] = { + { 0xff000000, 0xffffffff, + 0xffffffff, 0xffbfbfbf, 0xff151515, 0xff000000, + 0xffffffff, 0xffbfbfbf, 0xff151515, 0xff000000 }, + { 0xffffffff, 0xff000000, + 0xff000000, 0xff3f3f3f, 0xffe9e9e9, 0xffffffff, + 0xff000000, 0xff3f3f3f, 0xffe9e9e9, 0xffffffff }, + { 0xffd2d2d2, 0xff000000, + 0xff000000, 0xff343434, 0xffbfbfbf, 0xffd2d2d2, + 0xff000000, 0xff343434, 0xffbfbfbf, 0xffd2d2d2 }, + { 0xfefbfbfb, 0x00070707, + 0xff000000, 0xff3e3e3e, 0xffe4e4e4, 0xfffafafa, + 0x00000000, 0x3ffafafa, 0xe8fafafa, 0xfefafafa }, + }; + static const int width = 16, height = 8; + static const int pixel_coord[][2] = { + {12, 1}, {1, 0}, {0, 0}, {8, 0} + }; + HDC hdc; + GpStatus status; + GpGraphics *graphics_hdc; + GpGraphics *graphics_image; + GpGraphics *graphics_image_a; + GpBitmap *bitmap; + GpBitmap *bitmap_a; + GpHatch *brush_diag_cross; + GpHatch *brush_cross; + int i, j; + + hdc = GetDC(hwnd); + status = GdipCreateFromHDC(hdc, &graphics_hdc); + expect(Ok, status); + status = GdipSetCompositingMode(graphics_hdc, CompositingModeSourceCopy); + expect(Ok, status); + + status = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppRGB, NULL, &bitmap); + expect(Ok, status); + status = GdipGetImageGraphicsContext((GpImage *)bitmap, &graphics_image); + expect(Ok, status); + status = GdipSetCompositingMode(graphics_image, CompositingModeSourceCopy); + expect(Ok, status); + + status = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppARGB, NULL, &bitmap_a); + expect(Ok, status); + status = GdipGetImageGraphicsContext((GpImage *)bitmap_a, &graphics_image_a); + expect(Ok, status); + status = GdipSetCompositingMode(graphics_image_a, CompositingModeSourceCopy); + expect(Ok, status); + + for (i = 0; i < ARRAY_SIZE(colors); i++) + { + status = GdipCreateHatchBrush(HatchStyleDiagonalCross, colors[i][0], colors[i][1], + &brush_diag_cross); + expect(Ok, status); + status = GdipCreateHatchBrush(HatchStyleCross, colors[i][0], colors[i][1], + &brush_cross); + expect(Ok, status); + + GdipFillRectangleI(graphics_hdc, (GpBrush *)brush_diag_cross, 0, 0, width/2, height); + GdipFillRectangleI(graphics_image, (GpBrush *)brush_diag_cross, 0, 0, width/2, height); + GdipFillRectangleI(graphics_image_a, (GpBrush *)brush_diag_cross, 0, 0, width/2, height); + GdipFillRectangleI(graphics_hdc, (GpBrush *)brush_cross, width/2, 0, width/2, height); + GdipFillRectangleI(graphics_image, (GpBrush *)brush_cross, width/2, 0, width/2, height); + GdipFillRectangleI(graphics_image_a, (GpBrush *)brush_cross, width/2, 0, width/2, height); + + GdipDeleteBrush((GpBrush *)brush_diag_cross); + GdipDeleteBrush((GpBrush *)brush_cross); + + for (j = 0; j < 4; j++) + { + ARGB color; + const ARGB exp_color = colors[i][j+2]; + const ARGB exp_color_a = colors[i][j+6]; + const int x = pixel_coord[j][0]; + const int y = pixel_coord[j][1]; + + color = 0xff000000 | GetPixel(hdc, x, y); + todo_wine ok(color == exp_color, "For hwnd (%d, %d) colorset %d expected %08x, got %08x.\n", + x, y, i, exp_color, color); + + GdipBitmapGetPixel(bitmap, x, y, &color); + todo_wine ok(color == exp_color, "For rgb image (%d, %d) colorset %d expected %08x, got %08x.\n", + x, y, i, exp_color, color); + + GdipBitmapGetPixel(bitmap_a, x, y, &color); + todo_wine ok(color == exp_color_a, "For argb image (%d, %d) colorset %d expected %08x, got %08x.\n", + x, y, i, exp_color_a, color); + } + } + + GdipDeleteGraphics(graphics_image); + GdipDeleteGraphics(graphics_image_a); + GdipDisposeImage((GpImage*)bitmap); + GdipDisposeImage((GpImage*)bitmap_a); + + ReleaseDC(hwnd, hdc); + GdipDeleteGraphics(graphics_hdc); +} + START_TEST(brush) { struct GdiplusStartupInput gdiplusStartupInput; @@ -1686,6 +1906,8 @@ START_TEST(brush) test_pathgradientpresetblend(); test_pathgradientblend(); test_getHatchStyle(); + test_hatchBrushStyles(); + test_hatchBrushColors();
GdiplusShutdown(gdiplusToken); DestroyWindow(hwnd);