gdiplus: Support GdipSetClipRegion in metafiles.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4a02870296
commit
14bb8df8a5
|
@ -93,6 +93,7 @@ extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
|
||||||
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
|
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_SetClipRect(GpMetafile* metafile,
|
extern GpStatus METAFILE_SetClipRect(GpMetafile* metafile,
|
||||||
REAL x, REAL y, REAL width, REAL height, CombineMode mode) DECLSPEC_HIDDEN;
|
REAL x, REAL y, REAL width, REAL height, CombineMode mode) DECLSPEC_HIDDEN;
|
||||||
|
extern GpStatus METAFILE_SetClipRegion(GpMetafile* metafile, GpRegion* region, CombineMode mode) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* transform) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* transform) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) DECLSPEC_HIDDEN;
|
||||||
|
@ -124,6 +125,7 @@ extern void free_installed_fonts(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern BOOL lengthen_path(GpPath *path, INT len) DECLSPEC_HIDDEN;
|
extern BOOL lengthen_path(GpPath *path, INT len) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
extern DWORD write_region_data(const GpRegion *region, void *data) DECLSPEC_HIDDEN;
|
||||||
extern DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN;
|
extern DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
|
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -6269,6 +6269,13 @@ GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
|
||||||
if(graphics->busy)
|
if(graphics->busy)
|
||||||
return ObjectBusy;
|
return ObjectBusy;
|
||||||
|
|
||||||
|
if (graphics->image && graphics->image->type == ImageTypeMetafile)
|
||||||
|
{
|
||||||
|
status = METAFILE_SetClipRegion((GpMetafile*)graphics->image, region, mode);
|
||||||
|
if (status != Ok)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
status = GdipCloneRegion(region, &clip);
|
status = GdipCloneRegion(region, &clip);
|
||||||
if (status == Ok)
|
if (status == Ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -239,6 +239,13 @@ typedef struct EmfPlusPath
|
||||||
BYTE data[1];
|
BYTE data[1];
|
||||||
} EmfPlusPath;
|
} EmfPlusPath;
|
||||||
|
|
||||||
|
typedef struct EmfPlusRegion
|
||||||
|
{
|
||||||
|
DWORD Version;
|
||||||
|
DWORD RegionNodeCount;
|
||||||
|
BYTE RegionNode[1];
|
||||||
|
} EmfPlusRegion;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
BitmapDataTypePixel,
|
BitmapDataTypePixel,
|
||||||
|
@ -312,6 +319,7 @@ typedef struct EmfPlusObject
|
||||||
EmfPlusBrush brush;
|
EmfPlusBrush brush;
|
||||||
EmfPlusPen pen;
|
EmfPlusPen pen;
|
||||||
EmfPlusPath path;
|
EmfPlusPath path;
|
||||||
|
EmfPlusRegion region;
|
||||||
EmfPlusImage image;
|
EmfPlusImage image;
|
||||||
EmfPlusImageAttributes image_attributes;
|
EmfPlusImageAttributes image_attributes;
|
||||||
} ObjectData;
|
} ObjectData;
|
||||||
|
@ -847,6 +855,53 @@ GpStatus METAFILE_SetClipRect(GpMetafile* metafile, REAL x, REAL y, REAL width,
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GpStatus METAFILE_AddRegionObject(GpMetafile *metafile, GpRegion *region, DWORD *id)
|
||||||
|
{
|
||||||
|
EmfPlusObject *object_record;
|
||||||
|
DWORD size;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
|
*id = -1;
|
||||||
|
if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual)
|
||||||
|
return Ok;
|
||||||
|
|
||||||
|
size = write_region_data(region, NULL);
|
||||||
|
stat = METAFILE_AllocateRecord(metafile,
|
||||||
|
FIELD_OFFSET(EmfPlusObject, ObjectData.region) + size, (void**)&object_record);
|
||||||
|
if (stat != Ok) return stat;
|
||||||
|
|
||||||
|
*id = METAFILE_AddObjectId(metafile);
|
||||||
|
object_record->Header.Type = EmfPlusRecordTypeObject;
|
||||||
|
object_record->Header.Flags = *id | ObjectTypeRegion << 8;
|
||||||
|
write_region_data(region, &object_record->ObjectData.region);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpStatus METAFILE_SetClipRegion(GpMetafile* metafile, GpRegion* region, CombineMode mode)
|
||||||
|
{
|
||||||
|
EmfPlusRecordHeader *record;
|
||||||
|
DWORD region_id;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
|
if (metafile->metafile_type == MetafileTypeEmf)
|
||||||
|
{
|
||||||
|
FIXME("stub!\n");
|
||||||
|
return NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat = METAFILE_AddRegionObject(metafile, region, ®ion_id);
|
||||||
|
if (stat != Ok) return stat;
|
||||||
|
|
||||||
|
stat = METAFILE_AllocateRecord(metafile, sizeof(*record), (void**)&record);
|
||||||
|
if (stat != Ok) return stat;
|
||||||
|
|
||||||
|
record->Type = EmfPlusRecordTypeSetClipRegion;
|
||||||
|
record->Flags = region_id | mode << 8;
|
||||||
|
|
||||||
|
METAFILE_WriteRecords(metafile);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale)
|
GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale)
|
||||||
{
|
{
|
||||||
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||||
|
|
|
@ -699,7 +699,7 @@ static void write_element(const region_element* element, DWORD *buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD write_region_data(const GpRegion *region, void *data)
|
DWORD write_region_data(const GpRegion *region, void *data)
|
||||||
{
|
{
|
||||||
struct region_header *header = data;
|
struct region_header *header = data;
|
||||||
INT filled = 0;
|
INT filled = 0;
|
||||||
|
|
|
@ -2154,6 +2154,8 @@ static const emfplus_record clipping_records[] = {
|
||||||
{0, EmfPlusRecordTypeRestore},
|
{0, EmfPlusRecordTypeRestore},
|
||||||
{0, EmfPlusRecordTypeSetClipRect},
|
{0, EmfPlusRecordTypeSetClipRect},
|
||||||
{0, EmfPlusRecordTypeFillRects},
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
|
{0, EmfPlusRecordTypeObject, 1},
|
||||||
|
{0, EmfPlusRecordTypeSetClipRegion, 1},
|
||||||
{0, EmfPlusRecordTypeEndOfFile},
|
{0, EmfPlusRecordTypeEndOfFile},
|
||||||
{0, EMR_EOF},
|
{0, EMR_EOF},
|
||||||
{0}
|
{0}
|
||||||
|
@ -2165,6 +2167,7 @@ static void test_clipping(void)
|
||||||
GpMetafile *metafile;
|
GpMetafile *metafile;
|
||||||
GpGraphics *graphics;
|
GpGraphics *graphics;
|
||||||
GpBitmap *bitmap;
|
GpBitmap *bitmap;
|
||||||
|
GpRegion *region;
|
||||||
GpBrush *brush;
|
GpBrush *brush;
|
||||||
GpRectF rect;
|
GpRectF rect;
|
||||||
ARGB color;
|
ARGB color;
|
||||||
|
@ -2231,6 +2234,15 @@ static void test_clipping(void)
|
||||||
stat = GdipDeleteBrush(brush);
|
stat = GdipDeleteBrush(brush);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipCreateRegionRect(&rect, ®ion);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipSetClipRegion(graphics, region, CombineModeIntersect);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipDeleteRegion(region);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
stat = GdipDeleteGraphics(graphics);
|
stat = GdipDeleteGraphics(graphics);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue