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);
void fl_color(uchar);
Set the color for all subsequent drawing operations. Colors are identified by an 8-bit index. This is not the X pixel, it is an internal table! The table provides several general colors, a 24-entry gray ramp, and a 5x8x5 color cube. All of these are named with poorly-documented symbols in <FL/Enumerations.H>.
Under X, a color cell will be allocated out of fl_colormap each time you request an fl_color the first time. If the colormap fills up then a least-squares algorithim is used to find the closest color.
uchar fl_color();
void fl_color(uchar r, uchar g, uchar
b);
Set the color for all subsequent drawing operations. The closest possible match to the rgb color is used. Under X this works perfectly for TrueColor visuals. For colormap visuals the nearest index in the gray ramp or color cube is figured out, and fl_color(i) is done with that, this can result in two approximations of the color and is very inaccurate!
void Fl::set_color(uchar, uchar r, uchar g, uchar b);
void Fl::get_color(uchar, uchar &, uchar &, uchar &);
All arguments are integers.
If a complete circle is drawn it will fit inside the passed
bounding box. The two angles are measured in degrees counterclockwise
from 3'oclock and are the starting and ending angle of the arc, a2
must be greater or equal to a1.
fl_arc draws a 1-pixel thick line (notice this has a different
number of arguments than the fl_arc described
below.
fl_pie draws a filled-in pie slice. This slice may extend outside
the line drawn by fl_arc, to avoid this use w-1 and h-1.
All arguments are float.
fl_gap() should only be called between
fl_begin/end_complex_polygon(). To outline the polygon, use
fl_begin_loop() and replace each fl_gap() with
fl_end_loop();fl_begin_loop().
void fl_rectf(x, y, w, h);
Color a rectangle that exactly fills the given bounding box.
void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);
Color a rectangle with "exactly" the passed r,g,b color. On screens
with less than 24 bits of color this is done by drawing a
solid-colored block using fl_draw_image() so that dithering
is produced. If you have 24 bit color, this fills the rectangle with a
single pixel value and is about 1 zillion times faster.
void fl_rect(x, y, w, h);
Draw a 1-pixel border inside this bounding box.
void fl_line(x, y, x1, y1);
void fl_line(x, y, x1, y1, x2, y2);
Draw one or two 1-pixel thick lines between the given points.
void fl_loop(x, y, x1, y1, x2, y2);
void fl_loop(x, y, x1, y1, x2, y2, x3, y3);
Outline a 3 or 4-sided polygon with 1-pixel thick lines.
void fl_polygon(x, y, x1, y1, x2, y2);
void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
Fill a 3 or 4-sided polygon. The polygon must be convex.
void fl_xyline(x, y, x1, y1);
void fl_xyline(x, y, x1, y1, x2);
void fl_xyline(x, y, x1, y1, x2, y3);
Draw 1-pixel wide horizontal and vertical lines. A horizontal line is
drawn first, then a vertical, then a horizontal.
void fl_yxline(x, y, y1);
void fl_yxline(x, y, y1, x2);
void fl_yxline(x, y, y1, x2, y3);
Draw 1-pixel wide vertical and horizontal lines. A vertical line is
drawn first, then a horizontal, then a vertical.
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);
High-speed ellipse sections. These functions match the rather limited
circle drawing code provided by X and Windoze. The advantage over using fl_arc is that they are faster because they often use
the hardware, and they draw much nicer small circles, since the small
sizes are often hard-coded bitmaps.
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 Windoze 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)
void fl_push_matrix();
void fl_pop_matrix();
Save and restore the current transformation. The maximum depth of the
stack is 4.
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);
Concat another transformation to the current one. The rotation angle
is in degrees (not radians) counter-clockwise.
void fl_begin_line();
void fl_end_line();
Start and end drawing 1-pixel thick lines.
void fl_begin_loop();
void fl_end_loop();
Start and end drawing a closed sequence of 1-pixel thick lines.
void fl_begin_polygon();
void fl_end_polygon();
Start and end drawing a convex filled polygon.
void fl_begin_complex_polygon();
void fl_gap();
void fl_end_complex_polygon();
Start and end drawing a complex filled polygon. This polygon may be
concave, may have holes in it, or may be several disconnected pieces.
Call fl_gap() to seperate loops of the path (it is unnecessary but
harmless to call fl_gap() before the first vertex, after the last one,
or several times in a row). For portability, you should only draw
polygons that appear the same whether "even/odd" or "non-zero"
"winding rules" are used to fill them. This mostly means that holes
should be drawn in the opposite direction of the outside.
void fl_vertex(x, y);
Add a single vertex to the current path.
void fl_curve(int x,int y,int x1,int y1,int x2,int
y2,int x3,int y3);
Add a series of points on a Bezier curve to the path. The curve ends
(and two of the points) are at x,y and x3,y3.
void fl_arc(x, y, r, start, end);
Add a series of points to the current path on the arc of a circle (you
can get elliptical paths by using scale and rotate before calling
this). x,y are the center of the circle, and r is it's
radius. fl_arc() takes start and end angles that are
measured in degrees counter-clockwise from 3 o'clock. If end
is less than start then it draws clockwise.
void fl_circle(x, y, r);
fl_circle() is equivalent to fl_arc(...,0,360) but may be faster. It
must be the only thing in the path: if you want a circle as
part of a complex polygon you must use fl_arc(). Under Xlib and
Windoze this draws incorrectly if the transformation is both rotated
and non-square scaled.
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, uchar
align, uchar color);
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);
void fl_font(int face, int size);
The font is identified by a face and a size. The size of the font is measured in pixels (ie. it is not "resolution [in]dependent"). Lines should be spaced size pixels apart (or more).
The face is an index into an internal table. Initially only the first 16 faces are filled in. There are symbolic names for them: FL_HELVETICA, FL_TIMES, FL_COURIER, and modifier values FL_BOLD and FL_ITALIC which can be added to these, and FL_SYMBOL and FL_ZAPF_DINGBATS. Faces greater than 255 cannot be used in Fl_Widget labels, since it stores the index as a byte.
int fl_font();
int fl_size();
const char* Fl::get_font(int face);
const char* Fl::get_font_name(int face, int* attributes=0);
The integer pointed to by attributes (if the pointer is not
zero) is set to zero, FL_BOLD
(1) or
FL_ITALIC
(2) or FL_BOLD|FL_ITALIC
(maybe
more attributes will be defined in the future). To locate a "family"
of fonts, search forward and back for a set with non-zero attributes,
these faces along with the face with a zero attribute before them
constitute a family.
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);
The optional argument is a string to describe the set of fonts to add. Passing NULL will select only fonts that have the ISO8859-1 character set (and are thus usable by normal text). Passing "-*" will select all fonts with any encoding as long as they have normal X font names with dashes in them. Passing "*" will list every font that exists (on X this may produce some strange output). Other values may be useful but are system dependent. On Windoze NULL selects fonts with ISO8859-1 encoding and non-NULL selects all fonts.
Return value is how many faces are in the table after this is done.
void fl_cursor(uchar, uchar bg=FL_WHITE, uchar
fg=FL_BLACK);
The file <Enumerations.H> defines names for some cursors:
Under X you can get any XC_cursor value by
passing (XC_foo/2)+1
.
On X systems you can draw using any Xlib calls. Xlib requires a bunch of silly extra arguments, and fltk gives you values for all of these in static variables declared in <FL/x.H>:
extern Display* fl_display;
extern GC fl_gc;
extern Window fl_window;
extern int fl_screen;
extern XVisualInfo* fl_visual;
extern Colormap fl_colormap;
XDrawSomething(fl_display, fl_window, fl_gc, ...);
It may also be useful to refer to Fl_Window::current()
to get the window's size or position.
unsigned long fl_xpixel(uchar i);
unsigned long fl_xpixel(uchar r, uchar g, uchar
b);
On Win32 systems you can draw using any GDI calls. GDI requires a bunch of silly extra arguments, and fltk gives you values for all of these in static variables and functions declared in <FL/win32.H>:
extern HINSTANCE fl_display;
extern HWND fl_window;
extern HDC fl_gc;
COLORREF fl_RGB();
HPEN fl_pen();
HBRUSH fl_brush();
DrawSomething(fl_gc, ..., fl_brush());
It may also be useful to refer to Fl_Window::current()
to get the window's size or position.
OpenGL is poorly integrated into the drawing streams of current systems, so it works best if you specially construct windows for it by using Fl_Gl_Window and only use OpenGL to draw these. These windows provide a unique "OpenGL Context" and when draw() is called the OpenGL state is already set up.
It may be possible to use OpenGL to draw in any window by surrounding the code with these calls:
void gl_start();
void gl_finish();
You may want to use Fl_Window::current()->h()
to get
the drawable height so you can flip the coordinate system.
Do not use these when drawing an Fl_Gl_Window!
Fltk provides some extra gl drawing functions to draw characters,
rectangles, and arcs. See Fl_Gl_Window
for a list.
Big kludge to draw interactive selection rectangles without using
the overlay. Fltk will xor a single rectangle outline over a window.
Calling this will erase any previous rectangle (by xor'ing it), and
then draw the new one. Calling fl_overlay_clear() will erase the
rectangle without drawing a new one. Using this is tricky. You
should make a widget with both a handle() and draw() method. draw()
should call fl_overlay_clear() before doing anything else. Your
handle() method should call window()->make_current() and then
fl_overlay_rect() after FL_DRAG events, and should call
fl_overlay_clear() after a FL_RELEASE event.
Overlay rectangle
void fl_overlay_rect(int x, int y, int w, int h);
void fl_overlay_clear();