gdiplus: Implement BeginContainer metafile record.
Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
18964c9665
commit
410163a9f2
|
@ -101,6 +101,8 @@ extern GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST
|
||||||
extern GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixOrder order) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixOrder order) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_TranslateWorldTransform(GpMetafile* metafile, REAL dx, REAL dy, MatrixOrder order) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_TranslateWorldTransform(GpMetafile* metafile, REAL dx, REAL dy, MatrixOrder order) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
||||||
|
extern GpStatus METAFILE_BeginContainer(GpMetafile* metafile, GDIPCONST GpRectF *dstrect,
|
||||||
|
GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_BeginContainerNoParams(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_BeginContainerNoParams(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_EndContainer(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_EndContainer(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_SaveGraphics(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_SaveGraphics(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -5236,7 +5236,7 @@ GpStatus WINGDIPAPI GdipBeginContainer(GpGraphics *graphics, GDIPCONST GpRectF *
|
||||||
GdipMultiplyMatrix(&graphics->worldtrans, &transform, MatrixOrderPrepend);
|
GdipMultiplyMatrix(&graphics->worldtrans, &transform, MatrixOrderPrepend);
|
||||||
|
|
||||||
if (graphics->image && graphics->image->type == ImageTypeMetafile) {
|
if (graphics->image && graphics->image->type == ImageTypeMetafile) {
|
||||||
FIXME("Write to metafile\n");
|
METAFILE_BeginContainer((GpMetafile*)graphics->image, dstrect, srcrect, unit, container->contid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
|
|
|
@ -122,6 +122,14 @@ typedef struct EmfPlusTranslateWorldTransform
|
||||||
REAL dy;
|
REAL dy;
|
||||||
} EmfPlusTranslateWorldTransform;
|
} EmfPlusTranslateWorldTransform;
|
||||||
|
|
||||||
|
typedef struct EmfPlusBeginContainer
|
||||||
|
{
|
||||||
|
EmfPlusRecordHeader Header;
|
||||||
|
GpRectF DestRect;
|
||||||
|
GpRectF SrcRect;
|
||||||
|
DWORD StackIndex;
|
||||||
|
} EmfPlusBeginContainer;
|
||||||
|
|
||||||
typedef struct EmfPlusContainerRecord
|
typedef struct EmfPlusContainerRecord
|
||||||
{
|
{
|
||||||
EmfPlusRecordHeader Header;
|
EmfPlusRecordHeader Header;
|
||||||
|
@ -782,6 +790,30 @@ GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpStatus METAFILE_BeginContainer(GpMetafile* metafile, GDIPCONST GpRectF *dstrect,
|
||||||
|
GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex)
|
||||||
|
{
|
||||||
|
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||||
|
{
|
||||||
|
EmfPlusBeginContainer *record;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
|
stat = METAFILE_AllocateRecord(metafile, sizeof(*record), (void**)&record);
|
||||||
|
if (stat != Ok)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
record->Header.Type = EmfPlusRecordTypeBeginContainer;
|
||||||
|
record->Header.Flags = unit & 0xff;
|
||||||
|
record->DestRect = *dstrect;
|
||||||
|
record->SrcRect = *srcrect;
|
||||||
|
record->StackIndex = StackIndex;
|
||||||
|
|
||||||
|
METAFILE_WriteRecords(metafile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus METAFILE_BeginContainerNoParams(GpMetafile* metafile, DWORD StackIndex)
|
GpStatus METAFILE_BeginContainerNoParams(GpMetafile* metafile, DWORD StackIndex)
|
||||||
{
|
{
|
||||||
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||||
|
@ -1309,6 +1341,63 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
|
||||||
|
|
||||||
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||||
}
|
}
|
||||||
|
case EmfPlusRecordTypeBeginContainer:
|
||||||
|
{
|
||||||
|
EmfPlusBeginContainer *record = (EmfPlusBeginContainer*)header;
|
||||||
|
container* cont;
|
||||||
|
GpUnit unit;
|
||||||
|
REAL scale_x, scale_y;
|
||||||
|
GpRectF scaled_srcrect;
|
||||||
|
GpMatrix transform;
|
||||||
|
|
||||||
|
cont = heap_alloc_zero(sizeof(*cont));
|
||||||
|
if (!cont)
|
||||||
|
return OutOfMemory;
|
||||||
|
|
||||||
|
stat = GdipCloneRegion(metafile->clip, &cont->clip);
|
||||||
|
if (stat != Ok)
|
||||||
|
{
|
||||||
|
heap_free(cont);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
GdipBeginContainer2(metafile->playback_graphics, &cont->state);
|
||||||
|
|
||||||
|
if (stat != Ok)
|
||||||
|
{
|
||||||
|
GdipDeleteRegion(cont->clip);
|
||||||
|
heap_free(cont);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
cont->id = record->StackIndex;
|
||||||
|
cont->type = BEGIN_CONTAINER;
|
||||||
|
cont->world_transform = *metafile->world_transform;
|
||||||
|
cont->page_unit = metafile->page_unit;
|
||||||
|
cont->page_scale = metafile->page_scale;
|
||||||
|
list_add_head(&real_metafile->containers, &cont->entry);
|
||||||
|
|
||||||
|
unit = record->Header.Flags & 0xff;
|
||||||
|
|
||||||
|
scale_x = units_to_pixels(1.0, unit, metafile->image.xres);
|
||||||
|
scale_y = units_to_pixels(1.0, unit, metafile->image.yres);
|
||||||
|
|
||||||
|
scaled_srcrect.X = scale_x * record->SrcRect.X;
|
||||||
|
scaled_srcrect.Y = scale_y * record->SrcRect.Y;
|
||||||
|
scaled_srcrect.Width = scale_x * record->SrcRect.Width;
|
||||||
|
scaled_srcrect.Height = scale_y * record->SrcRect.Height;
|
||||||
|
|
||||||
|
transform.matrix[0] = record->DestRect.Width / scaled_srcrect.Width;
|
||||||
|
transform.matrix[1] = 0.0;
|
||||||
|
transform.matrix[2] = 0.0;
|
||||||
|
transform.matrix[3] = record->DestRect.Height / scaled_srcrect.Height;
|
||||||
|
transform.matrix[4] = record->DestRect.X - scaled_srcrect.X;
|
||||||
|
transform.matrix[5] = record->DestRect.Y - scaled_srcrect.Y;
|
||||||
|
|
||||||
|
GdipMultiplyMatrix(real_metafile->world_transform, &transform, MatrixOrderPrepend);
|
||||||
|
|
||||||
|
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||||
|
}
|
||||||
case EmfPlusRecordTypeBeginContainerNoParams:
|
case EmfPlusRecordTypeBeginContainerNoParams:
|
||||||
case EmfPlusRecordTypeSave:
|
case EmfPlusRecordTypeSave:
|
||||||
{
|
{
|
||||||
|
|
|
@ -1846,6 +1846,9 @@ static const emfplus_record container_records[] = {
|
||||||
{0, EmfPlusRecordTypeBeginContainerNoParams},
|
{0, EmfPlusRecordTypeBeginContainerNoParams},
|
||||||
{0, EmfPlusRecordTypeEndContainer},
|
{0, EmfPlusRecordTypeEndContainer},
|
||||||
{0, EmfPlusRecordTypeFillRects},
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
|
{0, EmfPlusRecordTypeBeginContainer},
|
||||||
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
|
{0, EmfPlusRecordTypeEndContainer},
|
||||||
{0, EmfPlusRecordTypeBeginContainerNoParams},
|
{0, EmfPlusRecordTypeBeginContainerNoParams},
|
||||||
{0, EmfPlusRecordTypeEndOfFile},
|
{0, EmfPlusRecordTypeEndOfFile},
|
||||||
{0, EMR_EOF},
|
{0, EMR_EOF},
|
||||||
|
@ -1865,6 +1868,8 @@ static void test_containers(void)
|
||||||
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
|
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
|
||||||
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
|
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
|
||||||
GraphicsContainer state1, state2;
|
GraphicsContainer state1, state2;
|
||||||
|
GpRectF srcrect, dstrect;
|
||||||
|
REAL dpix, dpiy;
|
||||||
|
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
|
|
||||||
|
@ -1938,6 +1943,41 @@ static void test_containers(void)
|
||||||
stat = GdipFillRectangle(graphics, brush, 20.0, 20.0, 5.0, 5.0);
|
stat = GdipFillRectangle(graphics, brush, 20.0, 20.0, 5.0, 5.0);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipDeleteBrush(brush);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
/* With transform applied */
|
||||||
|
stat = GdipGetDpiX(graphics, &dpix);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipGetDpiY(graphics, &dpiy);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
srcrect.X = 0.0;
|
||||||
|
srcrect.Y = 0.0;
|
||||||
|
srcrect.Width = 1.0;
|
||||||
|
srcrect.Height = 1.0;
|
||||||
|
|
||||||
|
dstrect.X = 25.0;
|
||||||
|
dstrect.Y = 0.0;
|
||||||
|
dstrect.Width = 5.0;
|
||||||
|
dstrect.Height = 5.0;
|
||||||
|
|
||||||
|
stat = GdipBeginContainer(graphics, &dstrect, &srcrect, UnitInch, &state1);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipFillRectangle(graphics, brush, 0.0, 0.0, dpix, dpiy);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipDeleteBrush(brush);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipEndContainer(graphics, state1);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
/* Restoring an invalid state seems to break the graphics object? */
|
/* Restoring an invalid state seems to break the graphics object? */
|
||||||
if (0) {
|
if (0) {
|
||||||
stat = GdipEndContainer(graphics, state1);
|
stat = GdipEndContainer(graphics, state1);
|
||||||
|
@ -1979,6 +2019,10 @@ static void test_containers(void)
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
expect(0xff00ff00, color);
|
expect(0xff00ff00, color);
|
||||||
|
|
||||||
|
stat = GdipBitmapGetPixel(bitmap, 55, 5, &color);
|
||||||
|
expect(Ok, stat);
|
||||||
|
expect(0xff00ffff, color);
|
||||||
|
|
||||||
stat = GdipDeleteGraphics(graphics);
|
stat = GdipDeleteGraphics(graphics);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue