Commit 065fbd20 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

gdi32: Improve EMR_CREATEDIBPATTERNBRUSHPT playback.

It makes the lbHatch data available after PlayEnhMetaFileRecord returns.
parent 37628a77
...@@ -1825,7 +1825,6 @@ BOOL WINAPI PlayEnhMetaFileRecord( ...@@ -1825,7 +1825,6 @@ BOOL WINAPI PlayEnhMetaFileRecord(
case EMR_CREATEDIBPATTERNBRUSHPT: case EMR_CREATEDIBPATTERNBRUSHPT:
{ {
const EMRCREATEDIBPATTERNBRUSHPT *lpCreate = (const EMRCREATEDIBPATTERNBRUSHPT *)mr; const EMRCREATEDIBPATTERNBRUSHPT *lpCreate = (const EMRCREATEDIBPATTERNBRUSHPT *)mr;
LPVOID lpPackedStruct;
/* Check that offsets and data are contained within the record /* Check that offsets and data are contained within the record
* (including checking for wrap-arounds). * (including checking for wrap-arounds).
...@@ -1839,28 +1838,15 @@ BOOL WINAPI PlayEnhMetaFileRecord( ...@@ -1839,28 +1838,15 @@ BOOL WINAPI PlayEnhMetaFileRecord(
break; break;
} }
/* This is a BITMAPINFO struct followed directly by bitmap bits */ if (lpCreate->offBmi + lpCreate->cbBmi != lpCreate->offBits)
lpPackedStruct = HeapAlloc( GetProcessHeap(), 0,
lpCreate->cbBmi + lpCreate->cbBits );
if(!lpPackedStruct)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); ERR("Invalid data in EMR_CREATEDIBPATTERNBRUSHPT record\n");
break; break;
} }
/* Now pack this structure */
memcpy( lpPackedStruct,
((const BYTE *)lpCreate) + lpCreate->offBmi,
lpCreate->cbBmi );
memcpy( ((BYTE*)lpPackedStruct) + lpCreate->cbBmi,
((const BYTE *)lpCreate) + lpCreate->offBits,
lpCreate->cbBits );
(handletable->objectHandle)[lpCreate->ihBrush] = (handletable->objectHandle)[lpCreate->ihBrush] =
CreateDIBPatternBrushPt( lpPackedStruct, CreateDIBPatternBrushPt( (const BYTE *)lpCreate + lpCreate->offBmi,
(UINT)lpCreate->iUsage ); (UINT)lpCreate->iUsage );
HeapFree(GetProcessHeap(), 0, lpPackedStruct);
break; break;
} }
......
...@@ -4183,6 +4183,38 @@ static void test_mf_PatternBrush(void) ...@@ -4183,6 +4183,38 @@ static void test_mf_PatternBrush(void)
HeapFree (GetProcessHeap(), 0, orig_lb); HeapFree (GetProcessHeap(), 0, orig_lb);
} }
static int CALLBACK pattern_brush_emf_enum_proc(HDC hdc, HANDLETABLE *htable,
const ENHMETARECORD *rec, int n, LPARAM arg)
{
LOGBRUSH brush;
BOOL ret;
switch (rec->iType)
{
case EMR_HEADER:
case EMR_SELECTOBJECT:
case EMR_EOF:
case EMR_CREATEMONOBRUSH:
return 1;
case EMR_CREATEDIBPATTERNBRUSHPT:
ok(!htable->objectHandle[2], "objectHandle[2] already used\n");
ret = PlayEnhMetaFileRecord(hdc, htable, rec, n);
ok(ret, "PlayEnhMetaFileRecord failed\n");
ok(htable->objectHandle[2] != NULL, "objectHandle[2] not created\n");
ret = GetObjectW(htable->objectHandle[2], sizeof(brush), &brush);
ok(ret, "GetObjectW failed\n");
ok(brush.lbStyle == BS_DIBPATTERN, "brush.lbStyle = %d\n", brush.lbStyle);
ok(brush.lbHatch > (ULONG_PTR)rec && brush.lbHatch < (ULONG_PTR)rec + rec->nSize,
"brush.lbHatch = %p, not in %p-%p range\n",
(void *)brush.lbHatch, rec, (const BYTE *)rec + rec->nSize);
return 1;
default:
ok(0, "unexpected record %lu\n", rec->iType);
return 0;
}
}
static void test_emf_pattern_brush(void) static void test_emf_pattern_brush(void)
{ {
char buffer[sizeof(BITMAPINFOHEADER) + (2 + 32 * 32 / 8) * sizeof(RGBQUAD)]; char buffer[sizeof(BITMAPINFOHEADER) + (2 + 32 * 32 / 8) * sizeof(RGBQUAD)];
...@@ -4237,8 +4269,6 @@ static void test_emf_pattern_brush(void) ...@@ -4237,8 +4269,6 @@ static void test_emf_pattern_brush(void)
dump_emf_records(emf, "emf_pattern_brush"); dump_emf_records(emf, "emf_pattern_brush");
} }
ret = DeleteEnhMetaFile(emf);
ok(ret, "DeleteMetaFile error %ld\n", GetLastError());
ret = DeleteObject(bitmap_brush); ret = DeleteObject(bitmap_brush);
ok(ret, "DeleteObject failed\n"); ok(ret, "DeleteObject failed\n");
ret = DeleteObject(dib_brush); ret = DeleteObject(dib_brush);
...@@ -4246,6 +4276,11 @@ static void test_emf_pattern_brush(void) ...@@ -4246,6 +4276,11 @@ static void test_emf_pattern_brush(void)
ret = DeleteObject((HBITMAP)orig_lb->lbHatch); ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
ok(ret, "DeleteObject failed\n"); ok(ret, "DeleteObject failed\n");
HeapFree(GetProcessHeap(), 0, orig_lb); HeapFree(GetProcessHeap(), 0, orig_lb);
ret = EnumEnhMetaFile(NULL, emf, pattern_brush_emf_enum_proc, NULL, NULL);
ok(ret, "EnumEnhMetaFile error %ld\n", GetLastError());
ret = DeleteEnhMetaFile(emf);
ok(ret, "DeleteMetaFile error %ld\n", GetLastError());
} }
static void test_mf_palette_brush(void) static void test_mf_palette_brush(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment