From b05cf906d1efa98f09e10a0a3f13aff06a8fe468 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 28 Apr 2009 18:03:41 -0500 Subject: [PATCH] gdiplus: Add blend information to linear gradient brushes. --- dlls/gdiplus/brush.c | 54 ++++++++++++++++++++++++++++++---- dlls/gdiplus/gdiplus_private.h | 3 ++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index e22d5aa9d28..9df52adf3c2 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -108,14 +108,38 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) break; } - case BrushTypeLinearGradient: - *clone = GdipAlloc(sizeof(GpLineGradient)); - if(!*clone) return OutOfMemory; + case BrushTypeLinearGradient:{ + GpLineGradient *dest, *src; + INT count; - memcpy(*clone, brush, sizeof(GpLineGradient)); + dest = GdipAlloc(sizeof(GpLineGradient)); + if(!dest) return OutOfMemory; - (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor); + src = (GpLineGradient*)brush; + + memcpy(dest, src, sizeof(GpLineGradient)); + + dest->brush.gdibrush = CreateSolidBrush(dest->brush.lb.lbColor); + + count = dest->blendcount; + dest->blendfac = GdipAlloc(count * sizeof(REAL)); + dest->blendpos = GdipAlloc(count * sizeof(REAL)); + + if (!dest->blendfac || !dest->blendpos) + { + GdipFree(dest->blendfac); + GdipFree(dest->blendpos); + DeleteObject(dest->brush.gdibrush); + GdipFree(dest); + return OutOfMemory; + } + + memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); + memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); + + *clone = &dest->brush; break; + } case BrushTypeTextureFill: *clone = GdipAlloc(sizeof(GpTexture)); if(!*clone) return OutOfMemory; @@ -226,6 +250,23 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint, (*line)->wrap = wrap; (*line)->gamma = FALSE; + (*line)->blendcount = 1; + (*line)->blendfac = GdipAlloc(sizeof(REAL)); + (*line)->blendpos = GdipAlloc(sizeof(REAL)); + + if (!(*line)->blendfac || !(*line)->blendpos) + { + GdipFree((*line)->blendfac); + GdipFree((*line)->blendpos); + DeleteObject((*line)->brush.gdibrush); + GdipFree(*line); + *line = NULL; + return OutOfMemory; + } + + (*line)->blendfac[0] = 1.0f; + (*line)->blendpos[0] = 1.0f; + return Ok; } @@ -765,7 +806,10 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) GdipFree(((GpPathGradient*) brush)->blendpos); break; case BrushTypeSolidColor: + break; case BrushTypeLinearGradient: + GdipFree(((GpLineGradient*)brush)->blendfac); + GdipFree(((GpLineGradient*)brush)->blendpos); break; case BrushTypeTextureFill: GdipDeleteMatrix(((GpTexture*)brush)->transform); diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index a8c49d3c2dc..e038bafa241 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -145,6 +145,9 @@ struct GpLineGradient{ ARGB endcolor; GpWrapMode wrap; BOOL gamma; + REAL* blendfac; /* blend factors */ + REAL* blendpos; /* blend positions */ + INT blendcount; }; struct GpTexture{