mirror of https://github.com/fltk/fltk
436 lines
12 KiB
C++
436 lines
12 KiB
C++
//
|
|
// 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
|
|
//
|
|
|
|
#include "unittests.h"
|
|
|
|
#include <config.h>
|
|
#include <FL/Fl_Box.H>
|
|
#include <FL/Fl_Hor_Value_Slider.H>
|
|
#include <FL/Fl_Dial.H>
|
|
#include <FL/Fl_Positioner.H>
|
|
#include <FL/fl_draw.H>
|
|
|
|
#if HAVE_GL
|
|
#include <FL/Fl_Gl_Window.H>
|
|
#endif
|
|
|
|
//
|
|
// --- test drawing circles and arcs ------
|
|
//
|
|
|
|
class Ut_Complex_Shapes_Test;
|
|
|
|
void draw_complex(Ut_Complex_Shapes_Test *p);
|
|
|
|
#if HAVE_GL
|
|
|
|
class Ut_GL_Complex_Shapes_Test : public Fl_Gl_Window {
|
|
public:
|
|
Ut_GL_Complex_Shapes_Test(int x, int y, int w, int h)
|
|
: Fl_Gl_Window(x, y, w, h) {
|
|
box(FL_FLAT_BOX);
|
|
end();
|
|
}
|
|
void draw() FL_OVERRIDE {
|
|
draw_begin();
|
|
Fl_Window::draw();
|
|
draw_complex((Ut_Complex_Shapes_Test*)parent());
|
|
draw_end();
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
class Ut_Native_Complex_Shapes_Test : public Fl_Window {
|
|
public:
|
|
Ut_Native_Complex_Shapes_Test(int x, int y, int w, int h)
|
|
: Fl_Window(x, y, w, h) {
|
|
box(FL_FLAT_BOX);
|
|
end();
|
|
}
|
|
void draw() FL_OVERRIDE {
|
|
Fl_Window::draw();
|
|
draw_complex((Ut_Complex_Shapes_Test*)parent());
|
|
}
|
|
};
|
|
|
|
//
|
|
//------- test the compelx shape drawing capabilities of this implementation ----------
|
|
//
|
|
class Ut_Complex_Shapes_Test : public Fl_Group {
|
|
Ut_Native_Complex_Shapes_Test* native_test_window;
|
|
#if HAVE_GL
|
|
Ut_GL_Complex_Shapes_Test* gl_test_window;
|
|
#endif
|
|
static void update_cb(Fl_Widget*, void *v) {
|
|
Ut_Complex_Shapes_Test* This = (Ut_Complex_Shapes_Test*)v;
|
|
This->native_test_window->redraw();
|
|
#if HAVE_GL
|
|
This->gl_test_window->redraw();
|
|
#endif
|
|
}
|
|
public:
|
|
Fl_Hor_Value_Slider* scale;
|
|
Fl_Dial* rotate;
|
|
Fl_Positioner* position;
|
|
void set_transformation() {
|
|
fl_translate(position->xvalue(), position->yvalue());
|
|
fl_rotate(-rotate->value());
|
|
fl_scale(scale->value(), scale->value());
|
|
}
|
|
static Fl_Widget* create() {
|
|
return new Ut_Complex_Shapes_Test(UT_TESTAREA_X, UT_TESTAREA_Y, UT_TESTAREA_W, UT_TESTAREA_H);
|
|
}
|
|
Ut_Complex_Shapes_Test(int x, int y, int w, int h) : Fl_Group(x, y, w, h) {
|
|
label("Testing complex shape drawing.");
|
|
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);
|
|
|
|
native_test_window = new Ut_Native_Complex_Shapes_Test(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 complex drawing with transformations.\n\n"
|
|
// Description:
|
|
"Draw a point pattern, an open line, a closed line, and a covenx polygon.\n\n"
|
|
// Things to look out for:
|
|
"Use the controls at the bottom right to scale, rotate, and move the patterns."
|
|
);
|
|
b+=44;
|
|
t = new Fl_Box(a, b, 18, 18, "2");
|
|
t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW);
|
|
t->tooltip(// Title:
|
|
"Testing complex polygons.\n\n"
|
|
// Description:
|
|
"Draw polygons at different leves of complexity. "
|
|
"All polygons should be within the blue boundaries\n\n"
|
|
// Things to look out for:
|
|
"1: a convex polygon\n"
|
|
"2: a non-convex polygon\n"
|
|
"3: two polygons in a single operation\n"
|
|
"4: a polygon with a square hole in it"
|
|
);
|
|
b+=44;
|
|
t = new Fl_Box(a, b, 18, 18, "3");
|
|
t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW);
|
|
t->tooltip(// Title:
|
|
"Testing complex polygons with arcs.\n\n"
|
|
// Description:
|
|
"Draw polygons with an arc section. "
|
|
"All polygons should be within the blue boundaries\n\n"
|
|
// Things to look out for:
|
|
"1: a polygon with a camel hump\n"
|
|
"2: a polygon with a camel dip"
|
|
);
|
|
#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);
|
|
|
|
gl_test_window = new Ut_GL_Complex_Shapes_Test(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 complex drawing with transformations.\n\n"
|
|
// Description:
|
|
"Draw a point pattern, an open line, a closed line, and a convex polygon.\n\n"
|
|
// Things to look out for:
|
|
"Use the controls at the bottom right to scale, rotate, and move the patterns."
|
|
);
|
|
b+=44;
|
|
t = new Fl_Box(a, b, 28, 18, "2a");
|
|
t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW);
|
|
t->tooltip(// Title:
|
|
"Testing complex polygons.\n\n"
|
|
// Description:
|
|
"Draw polygons at different leves of complexity. "
|
|
"All polygons should be within the blue boundaries\n\n"
|
|
// Things to look out for:
|
|
"1: a convex polygon\n"
|
|
"2: a non-convex polygon\n"
|
|
"3: two polygons in a single operation\n"
|
|
"4: a polygon with a square hole in it"
|
|
);
|
|
b+=44;
|
|
t = new Fl_Box(a, b, 28, 18, "3a");
|
|
t->box(FL_ROUNDED_BOX); t->color(FL_YELLOW);
|
|
t->tooltip(// Title:
|
|
"Testing complex polygons with arcs.\n\n"
|
|
// Description:
|
|
"Draw polygons with an arc section. "
|
|
"All polygons should be within the blue boundaries\n\n"
|
|
// Things to look out for:
|
|
"1: a polygon with a camel hump\n"
|
|
"2: a polygon with a camel dip"
|
|
);
|
|
#endif
|
|
|
|
a = UT_TESTAREA_X+UT_TESTAREA_W-250;
|
|
b = UT_TESTAREA_Y+UT_TESTAREA_H-50;
|
|
|
|
scale = new Fl_Hor_Value_Slider(a, b+10, 120, 20, "Scale:");
|
|
scale->align(FL_ALIGN_TOP_LEFT);
|
|
scale->range(0.8, 1.2);
|
|
scale->value(1.0);
|
|
scale->callback(update_cb, this);
|
|
|
|
rotate = new Fl_Dial(a+140, b, 40, 40, "Rotate:");
|
|
rotate->align(FL_ALIGN_TOP_LEFT);
|
|
rotate->angles(0, 360);
|
|
rotate->range(-180.0, 180.0);
|
|
rotate->value(0.0);
|
|
rotate->callback(update_cb, this);
|
|
|
|
position = new Fl_Positioner(a+200, b, 40, 40, "Offset:");
|
|
position->align(FL_ALIGN_TOP_LEFT);
|
|
position->xbounds(-10, 10);
|
|
position->ybounds(-10, 10);
|
|
position->value(0.0, 0.0);
|
|
position->callback(update_cb, this);
|
|
|
|
t = new Fl_Box(a-1, b-1, 1, 1);
|
|
resizable(t);
|
|
}
|
|
};
|
|
|
|
void convex_shape(int w, int h) {
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w, -h/2);
|
|
}
|
|
|
|
void complex_shape(int w, int h) {
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(0, -h/2);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w/2, 0);
|
|
fl_vertex(-w, -h/2);
|
|
}
|
|
|
|
void two_complex_shapes(int w, int h) {
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h-3);
|
|
fl_gap();
|
|
fl_vertex(w-3, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w, -h/2);
|
|
}
|
|
|
|
void complex_shape_with_hole(int w, int h) {
|
|
int w2 = w/3, h2 = h/3;
|
|
// clockwise
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w, -h/2);
|
|
fl_gap();
|
|
// counterclockwise
|
|
fl_vertex(-w2, -h2);
|
|
fl_vertex(-w2, h2);
|
|
fl_vertex( w2, h2);
|
|
fl_vertex( w2, -h2);
|
|
}
|
|
|
|
void draw_complex(Ut_Complex_Shapes_Test *p) {
|
|
int a = 0, b = 0, dx = 20, dy = 20, w = 10, h = 10;
|
|
int w2 = w/3, h2 = h/3;
|
|
// ---- 1: draw a random shape
|
|
fl_color(FL_BLACK);
|
|
// -- points
|
|
fl_push_matrix();
|
|
fl_translate(a+dx, b+dy);
|
|
p->set_transformation();
|
|
fl_begin_points();
|
|
convex_shape(w, h);
|
|
fl_end_points();
|
|
fl_pop_matrix();
|
|
// -- lines
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+50, b+dy);
|
|
p->set_transformation();
|
|
fl_begin_line();
|
|
convex_shape(w, h);
|
|
fl_end_line();
|
|
fl_pop_matrix();
|
|
// -- line loop
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+100, b+dy);
|
|
p->set_transformation();
|
|
fl_begin_loop();
|
|
convex_shape(w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- polygon
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+150, b+dy);
|
|
p->set_transformation();
|
|
fl_begin_polygon();
|
|
convex_shape(w, h);
|
|
fl_end_polygon();
|
|
fl_pop_matrix();
|
|
|
|
// ---- 2: draw a complex shape
|
|
b += 44;
|
|
// -- covex polygon drawn in complex mode
|
|
fl_push_matrix();
|
|
fl_translate(a+dx, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
convex_shape(w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
convex_shape(w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- non-convex polygon drawn in complex mode
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+50, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
complex_shape(w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
complex_shape(w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- two part polygon with gap
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+100, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
two_complex_shapes(w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h-3);
|
|
fl_end_loop();
|
|
fl_begin_loop();
|
|
fl_vertex(w-3, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w, -h/2);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- polygon with a hole
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+150, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
complex_shape_with_hole(w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
fl_vertex(-w/2, -h);
|
|
fl_vertex(w/2, -h);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h);
|
|
fl_vertex(0, h);
|
|
fl_vertex(-w, h/2);
|
|
fl_vertex(-w, -h/2);
|
|
fl_end_loop();
|
|
fl_begin_loop();
|
|
fl_vertex(-w2, -h2);
|
|
fl_vertex(-w2, h2);
|
|
fl_vertex( w2, h2);
|
|
fl_vertex( w2, -h2);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
|
|
// ---- 3: draw polygons with arcs
|
|
b += 44;
|
|
// -- a rectangle with a camel hump
|
|
fl_push_matrix();
|
|
fl_translate(a+dx, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
fl_vertex(-w, 0); fl_arc(0, 0, w-3, 180.0, 0.0); fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
fl_vertex(-w, 0); fl_arc(0, 0, w-3, 180.0, 0.0); fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- a rectangle with a camel dip
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+50, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
fl_vertex(-w, 0); fl_arc(0, 0, w-3, 180.0, 360.0); fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
fl_vertex(-w, 0); fl_arc(0, 0, w-3, 180.0, 360.0); fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
// -- a rectangle with a bezier curve top
|
|
fl_push_matrix();
|
|
fl_translate(a+dx+100, b+dy);
|
|
p->set_transformation();
|
|
fl_color(FL_DARK2);
|
|
fl_begin_complex_polygon();
|
|
fl_vertex(-w, 0);
|
|
fl_curve(-w+3, 0, 0, -h, 0, h, w-3, 0);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_complex_polygon();
|
|
fl_color(FL_BLUE);
|
|
fl_begin_loop();
|
|
fl_vertex(-w, 0);
|
|
fl_curve(-w+3, 0, 0, -h, 0, h, w-3, 0);
|
|
fl_vertex(w, 0);
|
|
fl_vertex(w, h); fl_vertex(-w, h);
|
|
fl_end_loop();
|
|
fl_pop_matrix();
|
|
}
|
|
|
|
UnitTest complex_shapes(UT_TEST_COMPLEX_SHAPES, "Complex Shapes", Ut_Complex_Shapes_Test::create);
|