mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-29 04:13:32 +00:00
[GDIPLUS]
- Sync to Wine 1.3.37 svn path=/trunk/; revision=56055
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
|
||||
|
||||
+1548
-600
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
INT Stride;
|
||||
PixelFormat PixelFormat;
|
||||
Gdiplus::PixelFormat PixelFormat;
|
||||
VOID* Scan0;
|
||||
UINT_PTR Reserved;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user