From b60145f1374e9d74ca12adac299ef25b9173fa26 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 14 Sep 2009 16:21:50 -0500 Subject: [PATCH] gdiplus: Store preset blends in linear gradient brushes. --- dlls/gdiplus/brush.c | 80 +++++++++++++++++++++++++++++++++------- dlls/gdiplus/gdiplus_private.h | 3 + 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index 8b18684..1425ab7 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -116,7 +116,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) } case BrushTypeLinearGradient:{ GpLineGradient *dest, *src; - INT count; + INT count, pcount; dest = GdipAlloc(sizeof(GpLineGradient)); if(!dest) return OutOfMemory; @@ -130,11 +130,20 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) 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) + if (!dest->blendfac || !dest->blendpos || + (pcount && (!dest->pblendcolor || !dest->pblendpos))) { GdipFree(dest->blendfac); GdipFree(dest->blendpos); + GdipFree(dest->pblendcolor); + GdipFree(dest->pblendpos); DeleteObject(dest->brush.gdibrush); GdipFree(dest); return OutOfMemory; @@ -143,6 +152,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) 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; } @@ -289,6 +304,10 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint, (*line)->blendfac[0] = 1.0f; (*line)->blendpos[0] = 1.0f; + (*line)->pblendcolor = NULL; + (*line)->pblendpos = NULL; + (*line)->pblendcount = 0; + return Ok; } @@ -866,6 +885,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) 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); @@ -1574,34 +1595,65 @@ GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count) { - static int calls; + ARGB *new_color; + REAL *new_pos; + TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count); - if(!(calls++)) - FIXME("not implemented\n"); + if (!brush || !blend || !positions || count < 2 || + positions[0] != 0.0f || positions[count-1] != 1.0f) + { + return InvalidParameter; + } - return NotImplemented; + 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) { - static int calls; + if (!brush || !blend || !positions || count < 2) + return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + if (brush->pblendcount == 0) + return GenericError; - return NotImplemented; + 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) { - static int calls; + if (!brush || !count) + return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + *count = brush->pblendcount; - return NotImplemented; + return Ok; } GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index e87176e..5320f47 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -166,6 +166,9 @@ struct GpLineGradient{ REAL* blendfac; /* blend factors */ REAL* blendpos; /* blend positions */ INT blendcount; + ARGB* pblendcolor; /* preset blend colors */ + REAL* pblendpos; /* preset blend positions */ + INT pblendcount; }; struct GpTexture{ -- 1.5.4.3