summaryrefslogtreecommitdiff
path: root/plugingui/painter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugingui/painter.cc')
-rw-r--r--plugingui/painter.cc179
1 files changed, 178 insertions, 1 deletions
diff --git a/plugingui/painter.cc b/plugingui/painter.cc
index 025363c..b74952f 100644
--- a/plugingui/painter.cc
+++ b/plugingui/painter.cc
@@ -49,6 +49,107 @@ void GUI::Painter::setColour(Colour colour)
this->colour = colour;
}
+void GUI::Painter::plot(int x, int y, double c)
+{
+ // plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
+
+ //c += 0.5;
+ //if(c > 1) c = 1;
+
+ pixbuf->addPixel(x, y,
+ (unsigned char)(colour.red * 255.0),
+ (unsigned char)(colour.green * 255.0),
+ (unsigned char)(colour.blue * 255.0),
+ (unsigned char)(colour.alpha * 255 * c));
+
+}
+
+#include <math.h>
+double GUI::Painter::ipart(double x)
+{
+ return floor(x); //integer part of x'
+}
+
+double GUI::Painter::round(double x)
+{
+ return ipart(x + 0.5);
+}
+
+double GUI::Painter::fpart(double x)
+{
+ return x - ipart(x);//'fractional part of x'
+}
+
+double GUI::Painter::rfpart(double x)
+{
+ return 1 - fpart(x);
+}
+
+
+#define SWAP(x, y) { int tmp = x; x = y; y = tmp; }
+void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
+{
+ bool steep = abs(y1 - y0) > abs(x1 - x0);
+
+ if(steep) {
+ SWAP(x0, y0);
+ SWAP(x1, y1);
+ }
+ if(x0 > x1) {
+ SWAP(x0, x1);
+ SWAP(y0, y1);
+ }
+
+ double dx = x1 - x0;
+ double dy = y1 - y0;
+ double gradient = dy / dx;
+
+ // handle first endpoint
+ double xend = round(x0);
+ double yend = y0 + gradient * (xend - x0);
+ double xgap = rfpart(x0 + 0.5);
+ double xpxl1 = xend; //this will be used in the main loop
+ double ypxl1 = ipart(yend);
+ if(steep) {
+ plot(ypxl1, xpxl1, rfpart(yend) * xgap);
+ plot(ypxl1+1, xpxl1, fpart(yend) * xgap);
+ } else {
+ plot(xpxl1, ypxl1 , rfpart(yend) * xgap);
+ plot(xpxl1, ypxl1+1, fpart(yend) * xgap);
+ }
+ double intery = yend + gradient; // first y-intersection for the main loop
+
+ // handle second endpoint
+
+ xend = round(x1);
+ yend = y1 + gradient * (xend - x1);
+ xgap = fpart(x1 + 0.5);
+ double xpxl2 = xend; //this will be used in the main loop
+ double ypxl2 = ipart(yend);
+ if(steep) {
+ plot(ypxl2 , xpxl2, rfpart(yend) * xgap);
+ plot(ypxl2+1, xpxl2, fpart(yend) * xgap);
+ } else {
+ plot(xpxl2, ypxl2, rfpart(yend) * xgap);
+ plot(xpxl2, ypxl2+1, fpart(yend) * xgap);
+ }
+
+ // main loop
+ for(int x = xpxl1 + 1; x <= xpxl2 - 1; x++) {
+ if(steep) {
+ plot(ipart(intery) , x, rfpart(intery));
+ plot(ipart(intery)+1, x, fpart(intery));
+ } else {
+ plot(x, ipart (intery), rfpart(intery));
+ plot(x, ipart (intery)+1, fpart(intery));
+ }
+ intery += gradient;
+ }
+}
+/////////////////////////////////////////////
+
+/*
+// No antialiasing
void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
{
int dx = abs(x1 - x0);
@@ -78,6 +179,7 @@ void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
}
}
}
+*/
void GUI::Painter::drawRectangle(int x1, int y1, int x2, int y2)
{
@@ -123,6 +225,80 @@ void GUI::Painter::drawPoint(int x, int y)
(unsigned char)(colour.alpha * 255.0));
}
+#if 0
+static double distance(double r, double y)
+{
+ double real_point = sqrt(pow(r, 2) - pow(y, 2));
+ return ceil(real_point) - real_point;
+}
+
+double new_color(double i) {
+ return i * 127;
+}
+
+void GUI::Painter::drawCircle(int cx, int cy, double radius)
+{
+ // wu_circle($image, $r, $color, $offset_x = null, $offset_y = null) {
+ //$red = $color["red"];
+ //$green = $color["green"];
+ //$blue = $color["blue"];
+ int offset_x = cx;
+ int offset_y = cy;
+ int x = radius;
+ // int xx = radius;
+ int y = -1;
+ // int yy = -1;
+ double t = 0;
+ //$color = imagecolorallocate($image, $red, $green, $blue);
+ while(x > y) {
+ y++;
+ double current_distance = distance(radius, y);
+ if(current_distance < t) {
+ x--;
+ }
+
+ double trasparency = new_color(current_distance);
+ double alpha = trasparency;
+ double alpha2 = 127.0 - trasparency;
+
+ double color = 1;
+
+ plot(x + offset_x, y + offset_y, color);
+ plot(x + offset_x - 1, y + offset_y, alpha2 );
+ plot(x + offset_x + 1, y + offset_y, alpha );
+
+ plot(y + offset_x, x + offset_y, color);
+ plot(y + offset_x, x + offset_y - 1, alpha2);
+ plot(y + offset_x, x + offset_y + 1, alpha);
+
+ plot(offset_x - x , y + offset_y, color);
+ plot(offset_x - x + 1, y + offset_y, alpha2);
+ plot(offset_x - x - 1, y + offset_y, alpha);
+
+ plot(offset_x - y, x + offset_y, color);
+ plot(offset_x - y, x + offset_y - 1, alpha2);
+ plot(offset_x - y, x + offset_y + 1, alpha);
+
+ plot(x + offset_x, offset_y - y, color);
+ plot(x + offset_x - 1, offset_y - y, alpha2);
+ plot(x + offset_x + 1, offset_y - y, alpha);
+
+ plot(y + offset_x, offset_y - x, color);
+ plot(y + offset_x, offset_y - x - 1, alpha);
+ plot(y + offset_x, offset_y - x + 1, alpha2);
+
+ plot(offset_x - y, offset_y - x, color);
+ plot(offset_x - y, offset_y - x - 1, alpha);
+ plot(offset_x - y, offset_y - x + 1, alpha2);
+
+ plot(offset_x - x, offset_y - y, color);
+ plot(offset_x - x - 1, offset_y - y, alpha);
+ plot(offset_x - x + 1, offset_y - y, alpha2);
+
+ t = current_distance;
+ }
+}
+#else
static void plot4points(GUI::Painter *p, int cx, int cy, int x, int y)
{
p->drawPoint(cx + x, cy + y);
@@ -131,7 +307,7 @@ static void plot4points(GUI::Painter *p, int cx, int cy, int x, int y)
if(x != 0 && y != 0) p->drawPoint(cx - x, cy - y);
}
-void GUI::Painter::drawCircle(int cx, int cy, int radius)
+void GUI::Painter::drawCircle(int cx, int cy, double radius)
{
int error = -radius;
int x = radius;
@@ -152,6 +328,7 @@ void GUI::Painter::drawCircle(int cx, int cy, int radius)
}
}
}
+#endif
static void plot4lines(GUI::Painter *p, int cx, int cy, int x, int y)
{