diff options
| author | Matthias Melcher <github@matthiasm.com> | 2022-02-06 15:22:24 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-06 15:22:24 +0100 |
| commit | db0a1f4baeb928b54d328d5dfbd0ec37b0b58bd3 (patch) | |
| tree | ed53495f5dd435d7c23cd4267fb785e5ebca679c /test | |
| parent | af4954aee3483f03ff69e990e80f4e4a18e8b7f6 (diff) | |
OpenGL implementation of all `fl_` "Drawing Fast Shapes" graphics calls (#385)
* Fix build system for unites,
* Updated unittest to check OpenGL drawing.
Making sure that OpenGL drawing is exactly the same
as native drawing to make FLTK widget rendering
look the same in GL windows.
* Make OpenGL optional.
* Implemented clipping in OpenGL
* unites drawing fast shapes
* Fixed CMake
* Updating unittest.
Added tests for fl_pi and fl_arc (int)
Renamed tab to render complex shapes.
* Improved OpenGL FLTK drawing emulation.
* Fixed GTK ROUND DOWN BOX
* Fixing Makefile for unittest
* Correctly aligning OpenGL text.
* Fixed text alignment in GL windows.
Explained the "FLTK over GL " example in Cube.
* Overlapping test.
* Better GL graphics alignment.
* Drawing the focus rect.
* Adding Alpha Channel support for GL.
* Added FLTK-on-GL documentation.
Diffstat (limited to 'test')
| -rw-r--r-- | test/CMakeLists.txt | 21 | ||||
| -rw-r--r-- | test/Makefile | 49 | ||||
| -rw-r--r-- | test/cube.cxx | 18 | ||||
| -rw-r--r-- | test/makedepend | 4 | ||||
| -rw-r--r-- | test/unittest_about.cxx | 4 | ||||
| -rw-r--r-- | test/unittest_circles.cxx | 236 | ||||
| -rw-r--r-- | test/unittest_complex_shapes.cxx (renamed from test/unittest_lines.cxx) | 64 | ||||
| -rw-r--r-- | test/unittest_fast_shapes.cxx | 383 | ||||
| -rw-r--r-- | test/unittest_images.cxx | 6 | ||||
| -rw-r--r-- | test/unittest_points.cxx | 294 | ||||
| -rw-r--r-- | test/unittest_rects.cxx | 51 | ||||
| -rw-r--r-- | test/unittest_schemes.cxx | 4 | ||||
| -rw-r--r-- | test/unittest_scrollbarsize.cxx | 5 | ||||
| -rw-r--r-- | test/unittest_simple_terminal.cxx | 4 | ||||
| -rw-r--r-- | test/unittest_symbol.cxx | 4 | ||||
| -rw-r--r-- | test/unittest_text.cxx | 4 | ||||
| -rw-r--r-- | test/unittest_viewport.cxx | 4 | ||||
| -rw-r--r-- | test/unittests.cxx | 208 | ||||
| -rw-r--r-- | test/unittests.h | 87 |
19 files changed, 1174 insertions, 276 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9197ebaac..f52af5cba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -139,9 +139,28 @@ CREATE_EXAMPLE (tile tile.cxx fltk) CREATE_EXAMPLE (tiled_image tiled_image.cxx fltk) CREATE_EXAMPLE (tree tree.fl fltk) CREATE_EXAMPLE (twowin twowin.cxx fltk) +SET (UNITTEST_SRCS + unittests.cxx + unittest_about.cxx + unittest_points.cxx + unittest_complex_shapes.cxx + unittest_fast_shapes.cxx + unittest_circles.cxx + unittest_text.cxx + unittest_symbol.cxx + unittest_images.cxx + unittest_viewport.cxx + unittest_scrollbarsize.cxx + unittest_schemes.cxx + unittest_simple_terminal.cxx +) +if (OPENGL_FOUND) + CREATE_EXAMPLE (unittests "${UNITTEST_SRCS}" "fltk_gl;fltk;${OPENGL_LIBRARIES}") # opt. Fl_Gl_Window +else() + CREATE_EXAMPLE (unittests "${UNITTEST_SRCS}" fltk) # w/o Fl_Gl_Window +endif() CREATE_EXAMPLE (utf8 utf8.cxx fltk) CREATE_EXAMPLE (valuators valuators.fl fltk) -CREATE_EXAMPLE (unittests unittests.cxx fltk) CREATE_EXAMPLE (windowfocus windowfocus.cxx fltk) CREATE_EXAMPLE (wizard wizard.cxx fltk) diff --git a/test/Makefile b/test/Makefile index c08446af8..49d56e7be 100644 --- a/test/Makefile +++ b/test/Makefile @@ -16,6 +16,36 @@ include ../makeinclude +CPPUNITTEST = \ + unittests.cxx \ + unittest_about.cxx \ + unittest_points.cxx \ + unittest_complex_shapes.cxx \ + unittest_fast_shapes.cxx \ + unittest_circles.cxx \ + unittest_text.cxx \ + unittest_symbol.cxx \ + unittest_images.cxx \ + unittest_viewport.cxx \ + unittest_scrollbarsize.cxx \ + unittest_schemes.cxx \ + unittest_simple_terminal.cxx + +OBJUNITTEST = \ + unittests.o \ + unittest_about.o \ + unittest_points.o \ + unittest_complex_shapes.o \ + unittest_fast_shapes.o \ + unittest_circles.o \ + unittest_text.o \ + unittest_symbol.o \ + unittest_images.o \ + unittest_viewport.o \ + unittest_scrollbarsize.o \ + unittest_schemes.o \ + unittest_simple_terminal.o + CPPFILES =\ adjuster.cxx \ animated.cxx \ @@ -103,13 +133,12 @@ CPPFILES =\ tiled_image.cxx \ tree.cxx \ twowin.cxx \ - unittests.cxx \ utf8.cxx \ valuators.cxx \ - windowfocus.cxx + windowfocus.cxx \ + $(CPPUNITTEST) ALL = \ - unittests$(EXEEXT) \ animated$(EXEEXT) \ adjuster$(EXEEXT) \ arc$(EXEEXT) \ @@ -200,7 +229,8 @@ GLALL = \ fullscreen$(EXEEXT) \ gl_overlay$(EXEEXT) \ glpuzzle$(EXEEXT) \ - shape$(EXEEXT) + shape$(EXEEXT) \ + unittests$(EXEEXT) all: $(ALL) $(GLDEMOS) @@ -299,11 +329,7 @@ uninstall-osx: $(ALL): $(LIBNAME) # General demos... -unittests$(EXEEXT): unittests.o - -unittests.o: unittests.cxx unittest_about.cxx unittest_points.cxx unittest_lines.cxx unittest_circles.cxx \ - unittest_rects.cxx unittest_text.cxx unittest_symbol.cxx unittest_viewport.cxx unittest_images.cxx \ - unittest_schemes.cxx unittest_scrollbarsize.cxx unittest_simple_terminal.cxx +unittests$(EXEEXT): $(OBJUNITTEST) adjuster$(EXEEXT): adjuster.o @@ -626,6 +652,11 @@ gl_overlay$(EXEEXT): gl_overlay.o $(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ gl_overlay.o $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS) $(OSX_ONLY) ../fltk-config --post $@ +unittests$(EXEEXT): $(OBJUNITTEST) + echo Linking $@... + $(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJUNITTEST) $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS) + $(OSX_ONLY) ../fltk-config --post $@ + shape$(EXEEXT): shape.o echo Linking $@... $(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ shape.o $(LINKFLTKGL) $(LINKFLTK) $(GLDLIBS) diff --git a/test/cube.cxx b/test/cube.cxx index 64e9044cd..fa96130ee 100644 --- a/test/cube.cxx +++ b/test/cube.cxx @@ -18,6 +18,7 @@ #include <config.h> #include <FL/Fl.H> +#include <FL/fl_ask.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> #include <FL/Fl_Button.H> @@ -184,6 +185,12 @@ void print_cb(Fl_Widget *w, void *data) #define MARGIN2 (MARGIN*2) #define MARGIN3 (MARGIN*3) +void show_info_cb(Fl_Widget*, void*) { + fl_message("This is an example of using FLTK widgets inside OpenGL windows.\n" + "Multiple widgets can be added to Fl_Gl_Windows. They will be\n" + "rendered as overlays over the scene."); +} + void makeform(const char *name) { // Widget's XYWH's int form_w = 800 + 4 * MARGIN; // main window width @@ -207,6 +214,14 @@ void makeform(const char *name) { lt_grp->begin(); // left GL window lt_cube = new cube_box(lt_cub_x, lt_cub_y, lt_cub_w, lt_cub_h, 0); + + lt_cube->begin(); + Fl_Widget *w = new Fl_Button(10, 10, 120, 30, "FLTK over GL"); + w->color(FL_FREE_COLOR); + w->box(FL_BORDER_BOX ); + w->callback(show_info_cb); + lt_cube->end(); + // center group Fl_Group *ct_grp = new Fl_Group(ct_grp_x, ct_grp_y, ct_grp_w, ct_grp_h); ct_grp->begin(); @@ -238,6 +253,7 @@ void makeform(const char *name) { int main(int argc, char **argv) { Fl::use_high_res_GL(1); + Fl::set_color(FL_FREE_COLOR, 255, 255, 0, 75); makeform(argv[0]); speed->bounds(4,0); #if HAVE_GL @@ -246,7 +262,7 @@ int main(int argc, char **argv) { speed->value(lt_cube->speed = rt_cube->speed = 0.0); #endif size->bounds(4,0.01); - size->value(lt_cube->size = rt_cube->size = 1.0); + size->value(lt_cube->size = rt_cube->size = 3.0); flat->value(1); lt_cube->wire = 0; rt_cube->wire = 1; form->label("cube"); form->show(argc,argv); diff --git a/test/makedepend b/test/makedepend index 6fc9d4451..e0b2658fe 100644 --- a/test/makedepend +++ b/test/makedepend @@ -2535,9 +2535,9 @@ unittests.o: ../FL/platform_types.h unittests.o: unittest_about.cxx unittests.o: unittest_circles.cxx unittests.o: unittest_images.cxx -unittests.o: unittest_lines.cxx +unittests.o: unittest_complex_shapes.cxx unittests.o: unittest_points.cxx -unittests.o: unittest_rects.cxx +unittests.o: unittest_fast_shapes.cxx unittests.o: unittest_schemes.cxx unittests.o: unittest_scrollbarsize.cxx unittests.o: unittest_simple_terminal.cxx diff --git a/test/unittest_about.cxx b/test/unittest_about.cxx index 966c7cb23..3c4084d31 100644 --- a/test/unittest_about.cxx +++ b/test/unittest_about.cxx @@ -14,6 +14,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Help_View.H> // @@ -51,4 +53,4 @@ public: } }; -UnitTest about("About...", About::create); +UnitTest about(kTestAbout, "About...", About::create); diff --git a/test/unittest_circles.cxx b/test/unittest_circles.cxx index 62ef28060..0d3fad25d 100644 --- a/test/unittest_circles.cxx +++ b/test/unittest_circles.cxx @@ -14,71 +14,203 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + +#include <config.h> #include <FL/Fl_Box.H> #include <FL/fl_draw.H> +#include <FL/math.h> +#if HAVE_GL +#include <FL/Fl_Gl_Window.H> +#endif + +// +// --- test drawing circles and arcs ------ +// + +void 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 + 0.5; + double y = yi + ry + 0.5; + double circ = M_PI*0.5*(rx+ry); + int i, segs = circ * (a2-a1) / 100; + 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 + cos(a1)*rx; + int ny = y - sin(a1)*ry; + fl_point(nx, ny); + for (i=segs; i>0; i--) { + a1+=step; + px = nx; py = ny; + nx = x + cos(a1)*rx; + ny = y - sin(a1)*ry; + //fl_line(px, py, nx, ny); + fl_point(nx, ny); + } +} + +void draw_circles() { + int a = 0, b = 0, w=40, h=40; + // ---- 1: draw a circle and a filled circle + fl_color(FL_RED); + arc(a+1, b+1, w-2, h-2, 0.0, 360.0); + fl_color(FL_GREEN); + arc(a, b, w, h, 0.0, 360.0); + arc(a+2, b+2, w-4, h-4, 0.0, 360.0); + fl_color(FL_BLACK); + fl_arc(a+1, b+1, w-1, h-1, 0.0, 360.0); + // ---- + fl_color(FL_RED); + arc(a+1+50, b+1, w-2, h-2, 0.0, 360.0); + fl_color(FL_GREEN); + arc(a+50, b, w, h, 0.0, 360.0); + fl_color(FL_BLACK); + fl_pie(a+1+50, b+1, w-1, h-1, 0.0, 360.0); + b+=44; + // ---- 2: draw arcs and pies + fl_color(FL_RED); +// arc(a-5, b-5, w+10, h+10, 45.0, 315.0); + arc(a+1, b+1, w-2, h-2, 45.0, 315.0); +// arc(a+5, b+5, w-10, h-10, 45.0, 315.0); +// arc(a+10, b+10, w-20, h-20, 45.0, 315.0); + fl_color(FL_GREEN); + arc(a, b, w, h, 45.0, 315.0); + arc(a+2, b+2, w-4, h-4, 45.0, 315.0); + fl_color(FL_BLACK); +// fl_arc(a-5, b-5, w+10, h+10, 45.0, 315.0); + fl_arc(a+1, b+1, w-1, h-1, 45.0, 315.0); +// fl_arc(a+5, b+5, w-10, h-10, 45.0, 315.0); +// fl_arc(a+10, b+10, w-20, h-20, 45.0, 315.0); + fl_color(FL_RED); + // ---- + arc(a+1+50, b+1, w-2, h-2, 45.0, 315.0); + fl_line(a+50+20, b+20, a+50+20+14, b+20-14); + fl_line(a+50+20, b+20, a+50+20+14, b+20+14); + fl_color(FL_GREEN); + arc(a+50, b, w, h, 45.0, 315.0); + fl_line(a+50+21, b+20, a+50+21+14, b+20-14); + fl_line(a+50+21, b+20, a+50+21+14, b+20+14); + fl_color(FL_BLACK); + fl_pie(a+1+50, b+1, w-1, h-1, 45.0, 315.0); +} + +#if HAVE_GL + +class GLCircleTest : public Fl_Gl_Window { +public: + GLCircleTest(int x, int y, int w, int h) + : Fl_Gl_Window(x, y, w, h) { + box(FL_FLAT_BOX); + } + void draw() { + draw_begin(); + Fl_Window::draw(); + draw_circles(); + draw_end(); + } +}; + +#endif + +class NativeCircleTest : public Fl_Window { +public: + NativeCircleTest(int x, int y, int w, int h) + : Fl_Window(x, y, w, h) { + box(FL_FLAT_BOX); + end(); + } + void draw() { + Fl_Window::draw(); + draw_circles(); + } +}; // //------- test the circle drawing capabilities of this implementation ---------- // -class CircleTest : public Fl_Box { +class CircleTest : public Fl_Group { public: static Fl_Widget *create() { return new CircleTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); } - CircleTest(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { - label("testing int drawing of circles and ovals (fl_arc, fl_pie)\n" + CircleTest(int x, int y, int w, int h) : Fl_Group(x, y, w, h) { + label("Testing fast circle, arc, and pie drawing\n\n" "No red lines should be visible. " - "If you see bright red pixels, the circle drawing alignment is off. " - "If you see dark red pixels, your system supports anti-aliasing " - "which should be of no concern. " - "The green rectangles should not be overwritten by circle drawings."); + "The green outlines should not be overwritten by circle drawings."); align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP); box(FL_BORDER_BOX); - } - void draw() { - Fl_Box::draw(); - int a = x()+10, b = y()+10; fl_color(FL_BLACK); fl_rect(a, b, 100, 100); - // test fl_arc for full circles - fl_color(FL_GREEN); fl_rect(a+ 9, b+ 9, 33, 33); - fl_color(FL_RED); fl_xyline(a+24, b+10, a+27); fl_xyline(a+24, b+40, a+27); - fl_yxline(a+10, b+24, b+27); fl_yxline(a+40, b+24, b+27); - fl_color(FL_BLACK); fl_arc(a+10, b+10, 31, 31, 0.0, 360.0); - // test fl_arc segmet 1 - fl_color(FL_GREEN); fl_rect(a+54, b+ 4, 43, 43); - fl_rect(a+54, b+4, 18, 18); fl_rect(a+79, b+29, 18, 18); - fl_color(FL_RED); fl_point(a+55, b+30); fl_point(a+70, b+45); - fl_point(a+80, b+5); fl_point(a+95, b+20); - fl_color(FL_BLACK); fl_arc(a+65, b+ 5, 31, 31, -35.0, 125.0); - // test fl_arc segmet 2 - fl_color(FL_BLACK); fl_arc(a+55, b+15, 31, 31, 145.0, 305.0); - // test fl_pie for full circles - fl_color(FL_RED); fl_xyline(a+24, b+60, a+27); fl_xyline(a+24, b+90, a+27); - fl_yxline(a+10, b+74, b+77); fl_yxline(a+40, b+74, b+77); - fl_color(FL_GREEN); fl_rect(a+ 9, b+59, 33, 33); - fl_color(FL_BLACK); fl_pie(a+10, b+60, 31, 31, 0.0, 360.0); - // test fl_pie segmet 1 - fl_color(FL_GREEN); fl_rect(a+54, b+54, 43, 43); - fl_rect(a+54, b+54, 18, 18); fl_rect(a+79, b+79, 18, 18); - fl_point(a+79, b+71); fl_point(a+71, b+79); - fl_color(FL_RED); fl_point(a+55, b+80); fl_point(a+70, b+95); - fl_point(a+80, b+55); fl_point(a+95, b+70); - fl_point(a+81, b+69); fl_point(a+69, b+81); - fl_color(FL_BLACK); fl_pie(a+65, b+55, 31, 31, -30.0, 120.0); - // test fl_pie segmet 2 - fl_color(FL_BLACK); fl_pie(a+55, b+65, 31, 31, 150.0, 300.0); - //---- oval testing (horizontal squish) - a +=120; b += 0; fl_color(FL_BLACK); fl_rect(a, b, 100, 100); - fl_color(FL_GREEN); - fl_rect(a+19, b+9, 63, 33); fl_rect(a+19, b+59, 63, 33); - fl_color(FL_BLACK); - fl_arc(a+20, b+10, 61, 31, 0, 360); fl_pie(a+20, b+60, 61, 31, 0, 360); - //---- oval testing (horizontal squish) - a += 120; b += 0; fl_color(FL_BLACK); fl_rect(a, b, 100, 100); - fl_color(FL_GREEN); - fl_rect(a+9, b+19, 33, 63); fl_rect(a+59, b+19, 33, 63); - fl_color(FL_BLACK); - fl_arc(a+10, b+20, 31, 61, 0, 360); fl_pie(a+60, b+20, 31, 61, 0, 360); + + int a = x+16, b = y+34; + Fl_Box *t = new Fl_Box(a, b-24, 80, 18, "native"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + /* NativeCircleTest *nr = */ new NativeCircleTest(a+23, b-1, 200, 200); + + t = new Fl_Box(a, b, 18, 18, "1"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing circle alignment.\n\n" + // Description: + "This draws a black circle and a black disc, surrounded by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing, circle drawing must be adjusted (see fl_arc, fl_pie).\n\n" + "If red pixels are showing, line width or aligment may be off." + ); + b+=44; + t = new Fl_Box(a, b, 18, 18, "2"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing arc and pie drawing.\n\n" + // Description: + "This draws a black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, rectangular frame drawing schould be adjusted (see fl_rect).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); + +#if HAVE_GL + + a = x+16+250, b = y+34; + t = new Fl_Box(a, b-24, 80, 18, "OpenGL"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + /* GLCircleTest *glr = */ new GLCircleTest(a+31, b-1, 200, 200); + + t = new Fl_Box(a, b, 26, 18, "1a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing circle alignment.\n\n" + // Description: + "This draws a black circle and a black disc, surrounded by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing, circle drawing must be adjusted (see fl_arc, fl_pie).\n\n" + "If red pixels are showing, line width or aligment may be off." + ); + b+=44; + t = new Fl_Box(a, b, 26, 18, "2a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing arc and pie drawing.\n\n" + // Description: + "This draws a black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, rectangular frame drawing schould be adjusted (see fl_rect).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); +#endif + + t = new Fl_Box(x+w-1,y+h-1, 1, 1); + resizable(t); } }; -UnitTest circle("circles and arcs", CircleTest::create); +UnitTest circle(kTestCircles, "Circles and Arcs", CircleTest::create); diff --git a/test/unittest_lines.cxx b/test/unittest_complex_shapes.cxx index b255159fc..399243e4b 100644 --- a/test/unittest_lines.cxx +++ b/test/unittest_complex_shapes.cxx @@ -14,23 +14,67 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Box.H> #include <FL/fl_draw.H> +#if 0 + +// TODO: +void fl_push_matrix() +void fl_pop_matrix() + +void fl_scale(double x,double y) +void fl_scale(double x) +void fl_translate(double x,double y) +void fl_rotate(double d) +void fl_mult_matrix(double a,double b,double c,double d,double x,double y) + +double fl_transform_x(double x, double y) +double fl_transform_y(double x, double y) +double fl_transform_dx(double x, double y) +double fl_transform_dy(double x, double y) +void fl_transformed_vertex(double xf, double yf) + +void fl_begin_points() +void fl_end_points() + +void fl_begin_line() +void fl_end_line() + +void fl_begin_loop() +void fl_end_loop() + +void fl_begin_polygon() +void fl_end_polygon() + +void fl_begin_complex_polygon() +void fl_gap() +void fl_end_complex_polygon() + +void fl_vertex(double x,double y) + +void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3) + +void fl_arc(double x, double y, double r, double start, double end) +void fl_circle(double x, double y, double r) + + +#endif + // -//------- test the line drawing capabilities of this implementation ---------- +//------- test Complex Shape drawing capabilities of this implementation ---------- // -class LineTest : public Fl_Box { +class ComplexShapesTest : public Fl_Box { public: static Fl_Widget *create() { - return new LineTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); + return new ComplexShapesTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); } - LineTest(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { - label("testing the integer based fl_line calls\n" - "No red pixels should be visible.\n" - "If you see bright red pixels, the line drawing alignment is off,\n" - "or the last pixel in a line does not get drawn.\n" - "If you see dark red pixels, anti-aliasing must be switched off."); + ComplexShapesTest(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { + label("Testing complex shape drawing.\n\n" + "Complex Shapes in FLTK are rendered using floating point coordinates " + "which can be transformed through a matrix."); align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP); box(FL_BORDER_BOX); } @@ -74,4 +118,4 @@ public: } }; -UnitTest lines("drawing lines", LineTest::create); +//UnitTest lines(kTestComplexShapes, "Complex Shapes", ComplexShapesTest::create); diff --git a/test/unittest_fast_shapes.cxx b/test/unittest_fast_shapes.cxx new file mode 100644 index 000000000..c486eb147 --- /dev/null +++ b/test/unittest_fast_shapes.cxx @@ -0,0 +1,383 @@ +// +// Unit tests for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +#include "unittests.h" + +#include <config.h> +#include <FL/Fl_Box.H> +#include <FL/fl_draw.H> // fl_text_extents() +#if HAVE_GL +#include <FL/Fl_Gl_Window.H> +#endif + +#if 0 + +// TODO: +void fl_line(int x, int y, int x1, int y1) +void fl_line(int x, int y, int x1, int y1, int x2, int y2) + +Draw one or two lines between the given points. +void fl_loop(int x, int y, int x1, int y1, int x2, int y2) +void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + +Outline a 3 or 4-sided polygon with lines. +void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) +void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + +Draw vertical and horizontal lines. A vertical line is drawn first, then a horizontal, then a vertical. + +#endif + +// +// --- test drawing shapes that are not transformed by the drawing matrix ------ +// + +void draw_fast_shapes() { + int a = 0, b = 0, i; + // 1: draw a filled rectangle (fl_rectf) + fl_color(FL_GREEN); + for (i=0; i<=40; i++) { fl_point(a+i, b); fl_point(a+i, b+20); } + for (i=0; i<=20; i++) { fl_point(a, b+i); fl_point(a+40, b+i); } + fl_color(FL_RED); + for (i=1; i<=39; i++) { fl_point(a+i, b+1); fl_point(a+i, b+19); } + for (i=1; i<=19; i++) { fl_point(a+1, b+i); fl_point(a+39, b+i); } + fl_color(FL_BLACK); + fl_rectf(a+1, b+1, 39, 19); + // 2: draw a one units wide frame + b+=24; + fl_color(FL_GREEN); + for (i=0; i<=40; i++) { fl_point(a+i, b); fl_point(a+i, b+20); } + for (i=0; i<=20; i++) { fl_point(a, b+i); fl_point(a+40, b+i); } + fl_color(FL_GREEN); + for (i=2; i<=38; i++) { fl_point(a+i, b+2); fl_point(a+i, b+18); } + for (i=2; i<=18; i++) { fl_point(a+2, b+i); fl_point(a+38, b+i); } + fl_color(FL_RED); + for (i=1; i<=39; i++) { fl_point(a+i, b+1); fl_point(a+i, b+19); } + for (i=1; i<=19; i++) { fl_point(a+1, b+i); fl_point(a+39, b+i); } + fl_color(FL_BLACK); + fl_rect(a+1, b+1, 39, 19); + // 3: draw a three units wide frame + b+=24; + fl_color(FL_GREEN); + fl_rect(a, b, 41, 21); + fl_rect(a+4, b+4, 33, 13); + fl_color(FL_RED); + fl_rect(a+1, b+1, 39, 19); + fl_rect(a+3, b+3, 35, 15); + fl_color(FL_BLACK); + fl_line_style(FL_SOLID, 3); + fl_rect(a+2, b+2, 37, 17); + fl_line_style(FL_SOLID, 1); + // 4: draw fl_xyline + b+=24; + fl_color(FL_GREEN); + fl_rect(a, b+8, 41, 3); // single line + fl_rect(a+45, b, 41, 3); // horizontal, then vertical line + fl_rect(a+83, b, 3, 21); + fl_rect(a+90, b, 21, 3); // horizontal, vertical, horizontal line + fl_rect(a+109, b, 3, 21); + fl_rect(a+109, b+18, 21, 3); + fl_color(FL_RED); + fl_rectf(a+1, b+9, 39, 1); // single line + fl_rectf(a+46, b+1, 39, 1); // two lines + fl_rectf(a+84, b+1, 1, 19); + fl_rectf(a+91, b+1, 20, 1); // three lines + fl_rectf(a+110, b+1, 1, 19); + fl_rectf(a+110, b+19, 19, 1); // three lines + fl_color(FL_BLACK); + fl_xyline(a+1, b+9, a+39); + fl_xyline(a+46, b+1, a+84, b+19); + fl_xyline(a+91, b+1, a+110, b+19, a+128); + b+=24; + fl_color(FL_GREEN); + fl_rect(a, b+7, 41, 5); // single line + fl_rect(a+45, b, 41, 5); // horizontal, then vertical line + fl_rect(a+81, b, 5, 21); + fl_rect(a+90, b, 22, 5); // horizontal, vertical, horizontal line + fl_rect(a+108, b, 5, 21); + fl_rect(a+108, b+16, 22, 5); + fl_color(FL_RED); + fl_rectf(a+1, b+8, 39, 3); // single line + fl_rectf(a+46, b+1, 39, 3); // two lines + fl_rectf(a+82, b+1, 3, 19); + fl_rectf(a+91, b+1, 20, 3); // three lines + fl_rectf(a+109, b+1, 3, 19); + fl_rectf(a+109, b+17, 20, 3); // three lines + fl_color(FL_BLACK); + fl_line_style(FL_SOLID, 3); + fl_xyline(a+1, b+9, a+39); + fl_xyline(a+46, b+2, a+83, b+19); + fl_xyline(a+91, b+2, a+110, b+18, a+128); + fl_line_style(FL_SOLID, 1); + // 5: draw fl_xyline + b+=24; + fl_color(FL_GREEN); + fl_rect(a+9, b, 3, 21); // single line + fl_rect(a+45, b, 3, 21); // horizontal, then vertical line + fl_rect(a+45, b+18, 41, 3); + fl_rect(a+90, b, 3, 11); // horizontal, vertical, horizontal line + fl_rect(a+90, b+9, 40, 3); + fl_rect(a+127, b+9, 3, 12); + fl_color(FL_RED); + fl_rectf(a+10, b+1, 1, 19); // single line + fl_rectf(a+46, b+1, 1, 19); // two lines + fl_rectf(a+46, b+19, 39, 1); + fl_rectf(a+91, b+1, 1, 10); // three lines + fl_rectf(a+91, b+10, 38, 1); + fl_rectf(a+128, b+10, 1, 10); // three lines + fl_color(FL_BLACK); + fl_yxline(a+10, b+1, b+19); + fl_yxline(a+46, b+1, b+19, a+84); + fl_yxline(a+91, b+1, b+10, a+128, b+19); + b+=24; + fl_color(FL_GREEN); + fl_rect(a+8, b, 5, 21); // single line + fl_rect(a+45, b, 5, 21); // horizontal, then vertical line + fl_rect(a+45, b+16, 41, 5); + fl_rect(a+90, b, 5, 11); // horizontal, vertical, horizontal line + fl_rect(a+90, b+8, 40, 5); + fl_rect(a+125, b+8, 5, 13); + fl_color(FL_RED); + fl_rectf(a+9, b+1, 3, 19); // single line + fl_rectf(a+46, b+1, 3, 19); // two lines + fl_rectf(a+46, b+17, 39, 3); + fl_rectf(a+91, b+1, 3, 10); // three lines + fl_rectf(a+91, b+9, 38, 3); + fl_rectf(a+126, b+9, 3, 11); // three lines + fl_color(FL_BLACK); + fl_line_style(FL_SOLID, 3); + fl_yxline(a+10, b+1, b+19); + fl_yxline(a+47, b+1, b+18, a+84); + fl_yxline(a+92, b+1, b+10, a+127, b+19); + fl_line_style(FL_SOLID, 1); + // 6: fast diagonal lines + b+=24; + fl_color(FL_GREEN); + fl_point(a, b); fl_point(a+1, b); fl_point(a, b+1); + fl_point(a+20, b+20); fl_point(a+19, b+20); fl_point(a+20, b+19); + fl_color(FL_RED); + fl_point(a+1, b+1); fl_point(a+19, b+19); + fl_color(FL_BLACK); + fl_line(a+1, b+1, a+19, b+19); + fl_color(FL_GREEN); + fl_point(a+25+1, b); fl_point(a+25, b+1); fl_point(a+25+4, b); fl_point(a+25, b+4); + fl_point(a+25+20, b+19); fl_point(a+25+19, b+20); fl_point(a+25+16, b+20); fl_point(a+25+20, b+16); + fl_color(FL_RED); + fl_point(a+25+2, b+2); fl_point(a+25+18, b+18); + fl_color(FL_BLACK); + fl_line_style(FL_SOLID, 5); + fl_line(a+25+1, b+1, a+25+19, b+19); + fl_line(a+50+1, b+1, a+50+20, b+20, a+50+39, b+1); + fl_line_style(FL_SOLID, 1); +} + +#if HAVE_GL + +class GLRectTest : public Fl_Gl_Window { +public: + GLRectTest(int x, int y, int w, int h) + : Fl_Gl_Window(x, y, w, h) { + box(FL_FLAT_BOX); + } + void draw() { + draw_begin(); + fl_color(color()); + fl_rectf(0, 0, w(), h()); + draw_fast_shapes(); + draw_end(); + } +}; + +#endif + +class NativeRectTest : public Fl_Window { +public: + NativeRectTest(int x, int y, int w, int h) + : Fl_Window(x, y, w, h) { + box(FL_FLAT_BOX); + end(); + } + void draw() { + Fl_Window::draw(); + draw_fast_shapes(); + } +}; + +class RectTest : public Fl_Group { // 520 x 365 +public: + static Fl_Widget *create() { + return new RectTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); + } + RectTest(int x, int y, int w, int h) : Fl_Group(x, y, w, h) { + label("Testing FLTK fast shape calls.\n" + "These calls draw horizontal and vertical lines, frames, and rectangles.\n\n" + "No red pixels should be visible. " + "If you see bright red lines, or if parts of the green frames are hidden, " + "drawing alignment is off."); + align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP); + box(FL_BORDER_BOX); + + int a = x+16, b = y+34; + Fl_Box *t = new Fl_Box(a, b-24, 80, 18, "native"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + /* NativeRectTest *nr = */ new NativeRectTest(a+23, b-1, 200, 200); + + t = new Fl_Box(a, b, 18, 18, "1"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing filled rectangle alignment.\n\n" + // Description: + "This draws a black rectangle, surrounded by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing, filled rectangles draw too big (see fl_rectf).\n\n" + "If red pixels are showing, filled rectangles are drawn too small." + ); + b+=24; + t = new Fl_Box(a, b, 18, 18, "2"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing rectangle frame alignment.\n\n" + // Description: + "This draws a black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, rectangular frame drawing schould be adjusted (see fl_rect).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); + b+=24; + t = new Fl_Box(a, b, 18, 18, "3"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing scaled frame alignment.\n\n" + // Description: + "This draws a 3 units wide black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, line width schould be adjusted (see fl_line_style).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); + b+=24; + t = new Fl_Box(a, b, 18, 18, "4"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_xyline.\n\n" + // Description: + "This draws 3 versions of fl_xyline surronded with a green outline.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, fl_xyline must be adjusted." + ); + b+=48; + t = new Fl_Box(a, b, 18, 18, "5"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_yxline.\n\n" + // Description: + "This draws 3 versions of fl_yxline surronded with a green outline.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, fl_yxline must be adjusted." + ); + b+=48; + t = new Fl_Box(a, b, 18, 18, "6"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_line(int...).\n\n" + // Description: + "This draws 2 lines at differnet widths, and one connected line.\n\n" + // Things to look out for: + "Green and red pixels mark the beginning and end of single lines." + "The line caps should be flat, the joints shoould be of type \"miter\"." + ); + +#if HAVE_GL + + a = x+16+250, b = y+34; + t = new Fl_Box(a, b-24, 80, 18, "OpenGL"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + /*GLRectTest *glr = */ new GLRectTest(a+31, b-1, 200, 200); + + t = new Fl_Box(a, b, 26, 18, "1a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing filled rectangle alignment.\n\n" + // Description: + "This draws a black rectangle, surrounded by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing, filled rectangles draw too big (see fl_rectf).\n\n" + "If red pixels are showing, filled rectangles are drawn too small." + ); + + b+=24; + t = new Fl_Box(a, b, 26, 18, "2a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing rectangle frame alignment.\n\n" + // Description: + "This draws a black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, rectangular frame drawing schould be adjusted (see fl_rect).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); + + b+=24; + t = new Fl_Box(a, b, 26, 18, "3a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing scaled frame alignment.\n\n" + // Description: + "This draws a 3 units wide black frame, surrounded on the inside and outside by a green frame.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, line width schould be adjusted (see fl_line_style).\n\n" + "If red pixels show in the corners of the frame in hidpi mode, line endings should be adjusted." + ); + b+=24; + t = new Fl_Box(a, b, 26, 18, "4a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_xyline.\n\n" + // Description: + "This draws 3 versions of fl_xyline surronded with a green outline.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, fl_xyline must be adjusted." + ); + b+=48; + t = new Fl_Box(a, b, 26, 18, "5a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_yxline.\n\n" + // Description: + "This draws 3 versions of fl_yxline surronded with a green outline.\n\n" + // Things to look out for: + "If green pixels are missing or red pixels are showing, fl_yxline must be adjusted." + ); + b+=48; + t = new Fl_Box(a, b, 26, 18, "6a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing fl_line(int...).\n\n" + // Description: + "This draws 2 lines at differnet widths, and one connected line.\n\n" + // Things to look out for: + "Green and red pixels mark the beginning and end of single lines." + "The line caps should be flat, the joints shoould be of type \"miter\"." + ); +#endif + + t = new Fl_Box(x+w-1,y+h-1, 1, 1); + resizable(t); + } +}; + +UnitTest rects(kTestFastShapes, "Fast Shapes", RectTest::create); diff --git a/test/unittest_images.cxx b/test/unittest_images.cxx index 210af96dc..dcc720f1b 100644 --- a/test/unittest_images.cxx +++ b/test/unittest_images.cxx @@ -14,12 +14,16 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Group.H> #include <FL/Fl_Button.H> #include <FL/Fl_Radio_Button.H> #include <FL/Fl_Check_Button.H> #include <FL/fl_draw.H> +#include <stdlib.h> + // Note: currently (March 2010) fl_draw_image() supports transparency with // alpha channel only on Apple (Mac OS X), but Fl_RGB_Image->draw() // supports transparency on all platforms ! @@ -291,4 +295,4 @@ Fl_RGB_Image *ImageTest::i_ga = 0; Fl_RGB_Image *ImageTest::i_rgb = 0; Fl_RGB_Image *ImageTest::i_rgba = 0; -UnitTest images("drawing images", ImageTest::create); +UnitTest images(kTestImages, "Drawing Images", ImageTest::create); diff --git a/test/unittest_points.cxx b/test/unittest_points.cxx index f8affc97e..22291b2ca 100644 --- a/test/unittest_points.cxx +++ b/test/unittest_points.cxx @@ -14,41 +14,293 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + +#include <config.h> #include <FL/Fl_Box.H> #include <FL/fl_draw.H> +#if HAVE_GL +#include <FL/Fl_Gl_Window.H> +#endif // //------- test the point drawing capabilities of this implementation ---------- // -class PointTest : public Fl_Box { + +class PointTestWin : public Fl_Window { +public: + PointTestWin(int x, int y, int w, int h) : + Fl_Window(x, y, w, h) { end(); } + void draw() { + int i; + fl_color(FL_WHITE); + fl_rectf(0, 0, 10, 10); + fl_color(FL_BLACK); + for (i=0; i<10; i++) { + fl_point(i, 0); + fl_point(i, 9); + } + for (i=0; i<10; i++) { + fl_point(0, i); + fl_point(9, i); + } + } +}; + +#if HAVE_GL + +class GLTestWin : public Fl_Gl_Window { +public: + GLTestWin(int x, int y, int w, int h) : + Fl_Gl_Window(x, y, w, h) { + box(FL_FLAT_BOX); + end(); + } + void draw() { + Fl_Gl_Window::draw_begin(); + Fl_Window::draw(); + + int a = -24, b = 5-9, i, j; + // Test 1a: pixel size + fl_color(FL_WHITE); fl_rectf(a+24, b+9-5, 10, 10); + fl_color(FL_BLACK); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + if ((i+j)&1) + fl_point(a+i+24+1, b+j+9-5+1); + // Test 2a: pixel color + for (int n=0; n<3; n++) { + static Fl_Color lut[3] = { FL_RED, FL_GREEN, FL_BLUE }; + int yy = b+9-5+24 + 16*n; + fl_color(FL_WHITE); fl_rectf(a+24, yy, 10, 10); + fl_color(lut[n]); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + fl_point(a+i+24+1, yy+j+1); + } + // Test 3a: pixel alignment inside windows (drawing happens in PointTestWin) + int xx = a+24, yy = b+2*24+2*16+9-5; + fl_color(FL_RED); + for (i=0; i<10; i++) { + fl_point(xx-1, yy+i); + fl_point(xx+10, yy+i); + } + fl_color(FL_BLACK); + for (i=0; i<10; i++) { + fl_point(xx+i, yy); + fl_point(xx+i, yy+9); + } + for (i=0; i<10; i++) { + fl_point(xx, yy+i); + fl_point(xx+9, yy+i); + } + fl_color(FL_WHITE); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + fl_point(xx+i+1, yy+j+1); + // Test 4a: check pixel clipping + xx = a+24; yy = b+3*24+2*16+9-5; + fl_push_clip(xx+1, yy+1, 9, 9); + fl_color(FL_RED); + for (i=0; i<10; i++) { + fl_point(xx+i, yy); + fl_point(xx+i, yy+9); + } + for (i=0; i<10; i++) { + fl_point(xx, yy+i); + fl_point(xx+9, yy+i); + } + fl_color(FL_BLACK); + for (i=1; i<9; i++) { + fl_point(xx+i, yy+1); + fl_point(xx+i, yy+8); + } + for (i=1; i<9; i++) { + fl_point(xx+1, yy+i); + fl_point(xx+8, yy+i); + } + fl_color(FL_WHITE); + for (i=1; i<7; i++) + for (j=1; j<7; j++) + fl_point(xx+i+1, yy+j+1); + fl_pop_clip(); + + Fl_Gl_Window::draw_end(); + } +}; + +#endif + +class PointTest : public Fl_Group { + PointTestWin *align_test_win; +#if HAVE_GL + GLTestWin *gl_test_win; +#endif public: static Fl_Widget *create() { return new PointTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); + // 520x365, resizable } - PointTest(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { - label("testing the fl_point call\n" - "You should see four pixels each in black, red, green and blue. " - "Make sure that pixels are not anti-aliased (blurred across multiple pixels)!"); + PointTest(int x, int y, int w, int h) : Fl_Group(x, y, w, h) { + label("Testing the fl_point call."); align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP); box(FL_BORDER_BOX); + int a = x+16, b = y+34; + Fl_Box *t = new Fl_Box(a, b-24, 80, 18, "native"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + t = new Fl_Box(a, b, 18, 18, "1"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixel size and antialiasing.\n\n" + // Description: + "This draws a checker board of black points on a white background.\n\n" + // Things to look out for: + "Black and white points should be the same size of one unit (1 pixel in regular mode, 2x2 pixels in hidpi mode)." + "If black points are smaller than white in hidpi mode, point size must be increased.\n\n" + "Points should not be blurry. Antialiasing should be switched of and the point coordinates should be centered on the pixel(s).\n\n" + "If parts of the white border are missing, the size of fl_rect should be adjusted." + ); + t = new Fl_Box(a, b+24, 18, 18, "2"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels color.\n\n" + // Description: + "This draws three squares in red, green, and blue.\n\n" + // Things to look out for: + "If the order of colors is different, the byte order when writing into the pixel buffer should be fixed." + ); + t = new Fl_Box(a, b+2*24+2*16, 18, 18, "3"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels alignment in windows.\n\n" + // Description: + "This draws a black frame around a white square.\n\n" + // Things to look out for: + "If parts of the black frame are clipped by the window and not visible, pixel offsets must be adjusted." + ); + align_test_win = new PointTestWin(a+24, b+2*24+2*16+9-5, 10, 10); + + t = new Fl_Box(a, b+3*24+2*16, 18, 18, "4"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels clipping.\n\n" + // Description: + "This draws a black frame around a white square.\n\n" + // Things to look out for: + "If red pixels are visble or black pixels are missing, graphics clipping is misaligned." + ); + + a+=100; +#if HAVE_GL + t = new Fl_Box(a, b-24, 80, 18, "OpenGL"); + t->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + + t = new Fl_Box(a, b, 26, 18, "1a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixel size and antialiasing.\n\n" + // Description: + "This draws a checker board of black points on a white background.\n\n" + // Things to look out for: + "Black and white points should be the same size of one unit (1 pixel in regular mode, 2x2 pixels in hidpi mode)." + "If black points are smaller than white in hidpi mode, point size must be increased.\n\n" + "Points should not be blurry. Antialiasing should be switched of and the point coordinates should be centered on the pixel(s).\n\n" + "If parts of the white border are missing, the size of fl_rect should be adjusted." + ); + t = new Fl_Box(a, b+24, 26, 18, "2a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels color.\n\n" + // Description: + "This draws three squares in red, green, and blue.\n\n" + // Things to look out for: + "If the order of colors is different, the color component order when writing into the pixel buffer should be fixed." + ); + t = new Fl_Box(a, b+2*24+2*16, 26, 18, "3a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels alignment in windows.\n\n" + // Description: + "This draws a black frame around a white square, extending to both sides.\n\n" + // Things to look out for: + "If parts of the black frame are clipped by the window and not visible, pixel offsets must be adjusted horizontally.\n\n" + "If the horizontal lines are misaligned, vertical pixel offset should be adjusted." + ); + + t = new Fl_Box(a, b+3*24+2*16, 26, 18, "4a"); + t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW); + t->tooltip(// Title: + "Testing pixels clipping.\n\n" + // Description: + "This draws a black frame around a white square. The square is slightly smaller.\n\n" + // Things to look out for: + "If red pixels are visble or black pixels are missing, graphics clipping is misaligned." + ); + + gl_test_win = new GLTestWin(a+24+8, b+9-5, 10, 4*24+2*16); +#endif + + t = new Fl_Box(x+w-1,y+h-1, 1, 1); + resizable(t); } void draw() { - Fl_Box::draw(); - int a = x()+10, b = y()+10; - fl_color(FL_WHITE); fl_rectf(a, b, 90, 90); - fl_color(FL_BLACK); fl_rect(a, b, 90, 90); - fl_point(a+10, b+10); fl_point(a+20, b+20); - fl_point(a+10, b+20); fl_point(a+20, b+10); - fl_color(FL_RED); a = x()+70; - fl_point(a+10, b+10); fl_point(a+20, b+20); - fl_point(a+10, b+20); fl_point(a+20, b+10); - fl_color(FL_GREEN); a = x()+10; b = y()+70; - fl_point(a+10, b+10); fl_point(a+20, b+20); - fl_point(a+10, b+20); fl_point(a+20, b+10); - fl_color(FL_BLUE); a = x()+70; - fl_point(a+10, b+10); fl_point(a+20, b+20); - fl_point(a+10, b+20); fl_point(a+20, b+10); + Fl_Group::draw(); + int a = x()+16, b = y()+34, i, j; + // Test 1: pixel size + fl_color(FL_WHITE); fl_rectf(a+24, b+9-5, 10, 10); + fl_color(FL_BLACK); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + if ((i+j)&1) + fl_point(a+i+24+1, b+j+9-5+1); + // Test 2: pixel color + for (int n=0; n<3; n++) { + static Fl_Color lut[3] = { FL_RED, FL_GREEN, FL_BLUE }; + int yy = b+9-5+24 + 16*n; + fl_color(FL_WHITE); fl_rectf(a+24, yy, 10, 10); + fl_color(lut[n]); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + fl_point(a+i+24+1, yy+j+1); + } + // Test 3: pixel alignment inside windows (drawing happens in PointTestWin) + // Test 4: check pixel clipping + int xx = a+24, yy = b+3*24+2*16+9-5; + fl_push_clip(xx, yy, 10, 10); + fl_color(FL_RED); + for (i=-1; i<11; i++) { + fl_point(xx+i, yy-1); + fl_point(xx+i, yy+10); + } + for (i=-1; i<11; i++) { + fl_point(xx-1, yy+i); + fl_point(xx+10, yy+i); + } + fl_color(FL_BLACK); + for (i=0; i<10; i++) { + fl_point(xx+i, yy); + fl_point(xx+i, yy+9); + } + for (i=0; i<10; i++) { + fl_point(xx, yy+i); + fl_point(xx+9, yy+i); + } + fl_color(FL_WHITE); + for (i=0; i<8; i++) + for (j=0; j<8; j++) + fl_point(xx+i+1, yy+j+1); + fl_pop_clip(); + // Test 3a: pixel alignment inside the OpenGL window +#if HAVE_GL + xx = a+24+108; yy = b+2*24+2*16+9-5; + fl_color(FL_BLACK); + for (i=-4; i<14; i++) { + fl_point(xx+i, yy); + fl_point(xx+i, yy+9); + } +#endif } }; -UnitTest points("drawing points", PointTest::create); +UnitTest points(kTestPoints, "Drawing Points", PointTest::create); diff --git a/test/unittest_rects.cxx b/test/unittest_rects.cxx deleted file mode 100644 index 69d2ae1e6..000000000 --- a/test/unittest_rects.cxx +++ /dev/null @@ -1,51 +0,0 @@ -// -// Unit tests for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2010 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <FL/Fl_Box.H> -#include <FL/fl_draw.H> // fl_text_extents() - -// -//------- test the rectangle drawing capabilities of this implementation ---------- -// -class RectTest : public Fl_Box { -public: - static Fl_Widget *create() { - return new RectTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H); - } - RectTest(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { - label("testing the fl_rect call\n" - "No red pixels should be visible. " - "If you see bright red lines, or if parts of the green frames are hidden, " - "the rect drawing alignment is off."); - align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP); - box(FL_BORDER_BOX); - } - void draw() { - Fl_Box::draw(); - int a = x()+10, b = y()+10; fl_color(FL_BLACK); fl_rect(a, b, 100, 100); - // testing fl_rect() with positive size - fl_color(FL_RED); fl_loop(a+10, b+10, a+40, b+10, a+40, b+40, a+10, b+40); - fl_color(FL_GREEN); fl_loop(a+ 9, b+ 9, a+41, b+ 9, a+41, b+41, a+ 9, b+41); - fl_color(FL_GREEN); fl_loop(a+11, b+11, a+39, b+11, a+39, b+39, a+11, b+39); - fl_color(FL_BLACK); fl_rect(a+10, b+10, 31, 31); - // testing fl_rect() with positive size - fl_color(FL_RED); fl_loop(a+60, b+60, a+90, b+60, a+90, b+90, a+60, b+90); - fl_color(FL_GREEN); fl_loop(a+59, b+59, a+91, b+59, a+91, b+91, a+59, b+91); - fl_color(FL_BLACK); fl_rectf(a+60, b+60, 31, 31); - } -}; - -UnitTest rects("rectangles", RectTest::create); diff --git a/test/unittest_schemes.cxx b/test/unittest_schemes.cxx index 9f5123ca6..767a18bfc 100644 --- a/test/unittest_schemes.cxx +++ b/test/unittest_schemes.cxx @@ -16,6 +16,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Choice.H> // needed by Edmanuel's test layout @@ -324,4 +326,4 @@ public: } }; -UnitTest schemestest("schemes test", SchemesTest::create); +UnitTest schemestest(kTestSchemes, "Schemes Test", SchemesTest::create); diff --git a/test/unittest_scrollbarsize.cxx b/test/unittest_scrollbarsize.cxx index f0aacd137..10b5668a2 100644 --- a/test/unittest_scrollbarsize.cxx +++ b/test/unittest_scrollbarsize.cxx @@ -14,7 +14,10 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Group.H> +#include <FL/Fl_Box.H> #include <FL/Fl_Browser.H> #include <FL/Fl_Tree.H> #include <FL/Fl_Table.H> @@ -216,4 +219,4 @@ public: } }; -UnitTest scrollbarsize("scrollbar size", ScrollBarSizeTest::create); +UnitTest scrollbarsize(kTestScrollbarsize, "Scrollbar Size", ScrollBarSizeTest::create); diff --git a/test/unittest_simple_terminal.cxx b/test/unittest_simple_terminal.cxx index 645f99685..778319028 100644 --- a/test/unittest_simple_terminal.cxx +++ b/test/unittest_simple_terminal.cxx @@ -14,6 +14,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <time.h> #include <FL/Fl_Group.H> #include <FL/Fl_Simple_Terminal.H> @@ -115,4 +117,4 @@ public: } }; -UnitTest simple_terminal("simple terminal", SimpleTerminal::create); +UnitTest simple_terminal(kTestSimpleTerminal, "Simple Terminal", SimpleTerminal::create); diff --git a/test/unittest_symbol.cxx b/test/unittest_symbol.cxx index ee95d1505..9e922394e 100644 --- a/test/unittest_symbol.cxx +++ b/test/unittest_symbol.cxx @@ -14,6 +14,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Box.H> #include <FL/fl_draw.H> @@ -86,4 +88,4 @@ public: } }; -UnitTest symbolExtents("symbol text", SymbolTest::create); +UnitTest symbolExtents(kTestSymbol, "Symbol Text", SymbolTest::create); diff --git a/test/unittest_text.cxx b/test/unittest_text.cxx index 80cce72e1..9613d54a8 100644 --- a/test/unittest_text.cxx +++ b/test/unittest_text.cxx @@ -14,6 +14,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Box.H> #include <FL/fl_draw.H> @@ -79,4 +81,4 @@ public: } }; -UnitTest textExtents("rendering text", TextExtentsTest::create); +UnitTest textExtents(kTestText, "Rendering text", TextExtentsTest::create); diff --git a/test/unittest_viewport.cxx b/test/unittest_viewport.cxx index 52026256a..0ae98fac5 100644 --- a/test/unittest_viewport.cxx +++ b/test/unittest_viewport.cxx @@ -14,6 +14,8 @@ // https://www.fltk.org/bugs.php // +#include "unittests.h" + #include <FL/Fl_Box.H> #include <FL/fl_draw.H> @@ -46,4 +48,4 @@ public: } }; -UnitTest viewport("viewport test", ViewportTest::create); +UnitTest viewport(kTestViewport, "Viewport Test", ViewportTest::create); diff --git a/test/unittests.cxx b/test/unittests.cxx index b81a007d1..47261241c 100644 --- a/test/unittests.cxx +++ b/test/unittests.cxx @@ -21,6 +21,8 @@ // v1.0 - Submit for svn // v1.1 - Matthias seperated all tests into multiple source files for hopefully easier handling +#include "unittests.h" + #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Hold_Browser.H> @@ -31,129 +33,90 @@ #include <FL/fl_string_functions.h> // fl_strdup() #include <stdlib.h> // malloc, free -// WINDOW/WIDGET SIZES -#define MAINWIN_W 700 // main window w() -#define MAINWIN_H 400 // main window h() -#define BROWSER_X 10 // browser x() -#define BROWSER_Y 25 // browser y() -#define BROWSER_W 150 // browser w() -#define BROWSER_H MAINWIN_H-35 // browser h() -#define TESTAREA_X (BROWSER_W + 20) // test area x() -#define TESTAREA_Y 25 // test area y() -#define TESTAREA_W (MAINWIN_W - BROWSER_W - 30) // test area w() -#define TESTAREA_H BROWSER_H // test area h() +class MainWindow *mainwin = 0; +class Fl_Hold_Browser *browser = 0; + +UnitTest::UnitTest(int index, const char *label, Fl_Widget* (*create)()) : + fWidget(0L) +{ + fLabel = fl_strdup(label); + fCreate = create; + add(index, this); +} -typedef void (*UnitTestCallback)(const char*,Fl_Group*); +UnitTest::~UnitTest() { + delete fWidget; + free(fLabel); +} -class MainWindow *mainwin = 0; -Fl_Hold_Browser *browser = 0; - -// This class helps to automagically register a new test with the unittest app. -// Please see the examples on how this is used. -class UnitTest { -public: - UnitTest(const char *label, Fl_Widget* (*create)()) : - fWidget(0L) - { - fLabel = fl_strdup(label); - fCreate = create; - add(this); - } - ~UnitTest() { - delete fWidget; - free(fLabel); - } - const char *label() { - return fLabel; - } - void create() { - fWidget = fCreate(); - if (fWidget) fWidget->hide(); - } - void show() { - if (fWidget) fWidget->show(); - } - void hide() { - if (fWidget) fWidget->hide(); - } - static int numTest() { return nTest; } - static UnitTest *test(int i) { return fTest[i]; } -private: - char *fLabel; - Fl_Widget *(*fCreate)(); - Fl_Widget *fWidget; - - static void add(UnitTest *t) { - fTest[nTest] = t; - nTest++; - } - static int nTest; - static UnitTest *fTest[]; -}; +const char *UnitTest::label() { + return fLabel; +} + +void UnitTest::create() { + fWidget = fCreate(); + if (fWidget) fWidget->hide(); +} + +void UnitTest::show() { + if (fWidget) fWidget->show(); +} + +void UnitTest::hide() { + if (fWidget) fWidget->hide(); +} + +void UnitTest::add(int index, UnitTest *t) { + fTest[index] = t; + if (index>=nTest) + nTest = index+1; +} int UnitTest::nTest = 0; -UnitTest *UnitTest::fTest[200]; - - -// The main window needs an additional drawing feature in order to support -// the viewport alignment test. -class MainWindow : public Fl_Double_Window { -public: - MainWindow(int w, int h, const char *l=0L) : - Fl_Double_Window(w, h, l), - fTestAlignment(0) - { } - // this code is used by the viewport alignment test - void drawAlignmentIndicators() { - const int sze = 16; - // top left corner - fl_color(FL_GREEN); fl_yxline(0, sze, 0, sze); - fl_color(FL_RED); fl_yxline(-1, sze, -1, sze); - fl_color(FL_WHITE); fl_rectf(3, 3, sze-2, sze-2); - fl_color(FL_BLACK); fl_rect(3, 3, sze-2, sze-2); - // bottom left corner - fl_color(FL_GREEN); fl_yxline(0, h()-sze-1, h()-1, sze); - fl_color(FL_RED); fl_yxline(-1, h()-sze-1, h(), sze); - fl_color(FL_WHITE); fl_rectf(3, h()-sze-1, sze-2, sze-2); - fl_color(FL_BLACK); fl_rect(3, h()-sze-1, sze-2, sze-2); - // bottom right corner - fl_color(FL_GREEN); fl_yxline(w()-1, h()-sze-1, h()-1, w()-sze-1); - fl_color(FL_RED); fl_yxline(w(), h()-sze-1, h(), w()-sze-1); - fl_color(FL_WHITE); fl_rectf(w()-sze-1, h()-sze-1, sze-2, sze-2); - fl_color(FL_BLACK); fl_rect(w()-sze-1, h()-sze-1, sze-2, sze-2); - // top right corner - fl_color(FL_GREEN); fl_yxline(w()-1, sze, 0, w()-sze-1); - fl_color(FL_RED); fl_yxline(w(), sze, -1, w()-sze-1); - fl_color(FL_WHITE); fl_rectf(w()-sze-1, 3, sze-2, sze-2); - fl_color(FL_BLACK); fl_rect(w()-sze-1, 3, sze-2, sze-2); - } - void draw() { - Fl_Double_Window::draw(); - if (fTestAlignment) { - drawAlignmentIndicators(); - } - } - void testAlignment(int v) { - fTestAlignment = v; - redraw(); +UnitTest *UnitTest::fTest[200] = { 0 }; + +MainWindow::MainWindow(int w, int h, const char *l) : +Fl_Double_Window(w, h, l), +fTestAlignment(0) +{ } + +void MainWindow::drawAlignmentIndicators() { + const int sze = 16; + // top left corner + fl_color(FL_GREEN); fl_yxline(0, sze, 0, sze); + fl_color(FL_RED); fl_yxline(-1, sze, -1, sze); + fl_color(FL_WHITE); fl_rectf(3, 3, sze-2, sze-2); + fl_color(FL_BLACK); fl_rect(3, 3, sze-2, sze-2); + // bottom left corner + fl_color(FL_GREEN); fl_yxline(0, h()-sze-1, h()-1, sze); + fl_color(FL_RED); fl_yxline(-1, h()-sze-1, h(), sze); + fl_color(FL_WHITE); fl_rectf(3, h()-sze-1, sze-2, sze-2); + fl_color(FL_BLACK); fl_rect(3, h()-sze-1, sze-2, sze-2); + // bottom right corner + fl_color(FL_GREEN); fl_yxline(w()-1, h()-sze-1, h()-1, w()-sze-1); + fl_color(FL_RED); fl_yxline(w(), h()-sze-1, h(), w()-sze-1); + fl_color(FL_WHITE); fl_rectf(w()-sze-1, h()-sze-1, sze-2, sze-2); + fl_color(FL_BLACK); fl_rect(w()-sze-1, h()-sze-1, sze-2, sze-2); + // top right corner + fl_color(FL_GREEN); fl_yxline(w()-1, sze, 0, w()-sze-1); + fl_color(FL_RED); fl_yxline(w(), sze, -1, w()-sze-1); + fl_color(FL_WHITE); fl_rectf(w()-sze-1, 3, sze-2, sze-2); + fl_color(FL_BLACK); fl_rect(w()-sze-1, 3, sze-2, sze-2); +} + +void MainWindow::draw() { + Fl_Double_Window::draw(); + if (fTestAlignment) { + drawAlignmentIndicators(); } - int fTestAlignment; -}; +} -//------- include the various unit tests as inline code ------- +void MainWindow::testAlignment(int v) { + fTestAlignment = v; + redraw(); +} -#include "unittest_about.cxx" -#include "unittest_points.cxx" -#include "unittest_lines.cxx" -#include "unittest_rects.cxx" -#include "unittest_circles.cxx" -#include "unittest_text.cxx" -#include "unittest_symbol.cxx" -#include "unittest_images.cxx" -#include "unittest_viewport.cxx" -#include "unittest_scrollbarsize.cxx" -#include "unittest_schemes.cxx" -#include "unittest_simple_terminal.cxx" +//------- include the various unit tests as inline code ------- // callback whenever the browser value changes void Browser_CB(Fl_Widget*, void*) { @@ -175,6 +138,7 @@ int main(int argc, char **argv) { Fl::get_system_colors(); Fl::scheme(Fl::scheme()); // init scheme before instantiating tests Fl::visual(FL_RGB); + Fl::use_high_res_GL(1); mainwin = new MainWindow(MAINWIN_W, MAINWIN_H, "FLTK Unit Tests"); browser = new Fl_Hold_Browser(BROWSER_X, BROWSER_Y, BROWSER_W, BROWSER_H, "Unit Tests"); browser->align(FL_ALIGN_TOP|FL_ALIGN_LEFT); @@ -184,16 +148,18 @@ int main(int argc, char **argv) { int i, n = UnitTest::numTest(); for (i=0; i<n; i++) { UnitTest *t = UnitTest::test(i); - mainwin->begin(); - t->create(); - mainwin->end(); - browser->add(t->label(), (void*)t); + if (t) { + mainwin->begin(); + t->create(); + mainwin->end(); + browser->add(t->label(), (void*)t); + } } mainwin->resizable(mainwin); mainwin->show(argc,argv); // Select first test in browser, and show that test. - browser->select(1); + browser->select(kTestAbout+1); Browser_CB(browser,0); return(Fl::run()); } diff --git a/test/unittests.h b/test/unittests.h new file mode 100644 index 000000000..3b9cddd3f --- /dev/null +++ b/test/unittests.h @@ -0,0 +1,87 @@ +// +// Unit tests for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2022 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +#ifndef UNITTESTS_H +#define UNITTESTS_H 1 + +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> + +// WINDOW/WIDGET SIZES +#define MAINWIN_W 700 // main window w() +#define MAINWIN_H 400 // main window h() +#define BROWSER_X 10 // browser x() +#define BROWSER_Y 25 // browser y() +#define BROWSER_W 150 // browser w() +#define BROWSER_H MAINWIN_H-35 // browser h() +#define TESTAREA_X (BROWSER_W + 20) // test area x() +#define TESTAREA_Y 25 // test area y() +#define TESTAREA_W (MAINWIN_W - BROWSER_W - 30) // test area w() +#define TESTAREA_H BROWSER_H // test area h() + +typedef void (*UnitTestCallback)(const char*, class Fl_Group*); + +extern class MainWindow *mainwin; +extern class Fl_Hold_Browser *browser; + +enum { + kTestAbout = 0, + kTestPoints, + kTestFastShapes, + kTestCircles, +// kTestComplexShapes, + kTestText, + kTestSymbol, + kTestImages, + kTestViewport, + kTestScrollbarsize, + kTestSchemes, + kTestSimpleTerminal +}; + +// This class helps to automatically register a new test with the unittest app. +// Please see the examples on how this is used. +class UnitTest { +public: + UnitTest(int index, const char *label, Fl_Widget* (*create)()); + ~UnitTest(); + const char *label(); + void create(); + void show(); + void hide(); + static int numTest() { return nTest; } + static UnitTest *test(int i) { return fTest[i]; } +private: + char *fLabel; + Fl_Widget *(*fCreate)(); + Fl_Widget *fWidget; + static void add(int index, UnitTest *t); + static int nTest; + static UnitTest *fTest[]; +}; + +// The main window needs an additional drawing feature in order to support +// the viewport alignment test. +class MainWindow : public Fl_Double_Window { +public: + MainWindow(int w, int h, const char *l=0L); + void drawAlignmentIndicators(); + void draw(); + void testAlignment(int v); + int fTestAlignment; +}; + +#endif |
