fix drawEllipseF

This commit is contained in:
Vadim Lopatin 2016-11-07 16:41:57 +03:00
parent 0613e5740f
commit b5658d7811
2 changed files with 62 additions and 14 deletions

View File

@ -1096,7 +1096,7 @@ void main()
//buf.fillRect(newClipRect, 0xC08080FF); //buf.fillRect(newClipRect, 0xC08080FF);
//Rect oldClip = buf.clipRect; //Rect oldClip = buf.clipRect;
//buf.clipRect = newClipRect; //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)]; 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+130, y+330)];
buf.polyLineF(poly, 18.0f, 0x80804020, true, 0x80FFFF00); 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+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+230, y+250), vec2(x+200, y+350), vec2(x+80, y+200), 0xC000FF00);
@ -1109,6 +1109,9 @@ void main()
buf.fillPolyF(poly2, 0x80203050); buf.fillPolyF(poly2, 0x80203050);
//buf.polyLineF(poly2, 2.0f, 0x80000000, true); //buf.polyLineF(poly2, 2.0f, 0x80000000, true);
canvas.font.drawText(buf, x + 500, y + 460, "fillPolyF()"d, 0x203050); canvas.font.drawText(buf, x + 500, y + 460, "fillPolyF()"d, 0x203050);
buf.drawEllipseF(x+300, y+600, 200, 150, 3, 0x80008000, 0x804040FF);
canvas.font.drawText(buf, x + 300, y + 600, "fillEllipseF()"d, 0x208050);
}; };
tabs.addTab(canvas, "TAB_CANVAS"c); tabs.addTab(canvas, "TAB_CANVAS"c);

View File

@ -628,30 +628,52 @@ class DrawBuf : RefCountedObject {
fillQuadF(quad[0], quad[1], quad[2], quad[3], colour); 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 /// draw poly line of arbitrary width in float coordinates; when cycled is true, connect first and last point (optionally fill inner area)
void polyLineF(PointF[] points, float width, uint colour, bool cycled = false, uint innerAreaColour = COLOR_TRANSPARENT) { void polyLineF(PointF[] points, float width, uint colour, bool cycled = false, uint innerAreaColour = COLOR_TRANSPARENT) {
if (points.length < 2) if (points.length < 2)
return; return;
bool hasInnerArea = !isFullyTransparentColor(innerAreaColour); bool hasInnerArea = !isFullyTransparentColor(innerAreaColour);
int len = cast(int)points.length;
if (hasInnerArea) { if (hasInnerArea) {
PointF[] innerArea; PointF[] innerArea;
innerArea.assumeSafeAppend; innerArea.assumeSafeAppend;
for(int i = 0; i + 1 < points.length; i++) { for(int i = 0; i < len; i++) {
PointF[4] quad; PointF[4] quad;
PointF prevPoint = (i > 0) ? points[i - 1] : (cycled ? points[$-1] : points[i]); int index0 = i - 1;
PointF nextPoint = (i + 2 < points.length) ? points[i + 2] : (cycled ? points[0] : points[$ - 1]); int index1 = i;
calcLineSegmentQuad(prevPoint, points[i], points[i + 1], nextPoint, width, quad); int index2 = (i + 1) % len;
innerArea ~= quad[0]; int index3 = (i + 2) % len;
if (index0 < 0)
index0 = len - 1;
calcLineSegmentQuad(points[index0], points[index1], points[index2], points[index3], width, quad);
innerArea ~= quad[3];
} }
fillPolyF(innerArea, innerAreaColour); fillPolyF(innerArea, innerAreaColour);
} }
for(int i = 0; i + 1 < points.length; i++) { if (!isFullyTransparentColor(colour)) {
PointF prevPoint = (i > 0) ? points[i - 1] : (cycled ? points[$-1] : points[i]); for(int i = 0; i + (cycled ? 0 : 1) < len; i++) {
PointF nextPoint = (i + 2 < points.length) ? points[i + 2] : (cycled ? points[0] : points[$ - 1]); int index0 = i - 1;
drawLineSegmentF(prevPoint, points[i], points[i + 1], nextPoint, width, colour); int index1 = i;
} int index2 = i + 1;
if (cycled && points.length > 2) { int index3 = i + 2;
drawLineSegmentF(points[$ - 2], points[$ - 1], points[0], points[1], width, colour); if (index0 < 0)
index0 = cycled ? len - 1 : 0;
if (index1 >= len)
index1 %= len; // only can be if cycled
if (index2 >= len) {
if (cycled)
index2 %= len;
else
index2 = len - 1;
}
if (index3 >= len) {
if (cycled)
index3 %= len;
else
index3 = len - 1;
}
drawLineSegmentF(points[index0], points[index1], points[index2], points[index3], width, colour);
}
} }
} }
@ -694,6 +716,29 @@ class DrawBuf : RefCountedObject {
} }
} }
/// draw ellipse or filled ellipse
void drawEllipseF(float centerX, float centerY, float xRadius, float yRadius, float lineWidth, uint lineColor, uint fillColor = COLOR_TRANSPARENT) {
import std.math : sin, cos, PI;
if (xRadius < 0)
xRadius = -xRadius;
if (yRadius < 0)
yRadius = -yRadius;
int numLines = cast(int)((xRadius + yRadius) / 5);
if (numLines < 4)
numLines = 4;
float step = PI * 2 / numLines;
float angle = 0;
PointF[] points;
points.assumeSafeAppend;
for (int i = 0; i < numLines; i++) {
float x = centerX + cos(angle) * xRadius;
float y = centerY + sin(angle) * yRadius;
angle += step;
points ~= PointF(x, y);
}
polyLineF(points, lineWidth, lineColor, true, fillColor);
}
/// draw poly line of width == 1px; when cycled is true, connect first and last point /// draw poly line of width == 1px; when cycled is true, connect first and last point
void polyLine(Point[] points, uint colour, bool cycled) { void polyLine(Point[] points, uint colour, bool cycled) {
if (points.length < 2) if (points.length < 2)