From 0613e5740facbd08bc554af4f8973f5adcb8decf Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Mon, 7 Nov 2016 16:00:16 +0300 Subject: [PATCH] fix fillPolyF --- examples/example1/src/example1.d | 7 +++++-- src/dlangui/graphics/drawbuf.d | 33 ++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/examples/example1/src/example1.d b/examples/example1/src/example1.d index 63bfd86e..944bb7ee 100644 --- a/examples/example1/src/example1.d +++ b/examples/example1/src/example1.d @@ -1097,15 +1097,18 @@ void main() //Rect oldClip = buf.clipRect; //buf.clipRect = newClipRect; PointF[] poly = [vec2(x+130, y+150), vec2(x+240, y+80), vec2(x+170, y+170), vec2(x+380, y+270), vec2(x+220, y+400), vec2(x+180, y+330)]; - buf.polyLineF(poly, 18.0f, 0x80804020, true); + buf.polyLineF(poly, 18.0f, 0x80804020, true, 0x80FFFF00); //buf.fillTriangleF(vec2(x+230, y+50), vec2(x+400, y+250), vec2(x+130, y+200), 0xC0FF0000); //buf.fillTriangleF(vec2(x+230, y+250), vec2(x+200, y+350), vec2(x+80, y+200), 0xC000FF00); //buf.fillTriangleF(vec2(x+430, y+250), vec2(x+280, y+150), vec2(x+200, y+300), 0xC00000FF); //buf.fillTriangleF(vec2(x+80, y+150), vec2(x+280, y+250), vec2(x+80, y+200), 0xC0008080); //buf.clipRect = oldClip; canvas.font.drawText(buf, x + 190, y + 260, "polyLineF()"d, 0x603010); - PointF[] poly2 = [vec2(x+330, y+250), vec2(x+440, y+180), vec2(x+370, y+270), vec2(x+480, y+300), vec2(x+520, y+200), vec2(x+420, y+450), vec2(x+380, y+430)]; + PointF[] poly2 = [vec2(x+430, y+250), vec2(x+540, y+180), vec2(x+470, y+270), vec2(x+580, y+300), + vec2(x+620, y+400), vec2(x+480, y+350), vec2(x+520, y+450), vec2(x+480, y+430)]; buf.fillPolyF(poly2, 0x80203050); + //buf.polyLineF(poly2, 2.0f, 0x80000000, true); + canvas.font.drawText(buf, x + 500, y + 460, "fillPolyF()"d, 0x203050); }; tabs.addTab(canvas, "TAB_CANVAS"c); diff --git a/src/dlangui/graphics/drawbuf.d b/src/dlangui/graphics/drawbuf.d index e94e8e66..f5f85b0c 100644 --- a/src/dlangui/graphics/drawbuf.d +++ b/src/dlangui/graphics/drawbuf.d @@ -582,8 +582,7 @@ class DrawBuf : RefCountedObject { return p1 + dir1 * a; } - /// draw line of arbitrary width in float coordinates p1..p2 with angle based on previous (p0..p1) and next (p2..p3) segments - void drawLineSegmentF(PointF p0, PointF p1, PointF p2, PointF p3, float width, uint colour) { + protected void calcLineSegmentQuad(PointF p0, PointF p1, PointF p2, PointF p3, float width, ref PointF[4] quad) { // direction vector PointF v = (p2 - p1).normalized; // calculate normal vector : rotate CCW 90 degrees @@ -617,13 +616,35 @@ class DrawBuf : RefCountedObject { pp20 = intersect0; pp21 = intersect1; } - fillQuadF(pp10, pp20, pp21, pp11, colour); + quad[0] = pp10; + quad[1] = pp20; + quad[2] = pp21; + quad[3] = pp11; + } + /// draw line of arbitrary width in float coordinates p1..p2 with angle based on previous (p0..p1) and next (p2..p3) segments + void drawLineSegmentF(PointF p0, PointF p1, PointF p2, PointF p3, float width, uint colour) { + PointF[4] quad; + calcLineSegmentQuad(p0, p1, p2, p3, width, quad); + fillQuadF(quad[0], quad[1], quad[2], quad[3], colour); } /// draw poly line of arbitrary width in float coordinates; when cycled is true, connect first and last point - void polyLineF(PointF[] points, float width, uint colour, bool cycled, uint innerAreaColour = COLOR_TRANSPARENT) { + void polyLineF(PointF[] points, float width, uint colour, bool cycled = false, uint innerAreaColour = COLOR_TRANSPARENT) { if (points.length < 2) return; + bool hasInnerArea = !isFullyTransparentColor(innerAreaColour); + if (hasInnerArea) { + PointF[] innerArea; + innerArea.assumeSafeAppend; + for(int i = 0; i + 1 < points.length; i++) { + PointF[4] quad; + PointF prevPoint = (i > 0) ? points[i - 1] : (cycled ? points[$-1] : points[i]); + PointF nextPoint = (i + 2 < points.length) ? points[i + 2] : (cycled ? points[0] : points[$ - 1]); + calcLineSegmentQuad(prevPoint, points[i], points[i + 1], nextPoint, width, quad); + innerArea ~= quad[0]; + } + fillPolyF(innerArea, innerAreaColour); + } for(int i = 0; i + 1 < points.length; i++) { PointF prevPoint = (i > 0) ? points[i - 1] : (cycled ? points[$-1] : points[i]); PointF nextPoint = (i + 2 < points.length) ? points[i + 2] : (cycled ? points[0] : points[$ - 1]); @@ -652,7 +673,7 @@ class DrawBuf : RefCountedObject { PointF p2 = list[(i + 1) % list.length]; PointF p3 = list[(i + 2) % list.length]; float cross = (p2 - p1).crossProduct(p3 - p2); - if (cross >= 0) { + if (cross > 0) { // draw triangle fillTriangleF(p1, p2, p3, colour); int indexToRemove = (i + 1) % (cast(int)list.length); @@ -660,7 +681,7 @@ class DrawBuf : RefCountedObject { for (int j = indexToRemove; j + 1 < list.length; j++) list[j] = list[j + 1]; list.length = list.length - 1; - i += 1; + i += 2; moved = true; } }