[GDIPLUS]

- Sync to Wine 1.3.37

svn path=/trunk/; revision=56055
This commit is contained in:
Rafal Harabien
2012-03-05 20:17:42 +00:00
parent a9d90422fd
commit 4ecb1c4ca7
21 changed files with 3879 additions and 1415 deletions
+2
View File
@@ -19,10 +19,12 @@ list(APPEND SOURCE
image.c
imageattributes.c
matrix.c
metafile.c
pathiterator.c
pen.c
region.c
stringformat.c
gdiplus.rc
${CMAKE_CURRENT_BINARY_DIR}/gdiplus_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/gdiplus.def)
+80 -17
View File
@@ -191,8 +191,14 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
GpStatus stat;
GpTexture *texture = (GpTexture*)brush;
GpTexture *new_texture;
UINT width, height;
stat = GdipCreateTexture(texture->image, texture->wrap, &new_texture);
stat = GdipGetImageWidth(texture->image, &width);
if (stat != Ok) return stat;
stat = GdipGetImageHeight(texture->image, &height);
if (stat != Ok) return stat;
stat = GdipCreateTextureIA(texture->image, texture->imageattributes, 0, 0, width, height, &new_texture);
if (stat == Ok)
{
@@ -246,6 +252,17 @@ static const char HatchBrushes[][8] = {
{ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
};
GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result)
{
if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
{
*result = HatchBrushes[hatchstyle];
return Ok;
}
else
return NotImplemented;
}
/******************************************************************************
* GdipCreateHatchBrush [GDIPLUS.@]
*/
@@ -789,7 +806,7 @@ GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
GpTexture **texture)
{
UINT width, height;
GpImageAttributes attributes;
GpImageAttributes *attributes;
GpStatus stat;
TRACE("%p, %d %p\n", image, wrapmode, texture);
@@ -801,10 +818,20 @@ GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
if (stat != Ok) return stat;
stat = GdipGetImageHeight(image, &height);
if (stat != Ok) return stat;
attributes.wrap = wrapmode;
return GdipCreateTextureIA(image, &attributes, 0, 0, width, height,
stat = GdipCreateImageAttributes(&attributes);
if (stat == Ok)
{
attributes->wrap = wrapmode;
stat = GdipCreateTextureIA(image, attributes, 0, 0, width, height,
texture);
GdipDisposeImageAttributes(attributes);
}
return stat;
}
/******************************************************************************
@@ -813,14 +840,25 @@ GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode,
REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
{
GpImageAttributes attributes;
GpImageAttributes *attributes;
GpStatus stat;
TRACE("%p %d %f %f %f %f %p\n", image, wrapmode,
x, y, width, height, texture);
attributes.wrap = wrapmode;
return GdipCreateTextureIA(image, &attributes, x, y, width, height,
texture);
stat = GdipCreateImageAttributes(&attributes);
if (stat == Ok)
{
attributes->wrap = wrapmode;
stat = GdipCreateTextureIA(image, attributes, x, y, width, height,
texture);
GdipDisposeImageAttributes(attributes);
}
return stat;
}
/******************************************************************************
@@ -870,16 +908,25 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
goto exit;
}
if (imageattr)
{
status = GdipCloneImageAttributes(imageattr, &(*texture)->imageattributes);
}
else
{
status = GdipCreateImageAttributes(&(*texture)->imageattributes);
if (status == Ok)
(*texture)->imageattributes->wrap = WrapModeTile;
}
if (status != Ok)
goto exit;
(*texture)->brush.lb.lbStyle = BS_PATTERN;
(*texture)->brush.lb.lbColor = 0;
(*texture)->brush.lb.lbHatch = (ULONG_PTR)hbm;
(*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
(*texture)->brush.bt = BrushTypeTextureFill;
if (imageattr)
(*texture)->wrap = imageattr->wrap;
else
(*texture)->wrap = WrapModeTile;
(*texture)->image = new_image;
exit:
@@ -892,6 +939,7 @@ exit:
if (*texture)
{
GdipDeleteMatrix((*texture)->transform);
GdipDisposeImageAttributes((*texture)->imageattributes);
GdipFree(*texture);
*texture = NULL;
}
@@ -919,14 +967,22 @@ GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttrib
GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode,
INT x, INT y, INT width, INT height, GpTexture **texture)
{
GpImageAttributes imageattr;
GpImageAttributes *imageattr;
GpStatus stat;
TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
texture);
imageattr.wrap = wrapmode;
stat = GdipCreateImageAttributes(&imageattr);
return GdipCreateTextureIA(image, &imageattr, x, y, width, height, texture);
if (stat == Ok)
{
imageattr->wrap = wrapmode;
stat = GdipCreateTextureIA(image, imageattr, x, y, width, height, texture);
}
return stat;
}
GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
@@ -1000,6 +1056,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
case BrushTypeTextureFill:
GdipDeleteMatrix(((GpTexture*)brush)->transform);
GdipDisposeImage(((GpTexture*)brush)->image);
GdipDisposeImageAttributes(((GpTexture*)brush)->imageattributes);
GdipFree(((GpTexture*)brush)->bitmap_bits);
break;
default:
break;
@@ -1222,11 +1280,16 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT *count)
{
static int calls;
TRACE("(%p, %p)\n", brush, count);
if (!brush || !count)
return InvalidParameter;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
@@ -1293,7 +1356,7 @@ GpStatus WINGDIPAPI GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmod
if(!brush || !wrapmode)
return InvalidParameter;
*wrapmode = brush->wrap;
*wrapmode = brush->imageattributes->wrap;
return Ok;
}
@@ -1773,7 +1836,7 @@ GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode
if(!brush)
return InvalidParameter;
brush->wrap = wrapmode;
brush->imageattributes->wrap = wrapmode;
return Ok;
}
+174 -13
View File
@@ -126,27 +126,27 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
{
case UnitWorld:
/* FIXME: Figure out when World != Pixel */
lfw->lfHeight = emSize; break;
(*font)->pixel_size = emSize; break;
case UnitDisplay:
FIXME("Unknown behavior for UnitDisplay! Please report!\n");
/* FIXME: Figure out how this works...
* MSDN says that if "DISPLAY" is a monitor, then pixel should be
* used. That's not what I got. Tests on Windows revealed no output,
* and the tests in tests/font crash windows */
lfw->lfHeight = 0; break;
(*font)->pixel_size = 0; break;
case UnitPixel:
lfw->lfHeight = emSize; break;
(*font)->pixel_size = emSize; break;
case UnitPoint:
lfw->lfHeight = point_to_pixel(emSize); break;
(*font)->pixel_size = point_to_pixel(emSize); break;
case UnitInch:
lfw->lfHeight = inch_to_pixel(emSize); break;
(*font)->pixel_size = inch_to_pixel(emSize); break;
case UnitDocument:
lfw->lfHeight = document_to_pixel(emSize); break;
(*font)->pixel_size = document_to_pixel(emSize); break;
case UnitMillimeter:
lfw->lfHeight = mm_to_pixel(emSize); break;
(*font)->pixel_size = mm_to_pixel(emSize); break;
}
lfw->lfHeight *= -1;
lfw->lfHeight = (*font)->pixel_size * -1;
lfw->lfWeight = style & FontStyleBold ? 700 : 400;
lfw->lfItalic = style & FontStyleItalic;
@@ -190,7 +190,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
(*font)->lfw.lfUnderline = logfont->lfUnderline;
(*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
(*font)->emSize = logfont->lfHeight;
(*font)->pixel_size = (*font)->emSize = logfont->lfHeight;
(*font)->unit = UnitPixel;
hfont = CreateFontIndirectW(&(*font)->lfw);
@@ -816,10 +816,20 @@ GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family,
GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily)
{
static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
static const WCHAR LiberationMono[] = {'L','i','b','e','r','a','t','i','o','n',' ','M','o','n','o','\0'};
GpStatus stat;
if (nativeFamily == NULL) return InvalidParameter;
return GdipCreateFontFamilyFromName(CourierNew, NULL, nativeFamily);
stat = GdipCreateFontFamilyFromName(CourierNew, NULL, nativeFamily);
if (stat == FontFamilyNotFound)
stat = GdipCreateFontFamilyFromName(LiberationMono, NULL, nativeFamily);
if (stat == FontFamilyNotFound)
ERR("Missing 'Courier New' font\n");
return stat;
}
/*****************************************************************************
@@ -837,12 +847,22 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamil
GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
{
static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
static const WCHAR LiberationSerif[] = {'L','i','b','e','r','a','t','i','o','n',' ','S','e','r','i','f','\0'};
GpStatus stat;
TRACE("(%p)\n", nativeFamily);
if (nativeFamily == NULL) return InvalidParameter;
return GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily);
stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily);
if (stat == FontFamilyNotFound)
stat = GdipCreateFontFamilyFromName(LiberationSerif, NULL, nativeFamily);
if (stat == FontFamilyNotFound)
ERR("Missing 'Times New Roman' font\n");
return stat;
}
/*****************************************************************************
@@ -930,17 +950,158 @@ GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection,
return NotImplemented;
}
/* Copied from msi/font.c */
typedef struct _tagTT_OFFSET_TABLE {
USHORT uMajorVersion;
USHORT uMinorVersion;
USHORT uNumOfTables;
USHORT uSearchRange;
USHORT uEntrySelector;
USHORT uRangeShift;
} TT_OFFSET_TABLE;
typedef struct _tagTT_TABLE_DIRECTORY {
char szTag[4]; /* table name */
ULONG uCheckSum; /* Check sum */
ULONG uOffset; /* Offset from beginning of file */
ULONG uLength; /* length of the table in bytes */
} TT_TABLE_DIRECTORY;
typedef struct _tagTT_NAME_TABLE_HEADER {
USHORT uFSelector; /* format selector. Always 0 */
USHORT uNRCount; /* Name Records count */
USHORT uStorageOffset; /* Offset for strings storage,
* from start of the table */
} TT_NAME_TABLE_HEADER;
#define NAME_ID_FULL_FONT_NAME 4
#define NAME_ID_VERSION 5
typedef struct _tagTT_NAME_RECORD {
USHORT uPlatformID;
USHORT uEncodingID;
USHORT uLanguageID;
USHORT uNameID;
USHORT uStringLength;
USHORT uStringOffset; /* from start of storage area */
} TT_NAME_RECORD;
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
/*
* Code based off of code located here
* http://www.codeproject.com/gdi/fontnamefromfile.asp
*/
static WCHAR *load_ttf_name_id( const char *mem, DWORD_PTR size, DWORD id, WCHAR *ret, DWORD len )
{
const TT_TABLE_DIRECTORY *tblDir;
TT_OFFSET_TABLE ttOffsetTable;
TT_NAME_TABLE_HEADER ttNTHeader;
TT_NAME_RECORD ttRecord;
DWORD ofs, pos;
int i;
if (sizeof(TT_OFFSET_TABLE) > size)
return NULL;
ttOffsetTable = *(TT_OFFSET_TABLE*)mem;
ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
return NULL;
pos = sizeof(ttOffsetTable);
for (i = 0; i < ttOffsetTable.uNumOfTables; i++)
{
tblDir = (const TT_TABLE_DIRECTORY*)&mem[pos];
pos += sizeof(*tblDir);
if (memcmp(tblDir->szTag,"name",4)==0)
{
ofs = SWAPLONG(tblDir->uOffset);
break;
}
}
if (i >= ttOffsetTable.uNumOfTables)
return NULL;
pos = ofs + sizeof(ttNTHeader);
if (pos > size)
return NULL;
ttNTHeader = *(TT_NAME_TABLE_HEADER*)&mem[ofs];
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
for(i=0; i<ttNTHeader.uNRCount; i++)
{
ttRecord = *(TT_NAME_RECORD*)&mem[pos];
pos += sizeof(ttRecord);
if (pos > size)
return NULL;
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if (ttRecord.uNameID == id)
{
const char *buf;
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
if (ofs + ttRecord.uStringOffset + ttNTHeader.uStorageOffset + ttRecord.uStringLength > size)
return NULL;
buf = mem + ofs + ttRecord.uStringOffset + ttNTHeader.uStorageOffset;
len = MultiByteToWideChar(CP_ACP, 0, buf, ttRecord.uStringLength, ret, len-1);
ret[len] = 0;
return ret;
}
}
return NULL;
}
static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam);
/*****************************************************************************
* GdipPrivateAddMemoryFont [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
GDIPCONST void* memory, INT length)
{
FIXME("%p, %p, %d\n", fontCollection, memory, length);
WCHAR buf[32], *name;
DWORD count = 0;
HANDLE font;
TRACE("%p, %p, %d\n", fontCollection, memory, length);
if (!(fontCollection && memory && length))
if (!fontCollection || !memory || !length)
return InvalidParameter;
name = load_ttf_name_id(memory, length, NAME_ID_FULL_FONT_NAME, buf, sizeof(buf)/sizeof(*buf));
if (!name)
return OutOfMemory;
font = AddFontMemResourceEx((void*)memory, length, NULL, &count);
TRACE("%s: %p/%u\n", debugstr_w(name), font, count);
if (!font || !count)
return InvalidParameter;
if (count)
{
HDC hdc;
LOGFONTW lfw;
hdc = GetDC(0);
lfw.lfCharSet = DEFAULT_CHARSET;
lstrcpyW(lfw.lfFaceName, name);
lfw.lfPitchAndFamily = 0;
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)fontCollection, 0))
{
ReleaseDC(0, hdc);
return OutOfMemory;
}
ReleaseDC(0, hdc);
}
return Ok;
}
+9 -8
View File
@@ -116,16 +116,17 @@ void WINAPI GdiplusNotificationUnhook(ULONG_PTR token)
/*****************************************************
* GdiplusShutdown [GDIPLUS.@]
*/
void WINAPI GdiplusShutdown(ULONG_PTR token)
{
/* FIXME: no object tracking */
}
/* "bricksntiles" expects a return value of 0, which native coincidentally gives */
ULONG WINAPI GdiplusShutdown_wrapper(ULONG_PTR token)
{
GdiplusShutdown(token);
/* Notice the slightly different prototype from the official
* signature which forces us to use the _wrapper suffix.
*/
/* FIXME: no object tracking */
/* "bricksntiles" expects a return value of 0, which native
* coincidentally gives.
*/
return 0;
}
@@ -406,7 +407,7 @@ BOOL lengthen_path(GpPath *path, INT len)
void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride)
{
UINT x, y;
INT x, y;
for (y=0; y<height; y++)
{
const BYTE *src=src_bits+y*src_stride;
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Microsoft.Windows.GdiPlus" version="1.0.6000.16386" processorArchitecture="" publicKeyToken="6595b64144ccf1df"/>
<file name="gdiplus.dll"/>
</assembly>
+22
View File
@@ -0,0 +1,22 @@
/*
* Resource file for gdiplus
*
* Copyright 2011 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* @makedep: gdiplus.manifest */
WINE_MANIFEST 24 gdiplus.manifest
File diff suppressed because it is too large Load Diff
+57 -19
View File
@@ -41,29 +41,38 @@
#define VERSION_MAGIC 0xdbc01001
#define TENSION_CONST (0.3)
COLORREF ARGB2COLORREF(ARGB color);
HBITMAP ARGB2BMP(ARGB color);
COLORREF ARGB2COLORREF(ARGB color) DECLSPEC_HIDDEN;
HBITMAP ARGB2BMP(ARGB color) DECLSPEC_HIDDEN;
extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
REAL startAngle, REAL sweepAngle);
extern REAL gdiplus_atan2(REAL dy, REAL dx);
extern GpStatus hresult_to_status(HRESULT res);
extern REAL convert_unit(REAL logpixels, GpUnit unit);
REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN;
extern REAL gdiplus_atan2(REAL dy, REAL dx) DECLSPEC_HIDDEN;
extern GpStatus hresult_to_status(HRESULT res) DECLSPEC_HIDDEN;
extern REAL convert_unit(REAL logpixels, GpUnit unit) DECLSPEC_HIDDEN;
extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics);
extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
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_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
REAL *y1, REAL *x2, REAL *y2);
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
REAL tension, REAL *x, REAL *y);
REAL tension, REAL *x, REAL *y) DECLSPEC_HIDDEN;
extern void free_installed_fonts(void);
extern void free_installed_fonts(void) DECLSPEC_HIDDEN;
extern BOOL lengthen_path(GpPath *path, INT len);
extern void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *hfont) DECLSPEC_HIDDEN;
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
extern BOOL lengthen_path(GpPath *path, INT len) DECLSPEC_HIDDEN;
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
typedef struct region_element region_element;
extern void delete_element(region_element *element);
extern void delete_element(region_element *element) DECLSPEC_HIDDEN;
extern GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
static inline INT roundr(REAL x)
{
@@ -103,16 +112,16 @@ static inline ARGB color_over(ARGB bg, ARGB fg)
return (a<<24)|(r<<16)|(g<<8)|b;
}
extern const char *debugstr_rectf(CONST RectF* rc);
extern const char *debugstr_rectf(CONST RectF* rc) DECLSPEC_HIDDEN;
extern const char *debugstr_pointf(CONST PointF* pt);
extern const char *debugstr_pointf(CONST PointF* pt) DECLSPEC_HIDDEN;
extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride);
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride) DECLSPEC_HIDDEN;
extern GpStatus convert_pixels(UINT width, UINT height,
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, ARGB *src_palette);
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ARGB *src_palette) DECLSPEC_HIDDEN;
struct GpPen{
UINT style;
@@ -213,7 +222,8 @@ struct GpTexture{
GpBrush brush;
GpMatrix *transform;
GpImage *image;
WrapMode wrap; /* not used yet */
GpImageAttributes *imageattributes;
BYTE *bitmap_bits; /* image bits converted to ARGB and run through imageattributes */
};
struct GpPath{
@@ -263,6 +273,22 @@ struct GpMetafile{
GpImage image;
GpRectF bounds;
GpUnit unit;
MetafileType metafile_type;
HENHMETAFILE hemf;
/* recording */
HDC record_dc;
GpGraphics *record_graphics;
BYTE *comment_data;
DWORD comment_data_size;
DWORD comment_data_length;
/* playback */
GpGraphics *playback_graphics;
HDC playback_dc;
GpPointF playback_points[3];
HANDLETABLE *handle_table;
int handle_count;
};
struct GpBitmap{
@@ -278,6 +304,7 @@ struct GpBitmap{
BYTE *bits; /* actual image bits if this is a DIB */
INT stride; /* stride of bits if this is a DIB */
BYTE *own_bits; /* image bits that need to be freed with this object */
INT lockx, locky; /* X and Y coordinates of the rect when a bitmap is locked for writing. */
};
struct GpCachedBitmap{
@@ -317,6 +344,7 @@ struct GpImageAttributes{
struct GpFont{
LOGFONTW lfw;
REAL emSize;
REAL pixel_size;
UINT height;
LONG line_spacing;
Unit unit;
@@ -394,4 +422,14 @@ struct GpRegion{
region_element node;
};
typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, void *user_data);
GpStatus gdip_format_string(HDC hdc,
GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
gdip_format_string_callback callback, void *user_data) DECLSPEC_HIDDEN;
#endif
File diff suppressed because it is too large Load Diff
+186 -14
View File
@@ -384,8 +384,7 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *po
/* close figure */
if(stat == Ok){
INT count = path->pathdata.Count;
path->pathdata.Types[count - 1] |= PathPointTypeCloseSubpath;
path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
path->newfigure = TRUE;
}
@@ -745,7 +744,7 @@ GpStatus WINGDIPAPI GdipAddPathPie(GpPath *path, REAL x, REAL y, REAL width, REA
arc2polybezier(ptf, x, y, width, height, startAngle, sweepAngle);
status = GdipAddPathLine(path, (width - x)/2, (height - y)/2, ptf[0].X, ptf[0].Y);
status = GdipAddPathLine(path, x + width/2, y + height/2, ptf[0].X, ptf[0].Y);
if(status != Ok){
GdipFree(ptf);
return status;
@@ -831,16 +830,187 @@ GpStatus WINGDIPAPI GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points,
return status;
}
static float fromfixedpoint(const FIXED v)
{
float f = ((float)v.fract) / (1<<(sizeof(v.fract)*8));
f += v.value;
return f;
}
struct format_string_args
{
GpPath *path;
UINT maxY;
};
static GpStatus format_string_callback(HDC dc,
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, void *priv)
{
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
struct format_string_args *args = priv;
GpPath *path = args->path;
GpStatus status = Ok;
float x = bounds->X;
float y = bounds->Y;
int i;
for (i = index; i < length; ++i)
{
GLYPHMETRICS gm;
TTPOLYGONHEADER *ph = NULL;
char *start;
DWORD len, ofs = 0;
UINT bb_end;
len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
if (len == GDI_ERROR)
{
status = GenericError;
break;
}
ph = GdipAlloc(len);
start = (char *)ph;
if (!ph || !lengthen_path(path, len / sizeof(POINTFX)))
{
status = OutOfMemory;
break;
}
GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, len, start, &identity);
bb_end = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
if (bb_end + y > args->maxY)
args->maxY = bb_end + y;
ofs = 0;
while (ofs < len)
{
DWORD ofs_start = ofs;
ph = (TTPOLYGONHEADER*)&start[ofs];
path->pathdata.Types[path->pathdata.Count] = PathPointTypeStart;
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x);
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(ph->pfxStart.y);
TRACE("Starting at count %i with pos %f, %f)\n", path->pathdata.Count, x, y);
ofs += sizeof(*ph);
while (ofs - ofs_start < ph->cb)
{
TTPOLYCURVE *curve = (TTPOLYCURVE*)&start[ofs];
int j;
ofs += sizeof(TTPOLYCURVE) + (curve->cpfx - 1) * sizeof(POINTFX);
switch (curve->wType)
{
case TT_PRIM_LINE:
for (j = 0; j < curve->cpfx; ++j)
{
path->pathdata.Types[path->pathdata.Count] = PathPointTypeLine;
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
}
break;
case TT_PRIM_CSPLINE:
for (j = 0; j < curve->cpfx; ++j)
{
path->pathdata.Types[path->pathdata.Count] = PathPointTypeBezier;
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
}
break;
default:
ERR("Unhandled type: %u\n", curve->wType);
status = GenericError;
}
}
path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
}
path->newfigure = TRUE;
x += gm.gmCellIncX;
y += gm.gmCellIncY;
GdipFree(ph);
if (status != Ok)
break;
}
return status;
}
GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFontFamily* family, INT style, REAL emSize, GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat* format)
{
FIXME("(%p, %p, %d, %p, %d, %f, %p, %p): stub\n", path, string, length, family, style, emSize, layoutRect, format);
return NotImplemented;
GpFont *font;
GpStatus status;
HANDLE hfont;
HDC dc;
GpPath *backup;
struct format_string_args args;
int i;
FIXME("(%p, %s, %d, %p, %d, %f, %p, %p): stub\n", path, debugstr_w(string), length, family, style, emSize, layoutRect, format);
if (!path || !string || !family || !emSize || !layoutRect || !format)
return InvalidParameter;
status = GdipCreateFont(family, emSize, style, UnitPixel, &font);
if (status != Ok)
return status;
hfont = CreateFontIndirectW(&font->lfw);
if (!hfont)
{
WARN("Failed to create font\n");
return GenericError;
}
if ((status = GdipClonePath(path, &backup)) != Ok)
{
DeleteObject(hfont);
return status;
}
dc = CreateCompatibleDC(0);
SelectObject(dc, hfont);
args.path = path;
args.maxY = 0;
status = gdip_format_string(dc, string, length, NULL, layoutRect, format, format_string_callback, &args);
DeleteDC(dc);
DeleteObject(hfont);
if (status != Ok) /* free backup */
{
GdipFree(path->pathdata.Points);
GdipFree(path->pathdata.Types);
*path = *backup;
GdipFree(backup);
return status;
}
if (format && format->vertalign == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
{
float inc = layoutRect->Height - args.maxY - layoutRect->Y;
inc /= 2;
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
path->pathdata.Points[i].Y += inc;
} else if (format && format->vertalign == StringAlignmentFar) {
float inc = layoutRect->Height - args.maxY - layoutRect->Y;
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
path->pathdata.Points[i].Y += inc;
}
GdipDeletePath(backup);
return status;
}
GpStatus WINGDIPAPI GdipAddPathStringI(GpPath* path, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFontFamily* family, INT style, REAL emSize, GDIPCONST Rect* layoutRect, GDIPCONST GpStringFormat* format)
{
FIXME("(%p, %p, %d, %p, %d, %f, %p, %p): stub\n", path, string, length, family, style, emSize, layoutRect, format);
return NotImplemented;
if (layoutRect)
{
RectF layoutRectF = {
(REAL)layoutRect->X,
(REAL)layoutRect->Y,
(REAL)layoutRect->Width,
(REAL)layoutRect->Height
};
return GdipAddPathString(path, string, length, family, style, emSize, &layoutRectF, format);
}
return InvalidParameter;
}
GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone)
@@ -1507,7 +1677,7 @@ GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x, y, width, height);
if(!path || width < 0.0 || height < 0.0)
if(!path)
return InvalidParameter;
/* make a backup copy of path data */
@@ -1536,9 +1706,10 @@ GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,
fail:
/* reverting */
GdipDeletePath(path);
GdipClonePath(backup, &path);
GdipDeletePath(backup);
GdipFree(path->pathdata.Points);
GdipFree(path->pathdata.Types);
memcpy(path, backup, sizeof(*path));
GdipFree(backup);
return retstat;
}
@@ -1581,9 +1752,10 @@ GpStatus WINGDIPAPI GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects
fail:
/* reverting */
GdipDeletePath(path);
GdipClonePath(backup, &path);
GdipDeletePath(backup);
GdipFree(path->pathdata.Points);
GdipFree(path->pathdata.Types);
memcpy(path, backup, sizeof(*path));
GdipFree(backup);
return retstat;
}
+238 -79
View File
@@ -296,6 +296,53 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
return Ok;
}
static inline UINT get_palette_index(BYTE r, BYTE g, BYTE b, BYTE a, GpBitmap* bitmap) {
BYTE index = 0;
int best_distance = 0x7fff;
int distance;
int i;
/* This algorithm scans entire palette,
computes difference from desired color (all color components have equal weight)
and returns the index of color with least difference.
Note: Maybe it could be replaced with a better algorithm for better image quality
and performance, though better algorithm would probably need some pre-built lookup
tables and thus may actually be slower if this method is called only few times per
every image.
*/
for(i=0;i<bitmap->image.palette_size;i++) {
ARGB color=bitmap->image.palette_entries[i];
distance=abs(b-(color & 0xff)) + abs(g-(color>>8 & 0xff)) + abs(r-(color>>16 & 0xff)) + abs(a-(color>>24 & 0xff));
if (distance<best_distance) {
best_distance=distance;
index=i;
}
}
return index;
}
static inline void setpixel_8bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
BYTE index = get_palette_index(r,g,b,a,bitmap);
row[x]=index;
}
static inline void setpixel_1bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
row[x/8] = (row[x/8] & ~(1<<(7-x%8))) | (get_palette_index(r,g,b,a,bitmap)<<(7-x%8));
}
static inline void setpixel_4bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x, GpBitmap* bitmap)
{
if (x & 1)
row[x/2] = (row[x/2] & 0xf0) | get_palette_index(r,g,b,a,bitmap);
else
row[x/2] = (row[x/2] & 0x0f) | get_palette_index(r,g,b,a,bitmap)<<4;
}
static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x)
{
@@ -434,6 +481,15 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
case PixelFormat64bppPARGB:
setpixel_64bppPARGB(r,g,b,a,row,x);
break;
case PixelFormat8bppIndexed:
setpixel_8bppIndexed(r,g,b,a,row,x,bitmap);
break;
case PixelFormat4bppIndexed:
setpixel_4bppIndexed(r,g,b,a,row,x,bitmap);
break;
case PixelFormat1bppIndexed:
setpixel_1bppIndexed(r,g,b,a,row,x,bitmap);
break;
default:
FIXME("not implemented for format 0x%x\n", bitmap->format);
return NotImplemented;
@@ -442,11 +498,11 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
return Ok;
}
GpStatus convert_pixels(UINT width, UINT height,
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, ARGB *src_palette)
{
UINT x, y;
INT x, y;
if (src_format == dst_format ||
(dst_format == PixelFormat32bppRGB && PIXELFORMATBPP(src_format) == 32))
@@ -857,9 +913,7 @@ GpStatus convert_pixels(UINT width, UINT height,
GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
UINT flags, PixelFormat format, BitmapData* lockeddata)
{
INT stride, bitspp = PIXELFORMATBPP(format);
BYTE *buff = NULL;
UINT abs_height;
INT bitspp = PIXELFORMATBPP(format);
GpRect act_rect; /* actual rect to be used */
GpStatus stat;
@@ -881,20 +935,13 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
act_rect.Height = bitmap->height;
}
if(flags & ImageLockModeUserInputBuf)
{
static int fixme=0;
if (!fixme++) FIXME("ImageLockModeUserInputBuf not implemented\n");
return NotImplemented;
}
if(bitmap->lockmode)
{
WARN("bitmap is already locked and cannot be locked again\n");
return WrongState;
}
if (bitmap->bits && bitmap->format == format)
if (bitmap->bits && bitmap->format == format && !(flags & ImageLockModeUserInputBuf))
{
/* no conversion is necessary; just use the bits directly */
lockeddata->Width = act_rect.Width;
@@ -912,11 +959,14 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
}
/* Make sure we can convert to the requested format. */
stat = convert_pixels(0, 0, 0, NULL, format, 0, NULL, bitmap->format, NULL);
if (stat == NotImplemented)
if (flags & ImageLockModeRead)
{
FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
return NotImplemented;
stat = convert_pixels(0, 0, 0, NULL, format, 0, NULL, bitmap->format, NULL);
if (stat == NotImplemented)
{
FIXME("cannot read bitmap from %x to %x\n", bitmap->format, format);
return NotImplemented;
}
}
/* If we're opening for writing, make sure we'll be able to write back in
@@ -931,34 +981,50 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect,
}
}
abs_height = bitmap->height;
stride = (bitmap->width * bitspp + 7) / 8;
stride = (stride + 3) & ~3;
buff = GdipAlloc(stride * abs_height);
if (!buff) return OutOfMemory;
stat = convert_pixels(bitmap->width, bitmap->height,
stride, buff, format,
bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
if (stat != Ok)
{
GdipFree(buff);
return stat;
}
lockeddata->Width = act_rect.Width;
lockeddata->Height = act_rect.Height;
lockeddata->PixelFormat = format;
lockeddata->Reserved = flags;
lockeddata->Stride = stride;
lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y;
if(!(flags & ImageLockModeUserInputBuf))
{
lockeddata->Stride = (((act_rect.Width * bitspp + 7) / 8) + 3) & ~3;
bitmap->bitmapbits = GdipAlloc(lockeddata->Stride * act_rect.Height);
if (!bitmap->bitmapbits) return OutOfMemory;
lockeddata->Scan0 = bitmap->bitmapbits;
}
if (flags & ImageLockModeRead)
{
static int fixme=0;
if (!fixme && (PIXELFORMATBPP(bitmap->format) * act_rect.X) % 8 != 0)
{
FIXME("Cannot copy rows that don't start at a whole byte.\n");
fixme = 1;
}
stat = convert_pixels(act_rect.Width, act_rect.Height,
lockeddata->Stride, lockeddata->Scan0, format,
bitmap->stride,
bitmap->bits + bitmap->stride * act_rect.Y + PIXELFORMATBPP(bitmap->format) * act_rect.X / 8,
bitmap->format, bitmap->image.palette_entries);
if (stat != Ok)
{
GdipFree(bitmap->bitmapbits);
bitmap->bitmapbits = NULL;
return stat;
}
}
bitmap->lockmode = flags;
bitmap->numlocks++;
bitmap->bitmapbits = buff;
bitmap->lockx = act_rect.X;
bitmap->locky = act_rect.Y;
return Ok;
}
@@ -980,6 +1046,7 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
BitmapData* lockeddata)
{
GpStatus stat;
static int fixme=0;
TRACE("(%p,%p)\n", bitmap, lockeddata);
@@ -989,10 +1056,7 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
if(!bitmap->lockmode)
return WrongState;
if(lockeddata->Reserved & ImageLockModeUserInputBuf)
return NotImplemented;
if(lockeddata->Reserved & ImageLockModeRead){
if(!(lockeddata->Reserved & ImageLockModeWrite)){
if(!(--bitmap->numlocks))
bitmap->lockmode = 0;
@@ -1001,7 +1065,7 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
return Ok;
}
if (!bitmap->bitmapbits)
if (!bitmap->bitmapbits && !(lockeddata->Reserved & ImageLockModeUserInputBuf))
{
/* we passed a direct reference; no need to do anything */
bitmap->lockmode = 0;
@@ -1009,9 +1073,17 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
return Ok;
}
stat = convert_pixels(bitmap->width, bitmap->height,
bitmap->stride, bitmap->bits, bitmap->format,
lockeddata->Stride, bitmap->bitmapbits, lockeddata->PixelFormat, NULL);
if (!fixme && (PIXELFORMATBPP(bitmap->format) * bitmap->lockx) % 8 != 0)
{
FIXME("Cannot copy rows that don't start at a whole byte.\n");
fixme = 1;
}
stat = convert_pixels(lockeddata->Width, lockeddata->Height,
bitmap->stride,
bitmap->bits + bitmap->stride * bitmap->locky + PIXELFORMATBPP(bitmap->format) * bitmap->lockx / 8,
bitmap->format,
lockeddata->Stride, lockeddata->Scan0, lockeddata->PixelFormat, NULL);
if (stat != Ok)
{
@@ -1298,12 +1370,12 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
HBITMAP* hbmReturn, ARGB background)
{
GpStatus stat;
HBITMAP result, oldbitmap;
HBITMAP result;
UINT width, height;
HDC hdc;
GpGraphics *graphics;
BITMAPINFOHEADER bih;
void *bits;
LPBYTE bits;
BitmapData lockeddata;
TRACE("(%p,%p,%x)\n", bitmap, hbmReturn, background);
if (!bitmap || !hbmReturn) return InvalidParameter;
@@ -1326,25 +1398,19 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
hdc = CreateCompatibleDC(NULL);
if (!hdc) return GenericError;
result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &bits,
result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits,
NULL, 0);
if (result)
{
oldbitmap = SelectObject(hdc, result);
lockeddata.Stride = -width * 4;
lockeddata.Scan0 = bits + (width * 4 * (height - 1));
stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead|ImageLockModeUserInputBuf,
PixelFormat32bppPARGB, &lockeddata);
stat = GdipCreateFromHDC(hdc, &graphics);
if (stat == Ok)
{
stat = GdipGraphicsClear(graphics, background);
if (stat == Ok)
stat = GdipDrawImage(graphics, (GpImage*)bitmap, 0, 0);
GdipDeleteGraphics(graphics);
}
SelectObject(hdc, oldbitmap);
stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
}
else
stat = GenericError;
@@ -1955,7 +2021,21 @@ GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
DeleteDC(((GpBitmap*)image)->hdc);
DeleteObject(((GpBitmap*)image)->hbitmap);
}
else if (image->type != ImageTypeMetafile)
else if (image->type == ImageTypeMetafile)
{
GpMetafile *metafile = (GpMetafile*)image;
GdipFree(metafile->comment_data);
DeleteEnhMetaFile(CloseEnhMetaFile(metafile->record_dc));
DeleteEnhMetaFile(metafile->hemf);
if (metafile->record_graphics)
{
WARN("metafile closed while recording\n");
/* not sure what to do here; for now just prevent the graphics from functioning or using this object */
metafile->record_graphics->image = NULL;
metafile->record_graphics->busy = TRUE;
}
}
else
{
WARN("invalid image: %p\n", image);
return ObjectBusy;
@@ -2071,12 +2151,7 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
if(!image || !graphics)
return InvalidParameter;
if(image->type != ImageTypeBitmap){
FIXME("not implemented for image type %d\n", image->type);
return NotImplemented;
}
if (((GpBitmap*)image)->hbitmap)
if (image->type == ImageTypeBitmap && ((GpBitmap*)image)->hbitmap)
{
hdc = ((GpBitmap*)image)->hdc;
@@ -2091,6 +2166,8 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
if (stat == Ok)
(*graphics)->image = image;
}
else if (image->type == ImageTypeMetafile)
stat = METAFILE_GetGraphicsContext((GpMetafile*)image, graphics);
else
stat = graphics_from_image(image, graphics);
@@ -2322,7 +2399,8 @@ GpStatus WINGDIPAPI GdipGetPropertyCount(GpImage *image, UINT* num)
if(!(calls++))
FIXME("not implemented\n");
return InvalidParameter;
*num = 0;
return Ok;
}
GpStatus WINGDIPAPI GdipGetPropertyIdList(GpImage *image, UINT num, PROPID* list)
@@ -2384,7 +2462,7 @@ struct image_format_dimension
const GUID *dimension;
};
struct image_format_dimension image_format_dimensions[] =
static struct image_format_dimension image_format_dimensions[] =
{
{&ImageFormatGIF, &FrameDimensionTime},
{&ImageFormatIcon, &FrameDimensionResolution},
@@ -3013,6 +3091,12 @@ static GpStatus encode_image_BMP(GpImage *image, IStream* stream,
return encode_image_WIC(image, stream, &CLSID_WICBmpEncoder, params);
}
static GpStatus encode_image_tiff(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
return encode_image_WIC(image, stream, &CLSID_WICTiffEncoder, params);
}
static GpStatus encode_image_png(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
@@ -3231,14 +3315,14 @@ static const struct image_codec codecs[NUM_CODECS] = {
/* FormatDescription */ tiff_format,
/* FilenameExtension */ tiff_extension,
/* MimeType */ tiff_mimetype,
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsEncoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Version */ 1,
/* SigCount */ 2,
/* SigSize */ 4,
/* SigPattern */ tiff_sig_pattern,
/* SigMask */ tiff_sig_mask,
},
NULL,
encode_image_tiff,
decode_image_tiff
},
{
@@ -3442,6 +3526,7 @@ GpStatus WINGDIPAPI GdipGetEncoderParameterListSize(GpImage *image,
GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBitmap** bitmap)
{
BITMAP bm;
DIBSECTION dib;
GpStatus retval;
PixelFormat format;
BitmapData lockeddata;
@@ -3452,12 +3537,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
if(!hbm || !bitmap)
return InvalidParameter;
/* TODO: Support for device-dependent bitmaps */
if(hpal){
FIXME("no support for device-dependent bitmaps\n");
return NotImplemented;
}
if (GetObjectA(hbm, sizeof(bm), &bm) != sizeof(bm))
return InvalidParameter;
@@ -3472,6 +3551,36 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
case 8:
format = PixelFormat8bppIndexed;
break;
case 16:
{
if (GetObjectA(hbm, sizeof(dib), &dib) == sizeof(dib))
{
if (dib.dsBitfields[0] == 0x7c00 &&
dib.dsBitfields[1] == 0x3e0 &&
dib.dsBitfields[2] == 0x1f)
{
format = PixelFormat16bppRGB555;
}
else if (dib.dsBitfields[0] == 0xf800 &&
dib.dsBitfields[1] == 0x7e0 &&
dib.dsBitfields[2] == 0x1f)
{
format = PixelFormat16bppRGB565;
}
else
{
FIXME("unrecognized bitfields %x,%x,%x\n", dib.dsBitfields[0],
dib.dsBitfields[1], dib.dsBitfields[2]);
return InvalidParameter;
}
}
else
{
FIXME("unimplemented for 16-bit ddb\n");
return InvalidParameter;
}
break;
}
case 24:
format = PixelFormat24bppRGB;
break;
@@ -3554,6 +3663,56 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
GdipBitmapUnlockBits(*bitmap, &lockeddata);
}
if (retval == Ok && hpal)
{
WORD num_palette_entries;
PALETTEENTRY *palette_entries=NULL;
ColorPalette *palette=NULL;
int i;
if (!GetObjectW(hpal, sizeof(num_palette_entries), &num_palette_entries))
retval = GenericError;
if (retval == Ok)
{
palette_entries = GdipAlloc(sizeof(PALETTEENTRY) * num_palette_entries);
palette = GdipAlloc(sizeof(ColorPalette) + sizeof(ARGB) * (num_palette_entries-1));
if (!palette_entries || !palette)
retval = OutOfMemory;
}
if (retval == Ok)
{
if (!GetPaletteEntries(hpal, 0, num_palette_entries, palette_entries))
retval = GenericError;
}
if (retval == Ok)
{
palette->Flags = 0;
palette->Count = num_palette_entries;
for (i=0; i<num_palette_entries; i++)
{
PALETTEENTRY * entry = &palette_entries[i];
palette->Entries[i] = 0xff000000 | entry->peRed << 16 |
entry->peGreen << 8 | entry->peBlue;
}
retval = GdipSetImagePalette((GpImage*)*bitmap, palette);
}
GdipFree(palette_entries);
GdipFree(palette);
}
if (retval != Ok)
{
GdipDisposeImage((GpImage*)*bitmap);
*bitmap = NULL;
}
}
return retval;
+30 -18
View File
@@ -85,27 +85,28 @@ GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22,
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect,
GDIPCONST GpPointF *pt, GpMatrix **matrix)
{
REAL m11, m12, m21, m22, dx, dy;
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
if(!matrix || !pt)
return InvalidParameter;
*matrix = GdipAlloc(sizeof(GpMatrix));
if(!*matrix) return OutOfMemory;
m11 = (pt[1].X - pt[0].X) / rect->Width;
m21 = (pt[2].X - pt[0].X) / rect->Height;
dx = pt[0].X - m11 * rect->X - m21 * rect->Y;
m12 = (pt[1].Y - pt[0].Y) / rect->Width;
m22 = (pt[2].Y - pt[0].Y) / rect->Height;
dy = pt[0].Y - m12 * rect->X - m22 * rect->Y;
memcpy((*matrix)->matrix, rect, 4 * sizeof(REAL));
(*matrix)->matrix[4] = pt->X;
(*matrix)->matrix[5] = pt->Y;
return Ok;
return GdipCreateMatrix2(m11, m12, m21, m22, dx, dy, matrix);
}
GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint *pt,
GpMatrix **matrix)
{
GpRectF rectF;
GpPointF ptF;
GpPointF ptF[3];
int i;
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
@@ -114,10 +115,11 @@ GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint
rectF.Width = (REAL)rect->Width;
rectF.Height = (REAL)rect->Height;
ptF.X = (REAL)pt->X;
ptF.Y = (REAL)pt->Y;
return GdipCreateMatrix3(&rectF, &ptF, matrix);
for (i = 0; i < 3; i++) {
ptF[i].X = (REAL)pt[i].X;
ptF[i].Y = (REAL)pt[i].Y;
}
return GdipCreateMatrix3(&rectF, ptF, matrix);
}
GpStatus WINGDIPAPI GdipCloneMatrix(GpMatrix *matrix, GpMatrix **clone)
@@ -231,8 +233,10 @@ GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GDIPCONST GpMatrix* mat
if(order == MatrixOrderAppend)
matrix_multiply(matrix->matrix, matrix2->matrix, matrix->matrix);
else
else if (order == MatrixOrderPrepend)
matrix_multiply(matrix2->matrix, matrix->matrix, matrix->matrix);
else
return InvalidParameter;
return Ok;
}
@@ -260,8 +264,10 @@ GpStatus WINGDIPAPI GdipRotateMatrix(GpMatrix *matrix, REAL angle,
if(order == MatrixOrderAppend)
matrix_multiply(matrix->matrix, rotate, matrix->matrix);
else
else if (order == MatrixOrderPrepend)
matrix_multiply(rotate, matrix->matrix, matrix->matrix);
else
return InvalidParameter;
return Ok;
}
@@ -285,8 +291,10 @@ GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY,
if(order == MatrixOrderAppend)
matrix_multiply(matrix->matrix, scale, matrix->matrix);
else
else if (order == MatrixOrderPrepend)
matrix_multiply(scale, matrix->matrix, matrix->matrix);
else
return InvalidParameter;
return Ok;
}
@@ -330,8 +338,10 @@ GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY,
if(order == MatrixOrderAppend)
matrix_multiply(matrix->matrix, shear, matrix->matrix);
else
else if (order == MatrixOrderPrepend)
matrix_multiply(shear, matrix->matrix, matrix->matrix);
else
return InvalidParameter;
return Ok;
}
@@ -410,8 +420,10 @@ GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX,
if(order == MatrixOrderAppend)
matrix_multiply(matrix->matrix, translate, matrix->matrix);
else
else if (order == MatrixOrderPrepend)
matrix_multiply(translate, matrix->matrix, matrix->matrix);
else
return InvalidParameter;
return Ok;
}
+553
View File
@@ -0,0 +1,553 @@
/*
* Copyright (C) 2011 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/unicode.h"
#define COBJMACROS
#include "objbase.h"
#include "ocidl.h"
#include "olectl.h"
#include "ole2.h"
#include "winreg.h"
#include "shlwapi.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
typedef struct EmfPlusRecordHeader
{
WORD Type;
WORD Flags;
DWORD Size;
DWORD DataSize;
} EmfPlusRecordHeader;
typedef struct EmfPlusHeader
{
EmfPlusRecordHeader Header;
DWORD Version;
DWORD EmfPlusFlags;
DWORD LogicalDpiX;
DWORD LogicalDpiY;
} EmfPlusHeader;
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
{
DWORD size_needed;
EmfPlusRecordHeader *record;
if (!metafile->comment_data_size)
{
DWORD data_size = max(256, size * 2 + 4);
metafile->comment_data = GdipAlloc(data_size);
if (!metafile->comment_data)
return OutOfMemory;
memcpy(metafile->comment_data, "EMF+", 4);
metafile->comment_data_size = data_size;
metafile->comment_data_length = 4;
}
size_needed = size + metafile->comment_data_length;
if (size_needed > metafile->comment_data_size)
{
DWORD data_size = size_needed * 2;
BYTE *new_data = GdipAlloc(data_size);
if (!new_data)
return OutOfMemory;
memcpy(new_data, metafile->comment_data, metafile->comment_data_length);
metafile->comment_data_size = data_size;
GdipFree(metafile->comment_data);
metafile->comment_data = new_data;
}
*result = metafile->comment_data + metafile->comment_data_length;
metafile->comment_data_length += size;
record = (EmfPlusRecordHeader*)*result;
record->Size = size;
record->DataSize = size - sizeof(EmfPlusRecordHeader);
return Ok;
}
static void METAFILE_WriteRecords(GpMetafile *metafile)
{
if (metafile->comment_data_length > 4)
{
GdiComment(metafile->record_dc, metafile->comment_data_length, metafile->comment_data);
metafile->comment_data_length = 4;
}
}
static GpStatus METAFILE_WriteHeader(GpMetafile *metafile, HDC hdc)
{
GpStatus stat;
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
{
EmfPlusHeader *header;
stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusHeader), (void**)&header);
if (stat != Ok)
return stat;
header->Header.Type = EmfPlusRecordTypeHeader;
if (metafile->metafile_type == MetafileTypeEmfPlusDual)
header->Header.Flags = 1;
else
header->Header.Flags = 0;
header->Version = 0xDBC01002;
if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY)
header->EmfPlusFlags = 1;
else
header->EmfPlusFlags = 0;
header->LogicalDpiX = GetDeviceCaps(hdc, LOGPIXELSX);
header->LogicalDpiY = GetDeviceCaps(hdc, LOGPIXELSY);
METAFILE_WriteRecords(metafile);
}
return Ok;
}
static GpStatus METAFILE_WriteEndOfFile(GpMetafile *metafile)
{
GpStatus stat;
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
{
EmfPlusRecordHeader *record;
stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusRecordHeader), (void**)&record);
if (stat != Ok)
return stat;
record->Type = EmfPlusRecordTypeEndOfFile;
record->Flags = 0;
METAFILE_WriteRecords(metafile);
}
return Ok;
}
GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect,
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
{
HDC record_dc;
REAL framerect_factor_x, framerect_factor_y;
RECT rc;
GpStatus stat;
TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
if (!hdc || type < EmfTypeEmfOnly || type > EmfTypeEmfPlusDual || !metafile)
return InvalidParameter;
if (!frameRect)
{
FIXME("not implemented for NULL rect\n");
return NotImplemented;
}
switch (frameUnit)
{
case MetafileFrameUnitPixel:
framerect_factor_x = 2540.0 / GetDeviceCaps(hdc, LOGPIXELSX);
framerect_factor_y = 2540.0 / GetDeviceCaps(hdc, LOGPIXELSY);
break;
case MetafileFrameUnitPoint:
framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
break;
case MetafileFrameUnitInch:
framerect_factor_x = framerect_factor_y = 2540.0;
break;
case MetafileFrameUnitDocument:
framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
break;
case MetafileFrameUnitMillimeter:
framerect_factor_x = framerect_factor_y = 100.0;
break;
case MetafileFrameUnitGdi:
framerect_factor_x = framerect_factor_y = 1.0;
break;
default:
return InvalidParameter;
}
rc.left = framerect_factor_x * frameRect->X;
rc.top = framerect_factor_y * frameRect->Y;
rc.right = rc.left + framerect_factor_x * frameRect->Width;
rc.bottom = rc.top + framerect_factor_y * frameRect->Height;
record_dc = CreateEnhMetaFileW(hdc, NULL, &rc, desc);
if (!record_dc)
return GenericError;
*metafile = GdipAlloc(sizeof(GpMetafile));
if(!*metafile)
{
DeleteEnhMetaFile(CloseEnhMetaFile(record_dc));
return OutOfMemory;
}
(*metafile)->image.type = ImageTypeMetafile;
(*metafile)->image.picture = NULL;
(*metafile)->image.flags = ImageFlagsNone;
(*metafile)->image.palette_flags = 0;
(*metafile)->image.palette_count = 0;
(*metafile)->image.palette_size = 0;
(*metafile)->image.palette_entries = NULL;
(*metafile)->bounds = *frameRect;
(*metafile)->unit = frameUnit;
(*metafile)->metafile_type = type;
(*metafile)->record_dc = record_dc;
(*metafile)->comment_data = NULL;
(*metafile)->comment_data_size = 0;
(*metafile)->comment_data_length = 0;
(*metafile)->hemf = NULL;
stat = METAFILE_WriteHeader(*metafile, hdc);
if (stat != Ok)
{
DeleteEnhMetaFile(CloseEnhMetaFile(record_dc));
GdipFree(*metafile);
*metafile = NULL;
return OutOfMemory;
}
return stat;
}
/*****************************************************************************
* GdipRecordMetafileI [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect *frameRect,
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
{
GpRectF frameRectF, *pFrameRectF;
TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
if (frameRect)
{
frameRectF.X = frameRect->X;
frameRectF.Y = frameRect->Y;
frameRectF.Width = frameRect->Width;
frameRectF.Height = frameRect->Height;
pFrameRectF = &frameRectF;
}
else
pFrameRectF = NULL;
return GdipRecordMetafile(hdc, type, pFrameRectF, frameUnit, desc, metafile);
}
GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result)
{
GpStatus stat;
if (!metafile->record_dc || metafile->record_graphics)
return InvalidParameter;
stat = graphics_from_image((GpImage*)metafile, &metafile->record_graphics);
if (stat == Ok)
*result = metafile->record_graphics;
return stat;
}
GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc)
{
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 = EmfPlusRecordTypeGetDC;
record->Flags = 0;
METAFILE_WriteRecords(metafile);
}
*hdc = metafile->record_dc;
return Ok;
}
GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc)
{
if (hdc != metafile->record_dc)
return InvalidParameter;
return Ok;
}
GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile)
{
GpStatus stat;
stat = METAFILE_WriteEndOfFile(metafile);
metafile->record_graphics = NULL;
metafile->hemf = CloseEnhMetaFile(metafile->record_dc);
metafile->record_dc = NULL;
GdipFree(metafile->comment_data);
metafile->comment_data = NULL;
metafile->comment_data_size = 0;
return stat;
}
GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE *hEmf)
{
TRACE("(%p,%p)\n", metafile, hEmf);
if (!metafile || !hEmf || !metafile->hemf)
return InvalidParameter;
*hEmf = metafile->hemf;
metafile->hemf = NULL;
return Ok;
}
static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
{
GpStatus stat = Ok;
stat = GdipGetDC(metafile->playback_graphics, &metafile->playback_dc);
if (stat == Ok)
{
/* The result of GdipGetDC always expects device co-ordinates, but the
* device co-ordinates of the source metafile do not correspond to
* device co-ordinates of the destination. Therefore, we set up the DC
* so that the metafile's bounds map to the destination points where we
* are drawing this metafile. */
SetMapMode(metafile->playback_dc, MM_ANISOTROPIC);
SetWindowOrgEx(metafile->playback_dc, metafile->bounds.X, metafile->bounds.Y, NULL);
SetWindowExtEx(metafile->playback_dc, metafile->bounds.Width, metafile->bounds.Height, NULL);
SetViewportOrgEx(metafile->playback_dc, metafile->playback_points[0].X, metafile->playback_points[0].Y, NULL);
SetViewportExtEx(metafile->playback_dc,
metafile->playback_points[1].X - metafile->playback_points[0].X,
metafile->playback_points[2].Y - metafile->playback_points[0].Y, NULL);
}
return stat;
}
static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile)
{
if (metafile->playback_dc)
{
GdipReleaseDC(metafile->playback_graphics, metafile->playback_dc);
metafile->playback_dc = NULL;
}
}
GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data)
{
TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data);
if (!metafile || (dataSize && !data) || !metafile->playback_graphics)
return InvalidParameter;
if (recordType >= 1 && recordType <= 0x7a)
{
/* regular EMF record */
if (metafile->playback_dc)
{
ENHMETARECORD *record;
record = GdipAlloc(dataSize + 8);
if (record)
{
record->iType = recordType;
record->nSize = dataSize;
memcpy(record->dParm, data, dataSize);
PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table,
record, metafile->handle_count);
GdipFree(record);
}
else
return OutOfMemory;
}
}
else
{
METAFILE_PlaybackReleaseDC((GpMetafile*)metafile);
switch(recordType)
{
case EmfPlusRecordTypeHeader:
case EmfPlusRecordTypeEndOfFile:
break;
case EmfPlusRecordTypeGetDC:
METAFILE_PlaybackGetDC((GpMetafile*)metafile);
break;
default:
FIXME("Not implemented for record type %x\n", recordType);
return NotImplemented;
}
}
return Ok;
}
struct enum_metafile_data
{
EnumerateMetafileProc callback;
void *callback_data;
GpMetafile *metafile;
};
static int CALLBACK enum_metafile_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
int nObj, LPARAM lpData)
{
BOOL ret;
struct enum_metafile_data *data = (struct enum_metafile_data*)lpData;
const BYTE* pStr;
data->metafile->handle_table = lpHTable;
data->metafile->handle_count = nObj;
/* First check for an EMF+ record. */
if (lpEMFR->iType == EMR_GDICOMMENT)
{
const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
{
int offset = 4;
while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
{
const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
if (record->DataSize)
pStr = (const BYTE*)(record+1);
else
pStr = NULL;
ret = data->callback(record->Type, record->Flags, record->DataSize,
pStr, data->callback_data);
if (!ret)
return 0;
offset += record->Size;
}
return 1;
}
}
if (lpEMFR->nSize != 8)
pStr = (const BYTE*)lpEMFR->dParm;
else
pStr = NULL;
return data->callback(lpEMFR->iType, 0, lpEMFR->nSize-8,
pStr, data->callback_data);
}
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *destPoints, INT count,
GDIPCONST GpRectF *srcRect, Unit srcUnit, EnumerateMetafileProc callback,
VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
{
struct enum_metafile_data data;
GpStatus stat;
GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
destPoints, count, srcRect, srcUnit, callback, callbackData,
imageAttributes);
if (!graphics || !metafile || !destPoints || count != 3 || !srcRect)
return InvalidParameter;
if (!metafile->hemf)
return InvalidParameter;
if (metafile->playback_graphics)
return ObjectBusy;
TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit,
debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]),
debugstr_pointf(&destPoints[2]));
data.callback = callback;
data.callback_data = callbackData;
data.metafile = real_metafile;
real_metafile->playback_graphics = graphics;
real_metafile->playback_dc = NULL;
memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3);
stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3);
if (stat == Ok && metafile->metafile_type == MetafileTypeEmf)
stat = METAFILE_PlaybackGetDC((GpMetafile*)metafile);
if (stat == Ok)
EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL);
METAFILE_PlaybackReleaseDC((GpMetafile*)metafile);
real_metafile->playback_graphics = NULL;
return stat;
}
+12 -11
View File
@@ -683,17 +683,18 @@ GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
return Ok;
}
if(!GetRgnBox(hrgn, &r)){
DeleteObject(hrgn);
return GenericError;
if(GetRgnBox(hrgn, &r)){
rect->X = r.left;
rect->Y = r.top;
rect->Width = r.right - r.left;
rect->Height = r.bottom - r.top;
}
else
status = GenericError;
rect->X = r.left;
rect->Y = r.top;
rect->Width = r.right - r.left;
rect->Height = r.bottom - r.top;
DeleteObject(hrgn);
return Ok;
return status;
}
/*****************************************************************************
@@ -1419,7 +1420,7 @@ static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGND
(*data)->rdh.rcBound.left = (*data)->rdh.rcBound.top = -0x400000;
(*data)->rdh.rcBound.right = (*data)->rdh.rcBound.bottom = 0x400000;
memcpy(&(*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
memcpy((*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
}
else
stat = OutOfMemory;
@@ -1468,7 +1469,7 @@ GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *region, GpRect *scans, INT *co
if (stat == Ok)
{
*count = data->rdh.nCount;
rects = (RECT*)&data->Buffer;
rects = (RECT*)data->Buffer;
if (scans)
{
@@ -1502,7 +1503,7 @@ GpStatus WINGDIPAPI GdipGetRegionScans(GpRegion *region, GpRectF *scans, INT *co
if (stat == Ok)
{
*count = data->rdh.nCount;
rects = (RECT*)&data->Buffer;
rects = (RECT*)data->Buffer;
if (scans)
{
+2 -2
View File
@@ -28,8 +28,8 @@ namespace Gdiplus
#include "gdiplusmem.h"
};
#include "gdiplustypes.h"
#include "gdiplusenums.h"
#include "gdiplustypes.h"
#include "gdiplusinit.h"
#include "gdipluspixelformats.h"
#include "gdiplusmetaheader.h"
@@ -48,8 +48,8 @@ namespace Gdiplus
#include "gdiplusmem.h"
#include "gdiplustypes.h"
#include "gdiplusenums.h"
#include "gdiplustypes.h"
#include "gdiplusinit.h"
#include "gdipluspixelformats.h"
#include "gdiplusmetaheader.h"
+287 -1
View File
@@ -42,6 +42,14 @@ enum BrushType
BrushTypeLinearGradient = 4
};
enum DriverStringOptions
{
DriverStringOptionsCmapLookup = 1,
DriverStringOptionsVertical = 2,
DriverStringOptionsRealizedAdvance = 4,
DriverStringOptionsLimitSubpixel = 4
};
enum FillMode
{
FillModeAlternate = 0,
@@ -430,10 +438,284 @@ enum HatchStyle
HatchStyleMax = HatchStyleTotal - 1
};
#define GDIP_EMFPLUS_RECORD_BASE 0x00004000
#define GDIP_WMF_RECORD_BASE 0x00010000
#define GDIP_WMF_RECORD_TO_EMFPLUS(x) ((x)|GDIP_WMF_RECORD_BASE)
enum EmfPlusRecordType {
WmfRecordTypeSetBkColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKCOLOR),
WmfRecordTypeSetBkMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKMODE),
WmfRecordTypeSetMapMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPMODE),
WmfRecordTypeSetROP2 = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETROP2),
WmfRecordTypeSetRelAbs = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETRELABS),
WmfRecordTypeSetPolyFillMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPOLYFILLMODE),
WmfRecordTypeSetStretchBltMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETSTRETCHBLTMODE),
WmfRecordTypeSetTextCharExtra = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCHAREXTRA),
WmfRecordTypeSetTextColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCOLOR),
WmfRecordTypeSetTextJustification = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTJUSTIFICATION),
WmfRecordTypeSetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWORG),
WmfRecordTypeSetWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWEXT),
WmfRecordTypeSetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTORG),
WmfRecordTypeSetViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTEXT),
WmfRecordTypeOffsetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETWINDOWORG),
WmfRecordTypeScaleWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEWINDOWEXT),
WmfRecordTypeOffsetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETVIEWPORTORG),
WmfRecordTypeScaleViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEVIEWPORTEXT),
WmfRecordTypeLineTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_LINETO),
WmfRecordTypeMoveTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_MOVETO),
WmfRecordTypeExcludeClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXCLUDECLIPRECT),
WmfRecordTypeIntersectClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_INTERSECTCLIPRECT),
WmfRecordTypeArc = GDIP_WMF_RECORD_TO_EMFPLUS(META_ARC),
WmfRecordTypeEllipse = GDIP_WMF_RECORD_TO_EMFPLUS(META_ELLIPSE),
WmfRecordTypeFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_FLOODFILL),
WmfRecordTypePie = GDIP_WMF_RECORD_TO_EMFPLUS(META_PIE),
WmfRecordTypeRectangle = GDIP_WMF_RECORD_TO_EMFPLUS(META_RECTANGLE),
WmfRecordTypeRoundRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_ROUNDRECT),
WmfRecordTypePatBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_PATBLT),
WmfRecordTypeSaveDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_SAVEDC),
WmfRecordTypeSetPixel = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPIXEL),
WmfRecordTypeOffsetClipRgn = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETCLIPRGN),
WmfRecordTypeTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_TEXTOUT),
WmfRecordTypeBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_BITBLT),
WmfRecordTypeStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHBLT),
WmfRecordTypePolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYGON),
WmfRecordTypePolyline = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYLINE),
WmfRecordTypeEscape = GDIP_WMF_RECORD_TO_EMFPLUS(META_ESCAPE),
WmfRecordTypeRestoreDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESTOREDC),
WmfRecordTypeFillRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FILLREGION),
WmfRecordTypeFrameRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FRAMEREGION),
WmfRecordTypeInvertRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_INVERTREGION),
WmfRecordTypePaintRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_PAINTREGION),
WmfRecordTypeSelectClipRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTCLIPREGION),
WmfRecordTypeSelectObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTOBJECT),
WmfRecordTypeSetTextAlign = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTALIGN),
WmfRecordTypeDrawText = GDIP_WMF_RECORD_TO_EMFPLUS(0x062F),
WmfRecordTypeChord = GDIP_WMF_RECORD_TO_EMFPLUS(META_CHORD),
WmfRecordTypeSetMapperFlags = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPPERFLAGS),
WmfRecordTypeExtTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTTEXTOUT),
WmfRecordTypeSetDIBToDev = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETDIBTODEV),
WmfRecordTypeSelectPalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTPALETTE),
WmfRecordTypeRealizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_REALIZEPALETTE),
WmfRecordTypeAnimatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_ANIMATEPALETTE),
WmfRecordTypeSetPalEntries = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPALENTRIES),
WmfRecordTypePolyPolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYPOLYGON),
WmfRecordTypeResizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESIZEPALETTE),
WmfRecordTypeDIBBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBBITBLT),
WmfRecordTypeDIBStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBSTRETCHBLT),
WmfRecordTypeDIBCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBCREATEPATTERNBRUSH),
WmfRecordTypeStretchDIB = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHDIB),
WmfRecordTypeExtFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTFLOODFILL),
WmfRecordTypeSetLayout = GDIP_WMF_RECORD_TO_EMFPLUS(0x0149),
WmfRecordTypeResetDC = GDIP_WMF_RECORD_TO_EMFPLUS(0x014C),
WmfRecordTypeStartDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x014D),
WmfRecordTypeStartPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x004F),
WmfRecordTypeEndPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x0050),
WmfRecordTypeAbortDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x0052),
WmfRecordTypeEndDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x005E),
WmfRecordTypeDeleteObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_DELETEOBJECT),
WmfRecordTypeCreatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPALETTE),
WmfRecordTypeCreateBrush = GDIP_WMF_RECORD_TO_EMFPLUS(0x00F8),
WmfRecordTypeCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPATTERNBRUSH),
WmfRecordTypeCreatePenIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPENINDIRECT),
WmfRecordTypeCreateFontIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEFONTINDIRECT),
WmfRecordTypeCreateBrushIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEBRUSHINDIRECT),
WmfRecordTypeCreateBitmapIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(0x02FD),
WmfRecordTypeCreateBitmap = GDIP_WMF_RECORD_TO_EMFPLUS(0x06FE),
WmfRecordTypeCreateRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEREGION),
EmfRecordTypeHeader = EMR_HEADER,
EmfRecordTypePolyBezier = EMR_POLYBEZIER,
EmfRecordTypePolygon = EMR_POLYGON,
EmfRecordTypePolyline = EMR_POLYLINE,
EmfRecordTypePolyBezierTo = EMR_POLYBEZIERTO,
EmfRecordTypePolyLineTo = EMR_POLYLINETO,
EmfRecordTypePolyPolyline = EMR_POLYPOLYLINE,
EmfRecordTypePolyPolygon = EMR_POLYPOLYGON,
EmfRecordTypeSetWindowExtEx = EMR_SETWINDOWEXTEX,
EmfRecordTypeSetWindowOrgEx = EMR_SETWINDOWORGEX,
EmfRecordTypeSetViewportExtEx = EMR_SETVIEWPORTEXTEX,
EmfRecordTypeSetViewportOrgEx = EMR_SETVIEWPORTORGEX,
EmfRecordTypeSetBrushOrgEx = EMR_SETBRUSHORGEX,
EmfRecordTypeEOF = EMR_EOF,
EmfRecordTypeSetPixelV = EMR_SETPIXELV,
EmfRecordTypeSetMapperFlags = EMR_SETMAPPERFLAGS,
EmfRecordTypeSetMapMode = EMR_SETMAPMODE,
EmfRecordTypeSetBkMode = EMR_SETBKMODE,
EmfRecordTypeSetPolyFillMode = EMR_SETPOLYFILLMODE,
EmfRecordTypeSetROP2 = EMR_SETROP2,
EmfRecordTypeSetStretchBltMode = EMR_SETSTRETCHBLTMODE,
EmfRecordTypeSetTextAlign = EMR_SETTEXTALIGN,
EmfRecordTypeSetColorAdjustment = EMR_SETCOLORADJUSTMENT,
EmfRecordTypeSetTextColor = EMR_SETTEXTCOLOR,
EmfRecordTypeSetBkColor = EMR_SETBKCOLOR,
EmfRecordTypeOffsetClipRgn = EMR_OFFSETCLIPRGN,
EmfRecordTypeMoveToEx = EMR_MOVETOEX,
EmfRecordTypeSetMetaRgn = EMR_SETMETARGN,
EmfRecordTypeExcludeClipRect = EMR_EXCLUDECLIPRECT,
EmfRecordTypeIntersectClipRect = EMR_INTERSECTCLIPRECT,
EmfRecordTypeScaleViewportExtEx = EMR_SCALEVIEWPORTEXTEX,
EmfRecordTypeScaleWindowExtEx = EMR_SCALEWINDOWEXTEX,
EmfRecordTypeSaveDC = EMR_SAVEDC,
EmfRecordTypeRestoreDC = EMR_RESTOREDC,
EmfRecordTypeSetWorldTransform = EMR_SETWORLDTRANSFORM,
EmfRecordTypeModifyWorldTransform = EMR_MODIFYWORLDTRANSFORM,
EmfRecordTypeSelectObject = EMR_SELECTOBJECT,
EmfRecordTypeCreatePen = EMR_CREATEPEN,
EmfRecordTypeCreateBrushIndirect = EMR_CREATEBRUSHINDIRECT,
EmfRecordTypeDeleteObject = EMR_DELETEOBJECT,
EmfRecordTypeAngleArc = EMR_ANGLEARC,
EmfRecordTypeEllipse = EMR_ELLIPSE,
EmfRecordTypeRectangle = EMR_RECTANGLE,
EmfRecordTypeRoundRect = EMR_ROUNDRECT,
EmfRecordTypeArc = EMR_ARC,
EmfRecordTypeChord = EMR_CHORD,
EmfRecordTypePie = EMR_PIE,
EmfRecordTypeSelectPalette = EMR_SELECTPALETTE,
EmfRecordTypeCreatePalette = EMR_CREATEPALETTE,
EmfRecordTypeSetPaletteEntries = EMR_SETPALETTEENTRIES,
EmfRecordTypeResizePalette = EMR_RESIZEPALETTE,
EmfRecordTypeRealizePalette = EMR_REALIZEPALETTE,
EmfRecordTypeExtFloodFill = EMR_EXTFLOODFILL,
EmfRecordTypeLineTo = EMR_LINETO,
EmfRecordTypeArcTo = EMR_ARCTO,
EmfRecordTypePolyDraw = EMR_POLYDRAW,
EmfRecordTypeSetArcDirection = EMR_SETARCDIRECTION,
EmfRecordTypeSetMiterLimit = EMR_SETMITERLIMIT,
EmfRecordTypeBeginPath = EMR_BEGINPATH,
EmfRecordTypeEndPath = EMR_ENDPATH,
EmfRecordTypeCloseFigure = EMR_CLOSEFIGURE,
EmfRecordTypeFillPath = EMR_FILLPATH,
EmfRecordTypeStrokeAndFillPath = EMR_STROKEANDFILLPATH,
EmfRecordTypeStrokePath = EMR_STROKEPATH,
EmfRecordTypeFlattenPath = EMR_FLATTENPATH,
EmfRecordTypeWidenPath = EMR_WIDENPATH,
EmfRecordTypeSelectClipPath = EMR_SELECTCLIPPATH,
EmfRecordTypeAbortPath = EMR_ABORTPATH,
EmfRecordTypeReserved_069 = 69,
EmfRecordTypeGdiComment = EMR_GDICOMMENT,
EmfRecordTypeFillRgn = EMR_FILLRGN,
EmfRecordTypeFrameRgn = EMR_FRAMERGN,
EmfRecordTypeInvertRgn = EMR_INVERTRGN,
EmfRecordTypePaintRgn = EMR_PAINTRGN,
EmfRecordTypeExtSelectClipRgn = EMR_EXTSELECTCLIPRGN,
EmfRecordTypeBitBlt = EMR_BITBLT,
EmfRecordTypeStretchBlt = EMR_STRETCHBLT,
EmfRecordTypeMaskBlt = EMR_MASKBLT,
EmfRecordTypePlgBlt = EMR_PLGBLT,
EmfRecordTypeSetDIBitsToDevice = 80,
EmfRecordTypeStretchDIBits = EMR_STRETCHDIBITS,
EmfRecordTypeExtCreateFontIndirect = EMR_EXTCREATEFONTINDIRECTW,
EmfRecordTypeExtTextOutA = EMR_EXTTEXTOUTA,
EmfRecordTypeExtTextOutW = EMR_EXTTEXTOUTW,
EmfRecordTypePolyBezier16 = EMR_POLYBEZIER16,
EmfRecordTypePolygon16 = EMR_POLYGON16,
EmfRecordTypePolyline16 = EMR_POLYLINE16,
EmfRecordTypePolyBezierTo16 = EMR_POLYBEZIERTO16,
EmfRecordTypePolylineTo16 = EMR_POLYLINETO16,
EmfRecordTypePolyPolyline16 = EMR_POLYPOLYLINE16,
EmfRecordTypePolyPolygon16 = EMR_POLYPOLYGON16,
EmfRecordTypePolyDraw16 = EMR_POLYDRAW16,
EmfRecordTypeCreateMonoBrush = EMR_CREATEMONOBRUSH,
EmfRecordTypeCreateDIBPatternBrushPt = EMR_CREATEDIBPATTERNBRUSHPT,
EmfRecordTypeExtCreatePen = EMR_EXTCREATEPEN,
EmfRecordTypePolyTextOutA = EMR_POLYTEXTOUTA,
EmfRecordTypePolyTextOutW = EMR_POLYTEXTOUTW,
EmfRecordTypeSetICMMode = 98,
EmfRecordTypeCreateColorSpace = 99,
EmfRecordTypeSetColorSpace = 100,
EmfRecordTypeDeleteColorSpace = 101,
EmfRecordTypeGLSRecord = 102,
EmfRecordTypeGLSBoundedRecord = 103,
EmfRecordTypePixelFormat = 104,
EmfRecordTypeDrawEscape = 105,
EmfRecordTypeExtEscape = 106,
EmfRecordTypeStartDoc = 107,
EmfRecordTypeSmallTextOut = 108,
EmfRecordTypeForceUFIMapping = 109,
EmfRecordTypeNamedEscape = 110,
EmfRecordTypeColorCorrectPalette = 111,
EmfRecordTypeSetICMProfileA = 112,
EmfRecordTypeSetICMProfileW = 113,
EmfRecordTypeAlphaBlend = 114,
EmfRecordTypeSetLayout = 115,
EmfRecordTypeTransparentBlt = 116,
EmfRecordTypeReserved_117 = 117,
EmfRecordTypeGradientFill = 118,
EmfRecordTypeSetLinkedUFIs = 119,
EmfRecordTypeSetTextJustification = 120,
EmfRecordTypeColorMatchToTargetW = 121,
EmfRecordTypeCreateColorSpaceW = 122,
EmfRecordTypeMax = 122,
EmfRecordTypeMin = 1,
EmfPlusRecordTypeInvalid = GDIP_EMFPLUS_RECORD_BASE,
EmfPlusRecordTypeHeader,
EmfPlusRecordTypeEndOfFile,
EmfPlusRecordTypeComment,
EmfPlusRecordTypeGetDC,
EmfPlusRecordTypeMultiFormatStart,
EmfPlusRecordTypeMultiFormatSection,
EmfPlusRecordTypeMultiFormatEnd,
EmfPlusRecordTypeObject,
EmfPlusRecordTypeClear,
EmfPlusRecordTypeFillRects,
EmfPlusRecordTypeDrawRects,
EmfPlusRecordTypeFillPolygon,
EmfPlusRecordTypeDrawLines,
EmfPlusRecordTypeFillEllipse,
EmfPlusRecordTypeDrawEllipse,
EmfPlusRecordTypeFillPie,
EmfPlusRecordTypeDrawPie,
EmfPlusRecordTypeDrawArc,
EmfPlusRecordTypeFillRegion,
EmfPlusRecordTypeFillPath,
EmfPlusRecordTypeDrawPath,
EmfPlusRecordTypeFillClosedCurve,
EmfPlusRecordTypeDrawClosedCurve,
EmfPlusRecordTypeDrawCurve,
EmfPlusRecordTypeDrawBeziers,
EmfPlusRecordTypeDrawImage,
EmfPlusRecordTypeDrawImagePoints,
EmfPlusRecordTypeDrawString,
EmfPlusRecordTypeSetRenderingOrigin,
EmfPlusRecordTypeSetAntiAliasMode,
EmfPlusRecordTypeSetTextRenderingHint,
EmfPlusRecordTypeSetTextContrast,
EmfPlusRecordTypeSetGammaValue,
EmfPlusRecordTypeSetInterpolationMode,
EmfPlusRecordTypeSetPixelOffsetMode,
EmfPlusRecordTypeSetCompositingMode,
EmfPlusRecordTypeSetCompositingQuality,
EmfPlusRecordTypeSave,
EmfPlusRecordTypeRestore,
EmfPlusRecordTypeBeginContainer,
EmfPlusRecordTypeBeginContainerNoParams,
EmfPlusRecordTypeEndContainer,
EmfPlusRecordTypeSetWorldTransform,
EmfPlusRecordTypeResetWorldTransform,
EmfPlusRecordTypeMultiplyWorldTransform,
EmfPlusRecordTypeTranslateWorldTransform,
EmfPlusRecordTypeScaleWorldTransform,
EmfPlusRecordTypeRotateWorldTransform,
EmfPlusRecordTypeSetPageTransform,
EmfPlusRecordTypeResetClip,
EmfPlusRecordTypeSetClipRect,
EmfPlusRecordTypeSetClipPath,
EmfPlusRecordTypeSetClipRegion,
EmfPlusRecordTypeOffsetClip,
EmfPlusRecordTypeDrawDriverString,
EmfPlusRecordTypeStrokeFillPath,
EmfPlusRecordTypeSerializableObject,
EmfPlusRecordTypeSetTSGraphics,
EmfPlusRecordTypeSetTSClip,
EmfPlusRecordTotal,
EmfPlusRecordTypeMax = EmfPlusRecordTotal-1,
EmfPlusRecordTypeMin = EmfPlusRecordTypeHeader
};
#ifndef __cplusplus
typedef enum Unit Unit;
typedef enum BrushType BrushType;
typedef enum DriverStringOptions DriverStringOptions;
typedef enum FillMode FillMode;
typedef enum LineCap LineCap;
typedef enum PathPointType PathPointType;
@@ -461,7 +743,7 @@ typedef enum StringTrimming StringTrimming;
typedef enum FontStyle FontStyle;
typedef enum StringFormatFlags StringFormatFlags;
typedef enum HotkeyPrefix HotkeyPrefix;
typedef enum PenAlignment GpPenAlignment;
typedef enum PenAlignment PenAlignment;
typedef enum PaletteFlags PaletteFlags;
typedef enum ImageCodecFlags ImageCodecFlags;
typedef enum CombineMode CombineMode;
@@ -471,7 +753,11 @@ typedef enum GpTestControlEnum GpTestControlEnum;
typedef enum MetafileFrameUnit MetafileFrameUnit;
typedef enum PenType PenType;
typedef enum HatchStyle HatchStyle;
typedef enum EmfPlusRecordType EmfPlusRecordType;
#endif /* end of c typedefs */
#undef GDIP_WMF_RECORD_TO_EMFPLUS
#define GDIP_WMF_RECORD_TO_EMFPLUS(x) ((EmfPlusRecordType)((x)|GDIP_WMF_RECORD_BASE))
#endif
+12
View File
@@ -206,10 +206,15 @@ GpStatus WINGDIPAPI GdipDrawRectanglesI(GpGraphics*,GpPen*,GDIPCONST GpRect*,INT
GpStatus WINGDIPAPI GdipDrawString(GpGraphics*,GDIPCONST WCHAR*,INT,
GDIPCONST GpFont*,GDIPCONST RectF*, GDIPCONST GpStringFormat*,
GDIPCONST GpBrush*);
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics*,
GDIPCONST GpMetafile*,GDIPCONST GpPointF*,INT,GDIPCONST GpRectF*,Unit,
EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics*,GpBrush*,GDIPCONST GpPointF*,INT,
REAL,GpFillMode);
GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics*,GpBrush*,GDIPCONST GpPoint*,INT,
REAL,GpFillMode);
GpStatus WINGDIPAPI GdipFillClosedCurve(GpGraphics*,GpBrush*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipFillClosedCurveI(GpGraphics*,GpBrush*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics*,GpBrush*,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipFillEllipseI(GpGraphics*,GpBrush*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipFillPath(GpGraphics*,GpBrush*,GpPath*);
@@ -472,6 +477,7 @@ GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient*,GDIPCONST ARGB*,
GDIPCONST REAL*,INT);
GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient*,ARGB*,REAL*,INT);
GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient*,INT*);
GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient*,GpMatrix*);
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient*);
GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient*,REAL,GpMatrixOrder);
GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient*,REAL,REAL,
@@ -520,7 +526,10 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR*, GDIPCONST Wm
GpMetafile**);
GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR*,GpMetafile**);
GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream*,GpMetafile**);
GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile*,HENHMETAFILE*);
GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile*,EmfPlusRecordType,UINT,UINT,GDIPCONST BYTE*);
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile*,UINT);
GpStatus WINGDIPAPI GdipRecordMetafile(HDC,EmfType,GDIPCONST GpRectF*,MetafileFrameUnit,GDIPCONST WCHAR*,GpMetafile**);
/* MetafileHeader */
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE,MetafileHeader*);
@@ -641,6 +650,9 @@ GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *, GpGraphics *, GpRect *);
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *, BYTE *, UINT, UINT *);
GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *, UINT *);
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *, GpGraphics *, HRGN *);
GpStatus WINGDIPAPI GdipGetRegionScans(GpRegion *, GpRectF *, INT *, GpMatrix *);
GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *, GpRect *, INT *, GpMatrix *);
GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *, UINT *, GpMatrix *);
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *, GpRegion *, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *, GpGraphics *, BOOL *);
+2
View File
@@ -22,6 +22,7 @@
#ifdef __cplusplus
class GpGraphics {};
class GpPen {};
class GpBrush {};
class GpHatch : public GpBrush {};
class GpSolidFill : public GpBrush {};
@@ -92,6 +93,7 @@ typedef WrapMode GpWrapMode;
typedef Color GpColor;
typedef FlushIntention GpFlushIntention;
typedef CoordinateSpace GpCoordinateSpace;
typedef PenAlignment GpPenAlignment;
typedef PenType GpPenType;
#endif
+1 -1
View File
@@ -110,7 +110,7 @@ public:
UINT Width;
UINT Height;
INT Stride;
PixelFormat PixelFormat;
Gdiplus::PixelFormat PixelFormat;
VOID* Scan0;
UINT_PTR Reserved;
};
+27
View File
@@ -55,6 +55,8 @@ typedef BOOL (CALLBACK * ImageAbort)(VOID *);
typedef ImageAbort DrawImageAbort;
typedef ImageAbort GetThumbnailImageAbort;
typedef BOOL (CALLBACK * EnumerateMetafileProc)(EmfPlusRecordType,UINT,UINT,const BYTE*,VOID*);
#ifdef __cplusplus
}
#endif
@@ -199,6 +201,31 @@ public:
INT Height;
};
class CharacterRange
{
public:
CharacterRange()
{
First = Length = 0;
}
CharacterRange(INT first, INT length)
{
First = first;
Length = length;
}
CharacterRange& operator=(const CharacterRange& rhs)
{
First = rhs.First;
Length = rhs.Length;
return *this;
}
public:
INT First;
INT Length;
};
#else /* end of c++ typedefs */
typedef struct Point
+2 -2
View File
@@ -49,7 +49,7 @@ reactos/dll/win32/cabinet # Synced to Wine-1.3.37
reactos/dll/win32/clusapi # Synced to Wine-1.3.37
reactos/dll/win32/comcat # Synced to Wine-1.3.37
reactos/dll/win32/comctl32 # Synced to Wine 1.3.37
reactos/dll/win32/comdlg32 # Autosync
reactos/dll/win32/comdlg32 # Synced to Wine 1.3.37
reactos/dll/win32/compstui # Synced to Wine-1.3.37
reactos/dll/win32/credui # Synced to Wine-1.3.37
reactos/dll/win32/crypt32 # Synced to Wine-1.3.37
@@ -61,7 +61,7 @@ reactos/dll/win32/dbghelp # Autosync
reactos/dll/win32/dciman32 # Autosync
reactos/dll/win32/dwmapi # Synced to Wine-1.3.37
reactos/dll/win32/fusion # Synced to Wine-1.3.37
reactos/dll/win32/gdiplus # Autosync
reactos/dll/win32/gdiplus # Synced to Wine-1.3.37
reactos/dll/win32/hhctrl.ocx # Autosync
reactos/dll/win32/hlink # Synced to Wine-1.3.37
reactos/dll/win32/hnetcfg # Synced to Wine-1.3.37