- Sync gdiplus with wine head

svn path=/trunk/; revision=36023
This commit is contained in:
Dmitry Chapyshev 2008-09-07 10:32:49 +00:00
parent e6b5795006
commit 821316817e
15 changed files with 2304 additions and 169 deletions

View file

@ -36,6 +36,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
{
TRACE("(%p, %p)\n", brush, clone);
if(!brush || !clone)
return InvalidParameter;
@ -125,6 +127,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
{
COLORREF col = ARGB2COLORREF(startcolor);
TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
startcolor, endcolor, wrap, line);
if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
return InvalidParameter;
@ -156,6 +161,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
GpPointF stF;
GpPointF endF;
TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
startcolor, endcolor, wrap, line);
if(!startpoint || !endpoint)
return InvalidParameter;
@ -173,6 +181,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
{
GpPointF start, end;
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
wrap, line);
if(!line || !rect)
return InvalidParameter;
@ -190,6 +201,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
{
GpRectF rectF;
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
wrap, line);
rectF.X = (REAL) rect->X;
rectF.Y = (REAL) rect->Y;
rectF.Width = (REAL) rect->Width;
@ -205,6 +219,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect
ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
GpLineGradient **line)
{
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
wrap, line);
return GdipCreateLineBrushFromRect(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
wrap, line);
}
@ -213,6 +230,9 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
GpLineGradient **line)
{
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
wrap, line);
return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
wrap, line);
}
@ -222,6 +242,8 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
{
COLORREF col = ARGB2COLORREF(0xffffffff);
TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
if(!points || !grad)
return InvalidParameter;
@ -278,6 +300,8 @@ GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
GpStatus ret;
INT i;
TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
if(!points || !grad)
return InvalidParameter;
@ -305,6 +329,8 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
{
COLORREF col = ARGB2COLORREF(0xffffffff);
TRACE("(%p, %p)\n", path, grad);
if(!path || !grad)
return InvalidParameter;
@ -357,6 +383,8 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
{
COLORREF col = ARGB2COLORREF(color);
TRACE("(%x, %p)\n", color, sf);
if(!sf) return InvalidParameter;
*sf = GdipAlloc(sizeof(GpSolidFill));
@ -373,6 +401,53 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
return Ok;
}
/*******************************************************************************
* GdipCreateTexture [GDIPLUS.@]
*
* PARAMS
* image [I] image to use
* wrapmode [I] optional
* texture [O] pointer to the resulting texturebrush
*
* RETURNS
* SUCCESS: Ok
* FAILURE: element of GpStatus
*/
GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
GpTexture **texture)
{
UINT width, height;
GpImageAttributes attributes;
GpStatus stat;
TRACE("%p, %d %p\n", image, wrapmode, texture);
if (!(image && texture))
return InvalidParameter;
stat = GdipGetImageWidth(image, &width);
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,
texture);
}
GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode,
REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
{
GpImageAttributes attributes;
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);
}
/* FIXME: imageattr ignored */
GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
@ -387,6 +462,9 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
BOOL bm_is_selected;
BYTE *dibits, *buff, *textbits;
TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
texture);
if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
return InvalidParameter;
@ -491,11 +569,29 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageattr,
INT x, INT y, INT width, INT height, GpTexture **texture)
{
TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image, imageattr, x, y, width, height,
texture);
return GdipCreateTextureIA(image,imageattr,(REAL)x,(REAL)y,(REAL)width,(REAL)height,texture);
}
GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode,
INT x, INT y, INT width, INT height, GpTexture **texture)
{
GpImageAttributes imageattr;
TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
texture);
imageattr.wrap = wrapmode;
return GdipCreateTextureIA(image, &imageattr, x, y, width, height, texture);
}
GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
{
TRACE("(%p, %p)\n", brush, type);
if(!brush || !type) return InvalidParameter;
*type = brush->bt;
@ -505,6 +601,8 @@ GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
{
TRACE("(%p)\n", brush);
if(!brush) return InvalidParameter;
switch(brush->bt)
@ -531,7 +629,9 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
BOOL *usinggamma)
{
if(!line)
TRACE("(%p, %p)\n", line, usinggamma);
if(!line || !usinggamma)
return InvalidParameter;
*usinggamma = line->gamma;
@ -541,6 +641,8 @@ GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
{
TRACE("(%p, %p)\n", brush, wrapmode);
if(!brush || !wrapmode)
return InvalidParameter;
@ -552,6 +654,8 @@ GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapm
GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend,
REAL *positions, INT count)
{
TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count);
if(!brush || !blend || !positions || count <= 0)
return InvalidParameter;
@ -568,6 +672,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend,
GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
{
TRACE("(%p, %p)\n", brush, count);
if(!brush || !count)
return InvalidParameter;
@ -579,6 +685,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *co
GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad,
GpPointF *point)
{
TRACE("(%p, %p)\n", grad, point);
if(!grad || !point)
return InvalidParameter;
@ -594,6 +702,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
GpStatus ret;
GpPointF ptf;
TRACE("(%p, %p)\n", grad, point);
if(!point)
return InvalidParameter;
@ -610,6 +720,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad,
REAL *x, REAL *y)
{
TRACE("(%p, %p, %p)\n", grad, x, y);
if(!grad || !x || !y)
return InvalidParameter;
@ -622,6 +734,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad,
BOOL *gamma)
{
TRACE("(%p, %p)\n", grad, gamma);
if(!grad || !gamma)
return InvalidParameter;
@ -633,6 +747,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
INT *count)
{
TRACE("(%p, %p)\n", grad, count);
if(!grad || !count)
return InvalidParameter;
@ -647,6 +763,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect
GpPath* path;
GpStatus stat;
TRACE("(%p, %p)\n", brush, rect);
if(!brush || !rect)
return InvalidParameter;
@ -672,6 +790,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect
GpRectF rectf;
GpStatus stat;
TRACE("(%p, %p)\n", brush, rect);
if(!brush || !rect)
return InvalidParameter;
@ -703,6 +823,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
GpWrapMode *wrapmode)
{
TRACE("(%p, %p)\n", brush, wrapmode);
if(!brush || !wrapmode)
return InvalidParameter;
@ -713,6 +835,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb)
{
TRACE("(%p, %p)\n", sf, argb);
if(!sf || !argb)
return InvalidParameter;
@ -738,6 +862,8 @@ GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush,
GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line,
BOOL usegamma)
{
TRACE("(%p, %d)\n", line, usegamma);
if(!line)
return InvalidParameter;
@ -763,6 +889,8 @@ GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus,
GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line,
GpWrapMode wrap)
{
TRACE("(%p, %d)\n", line, wrap);
if(!line || wrap == WrapModeClamp)
return InvalidParameter;
@ -774,6 +902,8 @@ GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line,
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
ARGB argb)
{
TRACE("(%p, %x)\n", grad, argb);
if(!grad)
return InvalidParameter;
@ -789,6 +919,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad,
GpPointF *point)
{
TRACE("(%p, %p)\n", grad, point);
if(!grad || !point)
return InvalidParameter;
@ -803,6 +935,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad,
{
GpPointF ptf;
TRACE("(%p, %p)\n", grad, point);
if(!point)
return InvalidParameter;
@ -815,6 +949,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad,
REAL x, REAL y)
{
TRACE("(%p, %.2f, %.2f)\n", grad, x, y);
if(!grad)
return InvalidParameter;
@ -827,6 +963,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
BOOL gamma)
{
TRACE("(%p, %d)\n", grad, gamma);
if(!grad)
return InvalidParameter;
@ -867,6 +1005,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
GpWrapMode wrap)
{
TRACE("(%p, %d)\n", grad, wrap);
if(!grad)
return InvalidParameter;
@ -877,6 +1017,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
{
TRACE("(%p, %x)\n", sf, argb);
if(!sf)
return InvalidParameter;
@ -906,6 +1048,8 @@ GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture,
GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
ARGB color2)
{
TRACE("(%p, %x, %x)\n", brush, color1, color2);
if(!brush)
return InvalidParameter;
@ -917,6 +1061,8 @@ GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors)
{
TRACE("(%p, %p)\n", brush, colors);
if(!brush || !colors)
return InvalidParameter;
@ -959,8 +1105,18 @@ GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
return NotImplemented;
}
GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
REAL dx, REAL dy, GpMatrixOrder order)
{
FIXME("stub: %p %f %f %d\n", brush, dx, dy, order);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
{
TRACE("(%p, %p)\n", brush, rect);
if(!brush || !rect)
return InvalidParameter;
@ -978,6 +1134,8 @@ GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
GpRectF rectF;
GpStatus ret;
TRACE("(%p, %p)\n", brush, rect);
if(!rect)
return InvalidParameter;

View file

@ -33,6 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
GpCustomLineCap** to)
{
TRACE("(%p, %p)\n", from, to);
if(!from || !to)
return InvalidParameter;
@ -108,6 +110,8 @@ GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath
GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
{
TRACE("(%p)\n", customCap);
if(!customCap)
return InvalidParameter;
@ -121,6 +125,8 @@ GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap,
GpLineJoin* lineJoin)
{
TRACE("(%p, %p)\n", customCap, lineJoin);
if(!customCap || !lineJoin)
return InvalidParameter;
@ -132,6 +138,8 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap,
GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap* custom,
REAL* widthScale)
{
TRACE("(%p, %p)\n", custom, widthScale);
if(!custom || !widthScale)
return InvalidParameter;
@ -168,6 +176,8 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap* custom,
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap* custom,
REAL* inset)
{
TRACE("(%p, %p)\n", custom, inset);
if(!custom || !inset)
return InvalidParameter;
@ -191,6 +201,8 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap* custom,
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* custom,
GpLineJoin join)
{
TRACE("(%p, %d)\n", custom, join);
if(!custom)
return InvalidParameter;
@ -212,6 +224,8 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap* custom,
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLineCap *baseCap)
{
TRACE("(%p, %p)\n", customCap, baseCap);
if(!customCap || !baseCap)
return InvalidParameter;
@ -219,3 +233,94 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLi
return Ok;
}
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
GpAdjustableArrowCap **cap)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middle)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middle)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width)
{
static int calls;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}

View file

@ -166,9 +166,14 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
HFONT hfont, oldfont;
TEXTMETRICW textmet;
TRACE("(%p, %p, %p)\n", hdc, logfont, font);
if(!logfont || !font)
return InvalidParameter;
if (logfont->lfFaceName[0] == 0)
return NotTrueTypeFont;
*font = GdipAlloc(sizeof(GpFont));
if(!*font) return OutOfMemory;
@ -203,6 +208,8 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC hdc,
{
LOGFONTW lfw;
TRACE("(%p, %p, %p)\n", hdc, lfa, font);
if(!lfa || !font)
return InvalidParameter;
@ -221,6 +228,8 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC hdc,
*/
GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
{
TRACE("(%p)\n", font);
if(!font)
return InvalidParameter;
@ -237,6 +246,8 @@ GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font)
HFONT hfont;
LOGFONTW lfw;
TRACE("(%p, %p)\n", hdc, font);
if(!font)
return InvalidParameter;
@ -250,6 +261,29 @@ GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font)
return GdipCreateFontFromLogfontW(hdc, &lfw, font);
}
/*******************************************************************************
* GdipGetFamily [GDIPLUS.@]
*
* Returns the FontFamily for the specified Font
*
* PARAMS
* font [I] Font to request from
* family [O] Resulting FontFamily object
*
* RETURNS
* SUCCESS: Ok
* FAILURE: An element of GpStatus
*/
GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
{
TRACE("%p %p\n", font, family);
if (!(font && family))
return InvalidParameter;
return GdipCreateFontFamilyFromName(font->lfw.lfFaceName, NULL, family);
}
/******************************************************************************
* GdipGetFontSize [GDIPLUS.@]
*
@ -268,6 +302,8 @@ GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font)
*/
GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
{
TRACE("(%p, %p)\n", font, size);
if (!(font && size)) return InvalidParameter;
*size = font->emSize;
@ -275,6 +311,40 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
return Ok;
}
/*******************************************************************************
* GdipGetFontStyle [GDIPLUS.@]
*
* Gets the font's style, returned in bitwise OR of FontStyle enumeration
*
* PARAMS
* font [I] font to request from
* style [O] resulting pointer to a FontStyle enumeration
*
* RETURNS
* SUCCESS: Ok
* FAILURE: InvalidParameter
*/
GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
{
TRACE("%p %p\n", font, style);
if (!(font && style))
return InvalidParameter;
if (font->lfw.lfWeight > 400)
*style = FontStyleBold;
else
*style = 0;
if (font->lfw.lfItalic)
*style |= FontStyleItalic;
if (font->lfw.lfUnderline)
*style |= FontStyleUnderline;
if (font->lfw.lfStrikeOut)
*style |= FontStyleStrikeout;
return Ok;
}
/*******************************************************************************
* GdipGetFontUnit [GDIPLUS.@]
*
@ -288,6 +358,8 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
*/
GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
{
TRACE("(%p, %p)\n", font, unit);
if (!(font && unit)) return InvalidParameter;
*unit = font->unit;
@ -301,6 +373,8 @@ GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
LOGFONTW *lfw)
{
TRACE("(%p, %p, %p)\n", font, graphics, lfw);
/* FIXME: use graphics */
if(!font || !graphics || !lfw)
return InvalidParameter;
@ -315,6 +389,8 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
*/
GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
{
TRACE("(%p, %p)\n", font, cloneFont);
if(!font || !cloneFont)
return InvalidParameter;
@ -326,6 +402,31 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
return Ok;
}
/*******************************************************************************
* GdipGetFontHeight [GDIPLUS.@]
* PARAMS
* font [I] Font to retrieve height from
* graphics [I] The current graphics context
* height [O] Resulting height
* RETURNS
* SUCCESS: Ok
* FAILURE: Another element of GpStatus
*
* NOTES
* Forwards to GdipGetFontHeightGivenDPI
*/
GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
GDIPCONST GpGraphics *graphics, REAL *height)
{
REAL dpi;
TRACE("%p %p %p\n", font, graphics, height);
dpi = GetDeviceCaps(graphics->hdc, LOGPIXELSY);
return GdipGetFontHeightGivenDPI(font, dpi, height);
}
/*******************************************************************************
* GdipGetFontHeightGivenDPI [GDIPLUS.@]
* PARAMS
@ -343,12 +444,22 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
*/
GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
{
if (!(font && height)) return InvalidParameter;
FIXME("%p (%s), %f, %p\n", font,
TRACE("%p (%s), %f, %p\n", font,
debugstr_w(font->lfw.lfFaceName), dpi, height);
return NotImplemented;
if (!(font && height)) return InvalidParameter;
switch (font->unit)
{
case UnitPixel:
*height = font->emSize;
break;
default:
FIXME("Unhandled unit type: %d\n", font->unit);
return NotImplemented;
}
return Ok;
}
/***********************************************************************
@ -529,6 +640,8 @@ GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family,
GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family,
INT style, UINT16* CellDescent)
{
TRACE("(%p, %d, %p)\n", family, style, CellDescent);
if (!(family && CellDescent)) return InvalidParameter;
*CellDescent = family->tmw.tmDescent;
@ -635,6 +748,8 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
{
static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
TRACE("(%p)\n", nativeFamily);
if (nativeFamily == NULL) return InvalidParameter;
return GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily);
@ -658,6 +773,8 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamil
* affect anything */
static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
TRACE("(%p)\n", nativeFamily);
if (nativeFamily == NULL) return InvalidParameter;
return GdipCreateFontFamilyFromName(MSSansSerif, NULL, nativeFamily);

View file

@ -311,3 +311,58 @@ void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
*x = roundr(tension * (xadj - xend) + xend);
*y = roundr(tension * (yadj - yend) + yend);
}
/* make sure path has enough space for len more points */
BOOL lengthen_path(GpPath *path, INT len)
{
/* initial allocation */
if(path->datalen == 0){
path->datalen = len * 2;
path->pathdata.Points = GdipAlloc(path->datalen * sizeof(PointF));
if(!path->pathdata.Points) return FALSE;
path->pathdata.Types = GdipAlloc(path->datalen);
if(!path->pathdata.Types){
GdipFree(path->pathdata.Points);
return FALSE;
}
}
/* reallocation, double size of arrays */
else if(path->datalen - path->pathdata.Count < len){
while(path->datalen - path->pathdata.Count < len)
path->datalen *= 2;
path->pathdata.Points = HeapReAlloc(GetProcessHeap(), 0,
path->pathdata.Points, path->datalen * sizeof(PointF));
if(!path->pathdata.Points) return FALSE;
path->pathdata.Types = HeapReAlloc(GetProcessHeap(), 0,
path->pathdata.Types, path->datalen);
if(!path->pathdata.Types) return FALSE;
}
return TRUE;
}
/* recursive deletion of GpRegion nodes */
inline void delete_element(region_element* element)
{
switch(element->type)
{
case RegionDataRect:
break;
case RegionDataPath:
GdipDeletePath(element->elementdata.pathdata.path);
break;
case RegionDataEmptyRect:
case RegionDataInfiniteRect:
break;
default:
delete_element(element->elementdata.combine.left);
delete_element(element->elementdata.combine.right);
GdipFree(element->elementdata.combine.left);
GdipFree(element->elementdata.combine.right);
break;
}
}

View file

@ -21,8 +21,8 @@
@ stdcall GdipAddPathLine(ptr long long long long)
@ stdcall GdipAddPathLineI(ptr long long long long)
@ stdcall GdipAddPathPath(ptr ptr long)
@ stub GdipAddPathPie
@ stub GdipAddPathPieI
@ stdcall GdipAddPathPie(ptr long long long long long long)
@ stdcall GdipAddPathPieI(ptr long long long long long long)
@ stdcall GdipAddPathPolygon(ptr ptr long)
@ stdcall GdipAddPathPolygonI(ptr ptr long)
@ stdcall GdipAddPathRectangle(ptr long long long long)
@ -69,7 +69,7 @@
@ stdcall GdipConvertToEmfPlus(ptr ptr ptr long ptr ptr)
@ stub GdipConvertToEmfPlusToFile
@ stub GdipConvertToEmfPlusToStream
@ stub GdipCreateAdjustableArrowCap
@ stdcall GdipCreateAdjustableArrowCap(long long long ptr)
@ stub GdipCreateBitmapFromDirectDrawSurface
@ stdcall GdipCreateBitmapFromFile(wstr ptr)
@ stdcall GdipCreateBitmapFromFileICM(wstr ptr)
@ -131,9 +131,9 @@
@ stdcall GdipCreateSolidFill(long ptr)
@ stdcall GdipCreateStreamOnFile(ptr long ptr)
@ stdcall GdipCreateStringFormat(long long ptr)
@ stub GdipCreateTexture2
@ stub GdipCreateTexture2I
@ stub GdipCreateTexture
@ stdcall GdipCreateTexture2(ptr long long long long long ptr)
@ stdcall GdipCreateTexture2I(ptr long long long long long ptr)
@ stdcall GdipCreateTexture(ptr long ptr)
@ stdcall GdipCreateTextureIA(ptr ptr long long long long ptr)
@ stdcall GdipCreateTextureIAI(ptr ptr long long long long ptr)
@ stdcall GdipDeleteBrush(ptr)
@ -213,8 +213,8 @@
@ stub GdipEnumerateMetafileSrcRectDestPointsI
@ stub GdipEnumerateMetafileSrcRectDestRect
@ stub GdipEnumerateMetafileSrcRectDestRectI
@ stub GdipFillClosedCurve2
@ stub GdipFillClosedCurve2I
@ stdcall GdipFillClosedCurve2(ptr ptr ptr long long long)
@ stdcall GdipFillClosedCurve2I(ptr ptr ptr long long long)
@ stub GdipFillClosedCurve
@ stub GdipFillClosedCurveI
@ stdcall GdipFillEllipse(ptr ptr long long long long)
@ -233,13 +233,13 @@
@ stdcall GdipFillRegion(ptr ptr ptr)
@ stdcall GdipFindFirstImageItem(ptr ptr)
@ stub GdipFindNextImageItem
@ stub GdipFlattenPath
@ stdcall GdipFlattenPath(ptr ptr long)
@ stdcall GdipFlush(ptr long)
@ stdcall GdipFree(ptr)
@ stub GdipGetAdjustableArrowCapFillState
@ stub GdipGetAdjustableArrowCapHeight
@ stub GdipGetAdjustableArrowCapMiddleInset
@ stub GdipGetAdjustableArrowCapWidth
@ stdcall GdipGetAdjustableArrowCapFillState(ptr ptr)
@ stdcall GdipGetAdjustableArrowCapHeight(ptr ptr)
@ stdcall GdipGetAdjustableArrowCapMiddleInset(ptr ptr)
@ stdcall GdipGetAdjustableArrowCapWidth(ptr ptr)
@ stub GdipGetAllPropertyItems
@ stdcall GdipGetBrushType(ptr ptr)
@ stdcall GdipGetCellAscent(ptr long ptr)
@ -263,14 +263,14 @@
@ stdcall GdipGetEmHeight(ptr long ptr)
@ stub GdipGetEncoderParameterList
@ stub GdipGetEncoderParameterListSize
@ stub GdipGetFamily
@ stdcall GdipGetFamily(ptr ptr)
@ stdcall GdipGetFamilyName(ptr ptr long)
@ stdcall GdipGetFontCollectionFamilyCount(ptr ptr)
@ stdcall GdipGetFontCollectionFamilyList(ptr long ptr ptr)
@ stub GdipGetFontHeight
@ stdcall GdipGetFontHeight(ptr ptr ptr)
@ stdcall GdipGetFontHeightGivenDPI(ptr long ptr)
@ stdcall GdipGetFontSize(ptr ptr)
@ stub GdipGetFontStyle
@ stdcall GdipGetFontStyle(ptr ptr)
@ stdcall GdipGetFontUnit(ptr ptr)
@ stdcall GdipGetGenericFontFamilyMonospace(ptr)
@ stdcall GdipGetGenericFontFamilySansSerif(ptr)
@ -403,7 +403,7 @@
@ stub GdipGetVisibleClipBounds
@ stub GdipGetVisibleClipBoundsI
@ stdcall GdipGetWorldTransform(ptr ptr)
@ stub GdipGraphicsClear
@ stdcall GdipGraphicsClear(ptr long)
@ stub GdipGraphicsSetAbort
@ stub GdipImageForceValidation
@ stdcall GdipImageGetFrameCount(ptr ptr ptr)
@ -414,7 +414,7 @@
@ stub GdipImageSetAbort
@ stub GdipInitializePalette
@ stdcall GdipInvertMatrix(ptr)
@ stub GdipIsClipEmpty
@ stdcall GdipIsClipEmpty(ptr ptr)
@ stdcall GdipIsEmptyRegion(ptr ptr ptr)
@ stdcall GdipIsEqualRegion(ptr ptr ptr ptr)
@ stdcall GdipIsInfiniteRegion(ptr ptr ptr)
@ -455,12 +455,12 @@
@ stdcall GdipPathIterGetCount(ptr ptr)
@ stdcall GdipPathIterGetSubpathCount(ptr ptr)
@ stdcall GdipPathIterHasCurve(ptr ptr)
@ stub GdipPathIterIsValid
@ stdcall GdipPathIterIsValid(ptr ptr)
@ stdcall GdipPathIterNextMarker(ptr ptr ptr ptr)
@ stub GdipPathIterNextMarkerPath
@ stub GdipPathIterNextPathType
@ stdcall GdipPathIterNextMarkerPath(ptr ptr ptr)
@ stdcall GdipPathIterNextPathType(ptr ptr ptr ptr ptr)
@ stdcall GdipPathIterNextSubpath(ptr ptr ptr ptr ptr)
@ stub GdipPathIterNextSubpathPath
@ stdcall GdipPathIterNextSubpathPath(ptr ptr ptr ptr)
@ stdcall GdipPathIterRewind(ptr)
@ stub GdipPlayMetafileRecord
@ stub GdipPlayTSClientRecord
@ -474,7 +474,7 @@
@ stub GdipRecordMetafileStreamI
@ stdcall GdipReleaseDC(ptr ptr)
@ stdcall GdipRemovePropertyItem(ptr long)
@ stub GdipResetClip
@ stdcall GdipResetClip(ptr)
@ stub GdipResetImageAttributes
@ stub GdipResetLineTransform
@ stub GdipResetPageTransform
@ -482,9 +482,9 @@
@ stub GdipResetPathGradientTransform
@ stub GdipResetPenTransform
@ stub GdipResetTextureTransform
@ stub GdipResetWorldTransform
@ stdcall GdipResetWorldTransform(ptr)
@ stdcall GdipRestoreGraphics(ptr long)
@ stub GdipReversePath
@ stdcall GdipReversePath(ptr)
@ stub GdipRotateLineTransform
@ stdcall GdipRotateMatrix(ptr long long)
@ stub GdipRotatePathGradientTransform
@ -502,10 +502,10 @@
@ stub GdipScalePenTransform
@ stub GdipScaleTextureTransform
@ stdcall GdipScaleWorldTransform(ptr long long long)
@ stub GdipSetAdjustableArrowCapFillState
@ stub GdipSetAdjustableArrowCapHeight
@ stub GdipSetAdjustableArrowCapMiddleInset
@ stub GdipSetAdjustableArrowCapWidth
@ stdcall GdipSetAdjustableArrowCapFillState(ptr long)
@ stdcall GdipSetAdjustableArrowCapHeight(ptr long)
@ stdcall GdipSetAdjustableArrowCapMiddleInset(ptr long)
@ stdcall GdipSetAdjustableArrowCapWidth(ptr long)
@ stub GdipSetClipGraphics
@ stub GdipSetClipHrgn
@ stub GdipSetClipPath
@ -611,7 +611,7 @@
@ stdcall GdipTransformRegion(ptr ptr)
@ stub GdipTranslateClip
@ stub GdipTranslateClipI
@ stub GdipTranslateLineTransform
@ stdcall GdipTranslateLineTransform(ptr long long long)
@ stdcall GdipTranslateMatrix(ptr long long long)
@ stub GdipTranslatePathGradientTransform
@ stub GdipTranslatePenTransform

View file

@ -52,6 +52,11 @@ extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
REAL tension, REAL *x, REAL *y);
extern BOOL lengthen_path(GpPath *path, INT len);
typedef struct region_element region_element;
extern inline void delete_element(region_element *element);
static inline INT roundr(REAL x)
{
return (INT) floor(x + 0.5);
@ -93,6 +98,8 @@ struct GpGraphics{
GpUnit unit; /* page unit */
REAL scale; /* page scale */
GpMatrix * worldtrans; /* world transform */
BOOL busy; /* hdc handle obtained by GdipGetDC */
GpRegion *clip;
};
struct GpBrush{
@ -160,6 +167,10 @@ struct GpCustomLineCap{
REAL scale;
};
struct GpAdustableArrowCap{
GpCustomLineCap cap;
};
struct GpImage{
IPicture* picture;
ImageType type;
@ -215,7 +226,16 @@ struct GpFontFamily{
WCHAR FamilyName[LF_FACESIZE];
};
typedef struct region_element
/* internal use */
typedef enum RegionType
{
RegionDataRect = 0x10000000,
RegionDataPath = 0x10000001,
RegionDataEmptyRect = 0x10000002,
RegionDataInfiniteRect = 0x10000003,
} RegionType;
struct region_element
{
DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */
union
@ -238,7 +258,7 @@ typedef struct region_element
struct region_element *right; /* what *left was combined with */
} combine;
} elementdata;
} region_element;
};
struct GpRegion{
struct

File diff suppressed because it is too large Load diff

View file

@ -33,35 +33,131 @@
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
/* make sure path has enough space for len more points */
static BOOL lengthen_path(GpPath *path, INT len)
typedef struct path_list_node_t path_list_node_t;
struct path_list_node_t {
GpPointF pt;
BYTE type; /* PathPointTypeStart or PathPointTypeLine */
path_list_node_t *next;
};
/* init list */
static BOOL init_path_list(path_list_node_t **node, REAL x, REAL y)
{
/* initial allocation */
if(path->datalen == 0){
path->datalen = len * 2;
*node = GdipAlloc(sizeof(path_list_node_t));
if(!*node)
return FALSE;
path->pathdata.Points = GdipAlloc(path->datalen * sizeof(PointF));
if(!path->pathdata.Points) return FALSE;
(*node)->pt.X = x;
(*node)->pt.Y = y;
(*node)->type = PathPointTypeStart;
(*node)->next = NULL;
path->pathdata.Types = GdipAlloc(path->datalen);
if(!path->pathdata.Types){
GdipFree(path->pathdata.Points);
return TRUE;
}
/* free all nodes including argument */
static void free_path_list(path_list_node_t *node)
{
path_list_node_t *n = node;
while(n){
n = n->next;
GdipFree(node);
node = n;
}
}
/* Add a node after 'node' */
/*
* Returns
* pointer on success
* NULL on allocation problems
*/
static path_list_node_t* add_path_list_node(path_list_node_t *node, REAL x, REAL y, BOOL type)
{
path_list_node_t *new;
new = GdipAlloc(sizeof(path_list_node_t));
if(!new)
return NULL;
new->pt.X = x;
new->pt.Y = y;
new->type = type;
new->next = node->next;
node->next = new;
return new;
}
/* returns element count */
static INT path_list_count(path_list_node_t *node)
{
INT count = 1;
while((node = node->next))
++count;
return count;
}
/* GdipFlattenPath helper */
/*
* Used to recursively flatten single Bezier curve
* Parameters:
* - start : pointer to start point node;
* - (x2, y2): first control point;
* - (x3, y3): second control point;
* - end : pointer to end point node
* - flatness: admissible error of linear approximation.
*
* Return value:
* TRUE : success
* FALSE: out of memory
*
* TODO: used quality criteria should be revised to match native as
* closer as possible.
*/
static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, REAL y3,
path_list_node_t *end, REAL flatness)
{
/* this 5 middle points with start/end define to half-curves */
GpPointF mp[5];
GpPointF pt, pt_st;
path_list_node_t *node;
/* calculate bezier curve middle points == new control points */
mp[0].X = (start->pt.X + x2) / 2.0;
mp[0].Y = (start->pt.Y + y2) / 2.0;
/* middle point between control points */
pt.X = (x2 + x3) / 2.0;
pt.Y = (y2 + y3) / 2.0;
mp[1].X = (mp[0].X + pt.X) / 2.0;
mp[1].Y = (mp[0].Y + pt.Y) / 2.0;
mp[4].X = (end->pt.X + x3) / 2.0;
mp[4].Y = (end->pt.Y + y3) / 2.0;
mp[3].X = (mp[4].X + pt.X) / 2.0;
mp[3].Y = (mp[4].Y + pt.Y) / 2.0;
mp[2].X = (mp[1].X + mp[3].X) / 2.0;
mp[2].Y = (mp[1].Y + mp[3].Y) / 2.0;
pt = end->pt;
pt_st = start->pt;
/* check flatness as a half of distance between middle point and a linearized path */
if(fabs(((pt.Y - pt_st.Y)*mp[2].X + (pt_st.X - pt.X)*mp[2].Y +
(pt_st.Y*pt.X - pt_st.X*pt.Y))) <=
(0.5 * flatness*sqrt((powf(pt.Y - pt_st.Y, 2.0) + powf(pt_st.X - pt.X, 2.0))))){
return TRUE;
}
else
/* add a middle point */
if(!(node = add_path_list_node(start, mp[2].X, mp[2].Y, PathPointTypeLine)))
return FALSE;
}
}
/* reallocation, double size of arrays */
else if(path->datalen - path->pathdata.Count < len){
while(path->datalen - path->pathdata.Count < len)
path->datalen *= 2;
path->pathdata.Points = HeapReAlloc(GetProcessHeap(), 0,
path->pathdata.Points, path->datalen * sizeof(PointF));
if(!path->pathdata.Points) return FALSE;
path->pathdata.Types = HeapReAlloc(GetProcessHeap(), 0,
path->pathdata.Types, path->datalen);
if(!path->pathdata.Types) return FALSE;
}
/* do the same with halfs */
flatten_bezier(start, mp[0].X, mp[0].Y, mp[1].X, mp[1].Y, node, flatness);
flatten_bezier(node, mp[3].X, mp[3].Y, mp[4].X, mp[4].Y, end, flatness);
return TRUE;
}
@ -71,6 +167,9 @@ GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2,
{
INT count, old_count, i;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
path, x1, y1, x2, y2, startAngle, sweepAngle);
if(!path)
return InvalidParameter;
@ -100,6 +199,9 @@ GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2,
GpStatus WINGDIPAPI GdipAddPathArcI(GpPath *path, INT x1, INT y1, INT x2,
INT y2, REAL startAngle, REAL sweepAngle)
{
TRACE("(%p, %d, %d, %d, %d, %.2f, %.2f)\n",
path, x1, y1, x2, y2, startAngle, sweepAngle);
return GdipAddPathArc(path,(REAL)x1,(REAL)y1,(REAL)x2,(REAL)y2,startAngle,sweepAngle);
}
@ -108,6 +210,9 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2,
{
INT old_count;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
path, x1, y1, x2, y2, x3, y3, x4, y4);
if(!path)
return InvalidParameter;
@ -140,6 +245,9 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2,
GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2,
INT y2, INT x3, INT y3, INT x4, INT y4)
{
TRACE("(%p, %d, %d, %d, %d, %d, %d, %d, %d)\n",
path, x1, y1, x2, y2, x3, y3, x4, y4);
return GdipAddPathBezier(path,(REAL)x1,(REAL)y1,(REAL)x2,(REAL)y2,(REAL)x3,(REAL)y3,
(REAL)x4,(REAL)y4);
}
@ -149,6 +257,8 @@ GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points,
{
INT i, old_count;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || ((count - 1) % 3))
return InvalidParameter;
@ -178,6 +288,8 @@ GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points,
GpStatus ret;
INT i;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!points || ((count - 1) % 3))
return InvalidParameter;
@ -199,12 +311,16 @@ GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points,
GpStatus WINGDIPAPI GdipAddPathClosedCurve(GpPath *path, GDIPCONST GpPointF *points,
INT count)
{
TRACE("(%p, %p, %d)\n", path, points, count);
return GdipAddPathClosedCurve2(path, points, count, 1.0);
}
GpStatus WINGDIPAPI GdipAddPathClosedCurveI(GpPath *path, GDIPCONST GpPoint *points,
INT count)
{
TRACE("(%p, %p, %d)\n", path, points, count);
return GdipAddPathClosedCurve2I(path, points, count, 1.0);
}
@ -217,6 +333,8 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *po
REAL x1, x2, y1, y2;
GpStatus stat;
TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
if(!path || !points || count <= 1)
return InvalidParameter;
@ -284,6 +402,8 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *po
INT i;
GpStatus stat;
TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
if(!path || !points || count <= 1)
return InvalidParameter;
@ -305,18 +425,22 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *po
GpStatus WINGDIPAPI GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, INT count)
{
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || count <= 1)
return InvalidParameter;
return GdipAddPathCurve2(path, points, count, 1.0);
return GdipAddPathCurve2(path, points, count, 1.0);
}
GpStatus WINGDIPAPI GdipAddPathCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count)
{
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || count <= 1)
return InvalidParameter;
return GdipAddPathCurve2I(path, points, count, 1.0);
return GdipAddPathCurve2I(path, points, count, 1.0);
}
GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
@ -327,6 +451,8 @@ GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points,
REAL x1, x2, y1, y2;
GpStatus stat;
TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
if(!path || !points || count <= 1)
return InvalidParameter;
@ -377,6 +503,8 @@ GpStatus WINGDIPAPI GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points,
INT i;
GpStatus stat;
TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
if(!path || !points || count <= 1)
return InvalidParameter;
@ -401,6 +529,8 @@ GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width,
{
INT old_count, numpts;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x, y, width, height);
if(!path)
return InvalidParameter;
@ -429,6 +559,8 @@ GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width,
GpStatus WINGDIPAPI GdipAddPathEllipseI(GpPath *path, INT x, INT y, INT width,
INT height)
{
TRACE("(%p, %d, %d, %d, %d)\n", path, x, y, width, height);
return GdipAddPathEllipse(path,(REAL)x,(REAL)y,(REAL)width,(REAL)height);
}
@ -437,6 +569,8 @@ GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points,
{
INT i, old_count;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points)
return InvalidParameter;
@ -467,6 +601,8 @@ GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, I
INT i;
GpStatus stat;
TRACE("(%p, %p, %d)\n", path, points, count);
if(count <= 0)
return InvalidParameter;
@ -489,6 +625,8 @@ GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REA
{
INT old_count;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2);
if(!path)
return InvalidParameter;
@ -514,6 +652,8 @@ GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REA
GpStatus WINGDIPAPI GdipAddPathLineI(GpPath *path, INT x1, INT y1, INT x2, INT y2)
{
TRACE("(%p, %d, %d, %d, %d)\n", path, x1, y1, x2, y2);
return GdipAddPathLine(path, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2);
}
@ -522,6 +662,8 @@ GpStatus WINGDIPAPI GdipAddPathPath(GpPath *path, GDIPCONST GpPath* addingPath,
{
INT old_count, count;
TRACE("(%p, %p, %d)\n", path, addingPath, connect);
if(!path || !addingPath)
return InvalidParameter;
@ -546,10 +688,69 @@ GpStatus WINGDIPAPI GdipAddPathPath(GpPath *path, GDIPCONST GpPath* addingPath,
return Ok;
}
GpStatus WINGDIPAPI GdipAddPathPie(GpPath *path, REAL x, REAL y, REAL width, REAL height,
REAL startAngle, REAL sweepAngle)
{
GpPointF *ptf;
GpStatus status;
INT i, count;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
path, x, y, width, height, startAngle, sweepAngle);
if(!path)
return InvalidParameter;
count = arc2polybezier(NULL, x, y, width, height, startAngle, sweepAngle);
if(count == 0)
return Ok;
ptf = GdipAlloc(sizeof(GpPointF)*count);
if(!ptf)
return OutOfMemory;
arc2polybezier(ptf, x, y, width, height, startAngle, sweepAngle);
status = GdipAddPathLine(path, (width - x)/2, (height - y)/2, ptf[0].X, ptf[0].Y);
if(status != Ok){
GdipFree(ptf);
return status;
}
/* one spline is already added as a line endpoint */
if(!lengthen_path(path, count - 1)){
GdipFree(ptf);
return OutOfMemory;
}
memcpy(&(path->pathdata.Points[path->pathdata.Count]), &(ptf[1]),sizeof(GpPointF)*(count-1));
for(i = 0; i < count-1; i++)
path->pathdata.Types[path->pathdata.Count+i] = PathPointTypeBezier;
path->pathdata.Count += count-1;
GdipClosePathFigure(path);
GdipFree(ptf);
return status;
}
GpStatus WINGDIPAPI GdipAddPathPieI(GpPath *path, INT x, INT y, INT width, INT height,
REAL startAngle, REAL sweepAngle)
{
TRACE("(%p, %d, %d, %d, %d, %.2f, %.2f)\n",
path, x, y, width, height, startAngle, sweepAngle);
return GdipAddPathPieI(path, (REAL)x, (REAL)y, (REAL)width, (REAL)height, startAngle, sweepAngle);
}
GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count)
{
INT old_count;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || count < 3)
return InvalidParameter;
@ -576,6 +777,8 @@ GpStatus WINGDIPAPI GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points,
GpStatus status;
INT i;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!points || count < 3)
return InvalidParameter;
@ -597,6 +800,8 @@ GpStatus WINGDIPAPI GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points,
GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone)
{
TRACE("(%p, %p)\n", path, clone);
if(!path || !clone)
return InvalidParameter;
@ -623,6 +828,8 @@ GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone)
GpStatus WINGDIPAPI GdipClosePathFigure(GpPath* path)
{
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -638,6 +845,8 @@ GpStatus WINGDIPAPI GdipClosePathFigures(GpPath* path)
{
INT i;
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -653,6 +862,8 @@ GpStatus WINGDIPAPI GdipClosePathFigures(GpPath* path)
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
{
TRACE("(%d, %p)\n", fill, path);
if(!path)
return InvalidParameter;
@ -668,6 +879,8 @@ GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF* points,
GDIPCONST BYTE* types, INT count, GpFillMode fill, GpPath **path)
{
TRACE("(%p, %p, %d, %d, %p)\n", points, types, count, fill, path);
if(!path)
return InvalidParameter;
@ -702,6 +915,8 @@ GpStatus WINGDIPAPI GdipCreatePath2I(GDIPCONST GpPoint* points,
GpStatus ret;
INT i;
TRACE("(%p, %p, %d, %d, %p)\n", points, types, count, fill, path);
ptF = GdipAlloc(sizeof(GpPointF)*count);
for(i = 0;i < count; i++){
@ -718,6 +933,8 @@ GpStatus WINGDIPAPI GdipCreatePath2I(GDIPCONST GpPoint* points,
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
{
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -728,8 +945,114 @@ GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
return Ok;
}
GpStatus WINGDIPAPI GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatness)
{
path_list_node_t *list, *node;
GpPointF pt;
INT i = 1;
INT startidx = 0;
TRACE("(%p, %p, %.2f)\n", path, matrix, flatness);
if(!path)
return InvalidParameter;
if(matrix){
WARN("transformation not supported yet!\n");
return NotImplemented;
}
if(path->pathdata.Count == 0)
return Ok;
pt = path->pathdata.Points[0];
if(!init_path_list(&list, pt.X, pt.Y))
return OutOfMemory;
node = list;
while(i < path->pathdata.Count){
BYTE type = path->pathdata.Types[i] & PathPointTypePathTypeMask;
path_list_node_t *start;
pt = path->pathdata.Points[i];
/* save last start point index */
if(type == PathPointTypeStart)
startidx = i;
/* always add line points and start points */
if((type == PathPointTypeStart) || (type == PathPointTypeLine)){
type = (path->pathdata.Types[i] & ~PathPointTypeBezier) | PathPointTypeLine;
if(!add_path_list_node(node, pt.X, pt.Y, type))
goto memout;
node = node->next;
continue;
}
/* Bezier curve always stored as 4 points */
if((path->pathdata.Types[i-1] & PathPointTypePathTypeMask) != PathPointTypeStart){
type = (path->pathdata.Types[i] & ~PathPointTypeBezier) | PathPointTypeLine;
if(!add_path_list_node(node, pt.X, pt.Y, type))
goto memout;
node = node->next;
}
/* test for closed figure */
if(path->pathdata.Types[i+1] & PathPointTypeCloseSubpath){
pt = path->pathdata.Points[startidx];
++i;
}
else
{
i += 2;
pt = path->pathdata.Points[i];
};
start = node;
/* add Bezier end point */
type = (path->pathdata.Types[i] & ~PathPointTypeBezier) | PathPointTypeLine;
if(!add_path_list_node(node, pt.X, pt.Y, type))
goto memout;
node = node->next;
/* flatten curve */
if(!flatten_bezier(start, path->pathdata.Points[i-2].X, path->pathdata.Points[i-2].Y,
path->pathdata.Points[i-1].X, path->pathdata.Points[i-1].Y,
node, flatness))
goto memout;
++i;
}/* while */
/* store path data back */
i = path_list_count(list);
if(!lengthen_path(path, i))
goto memout;
path->pathdata.Count = i;
node = list;
for(i = 0; i < path->pathdata.Count; i++){
path->pathdata.Points[i] = node->pt;
path->pathdata.Types[i] = node->type;
node = node->next;
}
free_path_list(list);
return Ok;
memout:
free_path_list(list);
return OutOfMemory;
}
GpStatus WINGDIPAPI GdipGetPathData(GpPath *path, GpPathData* pathData)
{
TRACE("(%p, %p)\n", path, pathData);
if(!path || !pathData)
return InvalidParameter;
@ -743,6 +1066,8 @@ GpStatus WINGDIPAPI GdipGetPathData(GpPath *path, GpPathData* pathData)
GpStatus WINGDIPAPI GdipGetPathFillMode(GpPath *path, GpFillMode *fillmode)
{
TRACE("(%p, %p)\n", path, fillmode);
if(!path || !fillmode)
return InvalidParameter;
@ -755,6 +1080,8 @@ GpStatus WINGDIPAPI GdipGetPathLastPoint(GpPath* path, GpPointF* lastPoint)
{
INT count;
TRACE("(%p, %p)\n", path, lastPoint);
if(!path || !lastPoint)
return InvalidParameter;
@ -767,6 +1094,8 @@ GpStatus WINGDIPAPI GdipGetPathLastPoint(GpPath* path, GpPointF* lastPoint)
GpStatus WINGDIPAPI GdipGetPathPoints(GpPath *path, GpPointF* points, INT count)
{
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path)
return InvalidParameter;
@ -784,6 +1113,8 @@ GpStatus WINGDIPAPI GdipGetPathPointsI(GpPath *path, GpPoint* points, INT count)
GpPointF *ptf;
INT i;
TRACE("(%p, %p, %d)\n", path, points, count);
if(count <= 0)
return InvalidParameter;
@ -803,6 +1134,8 @@ GpStatus WINGDIPAPI GdipGetPathPointsI(GpPath *path, GpPoint* points, INT count)
GpStatus WINGDIPAPI GdipGetPathTypes(GpPath *path, BYTE* types, INT count)
{
TRACE("(%p, %p, %d)\n", path, types, count);
if(!path)
return InvalidParameter;
@ -825,6 +1158,8 @@ GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds,
INT count, i;
REAL path_width = 1.0, width, height, temp, low_x, low_y, high_x, high_y;
TRACE("(%p, %p, %p, %p)\n", path, bounds, matrix, pen);
/* Matrix and pen can be null. */
if(!path || !bounds)
return InvalidParameter;
@ -905,6 +1240,8 @@ GpStatus WINGDIPAPI GdipGetPathWorldBoundsI(GpPath* path, GpRect* bounds,
GpStatus ret;
GpRectF boundsF;
TRACE("(%p, %p, %p, %p)\n", path, bounds, matrix, pen);
ret = GdipGetPathWorldBounds(path,&boundsF,matrix,pen);
if(ret == Ok){
@ -919,6 +1256,8 @@ GpStatus WINGDIPAPI GdipGetPathWorldBoundsI(GpPath* path, GpRect* bounds,
GpStatus WINGDIPAPI GdipGetPointCount(GpPath *path, INT *count)
{
TRACE("(%p, %p)\n", path, count);
if(!path)
return InvalidParameter;
@ -927,9 +1266,67 @@ GpStatus WINGDIPAPI GdipGetPointCount(GpPath *path, INT *count)
return Ok;
}
GpStatus WINGDIPAPI GdipReversePath(GpPath* path)
{
INT i, count;
INT start = 0; /* position in reversed path */
GpPathData revpath;
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
count = path->pathdata.Count;
if(count == 0) return Ok;
revpath.Points = GdipAlloc(sizeof(GpPointF)*count);
revpath.Types = GdipAlloc(sizeof(BYTE)*count);
revpath.Count = count;
if(!revpath.Points || !revpath.Types){
GdipFree(revpath.Points);
GdipFree(revpath.Types);
return OutOfMemory;
}
for(i = 0; i < count; i++){
/* find next start point */
if(path->pathdata.Types[count-i-1] == PathPointTypeStart){
INT j;
for(j = start; j <= i; j++){
revpath.Points[j] = path->pathdata.Points[count-j-1];
revpath.Types[j] = path->pathdata.Types[count-j-1];
}
/* mark start point */
revpath.Types[start] = PathPointTypeStart;
/* set 'figure' endpoint type */
if(i-start > 1){
revpath.Types[i] = path->pathdata.Types[count-start-1] & ~PathPointTypePathTypeMask;
revpath.Types[i] |= revpath.Types[i-1];
}
else
revpath.Types[i] = path->pathdata.Types[start];
start = i+1;
}
}
memcpy(path->pathdata.Points, revpath.Points, sizeof(GpPointF)*count);
memcpy(path->pathdata.Types, revpath.Types, sizeof(BYTE)*count);
GdipFree(revpath.Points);
GdipFree(revpath.Types);
return Ok;
}
GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y,
GpPen *pen, GpGraphics *graphics, BOOL *result)
{
TRACE("(%p, %d, %d, %p, %p, %p)\n", path, x, y, pen, graphics, result);
return GdipIsOutlineVisiblePathPoint(path, x, y, pen, graphics, result);
}
@ -949,6 +1346,8 @@ GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath* path, REAL x, REAL y,
GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath* path, INT x, INT y, GpGraphics *graphics, BOOL *result)
{
TRACE("(%p, %d, %d, %p, %p)\n", path, x, y, graphics, result);
return GdipIsVisiblePathPoint(path, x, y, graphics, result);
}
@ -966,6 +1365,8 @@ GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath* path, REAL x, REAL y, GpGraph
GpStatus WINGDIPAPI GdipStartPathFigure(GpPath *path)
{
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -976,6 +1377,8 @@ GpStatus WINGDIPAPI GdipStartPathFigure(GpPath *path)
GpStatus WINGDIPAPI GdipResetPath(GpPath *path)
{
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -988,6 +1391,8 @@ GpStatus WINGDIPAPI GdipResetPath(GpPath *path)
GpStatus WINGDIPAPI GdipSetPathFillMode(GpPath *path, GpFillMode fill)
{
TRACE("(%p, %d)\n", path, fill);
if(!path)
return InvalidParameter;
@ -998,6 +1403,8 @@ GpStatus WINGDIPAPI GdipSetPathFillMode(GpPath *path, GpFillMode fill)
GpStatus WINGDIPAPI GdipTransformPath(GpPath *path, GpMatrix *matrix)
{
TRACE("(%p, %p)\n", path, matrix);
if(!path)
return InvalidParameter;
@ -1016,6 +1423,8 @@ GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,
GpStatus retstat;
BOOL old_new;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x, y, width, height);
if(!path || width < 0.0 || height < 0.0)
return InvalidParameter;
@ -1055,6 +1464,8 @@ fail:
GpStatus WINGDIPAPI GdipAddPathRectangleI(GpPath *path, INT x, INT y,
INT width, INT height)
{
TRACE("(%p, %d, %d, %d, %d)\n", path, x, y, width, height);
return GdipAddPathRectangle(path,(REAL)x,(REAL)y,(REAL)width,(REAL)height);
}
@ -1064,6 +1475,8 @@ GpStatus WINGDIPAPI GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects
GpStatus retstat;
INT i;
TRACE("(%p, %p, %d)\n", path, rects, count);
/* count == 0 - verified condition */
if(!path || !rects || count == 0)
return InvalidParameter;
@ -1099,6 +1512,8 @@ GpStatus WINGDIPAPI GdipAddPathRectanglesI(GpPath *path, GDIPCONST GpRect *rects
GpStatus retstat;
INT i;
TRACE("(%p, %p, %d)\n", path, rects, count);
if(!rects || count == 0)
return InvalidParameter;
@ -1124,6 +1539,8 @@ GpStatus WINGDIPAPI GdipSetPathMarker(GpPath* path)
{
INT count;
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;
@ -1141,6 +1558,8 @@ GpStatus WINGDIPAPI GdipClearPathMarkers(GpPath* path)
INT count;
INT i;
TRACE("(%p)\n", path);
if(!path)
return InvalidParameter;

View file

@ -242,11 +242,50 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
{
if (!(image && cloneImage)) return InvalidParameter;
IStream* stream;
HRESULT hr;
INT size;
FIXME("stub: %p, %p\n", image, cloneImage);
TRACE("%p, %p\n", image, cloneImage);
return NotImplemented;
if (!image || !cloneImage)
return InvalidParameter;
hr = CreateStreamOnHGlobal(0, TRUE, &stream);
if (FAILED(hr))
return GenericError;
*cloneImage = GdipAlloc(sizeof(GpImage));
if (!*cloneImage)
{
IStream_Release(stream);
return OutOfMemory;
}
(*cloneImage)->type = image->type;
(*cloneImage)->flags = image->flags;
hr = IPicture_SaveAsFile(image->picture, stream, FALSE, &size);
if(FAILED(hr))
{
WARN("Failed to save image on stream\n");
goto out;
}
hr = OleLoadPicture(stream, size, FALSE, &IID_IPicture,
(LPVOID*) &(*cloneImage)->picture);
if (FAILED(hr))
{
WARN("Failed to load image from stream\n");
goto out;
}
IStream_Release(stream);
return Ok;
out:
IStream_Release(stream);
GdipFree(*cloneImage);
*cloneImage = NULL;
return GenericError;
}
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename,

View file

@ -30,6 +30,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr,
GpImageAttributes **cloneImageattr)
{
TRACE("(%p, %p)\n", imageattr, cloneImageattr);
if(!imageattr || !cloneImageattr)
return InvalidParameter;
@ -40,6 +42,8 @@ GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imagea
GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
{
TRACE("(%p)\n", imageattr);
if(!imageattr)
return InvalidParameter;
@ -51,6 +55,8 @@ GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
{
TRACE("(%p)\n", imageattr);
if(!imageattr)
return InvalidParameter;

View file

@ -27,6 +27,9 @@
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
/* Multiplies two matrices of the form
*
@ -58,6 +61,8 @@ static REAL matrix_det(GDIPCONST GpMatrix *matrix)
GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22,
REAL dx, REAL dy, GpMatrix **matrix)
{
TRACE("(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p)\n", m11, m12, m21, m22, dx, dy, matrix);
if(!matrix)
return InvalidParameter;
@ -80,6 +85,8 @@ GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22,
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect,
GDIPCONST GpPointF *pt, GpMatrix **matrix)
{
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
if(!matrix)
return InvalidParameter;
@ -100,6 +107,8 @@ GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint
GpRectF rectF;
GpPointF ptF;
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
rectF.X = (REAL)rect->X;
rectF.Y = (REAL)rect->Y;
rectF.Width = (REAL)rect->Width;
@ -113,6 +122,8 @@ GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint
GpStatus WINGDIPAPI GdipCloneMatrix(GpMatrix *matrix, GpMatrix **clone)
{
TRACE("(%p, %p)\n", matrix, clone);
if(!matrix || !clone)
return InvalidParameter;
@ -126,6 +137,8 @@ GpStatus WINGDIPAPI GdipCloneMatrix(GpMatrix *matrix, GpMatrix **clone)
GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
{
TRACE("(%p)\n", matrix);
if(!matrix)
return InvalidParameter;
@ -144,6 +157,8 @@ GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
{
TRACE("(%p)\n", matrix);
if(!matrix)
return InvalidParameter;
@ -155,6 +170,8 @@ GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix *matrix,
REAL *out)
{
TRACE("(%p, %p)\n", matrix, out);
if(!matrix || !out)
return InvalidParameter;
@ -169,6 +186,8 @@ GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
REAL det;
BOOL invertible;
TRACE("(%p)\n", matrix);
if(!matrix)
return InvalidParameter;
@ -192,6 +211,8 @@ GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
{
TRACE("(%p, %p)\n", matrix, result);
if(!matrix || !result)
return InvalidParameter;
@ -203,6 +224,8 @@ GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *res
GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GpMatrix* matrix2,
GpMatrixOrder order)
{
TRACE("(%p, %p, %d)\n", matrix, matrix2, order);
if(!matrix || !matrix2)
return InvalidParameter;
@ -219,6 +242,8 @@ GpStatus WINGDIPAPI GdipRotateMatrix(GpMatrix *matrix, REAL angle,
{
REAL cos_theta, sin_theta, rotate[6];
TRACE("(%p, %.2f, %d)\n", matrix, angle, order);
if(!matrix)
return InvalidParameter;
@ -246,6 +271,8 @@ GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY,
{
REAL scale[6];
TRACE("(%p, %.2f, %.2f, %d)\n", matrix, scaleX, scaleY, order);
if(!matrix)
return InvalidParameter;
@ -267,6 +294,9 @@ GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY,
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12,
REAL m21, REAL m22, REAL dx, REAL dy)
{
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", matrix, m11, m12,
m21, m22, dx, dy);
if(!matrix)
return InvalidParameter;
@ -285,6 +315,8 @@ GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY,
{
REAL shear[6];
TRACE("(%p, %.2f, %.2f, %d)\n", matrix, shearX, shearY, order);
if(!matrix)
return InvalidParameter;
@ -310,6 +342,8 @@ GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts,
REAL x, y;
INT i;
TRACE("(%p, %p, %d)\n", matrix, pts, count);
if(!matrix || !pts || count <= 0)
return InvalidParameter;
@ -331,6 +365,8 @@ GpStatus WINGDIPAPI GdipTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, I
GpStatus ret;
INT i;
TRACE("(%p, %p, %d)\n", matrix, pts, count);
if(count <= 0)
return InvalidParameter;
@ -360,6 +396,8 @@ GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX,
{
REAL translate[6];
TRACE("(%p, %.2f, %.2f, %d)\n", matrix, offsetX, offsetY, order);
if(!matrix)
return InvalidParameter;
@ -383,6 +421,8 @@ GpStatus WINGDIPAPI GdipVectorTransformMatrixPoints(GpMatrix *matrix, GpPointF *
REAL x, y;
INT i;
TRACE("(%p, %p, %d)\n", matrix, pts, count);
if(!matrix || !pts || count <= 0)
return InvalidParameter;
@ -404,6 +444,8 @@ GpStatus WINGDIPAPI GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *
GpStatus ret;
INT i;
TRACE("(%p, %p, %d)\n", matrix, pts, count);
if(count <= 0)
return InvalidParameter;
@ -431,6 +473,8 @@ GpStatus WINGDIPAPI GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *
GpStatus WINGDIPAPI GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2,
BOOL *result)
{
TRACE("(%p, %p, %p)\n", matrix, matrix2, result);
if(!matrix || !matrix2 || !result)
return InvalidParameter;
/* based on single array member of GpMatrix */
@ -445,6 +489,8 @@ GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *resul
GpStatus ret;
BOOL isIdentity;
TRACE("(%p, %p)\n", matrix, result);
if(!matrix || !result)
return InvalidParameter;

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Google (Evan Stade)
* Copyright (C) 2008 Nikolay Sivov <bunglehead at gmail dot com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -26,11 +27,16 @@
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator **iterator, GpPath* path)
{
INT size;
TRACE("(%p, %p)\n", iterator, path);
if(!iterator)
return InvalidParameter;
@ -62,6 +68,8 @@ GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator **iterator, GpPath* path)
GpStatus WINGDIPAPI GdipDeletePathIter(GpPathIterator *iter)
{
TRACE("(%p)\n", iter);
if(!iter)
return InvalidParameter;
@ -75,6 +83,9 @@ GpStatus WINGDIPAPI GdipDeletePathIter(GpPathIterator *iter)
GpStatus WINGDIPAPI GdipPathIterCopyData(GpPathIterator* iterator,
INT* resultCount, GpPointF* points, BYTE* types, INT startIndex, INT endIndex)
{
TRACE("(%p, %p, %p, %p, %d, %d)\n", iterator, resultCount, points, types,
startIndex, endIndex);
if(!iterator || !types || !points)
return InvalidParameter;
@ -97,6 +108,8 @@ GpStatus WINGDIPAPI GdipPathIterHasCurve(GpPathIterator* iterator, BOOL* hasCurv
{
INT i;
TRACE("(%p, %p)\n", iterator, hasCurve);
if(!iterator)
return InvalidParameter;
@ -115,6 +128,8 @@ GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator* iterator, INT* c
{
INT i;
TRACE("(%p, %p)\n", iterator, count);
if(!iterator || !count)
return InvalidParameter;
@ -132,6 +147,8 @@ GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator* iterator, INT *result
{
INT i;
TRACE("(%p, %p, %p, %p)\n", iterator, resultCount, startIndex, endIndex);
if(!iterator || !startIndex || !endIndex)
return InvalidParameter;
@ -153,19 +170,50 @@ GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator* iterator, INT *result
return Ok;
}
GpStatus WINGDIPAPI GdipPathIterNextMarkerPath(GpPathIterator* iterator, INT* result,
GpPath* path)
{
INT start, end;
TRACE("(%p, %p, %p)\n", iterator, result, path);
if(!iterator || !result)
return InvalidParameter;
GdipPathIterNextMarker(iterator, result, &start, &end);
/* return path */
if(((*result) > 0) && path){
GdipResetPath(path);
if(!lengthen_path(path, *result))
return OutOfMemory;
memcpy(path->pathdata.Points, &(iterator->pathdata.Points[start]), sizeof(GpPointF)*(*result));
memcpy(path->pathdata.Types, &(iterator->pathdata.Types[start]), sizeof(BYTE)*(*result));
path->pathdata.Count = *result;
}
return Ok;
}
GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator,
INT *resultCount, INT* startIndex, INT* endIndex, BOOL* isClosed)
{
INT i, count;
TRACE("(%p, %p, %p, %p, %p)\n", iterator, resultCount, startIndex,
endIndex, isClosed);
if(!iterator || !startIndex || !endIndex || !isClosed || !resultCount)
return InvalidParameter;
count = iterator->pathdata.Count;
/* iterator created with NULL path */
if(count == 0)
if(count == 0){
*resultCount = 0;
return Ok;
}
if(iterator->subpath_pos == count){
*startIndex = *endIndex = *resultCount = 0;
@ -192,6 +240,8 @@ GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator,
}
GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator *iterator)
{
TRACE("(%p)\n", iterator);
if(!iterator)
return InvalidParameter;
@ -204,6 +254,8 @@ GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator *iterator)
GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator* iterator, INT* count)
{
TRACE("(%p, %p)\n", iterator, count);
if(!iterator || !count)
return InvalidParameter;
@ -215,6 +267,8 @@ GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator* iterator, INT* count)
GpStatus WINGDIPAPI GdipPathIterEnumerate(GpPathIterator* iterator, INT* resultCount,
GpPointF *points, BYTE *types, INT count)
{
TRACE("(%p, %p, %p, %p, %d)\n", iterator, resultCount, points, types, count);
if((count < 0) || !resultCount)
return InvalidParameter;
@ -225,3 +279,52 @@ GpStatus WINGDIPAPI GdipPathIterEnumerate(GpPathIterator* iterator, INT* resultC
return GdipPathIterCopyData(iterator, resultCount, points, types, 0, count-1);
}
GpStatus WINGDIPAPI GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid)
{
TRACE("(%p, %p)\n", iterator, valid);
if(!iterator || !valid)
return InvalidParameter;
*valid = TRUE;
return Ok;
}
GpStatus WINGDIPAPI GdipPathIterNextPathType(GpPathIterator* iter, INT* result,
BYTE* type, INT* start, INT* end)
{
FIXME("(%p, %p, %p, %p, %p) stub\n", iter, result, type, start, end);
if(!iter || !result || !type || !start || !end)
return InvalidParameter;
return NotImplemented;
}
GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator* iter, INT* result,
GpPath* path, BOOL* closed)
{
INT start, end;
TRACE("(%p, %p, %p, %p)\n", iter, result, path, closed);
if(!iter || !result || !closed)
return InvalidParameter;
GdipPathIterNextSubpath(iter, result, &start, &end, closed);
/* return path */
if(((*result) > 0) && path){
GdipResetPath(path);
if(!lengthen_path(path, *result))
return OutOfMemory;
memcpy(path->pathdata.Points, &(iter->pathdata.Points[start]), sizeof(GpPointF)*(*result));
memcpy(path->pathdata.Types, &(iter->pathdata.Types[start]), sizeof(BYTE)*(*result));
path->pathdata.Count = *result;
}
return Ok;
}

View file

@ -73,19 +73,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
*
*/
typedef enum RegionType
{
RegionDataRect = 0x10000000,
RegionDataPath = 0x10000001,
RegionDataEmptyRect = 0x10000002,
RegionDataInfiniteRect = 0x10000003,
} RegionType;
#define FLAGS_NOFLAGS 0x0
#define FLAGS_INTPATH 0x4000
/* Header size as far as header->size is concerned. This doesn't include
* header->size or header->checksum
*/
static const INT sizeheader_size = sizeof(DWORD) * 2;
typedef struct packed_point
{
short X;
short Y;
} packed_point;
/* Everything is measured in DWORDS; round up if there's a remainder */
static inline INT get_pathtypes_size(const GpPath* path)
{
INT needed = path->pathdata.Count / sizeof(DWORD);
if (path->pathdata.Count % sizeof(DWORD) > 0)
needed++;
return needed * sizeof(DWORD);
}
static inline INT get_element_size(const region_element* element)
{
INT needed = sizeof(DWORD); /* DWORD for the type */
@ -121,72 +133,265 @@ static inline GpStatus init_region(GpRegion* region, const RegionType type)
return Ok;
}
static inline void delete_element(region_element* element)
static inline GpStatus clone_element(const region_element* element,
region_element** element2)
{
switch(element->type)
GpStatus stat;
/* root node is allocated with GpRegion */
if(!*element2){
*element2 = GdipAlloc(sizeof(region_element));
if (!*element2)
return OutOfMemory;
}
(*element2)->type = element->type;
switch (element->type)
{
case RegionDataRect:
break;
case RegionDataPath:
GdipDeletePath(element->elementdata.pathdata.path);
(*element2)->elementdata.rect = element->elementdata.rect;
break;
case RegionDataEmptyRect:
case RegionDataInfiniteRect:
break;
case RegionDataPath:
(*element2)->elementdata.pathdata.pathheader = element->elementdata.pathdata.pathheader;
stat = GdipClonePath(element->elementdata.pathdata.path,
&(*element2)->elementdata.pathdata.path);
if (stat != Ok) goto clone_out;
break;
default:
delete_element(element->elementdata.combine.left);
delete_element(element->elementdata.combine.right);
GdipFree(element->elementdata.combine.left);
GdipFree(element->elementdata.combine.right);
(*element2)->elementdata.combine.left = NULL;
(*element2)->elementdata.combine.right = NULL;
stat = clone_element(element->elementdata.combine.left,
&(*element2)->elementdata.combine.left);
if (stat != Ok) goto clone_out;
stat = clone_element(element->elementdata.combine.right,
&(*element2)->elementdata.combine.right);
if (stat != Ok) goto clone_out;
break;
}
return Ok;
clone_out:
delete_element(*element2);
*element2 = NULL;
return stat;
}
/* Common code for CombineRegion*
* All the caller has to do is get its format into an element
*/
static inline void fuse_region(GpRegion* region, region_element* left,
region_element* right, const CombineMode mode)
{
region->node.type = mode;
region->node.elementdata.combine.left = left;
region->node.elementdata.combine.right = right;
region->header.size = sizeheader_size + get_element_size(&region->node);
region->header.num_children += 2;
}
/*****************************************************************************
* GdipCloneRegion [GDIPLUS.@]
*
* Creates a deep copy of the region
*
* PARAMS
* region [I] source region
* clone [O] resulting clone
*
* RETURNS
* SUCCESS: Ok
* FAILURE: InvalidParameter or OutOfMemory
*/
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
{
FIXME("(%p %p): stub\n", region, clone);
region_element *element;
*clone = NULL;
return NotImplemented;
}
TRACE("%p %p\n", region, clone);
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
{
FIXME("(%p %p %d): stub\n", region, path, mode);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect,
CombineMode mode)
{
FIXME("(%p %p %d): stub\n", region, rect, mode);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipCombineRegionRectI(GpRegion *region, GDIPCONST GpRect *rect,
CombineMode mode)
{
FIXME("(%p %p %d): stub\n", region, rect, mode);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2,
CombineMode mode)
{
FIXME("(%p %p %d): stub\n", region1, region2, mode);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
{
if(!region)
if (!(region && clone))
return InvalidParameter;
*clone = GdipAlloc(sizeof(GpRegion));
if (!*clone)
return OutOfMemory;
element = &(*clone)->node;
(*clone)->header = region->header;
return clone_element(&region->node, &element);
}
/*****************************************************************************
* GdipCombineRegionPath [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
{
GpRegion *path_region;
region_element *left, *right = NULL;
GpStatus stat;
TRACE("%p %p %d\n", region, path, mode);
if (!(region && path))
return InvalidParameter;
stat = GdipCreateRegionPath(path, &path_region);
if (stat != Ok)
return stat;
/* simply replace region data */
if(mode == CombineModeReplace){
delete_element(&region->node);
memcpy(region, path_region, sizeof(GpRegion));
return Ok;
}
left = GdipAlloc(sizeof(region_element));
if (!left)
goto out;
*left = region->node;
stat = clone_element(&path_region->node, &right);
if (stat != Ok)
goto out;
fuse_region(region, left, right, mode);
GdipDeleteRegion(path_region);
return Ok;
out:
GdipFree(left);
delete_element(right);
GdipDeleteRegion(path_region);
return stat;
}
/*****************************************************************************
* GdipCombineRegionRect [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region,
GDIPCONST GpRectF *rect, CombineMode mode)
{
GpRegion *rect_region;
region_element *left, *right = NULL;
GpStatus stat;
TRACE("%p %p %d\n", region, rect, mode);
if (!(region && rect))
return InvalidParameter;
stat = GdipCreateRegionRect(rect, &rect_region);
if (stat != Ok)
return stat;
/* simply replace region data */
if(mode == CombineModeReplace){
delete_element(&region->node);
memcpy(region, rect_region, sizeof(GpRegion));
return Ok;
}
left = GdipAlloc(sizeof(region_element));
if (!left)
goto out;
memcpy(left, &region->node, sizeof(region_element));
stat = clone_element(&rect_region->node, &right);
if (stat != Ok)
goto out;
fuse_region(region, left, right, mode);
GdipDeleteRegion(rect_region);
return Ok;
out:
GdipFree(left);
delete_element(right);
GdipDeleteRegion(rect_region);
return stat;
}
/*****************************************************************************
* GdipCombineRegionRectI [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCombineRegionRectI(GpRegion *region,
GDIPCONST GpRect *rect, CombineMode mode)
{
GpRectF rectf;
TRACE("%p %p %d\n", region, rect, mode);
if (!rect)
return InvalidParameter;
rectf.X = (REAL)rect->X;
rectf.Y = (REAL)rect->Y;
rectf.Height = (REAL)rect->Height;
rectf.Width = (REAL)rect->Width;
return GdipCombineRegionRect(region, &rectf, mode);
}
GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1,
GpRegion *region2, CombineMode mode)
{
region_element *left, *right = NULL;
GpStatus stat;
GpRegion *reg2copy;
TRACE("%p %p %d\n", region1, region2, mode);
if(!(region1 && region2))
return InvalidParameter;
/* simply replace region data */
if(mode == CombineModeReplace){
stat = GdipCloneRegion(region2, &reg2copy);
if(stat != Ok) return stat;
delete_element(&region1->node);
memcpy(region1, reg2copy, sizeof(GpRegion));
return Ok;
}
left = GdipAlloc(sizeof(region_element));
if (!left)
return OutOfMemory;
*left = region1->node;
stat = clone_element(&region2->node, &right);
if (stat != Ok)
{
GdipFree(left);
delete_element(right);
return OutOfMemory;
}
fuse_region(region1, left, right, mode);
region1->header.num_children += region2->header.num_children;
return Ok;
}
/*****************************************************************************
* GdipCreateRegion [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
{
TRACE("%p\n", region);
if(!region)
return InvalidParameter;
*region = GdipAlloc(sizeof(GpRegion));
if(!*region)
return OutOfMemory;
@ -194,28 +399,166 @@ GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
return init_region(*region, RegionDataInfiniteRect);
}
/*****************************************************************************
* GdipCreateRegionPath [GDIPLUS.@]
*
* Creates a GpRegion from a GpPath
*
* PARAMS
* path [I] path to base the region on
* region [O] pointer to the newly allocated region
*
* RETURNS
* SUCCESS: Ok
* FAILURE: InvalidParameter
*
* NOTES
* If a path has no floating point points, its points will be stored as shorts
* (INTPATH)
*
* If a path is empty, it is considered to be an INTPATH
*/
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
{
FIXME("(%p, %p): stub\n", path, region);
region_element* element;
GpPoint *pointsi;
GpPointF *pointsf;
*region = NULL;
return NotImplemented;
GpStatus stat;
DWORD flags = FLAGS_INTPATH;
INT count, i;
TRACE("%p, %p\n", path, region);
if (!(path && region))
return InvalidParameter;
*region = GdipAlloc(sizeof(GpRegion));
if(!*region)
return OutOfMemory;
stat = init_region(*region, RegionDataPath);
if (stat != Ok)
{
GdipDeleteRegion(*region);
return stat;
}
element = &(*region)->node;
count = path->pathdata.Count;
/* Test to see if the path is an Integer path */
if (count)
{
pointsi = GdipAlloc(sizeof(GpPoint) * count);
pointsf = GdipAlloc(sizeof(GpPointF) * count);
if (!(pointsi && pointsf))
{
GdipFree(pointsi);
GdipFree(pointsf);
GdipDeleteRegion(*region);
return OutOfMemory;
}
stat = GdipGetPathPointsI(path, pointsi, count);
if (stat != Ok)
{
GdipDeleteRegion(*region);
return stat;
}
stat = GdipGetPathPoints(path, pointsf, count);
if (stat != Ok)
{
GdipDeleteRegion(*region);
return stat;
}
for (i = 0; i < count; i++)
{
if (!(pointsi[i].X == pointsf[i].X &&
pointsi[i].Y == pointsf[i].Y ))
{
flags = FLAGS_NOFLAGS;
break;
}
}
GdipFree(pointsi);
GdipFree(pointsf);
}
stat = GdipClonePath(path, &element->elementdata.pathdata.path);
if (stat != Ok)
{
GdipDeleteRegion(*region);
return stat;
}
/* 3 for headers, once again size doesn't count itself */
element->elementdata.pathdata.pathheader.size = ((sizeof(DWORD) * 3));
switch(flags)
{
/* Floats, sent out as floats */
case FLAGS_NOFLAGS:
element->elementdata.pathdata.pathheader.size +=
(sizeof(DWORD) * count * 2);
break;
/* INTs, sent out as packed shorts */
case FLAGS_INTPATH:
element->elementdata.pathdata.pathheader.size +=
(sizeof(DWORD) * count);
break;
default:
FIXME("Unhandled flags (%08x). Expect wrong results.\n", flags);
}
element->elementdata.pathdata.pathheader.size += get_pathtypes_size(path);
element->elementdata.pathdata.pathheader.magic = VERSION_MAGIC;
element->elementdata.pathdata.pathheader.count = count;
element->elementdata.pathdata.pathheader.flags = flags;
(*region)->header.size = sizeheader_size + get_element_size(element);
return Ok;
}
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
/*****************************************************************************
* GdipCreateRegionRect [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect,
GpRegion **region)
{
FIXME("(%p, %p): stub\n", rect, region);
GpStatus stat;
*region = NULL;
return NotImplemented;
TRACE("%p, %p\n", rect, region);
if (!(rect && region))
return InvalidParameter;
*region = GdipAlloc(sizeof(GpRegion));
stat = init_region(*region, RegionDataRect);
if(stat != Ok)
{
GdipDeleteRegion(*region);
return stat;
}
(*region)->node.elementdata.rect.X = rect->X;
(*region)->node.elementdata.rect.Y = rect->Y;
(*region)->node.elementdata.rect.Width = rect->Width;
(*region)->node.elementdata.rect.Height = rect->Height;
return Ok;
}
GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region)
GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect,
GpRegion **region)
{
FIXME("(%p, %p): stub\n", rect, region);
GpRectF rectf;
*region = NULL;
return NotImplemented;
TRACE("%p, %p\n", rect, region);
rectf.X = (REAL)rect->X;
rectf.Y = (REAL)rect->Y;
rectf.Width = (REAL)rect->Width;
rectf.Height = (REAL)rect->Height;
return GdipCreateRegionRect(&rectf, region);
}
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion **region)
@ -261,20 +604,161 @@ GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics,
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size, UINT *needed)
static inline void write_dword(DWORD* location, INT* offset, const DWORD write)
{
FIXME("(%p, %p, %d, %p): stub\n", region, buffer, size, needed);
return NotImplemented;
location[*offset] = write;
(*offset)++;
}
GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
static inline void write_float(DWORD* location, INT* offset, const FLOAT write)
{
if (!(region && needed))
((FLOAT*)location)[*offset] = write;
(*offset)++;
}
static inline void write_packed_point(DWORD* location, INT* offset,
const GpPointF* write)
{
packed_point point;
point.X = write->X;
point.Y = write->Y;
memcpy(location + *offset, &point, sizeof(packed_point));
(*offset)++;
}
static inline void write_path_types(DWORD* location, INT* offset,
const GpPath* path)
{
memcpy(location + *offset, path->pathdata.Types, path->pathdata.Count);
/* The unwritten parts of the DWORD (if any) must be cleared */
if (path->pathdata.Count % sizeof(DWORD))
ZeroMemory(((BYTE*)location) + (*offset * sizeof(DWORD)) +
path->pathdata.Count,
sizeof(DWORD) - path->pathdata.Count % sizeof(DWORD));
*offset += (get_pathtypes_size(path) / sizeof(DWORD));
}
static void write_element(const region_element* element, DWORD *buffer,
INT* filled)
{
write_dword(buffer, filled, element->type);
switch (element->type)
{
case CombineModeReplace:
case CombineModeIntersect:
case CombineModeUnion:
case CombineModeXor:
case CombineModeExclude:
case CombineModeComplement:
write_element(element->elementdata.combine.left, buffer, filled);
write_element(element->elementdata.combine.right, buffer, filled);
break;
case RegionDataRect:
write_float(buffer, filled, element->elementdata.rect.X);
write_float(buffer, filled, element->elementdata.rect.Y);
write_float(buffer, filled, element->elementdata.rect.Width);
write_float(buffer, filled, element->elementdata.rect.Height);
break;
case RegionDataPath:
{
INT i;
const GpPath* path = element->elementdata.pathdata.path;
memcpy(buffer + *filled, &element->elementdata.pathdata.pathheader,
sizeof(element->elementdata.pathdata.pathheader));
*filled += sizeof(element->elementdata.pathdata.pathheader) / sizeof(DWORD);
switch (element->elementdata.pathdata.pathheader.flags)
{
case FLAGS_NOFLAGS:
for (i = 0; i < path->pathdata.Count; i++)
{
write_float(buffer, filled, path->pathdata.Points[i].X);
write_float(buffer, filled, path->pathdata.Points[i].Y);
}
break;
case FLAGS_INTPATH:
for (i = 0; i < path->pathdata.Count; i++)
{
write_packed_point(buffer, filled,
&path->pathdata.Points[i]);
}
}
write_path_types(buffer, filled, path);
break;
}
case RegionDataEmptyRect:
case RegionDataInfiniteRect:
break;
}
}
/*****************************************************************************
* GdipGetRegionData [GDIPLUS.@]
*
* Returns the header, followed by combining ops and region elements.
*
* PARAMS
* region [I] region to retrieve from
* buffer [O] buffer to hold the resulting data
* size [I] size of the buffer
* needed [O] (optional) how much data was written
*
* RETURNS
* SUCCESS: Ok
* FAILURE: InvalidParamter
*
* NOTES
* The header contains the size, a checksum, a version string, and the number
* of children. The size does not count itself or the checksum.
* Version is always something like 0xdbc01001 or 0xdbc01002
*
* An element is a RECT, or PATH; Combining ops are stored as their
* CombineMode value. Special regions (infinite, empty) emit just their
* op-code; GpRectFs emit their code followed by their points; GpPaths emit
* their code followed by a second header for the path followed by the actual
* path data. Followed by the flags for each point. The pathheader contains
* the size of the data to follow, a version number again, followed by a count
* of how many points, and any special flags which may apply. 0x4000 means its
* a path of shorts instead of FLOAT.
*
* Combining Ops are stored in reverse order from when they were constructed;
* the output is a tree where the left side combining area is always taken
* first.
*/
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
UINT *needed)
{
INT filled = 0;
TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
if (!(region && buffer && size))
return InvalidParameter;
memcpy(buffer, &region->header, sizeof(region->header));
filled += sizeof(region->header) / sizeof(DWORD);
/* With few exceptions, everything written is DWORD aligned,
* so use that as our base */
write_element(&region->node, (DWORD*)buffer, &filled);
if (needed)
*needed = filled * sizeof(DWORD);
return Ok;
}
/*****************************************************************************
* GdipGetRegionDataSize [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
{
TRACE("%p, %p\n", region, needed);
if (!(region && needed))
return InvalidParameter;
/* header.size doesn't count header.size and header.checksum */
*needed = region->header.size + sizeof(DWORD) * 2;
@ -294,9 +778,14 @@ GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HR
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
{
FIXME("(%p, %p, %p): stub\n", region, graphics, res);
TRACE("(%p, %p, %p)\n", region, graphics, res);
return NotImplemented;
if(!region || !graphics || !res)
return InvalidParameter;
*res = (region->node.type == RegionDataEmptyRect);
return Ok;
}
GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *region, GpRegion *region2, GpGraphics *graphics,
@ -307,13 +796,25 @@ GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *region, GpRegion *region2, GpGra
return NotImplemented;
}
/*****************************************************************************
* GdipIsInfiniteRegion [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
{
FIXME("(%p, %p, %p): stub\n", region, graphics, res);
/* I think graphics is ignored here */
TRACE("(%p, %p, %p)\n", region, graphics, res);
return NotImplemented;
if(!region || !graphics || !res)
return InvalidParameter;
*res = (region->node.type == RegionDataInfiniteRect);
return Ok;
}
/*****************************************************************************
* GdipSetEmpty [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *region)
{
GpStatus stat;
@ -333,11 +834,11 @@ GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region)
{
GpStatus stat;
TRACE("%p\n", region);
if (!region)
return InvalidParameter;
TRACE("%p\n", region);
delete_element(&region->node);
stat = init_region(region, RegionDataInfiniteRect);

View file

@ -100,6 +100,8 @@ GpStatus WINGDIPAPI GdipDrawCurve(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipDrawCurveI(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT,REAL);
GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT,REAL);
GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics*,GpPen*,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics*,GpPen*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipDrawImage(GpGraphics*,GpImage*,REAL,REAL);
GpStatus WINGDIPAPI GdipDrawImageI(GpGraphics*,GpImage*,INT,INT);
GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics*,GpImage*,
@ -132,6 +134,11 @@ 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 GdipFillClosedCurve2(GpGraphics*,GpBrush*,GDIPCONST GpPointF*,INT,
REAL,GpFillMode);
GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics*,GpBrush*,GDIPCONST GpPoint*,INT,
REAL,GpFillMode);
GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics*,GpBrush*,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipFillEllipseI(GpGraphics*,GpBrush*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipFillPath(GpGraphics*,GpBrush*,GpPath*);
@ -149,6 +156,9 @@ GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics*,GpBrush*,GDIPCONST GpRectF*,I
GpStatus WINGDIPAPI GdipFillRectanglesI(GpGraphics*,GpBrush*,GDIPCONST GpRect*,INT);
GpStatus WINGDIPAPI GdipGetCompositingMode(GpGraphics*,CompositingMode*);
GpStatus WINGDIPAPI GdipGetClip(GpGraphics*,GpRegion*);
GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics*,GpRegion*,CombineMode);
GpStatus WINGDIPAPI GdipResetClip(GpGraphics*);
GpStatus WINGDIPAPI GdipIsClipEmpty(GpGraphics*, BOOL*);
GpStatus WINGDIPAPI GdipGetCompositingQuality(GpGraphics*,CompositingQuality*);
GpStatus WINGDIPAPI GdipGetDC(GpGraphics*,HDC*);
GpStatus WINGDIPAPI GdipGetImageDimension(GpImage*,REAL*,REAL*);
@ -159,6 +169,7 @@ GpStatus WINGDIPAPI GdipGetPixelOffsetMode(GpGraphics*,PixelOffsetMode*);
GpStatus WINGDIPAPI GdipGetSmoothingMode(GpGraphics*,SmoothingMode*);
GpStatus WINGDIPAPI GdipGetTextRenderingHint(GpGraphics*,TextRenderingHint*);
GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics*,GpMatrix*);
GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics*,ARGB);
GpStatus WINGDIPAPI GdipMeasureString(GpGraphics*,GDIPCONST WCHAR*,INT,
GDIPCONST GpFont*,GDIPCONST RectF*,GDIPCONST GpStringFormat*,RectF*,INT*,INT*);
GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics*, GDIPCONST WCHAR*,
@ -166,6 +177,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics*, GDIPCONST WCHAR*,
GpRegion**);
GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics*,HDC);
GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics*);
GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics*,GraphicsState);
GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics*,REAL,GpMatrixOrder);
GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics*,GraphicsState*);
@ -261,6 +273,8 @@ GpStatus WINGDIPAPI GdipAddPathLine2(GpPath*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipAddPathLineI(GpPath*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipAddPathPath(GpPath*,GDIPCONST GpPath*,BOOL);
GpStatus WINGDIPAPI GdipAddPathPie(GpPath*,REAL,REAL,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipAddPathPieI(GpPath*,INT,INT,INT,INT,REAL,REAL);
GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipAddPathPolygonI(GpPath*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath*,REAL,REAL,REAL,REAL);
@ -275,6 +289,7 @@ GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF*,GDIPCONST BYTE*,INT,
GpFillMode,GpPath**);
GpStatus WINGDIPAPI GdipCreatePath2I(GDIPCONST GpPoint*,GDIPCONST BYTE*,INT,GpFillMode,GpPath**);
GpStatus WINGDIPAPI GdipDeletePath(GpPath*);
GpStatus WINGDIPAPI GdipFlattenPath(GpPath*,GpMatrix*,REAL);
GpStatus WINGDIPAPI GdipGetPathData(GpPath*,GpPathData*);
GpStatus WINGDIPAPI GdipGetPathFillMode(GpPath*,GpFillMode*);
GpStatus WINGDIPAPI GdipGetPathLastPoint(GpPath*,GpPointF*);
@ -291,6 +306,7 @@ GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath*,INT,INT,GpPen*,
GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath*,REAL,REAL,GpGraphics*,BOOL*);
GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath*,INT,INT,GpGraphics*,BOOL*);
GpStatus WINGDIPAPI GdipResetPath(GpPath*);
GpStatus WINGDIPAPI GdipReversePath(GpPath*);
GpStatus WINGDIPAPI GdipSetPathFillMode(GpPath*,GpFillMode);
GpStatus WINGDIPAPI GdipStartPathFigure(GpPath*);
GpStatus WINGDIPAPI GdipTransformPath(GpPath*,GpMatrix*);
@ -324,12 +340,16 @@ GpStatus WINGDIPAPI GdipDeletePathIter(GpPathIterator*);
GpStatus WINGDIPAPI GdipPathIterCopyData(GpPathIterator*,INT*,GpPointF*,BYTE*,
INT,INT);
GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator*,INT*,INT*,INT*);
GpStatus WINGDIPAPI GdipPathIterNextMarkerPath(GpPathIterator*,INT*,GpPath*);
GpStatus WINGDIPAPI GdipPathIterNextPathType(GpPathIterator*,INT*,BYTE*,INT*,INT*);
GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator*,INT*,INT*,INT*,BOOL*);
GpStatus WINGDIPAPI GdipPathIterNextSubpathPath(GpPathIterator*,INT*,GpPath*,BOOL*);
GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator*);
GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator*,INT*);
GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator*,INT*);
GpStatus WINGDIPAPI GdipPathIterEnumerate(GpPathIterator*,INT*,GpPointF*,BYTE*,INT);
GpStatus WINGDIPAPI GdipPathIterHasCurve(GpPathIterator*,BOOL*);
GpStatus WINGDIPAPI GdipPathIterIsValid(GpPathIterator*,BOOL*);
GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap*,GpCustomLineCap**);
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath*,GpPath*,GpLineCap,REAL,
@ -418,8 +438,12 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC,GDIPCONST LOGFONTW*,GpFont**)
GpStatus WINGDIPAPI GdipDeleteFont(GpFont*);
GpStatus WINGDIPAPI GdipGetLogFontW(GpFont*,GpGraphics*,LOGFONTW*);
GpStatus WINGDIPAPI GdipCloneFont(GpFont*,GpFont**);
GpStatus WINGDIPAPI GdipGetFamily(GpFont*, GpFontFamily**);
GpStatus WINGDIPAPI GdipGetFontUnit(GpFont*, Unit*);
GpStatus WINGDIPAPI GdipGetFontSize(GpFont*, REAL*);
GpStatus WINGDIPAPI GdipGetFontStyle(GpFont*, INT*);
GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont*, GDIPCONST GpGraphics*,
REAL*);
GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont*, REAL, REAL*);
GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR*,
@ -499,6 +523,19 @@ GpStatus WINGDIPAPI GdipTranslateRegion(GpRegion *, REAL, REAL);
GpStatus WINGDIPAPI GdipTranslateRegionI(GpRegion *, INT, INT);
GpStatus WINGDIPAPI GdipFlush(GpGraphics*, GpFlushIntention);
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile*,UINT);
GpStatus WINGDIPAPI GdipSetClipRectI(GpGraphics*,INT,INT,INT,INT,CombineMode);
GpStatus WINGDIPAPI GdipFillRegion(GpGraphics*,GpBrush*,GpRegion*);
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL,REAL,BOOL,GpAdjustableArrowCap**);
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap*,BOOL*);
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap*,REAL*);
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap*,REAL*);
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap*,REAL*);
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap*,BOOL);
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap*,REAL);
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap*,REAL);
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap*,REAL);
#ifdef __cplusplus
}

View file

@ -28,6 +28,7 @@ class GpPath {};
class GpMatrix {};
class GpPathIterator {};
class GpCustomLineCap {};
class GpAdjustableArrowCap : public GpCustomLineCap {};
class GpImage {};
class GpMetafile : public GpImage {};
class GpImageAttributes {};
@ -52,6 +53,7 @@ typedef struct GpPath GpPath;
typedef struct GpMatrix GpMatrix;
typedef struct GpPathIterator GpPathIterator;
typedef struct GpCustomLineCap GpCustomLineCap;
typedef struct GpAdjustableArrowCap GpAdjustableArrowCap;
typedef struct GpImage GpImage;
typedef struct GpMetafile GpMetafile;
typedef struct GpImageAttributes GpImageAttributes;