/*
 * 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 "winuser.h"
#include "wingdi.h"

#define COBJMACROS
#include "objbase.h"
#include "olectl.h"
#include "ole2.h"

#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);

/******************************************************************************
 * GdipCloneBrush [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
{
    TRACE("(%p, %p)\n", brush, clone);

    if(!brush || !clone)
        return InvalidParameter;

    switch(brush->bt){
        case BrushTypeSolidColor:
        {
            *clone = GdipAlloc(sizeof(GpSolidFill));
            if (!*clone) return OutOfMemory;
            memcpy(*clone, brush, sizeof(GpSolidFill));
            break;
        }
        case BrushTypeHatchFill:
        {
            GpHatch *hatch = (GpHatch*)brush;

            return GdipCreateHatchBrush(hatch->hatchstyle, hatch->forecol, hatch->backcol, (GpHatch**)clone);
        }
        case BrushTypePathGradient:{
            GpPathGradient *src, *dest;
            INT count, pcount;
            GpStatus stat;

            *clone = GdipAlloc(sizeof(GpPathGradient));
            if (!*clone) return OutOfMemory;

            src = (GpPathGradient*) brush,
            dest = (GpPathGradient*) *clone;

            memcpy(dest, src, sizeof(GpPathGradient));

            stat = GdipClonePath(src->path, &dest->path);

            if(stat != Ok){
                GdipFree(dest);
                return stat;
            }

            stat = GdipCloneMatrix(src->transform, &dest->transform);

            if(stat != Ok){
                GdipDeletePath(dest->path);
                GdipFree(dest);
                return stat;
            }

            /* blending */
            count = src->blendcount;
            dest->blendcount = count;
            dest->blendfac = GdipAlloc(count * sizeof(REAL));
            dest->blendpos = GdipAlloc(count * sizeof(REAL));
            dest->surroundcolors = GdipAlloc(dest->surroundcolorcount * sizeof(ARGB));
            pcount = dest->pblendcount;
            if (pcount)
            {
                dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
                dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
            }

            if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors ||
               (pcount && (!dest->pblendcolor || !dest->pblendpos))){
                GdipDeletePath(dest->path);
                GdipDeleteMatrix(dest->transform);
                GdipFree(dest->blendfac);
                GdipFree(dest->blendpos);
                GdipFree(dest->surroundcolors);
                GdipFree(dest->pblendcolor);
                GdipFree(dest->pblendpos);
                GdipFree(dest);
                return OutOfMemory;
            }

            memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
            memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
            memcpy(dest->surroundcolors, src->surroundcolors, dest->surroundcolorcount * sizeof(ARGB));

            if (pcount)
            {
                memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
                memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
            }

            break;
        }
        case BrushTypeLinearGradient:{
            GpLineGradient *dest, *src;
            INT count, pcount;

            dest = GdipAlloc(sizeof(GpLineGradient));
            if(!dest)    return OutOfMemory;

            src = (GpLineGradient*)brush;

            memcpy(dest, src, sizeof(GpLineGradient));

            count = dest->blendcount;
            dest->blendfac = GdipAlloc(count * sizeof(REAL));
            dest->blendpos = GdipAlloc(count * sizeof(REAL));
            pcount = dest->pblendcount;
            if (pcount)
            {
                dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
                dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
            }

            if (!dest->blendfac || !dest->blendpos ||
                (pcount && (!dest->pblendcolor || !dest->pblendpos)))
            {
                GdipFree(dest->blendfac);
                GdipFree(dest->blendpos);
                GdipFree(dest->pblendcolor);
                GdipFree(dest->pblendpos);
                GdipFree(dest);
                return OutOfMemory;
            }

            memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
            memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));

            if (pcount)
            {
                memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
                memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
            }

            *clone = &dest->brush;
            break;
        }
        case BrushTypeTextureFill:
        {
            GpStatus stat;
            GpTexture *texture = (GpTexture*)brush;
            GpTexture *new_texture;
            UINT width, height;

            stat = GdipGetImageWidth(texture->image, &width);
            if (stat != Ok) return stat;
            stat = GdipGetImageHeight(texture->image, &height);
            if (stat != Ok) return stat;

            stat = GdipCreateTextureIA(texture->image, texture->imageattributes, 0, 0, width, height, &new_texture);

            if (stat == Ok)
            {
                memcpy(new_texture->transform, texture->transform, sizeof(GpMatrix));
                *clone = (GpBrush*)new_texture;
            }
            else
                *clone = NULL;

            return stat;
        }
        default:
            ERR("not implemented for brush type %d\n", brush->bt);
            return NotImplemented;
    }

    TRACE("<-- %p\n", *clone);
    return Ok;
}

static const char HatchBrushes[][8] = {
    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
    { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
    { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
    { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
    { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
    { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
    { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
    { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
    { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
    { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
    { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
    { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
    { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
    { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
    { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
    { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
    { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
    { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
    { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
    { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
    { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
    { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
    { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
    { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
    { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
    { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
};

GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result)
{
    if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
    {
        *result = HatchBrushes[hatchstyle];
        return Ok;
    }
    else
        return NotImplemented;
}

/******************************************************************************
 * GdipCreateHatchBrush [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
{
    TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);

    if(!brush)  return InvalidParameter;

    *brush = GdipAlloc(sizeof(GpHatch));
    if (!*brush) return OutOfMemory;

    (*brush)->brush.bt = BrushTypeHatchFill;
    (*brush)->forecol = forecol;
    (*brush)->backcol = backcol;
    (*brush)->hatchstyle = hatchstyle;
    TRACE("<-- %p\n", *brush);

    return Ok;
}

/******************************************************************************
 * GdipCreateLineBrush [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
    GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor,
    GpWrapMode wrap, GpLineGradient **line)
{
    TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint),
          debugstr_pointf(endpoint), startcolor, endcolor, wrap, line);

    if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
        return InvalidParameter;

    if (startpoint->X == endpoint->X && startpoint->Y == endpoint->Y)
        return OutOfMemory;

    *line = GdipAlloc(sizeof(GpLineGradient));
    if(!*line)  return OutOfMemory;

    (*line)->brush.bt = BrushTypeLinearGradient;

    (*line)->startpoint.X = startpoint->X;
    (*line)->startpoint.Y = startpoint->Y;
    (*line)->endpoint.X = endpoint->X;
    (*line)->endpoint.Y = endpoint->Y;
    (*line)->startcolor = startcolor;
    (*line)->endcolor = endcolor;
    (*line)->wrap = wrap;
    (*line)->gamma = FALSE;

    (*line)->rect.X = (startpoint->X < endpoint->X ? startpoint->X: endpoint->X);
    (*line)->rect.Y = (startpoint->Y < endpoint->Y ? startpoint->Y: endpoint->Y);
    (*line)->rect.Width  = fabs(startpoint->X - endpoint->X);
    (*line)->rect.Height = fabs(startpoint->Y - endpoint->Y);

    if ((*line)->rect.Width == 0)
    {
        (*line)->rect.X -= (*line)->rect.Height / 2.0f;
        (*line)->rect.Width = (*line)->rect.Height;
    }
    else if ((*line)->rect.Height == 0)
    {
        (*line)->rect.Y -= (*line)->rect.Width / 2.0f;
        (*line)->rect.Height = (*line)->rect.Width;
    }

    (*line)->blendcount = 1;
    (*line)->blendfac = GdipAlloc(sizeof(REAL));
    (*line)->blendpos = GdipAlloc(sizeof(REAL));

    if (!(*line)->blendfac || !(*line)->blendpos)
    {
        GdipFree((*line)->blendfac);
        GdipFree((*line)->blendpos);
        GdipFree(*line);
        *line = NULL;
        return OutOfMemory;
    }

    (*line)->blendfac[0] = 1.0f;
    (*line)->blendpos[0] = 1.0f;

    (*line)->pblendcolor = NULL;
    (*line)->pblendpos = NULL;
    (*line)->pblendcount = 0;

    TRACE("<-- %p\n", *line);

    return Ok;
}

GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
    GDIPCONST GpPoint* endpoint, ARGB startcolor, ARGB endcolor,
    GpWrapMode wrap, GpLineGradient **line)
{
    GpPointF stF;
    GpPointF endF;

    TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
          startcolor, endcolor, wrap, line);

    if(!startpoint || !endpoint)
        return InvalidParameter;

    stF.X  = (REAL)startpoint->X;
    stF.Y  = (REAL)startpoint->Y;
    endF.X = (REAL)endpoint->X;
    endF.Y = (REAL)endpoint->Y;

    return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line);
}

GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
    ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
    GpLineGradient **line)
{
    GpPointF start, end;
    GpStatus stat;

    TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
          wrap, line);

    if(!line || !rect)
        return InvalidParameter;

    switch (mode)
    {
    case LinearGradientModeHorizontal:
        start.X = rect->X;
        start.Y = rect->Y;
        end.X = rect->X + rect->Width;
        end.Y = rect->Y;
        break;
    case LinearGradientModeVertical:
        start.X = rect->X;
        start.Y = rect->Y;
        end.X = rect->X;
        end.Y = rect->Y + rect->Height;
        break;
    case LinearGradientModeForwardDiagonal:
        start.X = rect->X;
        start.Y = rect->Y;
        end.X = rect->X + rect->Width;
        end.Y = rect->Y + rect->Height;
        break;
    case LinearGradientModeBackwardDiagonal:
        start.X = rect->X + rect->Width;
        start.Y = rect->Y;
        end.X = rect->X;
        end.Y = rect->Y + rect->Height;
        break;
    default:
        return InvalidParameter;
    }

    stat = GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line);

    if (stat == Ok)
        (*line)->rect = *rect;

    return stat;
}

GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
    ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
    GpLineGradient **line)
{
    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;
    rectF.Height = (REAL) rect->Height;

    return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
}

/******************************************************************************
 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
    ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
    GpLineGradient **line)
{
    GpStatus stat;
    LinearGradientMode mode;
    REAL width, height, exofs, eyofs;
    REAL sin_angle, cos_angle, sin_cos_angle;

    TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
          wrap, line);

    sin_angle = sinf(deg2rad(angle));
    cos_angle = cosf(deg2rad(angle));
    sin_cos_angle = sin_angle * cos_angle;

    if (isAngleScalable)
    {
        width = height = 1.0;
    }
    else
    {
        width = rect->Width;
        height = rect->Height;
    }

    if (sin_cos_angle >= 0)
        mode = LinearGradientModeForwardDiagonal;
    else
        mode = LinearGradientModeBackwardDiagonal;

    stat = GdipCreateLineBrushFromRect(rect, startcolor, endcolor, mode, wrap, line);

    if (stat == Ok)
    {
        if (sin_cos_angle >= 0)
        {
            exofs = width * sin_cos_angle + height * cos_angle * cos_angle;
            eyofs = width * sin_angle * sin_angle + height * sin_cos_angle;
        }
        else
        {
            exofs = width * sin_angle * sin_angle + height * sin_cos_angle;
            eyofs = -width * sin_cos_angle + height * sin_angle * sin_angle;
        }

        if (isAngleScalable)
        {
            exofs = exofs * rect->Width;
            eyofs = eyofs * rect->Height;
        }

        if (sin_angle >= 0)
        {
            (*line)->endpoint.X = rect->X + exofs;
            (*line)->endpoint.Y = rect->Y + eyofs;
        }
        else
        {
            (*line)->endpoint.X = (*line)->startpoint.X;
            (*line)->endpoint.Y = (*line)->startpoint.Y;
            (*line)->startpoint.X = rect->X + exofs;
            (*line)->startpoint.Y = rect->Y + eyofs;
        }
    }

    return stat;
}

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);
}

static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradient **grad)
{
    GpRectF bounds;
    GpStatus stat;

    if(!path || !grad)
        return InvalidParameter;

    if (path->pathdata.Count < 2)
        return OutOfMemory;

    GdipGetPathWorldBounds(path, &bounds, NULL, NULL);

    *grad = GdipAlloc(sizeof(GpPathGradient));
    if (!*grad)
    {
        return OutOfMemory;
    }

    stat = GdipCreateMatrix(&(*grad)->transform);
    if (stat != Ok)
    {
        GdipFree(*grad);
        return stat;
    }

    (*grad)->blendfac = GdipAlloc(sizeof(REAL));
    (*grad)->blendpos = GdipAlloc(sizeof(REAL));
    (*grad)->surroundcolors = GdipAlloc(sizeof(ARGB));
    if(!(*grad)->blendfac || !(*grad)->blendpos || !(*grad)->surroundcolors){
        GdipDeleteMatrix((*grad)->transform);
        GdipFree((*grad)->blendfac);
        GdipFree((*grad)->blendpos);
        GdipFree((*grad)->surroundcolors);
        GdipFree(*grad);
        *grad = NULL;
        return OutOfMemory;
    }
    (*grad)->blendfac[0] = 1.0;
    (*grad)->blendpos[0] = 1.0;
    (*grad)->blendcount  = 1;

    (*grad)->path = path;

    (*grad)->brush.bt = BrushTypePathGradient;
    (*grad)->centercolor = centercolor;
    (*grad)->wrap = WrapModeClamp;
    (*grad)->gamma = FALSE;
    /* FIXME: this should be set to the "centroid" of the path by default */
    (*grad)->center.X = bounds.X + bounds.Width / 2;
    (*grad)->center.Y = bounds.Y + bounds.Height / 2;
    (*grad)->focus.X = 0.0;
    (*grad)->focus.Y = 0.0;
    (*grad)->surroundcolors[0] = 0xffffffff;
    (*grad)->surroundcolorcount = 1;

    TRACE("<-- %p\n", *grad);

    return Ok;
}

GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
    INT count, GpWrapMode wrap, GpPathGradient **grad)
{
    GpStatus stat;
    GpPath *path;

    TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);

    if(!grad)
        return InvalidParameter;

    if(!points || count <= 0)
        return OutOfMemory;

    stat = GdipCreatePath(FillModeAlternate, &path);

    if (stat == Ok)
    {
        stat = GdipAddPathLine2(path, points, count);

        if (stat == Ok)
            stat = create_path_gradient(path, 0xff000000, grad);

        if (stat != Ok)
            GdipDeletePath(path);
    }

    if (stat == Ok)
        (*grad)->wrap = wrap;

    return stat;
}

GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
    INT count, GpWrapMode wrap, GpPathGradient **grad)
{
    GpStatus stat;
    GpPath *path;

    TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);

    if(!grad)
        return InvalidParameter;

    if(!points || count <= 0)
        return OutOfMemory;

    stat = GdipCreatePath(FillModeAlternate, &path);

    if (stat == Ok)
    {
        stat = GdipAddPathLine2I(path, points, count);

        if (stat == Ok)
            stat = create_path_gradient(path, 0xff000000, grad);

        if (stat != Ok)
            GdipDeletePath(path);
    }

    if (stat == Ok)
        (*grad)->wrap = wrap;

    return stat;
}

/******************************************************************************
 * GdipCreatePathGradientFromPath [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
    GpPathGradient **grad)
{
    GpStatus stat;
    GpPath *new_path;

    TRACE("(%p, %p)\n", path, grad);

    if(!grad)
        return InvalidParameter;

    if (!path)
        return OutOfMemory;

    stat = GdipClonePath((GpPath*)path, &new_path);

    if (stat == Ok)
    {
        stat = create_path_gradient(new_path, 0xffffffff, grad);

        if (stat != Ok)
            GdipDeletePath(new_path);
    }

    return stat;
}

/******************************************************************************
 * GdipCreateSolidFill [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
{
    TRACE("(%x, %p)\n", color, sf);

    if(!sf)  return InvalidParameter;

    *sf = GdipAlloc(sizeof(GpSolidFill));
    if (!*sf) return OutOfMemory;

    (*sf)->brush.bt = BrushTypeSolidColor;
    (*sf)->color = color;

    TRACE("<-- %p\n", *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;

    stat = GdipCreateImageAttributes(&attributes);

    if (stat == Ok)
    {
        attributes->wrap = wrapmode;

        stat = GdipCreateTextureIA(image, attributes, 0, 0, width, height,
            texture);

        GdipDisposeImageAttributes(attributes);
    }

    return stat;
}

/******************************************************************************
 * GdipCreateTexture2 [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode,
        REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
{
    GpImageAttributes *attributes;
    GpStatus stat;

    TRACE("%p %d %f %f %f %f %p\n", image, wrapmode,
            x, y, width, height, texture);

    stat = GdipCreateImageAttributes(&attributes);

    if (stat == Ok)
    {
        attributes->wrap = wrapmode;

        stat = GdipCreateTextureIA(image, attributes, x, y, width, height,
                texture);

        GdipDisposeImageAttributes(attributes);
    }

    return stat;
}

/******************************************************************************
 * GdipCreateTextureIA [GDIPLUS.@]
 *
 * FIXME: imageattr ignored
 */
GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
    GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
    REAL height, GpTexture **texture)
{
    GpStatus status;
    GpImage *new_image=NULL;

    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;

    *texture = NULL;

    if(image->type != ImageTypeBitmap){
        FIXME("not implemented for image type %d\n", image->type);
        return NotImplemented;
    }

    status = GdipCloneBitmapArea(x, y, width, height, PixelFormatDontCare, (GpBitmap*)image, (GpBitmap**)&new_image);
    if (status != Ok)
        return status;

    *texture = GdipAlloc(sizeof(GpTexture));
    if (!*texture){
        status = OutOfMemory;
        goto exit;
    }

    if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){
        goto exit;
    }

    if (imageattr)
    {
        status = GdipCloneImageAttributes(imageattr, &(*texture)->imageattributes);
    }
    else
    {
        status = GdipCreateImageAttributes(&(*texture)->imageattributes);
        if (status == Ok)
            (*texture)->imageattributes->wrap = WrapModeTile;
    }
    if (status == Ok)
    {
        (*texture)->brush.bt = BrushTypeTextureFill;
        (*texture)->image = new_image;
    }

exit:
    if (status == Ok)
    {
        TRACE("<-- %p\n", *texture);
    }
    else
    {
        if (*texture)
        {
            GdipDeleteMatrix((*texture)->transform);
            GdipDisposeImageAttributes((*texture)->imageattributes);
            GdipFree(*texture);
            *texture = NULL;
        }
        GdipDisposeImage(new_image);
        TRACE("<-- error %u\n", status);
    }

    return status;
}

/******************************************************************************
 * GdipCreateTextureIAI [GDIPLUS.@]
 */
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;
    GpStatus stat;

    TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
            texture);

    stat = GdipCreateImageAttributes(&imageattr);

    if (stat == Ok)
    {
        imageattr->wrap = wrapmode;

        stat = GdipCreateTextureIA(image, imageattr, x, y, width, height, texture);
    }

    return stat;
}

GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
{
    TRACE("(%p, %p)\n", brush, type);

    if(!brush || !type)  return InvalidParameter;

    *type = brush->bt;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetHatchBackgroundColor(GpHatch *brush, ARGB *backcol)
{
    TRACE("(%p, %p)\n", brush, backcol);

    if(!brush || !backcol)  return InvalidParameter;

    *backcol = brush->backcol;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol)
{
    TRACE("(%p, %p)\n", brush, forecol);

    if(!brush || !forecol)  return InvalidParameter;

    *forecol = brush->forecol;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle)
{
    TRACE("(%p, %p)\n", brush, hatchstyle);

    if(!brush || !hatchstyle)  return InvalidParameter;

    *hatchstyle = brush->hatchstyle;

    return Ok;
}

GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
{
    TRACE("(%p)\n", brush);

    if(!brush)  return InvalidParameter;

    switch(brush->bt)
    {
        case BrushTypePathGradient:
            GdipDeletePath(((GpPathGradient*) brush)->path);
            GdipDeleteMatrix(((GpPathGradient*) brush)->transform);
            GdipFree(((GpPathGradient*) brush)->blendfac);
            GdipFree(((GpPathGradient*) brush)->blendpos);
            GdipFree(((GpPathGradient*) brush)->surroundcolors);
            GdipFree(((GpPathGradient*) brush)->pblendcolor);
            GdipFree(((GpPathGradient*) brush)->pblendpos);
            break;
        case BrushTypeLinearGradient:
            GdipFree(((GpLineGradient*)brush)->blendfac);
            GdipFree(((GpLineGradient*)brush)->blendpos);
            GdipFree(((GpLineGradient*)brush)->pblendcolor);
            GdipFree(((GpLineGradient*)brush)->pblendpos);
            break;
        case BrushTypeTextureFill:
            GdipDeleteMatrix(((GpTexture*)brush)->transform);
            GdipDisposeImage(((GpTexture*)brush)->image);
            GdipDisposeImageAttributes(((GpTexture*)brush)->imageattributes);
            GdipFree(((GpTexture*)brush)->bitmap_bits);
            break;
        default:
            break;
    }

    GdipFree(brush);

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
    BOOL *usinggamma)
{
    TRACE("(%p, %p)\n", line, usinggamma);

    if(!line || !usinggamma)
        return InvalidParameter;

    *usinggamma = line->gamma;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
{
    TRACE("(%p, %p)\n", brush, wrapmode);

    if(!brush || !wrapmode)
        return InvalidParameter;

    *wrapmode = brush->wrap;

    return Ok;
}

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;

    if(count < brush->blendcount)
        return InsufficientBuffer;

    memcpy(blend, brush->blendfac, count*sizeof(REAL));
    if(brush->blendcount > 1){
        memcpy(positions, brush->blendpos, count*sizeof(REAL));
    }

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
{
    TRACE("(%p, %p)\n", brush, count);

    if(!brush || !count)
        return InvalidParameter;

    *count = brush->blendcount;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad,
    GpPointF *point)
{
    TRACE("(%p, %p)\n", grad, point);

    if(!grad || !point)
        return InvalidParameter;

    point->X = grad->center.X;
    point->Y = grad->center.Y;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
    GpPoint *point)
{
    GpStatus ret;
    GpPointF ptf;

    TRACE("(%p, %p)\n", grad, point);

    if(!point)
        return InvalidParameter;

    ret = GdipGetPathGradientCenterPoint(grad,&ptf);

    if(ret == Ok){
        point->X = gdip_round(ptf.X);
        point->Y = gdip_round(ptf.Y);
    }

    return ret;
}

GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient *grad,
    ARGB *colors)
{
    TRACE("(%p,%p)\n", grad, colors);

    if (!grad || !colors)
        return InvalidParameter;

    *colors = grad->centercolor;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad,
    REAL *x, REAL *y)
{
    TRACE("(%p, %p, %p)\n", grad, x, y);

    if(!grad || !x || !y)
        return InvalidParameter;

    *x = grad->focus.X;
    *y = grad->focus.Y;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad,
    BOOL *gamma)
{
    TRACE("(%p, %p)\n", grad, gamma);

    if(!grad || !gamma)
        return InvalidParameter;

    *gamma = grad->gamma;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientPath(GpPathGradient *grad, GpPath *path)
{
    static int calls;

    TRACE("(%p, %p)\n", grad, path);

    if (!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
    INT *count)
{
    TRACE("(%p, %p)\n", grad, count);

    if(!grad || !count)
        return InvalidParameter;

    *count = grad->path->pathdata.Count;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
{
    GpStatus stat;

    TRACE("(%p, %p)\n", brush, rect);

    if(!brush || !rect)
        return InvalidParameter;

    stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL);

    return stat;
}

GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
{
    GpRectF rectf;
    GpStatus stat;

    TRACE("(%p, %p)\n", brush, rect);

    if(!brush || !rect)
        return InvalidParameter;

    stat = GdipGetPathGradientRect(brush, &rectf);
    if(stat != Ok)  return stat;

    rect->X = gdip_round(rectf.X);
    rect->Y = gdip_round(rectf.Y);
    rect->Width  = gdip_round(rectf.Width);
    rect->Height = gdip_round(rectf.Height);

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
    *grad, ARGB *argb, INT *count)
{
    INT i;

    TRACE("(%p,%p,%p)\n", grad, argb, count);

    if(!grad || !argb || !count || (*count < grad->path->pathdata.Count))
        return InvalidParameter;

    for (i=0; i<grad->path->pathdata.Count; i++)
    {
        if (i < grad->surroundcolorcount)
            argb[i] = grad->surroundcolors[i];
        else
            argb[i] = grad->surroundcolors[grad->surroundcolorcount-1];
    }

    *count = grad->surroundcolorcount;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT *count)
{
    TRACE("(%p, %p)\n", brush, count);

    if (!brush || !count)
       return InvalidParameter;

    /* Yes, this actually returns the number of points in the path (which is the
     * required size of a buffer to get the surround colors), rather than the
     * number of surround colors. The real count is returned when getting the
     * colors. */
    *count = brush->path->pathdata.Count;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
    GpWrapMode *wrapmode)
{
    TRACE("(%p, %p)\n", brush, wrapmode);

    if(!brush || !wrapmode)
        return InvalidParameter;

    *wrapmode = brush->wrap;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb)
{
    TRACE("(%p, %p)\n", sf, argb);

    if(!sf || !argb)
        return InvalidParameter;

    *argb = sf->color;

    return Ok;
}

/******************************************************************************
 * GdipGetTextureImage [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipGetTextureImage(GpTexture *brush, GpImage **image)
{
    TRACE("(%p, %p)\n", brush, image);

    if(!brush || !image)
        return InvalidParameter;

    return GdipCloneImage(brush->image, image);
}

/******************************************************************************
 * GdipGetTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix)
{
    TRACE("(%p, %p)\n", brush, matrix);

    if(!brush || !matrix)
        return InvalidParameter;

    memcpy(matrix, brush->transform, sizeof(GpMatrix));

    return Ok;
}

/******************************************************************************
 * GdipGetTextureWrapMode [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode)
{
    TRACE("(%p, %p)\n", brush, wrapmode);

    if(!brush || !wrapmode)
        return InvalidParameter;

    *wrapmode = brush->imageattributes->wrap;

    return Ok;
}

/******************************************************************************
 * GdipMultiplyTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipMultiplyTextureTransform(GpTexture* brush,
    GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
{
    TRACE("(%p, %p, %d)\n", brush, matrix, order);

    if(!brush || !matrix)
        return InvalidParameter;

    return GdipMultiplyMatrix(brush->transform, matrix, order);
}

/******************************************************************************
 * GdipResetTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipResetTextureTransform(GpTexture* brush)
{
    TRACE("(%p)\n", brush);

    if(!brush)
        return InvalidParameter;

    return GdipSetMatrixElements(brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
}

/******************************************************************************
 * GdipScaleTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture* brush,
    REAL sx, REAL sy, GpMatrixOrder order)
{
    TRACE("(%p, %.2f, %.2f, %d)\n", brush, sx, sy, order);

    if(!brush)
        return InvalidParameter;

    return GdipScaleMatrix(brush->transform, sx, sy, order);
}

GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush,
    GDIPCONST REAL *factors, GDIPCONST REAL* positions, INT count)
{
    REAL *new_blendfac, *new_blendpos;

    TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count);

    if(!brush || !factors || !positions || count <= 0 ||
       (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f)))
        return InvalidParameter;

    new_blendfac = GdipAlloc(count * sizeof(REAL));
    new_blendpos = GdipAlloc(count * sizeof(REAL));

    if (!new_blendfac || !new_blendpos)
    {
        GdipFree(new_blendfac);
        GdipFree(new_blendpos);
        return OutOfMemory;
    }

    memcpy(new_blendfac, factors, count * sizeof(REAL));
    memcpy(new_blendpos, positions, count * sizeof(REAL));

    GdipFree(brush->blendfac);
    GdipFree(brush->blendpos);

    brush->blendcount = count;
    brush->blendfac = new_blendfac;
    brush->blendpos = new_blendpos;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors,
    REAL *positions, INT count)
{
    TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count);

    if (!brush || !factors || !positions || count <= 0)
        return InvalidParameter;

    if (count < brush->blendcount)
        return InsufficientBuffer;

    memcpy(factors, brush->blendfac, brush->blendcount * sizeof(REAL));
    memcpy(positions, brush->blendpos, brush->blendcount * sizeof(REAL));

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count)
{
    TRACE("(%p, %p)\n", brush, count);

    if (!brush || !count)
        return InvalidParameter;

    *count = brush->blendcount;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line,
    BOOL usegamma)
{
    TRACE("(%p, %d)\n", line, usegamma);

    if(!line)
        return InvalidParameter;

    line->gamma = usegamma;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus,
    REAL scale)
{
    REAL factors[33];
    REAL positions[33];
    int num_points = 0;
    int i;
    const int precision = 16;
    REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */
    REAL min_erf;
    REAL scale_erf;

    TRACE("(%p, %0.2f, %0.2f)\n", line, focus, scale);

    if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
        return InvalidParameter;

    /* we want 2 standard deviations */
    erf_range = 2.0 / sqrt(2);

    /* calculate the constants we need to normalize the error function to be
        between 0.0 and scale over the range we need */
    min_erf = erf(-erf_range);
    scale_erf = scale / (-2.0 * min_erf);

    if (focus != 0.0)
    {
        positions[0] = 0.0;
        factors[0] = 0.0;
        for (i=1; i<precision; i++)
        {
            positions[i] = focus * i / precision;
            factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf);
        }
        num_points += precision;
    }

    positions[num_points] = focus;
    factors[num_points] = scale;
    num_points += 1;

    if (focus != 1.0)
    {
        for (i=1; i<precision; i++)
        {
            positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision));
            factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf);
        }
        num_points += precision;
        positions[num_points-1] = 1.0;
        factors[num_points-1] = 0.0;
    }

    return GdipSetLineBlend(line, factors, positions, num_points);
}

GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line,
    GpWrapMode wrap)
{
    TRACE("(%p, %d)\n", line, wrap);

    if(!line || wrap == WrapModeClamp)
        return InvalidParameter;

    line->wrap = wrap;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST REAL *blend,
    GDIPCONST REAL *pos, INT count)
{
    REAL *new_blendfac, *new_blendpos;

    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);

    if(!brush || !blend || !pos || count <= 0 ||
       (count >= 2 && (pos[0] != 0.0f || pos[count-1] != 1.0f)))
        return InvalidParameter;

    new_blendfac = GdipAlloc(count * sizeof(REAL));
    new_blendpos = GdipAlloc(count * sizeof(REAL));

    if (!new_blendfac || !new_blendpos)
    {
        GdipFree(new_blendfac);
        GdipFree(new_blendpos);
        return OutOfMemory;
    }

    memcpy(new_blendfac, blend, count * sizeof(REAL));
    memcpy(new_blendpos, pos, count * sizeof(REAL));

    GdipFree(brush->blendfac);
    GdipFree(brush->blendpos);

    brush->blendcount = count;
    brush->blendfac = new_blendfac;
    brush->blendpos = new_blendpos;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush,
    REAL focus, REAL scale)
{
    REAL factors[3];
    REAL positions[3];
    int num_points = 0;

    TRACE("(%p,%0.2f,%0.2f)\n", brush, focus, scale);

    if (!brush) return InvalidParameter;

    if (focus != 0.0)
    {
        factors[num_points] = 0.0;
        positions[num_points] = 0.0;
        num_points++;
    }

    factors[num_points] = scale;
    positions[num_points] = focus;
    num_points++;

    if (focus != 1.0)
    {
        factors[num_points] = 0.0;
        positions[num_points] = 1.0;
        num_points++;
    }

    return GdipSetPathGradientBlend(brush, factors, positions, num_points);
}

GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush,
    GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
{
    ARGB *new_color;
    REAL *new_pos;
    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);

    if (!brush || !blend || !pos || count < 2 ||
        pos[0] != 0.0f || pos[count-1] != 1.0f)
    {
        return InvalidParameter;
    }

    new_color = GdipAlloc(count * sizeof(ARGB));
    new_pos = GdipAlloc(count * sizeof(REAL));
    if (!new_color || !new_pos)
    {
        GdipFree(new_color);
        GdipFree(new_pos);
        return OutOfMemory;
    }

    memcpy(new_color, blend, sizeof(ARGB) * count);
    memcpy(new_pos, pos, sizeof(REAL) * count);

    GdipFree(brush->pblendcolor);
    GdipFree(brush->pblendpos);

    brush->pblendcolor = new_color;
    brush->pblendpos = new_pos;
    brush->pblendcount = count;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush,
    ARGB *blend, REAL *pos, INT count)
{
    TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);

    if (count < 0)
        return OutOfMemory;

    if (!brush || !blend || !pos || count < 2)
        return InvalidParameter;

    if (brush->pblendcount == 0)
        return GenericError;

    if (count != brush->pblendcount)
    {
        /* Native lines up the ends of each array, and copies the destination size. */
        FIXME("Braindead behavior on wrong-sized buffer not implemented.\n");
        return InvalidParameter;
    }

    memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
    memcpy(pos, brush->pblendpos, sizeof(REAL) * brush->pblendcount);

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush,
    INT *count)
{
    TRACE("(%p,%p)\n", brush, count);

    if (!brush || !count)
        return InvalidParameter;

    *count = brush->pblendcount;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
    ARGB argb)
{
    TRACE("(%p, %x)\n", grad, argb);

    if(!grad)
        return InvalidParameter;

    grad->centercolor = argb;
    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad,
    GpPointF *point)
{
    TRACE("(%p, %s)\n", grad, debugstr_pointf(point));

    if(!grad || !point)
        return InvalidParameter;

    grad->center.X = point->X;
    grad->center.Y = point->Y;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad,
    GpPoint *point)
{
    GpPointF ptf;

    TRACE("(%p, %p)\n", grad, point);

    if(!point)
        return InvalidParameter;

    ptf.X = (REAL)point->X;
    ptf.Y = (REAL)point->Y;

    return GdipSetPathGradientCenterPoint(grad,&ptf);
}

GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad,
    REAL x, REAL y)
{
    TRACE("(%p, %.2f, %.2f)\n", grad, x, y);

    if(!grad)
        return InvalidParameter;

    grad->focus.X = x;
    grad->focus.Y = y;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
    BOOL gamma)
{
    TRACE("(%p, %d)\n", grad, gamma);

    if(!grad)
        return InvalidParameter;

    grad->gamma = gamma;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
    REAL focus, REAL scale)
{
    REAL factors[33];
    REAL positions[33];
    int num_points = 0;
    int i;
    const int precision = 16;
    REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */
    REAL min_erf;
    REAL scale_erf;

    TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale);

    if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
        return InvalidParameter;

    /* we want 2 standard deviations */
    erf_range = 2.0 / sqrt(2);

    /* calculate the constants we need to normalize the error function to be
        between 0.0 and scale over the range we need */
    min_erf = erf(-erf_range);
    scale_erf = scale / (-2.0 * min_erf);

    if (focus != 0.0)
    {
        positions[0] = 0.0;
        factors[0] = 0.0;
        for (i=1; i<precision; i++)
        {
            positions[i] = focus * i / precision;
            factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf);
        }
        num_points += precision;
    }

    positions[num_points] = focus;
    factors[num_points] = scale;
    num_points += 1;

    if (focus != 1.0)
    {
        for (i=1; i<precision; i++)
        {
            positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision));
            factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf);
        }
        num_points += precision;
        positions[num_points-1] = 1.0;
        factors[num_points-1] = 0.0;
    }

    return GdipSetPathGradientBlend(grad, factors, positions, num_points);
}

GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
    *grad, GDIPCONST ARGB *argb, INT *count)
{
    ARGB *new_surroundcolors;
    INT i, num_colors;

    TRACE("(%p,%p,%p)\n", grad, argb, count);

    if(!grad || !argb || !count || (*count <= 0) ||
        (*count > grad->path->pathdata.Count))
        return InvalidParameter;

    num_colors = *count;

    /* If all colors are the same, only store 1 color. */
    if (*count > 1)
    {
        for (i=1; i < num_colors; i++)
            if (argb[i] != argb[i-1])
                break;

        if (i == num_colors)
            num_colors = 1;
    }

    new_surroundcolors = GdipAlloc(num_colors * sizeof(ARGB));
    if (!new_surroundcolors)
        return OutOfMemory;

    memcpy(new_surroundcolors, argb, num_colors * sizeof(ARGB));

    GdipFree(grad->surroundcolors);

    grad->surroundcolors = new_surroundcolors;
    grad->surroundcolorcount = num_colors;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
    GpWrapMode wrap)
{
    TRACE("(%p, %d)\n", grad, wrap);

    if(!grad)
        return InvalidParameter;

    grad->wrap = wrap;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad,
    GpMatrix *matrix)
{
    TRACE("(%p,%p)\n", grad, matrix);

    if (!grad || !matrix)
        return InvalidParameter;

    memcpy(grad->transform, matrix, sizeof(GpMatrix));

    return Ok;
}

GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad,
    GpMatrix *matrix)
{
    TRACE("(%p,%p)\n", grad, matrix);

    if (!grad || !matrix)
        return InvalidParameter;

    memcpy(matrix, grad->transform, sizeof(GpMatrix));

    return Ok;
}

GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad,
    GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
{
    TRACE("(%p,%p,%i)\n", grad, matrix, order);

    if (!grad)
        return InvalidParameter;

    return GdipMultiplyMatrix(grad->transform, matrix, order);
}

GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad)
{
    TRACE("(%p)\n", grad);

    if (!grad)
        return InvalidParameter;

    return GdipSetMatrixElements(grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
}

GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad,
    REAL angle, GpMatrixOrder order)
{
    TRACE("(%p,%0.2f,%i)\n", grad, angle, order);

    if (!grad)
        return InvalidParameter;

    return GdipRotateMatrix(grad->transform, angle, order);
}

GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad,
    REAL sx, REAL sy, GpMatrixOrder order)
{
    TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, sx, sy, order);

    if (!grad)
        return InvalidParameter;

    return GdipScaleMatrix(grad->transform, sx, sy, order);
}

GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad,
    REAL dx, REAL dy, GpMatrixOrder order)
{
    TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, dx, dy, order);

    if (!grad)
        return InvalidParameter;

    return GdipTranslateMatrix(grad->transform, dx, dy, order);
}

GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
{
    TRACE("(%p, %x)\n", sf, argb);

    if(!sf)
        return InvalidParameter;

    sf->color = argb;
    return Ok;
}

/******************************************************************************
 * GdipSetTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture,
    GDIPCONST GpMatrix *matrix)
{
    TRACE("(%p, %p)\n", texture, matrix);

    if(!texture || !matrix)
        return InvalidParameter;

    memcpy(texture->transform, matrix, sizeof(GpMatrix));

    return Ok;
}

/******************************************************************************
 * GdipSetTextureWrapMode [GDIPLUS.@]
 *
 * WrapMode not used, only stored
 */
GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode)
{
    TRACE("(%p, %d)\n", brush, wrapmode);

    if(!brush)
        return InvalidParameter;

    brush->imageattributes->wrap = wrapmode;

    return Ok;
}

GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
    ARGB color2)
{
    TRACE("(%p, %x, %x)\n", brush, color1, color2);

    if(!brush)
        return InvalidParameter;

    brush->startcolor = color1;
    brush->endcolor   = color2;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors)
{
    TRACE("(%p, %p)\n", brush, colors);

    if(!brush || !colors)
        return InvalidParameter;

    colors[0] = brush->startcolor;
    colors[1] = brush->endcolor;

    return Ok;
}

/******************************************************************************
 * GdipRotateTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture* brush, REAL angle,
    GpMatrixOrder order)
{
    TRACE("(%p, %.2f, %d)\n", brush, angle, order);

    if(!brush)
        return InvalidParameter;

    return GdipRotateMatrix(brush->transform, angle, order);
}

GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
    REAL scale)
{
    REAL factors[3];
    REAL positions[3];
    int num_points = 0;

    TRACE("(%p,%.2f,%.2f)\n", brush, focus, scale);

    if (!brush) return InvalidParameter;

    if (focus != 0.0)
    {
        factors[num_points] = 0.0;
        positions[num_points] = 0.0;
        num_points++;
    }

    factors[num_points] = scale;
    positions[num_points] = focus;
    num_points++;

    if (focus != 1.0)
    {
        factors[num_points] = 0.0;
        positions[num_points] = 1.0;
        num_points++;
    }

    return GdipSetLineBlend(brush, factors, positions, num_points);
}

GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
    GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
{
    ARGB *new_color;
    REAL *new_pos;
    TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count);

    if (!brush || !blend || !positions || count < 2 ||
        positions[0] != 0.0f || positions[count-1] != 1.0f)
    {
        return InvalidParameter;
    }

    new_color = GdipAlloc(count * sizeof(ARGB));
    new_pos = GdipAlloc(count * sizeof(REAL));
    if (!new_color || !new_pos)
    {
        GdipFree(new_color);
        GdipFree(new_pos);
        return OutOfMemory;
    }

    memcpy(new_color, blend, sizeof(ARGB) * count);
    memcpy(new_pos, positions, sizeof(REAL) * count);

    GdipFree(brush->pblendcolor);
    GdipFree(brush->pblendpos);

    brush->pblendcolor = new_color;
    brush->pblendpos = new_pos;
    brush->pblendcount = count;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush,
    ARGB *blend, REAL* positions, INT count)
{
    if (!brush || !blend || !positions || count < 2)
        return InvalidParameter;

    if (brush->pblendcount == 0)
        return GenericError;

    if (count < brush->pblendcount)
        return InsufficientBuffer;

    memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
    memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount);

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush,
    INT *count)
{
    if (!brush || !count)
        return InvalidParameter;

    *count = brush->pblendcount;

    return Ok;
}

GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
{
    static int calls;

    TRACE("(%p)\n", brush);

    if(!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
    GDIPCONST GpMatrix *matrix)
{
    static int calls;

    TRACE("(%p,%p)\n", brush,  matrix);

    if(!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix)
{
    static int calls;

    TRACE("(%p,%p)\n", brush, matrix);

    if(!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy,
    GpMatrixOrder order)
{
    static int calls;

    TRACE("(%p,%0.2f,%0.2f,%u)\n", brush, sx, sy, order);

    if(!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipMultiplyLineTransform(GpLineGradient *brush,
    GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
{
    static int calls;

    TRACE("(%p,%p,%u)\n", brush, matrix, order);

    if(!(calls++))
        FIXME("not implemented\n");

    return NotImplemented;
}

GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
        REAL dx, REAL dy, GpMatrixOrder order)
{
    static int calls;

    TRACE("(%p,%f,%f,%d)\n", brush, dx, dy, order);

    if(!(calls++))
        FIXME("not implemented\n");

    return Ok;
}

/******************************************************************************
 * GdipTranslateTextureTransform [GDIPLUS.@]
 */
GpStatus WINGDIPAPI GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REAL dy,
    GpMatrixOrder order)
{
    TRACE("(%p, %.2f, %.2f, %d)\n", brush, dx, dy, order);

    if(!brush)
        return InvalidParameter;

    return GdipTranslateMatrix(brush->transform, dx, dy, order);
}

GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
{
    TRACE("(%p, %p)\n", brush, rect);

    if(!brush || !rect)
        return InvalidParameter;

    *rect = brush->rect;

    return Ok;
}

GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
{
    GpRectF  rectF;
    GpStatus ret;

    TRACE("(%p, %p)\n", brush, rect);

    if(!rect)
        return InvalidParameter;

    ret = GdipGetLineRect(brush, &rectF);

    if(ret == Ok){
        rect->X      = gdip_round(rectF.X);
        rect->Y      = gdip_round(rectF.Y);
        rect->Width  = gdip_round(rectF.Width);
        rect->Height = gdip_round(rectF.Height);
    }

    return ret;
}

GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient* brush,
    REAL angle, GpMatrixOrder order)
{
    static int calls;

    TRACE("(%p,%0.2f,%u)\n", brush, angle, order);

    if(!brush)
        return InvalidParameter;

    if(!(calls++))
        FIXME("(%p, %.2f, %d) stub\n", brush, angle, order);

    return NotImplemented;
}
