1 /* pamdraw.h - header file for simple drawing routines in libnetpbm.
2 **
3 ** Simple, yes, and also fairly slow if the truth be told; but also very
4 ** flexible and powerful.
5 **
6 ** The two basic concepts are the drawproc and clientdata. All the drawing
7 ** routines take a drawproc that does the actual drawing. A drawproc draws
8 ** a single point, and it looks like this:
9 */
10
11 #include <netpbm/pm_config.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 #if 0
17 } /* to fake out automatic code indenters */
18 #endif
19
20
21 typedef struct {
22 int x;
23 int y;
24 } pamd_point;
25
26 static __inline__ pamd_point
pamd_makePoint(int const x,int const y)27 pamd_makePoint(int const x,
28 int const y) {
29
30 pamd_point p;
31
32 p.x = x;
33 p.y = y;
34
35 return p;
36 }
37
38 void
39 pamd_validateCoord(int const c);
40
41 void
42 pamd_validatePoint(pamd_point const p);
43
44 typedef enum {
45 PAMD_PATHLEG_LINE
46 } pamd_pathlegtype;
47
48 struct pamd_linelegparms {
49 pamd_point end;
50 };
51
52 typedef struct {
53 /*----------------------------------------------------------------------------
54 A leg of a pamd_path.
55 -----------------------------------------------------------------------------*/
56 pamd_pathlegtype type;
57 union {
58 struct pamd_linelegparms linelegparms;
59 } u;
60 } pamd_pathleg;
61
62 typedef struct {
63 /*----------------------------------------------------------------------------
64 A closed path
65 -----------------------------------------------------------------------------*/
66 unsigned int version;
67 /* Must be zero. For future expansion. */
68 pamd_point begPoint;
69 unsigned int legCount;
70 /* Number of legs in the path; i.e. size of 'legs' array */
71 size_t legSize;
72 /* Size of storage occupied by one pamd_pathleg. I.e.
73 sizeof(pamd_pathleg). Used for
74 binary backward compatibility between callers and libpamd
75 as the definition of pamd_pathleg changes.
76 */
77 pamd_pathleg * legs;
78 } pamd_path;
79
80
81
82 typedef void pamd_drawproc(tuple **, unsigned int, unsigned int, unsigned int,
83 sample, pamd_point, const void *);
84
85 pamd_drawproc pamd_point_drawproc;
86
87 /*
88 ** So, you call a drawing routine, e.g. pamd_line(), and pass it a drawproc;
89 ** it calls the drawproc for each point it wants to draw. Why so complicated?
90 ** Because you can define your own drawprocs to do more interesting things than
91 ** simply draw the point. For example, you could make one that calls back into
92 ** another drawing routine, say pamd_circle() to draw a circle at each point
93 ** of a line.
94 **
95 ** Slow? Well sure, we're talking results here, not realtime. You can do
96 ** tricks with this arrangement that you couldn't even think of before.
97 ** Still, to speed things up for the 90% case you can use this:
98 */
99 #define PAMD_NULLDRAWPROC NULL
100 /*
101 ** Just like pamd_point_drawproc() it simply draws the point, but it's done
102 ** inline, and clipping is assumed to be handled at a higher level.
103 **
104 ** Now, what about clientdata. Well, it's an arbitrary pointer, and can
105 ** mean something different to each different drawproc. For the above two
106 ** drawprocs, clientdata should be a pointer to a tuple holding the color
107 ** to be drawn. Other drawprocs can use it to point to something else,
108 ** e.g. some structure to be modified, or they can ignore it.
109 */
110
111
112 /* Outline drawing routines. Lines, splines, circles, etc. */
113
114 int
115 pamd_setlinetype(int const type);
116
117 #define PAMD_LINETYPE_NORMAL 0
118 #define PAMD_LINETYPE_NODIAGS 1
119 /* If you set NODIAGS, all tuples drawn by pamd_line() will be 4-connected
120 ** instead of 8-connected; in other words, no diagonals. This is useful
121 ** for some applications, for example when you draw many parallel lines
122 ** and you want them to fit together without gaps.
123 */
124
125 int
126 pamd_setlineclip(int const clip);
127
128 #define pamd_setlineclipping(x) pamd_setlineclip(x)
129 /* Normally, pamd_line() clips to the edges of the pixmap. You can use this
130 ** routine to disable the clipping, for example if you are using a drawproc
131 ** that wants to do its own clipping.
132 */
133
134 void
135 pamd_line(tuple ** const tuples,
136 int const cols,
137 int const rows,
138 int const depth,
139 sample const maxval,
140 pamd_point const p0,
141 pamd_point const p1,
142 pamd_drawproc drawProc,
143 const void * const clientdata);
144
145 /* Draws a line from p0 to p1. */
146
147 void
148 pamd_spline3(tuple ** const tuples,
149 int const cols,
150 int const rows,
151 int const depth,
152 sample const maxval,
153 pamd_point const p0,
154 pamd_point const p1,
155 pamd_point const p2,
156 pamd_drawproc drawProc,
157 const void * const clientdata);
158
159 /* Draws a three-point spline from p0 to p2, with p1
160 as the control point. All drawing is done via pamd_line(),
161 so the routines that control it control pamd_spline3p() as well.
162 */
163
164 void
165 pamd_polyspline(tuple ** const tuples,
166 unsigned int const cols,
167 unsigned int const rows,
168 unsigned int const depth,
169 sample const maxval,
170 pamd_point const p0,
171 unsigned int const nc,
172 pamd_point * const c,
173 pamd_point const p1,
174 pamd_drawproc drawProc,
175 const void * const clientdata);
176
177 /* Draws a bunch of splines end to end. p0 and p1 are the initial and
178 final points, and the c[] are the intermediate control points. nc is
179 the number of these control points.
180 */
181
182 void
183 pamd_spline4(tuple ** const tuples,
184 unsigned int const cols,
185 unsigned int const rows,
186 unsigned int const depth,
187 sample const maxval,
188 pamd_point const endPt0,
189 pamd_point const endPt1,
190 pamd_point const ctlPt0,
191 pamd_point const ctlPt1,
192 pamd_drawproc drawProc,
193 const void * const clientdata);
194
195 void
196 pamd_circle(tuple ** const tuples,
197 unsigned int const cols,
198 unsigned int const rows,
199 unsigned int const depth,
200 sample const maxval,
201 pamd_point const center,
202 unsigned int const radius,
203 pamd_drawproc drawProc,
204 const void * const clientData);
205 /* Draws a circle centered at 'center' with radius 'radius' */
206
207 /* Simple filling routines. */
208
209 void
210 pamd_filledrectangle(tuple ** const tuples,
211 int const cols,
212 int const rows,
213 int const depth,
214 sample const maxval,
215 int const left,
216 int const top,
217 int const width,
218 int const height,
219 pamd_drawproc drawProc,
220 const void * const clientdata);
221 /* Fills in the rectangle [left, top, width, height]. */
222
223
224 void
225 pamd_fill_path(tuple ** const tuples,
226 int const cols,
227 int const rows,
228 int const depth,
229 sample const maxval,
230 pamd_path * const pathP,
231 tuple const color);
232 /* Fills in a closed path. Not much different from pamd_fill(),
233 but with a different interface.
234 */
235
236
237 /* Arbitrary filling routines. With these you can fill any outline that
238 ** you can draw with the outline routines.
239 */
240
241 struct fillobj;
242
243 struct fillobj *
244 pamd_fill_create(void);
245 /* Returns a blank fillhandle. */
246
247 void
248 pamd_fill_destroy(struct fillobj * fillObjP);
249
250 void
251 pamd_fill_drawproc(tuple ** const tuples,
252 unsigned int const cols,
253 unsigned int const rows,
254 unsigned int const depth,
255 sample const maxval,
256 pamd_point const p,
257 const void * const clientdata);
258 /* Use this drawproc to trace the outline you want filled. Use
259 the fillhandle as the clientdata.
260 */
261
262 void
263 pamd_fill(tuple ** const tuples,
264 int const cols,
265 int const rows,
266 int const depth,
267 sample const maxval,
268 struct fillobj * const fillObjP,
269 pamd_drawproc drawProc,
270 const void * const clientdata);
271
272 /* Once you've traced the outline, give the fillhandle to this routine to
273 do the actual drawing. As usual, it takes a drawproc and clientdata;
274 you could define drawprocs to do stipple fills and such.
275 */
276
277 /* Text drawing routines. */
278
279 void
280 pamd_text(tuple** const tuples,
281 int const cols,
282 int const rows,
283 int const depth,
284 sample const maxval,
285 pamd_point const pos,
286 int const height,
287 int const angle,
288 const char * const sArg,
289 pamd_drawproc drawProc,
290 const void * const clientdata);
291
292 /* Draws the null-terminated string 's' left justified at the point ('x',
293 'y'). The text will be 'height' tuples high and will be aligned on a
294 baseline inclined 'angle' degrees with the X axis. The supplied
295 drawproc and clientdata are passed to pamd_line() which performs the
296 actual drawing.
297 */
298
299 void
300 pamd_text_box(int const height,
301 int const angle,
302 const char * const s,
303 int * const leftP,
304 int * const topP,
305 int * const rightP,
306 int * const bottomP);
307 /* Calculates the extents box for text drawn by pamd_text with the given
308 string, size, and orientation. Most extent box calculations should use
309 an angle specification of zero to calculate the unrotated box enclosing
310 the text. If you need the extents of rotated text, however, you can
311 call pamd_text_box with a nonzero angle.
312 */
313
314 #ifdef __cplusplus
315 }
316 #endif
317
318