diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 300e2507852..0fb2d99dcef 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -230,6 +230,8 @@ static DWORD emfdc_create_brush( struct emf *emf, HBRUSH brush ) emr->cbBits = info->bmiHeader.biSizeImage; emr->emr.nSize = emr->offBits + emr->cbBits; + if (info->bmiHeader.biClrUsed == 1 << info->bmiHeader.biBitCount) + info->bmiHeader.biClrUsed = 0; memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi ); get_brush_bitmap_info( brush, NULL, (char *)emr + emr->offBits, NULL ); diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index 5e10c654388..693353ea5f2 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -1459,6 +1459,69 @@ static const unsigned char EMF_GRADIENTFILL_BITS[] = 0x14, 0x00, 0x00, 0x00 }; +static const unsigned char emf_pattern_brush_bits[] = +{ + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe6, 0xff, 0xff, 0xff, 0xe5, 0xff, 0xff, 0xff, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0xd8, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x77, 0x07, 0x00, 0x00, 0x3b, 0x04, 0x00, 0x00, + 0xfa, 0x01, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0xb7, 0x07, 0x00, + 0x4f, 0x5f, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, + 0xd4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 +}; + static const unsigned char mf_palette_brush_bits[] = { 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0xb2, 0x03, @@ -3866,6 +3929,71 @@ static void test_mf_PatternBrush(void) HeapFree (GetProcessHeap(), 0, orig_lb); } +static void test_emf_pattern_brush(void) +{ + char buffer[sizeof(BITMAPINFOHEADER) + (2 + 32 * 32 / 8) * sizeof(RGBQUAD)]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + HDC hdc; + HENHMETAFILE emf; + LOGBRUSH *orig_lb; + HBRUSH bitmap_brush, dib_brush; + DWORD *bits; + unsigned int i; + BOOL ret; + + orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH)); + + orig_lb->lbStyle = BS_PATTERN; + orig_lb->lbColor = RGB(0, 0, 0); + orig_lb->lbHatch = (ULONG_PTR)CreateBitmap(8, 8, 1, 1, SAMPLE_PATTERN_BRUSH); + ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %d.\n", GetLastError()); + + bitmap_brush = CreateBrushIndirect(orig_lb); + ok(bitmap_brush != 0, "CreateBrushIndirect error %d\n", GetLastError()); + + hdc = CreateEnhMetaFileA(NULL, NULL, NULL, NULL); + ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError()); + + bitmap_brush = SelectObject(hdc, bitmap_brush); + ok(bitmap_brush != 0, "SelectObject error %d.\n", GetLastError()); + + memset(info, 0, sizeof(buffer)); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biHeight = 32; + info->bmiHeader.biWidth = 32; + info->bmiHeader.biBitCount = 1; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biCompression = BI_RGB; + bits = (DWORD *)info->bmiColors; + for (i = 0; i < 32 * 32 / 8; i++) bits[i] = i; + + dib_brush = CreateDIBPatternBrushPt(info, DIB_RGB_COLORS); + ok(dib_brush != NULL, "CreatePatternBrush failed\n"); + + dib_brush = SelectObject(hdc, dib_brush); + ok(dib_brush != 0, "SelectObject error %d.\n", GetLastError()); + + emf = CloseEnhMetaFile(hdc); + ok(emf != 0, "CloseEnhMetaFile error %d\n", GetLastError()); + + if (compare_emf_bits(emf, emf_pattern_brush_bits, sizeof(emf_pattern_brush_bits), + "emf_pattern_brush", FALSE)) + { + dump_emf_bits(emf, "emf_pattern_brush"); + dump_emf_records(emf, "emf_pattern_brush"); + } + + ret = DeleteEnhMetaFile(emf); + ok(ret, "DeleteMetaFile error %d\n", GetLastError()); + ret = DeleteObject(bitmap_brush); + ok(ret, "DeleteObject failed\n"); + ret = DeleteObject(dib_brush); + ok(ret, "DeleteObject failed\n"); + ret = DeleteObject((HBITMAP)orig_lb->lbHatch); + ok(ret, "DeleteObject failed\n"); + HeapFree(GetProcessHeap(), 0, orig_lb); +} + static void test_mf_palette_brush(void) { char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + 16 * 16]; @@ -7492,6 +7620,7 @@ START_TEST(metafile) test_emf_attrs(); test_emf_select(); test_emf_blit(); + test_emf_pattern_brush(); /* For win-format metafiles (mfdrv) */ test_mf_SaveDC();