Chapter XXX - Drawing Things in FLTK

When can you draw things in FLTK?

There are only certain places you can execute drawing code in FLTK. Calling these functions at other places will result in undefined behavior!

FLTK Drawing functions
#include <FL/fl_draw.H>


Clipping

You can limit all your drawing to a rectangular region by calling fl_clip, and put the drawings back by using fl_pop_clip. This rectangle is measured in pixels (it is unaffected by the current transformation matrix).

In addition, the system may provide clipping when updating windows, this clip region may be more complex than a simple rectangle.

void fl_clip(int x, int y, int w, int h);

void fl_pop_clip();

int fl_not_clipped(int x, int y, int w, int h);

int fl_clip_box(int x, int y, int w, int h,
    int& X, int& Y, int& W, int& H);


Colors

void fl_color(Fl_Color);

Fl_Color fl_color();

void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);

void fl_color(uchar r, uchar g, uchar b);


Fast Shapes

These are used to draw almost all the FLTK widgets. They draw on exact pixel boundaries and are as fast as possible, and their behavior will be duplicated exactly on any platform FLTK is ported to. It is undefined whether these are affected by the transformation matrix, so you should only call these while it is the identity.

All arguments are integers.

void fl_rectf(x, y, w, h);

void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);

void fl_rect(x, y, w, h);

void fl_line(x, y, x1, y1);
void fl_line(x, y, x1, y1, x2, y2);

void fl_loop(x, y, x1, y1, x2, y2);
void fl_loop(x, y, x1, y1, x2, y2, x3, y3);

void fl_polygon(x, y, x1, y1, x2, y2);
void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);

void fl_xyline(x, y, x1, y1);
void fl_xyline(x, y, x1, y1, x2);
void fl_xyline(x, y, x1, y1, x2, y3);

void fl_yxline(x, y, y1);
void fl_yxline(x, y, y1, x2);
void fl_yxline(x, y, y1, x2, y3);

void fl_arc(x, y, w, h, double a1, double a2);
void fl_pie(x, y, w, h, double a1, double a2);
void fl_chord(x, y, w, h, double a1, double a2);


Complex Shapes

These functions let you draw arbitrary shapes with 2-D linear transformations. The functionality matches PostScript. The exact pixels filled in is less defined than for the above calls, so that FLTK can take advantage of drawing hardware. (Both Xlib and MSWindows round all the transformed verticies to integers before drawing the line segments. This severely limits the accuracy of these functions for complex graphics. Try using OpenGL instead)

All arguments are float.

void fl_push_matrix();
void fl_pop_matrix();

void fl_scale(x, y);
void fl_scale(x);
void fl_translate(x, y);
void fl_rotate(d);
void fl_mult_matrix(a, b, c, d, x, y);

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(x, y);

void fl_curve(int x,int y,int x1,int y1,int x2,int y2,int x3,int y3);

void fl_arc(x, y, r, start, end);

void fl_circle(x, y, r);


Text

All text is drawn in the current font. It is undefined whether this location or the characters are modified by the current transformation.

void fl_draw(const char*, float x, float y);
void fl_draw(const char*, int n, float x, float y);

void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);

void fl_measure(const char*, int& w, int& h);

int fl_height();

int fl_descent();

float fl_width(const char*);
float fl_width(const char*, int n);
float fl_width(uchar);

const char* fl_shortcut_label(ulong);


Fonts

void fl_font(int face, int size);

int fl_font();
int fl_size();

const char* Fl::get_font(int face);

const char* Fl::get_font_name(int face, int* attributes=0);

int get_font_sizes(int face, int*& sizep);

int Fl::set_font(int face, const char*);

int Fl::set_font(int face, int from);

int Fl::set_fonts(const char* = 0);


Bitmaps, Pixmaps and Images

Click here for information on drawing images

Cursor

void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);


Overlay rectangle

void fl_overlay_rect(int x, int y, int w, int h);
void fl_overlay_clear();

(back to contents) Drawing Images in FLTK

Drawing Images in FLTK

To draw images, you can either do it directly from data in your memory, or you can create Fl_Bitmap or Fl_Image or Fl_Pixmap objects. The advantage of drawing directly is that it is more intuitive, and it is faster if the image data changes more often than it is redrawn. The advantage of using the object is that FLTK will cache translated forms of the image (on X it uses a server pixmap) and thus redrawing it is much faster.


Direct Image Drawing
#include <FL/fl_draw.H>

It is undefined whether the location or drawing of the image is affected by the current transformation, so you should only call these when it is the identity.

All untyped arguments are integers.

void fl_draw_bitmap(const uchar*, X, Y, W, H, LD = 0);

void fl_draw_image(const uchar*, X, Y, W, H, D = 3, LD = 0);
void fl_draw_image_mono(const uchar*, X, Y, W, H, D = 1, LD = 0);

typedef void (*fl_draw_image_cb)(void*, x, y, w, uchar*);
void fl_draw_image(fl_draw_image_cb, void*, X, Y, W, H, D = 3);
void fl_draw_image_mono(fl_draw_image_cb, void*, X, Y, W, H, D = 1);

int fl_draw_pixmap(char** data, X, Y, Fl_Color=FL_GRAY);

int fl_measure_pixmap(char** data, int &w, int &h);


class Fl_Bitmap
#include <FL/Fl_Bitmap.H>

This object encapsulates the width, height, and bits of an Xbitmap (XBM), and allows you to make an Fl_Widget use a bitmap as a label, or to just draw the bitmap directly. Under X it will create an offscreen pixmap the first time it is drawn, and copy this each subsequent time it is drawn.

Fl_Bitmap(const char *bits, int W, int H);
Fl_Bitmap(const uchar *bits, int W, int H);

Construct from an Xbitmap. The bits pointer is simply copied to the object, so it must point at persistent storage. I provide two constructors because various X implementations disagree about the type of bitmap data. To use an XBM file, #include "foo.xbm", and then do "new Fl_Bitmap(foo_bits,foo_width,foo_height)"

~Fl_Bitmap()

The destructor will destroy any X pixmap created. It does not do anything to the bits data.

void draw(int x, int y, int w, int h, int ox=0, int oy=0);

x,y,w,h indicates a destination rectangle. ox,oy,w,h is a source rectangle. This source rectangle from the bitmap is drawn in the destination. 1 bits are drawn with the current color, 0 bits are unchanged. The source rectangle may extend outside the bitmap (i.e. ox and oy may be negative and w and h may be bigger than the bitmap) and this area is left unchanged.

void draw(int x, int y);

Draws the bitmap with the upper-left corner at x,y. This is the same as doing draw(x,y,this->w,this->h,0,0).

void label(Fl_Widget *);

Change the label() and the labeltype() of the widget to draw the bitmap. 1 bits will be drawn with the labelcolor(), zero bits will be unchanged. You can use the same bitmap for many widgets.


class Fl_Pixmap
#include <FL/Fl_Pixmap.H>

This object encapsulates the data from an XPM image, and allows you to make an Fl_Widget use a pixmap as a label, or to just draw the pixmap directly. Under X it will create an offscreen pixmap the first time it is drawn, and copy this each subsequent time it is drawn.

The current implementation converts the pixmap to 8 bit color data and uses fl_draw_image() to draw it. Thus you will get dithered colors on an 8 bit screen.

Fl_Pixmap(char * const * data);

Construct from XPM data. The data pointer is simply copied to the object, so it must point at persistent storage. To use an XPM file, #include "foo.xpm", and then do "new Fl_Pixmap(foo)"

~Fl_Pixmap()

The destructor will destroy any X pixmap created. It does not do anything to the data.

void draw(int x, int y, int w, int h, int ox=0, int oy=0);

x,y,w,h indicates a destination rectangle. ox,oy,w,h is a source rectangle. This source rectangle is copied to the destination. The source rectangle may extend outside the pixmap (i.e. ox and oy may be negative and w and h may be bigger than the pixmap) and this area is left unchanged.

void draw(int x, int y);

Draws the image with the upper-left corner at x,y. This is the same as doing draw(x,y,this->w,this->h,0,0).

void label(Fl_Widget *);

Change the label() and the labeltype() of the widget to draw the pixmap. You can use the same pixmap for many widgets.


class Fl_Image
#include <FL/Fl_Image.H>

This object encapsulates a full-color RGB image, and allows you to make an Fl_Widget use a Image as a label, or to just draw the Image directly. Under X it will create an offscreen pixmap the first time it is drawn, and copy this each subsequent time it is drawn.

See fl_draw_image() for what happens. On 8 bit screens dithering is used.

Fl_Image(char uchar *data, int W, int H, int D=3, int LD=0);

Construct from a pointer to RGB data. W and H are the size of the image in pixels. D is the delta between pixels (it may be more than 3 to skip alpha or other data, or negative to flip the image left/right). LD is the delta between lines (it may be more than D*W to crop images, or negative to flip the image vertically). The data pointer is simply copied to the object, so it must point at persistent storage.

~Fl_Image()

The destructor will destroy any X pixmap created. It does not do anything to the data.

void draw(int x, int y, int w, int h, int ox=0, int oy=0);

x,y,w,h indicates a destination rectangle. ox,oy,w,h is a source rectangle. This source rectangle is copied to the destination. The source rectangle may extend outside the image (i.e. ox and oy may be negative and w and h may be bigger than the image) and this area is left unchanged.

void draw(int x, int y);

Draws the image with the upper-left corner at x,y. This is the same as doing draw(x,y,this->w,this->h,0,0).

void label(Fl_Widget *);

Change the label() and the labeltype() of the widget to draw the Image. You can use the same Image for many widgets.

(back to contents) FLTK enhancements to the XPM format

FLTK enhancements to the XPM format

I made some additions to XPM that may be good, or intensely disliked by X purists. I do not know if the changes are compatable with current XPM.

The change was to make a "compressed colormap" that avoids XParseColor(), and gives the actual color values (which is really what everybody wants!). Only colormaps of this form, and ones where the colors are named as "#rrggbb", will be portable to non-X platforms.

A compressed colormap is indicated by the number of colors being negative. The colormap is then given as an array of 4*numcolors characters. Each color is described by 4 characters: the index character, and the red, green, and blue value (for 2-character indexes each color needs 5 characters).

XPM files support a single transparent index. I require this index to be ' ' (space). To indicate that ' ' is transparent, it should be first in the color table. To make ' ' not be transparent, put it somewhere other than first in the table.

To make the XPM files easily parseable, but still portable to most C compilers, I suggest the following format:

/* XPM */
static char * name[] = {
/* width height ncolors chars_per_pixel */
"64 64 -4 1 ",
/* colormap */
"\
 \x50\x50\x80\
.\xff\xff\x00\
r\xff\x00\x00\
b\x00\x00\x00",
/* pixels */
"        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb        ",
"        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb        ",
"        bb............................................bb        ",
...

All lines starting with "/*" are optional. Parsers should handle '\' at the end of the line and \xNN and \NNN characters. This requires the C compiler to parse \xNN characters.

Chapter XXX - Drawing Things in FLTK

When can you draw things in FLTK?

There are only certain places you can execute drawing code in FLTK. Calling these functions at other places will result in undefined behavior!

FLTK Drawing functions
#include <FL/fl_draw.H>


Clipping

You can limit all your drawing to a rectangular region by calling fl_clip, and put the drawings back by using fl_pop_clip. This rectangle is measured in pixels (it is unaffected by the current transformation matrix).

In addition, the system may provide clipping when updating windows, this clip region may be more complex than a simple rectangle.

void fl_clip(int x, int y, int w, int h);

void fl_pop_clip();

int fl_not_clipped(int x, int y, int w, int h);

int fl_clip_box(int x, int y, int w, int h,
    int& X, int& Y, int& W, int& H);


Colors

void fl_color(Fl_Color);

Fl_Color fl_color();

void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);

void fl_color(uchar r, uchar g, uchar b);


Fast Shapes

These are used to draw almost all the FLTK widgets. They draw on exact pixel boundaries and are as fast as possible, and their behavior will be duplicated exactly on any platform FLTK is ported to. It is undefined whether these are affected by the transformation matrix, so you should only call these while it is the identity.

All arguments are integers.

void fl_rectf(x, y, w, h);

void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);

void fl_rect(x, y, w, h);

void fl_line(x, y, x1, y1);
void fl_line(x, y, x1, y1, x2, y2);

void fl_loop(x, y, x1, y1, x2, y2);
void fl_loop(x, y, x1, y1, x2, y2, x3, y3);

void fl_polygon(x, y, x1, y1, x2, y2);
void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);

void fl_xyline(x, y, x1, y1);
void fl_xyline(x, y, x1, y1, x2);
void fl_xyline(x, y, x1, y1, x2, y3);

void fl_yxline(x, y, y1);
void fl_yxline(x, y, y1, x2);
void fl_yxline(x, y, y1, x2, y3);

void fl_arc(x, y, w, h, double a1, double a2);
void fl_pie(x, y, w, h, double a1, double a2);
void fl_chord(x, y, w, h, double a1, double a2);


Complex Shapes

These functions let you draw arbitrary shapes with 2-D linear transformations. The functionality matches PostScript. The exact pixels filled in is less defined than for the above calls, so that FLTK can take advantage of drawing hardware. (Both Xlib and MSWindows round all the transformed verticies to integers before drawing the line segments. This severely limits the accuracy of these functions for complex graphics. Try using OpenGL instead)

All arguments are float.

void fl_push_matrix();
void fl_pop_matrix();

void fl_scale(x, y);
void fl_scale(x);
void fl_translate(x, y);
void fl_rotate(d);
void fl_mult_matrix(a, b, c, d, x, y);

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(x, y);

void fl_curve(int x,int y,int x1,int y1,int x2,int y2,int x3,int y3);

void fl_arc(x, y, r, start, end);

void fl_circle(x, y, r);


Text

All text is drawn in the current font. It is undefined whether this location or the characters are modified by the current transformation.

void fl_draw(const char*, float x, float y);
void fl_draw(const char*, int n, float x, float y);

void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);

void fl_measure(const char*, int& w, int& h);

int fl_height();

int fl_descent();

float fl_width(const char*);
float fl_width(const char*, int n);
float fl_width(uchar);

const char* fl_shortcut_label(ulong);


Fonts

void fl_font(int face, int size);

int fl_font();
int fl_size();

const char* Fl::get_font(int face);

const char* Fl::get_font_name(int face, int* attributes=0);

int get_font_sizes(int face, int*& sizep);

int Fl::set_font(int face, const char*);

int Fl::set_font(int face, int from);

int Fl::set_fonts(const char* = 0);


Bitmaps, Pixmaps and Images

Click here for information on drawing images

Cursor

void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);


Overlay rectangle

void fl_overlay_rect(int x, int y, int w, int h);
void fl_overlay_clear();

(back to contents)