gdiplus: Write FillRects records to metafiles.

This commit is contained in:
Vincent Povirk 2013-11-20 16:50:51 -06:00 committed by Alexandre Julliard
parent 8babdc860a
commit c491d52821
3 changed files with 103 additions and 0 deletions

View File

@ -57,6 +57,8 @@ extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLS
extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN;
extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN;
extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
extern MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf) DECLSPEC_HIDDEN;

View File

@ -3858,6 +3858,13 @@ GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics *graphics, GpBrush *brush, GDI
if(!rects)
return InvalidParameter;
if (graphics->image && graphics->image->type == ImageTypeMetafile)
{
status = METAFILE_FillRectangles((GpMetafile*)graphics->image, brush, rects, count);
/* FIXME: Add gdi32 drawing. */
return status;
}
status = GdipCreatePath(FillModeAlternate, &path);
if (status != Ok) return status;

View File

@ -57,6 +57,21 @@ typedef struct EmfPlusHeader
DWORD LogicalDpiY;
} EmfPlusHeader;
typedef struct EmfPlusFillRects
{
EmfPlusRecordHeader Header;
DWORD BrushID;
DWORD Count;
} EmfPlusFillRects;
typedef struct EmfPlusRect
{
SHORT X;
SHORT Y;
SHORT Width;
SHORT Height;
} EmfPlusRect;
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
{
DWORD size_needed;
@ -316,6 +331,85 @@ GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc)
return Ok;
}
static BOOL is_integer_rect(const GpRectF *rect)
{
SHORT x, y, width, height;
x = rect->X;
y = rect->Y;
width = rect->Width;
height = rect->Height;
if (rect->X != (REAL)x || rect->Y != (REAL)y ||
rect->Width != (REAL)width || rect->Height != (REAL)height)
return FALSE;
return TRUE;
}
GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
GDIPCONST GpRectF* rects, INT count)
{
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
{
EmfPlusFillRects *record;
GpStatus stat;
BOOL integer_rects=1;
int i;
DWORD brushid;
int flags = 0;
if (brush->bt == BrushTypeSolidColor)
{
flags |= 0x8000;
brushid = ((GpSolidFill*)brush)->color;
}
else
{
FIXME("brush serialization not implemented\n");
return NotImplemented;
}
for (i=0; i<count; i++)
{
if (!is_integer_rect(&rects[i]))
{
integer_rects = 0;
break;
}
}
if (integer_rects)
flags |= 0x4000;
stat = METAFILE_AllocateRecord(metafile,
sizeof(EmfPlusFillRects) + count * (integer_rects ? sizeof(EmfPlusRect) : sizeof(GpRectF)),
(void**)&record);
if (stat != Ok)
return stat;
record->Header.Type = EmfPlusRecordTypeFillRects;
record->Header.Flags = flags;
record->BrushID = brushid;
record->Count = count;
if (integer_rects)
{
EmfPlusRect *record_rects = (EmfPlusRect*)(record+1);
for (i=0; i<count; i++)
{
record_rects[i].X = (SHORT)rects[i].X;
record_rects[i].Y = (SHORT)rects[i].Y;
record_rects[i].Width = (SHORT)rects[i].Width;
record_rects[i].Height = (SHORT)rects[i].Height;
}
}
else
memcpy(record+1, rects, sizeof(GpRectF) * count);
METAFILE_WriteRecords(metafile);
}
return Ok;
}
GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc)
{
if (hdc != metafile->record_dc)