From 70349a403da6be8dc7c212bcf1ac2676eaddb1cc Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 7 Oct 2015 18:32:55 -0400 Subject: [PATCH] Implemented radial gradients. --- winarea_d2d/draw.c | 31 ++++++++++++++++++++++++---- winarea_d2d/main.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ winarea_d2d/ui.h | 4 ++-- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/winarea_d2d/draw.c b/winarea_d2d/draw.c index e09e7e74..293ad5ca 100644 --- a/winarea_d2d/draw.c +++ b/winarea_d2d/draw.c @@ -348,11 +348,34 @@ static ID2D1Brush *makeLinearBrush(uiDrawBrush *b, ID2D1RenderTarget *rt, D2D1_B return (ID2D1Brush *) brush; } -/* TODO static ID2D1Brush *makeRadialBrush(uiDrawBrush *b, ID2D1RenderTarget *rt, D2D1_BRUSH_PROPERTIES *props) { + ID2D1RadialGradientBrush *brush; + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES gprops; + ID2D1GradientStopCollection *stops; + HRESULT hr; + + ZeroMemory(&gprops, sizeof (D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES)); + gprops.gradientOriginOffset.x = b->X0 - b->X1; + gprops.gradientOriginOffset.y = b->Y0 - b->Y1; + gprops.center.x = b->X1; + gprops.center.y = b->Y1; + gprops.radiusX = b->OuterRadius; + gprops.radiusY = b->OuterRadius; + + stops = mkstops(b, rt); + + hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, + &gprops, + props, + stops, + &brush); + if (hr != S_OK) + logHRESULT("error creating gradient brush in makeRadialBrush()", hr); + + ID2D1GradientStopCollection_Release(stops); + return (ID2D1Brush *) brush; } -*/ static ID2D1Brush *makeBrush(uiDrawBrush *b, ID2D1RenderTarget *rt) { @@ -369,8 +392,8 @@ static ID2D1Brush *makeBrush(uiDrawBrush *b, ID2D1RenderTarget *rt) return makeSolidBrush(b, rt, &props); case uiDrawBrushTypeLinearGradient: return makeLinearBrush(b, rt, &props); -// case uiDrawBrushTypeRadialGradient: -// return makeRadialBrush(b, rt, &props); + case uiDrawBrushTypeRadialGradient: + return makeRadialBrush(b, rt, &props); // case uiDrawBrushTypeImage: // TODO } diff --git a/winarea_d2d/main.c b/winarea_d2d/main.c index e256a35c..d7764c5a 100644 --- a/winarea_d2d/main.c +++ b/winarea_d2d/main.c @@ -176,6 +176,56 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) } #undef YO #undef XO + uiDrawFreePath(path); + + // based on https://msdn.microsoft.com/en-us/library/windows/desktop/dd756679%28v=vs.85%29.aspx + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 585, 235); + uiDrawPathArcTo(path, + 510, 235, + 75, + 0, + // TODO why doesn't 360° work + 2 * M_PI - 0.1); + uiDrawPathEnd(path); + // first the stroke + brush.Type = uiDrawBrushTypeSolid; + brush.R = 0; + brush.G = 0; + brush.B = 0; + brush.A = 1; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Thickness = 1; + uiDrawStroke(p->Context, path, &brush, &sp); + // then the fill + { + uiDrawBrushGradientStop stops[2]; + + stops[0].Pos = 0.0; + stops[0].R = 1.0; + stops[0].G = 1.0; + stops[0].B = 0.0; + stops[0].A = 1.0; + stops[1].Pos = 1.0; + stops[1].R = ((double) 0x22) / 255.0; + stops[1].G = ((double) 0x8B) / 255.0; + stops[1].B = ((double) 0x22) / 255.0; + stops[1].A = 1.0; + brush.Type = uiDrawBrushTypeRadialGradient; + // start point + brush.X0 = 510; + brush.Y0 = 235; + // outer circle's center + brush.X1 = 510; + brush.Y1 = 235; + brush.OuterRadius = 75; + brush.Stops = stops; + brush.NumStops = 2; + uiDrawFill(p->Context, path, &brush); + } + uiDrawFreePath(path); } static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area) diff --git a/winarea_d2d/ui.h b/winarea_d2d/ui.h index 03698508..9eae3ff6 100644 --- a/winarea_d2d/ui.h +++ b/winarea_d2d/ui.h @@ -52,9 +52,9 @@ typedef enum uiDrawFillMode uiDrawFillMode; enum uiDrawBrushType { uiDrawBrushTypeSolid, uiDrawBrushTypeLinearGradient, -/*TODO uiDrawBrushTypeRadialGradient, + uiDrawBrushTypeRadialGradient, uiDrawBrushTypeImage, -*/}; +}; enum uiDrawLineCap { uiDrawLineCapFlat,