From acba16a38f83d3463911dd4f49a8e42ef5e01f6e Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Fri, 15 Apr 2016 21:26:13 +0000 Subject: Pico can draw lines rectf and arcs, so the top level driver does not have to git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11621 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/drivers/Pico/Fl_Pico_Graphics_Driver.H | 8 +- src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx | 250 +++++++++++++++++++++-- src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H | 4 +- 3 files changed, 234 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/drivers/Pico/Fl_Pico_Graphics_Driver.H b/src/drivers/Pico/Fl_Pico_Graphics_Driver.H index 7b678a8bf..11432e2ed 100644 --- a/src/drivers/Pico/Fl_Pico_Graphics_Driver.H +++ b/src/drivers/Pico/Fl_Pico_Graphics_Driver.H @@ -120,10 +120,10 @@ class Fl_Pico_Graphics_Driver : public Fl_Graphics_Driver { // virtual void scale(double x, double y); // virtual void scale(double x); // virtual void translate(double x,double y); -// virtual void begin_points(); -// virtual void begin_line(); -// virtual void begin_loop(); -// virtual void begin_polygon(); + virtual void begin_points(); + virtual void begin_line(); + virtual void begin_loop(); + virtual void begin_polygon(); virtual void begin_complex_polygon() ; // virtual double transform_x(double x, double y); // virtual double transform_y(double x, double y); diff --git a/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx b/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx index 1b9be9cf9..1bbf6b4eb 100644 --- a/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx +++ b/src/drivers/Pico/Fl_Pico_Graphics_Driver.cxx @@ -20,6 +20,7 @@ #include "../../config_lib.h" #include "Fl_Pico_Graphics_Driver.h" #include +#include void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { @@ -30,65 +31,133 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { void Fl_Pico_Graphics_Driver::point(int x, int y) { - // implement in derived class + // This is the one methods that *must* be overiden in the final driver + // class. All other methods can be derived from this one method. The + // result should work, but will be slow and inefficient. } + void Fl_Pico_Graphics_Driver::rect(int x, int y, int w, int h) { - line(x, y, x+w-1, y); - line(x+w-1, y, x+w-1, y+h-1); - line(x+w-1, y+h-1, x, y+h-1); - line(x, y+h-1, x, y); + int x1 = x+w-1, y1 = y+h-1; + xyline(x, y, x1); + xyline(x, y1, x1); + yxline(x, y, y1); + yxline(x1, y, y1); } + void Fl_Pico_Graphics_Driver::rectf(int x, int y, int w, int h) { - // implement in derived class + int i = y, n = y+h, xn = x+w-1; + for ( ; i0)-(x<0); } + + void Fl_Pico_Graphics_Driver::line(int x, int y, int x1, int y1) { - // implement in derived class + if (x==x1) { + return yxline(x, y, y1); + } + if (y==y1) { + return xyline(x, y, x1); + } + // Bresenham + int w = x1 - x, dx = abs(w); + int h = y1 - y, dy = abs(h); + int dx1 = sign(w), dy1 = sign(h), dx2, dy2; + int min, max; + if (dx < dy) { + min = dx; max = dy; + dx2 = 0; + dy2 = dy1; + } else { + min = dy; max = dx; + dx2 = dx1; + dy2 = 0; + } + int num = max/2; + for (int i=max+1; i>0; i--) { + point(x, y); + num += min; + if (num>=max) { + num -= max; + x += dx1; + y += dy1; + } else { + x += dx2; + y += dy2; + } + } } + void Fl_Pico_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { line(x, y, x1, y1); line(x1, y1, x2, y2); } + void Fl_Pico_Graphics_Driver::xyline(int x, int y, int x1) { - line(x, y, x1, y); + int i; + if (x10) { - if (what==LINE) { - line(px, py, x, y); + if (pn>0) { + switch (what) { + case POINT_: point(x, y); break; + case LINE: line(px, py, x, y); break; + case LOOP: line(px, py, x, y); break; + case POLYGON: line(px, py, x, y); break; // FIXME: fill! } } - n++; + if (pn==0 ) { pxf = x; pyf = y; } px = x; py = y; + pn++; } + void Fl_Pico_Graphics_Driver::end_points() { + pn = 0; } + void Fl_Pico_Graphics_Driver::end_line() { - // nothing to do + pn = 0; } + void Fl_Pico_Graphics_Driver::end_loop() { + line(px, py, pxf, pyf); + pn = 0; } + void Fl_Pico_Graphics_Driver::end_polygon() { + line(px, py, pxf, pyf); // FIXME: fill! + pn = 0; } + void Fl_Pico_Graphics_Driver::end_complex_polygon() { + line(px, py, pxf, pyf); // FIXME: fill! + pn = 0; } + void Fl_Pico_Graphics_Driver::gap() { + pn = 0; +} + + +static double _fl_hypot(double x, double y) { + return sqrt(x*x + y*y); } + void Fl_Pico_Graphics_Driver::circle(double x, double y, double r) { + begin_loop(); + double X = r; + double Y = 0; + fl_vertex(x+X,y+Y); + + double epsilon; { + double r1 = _fl_hypot(fl_transform_dx(r,0), fl_transform_dy(r,0)); + double r2 = _fl_hypot(fl_transform_dx(0,r), fl_transform_dy(0,r)); + if (r1 > r2) r1 = r2; + if (r1 < 2.) r1 = 2.; + epsilon = 2*acos(1.0 - 0.125/r1); + } + double A = 360.0; + int i = int(ceil(fabs(A)/epsilon)); // Segments in approximation + + if (i) { + epsilon = A/i; // Arc length for equal-size steps + double cos_e = cos(epsilon); // Rotation coefficients + double sin_e = sin(epsilon); + do { + double Xnew = cos_e*X + sin_e*Y; + Y = -sin_e*X + cos_e*Y; + fl_vertex(x + (X=Xnew), y + Y); + } while (--i); + } + end_loop(); } -void Fl_Pico_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) + +void Fl_Pico_Graphics_Driver::arc(int xi, int yi, int w, int h, double a1, double a2) { + if (a2<=a1) return; + + double rx = w/2.0; + double ry = h/2.0; + double x = xi + rx; + double y = yi + ry; + double circ = M_PI*0.5*(rx+ry); + int i, segs = circ * (a2-a1) / 1000; // every line is about three pixels long + if (segs<3) segs = 3; + + int px, py; + a1 = a1/180*M_PI; + a2 = a2/180*M_PI; + double step = (a2-a1)/segs; + + int nx = x + sin(a1)*rx; + int ny = y - cos(a1)*ry; + for (i=segs; i>0; i--) { + a1+=step; + px = nx; py = ny; + nx = x + sin(a1)*rx; + ny = y - cos(a1)*ry; + line(px, py, nx, ny); + } } + void Fl_Pico_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) { + // FIXME: implement this } + void Fl_Pico_Graphics_Driver::line_style(int style, int width, char* dashes) { } + void Fl_Pico_Graphics_Driver::color(uchar r, uchar g, uchar b) { } + Fl_Bitmask Fl_Pico_Graphics_Driver::create_bitmask(int w, int h, const uchar *array) { return 0; } + void Fl_Pico_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) { } @@ -266,14 +469,17 @@ double Fl_Pico_Graphics_Driver::width(const char *str, int n) { return size_*n*0.5; } + int Fl_Pico_Graphics_Driver::descent() { return (int)(size_ - size_*0.8); } + int Fl_Pico_Graphics_Driver::height() { return (int)(size_); } + void Fl_Pico_Graphics_Driver::draw(const char *str, int n, int x, int y) { int i; diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H index d9ab01b0f..8f6dc79a6 100644 --- a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H +++ b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H @@ -66,10 +66,10 @@ public: void rectf(int x, int y, int w, int h); void line(int x, int y, int x1, int y1); // void line(int x, int y, int x1, int y1, int x2, int y2); - // void xyline(int x, int y, int x1); + void xyline(int x, int y, int x1) { line(x, y, x1, y); } // void xyline(int x, int y, int x1, int y2); // void xyline(int x, int y, int x1, int y2, int x3); - // void yxline(int x, int y, int y1); + void yxline(int x, int y, int y1) { line(x, y, x, y1); } // void yxline(int x, int y, int y1, int x2); // void yxline(int x, int y, int y1, int x2, int y3); // void loop(int x0, int y0, int x1, int y1, int x2, int y2); -- cgit v1.2.3