1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
|
<HTML>
<BODY>
<H1>Chapter XXX - Drawing Things in FLTK</H1>
<h2>When can you draw things in FLTK?</h2>
There are only certain places you can execute drawing code in FLTK.
Calling these functions at other places will result in undefined
behavior!
<ul>
<li>The most common is inside the virtual method <a
href=subclass.html#draw>Fl_Widget::draw()</a>. To write code here,
you must subclass one of the existing Fl_Widget classes and implement
your own version of draw().
<p>
<li>You can also write <a href=Boxtypes.html>boxtypes</a> and <a href
= Labeltypes.html>labeltypes</a>. These are small procedures that can be
called by existing Fl_Widget draw() methods. These "types" are
identified by an 8-bit index that is stored in the widget's box(),
labeltype(), and possibly other properties.
<p>
<li>You can call <a
href=Fl_Window.html#make_current>Fl_Window::make_current()</a> to do
incremental update of a widget (use <a
href=Fl_Widget.html#window>Fl_Widget::window()</a> to find the
window). <i>Under X this only works for the base Fl_Window class, not
for double buffered, overlay, or OpenGL windows!</i>
</ul>
</ul><h2>FLTK Drawing functions<br>#include <FL/fl_draw.H></h2>
<ul>
<li><a href=#clipping>Clipping</a>
<li><a href=#color>Colors</a>
<li><a href=#fast>Fast Shapes</a>
<li><a href=#vertex>Complex Shapes</a>
<li><a href=#text>Text</a>
<li><a href=images.html>Images</a>
<li><a href=#cursor>Cursor</a>
<li><a href=#overlay>Overlay</a>
<li><a href=Fl_Gl_Window.html#gl_start>Using OpenGL</a>
</ul>
</ul><hr><h3>Clipping</h3>
<p>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).
<p>In addition, the system may provide clipping when updating windows,
this clip region may be more complex than a simple rectangle.
</ul><h4><code>void fl_clip(int x, int y, int w, int h);</code></h4><ul>
Intesect the current clip region with a rectangle and push this new
region onto the stack.
</ul><h4><code>void fl_pop_clip();</code></h4><ul>
Restore the previous clip region. <i>You must call fl_pop_clip() once
for every time you call fl_clip(). If you return to FLTK with the
clip stack not empty unpredictable results occur.</i>
</ul><h4><code>int fl_not_clipped(int x, int y, int w, int h);</code></h4><ul>
Returns true if any of the rectangle intersects the current clip
region. If this returns false you don't have to draw the object.
<i>On X this returns 2 if the rectangle is partially clipped, and 1 if
it is entirely inside the clip region</i>.
</ul><h4><code>int fl_clip_box(int x, int y, int w, int h,<br>
    int& X, int& Y, int& W, int& H);</code></h4><ul>
Intersect the rectangle x,y,w,h with the current clip region and
returns the bounding box of the result in X,Y,W,H. Returns non-zero
if the resulting rectangle is different than the original. This can
be used to limit the necessary drawing to a rectangle. W and H are set to
zero if the rectangle is completely outside the region.
</ul><hr><h3>Colors</h3>
</ul><h4><code>void fl_color(Fl_Color);</code></h4><ul>
<p>Set the color for all subsequent drawing operations. Fl_Color is
an enumeration type, all values are in the range 0-255. This is
<i>not</i> 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 <a
href=Enumerations.html><FL/Enumerations.H></a>.
<p><i>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.</i>
</ul><h4><code>Fl_Color fl_color();</code></h4><ul>
Returns the last fl_color() that was set. This can be used for state
save/restore.
</ul><h4><code>void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
<br>void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);</code></h4><ul>
Set or get an entry in the fl_color index table. You can set it to
any 8-bit rgb color. <i>On X, if the index has been requested before,
the pixel is free'd. No pixel is allocated until fl_color(i) is used
again, and there is no guarantee that the same pixel will be used next
time.</i>
</ul><h4><code>void fl_color(uchar r, uchar g, uchar
b);</code></h4><ul>
<p>Set the color for all subsequent drawing operations. The closest
possible match to the rgb color is used. <i>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!</i>
</ul><hr><h3>Fast Shapes</h3>
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 <a
href=#vertex>transformation matrix</a>, so you should only call these
while it is the identity.
<p><i>All arguments are integers.</i>
</ul><h4><code>void fl_rectf(x, y, w, h);</code></h4><ul>
Color a rectangle that exactly fills the given bounding box.
</ul><h4><code>void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);</code></h4><ul>
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 <a
href=images.html#fl_draw_image>fl_draw_image()</a> 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.
</ul><h4><code>void fl_rect(x, y, w, h);</code></h4><ul>
Draw a 1-pixel border <i>inside</i> this bounding box.
</ul><h4><code>void fl_line(x, y, x1, y1);
<br>void fl_line(x, y, x1, y1, x2, y2);</code></h4><ul>
Draw one or two 1-pixel thick lines between the given points.
</ul><h4><code>void fl_loop(x, y, x1, y1, x2, y2);
<br>void fl_loop(x, y, x1, y1, x2, y2, x3, y3);
</code></h4><ul>
Outline a 3 or 4-sided polygon with 1-pixel thick lines.
</ul><h4><code>void fl_polygon(x, y, x1, y1, x2, y2);
<br>void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
</code></h4><ul>
Fill a 3 or 4-sided polygon. The polygon must be convex.
</ul><h4><code>void fl_xyline(x, y, x1, y1);
<br>void fl_xyline(x, y, x1, y1, x2);
<br>void fl_xyline(x, y, x1, y1, x2, y3);
</code></h4><ul>
Draw 1-pixel wide horizontal and vertical lines. A horizontal line is
drawn first, then a vertical, then a horizontal.
</ul><h4><code>void fl_yxline(x, y, y1);
<br>void fl_yxline(x, y, y1, x2);
<br>void fl_yxline(x, y, y1, x2, y3);
</code></h4><ul>
Draw 1-pixel wide vertical and horizontal lines. A vertical line is
drawn first, then a horizontal, then a vertical.
</ul><h4><code>
void fl_arc(x, y, w, h, double a1, double a2);<br>
void fl_pie(x, y, w, h, double a1, double a2);<br>
void fl_chord(x, y, w, h, double a1, double a2);</code></h4><ul>
High-speed ellipse sections. These functions match the rather limited
circle drawing code provided by X and MSWindows. The advantage over using <a
href=#fl_arc>fl_arc</a> 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.
<p>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.
<p>fl_arc draws a 1-pixel thick line (notice this has a different
number of arguments than the <a href=#fl_arc>fl_arc</a> described
below.
<p>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.
<p>fl_chord is not yet implemented.
</ul><hr><h3>Complex Shapes</h3>
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)
<p><i>All arguments are float.</i>
</ul><h4><code>void fl_push_matrix();
<br>void fl_pop_matrix();</code></h4><ul>
Save and restore the current transformation. The maximum depth of the
stack is 4.
</ul><h4><code>void fl_scale(x, y);
<br>void fl_scale(x);
<br>void fl_translate(x, y);
<br>void fl_rotate(d);
<br>void fl_mult_matrix(a, b, c, d, x, y);</code></h4><ul>
Concat another transformation to the current one. The rotation angle
is in degrees (not radians) counter-clockwise.
</ul><h4><code>void fl_begin_line();
<br>void fl_end_line();</code></h4><ul>
Start and end drawing 1-pixel thick lines.
</ul><h4><code>void fl_begin_loop();
<br>void fl_end_loop();</code></h4><ul>
Start and end drawing a closed sequence of 1-pixel thick lines.
</ul><h4><code>void fl_begin_polygon();
<br>void fl_end_polygon();</code></h4><ul>
Start and end drawing a convex filled polygon.
</ul><h4><code>void fl_begin_complex_polygon();
<br>void fl_gap();
<br>void fl_end_complex_polygon();</code></h4><ul>
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.
<p><i>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().</i>
</ul><h4><code>void fl_vertex(x, y);</code></h4><ul>
Add a single vertex to the current path.
</ul><h4><code>void fl_curve(int x,int y,int x1,int y1,int x2,int
y2,int x3,int y3);</code></h4><ul>
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.
</ul><h4><code>void fl_arc(x, y, r, start, end);</code></h4><ul>
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). <i>x,y</i> are the center of the circle, and <i>r</i> is it's
radius. fl_arc() takes <i>start</i> and <i>end</i> angles that are
measured in degrees counter-clockwise from 3 o'clock. If <i>end</i>
is less than <i>start</i> then it draws clockwise.
</ul><h4><code>void fl_circle(x, y, r);</code></h4><ul>
fl_circle() is equivalent to fl_arc(...,0,360) but may be faster. It
must be the <i>only</i> thing in the path: if you want a circle as
part of a complex polygon you must use fl_arc(). <i>Under Xlib and
MSWindows this draws incorrectly if the transformation is both rotated
and non-square scaled.</i>
</ul><hr><h3>Text</h3>
All text is drawn in the <a href=#fl_font>current font</a>. It is
undefined whether this location or the characters are modified by the
current transformation.
</ul><h4><code>void fl_draw(const char*, float x, float y);
<br>void fl_draw(const char*, int n, float x, float y);</code></h4><ul>
Draw a null terminated string or an array of <i>n</i> characters
starting at the given location.
</ul><h4><code>void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);</code></h4><ul>
Fancy string drawing function which is used to draw all the labels.
The string is formatted and aligned inside the passed box. Handles
'\t' and '\n', expands all other control characters to ^X, and aligns
inside or against the edges of the box. See <a
href=Fl_Widget.html#align>Fl_Widget::align()</a> for values for
<i>align</i>. The value FL_ALIGN_INSIDE is ignored, this always
prints inside the box.
</ul><h4><code>void fl_measure(const char*, int& w, int& h);</code></h4><ul>
Measure how wide and tall the string will be when printed by the
fl_draw(...align) function. If the incoming w is non-zero it will
wrap to that width.
</ul><h4><code>int fl_height();</code></h4><ul>
Recommended minimum line spacing for the current font. You can also
just use the value of <i>size</i> passed to <a
href=#fl_font>fl_font()</a>.
</ul><h4><code>int fl_descent();</code></h4><ul>
Recommended distance above the bottom of a fl_height() tall box to
draw the text at so it looks centered vertically in that box.
</ul><h4><code>float fl_width(const char*);
<br>float fl_width(const char*, int n);
<br>float fl_width(uchar);</code></h4><ul>
Return the width of a null-terminated string, a sequence of n
characters, and a single character.
</ul><h4><code>const char* fl_shortcut_label(ulong);</code></h4><ul>
Unparse a shortcut value as used by <a
href=Fl_Button.html#shortcut>Fl_Button</a> or <a
href=Fl_Menu.html>Fl_Menu_Item</a> into a human-readable string like
"Alt+N". This only works if the shortcut is a character key or a
numbered Function key. If the shortcut is zero an empty string is
returned. The return value points at a static buffer that is
overwritten with each call.
</ul><hr><h3>Fonts</h3>
</ul><h4><code>void fl_font(int face, int size);</code></h4><ul>
Set the current font, which is then used by the routines described
above. You may call this outside a draw context if necessary to call
fl_width(), but on X this will open the display.
<p>The font is identified by a <i>face</i> and a <i>size</i>. The
size of the font is measured in <i>pixels</i> (ie. it is not
"resolution [in]dependent"). Lines should be spaced <i>size</i>
pixels apart (or more).
<p>The <i>face</i> 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.
</ul><h4><code>int fl_font();<br>
int fl_size();</code></h4><ul>
Returns the face and size set by the most recent fl_font(a,b). This
can be used to save/restore the font.
</ul><h4><code>const char* Fl::get_font(int face);</code></h4><ul>
Get the string for this face. This string is different for each face.
Under X this value is passed to XListFonts to get all the sizes of
this face.
</ul><h4><code>const char* Fl::get_font_name(int face, int* attributes=0);</code></h4><ul>
Get a human-readable string describing the family of this face. This
is useful if you are presenting a choice to the user. There is no
guarantee that each face has a different name. The return value
points to a static buffer that is overwritten each call.
<p>The integer pointed to by <i>attributes</i> (if the pointer is not
zero) is set to zero, <code>FL_BOLD</code>(1) or
<code>FL_ITALIC</code>(2) or <code>FL_BOLD|FL_ITALIC</code> (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.
</ul><h4><code>int get_font_sizes(int face, int*& sizep);</code></h4><ul>
Return an array of sizes in <i>sizep</i>. The return value is the
length of this array. The sizes are sorted from smallest to largest
and indicate what sizes can be given to fl_font() that will be matched
exactly (fl_font() will pick the closest size for other sizes). A
zero in the first location of the array indicates a scalable font,
where any size works, although the array may list sizes that work
"better" than others. Warning: the returned array points at a static
buffer that is overwritten each call. Under X this will open the
display.
</ul><h4><code>int Fl::set_font(int face, const char*);</code></h4><ul>
Change a face. The string pointer is simply stored, the string is not
copied, so the string must be in static memory.
</ul><h4><code>int Fl::set_font(int face, int from);</code></h4><ul>
Copy one face to another.
</ul><h4><code>int Fl::set_fonts(const char* = 0);</code></h4><ul>
FLTK will open the display, and add every font on the server to the
face table. It will attempt to put "families" of faces together, so
that the normal one is first, followed by bold, italic, and bold
italic.
<p>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 MSWindows NULL selects fonts
with ISO8859-1 encoding and non-NULL selects all fonts.
<p>Return value is how many faces are in the table after this is done.
</ul><hr><h2>Bitmaps, Pixmaps and Images</h2>
<a href=images.html#direct>Click here for information on drawing images</a>
</ul><hr><h3>Cursor</h3>
</ul><h4><code>void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);</code></h4><ul>
Change the cursor. Depending on the system this may affect the cursor
everywhere, or only when it is pointing at the window that is current
when you call this. For portability you should change the cursor back
to the default in response to FL_LEAVE events.
<p>The type Fl_Cursor is an enumeration defined in <a
href=Enumerations.html><Enumerations.H></a>. The
double-headed arrows are bitmaps provided by FLTK on X, the others are
provided by system-defined cursors. Under X you can get any XC_cursor
value by passing <code>Fl_Cursor((XC_foo/2)+1)</code>.
<p><ul>
<li><code>FL_CURSOR_DEFAULT</code> (0) usually an arrow
<li><code>FL_CURSOR_ARROW</code>
<li><code>FL_CURSOR_CROSS</code> - crosshair
<li><code>FL_CURSOR_WAIT</code> - watch or hourglass
<li><code>FL_CURSOR_INSERT</code> - I-beam
<li><code>FL_CURSOR_HAND</code> - hand (uparrow on MSWindows)
<li><code>FL_CURSOR_HELP</code> - question mark
<li><code>FL_CURSOR_MOVE</code> - 4-pointed arrow
<li><code>FL_CURSOR_NS</code> - up/down arrow
<li><code>FL_CURSOR_WE</code> - left/right arrow
<li><code>FL_CURSOR_NWSE</code> - diagonal arrow
<li><code>FL_CURSOR_NESW</code> - diagonal arrow
<li><code>FL_CURSOR_NONE</code> - invisible
</ul>
</ul><hr><h3>Overlay rectangle</h3>
</ul><h4><code>void fl_overlay_rect(int x, int y, int w, int h);<br>
void fl_overlay_clear();</code></h4><ul>
<p>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.
</ul><p><a href = index.html>(back to contents)</a>
</BODY>
</HTML>
<title>Drawing Images in FLTK</title>
<h2>Drawing Images in FLTK</h2>
To draw images, you can either do it directly from data in your
memory, or you can create <a href=#Fl_Bitmap>Fl_Bitmap</a> or <a
href=#Fl_Image>Fl_Image</a> or <a href=#Fl_Pixmap>Fl_Pixmap</a>
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 <i>much</i> faster.
<a name=direct>
<h2><hr>Direct Image Drawing<br>
#include <FL/fl_draw.H></h2>
<p>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.
<p><i>All untyped arguments are integers.</i>
</ul><h4><code>
void fl_draw_bitmap(const uchar*, X, Y, W, H, LD = 0);</code></h4><ul>
This function is planned but not yet implemented (it may be impossible
under X without allocating a pixmap).
<a name=fl_draw_image>
</ul><h4><code>
void fl_draw_image(const uchar*, X, Y, W, H, D = 3, LD = 0);<br>
void fl_draw_image_mono(const uchar*, X, Y, W, H, D = 1, LD = 0);
</code></h4><ul>
Draw an 8-bit per color rgb image. The pointer points at the "r" data
of the top-left pixel. Data must be in r,g,b order. X, Y are where
to put the top-left corner. W and H define the size of the image. D
is the delta to add to the pointer between pixels, it may be any value
greater or equal to 3, or it can be negative to flip the image
horizontally. LD is the delta to add to the pointer between lines (if
0 is passed it uses W*D), and may be larger than W*D to crop data, or
negative to flip the image vertically.
<p>It is highly recommended that you put the following code before the
first show() of <i>any</i> window in your program to get rid of the
dithering if possible:
<ul><p><code>Fl::visual(FL_RGB)</code></ul>
<p>Gray scale (1-channel) images may be drawn. This is done if abs(D)
is less than 3, or by calling <code>fl_draw_image_mono</code>. Only
one 8-bit sample is used for each pixel, and (on screens with
different numbers of bits for red, green, and blue) only gray colors
are used. Setting D greater than 1 will let you display one channel
of a color image.
<p><i>The X version does not support all possible visuals.</i> If FLTK
cannot draw the image in the current visual it will abort. FLTK
supports any visual of 8 bits or less, and all common TrueColor
visuals up to 32 bits.
</ul><h4><code>
typedef void (*fl_draw_image_cb)(void*, x, y, w, uchar*);<br>
void fl_draw_image(fl_draw_image_cb, void*, X, Y, W, H, D = 3);<br>
void fl_draw_image_mono(fl_draw_image_cb, void*, X, Y, W, H, D = 1);
</code></h4><ul>
Call the passed function to provide each scan line of the image. This
lets you generate the image as it is being drawn, or do arbitrary
decompression of stored data (provided it can be decompressed to
individual scan lines easily).
<p>The callback is called with the void* user data pointer (this can
be used to point at a structure of information about the image), and
the x, y, and w of the scan line desired from the image. 0,0 is the
upper-left corner (<i>not X,Y</i>). A pointer to a buffer to put the
data into is passed. You must copy w pixels from scanline y, starting
at pixel x, to this buffer.
<p>Due to cropping, less than the whole image may be requested. So x
may be greater than zero, the first y may be greater than zero, and w
may be less than W. The buffer is long enough to store the entire W*D
pixels, this is for convienence with some decompression schemes where
you must decompress the entire line at once: decompress it into the
buffer, and then if x is not zero, memcpy the data over so the x'th
pixel is at the start of the buffer.
<p>You can assumme the y's will be consecutive, except the first one
may be greater than zero.
<p>If D is 4 or more, you must fill in the unused bytes with zero.
</ul><h4><code>
int fl_draw_pixmap(char** data, X, Y, Fl_Color=FL_GRAY);</code></h4><ul>
Draw XPM image data, with the top-left corner at the given position.
The images is dithered on 8-bit displays so you won't lose color space
for programs displaying both images and pixmaps. This function
returns zero if there was any error decoding the xpm data.
<p>To use an XPM, do "<code>#include "foo.xpm"</code>" and then
"<code>fl_draw_pixmap(foo, X, Y)</code>".
<p>In the current version the XPM data is converted to 8-bit full
color and passed through fl_draw_image(). This is obviously not the
most efficient way to do it, and has the same visual limitations as
listed above for fl_draw_image(). Transparent colors are replaced by
the optional Fl_Color argument (this may change in the future).
<p><a href=xpm.html>FLTK supports some (questionable) enhancements to
the XPM format.</a>
</ul><h4><code>
int fl_measure_pixmap(char** data, int &w, int
&h);</code></h4><ul>
An XPM image contains the dimensions in it's data. This function
finds and returns the width and height. The return value is non-zero
if it parsed the dimensions ok, and zero if there is any problem.
</ul>
<a name=Fl_Bitmap>
<h2><hr>class Fl_Bitmap
<br>#include <FL/Fl_Bitmap.H></h2>
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. <i>Under X it will create an
offscreen pixmap the first time it is drawn, and copy this each
subsequent time it is drawn</i>.
<h4><code>Fl_Bitmap(const char *bits, int W, int H);
<br>Fl_Bitmap(const uchar *bits, int W, int H);</code></h4>
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,
<code>#include "foo.xbm"</code>, and then do "<code>new
Fl_Bitmap(foo_bits,foo_width,foo_height)</code>"
<h4><code>~Fl_Bitmap()</code></h4>
The destructor will destroy any X pixmap created. It does not do
anything to the bits data.
<h4><code>void draw(int x, int y, int w, int h, int ox=0, int oy=0);</code></h4>
<i>x,y,w,h</i> indicates a destination rectangle. <i>ox,oy,w,h</i> 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.
<h4><code>void draw(int x, int y);</code></h4>
Draws the bitmap with the upper-left corner at <i>x,y</i>. This is
the same as doing <code>draw(x,y,this->w,this->h,0,0)</code>.
<h4><code>void label(Fl_Widget *);</code></h4>
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.
<a name=Fl_Pixmap>
<h2><hr>class Fl_Pixmap
<br>#include <FL/Fl_Pixmap.H></h2>
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. <i>Under X it will create an offscreen pixmap the first
time it is drawn, and copy this each subsequent time it is drawn</i>.
<p>The current implementation converts the pixmap to 8 bit color data
and uses <a href=#fl_draw_image>fl_draw_image()</a> to draw
it. Thus you will get dithered colors on an 8 bit screen.
<h4><code>Fl_Pixmap(char * const * data);</code></h4>
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,
<code>#include "foo.xpm"</code>, and then do "<code>new
Fl_Pixmap(foo)</code>"
<h4><code>~Fl_Pixmap()</code></h4>
The destructor will destroy any X pixmap created. It does not do
anything to the data.
<h4><code>void draw(int x, int y, int w, int h, int ox=0, int oy=0);</code></h4>
<i>x,y,w,h</i> indicates a destination rectangle. <i>ox,oy,w,h</i> 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.
<h4><code>void draw(int x, int y);</code></h4>
Draws the image with the upper-left corner at <i>x,y</i>. This is
the same as doing <code>draw(x,y,this->w,this->h,0,0)</code>.
<h4><code>void label(Fl_Widget *);</code></h4>
Change the label() and the labeltype() of the widget to draw the
pixmap. You can use the same pixmap for many widgets.
<a name=Fl_Image>
<h2><hr>class Fl_Image
<br>#include <FL/Fl_Image.H></h2>
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. <i>Under X it will create an offscreen pixmap the first
time it is drawn, and copy this each subsequent time it is drawn</i>.
<p>See <a href=#fl_draw_image>fl_draw_image()</a> for what
happens. On 8 bit screens dithering is used.
<h4><code>Fl_Image(char uchar *data, int W, int H, int D=3, int LD=0);</code></h4>
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.
<h4><code>~Fl_Image()</code></h4>
The destructor will destroy any X pixmap created. It does not do
anything to the data.
<h4><code>void draw(int x, int y, int w, int h, int ox=0, int oy=0);</code></h4>
<i>x,y,w,h</i> indicates a destination rectangle. <i>ox,oy,w,h</i> 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.
<h4><code>void draw(int x, int y);</code></h4>
Draws the image with the upper-left corner at <i>x,y</i>. This is
the same as doing <code>draw(x,y,this->w,this->h,0,0)</code>.
<h4><code>void label(Fl_Widget *);</code></h4>
Change the label() and the labeltype() of the widget to draw the
Image. You can use the same Image for many widgets.
<p><a href = index.html>(back to contents)</a>
<title>FLTK enhancements to the XPM format</title>
<h2>FLTK enhancements to the XPM format</h2>
<p>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.
<p>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.
<p>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).
<p>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.
<p>To make the XPM files easily parseable, but still portable to most
C compilers, I suggest the following format:
<pre>
/* 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 ",
...
</pre>
<p>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.
<HTML>
<BODY>
<H1>Chapter XXX - Drawing Things in FLTK</H1>
<h2>When can you draw things in FLTK?</h2>
There are only certain places you can execute drawing code in FLTK.
Calling these functions at other places will result in undefined
behavior!
<ul>
<li>The most common is inside the virtual method <a
href=subclass.html#draw>Fl_Widget::draw()</a>. To write code here,
you must subclass one of the existing Fl_Widget classes and implement
your own version of draw().
<p>
<li>You can also write <a href=Boxtypes.html>boxtypes</a> and <a href
= Labeltypes.html>labeltypes</a>. These are small procedures that can be
called by existing Fl_Widget draw() methods. These "types" are
identified by an 8-bit index that is stored in the widget's box(),
labeltype(), and possibly other properties.
<p>
<li>You can call <a
href=Fl_Window.html#make_current>Fl_Window::make_current()</a> to do
incremental update of a widget (use <a
href=Fl_Widget.html#window>Fl_Widget::window()</a> to find the
window). <i>Under X this only works for the base Fl_Window class, not
for double buffered, overlay, or OpenGL windows!</i>
</ul>
</ul><h2>FLTK Drawing functions<br>#include <FL/fl_draw.H></h2>
<ul>
<li><a href=#clipping>Clipping</a>
<li><a href=#color>Colors</a>
<li><a href=#fast>Fast Shapes</a>
<li><a href=#vertex>Complex Shapes</a>
<li><a href=#text>Text</a>
<li><a href=images.html>Images</a>
<li><a href=#cursor>Cursor</a>
<li><a href=#overlay>Overlay</a>
<li><a href=Fl_Gl_Window.html#gl_start>Using OpenGL</a>
</ul>
</ul><hr><h3>Clipping</h3>
<p>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).
<p>In addition, the system may provide clipping when updating windows,
this clip region may be more complex than a simple rectangle.
</ul><h4><code>void fl_clip(int x, int y, int w, int h);</code></h4><ul>
Intesect the current clip region with a rectangle and push this new
region onto the stack.
</ul><h4><code>void fl_pop_clip();</code></h4><ul>
Restore the previous clip region. <i>You must call fl_pop_clip() once
for every time you call fl_clip(). If you return to FLTK with the
clip stack not empty unpredictable results occur.</i>
</ul><h4><code>int fl_not_clipped(int x, int y, int w, int h);</code></h4><ul>
Returns true if any of the rectangle intersects the current clip
region. If this returns false you don't have to draw the object.
<i>On X this returns 2 if the rectangle is partially clipped, and 1 if
it is entirely inside the clip region</i>.
</ul><h4><code>int fl_clip_box(int x, int y, int w, int h,<br>
    int& X, int& Y, int& W, int& H);</code></h4><ul>
Intersect the rectangle x,y,w,h with the current clip region and
returns the bounding box of the result in X,Y,W,H. Returns non-zero
if the resulting rectangle is different than the original. This can
be used to limit the necessary drawing to a rectangle. W and H are set to
zero if the rectangle is completely outside the region.
</ul><hr><h3>Colors</h3>
</ul><h4><code>void fl_color(Fl_Color);</code></h4><ul>
<p>Set the color for all subsequent drawing operations. Fl_Color is
an enumeration type, all values are in the range 0-255. This is
<i>not</i> 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 <a
href=Enumerations.html><FL/Enumerations.H></a>.
<p><i>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.</i>
</ul><h4><code>Fl_Color fl_color();</code></h4><ul>
Returns the last fl_color() that was set. This can be used for state
save/restore.
</ul><h4><code>void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
<br>void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);</code></h4><ul>
Set or get an entry in the fl_color index table. You can set it to
any 8-bit rgb color. <i>On X, if the index has been requested before,
the pixel is free'd. No pixel is allocated until fl_color(i) is used
again, and there is no guarantee that the same pixel will be used next
time.</i>
</ul><h4><code>void fl_color(uchar r, uchar g, uchar
b);</code></h4><ul>
<p>Set the color for all subsequent drawing operations. The closest
possible match to the rgb color is used. <i>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!</i>
</ul><hr><h3>Fast Shapes</h3>
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 <a
href=#vertex>transformation matrix</a>, so you should only call these
while it is the identity.
<p><i>All arguments are integers.</i>
</ul><h4><code>void fl_rectf(x, y, w, h);</code></h4><ul>
Color a rectangle that exactly fills the given bounding box.
</ul><h4><code>void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);</code></h4><ul>
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 <a
href=images.html#fl_draw_image>fl_draw_image()</a> 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.
</ul><h4><code>void fl_rect(x, y, w, h);</code></h4><ul>
Draw a 1-pixel border <i>inside</i> this bounding box.
</ul><h4><code>void fl_line(x, y, x1, y1);
<br>void fl_line(x, y, x1, y1, x2, y2);</code></h4><ul>
Draw one or two 1-pixel thick lines between the given points.
</ul><h4><code>void fl_loop(x, y, x1, y1, x2, y2);
<br>void fl_loop(x, y, x1, y1, x2, y2, x3, y3);
</code></h4><ul>
Outline a 3 or 4-sided polygon with 1-pixel thick lines.
</ul><h4><code>void fl_polygon(x, y, x1, y1, x2, y2);
<br>void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
</code></h4><ul>
Fill a 3 or 4-sided polygon. The polygon must be convex.
</ul><h4><code>void fl_xyline(x, y, x1, y1);
<br>void fl_xyline(x, y, x1, y1, x2);
<br>void fl_xyline(x, y, x1, y1, x2, y3);
</code></h4><ul>
Draw 1-pixel wide horizontal and vertical lines. A horizontal line is
drawn first, then a vertical, then a horizontal.
</ul><h4><code>void fl_yxline(x, y, y1);
<br>void fl_yxline(x, y, y1, x2);
<br>void fl_yxline(x, y, y1, x2, y3);
</code></h4><ul>
Draw 1-pixel wide vertical and horizontal lines. A vertical line is
drawn first, then a horizontal, then a vertical.
</ul><h4><code>
void fl_arc(x, y, w, h, double a1, double a2);<br>
void fl_pie(x, y, w, h, double a1, double a2);<br>
void fl_chord(x, y, w, h, double a1, double a2);</code></h4><ul>
High-speed ellipse sections. These functions match the rather limited
circle drawing code provided by X and MSWindows. The advantage over using <a
href=#fl_arc>fl_arc</a> 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.
<p>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.
<p>fl_arc draws a 1-pixel thick line (notice this has a different
number of arguments than the <a href=#fl_arc>fl_arc</a> described
below.
<p>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.
<p>fl_chord is not yet implemented.
</ul><hr><h3>Complex Shapes</h3>
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)
<p><i>All arguments are float.</i>
</ul><h4><code>void fl_push_matrix();
<br>void fl_pop_matrix();</code></h4><ul>
Save and restore the current transformation. The maximum depth of the
stack is 4.
</ul><h4><code>void fl_scale(x, y);
<br>void fl_scale(x);
<br>void fl_translate(x, y);
<br>void fl_rotate(d);
<br>void fl_mult_matrix(a, b, c, d, x, y);</code></h4><ul>
Concat another transformation to the current one. The rotation angle
is in degrees (not radians) counter-clockwise.
</ul><h4><code>void fl_begin_line();
<br>void fl_end_line();</code></h4><ul>
Start and end drawing 1-pixel thick lines.
</ul><h4><code>void fl_begin_loop();
<br>void fl_end_loop();</code></h4><ul>
Start and end drawing a closed sequence of 1-pixel thick lines.
</ul><h4><code>void fl_begin_polygon();
<br>void fl_end_polygon();</code></h4><ul>
Start and end drawing a convex filled polygon.
</ul><h4><code>void fl_begin_complex_polygon();
<br>void fl_gap();
<br>void fl_end_complex_polygon();</code></h4><ul>
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.
<p><i>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().</i>
</ul><h4><code>void fl_vertex(x, y);</code></h4><ul>
Add a single vertex to the current path.
</ul><h4><code>void fl_curve(int x,int y,int x1,int y1,int x2,int
y2,int x3,int y3);</code></h4><ul>
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.
</ul><h4><code>void fl_arc(x, y, r, start, end);</code></h4><ul>
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). <i>x,y</i> are the center of the circle, and <i>r</i> is it's
radius. fl_arc() takes <i>start</i> and <i>end</i> angles that are
measured in degrees counter-clockwise from 3 o'clock. If <i>end</i>
is less than <i>start</i> then it draws clockwise.
</ul><h4><code>void fl_circle(x, y, r);</code></h4><ul>
fl_circle() is equivalent to fl_arc(...,0,360) but may be faster. It
must be the <i>only</i> thing in the path: if you want a circle as
part of a complex polygon you must use fl_arc(). <i>Under Xlib and
MSWindows this draws incorrectly if the transformation is both rotated
and non-square scaled.</i>
</ul><hr><h3>Text</h3>
All text is drawn in the <a href=#fl_font>current font</a>. It is
undefined whether this location or the characters are modified by the
current transformation.
</ul><h4><code>void fl_draw(const char*, float x, float y);
<br>void fl_draw(const char*, int n, float x, float y);</code></h4><ul>
Draw a null terminated string or an array of n characters in the
current font, starting at the given location.
</ul><h4><code>void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);</code></h4><ul>
Fancy string drawing function which is used to draw all the labels.
The string is formatted and aligned inside the passed box. Handles
'\t' and '\n', expands all other control characters to ^X, and aligns
inside or against the edges of the box. See <a
href=Fl_Widget.html#align>Fl_Widget::align()</a> for values for
<i>align</i>. The value FL_ALIGN_INSIDE is ignored, this always
prints inside the box.
</ul><h4><code>void fl_measure(const char*, int& w, int& h);</code></h4><ul>
Measure how wide and tall the string will be when printed by the
fl_draw(...align) function. If the incoming w is non-zero it will
wrap to that width.
</ul><h4><code>int fl_height();</code></h4><ul>
Recommended minimum line spacing for the current font. You can also
just use the value of <i>size</i> passed to <a
href=#fl_font>fl_font()</a>.
</ul><h4><code>int fl_descent();</code></h4><ul>
Recommended distance above the bottom of a fl_height() tall box to
draw the text at so it looks centered vertically in that box.
</ul><h4><code>float fl_width(const char*);
<br>float fl_width(const char*, int n);
<br>float fl_width(uchar);</code></h4><ul>
Return the width of a null-terminated string, a sequence of n
characters, and a single character.
</ul><h4><code>const char* fl_shortcut_label(ulong);</code></h4><ul>
Unparse a shortcut value as used by <a
href=Fl_Button.html#shortcut>Fl_Button</a> or <a
href=Fl_Menu.html>Fl_Menu_Item</a> into a human-readable string like
"Alt+N". This only works if the shortcut is a character key or a
numbered Function key. If the shortcut is zero an empty string is
returned. The return value points at a static buffer that is
overwritten with each call.
</ul><hr><h3>Fonts</h3>
</ul><h4><code>void fl_font(int face, int size);</code></h4><ul>
Set the current font, which is then used by the routines described
above. You may call this outside a draw context if necessary to call
fl_width(), but on X this will open the display.
<p>The font is identified by a <i>face</i> and a <i>size</i>. The
size of the font is measured in <i>pixels</i> (ie. it is not
"resolution [in]dependent"). Lines should be spaced <i>size</i>
pixels apart (or more).
<p>The <i>face</i> 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.
</ul><h4><code>int fl_font();<br>
int fl_size();</code></h4><ul>
Returns the face and size set by the most recent fl_font(a,b). This
can be used to save/restore the font.
</ul><h4><code>const char* Fl::get_font(int face);</code></h4><ul>
Get the string for this face. This string is different for each face.
Under X this value is passed to XListFonts to get all the sizes of
this face.
</ul><h4><code>const char* Fl::get_font_name(int face, int* attributes=0);</code></h4><ul>
Get a human-readable string describing the family of this face. This
is useful if you are presenting a choice to the user. There is no
guarantee that each face has a different name. The return value
points to a static buffer that is overwritten each call.
<p>The integer pointed to by <i>attributes</i> (if the pointer is not
zero) is set to zero, <code>FL_BOLD</code>(1) or
<code>FL_ITALIC</code>(2) or <code>FL_BOLD|FL_ITALIC</code> (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.
</ul><h4><code>int get_font_sizes(int face, int*& sizep);</code></h4><ul>
Return an array of sizes in <i>sizep</i>. The return value is the
length of this array. The sizes are sorted from smallest to largest
and indicate what sizes can be given to fl_font() that will be matched
exactly (fl_font() will pick the closest size for other sizes). A
zero in the first location of the array indicates a scalable font,
where any size works, although the array may list sizes that work
"better" than others. Warning: the returned array points at a static
buffer that is overwritten each call. Under X this will open the
display.
</ul><h4><code>int Fl::set_font(int face, const char*);</code></h4><ul>
Change a face. The string pointer is simply stored, the string is not
copied, so the string must be in static memory.
</ul><h4><code>int Fl::set_font(int face, int from);</code></h4><ul>
Copy one face to another.
</ul><h4><code>int Fl::set_fonts(const char* = 0);</code></h4><ul>
FLTK will open the display, and add every font on the server to the
face table. It will attempt to put "families" of faces together, so
that the normal one is first, followed by bold, italic, and bold
italic.
<p>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 MSWindows NULL selects fonts
with ISO8859-1 encoding and non-NULL selects all fonts.
<p>Return value is how many faces are in the table after this is done.
</ul><hr><h2>Bitmaps, Pixmaps and Images</h2>
<a href=images.html#direct>Click here for information on drawing images</a>
</ul><hr><h3>Cursor</h3>
</ul><h4><code>void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);</code></h4><ul>
Change the cursor. Depending on the system this may affect the cursor
everywhere, or only when it is pointing at the window that is current
when you call this. For portability you should change the cursor back
to the default in response to FL_LEAVE events.
<p>The type Fl_Cursor is an enumeration defined in <a
href=Enumerations.html><Enumerations.H></a>. The
double-headed arrows are bitmaps provided by FLTK on X, the others are
provided by system-defined cursors. Under X you can get any XC_cursor
value by passing <code>Fl_Cursor((XC_foo/2)+1)</code>.
<p><ul>
<li><code>FL_CURSOR_DEFAULT</code> (0) usually an arrow
<li><code>FL_CURSOR_ARROW</code>
<li><code>FL_CURSOR_CROSS</code> - crosshair
<li><code>FL_CURSOR_WAIT</code> - watch or hourglass
<li><code>FL_CURSOR_INSERT</code> - I-beam
<li><code>FL_CURSOR_HAND</code> - hand (uparrow on MSWindows)
<li><code>FL_CURSOR_HELP</code> - question mark
<li><code>FL_CURSOR_MOVE</code> - 4-pointed arrow
<li><code>FL_CURSOR_NS</code> - up/down arrow
<li><code>FL_CURSOR_WE</code> - left/right arrow
<li><code>FL_CURSOR_NWSE</code> - diagonal arrow
<li><code>FL_CURSOR_NESW</code> - diagonal arrow
<li><code>FL_CURSOR_NONE</code> - invisible
</ul>
</ul><hr><h3>Overlay rectangle</h3>
</ul><h4><code>void fl_overlay_rect(int x, int y, int w, int h);<br>
void fl_overlay_clear();</code></h4><ul>
<p>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.
</ul><p><a href = index.html>(back to contents)</a>
</BODY>
</HTML>
|