2008-03-25 17:34:57 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007 Google (Evan Stade)
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2018-03-09 12:09:03 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "wingdi.h"
|
|
|
|
|
|
|
|
#include "objbase.h"
|
|
|
|
|
|
|
|
#include "gdiplus.h"
|
2008-03-25 17:34:57 +00:00
|
|
|
#include "gdiplus_private.h"
|
2018-03-09 12:09:03 +00:00
|
|
|
#include "wine/debug.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
static DWORD gdip_to_gdi_dash(GpDashStyle dash)
|
|
|
|
{
|
|
|
|
switch(dash){
|
|
|
|
case DashStyleSolid:
|
|
|
|
return PS_SOLID;
|
|
|
|
case DashStyleDash:
|
|
|
|
return PS_DASH;
|
|
|
|
case DashStyleDot:
|
|
|
|
return PS_DOT;
|
|
|
|
case DashStyleDashDot:
|
|
|
|
return PS_DASHDOT;
|
|
|
|
case DashStyleDashDotDot:
|
|
|
|
return PS_DASHDOTDOT;
|
|
|
|
case DashStyleCustom:
|
|
|
|
return PS_USERSTYLE;
|
|
|
|
default:
|
|
|
|
ERR("Not a member of GpDashStyle enumeration\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD gdip_to_gdi_join(GpLineJoin join)
|
|
|
|
{
|
|
|
|
switch(join){
|
|
|
|
case LineJoinRound:
|
|
|
|
return PS_JOIN_ROUND;
|
|
|
|
case LineJoinBevel:
|
|
|
|
return PS_JOIN_BEVEL;
|
|
|
|
case LineJoinMiter:
|
|
|
|
case LineJoinMiterClipped:
|
|
|
|
return PS_JOIN_MITER;
|
|
|
|
default:
|
|
|
|
ERR("Not a member of GpLineJoin enumeration\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
static GpPenType bt_to_pt(GpBrushType bt)
|
|
|
|
{
|
|
|
|
switch(bt){
|
|
|
|
case BrushTypeSolidColor:
|
|
|
|
return PenTypeSolidColor;
|
|
|
|
case BrushTypeHatchFill:
|
|
|
|
return PenTypeHatchFill;
|
|
|
|
case BrushTypeTextureFill:
|
|
|
|
return PenTypeTextureFill;
|
|
|
|
case BrushTypePathGradient:
|
|
|
|
return PenTypePathGradient;
|
|
|
|
case BrushTypeLinearGradient:
|
|
|
|
return PenTypeLinearGradient;
|
|
|
|
default:
|
|
|
|
return PenTypeUnknown;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
|
|
|
|
{
|
2013-09-19 15:10:19 +00:00
|
|
|
GpStatus stat;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, clonepen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !clonepen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2015-11-22 10:10:02 +00:00
|
|
|
*clonepen = heap_alloc_zero(sizeof(GpPen));
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!*clonepen) return OutOfMemory;
|
|
|
|
|
|
|
|
**clonepen = *pen;
|
|
|
|
|
2013-09-19 15:10:19 +00:00
|
|
|
(*clonepen)->customstart = NULL;
|
|
|
|
(*clonepen)->customend = NULL;
|
|
|
|
(*clonepen)->brush = NULL;
|
|
|
|
(*clonepen)->dashes = NULL;
|
|
|
|
|
|
|
|
stat = GdipCloneBrush(pen->brush, &(*clonepen)->brush);
|
|
|
|
|
|
|
|
if (stat == Ok && pen->customstart)
|
|
|
|
stat = GdipCloneCustomLineCap(pen->customstart, &(*clonepen)->customstart);
|
|
|
|
|
|
|
|
if (stat == Ok && pen->customend)
|
|
|
|
stat = GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
|
|
|
|
|
|
|
|
if (stat == Ok && pen->dashes)
|
|
|
|
{
|
2015-11-22 10:10:02 +00:00
|
|
|
(*clonepen)->dashes = heap_alloc_zero(pen->numdashes * sizeof(REAL));
|
2013-09-19 15:10:19 +00:00
|
|
|
if ((*clonepen)->dashes)
|
|
|
|
memcpy((*clonepen)->dashes, pen->dashes, pen->numdashes * sizeof(REAL));
|
|
|
|
else
|
|
|
|
stat = OutOfMemory;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stat != Ok)
|
|
|
|
{
|
|
|
|
GdipDeletePen(*clonepen);
|
|
|
|
*clonepen = NULL;
|
|
|
|
return stat;
|
|
|
|
}
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *clonepen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, REAL width, GpUnit unit,
|
|
|
|
GpPen **pen)
|
|
|
|
{
|
|
|
|
GpBrush *brush;
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus status;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%x, %.2f, %d, %p)\n", color, width, unit, pen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GdipCreateSolidFill(color, (GpSolidFill **)(&brush));
|
2008-07-02 08:19:00 +00:00
|
|
|
status = GdipCreatePen2(brush, width, unit, pen);
|
|
|
|
GdipDeleteBrush(brush);
|
|
|
|
return status;
|
2008-03-25 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit,
|
|
|
|
GpPen **pen)
|
|
|
|
{
|
|
|
|
GpPen *gp_pen;
|
2008-07-02 08:19:00 +00:00
|
|
|
GpBrush *clone_brush;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %.2f, %d, %p)\n", brush, width, unit, pen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !brush)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2015-11-22 10:10:02 +00:00
|
|
|
gp_pen = heap_alloc_zero(sizeof(GpPen));
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!gp_pen) return OutOfMemory;
|
|
|
|
|
|
|
|
gp_pen->style = GP_DEFAULT_PENSTYLE;
|
|
|
|
gp_pen->width = width;
|
|
|
|
gp_pen->unit = unit;
|
|
|
|
gp_pen->endcap = LineCapFlat;
|
|
|
|
gp_pen->join = LineJoinMiter;
|
|
|
|
gp_pen->miterlimit = 10.0;
|
|
|
|
gp_pen->dash = DashStyleSolid;
|
|
|
|
gp_pen->offset = 0.0;
|
2008-08-05 12:23:58 +00:00
|
|
|
gp_pen->customstart = NULL;
|
|
|
|
gp_pen->customend = NULL;
|
2016-03-02 10:34:40 +00:00
|
|
|
GdipSetMatrixElements(&gp_pen->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) {
|
|
|
|
FIXME("UnitWorld, UnitPixel only supported units\n");
|
2015-11-22 10:10:02 +00:00
|
|
|
heap_free(gp_pen);
|
2008-03-25 17:34:57 +00:00
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GdipCloneBrush(brush, &clone_brush);
|
|
|
|
gp_pen->brush = clone_brush;
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
*pen = gp_pen;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("<-- %p\n", *pen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p)\n", pen);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
|
|
|
GdipDeleteBrush(pen->brush);
|
|
|
|
GdipDeleteCustomLineCap(pen->customstart);
|
|
|
|
GdipDeleteCustomLineCap(pen->customend);
|
2015-11-22 10:10:02 +00:00
|
|
|
heap_free(pen->dashes);
|
|
|
|
heap_free(pen);
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenBrushFill(GpPen *pen, GpBrush **brush)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, brush);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !brush)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return GdipCloneBrush(pen->brush, brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenColor(GpPen *pen, ARGB *argb)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, argb);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !argb)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(pen->brush->bt != BrushTypeSolidColor)
|
|
|
|
return NotImplemented;
|
|
|
|
|
|
|
|
return GdipGetSolidFillColor(((GpSolidFill*)pen->brush), argb);
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenCustomEndCap(GpPen *pen, GpCustomLineCap** customCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, customCap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!pen || !customCap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!pen->customend){
|
|
|
|
*customCap = NULL;
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GdipCloneCustomLineCap(pen->customend, customCap);
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenCustomStartCap(GpPen *pen, GpCustomLineCap** customCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, customCap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!pen || !customCap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!pen->customstart){
|
|
|
|
*customCap = NULL;
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GdipCloneCustomLineCap(pen->customstart, customCap);
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p, %d)\n", pen, dash, count);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !dash || count > pen->numdashes)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
/* note: if you pass a negative value for count, it crashes native gdiplus. */
|
|
|
|
if(count < 0)
|
|
|
|
return GenericError;
|
|
|
|
|
|
|
|
memcpy(dash, pen->dashes, count * sizeof(REAL));
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, dashCap);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !dashCap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*dashCap = pen->dashcap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenDashCount(GpPen *pen, INT *count)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, count);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!pen || !count)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*count = pen->numdashes;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen *pen, REAL *offset)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, offset);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !offset)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*offset = pen->offset;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, dash);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !dash)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*dash = pen->dash;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenEndCap(GpPen *pen, GpLineCap *endCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, endCap);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !endCap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*endCap = pen->endcap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenFillType(GpPen *pen, GpPenType* type)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p)\n", pen, type);
|
|
|
|
|
|
|
|
if(!pen || !type)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*type = bt_to_pt(pen->brush->bt);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, lineJoin);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !lineJoin)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*lineJoin = pen->join;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenMode(GpPen *pen, GpPenAlignment *mode)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, mode);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!pen || !mode)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*mode = pen->align;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, miterLimit);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !miterLimit)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*miterLimit = pen->miterlimit;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenStartCap(GpPen *pen, GpLineCap *startCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, startCap);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !startCap)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*startCap = pen->startcap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenUnit(GpPen *pen, GpUnit *unit)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, unit);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !unit)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*unit = pen->unit;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenWidth(GpPen *pen, REAL *width)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, width);
|
|
|
|
|
2008-07-02 08:19:00 +00:00
|
|
|
if(!pen || !width)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
*width = pen->width;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2009-01-27 18:03:33 +00:00
|
|
|
GpStatus WINGDIPAPI GdipResetPenTransform(GpPen *pen)
|
|
|
|
{
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p)\n", pen);
|
|
|
|
|
2009-01-27 18:03:33 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2016-03-02 10:34:40 +00:00
|
|
|
GdipSetMatrixElements(&pen->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
2009-01-27 18:03:33 +00:00
|
|
|
|
2016-03-02 10:34:40 +00:00
|
|
|
return Ok;
|
2009-01-27 18:03:33 +00:00
|
|
|
}
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenTransform(GpPen *pen, GpMatrix *matrix)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n", pen, matrix);
|
|
|
|
|
|
|
|
if(!pen || !matrix)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
2016-03-02 10:34:40 +00:00
|
|
|
FIXME("(%p,%p) Semi-stub\n", pen, matrix);
|
|
|
|
|
|
|
|
pen->transform = *matrix;
|
2010-11-20 11:24:17 +00:00
|
|
|
|
2016-03-02 10:34:40 +00:00
|
|
|
return Ok;
|
2010-11-20 11:24:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *pen, GpMatrix *matrix)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p)\n", pen, matrix);
|
|
|
|
|
|
|
|
if(!pen || !matrix)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2016-03-02 10:34:40 +00:00
|
|
|
*matrix = pen->transform;
|
2010-11-20 11:24:17 +00:00
|
|
|
|
2016-03-02 10:34:40 +00:00
|
|
|
return Ok;
|
2010-11-20 11:24:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder order)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, dx, dy, order);
|
|
|
|
|
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2009-01-27 18:03:33 +00:00
|
|
|
GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder order)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
2010-03-04 13:34:05 +00:00
|
|
|
TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, sx, sy, order);
|
|
|
|
|
2009-01-27 18:03:33 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("(%p, %.2f, %.2f, %d) stub\n", pen, sx, sy, order);
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2010-11-20 11:24:17 +00:00
|
|
|
GpStatus WINGDIPAPI GdipRotatePenTransform(GpPen *pen, REAL angle, GpMatrixOrder order)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%0.2f,%u)\n", pen, angle, order);
|
|
|
|
|
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
GpStatus WINGDIPAPI GdipMultiplyPenTransform(GpPen *pen, GDIPCONST GpMatrix *matrix,
|
|
|
|
GpMatrixOrder order)
|
|
|
|
{
|
|
|
|
static int calls;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%u)\n", pen, matrix, order);
|
|
|
|
|
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(!(calls++))
|
|
|
|
FIXME("not implemented\n");
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, brush);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !brush)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
GdipDeleteBrush(pen->brush);
|
|
|
|
return GdipCloneBrush(brush, &pen->brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %x)\n", pen, argb);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(pen->brush->bt != BrushTypeSolidColor)
|
|
|
|
return NotImplemented;
|
|
|
|
|
|
|
|
return GdipSetSolidFillColor(((GpSolidFill*)pen->brush), argb);
|
|
|
|
}
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
GpStatus WINGDIPAPI GdipGetPenCompoundCount(GpPen *pen, INT *count)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %p): stub\n", pen, count);
|
|
|
|
|
|
|
|
if (!pen || !count)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *dash,
|
|
|
|
INT count)
|
|
|
|
{
|
2008-12-16 18:41:07 +00:00
|
|
|
FIXME("(%p, %p, %i): stub\n", pen, dash, count);
|
2008-12-06 09:26:01 +00:00
|
|
|
|
|
|
|
if (!pen || !dash || count < 2 || count%2 == 1)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
return NotImplemented;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCap)
|
|
|
|
{
|
|
|
|
GpCustomLineCap * cap;
|
|
|
|
GpStatus ret;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, customCap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/* native crashes on pen == NULL, customCap != NULL */
|
|
|
|
if(!customCap) return InvalidParameter;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
|
|
|
|
GdipDeleteCustomLineCap(pen->customend);
|
|
|
|
pen->endcap = LineCapCustom;
|
|
|
|
pen->customend = cap;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap* customCap)
|
|
|
|
{
|
|
|
|
GpCustomLineCap * cap;
|
|
|
|
GpStatus ret;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p)\n", pen, customCap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
/* native crashes on pen == NULL, customCap != NULL */
|
|
|
|
if(!customCap) return InvalidParameter;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
|
|
|
|
GdipDeleteCustomLineCap(pen->customstart);
|
|
|
|
pen->startcap = LineCapCustom;
|
|
|
|
pen->customstart = cap;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash,
|
|
|
|
INT count)
|
|
|
|
{
|
|
|
|
INT i;
|
|
|
|
REAL sum = 0;
|
|
|
|
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %p, %d)\n", pen, dash, count);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen || !dash)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2008-06-01 13:14:02 +00:00
|
|
|
if(count <= 0)
|
|
|
|
return OutOfMemory;
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
for(i = 0; i < count; i++){
|
|
|
|
sum += dash[i];
|
|
|
|
if(dash[i] < 0.0)
|
|
|
|
return InvalidParameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sum == 0.0 && count)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
2015-11-22 10:10:02 +00:00
|
|
|
heap_free(pen->dashes);
|
2008-03-25 17:34:57 +00:00
|
|
|
pen->dashes = NULL;
|
|
|
|
|
|
|
|
if(count > 0)
|
2015-11-22 10:10:02 +00:00
|
|
|
pen->dashes = heap_alloc_zero(count * sizeof(REAL));
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen->dashes){
|
|
|
|
pen->numdashes = 0;
|
|
|
|
return OutOfMemory;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdipSetPenDashStyle(pen, DashStyleCustom);
|
|
|
|
memcpy(pen->dashes, dash, count * sizeof(REAL));
|
|
|
|
pen->numdashes = count;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenDashCap197819(GpPen *pen, GpDashCap dashCap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, dashCap);
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
pen->dashcap = dashCap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
/* FIXME: dash offset not used */
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen *pen, REAL offset)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %.2f)\n", pen, offset);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
pen->offset = offset;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, dash);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
if(dash != DashStyleCustom){
|
2015-11-22 10:10:02 +00:00
|
|
|
heap_free(pen->dashes);
|
2008-03-25 17:34:57 +00:00
|
|
|
pen->dashes = NULL;
|
|
|
|
pen->numdashes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pen->dash = dash;
|
|
|
|
pen->style &= ~(PS_ALTERNATE | PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT |
|
|
|
|
PS_DASHDOTDOT | PS_NULL | PS_USERSTYLE | PS_INSIDEFRAME);
|
|
|
|
pen->style |= gdip_to_gdi_dash(dash);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenEndCap(GpPen *pen, GpLineCap cap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, cap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
|
|
|
/* The old custom cap gets deleted even if the new style is LineCapCustom. */
|
|
|
|
GdipDeleteCustomLineCap(pen->customend);
|
|
|
|
pen->customend = NULL;
|
|
|
|
pen->endcap = cap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: startcap, dashcap not used. */
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenLineCap197819(GpPen *pen, GpLineCap start,
|
|
|
|
GpLineCap end, GpDashCap dash)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("%p, %d, %d, %d)\n", pen, start, end, dash);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
GdipDeleteCustomLineCap(pen->customend);
|
|
|
|
GdipDeleteCustomLineCap(pen->customstart);
|
|
|
|
pen->customend = NULL;
|
|
|
|
pen->customstart = NULL;
|
|
|
|
|
|
|
|
pen->startcap = start;
|
|
|
|
pen->endcap = end;
|
|
|
|
pen->dashcap = dash;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Miter line joins behave a bit differently than they do in windows.
|
|
|
|
* Both kinds of miter joins clip if the angle is less than 11 degrees. */
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, join);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
|
|
|
pen->join = join;
|
|
|
|
pen->style &= ~(PS_JOIN_ROUND | PS_JOIN_BEVEL | PS_JOIN_MITER);
|
|
|
|
pen->style |= gdip_to_gdi_join(join);
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen *pen, REAL limit)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %.2f)\n", pen, limit);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen)
|
|
|
|
return InvalidParameter;
|
|
|
|
|
|
|
|
pen->miterlimit = limit;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen *pen, GpLineCap cap)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, cap);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
|
|
|
GdipDeleteCustomLineCap(pen->customstart);
|
|
|
|
pen->customstart = NULL;
|
|
|
|
pen->startcap = cap;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
GpStatus WINGDIPAPI GdipSetPenWidth(GpPen *pen, REAL width)
|
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %.2f)\n", pen, width);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
|
|
|
pen->width = width;
|
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
GpStatus WINGDIPAPI GdipSetPenMode(GpPen *pen, GpPenAlignment mode)
|
2008-03-25 17:34:57 +00:00
|
|
|
{
|
2008-12-06 09:26:01 +00:00
|
|
|
TRACE("(%p, %d)\n", pen, mode);
|
|
|
|
|
2008-03-25 17:34:57 +00:00
|
|
|
if(!pen) return InvalidParameter;
|
|
|
|
|
2008-08-05 12:23:58 +00:00
|
|
|
pen->align = mode;
|
2008-03-25 17:34:57 +00:00
|
|
|
|
|
|
|
return Ok;
|
|
|
|
}
|