mirror of
https://github.com/fltk/fltk.git
synced 2026-05-20 04:31:25 +08:00
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.
This commit is contained in:
@@ -1063,6 +1063,7 @@ int main() {
|
||||
|
||||
// color map:
|
||||
static void set_color(Fl_Color, uchar, uchar, uchar);
|
||||
static void set_color(Fl_Color, uchar, uchar, uchar, uchar);
|
||||
/**
|
||||
Sets an entry in the fl_color index table. You can set it to any
|
||||
8-bit RGB color. The color is not allocated until fl_color(i) is used.
|
||||
@@ -1070,6 +1071,7 @@ int main() {
|
||||
static void set_color(Fl_Color i, unsigned c); // platform dependent
|
||||
static unsigned get_color(Fl_Color i);
|
||||
static void get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue);
|
||||
static void get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue, uchar &alpha);
|
||||
/**
|
||||
Frees the specified color from the colormap, if applicable.
|
||||
If overlay is non-zero then the color is freed from the
|
||||
|
||||
@@ -67,7 +67,9 @@ class FL_EXPORT Fl_Gl_Window : public Fl_Window {
|
||||
int mode(int, const int *);
|
||||
static int gl_plugin_linkage();
|
||||
protected:
|
||||
void draw_begin();
|
||||
virtual void draw();
|
||||
void draw_end();
|
||||
|
||||
public:
|
||||
void show();
|
||||
|
||||
@@ -257,6 +257,75 @@ adhere to for maximum portability:
|
||||
Do \e not call \p gl_start() or
|
||||
\p gl_finish() when drawing into an Fl_Gl_Window !
|
||||
|
||||
|
||||
\section opengl_with_fltk_widgets Using FLTK widgets in OpenGL Windows
|
||||
|
||||
FLTK widgets can be added to `Fl_Gl_Window`s just as they would be added to
|
||||
`Fl_Window`s. They are rendered as an overlay over the user defined
|
||||
OpenGL graphics using 'fl_..' graphics calls that are implemented in GL.
|
||||
|
||||
`Fl_Gl_Window` does not add subsequent widgets as children by default as
|
||||
`Fl_Window` does. Call `myGlWindow->begin()` after creating the GL window to
|
||||
automatically add following widgets. Remember to call `myGlWindow->end()`.
|
||||
|
||||
\code
|
||||
class My_Gl_Window : public Fl_Gl_Window {
|
||||
...
|
||||
void draw();
|
||||
...
|
||||
};
|
||||
|
||||
...
|
||||
myGlWindow = new My_Gl_Window(0, 0, 500, 500);
|
||||
myGlWindow->begin();
|
||||
myButton = new Fl_Button(10, 10, 120, 24, "Hello!");
|
||||
myGlWindow->end();
|
||||
...
|
||||
|
||||
void My_Gl_Window::draw() {
|
||||
// ... user GL drawing code
|
||||
Fl_Gl_Window::draw(); // Draw FLTK child widgets.
|
||||
}
|
||||
\endcode
|
||||
|
||||
Users can draw into the overlay by using GL graphics calls as well as all
|
||||
`fl_...` graphics calls from the "Drawing Fast Shapes" section.
|
||||
|
||||
\code
|
||||
void My_Gl_Window::draw() {
|
||||
// ... user GL drawing code
|
||||
Fl_Gl_Window::draw_begin(); // Set up 1:1 projection
|
||||
Fl_Window::draw(); // Draw FLTK children
|
||||
fl_color(FL_RED);
|
||||
fl_rect(10, 10, 100, 100);
|
||||
Fl_Gl_Window::draw_end(); // Restore GL state
|
||||
}
|
||||
\endcode
|
||||
|
||||
Widgets can be drawn with transparencies by assigning an alpha value to a
|
||||
colormap entry and using that color in the widget.
|
||||
|
||||
\code
|
||||
Fl::set_color(FL_FREE_COLOR, 255, 255, 0, 127); // 50% transparent yellow
|
||||
myGlWindow = new My_Gl_Window(0, 0, 500, 500);
|
||||
myGlWindow->begin();
|
||||
myButton = new Fl_Button(10, 10, 120, 24, "Hello!");
|
||||
myButton->box(FL_BORDER_BOX);
|
||||
myButton->color(FL_FREE_COLOR);
|
||||
myGlWindow->end();
|
||||
\endcode
|
||||
|
||||
Transparencies can also be set directly when drawing. This can be used to
|
||||
create custom box types and RGB overlay drawings with an alpha channel.
|
||||
|
||||
\code
|
||||
fl_color(0, 255, 0, 127); // 50% transparent green
|
||||
fl_rectf(10, 10, 100, 100);
|
||||
fl_color(FL_RED); // back to opaque red
|
||||
fl_rect(20, 20, 80, 80);
|
||||
\endcode
|
||||
|
||||
|
||||
\section opengl_drawing OpenGL Drawing Functions
|
||||
|
||||
FLTK provides some useful OpenGL drawing functions. They can
|
||||
|
||||
+65
-21
@@ -26,6 +26,7 @@ extern int fl_gl_load_plugin;
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
#include <FL/fl_utf8.h>
|
||||
#include "drivers/OpenGL/Fl_OpenGL_Display_Device.H"
|
||||
#include "drivers/OpenGL/Fl_OpenGL_Graphics_Driver.H"
|
||||
|
||||
#include <stdlib.h>
|
||||
# if (HAVE_DLSYM && HAVE_DLFCN_H)
|
||||
@@ -337,6 +338,53 @@ void Fl_Gl_Window::init() {
|
||||
void Fl_Gl_Window::draw_overlay() {}
|
||||
|
||||
|
||||
void Fl_Gl_Window::draw_begin() {
|
||||
Fl_Surface_Device::push_current( Fl_OpenGL_Display_Device::display_device() );
|
||||
Fl_OpenGL_Graphics_Driver *drv = (Fl_OpenGL_Graphics_Driver*)fl_graphics_driver;
|
||||
drv->pixels_per_unit_ = pixels_per_unit();
|
||||
|
||||
if (!valid()) {
|
||||
glViewport(0, 0, pixel_w(), pixel_h());
|
||||
valid(1);
|
||||
}
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glPushAttrib(GL_TRANSFORM_BIT);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
// glOrtho(-0.5, w()-0.5, h()-0.5, -0.5, -1, 1);
|
||||
glOrtho(0.0, w(), h(), 0.0, -1.0, 1.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
glLineWidth((GLfloat)(drv->pixels_per_unit_*drv->line_width_));
|
||||
glPointSize((GLfloat)(drv->pixels_per_unit_));
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
// TODO: all of the settings should be saved on the GL stack
|
||||
}
|
||||
|
||||
void Fl_Gl_Window::draw_end() {
|
||||
glMatrixMode(GL_MODELVIEW_MATRIX);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glPopAttrib(); // GL_TRANSFORM_BIT
|
||||
glPopAttrib(); // GL_ENABLE_BIT
|
||||
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
|
||||
/** Draws the Fl_Gl_Window.
|
||||
You \e \b must subclass Fl_Gl_Window and provide an implementation for
|
||||
draw(). You may also provide an implementation of draw_overlay()
|
||||
@@ -389,32 +437,28 @@ void Fl_Gl_Window::draw_overlay() {}
|
||||
}
|
||||
\endcode
|
||||
|
||||
Regular FLTK widgets can be added as children to the Fl_Gl_Window. To
|
||||
correctly overlay the widgets, Fl_Gl_Window::draw() must be called after
|
||||
rendering the main scene.
|
||||
\code
|
||||
void mywindow::draw() {
|
||||
// draw 3d graphics scene
|
||||
Fl_Gl_Window::draw();
|
||||
// -- or --
|
||||
draw_begin();
|
||||
Fl_Window::draw();
|
||||
// other 2d drawing calls, overlays, etc.
|
||||
draw_end();
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
void Fl_Gl_Window::draw() {
|
||||
Fl_Surface_Device::push_current( Fl_OpenGL_Display_Device::display_device() );
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
GLint viewport[4];
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
if (viewport[2] != pixel_w() || viewport[3] != pixel_h()) {
|
||||
glViewport(0, 0, pixel_w(), pixel_h());
|
||||
}
|
||||
glOrtho(-0.5, w()-0.5, h()-0.5, -0.5, -1, 1);
|
||||
// glOrtho(0, w(), h(), 0, -1, 1);
|
||||
glLineWidth((GLfloat)pixels_per_unit()); // should be 1 or 2 (2 if highres OpenGL)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // FIXME: push on state stack
|
||||
glEnable(GL_BLEND); // FIXME: push on state stack
|
||||
|
||||
draw_begin();
|
||||
Fl_Window::draw();
|
||||
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
Fl_Surface_Device::pop_current();
|
||||
draw_end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Handle some FLTK events as needed.
|
||||
*/
|
||||
|
||||
@@ -24,12 +24,20 @@
|
||||
#define FL_OPENGL_GRAPHICS_DRIVER_H
|
||||
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
/**
|
||||
\brief OpenGL specific graphics class.
|
||||
*/
|
||||
class FL_EXPORT Fl_OpenGL_Graphics_Driver : public Fl_Graphics_Driver {
|
||||
public:
|
||||
float pixels_per_unit_;
|
||||
float line_width_;
|
||||
int line_stipple_;
|
||||
Fl_OpenGL_Graphics_Driver() :
|
||||
pixels_per_unit_(1.0f),
|
||||
line_width_(1.0f),
|
||||
line_stipple_(FL_SOLID) { }
|
||||
// --- line and polygon drawing with integer coordinates
|
||||
void point(int x, int y);
|
||||
void rect(int x, int y, int w, int h);
|
||||
@@ -46,10 +54,17 @@ public:
|
||||
void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void focus_rect(int x, int y, int w, int h);
|
||||
// ---- clipping
|
||||
void push_clip(int x, int y, int w, int h);
|
||||
int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
|
||||
int not_clipped(int x, int y, int w, int h);
|
||||
void pop_clip();
|
||||
void push_no_clip();
|
||||
Fl_Region clip_region();
|
||||
void clip_region(Fl_Region r);
|
||||
void restore_clip();
|
||||
int not_clipped(int x, int y, int w, int h);
|
||||
int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
|
||||
// ---- matrix transformed drawing
|
||||
void transformed_vertex(double xf, double yf);
|
||||
void begin_points();
|
||||
void end_points();
|
||||
|
||||
@@ -27,20 +27,21 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <FL/math.h>
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) {
|
||||
if (w <= 0 || h <= 0) return;
|
||||
while (a2<a1) a2 += 360.0; // TODO: write a sensible fmod angle alignment here
|
||||
a1 = a1/180.0f*M_PI; a2 = a2/180.0f*M_PI;
|
||||
double cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
|
||||
double rMax; if (w<h) rMax = h/2; else rMax = w/2;
|
||||
a1 = a1/180.0*M_PI; a2 = a2/180.0*M_PI;
|
||||
double cx = x + 0.5*w, cy = y + 0.5*h;
|
||||
double rx = 0.5*w-0.3, ry = 0.5*h-0.3;
|
||||
double rMax; if (w>h) rMax = rx; else rMax = ry;
|
||||
int nSeg = (int)(10 * sqrt(rMax))+1;
|
||||
double incr = (a2-a1)/(double)nSeg;
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i=0; i<nSeg; i++) {
|
||||
glVertex2d(cx+cos(a1)*rMax, cy-sin(a1)*rMax);
|
||||
for (int i=0; i<=nSeg; i++) {
|
||||
glVertex2d(cx+cos(a1)*rx, cy-sin(a1)*ry);
|
||||
a1 += incr;
|
||||
}
|
||||
glEnd();
|
||||
@@ -53,16 +54,17 @@ void Fl_OpenGL_Graphics_Driver::arc(double x, double y, double r, double start,
|
||||
void Fl_OpenGL_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
|
||||
if (w <= 0 || h <= 0) return;
|
||||
while (a2<a1) a2 += 360.0; // TODO: write a sensible fmod angle alignment here
|
||||
a1 = a1/180.0f*M_PI; a2 = a2/180.0f*M_PI;
|
||||
double cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
|
||||
double rMax; if (w<h) rMax = h/2; else rMax = w/2;
|
||||
a1 = a1/180.0*M_PI; a2 = a2/180.0*M_PI;
|
||||
double cx = x + 0.5*w, cy = y + 0.5*h;
|
||||
double rx = 0.5*w, ry = 0.5*h;
|
||||
double rMax; if (w>h) rMax = rx; else rMax = ry;
|
||||
int nSeg = (int)(10 * sqrt(rMax))+1;
|
||||
double incr = (a2-a1)/(double)nSeg;
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2d(cx, cy);
|
||||
for (int i=0; i<nSeg+1; i++) {
|
||||
glVertex2d(cx+cos(a1)*rMax, cy-sin(a1)*rMax);
|
||||
for (int i=0; i<=nSeg; i++) {
|
||||
glVertex2d(cx+cos(a1)*rx, cy-sin(a1)*ry);
|
||||
a1 += incr;
|
||||
}
|
||||
glEnd();
|
||||
|
||||
@@ -30,41 +30,21 @@
|
||||
|
||||
// Implementation of fl_color(i), fl_color(r,g,b).
|
||||
|
||||
extern unsigned fl_cmap[256]; // defined in fl_color.cxx
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::color(Fl_Color i) {
|
||||
// FIXME: do we need the code below?
|
||||
/*
|
||||
#if HAVE_GL_OVERLAY
|
||||
#if defined(_WIN32)
|
||||
if (fl_overlay && fl_overlay_depth) {
|
||||
if (fl_overlay_depth < 8) {
|
||||
// only black & white produce the expected colors. This could
|
||||
// be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
|
||||
int size = 1<<fl_overlay_depth;
|
||||
if (!i) glIndexi(size-2);
|
||||
else if (i >= size-2) glIndexi(size-1);
|
||||
else glIndexi(i);
|
||||
} else {
|
||||
glIndexi(i ? i : FL_GRAY_RAMP);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
if (i & 0xffffff00) {
|
||||
unsigned rgb = (unsigned)i;
|
||||
color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
|
||||
} else {
|
||||
unsigned rgba = ((unsigned)i)^0x000000ff;
|
||||
Fl_Graphics_Driver::color(i);
|
||||
uchar red, green, blue;
|
||||
Fl::get_color(i, red, green, blue);
|
||||
glColor3ub(red, green, blue);
|
||||
glColor4ub(rgba>>24, rgba>>16, rgba>>8, rgba);
|
||||
} else {
|
||||
unsigned rgba = ((unsigned)fl_cmap[i])^0x000000ff;
|
||||
Fl_Graphics_Driver::color(fl_cmap[i]);
|
||||
glColor4ub(rgba>>24, rgba>>16, rgba>>8, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::color(uchar r,uchar g,uchar b) {
|
||||
void Fl_OpenGL_Graphics_Driver::color(uchar r, uchar g, uchar b) {
|
||||
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
||||
glColor3ub(r,g,b);
|
||||
}
|
||||
|
||||
@@ -31,27 +31,41 @@
|
||||
// OpenGL implementation does not support cap and join types
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::line_style(int style, int width, char* dashes) {
|
||||
|
||||
if (width<1) width = 1;
|
||||
line_width_ = width;
|
||||
|
||||
if (style==FL_SOLID) {
|
||||
int stipple = style & 0x00ff;
|
||||
line_stipple_ = stipple;
|
||||
// int cap = style & 0x0f00;
|
||||
// int join = style & 0xf000;
|
||||
|
||||
if (stipple==FL_SOLID) {
|
||||
glLineStipple(1, 0xFFFF);
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
} else {
|
||||
switch (style) {
|
||||
char enable = 1;
|
||||
switch (stipple & 0x00ff) {
|
||||
case FL_DASH:
|
||||
glLineStipple(width, 0x0F0F); // ....****....****
|
||||
glLineStipple(pixels_per_unit_*line_width_, 0x0F0F); // ....****....****
|
||||
break;
|
||||
case FL_DOT:
|
||||
glLineStipple(width, 0x5555); // .*.*.*.*.*.*.*.*
|
||||
glLineStipple(pixels_per_unit_*line_width_, 0x5555); // .*.*.*.*.*.*.*.*
|
||||
break;
|
||||
case FL_DASHDOT:
|
||||
glLineStipple(width, 0x2727); // ..*..***..*..***
|
||||
glLineStipple(pixels_per_unit_*line_width_, 0x2727); // ..*..***..*..***
|
||||
break;
|
||||
case FL_DASHDOTDOT:
|
||||
glLineStipple(width, 0x5757); // .*.*.***.*.*.***
|
||||
glLineStipple(pixels_per_unit_*line_width_, 0x5757); // .*.*.***.*.*.***
|
||||
break;
|
||||
default:
|
||||
glLineStipple(1, 0xFFFF);
|
||||
enable = 0;
|
||||
}
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
if (enable)
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
else
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
glLineWidth( (GLfloat)(pixels_per_unit_ * line_width_) );
|
||||
glPointSize( (GLfloat)(pixels_per_unit_) );
|
||||
}
|
||||
|
||||
@@ -26,105 +26,109 @@
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_RGB_Image.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/math.h>
|
||||
|
||||
// --- line and polygon drawing with integer coordinates
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::point(int x, int y) {
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2i(x, y);
|
||||
glVertex2f(x+0.5f, y+0.5f);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::rect(int x, int y, int w, int h) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x+w, y);
|
||||
glVertex2i(x+w, y+h);
|
||||
glVertex2i(x, y+h);
|
||||
glEnd();
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x+0.5f, yy = y+0.5f;
|
||||
float rr = x+w-0.5f, bb = y+h-0.5f;
|
||||
glRectf(xx-offset, yy-offset, rr+offset, yy+offset);
|
||||
glRectf(xx-offset, bb-offset, rr+offset, bb+offset);
|
||||
glRectf(xx-offset, yy-offset, xx+offset, bb+offset);
|
||||
glRectf(rr-offset, yy-offset, rr+offset, bb+offset);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::rectf(int x, int y, int w, int h) {
|
||||
if (w<=0 || h<=0) return;
|
||||
// OpenGL has the natural origin at the bottom left. Drawing in FLTK
|
||||
// coordinates requires that we shift the rectangle one pixel up.
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2i(x, y-1);
|
||||
glVertex2i(x+w, y-1);
|
||||
glVertex2i(x+w, y+h-1);
|
||||
glVertex2i(x, y+h-1);
|
||||
glEnd();
|
||||
glRectf(x, y, x+w, y+h);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::line(int x, int y, int x1, int y1) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x1, y1);
|
||||
glEnd();
|
||||
point(x1, y1);
|
||||
if (x==x1 && y==y1) return;
|
||||
if (x==x1) {
|
||||
yxline(x, y, y1);
|
||||
return;
|
||||
}
|
||||
if (y==y1) {
|
||||
xyline(x, y, x1);
|
||||
return;
|
||||
}
|
||||
float xx = x+0.5f, xx1 = x1+0.5f;
|
||||
float yy = y+0.5f, yy1 = y1+0.5f;
|
||||
if (line_width_==1.0f) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2f(xx, yy);
|
||||
glVertex2f(xx1, yy1);
|
||||
glEnd();
|
||||
} else {
|
||||
float dx = xx1-xx, dy = yy1-yy;
|
||||
float len = sqrtf(dx*dx+dy*dy);
|
||||
dx = dx/len*line_width_*0.5f;
|
||||
dy = dy/len*line_width_*0.5f;
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2f(xx-dy, yy+dx);
|
||||
glVertex2f(xx+dy, yy-dx);
|
||||
glVertex2f(xx1-dy, yy1+dx);
|
||||
glVertex2f(xx1+dy, yy1-dx);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x1, y1);
|
||||
glVertex2i(x2, y2);
|
||||
glEnd();
|
||||
point(x2, y2);
|
||||
// TODO: no corner types (miter) yet
|
||||
line(x, y, x1, y1);
|
||||
line(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x1, y);
|
||||
glEnd();
|
||||
point(x1, y);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x, yy = y+0.5f, rr = x1+1.0f;
|
||||
glRectf(xx, yy-offset, rr, yy+offset);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x1, y);
|
||||
glVertex2i(x1, y2);
|
||||
glEnd();
|
||||
point(x1, y2);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x, yy = y+0.5f, rr = x1+0.5f, bb = y2+1.0f;
|
||||
glRectf(xx, yy-offset, rr+offset, yy+offset);
|
||||
glRectf(rr-offset, yy+offset, rr+offset, bb);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x1, y);
|
||||
glVertex2i(x1, y2);
|
||||
glVertex2i(x3, y2);
|
||||
glEnd();
|
||||
point(x3, y2);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x, yy = y+0.5f, xx1 = x1+0.5f, rr = x3+1.0f, bb = y2+0.5;
|
||||
glRectf(xx, yy-offset, xx1+offset, yy+offset);
|
||||
glRectf(xx1-offset, yy+offset, xx1+offset, bb+offset);
|
||||
glRectf(xx1+offset, bb-offset, rr, bb+offset);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x, y1);
|
||||
glEnd();
|
||||
point(x, y1);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x+0.5f, yy = y, bb = y1+1.0f;
|
||||
glRectf(xx-offset, yy, xx+offset, bb);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x, y1);
|
||||
glVertex2i(x2, y1);
|
||||
glEnd();
|
||||
point(x2, y1);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x+0.5f, yy = y, rr = x2+1.0f, bb = y1+0.5f;
|
||||
glRectf(xx-offset, yy, xx+offset, bb+offset);
|
||||
glRectf(xx+offset, bb-offset, rr, bb+offset);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x, y1);
|
||||
glVertex2i(x2, y1);
|
||||
glVertex2i(x2, y3);
|
||||
glEnd();
|
||||
point(x2, y3);
|
||||
float offset = line_width_ / 2.0f;
|
||||
float xx = x+0.5f, yy = y, yy1 = y1+0.5f, rr = x2+0.5f, bb = y3+1.0f;
|
||||
glRectf(xx-offset, yy, xx+offset, yy1+offset);
|
||||
glRectf(xx+offset, yy1-offset, rr+offset, yy1+offset);
|
||||
glRectf(rr-offset, yy1+offset, rr+offset, bb);
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
|
||||
@@ -161,24 +165,197 @@ void Fl_OpenGL_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2,
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
|
||||
float width = line_width_;
|
||||
int stipple = line_stipple_;
|
||||
line_style(FL_DOT, 1);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(x+0.5f, y+0.5f);
|
||||
glVertex2f(x+w+0.5f, y+0.5f);
|
||||
glVertex2f(x+w+0.5f, y+h+0.5f);
|
||||
glVertex2f(x+0.5f, y+h+0.5f);
|
||||
glEnd();
|
||||
line_style(stipple, width);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static int gl_min(int a, int b) { return (a<b) ? a : b; }
|
||||
static int gl_max(int a, int b) { return (a>b) ? a : b; }
|
||||
|
||||
enum {
|
||||
kStateFull, // Region is the full window
|
||||
kStateRect, // Region is a rectangle
|
||||
kStateEmpty // Region is an empty space
|
||||
};
|
||||
|
||||
typedef struct Fl_Gl_Region {
|
||||
int x, y, w, h;
|
||||
int gl_x, gl_y, gl_w, gl_h;
|
||||
char state;
|
||||
void set(int inX, int inY, int inW, int inH) {
|
||||
if (inW<=0 || inH<=0) {
|
||||
state = kStateEmpty;
|
||||
x = inX; y = inY; w = 1; h = 1; // or 0?
|
||||
} else {
|
||||
x = inX; y = inY; w = inW; h = inH;
|
||||
state = kStateRect;
|
||||
}
|
||||
Fl_Gl_Window *win = Fl_Gl_Window::current()->as_gl_window();
|
||||
if (win) {
|
||||
float scale = win->pixels_per_unit();
|
||||
gl_x = x*scale;
|
||||
gl_y = (win->h()-h-y+1)*scale;
|
||||
gl_w = (w-1)*scale;
|
||||
gl_h = (h-1)*scale;
|
||||
if (inX<=0 && inY<=0 && inX+inW>win->w() && inY+inH>=win->h()) {
|
||||
state = kStateFull;
|
||||
}
|
||||
} else {
|
||||
state = kStateFull;
|
||||
}
|
||||
}
|
||||
void set_full() { state = kStateFull; }
|
||||
void set_empty() { state = kStateEmpty; }
|
||||
void set_intersect(int inX, int inY, int inW, int inH, Fl_Gl_Region &g) {
|
||||
if (g.state==kStateFull) {
|
||||
set(inX, inY, inW, inH);
|
||||
} else if (g.state==kStateEmpty) {
|
||||
set_empty();
|
||||
} else {
|
||||
int rx = gl_max(inX, g.x);
|
||||
int ry = gl_max(inY, g.y);
|
||||
int rr = gl_min(inX+inW, g.x+g.w);
|
||||
int rb = gl_max(inY+inH, g.y+g.h);
|
||||
set(rx, ry, rr-rx, rb-ry);
|
||||
}
|
||||
}
|
||||
void apply() {
|
||||
if (state==kStateFull) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
glScissor(gl_x, gl_y, gl_w, gl_h);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
} Fl_Gl_Region;
|
||||
|
||||
static int gl_rstackptr = 0;
|
||||
static const int gl_region_stack_max = FL_REGION_STACK_SIZE - 1;
|
||||
static Fl_Gl_Region gl_rstack[FL_REGION_STACK_SIZE];
|
||||
|
||||
/*
|
||||
Intersect the given rect with the current rect, push the result on the stack,
|
||||
and apply the new clipping area.
|
||||
*/
|
||||
void Fl_OpenGL_Graphics_Driver::push_clip(int x, int y, int w, int h) {
|
||||
// TODO: implement OpenGL clipping
|
||||
if (rstackptr < region_stack_max) rstack[++rstackptr] = 0L;
|
||||
else Fl::warning("Fl_OpenGL_Graphics_Driver::push_clip: clip stack overflow!\n");
|
||||
if (gl_rstackptr==gl_region_stack_max) {
|
||||
Fl::warning("Fl_OpenGL_Graphics_Driver::push_clip: clip stack overflow!\n");
|
||||
return;
|
||||
}
|
||||
if (gl_rstackptr==0) {
|
||||
gl_rstack[gl_rstackptr].set(x, y, w, h);
|
||||
} else {
|
||||
gl_rstack[gl_rstackptr].set_intersect(x, y, w, h, gl_rstack[gl_rstackptr-1]);
|
||||
}
|
||||
gl_rstack[gl_rstackptr].apply();
|
||||
gl_rstackptr++;
|
||||
}
|
||||
|
||||
int Fl_OpenGL_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {
|
||||
// TODO: implement OpenGL clipping
|
||||
X = x; Y = y; W = w; H = h;
|
||||
return 0;
|
||||
/*
|
||||
Remove the current clipping area and apply the previous one on the stack.
|
||||
*/
|
||||
void Fl_OpenGL_Graphics_Driver::pop_clip() {
|
||||
if (gl_rstackptr==0) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
Fl::warning("Fl_OpenGL_Graphics_Driver::pop_clip: clip stack underflow!\n");
|
||||
return;
|
||||
}
|
||||
gl_rstackptr--;
|
||||
restore_clip();
|
||||
}
|
||||
|
||||
int Fl_OpenGL_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
|
||||
// TODO: implement OpenGL clipping
|
||||
return 1;
|
||||
/*
|
||||
Push a full area onton the stack, so no clipping will take place.
|
||||
*/
|
||||
void Fl_OpenGL_Graphics_Driver::push_no_clip() {
|
||||
if (gl_rstackptr==gl_region_stack_max) {
|
||||
Fl::warning("Fl_OpenGL_Graphics_Driver::push_no_clip: clip stack overflow!\n");
|
||||
return;
|
||||
}
|
||||
gl_rstack[gl_rstackptr].set_full();
|
||||
gl_rstack[gl_rstackptr].apply();
|
||||
gl_rstackptr++;
|
||||
}
|
||||
|
||||
/*
|
||||
We don't know the format of clip regions of the default driver, so return NULL.
|
||||
*/
|
||||
Fl_Region Fl_OpenGL_Graphics_Driver::clip_region() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
We don't know the format of clip regions of the default driver, so do the best
|
||||
we can.
|
||||
*/
|
||||
void Fl_OpenGL_Graphics_Driver::clip_region(Fl_Region r) {
|
||||
if (r==NULL) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
restore_clip();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Apply the current clipping rect.
|
||||
*/
|
||||
void Fl_OpenGL_Graphics_Driver::restore_clip() {
|
||||
// TODO: implement OpenGL clipping
|
||||
fl_clip_state_number++;
|
||||
if (gl_rstackptr==0) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
gl_rstack[gl_rstackptr-1].apply();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Does the rectangle intersect the current clip region?
|
||||
0 = regions don't intersect, nothing to draw
|
||||
1 = region is fully inside current clipping region
|
||||
2 = region is partially inside current clipping region
|
||||
*/
|
||||
int Fl_OpenGL_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
|
||||
if (gl_rstackptr==0)
|
||||
return 1;
|
||||
Fl_Gl_Region &g = gl_rstack[gl_rstackptr-1];
|
||||
if (g.state==kStateFull)
|
||||
return 1;
|
||||
if (g.state==kStateEmpty)
|
||||
return 0;
|
||||
int r = x+w, b = y + h;
|
||||
int gr = g.x+g.w, gb = g.y+g.h;
|
||||
if (r<=g.x || x>=gr || b<=g.y || y>=gb) return 0;
|
||||
if (x>=g.x && y>=g.y && r<=gr && b<=gb) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate the intersection of the given rect and the clipping area.
|
||||
Return 0 if the result did not change.
|
||||
*/
|
||||
int Fl_OpenGL_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {
|
||||
X = x; Y = y; W = w; H = h;
|
||||
if (gl_rstackptr==0)
|
||||
return 0;
|
||||
Fl_Gl_Region &g = gl_rstack[gl_rstackptr-1];
|
||||
if (g.state==kStateFull)
|
||||
return 0;
|
||||
int r = x+w, b = y + h;
|
||||
int gr = g.x+g.w, gb = g.y+g.h;
|
||||
X = gl_max(x, g.x);
|
||||
Y = gl_max(y, g.y);
|
||||
W = gl_min(r, gr) - X;
|
||||
H = gl_min(b, gb) - Y;
|
||||
return (x!=X || y!=Y || w!=W || h!=H);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,19 @@ void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) {
|
||||
((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8));
|
||||
}
|
||||
|
||||
/**
|
||||
Sets an entry in the fl_color index table.
|
||||
|
||||
You can set it to any 8-bit RGBA color.
|
||||
*/
|
||||
void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue, uchar alpha) {
|
||||
Fl::set_color((Fl_Color)(i & 255),
|
||||
((unsigned)red<<24)
|
||||
|((unsigned)green<<16)
|
||||
|((unsigned)blue<<8)
|
||||
|(alpha^0xff));
|
||||
}
|
||||
|
||||
|
||||
void Fl::set_color(Fl_Color i, unsigned c)
|
||||
{
|
||||
@@ -96,6 +109,26 @@ void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) {
|
||||
blue = uchar(c>>8);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the RGBA value(s) for the given FLTK color index.
|
||||
|
||||
This form returns the red, green, blue, and alpha values
|
||||
separately in referenced variables.
|
||||
|
||||
\see unsigned get_color(Fl_Color c)
|
||||
*/
|
||||
void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue, uchar &alpha) {
|
||||
unsigned c;
|
||||
|
||||
if (i & 0xffffff00) c = (unsigned)i;
|
||||
else c = fl_cmap[i];
|
||||
|
||||
red = uchar(c>>24);
|
||||
green = uchar(c>>16);
|
||||
blue = uchar(c>>8);
|
||||
alpha = uchar(c^0x000000ff);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the weighted average color between the two given colors.
|
||||
|
||||
|
||||
@@ -234,6 +234,16 @@ static void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) {
|
||||
gtk_color(c);
|
||||
draw(FILL, x, y, w, h, 2);
|
||||
|
||||
gtk_color(fl_color_average(FL_WHITE, c, 0.1f));
|
||||
draw(LOWER_RIGHT, x+1, y, w-2, h, 2);
|
||||
draw(LOWER_RIGHT, x, y, w, h, 3);
|
||||
gtk_color(fl_color_average(FL_WHITE, c, 0.2f));
|
||||
draw(LOWER_RIGHT, x+1, y, w-2, h, 1);
|
||||
draw(LOWER_RIGHT, x, y, w, h, 2);
|
||||
gtk_color(fl_color_average(FL_WHITE, c, 0.5f));
|
||||
draw(LOWER_RIGHT, x+1, y, w-2, h, 0);
|
||||
draw(LOWER_RIGHT, x, y, w, h, 1);
|
||||
|
||||
gtk_color(fl_color_average(FL_BLACK, c, 0.05f));
|
||||
draw(UPPER_LEFT, x, y, w, h, 2);
|
||||
draw(UPPER_LEFT, x+1, y, w-2, h, 1);
|
||||
|
||||
+20
-1
@@ -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)
|
||||
|
||||
|
||||
+40
-9
@@ -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)
|
||||
|
||||
+17
-1
@@ -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);
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
+184
-52
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
+279
-27
@@ -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:
|
||||
static Fl_Widget *create() {
|
||||
return new PointTest(TESTAREA_X, TESTAREA_Y, TESTAREA_W, TESTAREA_H);
|
||||
}
|
||||
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)!");
|
||||
align(FL_ALIGN_INSIDE|FL_ALIGN_BOTTOM|FL_ALIGN_LEFT|FL_ALIGN_WRAP);
|
||||
box(FL_BORDER_BOX);
|
||||
}
|
||||
PointTestWin(int x, int y, int w, int h) :
|
||||
Fl_Window(x, y, w, h) { end(); }
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
UnitTest points("drawing points", PointTest::create);
|
||||
#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_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_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(kTestPoints, "Drawing Points", PointTest::create);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+84
-118
@@ -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,130 +33,91 @@
|
||||
#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()
|
||||
|
||||
typedef void (*UnitTestCallback)(const char*,Fl_Group*);
|
||||
|
||||
class MainWindow *mainwin = 0;
|
||||
Fl_Hold_Browser *browser = 0;
|
||||
class 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;
|
||||
UnitTest::UnitTest(int index, const char *label, Fl_Widget* (*create)()) :
|
||||
fWidget(0L)
|
||||
{
|
||||
fLabel = fl_strdup(label);
|
||||
fCreate = create;
|
||||
add(index, this);
|
||||
}
|
||||
|
||||
static void add(UnitTest *t) {
|
||||
fTest[nTest] = t;
|
||||
nTest++;
|
||||
}
|
||||
static int nTest;
|
||||
static UnitTest *fTest[];
|
||||
};
|
||||
UnitTest::~UnitTest() {
|
||||
delete fWidget;
|
||||
free(fLabel);
|
||||
}
|
||||
|
||||
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];
|
||||
UnitTest *UnitTest::fTest[200] = { 0 };
|
||||
|
||||
MainWindow::MainWindow(int w, int h, const char *l) :
|
||||
Fl_Double_Window(w, h, l),
|
||||
fTestAlignment(0)
|
||||
{ }
|
||||
|
||||
// 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 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();
|
||||
}
|
||||
void draw() {
|
||||
Fl_Double_Window::draw();
|
||||
if (fTestAlignment) {
|
||||
drawAlignmentIndicators();
|
||||
}
|
||||
}
|
||||
void testAlignment(int v) {
|
||||
fTestAlignment = v;
|
||||
redraw();
|
||||
}
|
||||
int fTestAlignment;
|
||||
};
|
||||
}
|
||||
|
||||
void MainWindow::testAlignment(int v) {
|
||||
fTestAlignment = v;
|
||||
redraw();
|
||||
}
|
||||
|
||||
//------- include the various unit tests as inline code -------
|
||||
|
||||
#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"
|
||||
|
||||
// callback whenever the browser value changes
|
||||
void Browser_CB(Fl_Widget*, void*) {
|
||||
for ( int t=1; t<=browser->size(); t++ ) {
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user