mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 01:35:43 +00:00
[GDIPLUS] Sync with Wine Staging 1.9.16. CORE-11866
svn path=/trunk/; revision=72341
This commit is contained in:
parent
ee606040a1
commit
3f043d113a
9 changed files with 441 additions and 27 deletions
|
@ -191,7 +191,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
if (stat == Ok)
|
||||
{
|
||||
new_texture->transform = texture->transform;
|
||||
*clone = (GpBrush*)new_texture;
|
||||
*clone = &new_texture->brush;
|
||||
}
|
||||
else
|
||||
*clone = NULL;
|
||||
|
|
|
@ -264,7 +264,7 @@
|
|||
264 stdcall GdipGetHatchForegroundColor(ptr ptr)
|
||||
265 stdcall GdipGetHatchStyle(ptr ptr)
|
||||
266 stdcall GdipGetHemfFromMetafile(ptr ptr)
|
||||
267 stub GdipGetImageAttributesAdjustedPalette
|
||||
267 stdcall GdipGetImageAttributesAdjustedPalette(ptr ptr long)
|
||||
268 stdcall GdipGetImageBounds(ptr ptr ptr)
|
||||
269 stdcall GdipGetImageDecoders(long long ptr)
|
||||
270 stdcall GdipGetImageDecodersSize(ptr ptr)
|
||||
|
|
|
@ -94,9 +94,12 @@ 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_GraphicsClear(GpMetafile* metafile, ARGB color) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
|
||||
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
|
||||
|
@ -184,6 +187,9 @@ extern GpStatus convert_pixels(INT width, INT height,
|
|||
INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
|
||||
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
|
||||
|
||||
extern PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
|
||||
UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt) DECLSPEC_HIDDEN;
|
||||
|
||||
struct GpMatrix{
|
||||
REAL matrix[6];
|
||||
};
|
||||
|
@ -322,7 +328,7 @@ struct GpCustomLineCap{
|
|||
REAL scale;
|
||||
};
|
||||
|
||||
struct GpAdustableArrowCap{
|
||||
struct GpAdjustableArrowCap{
|
||||
GpCustomLineCap cap;
|
||||
};
|
||||
|
||||
|
@ -351,6 +357,8 @@ struct GpMetafile{
|
|||
DWORD comment_data_size;
|
||||
DWORD comment_data_length;
|
||||
IStream *record_stream;
|
||||
BOOL auto_frame; /* If true, determine the frame automatically */
|
||||
GpPointF auto_frame_min, auto_frame_max;
|
||||
|
||||
/* playback */
|
||||
GpGraphics *playback_graphics;
|
||||
|
@ -362,6 +370,7 @@ struct GpMetafile{
|
|||
GpMatrix *world_transform;
|
||||
GpUnit page_unit;
|
||||
REAL page_scale;
|
||||
GpRegion *base_clip; /* clip region in device space for all metafile output */
|
||||
};
|
||||
|
||||
struct GpBitmap{
|
||||
|
|
|
@ -657,7 +657,7 @@ static BOOL color_is_gray(ARGB color)
|
|||
}
|
||||
|
||||
/* returns preferred pixel format for the applied attributes */
|
||||
static PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
|
||||
PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
|
||||
UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt)
|
||||
{
|
||||
UINT x, y;
|
||||
|
@ -4277,6 +4277,7 @@ GpStatus WINGDIPAPI GdipGetVisibleClipBounds(GpGraphics *graphics, GpRectF *rect
|
|||
{
|
||||
GpRegion *clip_rgn;
|
||||
GpStatus stat;
|
||||
GpMatrix device_to_world;
|
||||
|
||||
TRACE("(%p, %p)\n", graphics, rect);
|
||||
|
||||
|
@ -4293,6 +4294,13 @@ GpStatus WINGDIPAPI GdipGetVisibleClipBounds(GpGraphics *graphics, GpRectF *rect
|
|||
if((stat = get_visible_clip_region(graphics, clip_rgn)) != Ok)
|
||||
goto cleanup;
|
||||
|
||||
/* transform to world coordinates */
|
||||
if((stat = get_graphics_transform(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &device_to_world)) != Ok)
|
||||
goto cleanup;
|
||||
|
||||
if((stat = GdipTransformRegion(clip_rgn, &device_to_world)) != Ok)
|
||||
goto cleanup;
|
||||
|
||||
/* get bounds of the region */
|
||||
stat = GdipGetRegionBounds(clip_rgn, graphics, rect);
|
||||
|
||||
|
@ -4351,10 +4359,13 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
|
|||
if(graphics->busy)
|
||||
return ObjectBusy;
|
||||
|
||||
if (graphics->image && graphics->image->type == ImageTypeMetafile)
|
||||
return METAFILE_GraphicsClear((GpMetafile*)graphics->image, color);
|
||||
|
||||
if((stat = GdipCreateSolidFill(color, &brush)) != Ok)
|
||||
return stat;
|
||||
|
||||
if((stat = get_graphics_bounds(graphics, &wnd_rect)) != Ok){
|
||||
if((stat = GdipGetVisibleClipBounds(graphics, &wnd_rect)) != Ok){
|
||||
GdipDeleteBrush((GpBrush*)brush);
|
||||
return stat;
|
||||
}
|
||||
|
@ -5097,6 +5108,8 @@ GpStatus WINGDIPAPI GdipResetClip(GpGraphics *graphics)
|
|||
|
||||
GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
|
||||
{
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("(%p)\n", graphics);
|
||||
|
||||
if(!graphics)
|
||||
|
@ -5105,6 +5118,13 @@ GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
|
|||
if(graphics->busy)
|
||||
return ObjectBusy;
|
||||
|
||||
if (graphics->image && graphics->image->type == ImageTypeMetafile) {
|
||||
stat = METAFILE_ResetWorldTransform((GpMetafile*)graphics->image);
|
||||
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
}
|
||||
|
||||
return GdipSetMatrixElements(&graphics->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
@ -5211,6 +5231,8 @@ GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsContainer sta
|
|||
GpStatus WINGDIPAPI GdipScaleWorldTransform(GpGraphics *graphics, REAL sx,
|
||||
REAL sy, GpMatrixOrder order)
|
||||
{
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("(%p, %.2f, %.2f, %d)\n", graphics, sx, sy, order);
|
||||
|
||||
if(!graphics)
|
||||
|
@ -5219,6 +5241,13 @@ GpStatus WINGDIPAPI GdipScaleWorldTransform(GpGraphics *graphics, REAL sx,
|
|||
if(graphics->busy)
|
||||
return ObjectBusy;
|
||||
|
||||
if (graphics->image && graphics->image->type == ImageTypeMetafile) {
|
||||
stat = METAFILE_ScaleWorldTransform((GpMetafile*)graphics->image, sx, sy, order);
|
||||
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
}
|
||||
|
||||
return GdipScaleMatrix(&graphics->worldtrans, sx, sy, order);
|
||||
}
|
||||
|
||||
|
|
|
@ -1245,7 +1245,7 @@ GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
|
|||
}
|
||||
|
||||
if (stat != Ok)
|
||||
GdipDisposeImage((GpImage*)*dstBitmap);
|
||||
GdipDisposeImage(&(*dstBitmap)->image);
|
||||
}
|
||||
|
||||
if (stat != Ok)
|
||||
|
@ -1445,8 +1445,8 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
|
|||
|
||||
if (!bitmap || !hbmReturn) return InvalidParameter;
|
||||
|
||||
GdipGetImageWidth((GpImage*)bitmap, &width);
|
||||
GdipGetImageHeight((GpImage*)bitmap, &height);
|
||||
GdipGetImageWidth(&bitmap->image, &width);
|
||||
GdipGetImageHeight(&bitmap->image, &height);
|
||||
|
||||
bih.biSize = sizeof(bih);
|
||||
bih.biWidth = width;
|
||||
|
@ -1570,7 +1570,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
|
|||
if (stat != Ok) {
|
||||
DeleteObject(iinfo.hbmColor);
|
||||
DeleteObject(iinfo.hbmMask);
|
||||
GdipDisposeImage((GpImage*)*bitmap);
|
||||
GdipDisposeImage(&(*bitmap)->image);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
@ -2932,7 +2932,7 @@ static void add_property(GpBitmap *bitmap, PropertyItem *item)
|
|||
UINT i;
|
||||
char *item_value;
|
||||
|
||||
GdipGetPropertySize((GpImage *)bitmap, &prop_size, &prop_count);
|
||||
GdipGetPropertySize(&bitmap->image, &prop_size, &prop_count);
|
||||
|
||||
prop_item = heap_alloc_zero(prop_size + item->length + sizeof(PropertyItem));
|
||||
if (!prop_item) return;
|
||||
|
@ -3388,7 +3388,7 @@ static void png_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
|
|||
{ "Source", PropertyTagEquipModel },
|
||||
{ "Comment", PropertyTagExifUserComment },
|
||||
};
|
||||
BOOL seen_gamma=FALSE;
|
||||
BOOL seen_gamma=FALSE, seen_whitepoint=FALSE, seen_chrm=FALSE;
|
||||
|
||||
hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &frame);
|
||||
if (hr != S_OK) return;
|
||||
|
@ -3457,6 +3457,57 @@ static void png_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (SUCCEEDED(hr) && IsEqualGUID(&GUID_MetadataFormatChunkcHRM, &format))
|
||||
{
|
||||
PropertyItem* item;
|
||||
|
||||
if (!seen_whitepoint)
|
||||
{
|
||||
item = GdipAlloc(sizeof(PropertyItem) + sizeof(ULONG) * 4);
|
||||
if (item)
|
||||
{
|
||||
ULONG *rational;
|
||||
item->length = sizeof(ULONG) * 4;
|
||||
item->type = PropertyTagTypeRational;
|
||||
item->id = PropertyTagWhitePoint;
|
||||
rational = item->value = item + 1;
|
||||
rational[0] = get_ulong_by_index(reader, 0);
|
||||
rational[1] = 100000;
|
||||
rational[2] = get_ulong_by_index(reader, 1);
|
||||
rational[3] = 100000;
|
||||
add_property(bitmap, item);
|
||||
seen_whitepoint = TRUE;
|
||||
GdipFree(item);
|
||||
}
|
||||
}
|
||||
if (!seen_chrm)
|
||||
{
|
||||
item = GdipAlloc(sizeof(PropertyItem) + sizeof(ULONG) * 12);
|
||||
if (item)
|
||||
{
|
||||
ULONG *rational;
|
||||
item->length = sizeof(ULONG) * 12;
|
||||
item->type = PropertyTagTypeRational;
|
||||
item->id = PropertyTagPrimaryChromaticities;
|
||||
rational = item->value = item + 1;
|
||||
rational[0] = get_ulong_by_index(reader, 2);
|
||||
rational[1] = 100000;
|
||||
rational[2] = get_ulong_by_index(reader, 3);
|
||||
rational[3] = 100000;
|
||||
rational[4] = get_ulong_by_index(reader, 4);
|
||||
rational[5] = 100000;
|
||||
rational[6] = get_ulong_by_index(reader, 5);
|
||||
rational[7] = 100000;
|
||||
rational[8] = get_ulong_by_index(reader, 6);
|
||||
rational[9] = 100000;
|
||||
rational[10] = get_ulong_by_index(reader, 7);
|
||||
rational[11] = 100000;
|
||||
add_property(bitmap, item);
|
||||
seen_chrm = TRUE;
|
||||
GdipFree(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IWICMetadataReader_Release(reader);
|
||||
}
|
||||
|
@ -3568,11 +3619,11 @@ static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder, BOOL force_conversi
|
|||
}
|
||||
|
||||
if (SUCCEEDED(hr) && status == Ok)
|
||||
*image = (GpImage*)bitmap;
|
||||
*image = &bitmap->image;
|
||||
else
|
||||
{
|
||||
*image = NULL;
|
||||
GdipDisposeImage((GpImage*)bitmap);
|
||||
GdipDisposeImage(&bitmap->image);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && status == Ok)
|
||||
|
@ -3614,7 +3665,14 @@ static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder, BOOL force_conversi
|
|||
if (status == Ok)
|
||||
{
|
||||
/* Native GDI+ used to be smarter, but since Win7 it just sets these flags. */
|
||||
bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
|
||||
bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI;
|
||||
if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat2bppGray) ||
|
||||
IsEqualGUID(&wic_format, &GUID_WICPixelFormat4bppGray) ||
|
||||
IsEqualGUID(&wic_format, &GUID_WICPixelFormat8bppGray) ||
|
||||
IsEqualGUID(&wic_format, &GUID_WICPixelFormat16bppGray))
|
||||
bitmap->image.flags |= ImageFlagsColorSpaceGRAY;
|
||||
else
|
||||
bitmap->image.flags |= ImageFlagsColorSpaceRGB;
|
||||
bitmap->image.frame_count = frame_count;
|
||||
bitmap->image.current_frame = active_frame;
|
||||
bitmap->image.decoder = decoder;
|
||||
|
@ -3856,7 +3914,37 @@ static GpStatus decode_image_jpeg(IStream* stream, GpImage **image)
|
|||
|
||||
static GpStatus decode_image_png(IStream* stream, GpImage **image)
|
||||
{
|
||||
return decode_image_wic(stream, &GUID_ContainerFormatPng, png_metadata_reader, image);
|
||||
IWICBitmapDecoder *decoder;
|
||||
IWICBitmapFrameDecode *frame;
|
||||
GpStatus status;
|
||||
HRESULT hr;
|
||||
GUID format;
|
||||
BOOL force_conversion = FALSE;
|
||||
|
||||
status = initialize_decoder_wic(stream, &GUID_ContainerFormatPng, &decoder);
|
||||
if (status != Ok)
|
||||
return status;
|
||||
|
||||
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
if (IsEqualGUID(&format, &GUID_WICPixelFormat8bppGray))
|
||||
force_conversion = TRUE;
|
||||
status = decode_frame_wic(decoder, force_conversion, 0, png_metadata_reader, image);
|
||||
}
|
||||
else
|
||||
status = hresult_to_status(hr);
|
||||
|
||||
IWICBitmapFrameDecode_Release(frame);
|
||||
}
|
||||
else
|
||||
status = hresult_to_status(hr);
|
||||
|
||||
IWICBitmapDecoder_Release(decoder);
|
||||
return status;
|
||||
}
|
||||
|
||||
static GpStatus decode_image_gif(IStream* stream, GpImage **image)
|
||||
|
@ -4987,7 +5075,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
|
|||
entry[i].peGreen << 8 | entry[i].peBlue;
|
||||
}
|
||||
|
||||
retval = GdipSetImagePalette((GpImage*)*bitmap, palette);
|
||||
retval = GdipSetImagePalette(&(*bitmap)->image, palette);
|
||||
}
|
||||
|
||||
heap_free(palette);
|
||||
|
@ -4995,7 +5083,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
|
|||
|
||||
if (retval != Ok)
|
||||
{
|
||||
GdipDisposeImage((GpImage*)*bitmap);
|
||||
GdipDisposeImage(&(*bitmap)->image);
|
||||
*bitmap = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -5250,7 +5338,7 @@ GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
|
|||
if (stat == Ok)
|
||||
move_bitmap(bitmap, new_bitmap, FALSE);
|
||||
else
|
||||
GdipDisposeImage((GpImage*)new_bitmap);
|
||||
GdipDisposeImage(&new_bitmap->image);
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,21 @@ GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
|
|||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipGetImageAttributesAdjustedPalette(GpImageAttributes *imageattr,
|
||||
ColorPalette *palette, ColorAdjustType type)
|
||||
{
|
||||
TRACE("(%p,%p,%u)\n", imageattr, palette, type);
|
||||
|
||||
if (!imageattr || !palette || !palette->Count ||
|
||||
type >= ColorAdjustTypeCount || type == ColorAdjustTypeDefault)
|
||||
return InvalidParameter;
|
||||
|
||||
apply_image_attributes(imageattr, (LPBYTE)palette->Entries, palette->Count, 1, 0,
|
||||
type, PixelFormat32bppARGB);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr,
|
||||
ColorAdjustType type, BOOL enableFlag, ARGB colorLow, ARGB colorHigh)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,12 @@ typedef struct EmfPlusHeader
|
|||
DWORD LogicalDpiY;
|
||||
} EmfPlusHeader;
|
||||
|
||||
typedef struct EmfPlusClear
|
||||
{
|
||||
EmfPlusRecordHeader Header;
|
||||
DWORD Color;
|
||||
} EmfPlusClear;
|
||||
|
||||
typedef struct EmfPlusFillRects
|
||||
{
|
||||
EmfPlusRecordHeader Header;
|
||||
|
@ -56,6 +62,13 @@ typedef struct EmfPlusRect
|
|||
SHORT Height;
|
||||
} EmfPlusRect;
|
||||
|
||||
typedef struct EmfPlusScaleWorldTransform
|
||||
{
|
||||
EmfPlusRecordHeader Header;
|
||||
REAL Sx;
|
||||
REAL Sy;
|
||||
} EmfPlusScaleWorldTransform;
|
||||
|
||||
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
|
||||
{
|
||||
DWORD size_needed;
|
||||
|
@ -248,6 +261,15 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
|
|||
(*metafile)->comment_data_length = 0;
|
||||
(*metafile)->hemf = NULL;
|
||||
|
||||
if (!frameRect)
|
||||
{
|
||||
(*metafile)->auto_frame = TRUE;
|
||||
(*metafile)->auto_frame_min.X = 0;
|
||||
(*metafile)->auto_frame_min.Y = 0;
|
||||
(*metafile)->auto_frame_max.X = -1;
|
||||
(*metafile)->auto_frame_max.Y = -1;
|
||||
}
|
||||
|
||||
stat = METAFILE_WriteHeader(*metafile, hdc);
|
||||
|
||||
if (stat != Ok)
|
||||
|
@ -306,6 +328,30 @@ GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType t
|
|||
return stat;
|
||||
}
|
||||
|
||||
static void METAFILE_AdjustFrame(GpMetafile* metafile, const GpPointF *points,
|
||||
UINT num_points)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!metafile->auto_frame || !num_points)
|
||||
return;
|
||||
|
||||
if (metafile->auto_frame_max.X < metafile->auto_frame_min.X)
|
||||
metafile->auto_frame_max = metafile->auto_frame_min = points[0];
|
||||
|
||||
for (i=0; i<num_points; i++)
|
||||
{
|
||||
if (points[i].X < metafile->auto_frame_min.X)
|
||||
metafile->auto_frame_min.X = points[i].X;
|
||||
if (points[i].X > metafile->auto_frame_max.X)
|
||||
metafile->auto_frame_max.X = points[i].X;
|
||||
if (points[i].Y < metafile->auto_frame_min.Y)
|
||||
metafile->auto_frame_min.Y = points[i].Y;
|
||||
if (points[i].Y > metafile->auto_frame_max.Y)
|
||||
metafile->auto_frame_max.Y = points[i].Y;
|
||||
}
|
||||
}
|
||||
|
||||
GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result)
|
||||
{
|
||||
GpStatus stat;
|
||||
|
@ -347,6 +393,27 @@ GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc)
|
|||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus METAFILE_GraphicsClear(GpMetafile* metafile, ARGB color)
|
||||
{
|
||||
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||
{
|
||||
EmfPlusClear *record;
|
||||
GpStatus stat;
|
||||
|
||||
stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusClear), (void**)&record);
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
|
||||
record->Header.Type = EmfPlusRecordTypeClear;
|
||||
record->Header.Flags = 0;
|
||||
record->Color = color;
|
||||
|
||||
METAFILE_WriteRecords(metafile);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static BOOL is_integer_rect(const GpRectF *rect)
|
||||
{
|
||||
SHORT x, y, width, height;
|
||||
|
@ -423,6 +490,29 @@ GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
|
|||
METAFILE_WriteRecords(metafile);
|
||||
}
|
||||
|
||||
if (metafile->auto_frame)
|
||||
{
|
||||
GpPointF corners[4];
|
||||
int i;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
corners[0].X = rects[i].X;
|
||||
corners[0].Y = rects[i].Y;
|
||||
corners[1].X = rects[i].X + rects[i].Width;
|
||||
corners[1].Y = rects[i].Y;
|
||||
corners[2].X = rects[i].X;
|
||||
corners[2].Y = rects[i].Y + rects[i].Height;
|
||||
corners[3].X = rects[i].X + rects[i].Width;
|
||||
corners[3].Y = rects[i].Y + rects[i].Height;
|
||||
|
||||
GdipTransformPoints(metafile->record_graphics, CoordinateSpaceDevice,
|
||||
CoordinateSpaceWorld, corners, 4);
|
||||
|
||||
METAFILE_AdjustFrame(metafile, corners, 4);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -449,6 +539,52 @@ GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale
|
|||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order)
|
||||
{
|
||||
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||
{
|
||||
EmfPlusScaleWorldTransform *record;
|
||||
GpStatus stat;
|
||||
|
||||
stat = METAFILE_AllocateRecord(metafile,
|
||||
sizeof(EmfPlusScaleWorldTransform),
|
||||
(void**)&record);
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
|
||||
record->Header.Type = EmfPlusRecordTypeScaleWorldTransform;
|
||||
record->Header.Flags = (order == MatrixOrderAppend ? 4 : 0);
|
||||
record->Sx = sx;
|
||||
record->Sy = sy;
|
||||
|
||||
METAFILE_WriteRecords(metafile);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
|
||||
{
|
||||
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||
{
|
||||
EmfPlusRecordHeader *record;
|
||||
GpStatus stat;
|
||||
|
||||
stat = METAFILE_AllocateRecord(metafile,
|
||||
sizeof(EmfPlusRecordHeader),
|
||||
(void**)&record);
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
|
||||
record->Type = EmfPlusRecordTypeResetWorldTransform;
|
||||
record->Flags = 0;
|
||||
|
||||
METAFILE_WriteRecords(metafile);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc)
|
||||
{
|
||||
if (hdc != metafile->record_dc)
|
||||
|
@ -476,6 +612,57 @@ GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile)
|
|||
MetafileHeader header;
|
||||
|
||||
stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header);
|
||||
if (stat == Ok && metafile->auto_frame &&
|
||||
metafile->auto_frame_max.X >= metafile->auto_frame_min.X)
|
||||
{
|
||||
RECTL bounds_rc, gdi_bounds_rc;
|
||||
REAL x_scale = 2540.0 / header.DpiX;
|
||||
REAL y_scale = 2540.0 / header.DpiY;
|
||||
BYTE* buffer;
|
||||
UINT buffer_size;
|
||||
|
||||
bounds_rc.left = floorf(metafile->auto_frame_min.X * x_scale);
|
||||
bounds_rc.top = floorf(metafile->auto_frame_min.Y * y_scale);
|
||||
bounds_rc.right = ceilf(metafile->auto_frame_max.X * x_scale);
|
||||
bounds_rc.bottom = ceilf(metafile->auto_frame_max.Y * y_scale);
|
||||
|
||||
gdi_bounds_rc = header.u.EmfHeader.rclBounds;
|
||||
if (gdi_bounds_rc.right > gdi_bounds_rc.left && gdi_bounds_rc.bottom > gdi_bounds_rc.top)
|
||||
{
|
||||
bounds_rc.left = min(bounds_rc.left, gdi_bounds_rc.left);
|
||||
bounds_rc.top = min(bounds_rc.top, gdi_bounds_rc.top);
|
||||
bounds_rc.right = max(bounds_rc.right, gdi_bounds_rc.right);
|
||||
bounds_rc.bottom = max(bounds_rc.bottom, gdi_bounds_rc.bottom);
|
||||
}
|
||||
|
||||
buffer_size = GetEnhMetaFileBits(metafile->hemf, 0, NULL);
|
||||
buffer = heap_alloc(buffer_size);
|
||||
if (buffer)
|
||||
{
|
||||
HENHMETAFILE new_hemf;
|
||||
|
||||
GetEnhMetaFileBits(metafile->hemf, buffer_size, buffer);
|
||||
|
||||
((ENHMETAHEADER*)buffer)->rclFrame = bounds_rc;
|
||||
|
||||
new_hemf = SetEnhMetaFileBits(buffer_size, buffer);
|
||||
|
||||
if (new_hemf)
|
||||
{
|
||||
DeleteEnhMetaFile(metafile->hemf);
|
||||
metafile->hemf = new_hemf;
|
||||
}
|
||||
else
|
||||
stat = OutOfMemory;
|
||||
|
||||
heap_free(buffer);
|
||||
}
|
||||
else
|
||||
stat = OutOfMemory;
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header);
|
||||
}
|
||||
if (stat == Ok)
|
||||
{
|
||||
metafile->bounds.X = header.X;
|
||||
|
@ -568,6 +755,11 @@ static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile)
|
|||
}
|
||||
}
|
||||
|
||||
static GpStatus METAFILE_PlaybackUpdateClip(GpMetafile *metafile)
|
||||
{
|
||||
return GdipCombineRegionRegion(metafile->playback_graphics->clip, metafile->base_clip, CombineModeReplace);
|
||||
}
|
||||
|
||||
static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile)
|
||||
{
|
||||
GpMatrix *real_transform;
|
||||
|
@ -645,6 +837,12 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
|
|||
case EmfPlusRecordTypeGetDC:
|
||||
METAFILE_PlaybackGetDC((GpMetafile*)metafile);
|
||||
break;
|
||||
case EmfPlusRecordTypeClear:
|
||||
{
|
||||
EmfPlusClear *record = (EmfPlusClear*)header;
|
||||
|
||||
return GdipGraphicsClear(metafile->playback_graphics, record->Color);
|
||||
}
|
||||
case EmfPlusRecordTypeFillRects:
|
||||
{
|
||||
EmfPlusFillRects *record = (EmfPlusFillRects*)header;
|
||||
|
@ -724,6 +922,24 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
|
|||
|
||||
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||
}
|
||||
case EmfPlusRecordTypeScaleWorldTransform:
|
||||
{
|
||||
EmfPlusScaleWorldTransform *record = (EmfPlusScaleWorldTransform*)header;
|
||||
MatrixOrder order = (flags & 0x4) ? MatrixOrderAppend : MatrixOrderPrepend;
|
||||
|
||||
if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusScaleWorldTransform))
|
||||
return InvalidParameter;
|
||||
|
||||
GdipScaleMatrix(real_metafile->world_transform, record->Sx, record->Sy, order);
|
||||
|
||||
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||
}
|
||||
case EmfPlusRecordTypeResetWorldTransform:
|
||||
{
|
||||
GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
|
||||
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||
}
|
||||
default:
|
||||
FIXME("Not implemented for record type %x\n", recordType);
|
||||
return NotImplemented;
|
||||
|
@ -799,6 +1015,7 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
GpStatus stat;
|
||||
GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
|
||||
GraphicsContainer state;
|
||||
GpPath *dst_path;
|
||||
|
||||
TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
|
||||
destPoints, count, srcRect, srcUnit, callback, callbackData,
|
||||
|
@ -838,6 +1055,38 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
if (stat == Ok)
|
||||
stat = GdipSetPageUnit(graphics, UnitPixel);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipResetWorldTransform(graphics);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCreateRegion(&real_metafile->base_clip);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipGetClip(graphics, real_metafile->base_clip);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCreatePath(FillModeAlternate, &dst_path);
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
GpPointF clip_points[4];
|
||||
|
||||
clip_points[0] = real_metafile->playback_points[0];
|
||||
clip_points[1] = real_metafile->playback_points[1];
|
||||
clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X
|
||||
- real_metafile->playback_points[0].X;
|
||||
clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y
|
||||
- real_metafile->playback_points[0].Y;
|
||||
clip_points[3] = real_metafile->playback_points[2];
|
||||
|
||||
stat = GdipAddPathPolygon(dst_path, clip_points, 4);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect);
|
||||
|
||||
GdipDeletePath(dst_path);
|
||||
}
|
||||
|
||||
if (stat == Ok)
|
||||
stat = GdipCreateMatrix(&real_metafile->world_transform);
|
||||
|
||||
|
@ -848,6 +1097,11 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||
}
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = METAFILE_PlaybackUpdateClip(real_metafile);
|
||||
}
|
||||
|
||||
if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf ||
|
||||
metafile->metafile_type == MetafileTypeWmfPlaceable ||
|
||||
metafile->metafile_type == MetafileTypeWmf))
|
||||
|
@ -861,6 +1115,9 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
GdipDeleteMatrix(real_metafile->world_transform);
|
||||
real_metafile->world_transform = NULL;
|
||||
|
||||
GdipDeleteRegion(real_metafile->base_clip);
|
||||
real_metafile->base_clip = NULL;
|
||||
|
||||
GdipEndContainer(graphics, state);
|
||||
}
|
||||
|
||||
|
@ -1205,8 +1462,22 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR *file,
|
|||
GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR *file,
|
||||
GpMetafile **metafile)
|
||||
{
|
||||
FIXME("(%p, %p): stub\n", file, metafile);
|
||||
return NotImplemented;
|
||||
GpStatus status;
|
||||
IStream *stream;
|
||||
|
||||
TRACE("(%p, %p)\n", file, metafile);
|
||||
|
||||
if (!file || !metafile) return InvalidParameter;
|
||||
|
||||
*metafile = NULL;
|
||||
|
||||
status = GdipCreateStreamOnFile(file, GENERIC_READ, &stream);
|
||||
if (status == Ok)
|
||||
{
|
||||
status = GdipCreateMetafileFromStream(stream, metafile);
|
||||
IStream_Release(stream);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream *stream,
|
||||
|
|
|
@ -809,7 +809,7 @@ static void write_element(const region_element* element, DWORD *buffer,
|
|||
* their code followed by a second header for the path followed by the actual
|
||||
* path data. Followed by the flags for each point. The pathheader contains
|
||||
* the size of the data to follow, a version number again, followed by a count
|
||||
* of how many points, and any special flags which may apply. 0x4000 means its
|
||||
* of how many points, and any special flags which may apply. 0x4000 means it's
|
||||
* a path of shorts instead of FLOAT.
|
||||
*
|
||||
* Combining Ops are stored in reverse order from when they were constructed;
|
||||
|
@ -1102,6 +1102,12 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
|
|||
GpStatus stat;
|
||||
INT save_state;
|
||||
|
||||
if (!path->pathdata.Count) /* PathToRegion doesn't support empty paths */
|
||||
{
|
||||
*hrgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||
return *hrgn ? Ok : OutOfMemory;
|
||||
}
|
||||
|
||||
if (!graphics)
|
||||
{
|
||||
new_hdc = CreateCompatibleDC(0);
|
||||
|
@ -1384,11 +1390,7 @@ GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion* region, REAL x, REAL y, RE
|
|||
return Ok;
|
||||
}
|
||||
|
||||
rect.left = ceilr(x);
|
||||
rect.top = ceilr(y);
|
||||
rect.right = ceilr(x + w);
|
||||
rect.bottom = ceilr(y + h);
|
||||
|
||||
SetRect(&rect, ceilr(x), ceilr(y), ceilr(x + w), ceilr(y + h));
|
||||
*res = RectInRegion(hrgn, &rect);
|
||||
|
||||
DeleteObject(hrgn);
|
||||
|
|
|
@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-1.9.11
|
|||
reactos/dll/win32/faultrep # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/fontsub # Synced to WineStaging-1.9.13
|
||||
reactos/dll/win32/fusion # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/gdiplus # Synced to WineStaging-1.9.11
|
||||
reactos/dll/win32/gdiplus # Synced to WineStaging-1.9.16
|
||||
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-1.9.16
|
||||
reactos/dll/win32/hlink # Synced to WineStaging-1.9.16
|
||||
reactos/dll/win32/hnetcfg # Synced to WineStaging-1.9.11
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue