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