blob: ca81bee2174e84fe4aee86c556f9ccfcb1cb9faf [file] [log] [blame]
/*
* 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
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "objbase.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
GpCustomLineCap** to)
{
TRACE("(%p, %p)\n", from, to);
if(!from || !to)
return InvalidParameter;
*to = heap_alloc_zero(sizeof(GpCustomLineCap));
if(!*to) return OutOfMemory;
memcpy(*to, from, sizeof(GpCustomLineCap));
(*to)->pathdata.Points = heap_alloc_zero(from->pathdata.Count * sizeof(PointF));
(*to)->pathdata.Types = heap_alloc_zero(from->pathdata.Count);
if((!(*to)->pathdata.Types || !(*to)->pathdata.Points) && (*to)->pathdata.Count){
heap_free((*to)->pathdata.Points);
heap_free((*to)->pathdata.Types);
heap_free(*to);
return OutOfMemory;
}
memcpy((*to)->pathdata.Points, from->pathdata.Points, from->pathdata.Count
* sizeof(PointF));
memcpy((*to)->pathdata.Types, from->pathdata.Types, from->pathdata.Count);
TRACE("<-- %p\n", *to);
return Ok;
}
/* FIXME: Sometimes when fillPath is non-null and stroke path is null, the native
* version of this function returns NotImplemented. I cannot figure out why. */
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
{
GpPathData *pathdata;
TRACE("%p %p %d %f %p\n", fillPath, strokePath, baseCap, baseInset, customCap);
if(!customCap || !(fillPath || strokePath))
return InvalidParameter;
*customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
if(!*customCap) return OutOfMemory;
(*customCap)->type = CustomLineCapTypeDefault;
if(strokePath){
(*customCap)->fill = FALSE;
pathdata = &strokePath->pathdata;
}
else{
(*customCap)->fill = TRUE;
pathdata = &fillPath->pathdata;
}
(*customCap)->pathdata.Points = heap_alloc_zero(pathdata->Count * sizeof(PointF));
(*customCap)->pathdata.Types = heap_alloc_zero(pathdata->Count);
if((!(*customCap)->pathdata.Types || !(*customCap)->pathdata.Points) &&
pathdata->Count){
heap_free((*customCap)->pathdata.Points);
heap_free((*customCap)->pathdata.Types);
heap_free(*customCap);
return OutOfMemory;
}
memcpy((*customCap)->pathdata.Points, pathdata->Points, pathdata->Count
* sizeof(PointF));
memcpy((*customCap)->pathdata.Types, pathdata->Types, pathdata->Count);
(*customCap)->pathdata.Count = pathdata->Count;
(*customCap)->inset = baseInset;
(*customCap)->cap = baseCap;
(*customCap)->join = LineJoinMiter;
(*customCap)->scale = 1.0;
TRACE("<-- %p\n", *customCap);
return Ok;
}
GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
{
TRACE("(%p)\n", customCap);
if(!customCap)
return InvalidParameter;
heap_free(customCap->pathdata.Points);
heap_free(customCap->pathdata.Types);
heap_free(customCap);
return Ok;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap,
GpLineJoin* lineJoin)
{
TRACE("(%p, %p)\n", customCap, lineJoin);
if(!customCap || !lineJoin)
return InvalidParameter;
*lineJoin = customCap->join;
return Ok;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap* custom,
REAL* widthScale)
{
TRACE("(%p, %p)\n", custom, widthScale);
if(!custom || !widthScale)
return InvalidParameter;
*widthScale = custom->scale;
return Ok;
}
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap* custom,
GpLineCap start, GpLineCap end)
{
static int calls;
TRACE("(%p,%u,%u)\n", custom, start, end);
if(!custom)
return InvalidParameter;
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap* custom,
GpLineCap base)
{
static int calls;
TRACE("(%p,%u)\n", custom, base);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap* custom,
REAL* inset)
{
TRACE("(%p, %p)\n", custom, inset);
if(!custom || !inset)
return InvalidParameter;
*inset = custom->inset;
return Ok;
}
GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap* custom,
REAL inset)
{
static int calls;
TRACE("(%p,%0.2f)\n", custom, inset);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
/*FIXME: LineJoin completely ignored now */
GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* custom,
GpLineJoin join)
{
TRACE("(%p, %d)\n", custom, join);
if(!custom)
return InvalidParameter;
custom->join = join;
return Ok;
}
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap* custom, REAL width)
{
TRACE("(%p,%0.2f)\n", custom, width);
if(!custom)
return InvalidParameter;
custom->scale = width;
return Ok;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLineCap *baseCap)
{
TRACE("(%p, %p)\n", customCap, baseCap);
if(!customCap || !baseCap)
return InvalidParameter;
*baseCap = customCap->cap;
return Ok;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomLineCapType *type)
{
TRACE("(%p, %p)\n", customCap, type);
if(!customCap || !type)
return InvalidParameter;
*type = customCap->type;
return Ok;
}
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
GpAdjustableArrowCap **cap)
{
static int calls;
TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
{
static int calls;
TRACE("(%p,%p)\n", cap, fill);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
{
static int calls;
TRACE("(%p,%p)\n", cap, height);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middle)
{
static int calls;
TRACE("(%p,%p)\n", cap, middle);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width)
{
static int calls;
TRACE("(%p,%p)\n", cap, width);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
{
static int calls;
TRACE("(%p,%i)\n", cap, fill);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
{
static int calls;
TRACE("(%p,%0.2f)\n", cap, height);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middle)
{
static int calls;
TRACE("(%p,%0.2f)\n", cap, middle);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width)
{
static int calls;
TRACE("(%p,%0.2f)\n", cap, width);
if(!(calls++))
FIXME("not implemented\n");
return NotImplemented;
}