1 /* libwmf ("ipa/fig/draw.h"): library for wmf conversion
2 Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
3
4 The libwmf Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The libwmf Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the libwmf Library; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19
wmf_fig_flood_interior(wmfAPI * API,wmfFlood_t * flood)20 static void wmf_fig_flood_interior (wmfAPI* API,wmfFlood_t* flood)
21 { /* wmf_fig_t* ddata = WMF_FIG_GetData (API); */
22 (void)flood;
23 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]flood_interior");
24
25 if (API->flags & WMF_OPT_IGNORE_NONFATAL)
26 { WMF_DEBUG (API,"flood_interior unsupported.");
27 }
28 else
29 { WMF_ERROR (API,"flood_interior unsupported.");
30 API->err = wmf_E_Glitch;
31 }
32 }
33
wmf_fig_flood_exterior(wmfAPI * API,wmfFlood_t * flood)34 static void wmf_fig_flood_exterior (wmfAPI* API,wmfFlood_t* flood)
35 { /* wmf_fig_t* ddata = WMF_FIG_GetData (API); */
36 (void)flood;
37 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]flood_exterior");
38
39 if (API->flags & WMF_OPT_IGNORE_NONFATAL)
40 { WMF_DEBUG (API,"flood_exterior unsupported.");
41 }
42 else
43 { WMF_ERROR (API,"flood_exterior unsupported.");
44 API->err = wmf_E_Glitch;
45 }
46 }
47
wmf_fig_draw_pixel(wmfAPI * API,wmfDrawPixel_t * draw_pixel)48 static void wmf_fig_draw_pixel (wmfAPI* API,wmfDrawPixel_t* draw_pixel)
49 { wmfBrush* set_brush = 0;
50
51 wmfBrush brush;
52
53 wmfPen* set_pen = 0;
54
55 wmfPen pen;
56
57 wmfDrawRectangle_t draw_rect;
58
59 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_pixel");
60
61 /* Going to redirect this to wmf_fig_draw_rectangle
62 */
63 draw_rect.dc = draw_pixel->dc;
64
65 draw_rect.width = 0;
66 draw_rect.height = 0;
67
68 /* brush setup
69 */
70 set_brush = WMF_DC_BRUSH (draw_rect.dc);
71
72 brush = (*set_brush);
73
74 WMF_BRUSH_SET_STYLE (&brush,BS_SOLID);
75
76 WMF_BRUSH_SET_COLOR (&brush,&(draw_pixel->color));
77
78 WMF_DC_SET_BRUSH (draw_rect.dc,&brush);
79
80 /* pen setup
81 */
82 set_pen = WMF_DC_PEN (draw_rect.dc);
83
84 pen = (*set_pen);
85
86 WMF_PEN_SET_STYLE (&pen,PS_NULL);
87
88 WMF_DC_SET_PEN (draw_rect.dc,&pen);
89
90 draw_rect.TL.x = (float) draw_pixel->pt.x;
91 draw_rect.TL.y = (float) draw_pixel->pt.y;
92 draw_rect.BR.x = (float) (draw_pixel->pt.x + draw_pixel->pixel_width );
93 draw_rect.BR.y = (float) (draw_pixel->pt.y + draw_pixel->pixel_height);
94
95 wmf_fig_draw_rectangle (API,&draw_rect);
96
97 WMF_DC_SET_BRUSH (draw_rect.dc,set_brush); /* Soon to be redundant ?? */
98
99 WMF_DC_SET_PEN (draw_rect.dc,set_pen); /* Soon to be redundant ?? */
100 }
101
wmf_fig_draw_pie(wmfAPI * API,wmfDrawArc_t * draw_arc)102 static void wmf_fig_draw_pie (wmfAPI* API,wmfDrawArc_t* draw_arc)
103 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
104
105 wmfStream* out = ddata->out;
106
107 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_pie");
108
109 wmf_stream_printf (API,out,"# wmf_[fig_]draw_pie\n");
110
111 fig_draw_arc (API,draw_arc,0);
112
113 wmf_stream_printf (API,out,"# draw_pie not impl\n");
114 }
115
wmf_fig_draw_chord(wmfAPI * API,wmfDrawArc_t * draw_arc)116 static void wmf_fig_draw_chord (wmfAPI* API,wmfDrawArc_t* draw_arc)
117 { (void)draw_arc;
118 wmf_fig_t* ddata = WMF_FIG_GetData (API);
119
120 wmfStream* out = ddata->out;
121
122 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_chord");
123
124 wmf_stream_printf (API,out,"# draw_chord not impl\n");
125 }
126
wmf_fig_draw_arc(wmfAPI * API,wmfDrawArc_t * draw_arc)127 static void wmf_fig_draw_arc (wmfAPI* API,wmfDrawArc_t* draw_arc)
128 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
129
130 wmfStream* out = ddata->out;
131
132 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_arc");
133
134 wmf_stream_printf (API,out,"# wmf_[fig_]draw_arc\n");
135
136 fig_draw_arc(API, draw_arc, 1);
137
138 wmf_stream_printf (API,out,"# end draw_arc\n");
139 }
140
fig_draw_arc(wmfAPI * API,wmfDrawArc_t * draw_arc,int sub_type)141 static void fig_draw_arc (wmfAPI* API,wmfDrawArc_t* draw_arc,int sub_type)
142 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
143
144 wmfStream* out = ddata->out;
145
146 figDC fig;
147
148 figPoint TL;
149 figPoint BR;
150
151 int direction;
152
153 int Ox;
154 int Oy;
155
156 float start_x;
157 float start_y;
158 float end_x;
159 float end_y;
160 float mid_x;
161 float mid_y;
162
163 float rad;
164 float start;
165 float end;
166 float mid;
167
168 WMF_DEBUG (API,"~~~~~~~~fig_draw_arc");
169
170 wmf_stream_printf (API,out,"# fig_draw_arc\n");
171
172 fig_set_style (API,draw_arc->dc,&fig);
173
174 ddata->depth -= ddata->ddec;
175
176 direction = 0;
177
178 start_x = (float) draw_arc->start.x;
179 start_y = (float) draw_arc->start.y;
180 end_x = (float) draw_arc->end.x;
181 end_y = (float) draw_arc->end.y;
182
183 TL = fig_translate (API,draw_arc->TL);
184 BR = fig_translate (API,draw_arc->BR);
185
186 /* origin: */
187 Ox = (BR.x + TL.x + 1) / 2;
188 Oy = (BR.y + TL.y + 1) / 2;
189
190 /* long axis */
191 rad = ((float) (BR.x - TL.x)) / 2;
192
193 /*
194 start_y = sqrt(rad * rad - start_x * start_x);
195 if (draw_arc->start.y < 0) start_y = - start_y;
196 end_y = sqrt(rad * rad - end_x * end_x);
197 if (draw_arc->end.y < 0) end_y = - end_y;
198 */
199
200 start = atan2 (start_y,start_x);
201 end = atan2 ( end_y, end_x);
202
203 /* rad = sqrt(start_x*start_x + start_y*start_y); */
204
205 /* Construct middle point: */
206 if (end < start) end += M_2PI;
207 mid = 0.5 * (start + end);
208
209 mid_x = Ox + (rad * cos (mid));
210 mid_y = Oy + (rad * sin (mid));
211
212 /* Shift to origin: */
213 start_x = Ox + start_x;
214 start_y = Oy + start_y;
215 end_x = Ox + end_x;
216 end_y = Oy + end_y;
217
218 wmf_stream_printf (API,out,
219 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %f %f %d %d %d %d %d %d\n",
220 O_ARC,
221 sub_type,
222 fig.line_style,
223 fig.thickness,
224 fig.pen_color,
225 fig.fill_color,
226 ddata->depth,
227 fig.pen_style,
228 fig.area_fill,
229 fig.style_val,
230 fig.cap_style,
231 direction,
232 fig.forward_arrow,
233 fig.backward_arrow,
234 (float) Ox,
235 (float) Oy,
236 (int) start_x,
237 (int) start_y,
238 (int) mid_x,
239 (int) mid_y,
240 (int) end_x,
241 (int) end_y);
242 }
243
wmf_fig_draw_ellipse(wmfAPI * API,wmfDrawArc_t * draw_arc)244 static void wmf_fig_draw_ellipse (wmfAPI* API,wmfDrawArc_t* draw_arc)
245 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
246
247 wmfStream* out = ddata->out;
248
249 figDC fig;
250
251 figPoint TL;
252 figPoint BR;
253
254 float angle;
255
256 int sub_type;
257 int direction;
258
259 int Ox;
260 int Oy;
261 int a;
262 int b;
263
264 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_ellipse");
265
266 wmf_stream_printf (API,out,"# wmf_[fig_]draw_ellipse\n");
267
268 fig_set_style (API,draw_arc->dc,&fig);
269
270 sub_type = 1;
271
272 ddata->depth -= ddata->ddec;
273
274 direction = 1;
275
276 angle = 0.0;
277
278 TL = fig_translate (API,draw_arc->TL);
279 BR = fig_translate (API,draw_arc->BR);
280
281 /* origin of ellipse */
282 Ox = (BR.x + TL.x + 1) / 2;
283 Oy = (BR.y + TL.y + 1) / 2;
284
285 /* axes of ellipse */
286 a = (BR.x - TL.x + 1) / 2;
287 b = (BR.y - TL.y + 1) / 2;
288
289 wmf_stream_printf (API,out,
290 "%d %d %d %d %d %d %d %d %d %f %d %f %d %d %d %d %d %d %d %d\n",
291 O_ELLIPSE,
292 sub_type,
293 fig.line_style,
294 fig.thickness,
295 fig.pen_color,
296 fig.fill_color,
297 ddata->depth,
298 fig.pen_style,
299 fig.area_fill,
300 fig.style_val,
301 direction,
302 angle,
303 Ox,
304 Oy,
305 a,
306 b,
307 Ox,
308 Oy,
309 (Ox + a),
310 (Oy + b));
311
312 wmf_stream_printf (API,out,"# end draw_ellipse\n");
313 }
314
wmf_fig_draw_line(wmfAPI * API,wmfDrawLine_t * draw_line)315 static void wmf_fig_draw_line (wmfAPI* API,wmfDrawLine_t* draw_line)
316 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
317
318 wmfStream* out = ddata->out;
319
320 figDC fig;
321
322 figPoint from;
323 figPoint to;
324
325 int npoints;
326
327 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_line");
328
329 if (out == 0) return;
330
331 if (TO_DRAW (draw_line))
332 { wmf_stream_printf (API,out,"# wmf_[fig_]draw_line\n");
333
334 fig_set_style (API,draw_line->dc,&fig);
335
336 ddata->depth -= ddata->ddec;
337
338 npoints = 2;
339
340 wmf_stream_printf (API,out,
341 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
342 O_POLYLINE,
343 T_POLYLINE,
344 fig.line_style,
345 fig.thickness,
346 fig.pen_color,
347 fig.fill_color,
348 ddata->depth,
349 fig.pen_style,
350 fig.area_fill,
351 fig.style_val,
352 fig.join_style,
353 fig.cap_style,
354 fig.radius,
355 fig.forward_arrow,
356 fig.backward_arrow,
357 npoints);
358
359 from = fig_translate (API,draw_line->from);
360 to = fig_translate (API,draw_line->to );
361
362 wmf_stream_printf (API,out,
363 "%d %d\n%d %d\n",
364 from.x,
365 from.y,
366 to.x,
367 to.y);
368
369 wmf_stream_printf (API,out,"# end draw_line\n");
370 }
371 }
372
wmf_fig_poly_line(wmfAPI * API,wmfPolyLine_t * poly_line)373 static void wmf_fig_poly_line (wmfAPI* API,wmfPolyLine_t* poly_line)
374 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
375
376 wmfStream* out = ddata->out;
377
378 wmfPolyLine_t sub_line;
379
380 figDC fig;
381
382 figPoint pt;
383
384 U16 i;
385 U16 sub_length;
386 U16 sub_count;
387
388 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]poly_line");
389
390 if (out == 0) return;
391
392 if (poly_line->count > 500)
393 { sub_length = poly_line->count / (1 + poly_line->count / 500);
394 sub_count = 0;
395
396 sub_line.dc = poly_line->dc;
397 sub_line.pt = poly_line->pt;
398
399 while (poly_line->count > sub_count + 1)
400 { sub_line.count = MIN (sub_length,poly_line->count - sub_count);
401
402 wmf_fig_poly_line (API,&sub_line);
403 sub_line.pt += sub_line.count - 1;
404 sub_count += sub_line.count - 1;
405 }
406 }
407 else if ((poly_line->count > 1) && TO_DRAW (poly_line))
408 { fig_set_style (API,poly_line->dc,&fig); /* fjf - the logic may have change here ?? */
409
410 fig.area_fill = -1; /* override fill settings */
411
412 ddata->depth -= ddata->ddec;
413
414 wmf_stream_printf (API,out,"# wmf_[fig_]poly_line\n");
415
416 wmf_stream_printf (API,out,
417 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
418 O_POLYLINE,
419 T_POLYLINE,
420 fig.line_style,
421 fig.thickness,
422 fig.pen_color,
423 fig.fill_color,
424 ddata->depth,
425 fig.pen_style,
426 fig.area_fill,
427 fig.style_val,
428 fig.join_style,
429 fig.cap_style,
430 fig.radius,
431 fig.forward_arrow,
432 fig.backward_arrow,
433 poly_line->count);
434
435
436 /* Output co-ordinate pairs: */
437 for (i = 0; i < poly_line->count; i++)
438 { pt = fig_translate (API,poly_line->pt[poly_line->count-1-i]);
439
440 wmf_stream_printf (API,out,"%d %d\n",pt.x,pt.y);
441 }
442
443 wmf_stream_printf (API,out,"# end poly_line\n");
444 }
445 }
446
wmf_fig_draw_polygon(wmfAPI * API,wmfPolyLine_t * poly_line)447 static void wmf_fig_draw_polygon (wmfAPI* API,wmfPolyLine_t* poly_line)
448 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
449
450 wmfStream* out = ddata->out;
451
452 figDC fig;
453
454 figPoint pt;
455
456 U16 i;
457
458 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_polygon");
459
460 if (out == 0) return;
461
462 if (poly_line->count > 500)
463 { if (API->flags & WMF_OPT_IGNORE_NONFATAL)
464 { WMF_DEBUG (API,"Too many points on polygon!");
465 }
466 else
467 { WMF_ERROR (API,"Too many points on polygon!");
468 API->err = wmf_E_Glitch;
469 }
470 }
471 else if (poly_line->count > 2)
472 { fig_set_style (API,poly_line->dc,&fig);
473
474 ddata->depth -= ddata->ddec;
475
476 if (TO_FILL (poly_line))
477 { wmf_stream_printf (API,out,"# wmf_[fig_]draw_polygon\n");
478
479 wmf_stream_printf (API,out,
480 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
481 O_POLYLINE,
482 T_POLYGON,
483 fig.line_style,
484 fig.thickness,
485 fig.pen_color,
486 fig.fill_color,
487 ddata->depth,
488 fig.pen_style,
489 fig.area_fill,
490 fig.style_val,
491 fig.join_style,
492 fig.cap_style,
493 fig.radius,
494 fig.forward_arrow,
495 fig.backward_arrow,
496 poly_line->count + 1);
497
498 for (i = 0; i < poly_line->count; i++)
499 { pt = fig_translate (API,poly_line->pt[i]);
500
501 wmf_stream_printf (API,out,"%d %d\n",pt.x,pt.y);
502 }
503
504 pt = fig_translate (API,poly_line->pt[0]);
505
506 wmf_stream_printf (API,out,"%d %d\n",pt.x,pt.y);
507
508 wmf_stream_printf (API,out,"# end draw_polygon\n");
509 }
510 if (TO_DRAW (poly_line))
511 { fig.area_fill = -1;
512
513 fig.thickness++;
514
515 wmf_stream_printf (API,out,"# wmf_[fig_]draw_polygon\n");
516
517 wmf_stream_printf (API,out,
518 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
519 O_POLYLINE,
520 T_POLYGON,
521 fig.line_style,
522 fig.thickness,
523 fig.pen_color,
524 fig.fill_color,
525 ddata->depth,
526 fig.pen_style,
527 fig.area_fill,
528 fig.style_val,
529 fig.join_style,
530 fig.cap_style,
531 fig.radius,
532 fig.forward_arrow,
533 fig.backward_arrow,
534 poly_line->count + 1);
535
536 for (i = 0; i < poly_line->count; i++)
537 { pt = fig_translate (API,poly_line->pt[poly_line->count-1-i]);
538
539 wmf_stream_printf (API,out,"%d %d\n",pt.x,pt.y);
540 }
541
542 pt = fig_translate (API,poly_line->pt[poly_line->count-1]);
543
544 wmf_stream_printf (API,out,"%d %d\n",pt.x,pt.y);
545
546 wmf_stream_printf (API,out,"# end draw_polygon\n");
547 }
548 }
549 }
550
wmf_fig_draw_rectangle(wmfAPI * API,wmfDrawRectangle_t * draw_rect)551 static void wmf_fig_draw_rectangle (wmfAPI* API,wmfDrawRectangle_t* draw_rect)
552 { wmf_fig_t* ddata = WMF_FIG_GetData (API);
553
554 wmfStream* out = ddata->out;
555
556 figDC fig;
557
558 figPoint TL;
559 figPoint BR;
560
561 WMF_DEBUG (API,"~~~~~~~~wmf_[fig_]draw_rectangle");
562
563 if (out == 0) return;
564
565 fig_set_style (API,draw_rect->dc,&fig);
566
567 ddata->depth -= ddata->ddec;
568
569 TL = fig_translate (API,draw_rect->TL);
570 BR = fig_translate (API,draw_rect->BR);
571
572 if (TO_FILL (draw_rect))
573 { wmf_stream_printf (API,out,"# wmf_[fig_]draw_rectangle\n");
574
575 wmf_stream_printf (API,out,
576 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
577 O_POLYLINE,
578 T_BOX,
579 fig.line_style,
580 fig.thickness,
581 fig.pen_color,
582 fig.fill_color,
583 ddata->depth,
584 fig.pen_style,
585 fig.area_fill,
586 fig.style_val,
587 fig.join_style,
588 fig.cap_style,
589 fig.radius,
590 fig.forward_arrow,
591 fig.backward_arrow,
592 5);
593
594 wmf_stream_printf (API,out,"%d %d\n%d %d\n%d %d\n%d %d\n%d %d\n",
595 TL.x,TL.y,
596 TL.x,BR.y,
597 BR.x,BR.y,
598 BR.x,TL.y,
599 TL.x,TL.y);
600
601 wmf_stream_printf (API,out,"# end draw_rectangle\n");
602 }
603 if (TO_DRAW (draw_rect))
604 { fig.area_fill = -1;
605
606 fig.thickness++;
607
608 wmf_stream_printf (API,out,"# wmf_[fig_]draw_rectangle\n");
609
610 wmf_stream_printf (API,out,
611 "%d %d %d %d %d %d %d %d %d %f %d %d %d %d %d %d\n",
612 O_POLYLINE,
613 T_BOX,
614 fig.line_style,
615 fig.thickness,
616 fig.pen_color,
617 fig.fill_color,
618 ddata->depth,
619 fig.pen_style,
620 fig.area_fill,
621 fig.style_val,
622 fig.join_style,
623 fig.cap_style,
624 fig.radius,
625 fig.forward_arrow,
626 fig.backward_arrow,
627 5);
628
629 wmf_stream_printf (API,out,"%d %d\n%d %d\n%d %d\n%d %d\n %d %d\n",
630 TL.x,TL.y,
631 TL.x,BR.y,
632 BR.x,BR.y,
633 BR.x,TL.y,
634 TL.x,TL.y);
635
636 wmf_stream_printf (API,out,"# end draw_rectangle\n");
637 }
638 }
639