1 /*
2 Copyright (C) 2019-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: WxdkdrawObj.cpt
12 */
13 
14 /**	@file WxdkdrawObj.cpp The WxdkdrawObj module.
15 */
16 
17 
18 #include <wxdkdraw/wxdkdraw.h>
19 
20 #if	DK4_HAVE_MATH_H
21 #ifndef	MATH_H_INCLUDED
22 #include <math.h>
23 #define MATH_H_INCLUDED 1
24 #endif
25 #endif
26 
27 #ifndef	DK4MATH_H_INCLUDED
28 #include <libdk4c/dk4math.h>
29 #endif
30 
31 #ifndef	DK4BIF_H_INCLUDED
32 #include <libdk4bif/dk4bif.h>
33 #endif
34 
35 
36 #ifndef	DK4MAAU16_H_INCLUDED
37 #include <libdk4ma/dk4maau16.h>
38 #endif
39 
40 #ifndef	DK4MAAI16_H_INCLUDED
41 #include <libdk4ma/dk4maai16.h>
42 #endif
43 
44 #ifndef	DK4MAAI32_H_INCLUDED
45 #include <libdk4ma/dk4maai32.h>
46 #endif
47 
48 
49 
50 
51 
52 /**	Image types handled by wxdkdraw.
53 */
54 static const Wxd_suffix_and_type_t	image_type_suffixes[] = {
55 	{ wxT(".png")	,	wxBITMAP_TYPE_PNG	} ,
56 	{ wxT(".jpg")	,	wxBITMAP_TYPE_JPEG	} ,
57 	{ wxT(".jpeg")	,	wxBITMAP_TYPE_JPEG	} ,
58 	{ wxT(".pbm")	,	wxBITMAP_TYPE_PNM	} ,
59 	{ wxT(".pgm")	,	wxBITMAP_TYPE_PNM	} ,
60 	{ wxT(".ppm")	,	wxBITMAP_TYPE_PNM	} ,
61 	{ wxT(".pnm")	,	wxBITMAP_TYPE_PNM	} ,
62 	{ wxT(".pam")	,	wxBITMAP_TYPE_PNM	} ,
63 	{ wxT(".tif")	,	wxBITMAP_TYPE_TIF	} ,
64 	{ wxT(".tiff")	,	wxBITMAP_TYPE_TIFF	} ,
65 	{ NULL			,	wxBITMAP_TYPE_INVALID }
66 };
67 
68 
69 
70 /**	Angles to check when calculating arc bounding box.
71 */
72 static double arc_angles[] = {
73 	(-4.0 * M_PI),
74 	(-3.0 * M_PI - M_PI_2),
75 	(-3.0 * M_PI),
76 	(-2.0 * M_PI - M_PI_2),
77 	(-2.0 * M_PI),
78 	(-1.0 * M_PI - M_PI_2),
79 	(-1.0 * M_PI),
80 	(-1.0 * M_PI_2),
81 	0.0,
82 	M_PI_2,
83 	M_PI,
84 	(M_PI + M_PI_2),
85 	(2.0 * M_PI),
86 	(2.0 * M_PI + M_PI_2),
87 	(3.0 * M_PI),
88 	(3.0 * M_PI + M_PI_2)
89 };
90 
91 
92 
93 /**	Number of elements in arc_angles array.
94 */
95 static const size_t	sz_arc_angles = sizeof(arc_angles)/sizeof(double);
96 
97 
98 
99 /**	Flip coordinate value.
100 	@param	min	Bounding box minimum.
101 	@param	max	Bounding box maximum.
102 	@param	v	Value to flip.
103 	@param	erp	Error report, may be NULL.
104 	@return	Flip result.
105 */
106 static
107 int32_t
wxdobj_flip_coordinate(int32_t min,int32_t max,int32_t v,dk4_er_t * erp)108 wxdobj_flip_coordinate(int32_t min, int32_t max, int32_t v, dk4_er_t *erp)
109 {
110 	dk4_er_t	er;
111 	int32_t		back	= (int32_t)0L;
112 
113 	dk4error_init(&er);
114 	back = dk4ma_int32_t_sub(dk4ma_int32_t_add(min, max, &er), v, &er);
115 	if (DK4_E_NONE != er.ec) {
116 		dk4error_init(&er);
117 		back = dk4ma_int32_t_add(min, dk4ma_int32_t_sub(max, v, &er), &er);
118 		if (DK4_E_NONE != er.ec) {
119 			dk4error_init(&er);
120 			back = dk4ma_int32_t_add(max, dk4ma_int32_t_sub(min, v, &er), &er);
121 			if (DK4_E_NONE != er.ec) {
122 				dk4error_init(&er);
123 				back = dk4ma_int32_from_double(
124 					((double)min + (double)max - (double)v),	&er
125 				);
126 				if (DK4_E_NONE != er.ec) {
127 					dk4error_copy(erp, &er);
128 				}
129 			}
130 		}
131 	}
132 	return back;
133 }
134 
135 
136 
137 /**	Set bounding box x and y value.
138 	Use this function to add the first point.
139 	@param	pbox	Bounding box to set.
140 	@param	x		X coordinate.
141 	@param	y		Y coordinate.
142 */
143 static
144 void
wxdobj_bb_set_point(Wxd_bb_t * pbox,int32_t x,int32_t y)145 wxdobj_bb_set_point(
146 	Wxd_bb_t	*pbox,
147 	int32_t		 x,
148 	int32_t		 y
149 )
150 {
151 	if (NULL != pbox) {
152 		pbox->xl = pbox->xr = x;
153 		pbox->yb = pbox->yt = y;
154 	}
155 }
156 
157 
158 
159 /**	Add bounding box x and y value.
160 	Use this function to add further points.
161 	@param	pbox	Bounding box to set.
162 	@param	x		X coordinate.
163 	@param	y		Y coordinate.
164 */
165 static
166 void
wxdobj_bb_add_point(Wxd_bb_t * pbox,int32_t x,int32_t y)167 wxdobj_bb_add_point(
168 	Wxd_bb_t	*pbox,
169 	int32_t		 x,
170 	int32_t		 y
171 )
172 {
173 	if (NULL != pbox) {
174 		if (x < pbox->xl) { pbox->xl = x; }
175 		if (x > pbox->xr) { pbox->xr = x; }
176 		if (y < pbox->yb) { pbox->yb = y; }
177 		if (y > pbox->yt) { pbox->yt = y; }
178 	}
179 }
180 
181 
182 
183 bool
wxdobj_bb_add_bb(Wxd_bb_t * pbox,Wxd_bb_t const * psrc)184 wxdobj_bb_add_bb(
185 	Wxd_bb_t		*pbox,
186 	Wxd_bb_t const	*psrc
187 )
188 {
189 	bool		back	= false;
190 	if ((NULL != pbox) && (NULL != psrc)) {
191 		wxdobj_bb_add_point(pbox, psrc->xl, psrc->yb);
192 		wxdobj_bb_add_point(pbox, psrc->xr, psrc->yt);
193 		back = true;
194 	}
195 	return back;
196 }
197 
198 
199 
200 void
wxdobj_report_object(Wxd_object_t * pobj)201 wxdobj_report_object(
202 #if	TRACE_DEBUG
203 	Wxd_object_t	*pobj
204 #else
205 	Wxd_object_t	* DK4_ARG_UNUSED(pobj)
206 #endif
207 )
208 {
209 #if	TRACE_DEBUG
210 	double			s;
211 	uint16_t		i;
212 	int32_t			x;
213 	int32_t			y;
214 
215 	if (NULL != pobj) {
216 		switch (pobj->ot) {
217 			case WXD_OT_GROUP_BEGIN : {
218 
219 			} break;
220 			case WXD_OT_TEXT : {
221 
222 			} break;
223 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
224 				if (WXD_OT_POLYLINE == pobj->ot) {
225 
226 				}
227 				else {
228 
229 				}
230 
231 				if (NULL != (pobj->det).p.p) {
232 				for (i = 0; i < (pobj->det).p.n; i++) {
233 					x = ((pobj->det).p.p)[i].x;
234 					y = ((pobj->det).p.p)[i].y;
235 
236 				}
237 				}
238 				else {
239 
240 				}
241 			} break;
242 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
243 				if (WXD_OT_O_SPLINE == pobj->ot) {
244 
245 				}
246 				else {
247 
248 				}
249 
250 				if (NULL != (pobj->det).p.p) {
251 					for (i = 0; i < (pobj->det).s.n; i++) {
252 						x = ((pobj->det).s.p)[i].x;
253 						y = ((pobj->det).s.p)[i].y;
254 						s = ((pobj->det).s.p)[i].s;
255 
256 					}
257 				}
258 				else {
259 
260 				}
261 			} break;
262 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
263 				if (WXD_OT_O_ARC == pobj->ot) {
264 
265 				}
266 				else {
267 
268 				}
269 			} break;
270 			case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
271 				if (WXD_OT_CIRCLE == pobj->ot) {
272 
273 				}
274 				else {
275 
276 				}
277 
278 
279 
280 
281 
282 			} break;
283 			case WXD_OT_BOX : {
284 
285 			} break;
286 			case WXD_OT_IMAGE : {
287 
288 			} break;
289 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
290 				if (WXD_OT_DOT_FILLED == pobj->ot) {
291 
292 				}
293 				else {
294 
295 				}
296 			} break;
297 			default : {
298 			} break;
299 		}
300 	}
301 	else {
302 	}
303 
304 #else
305 	DK4_UNUSED_ARG(pobj)
306 #endif
307 }
308 
309 
310 
311 bool
wxdobj_is_active(Wxd_object_t * pobj)312 wxdobj_is_active(Wxd_object_t *pobj)
313 {
314 	bool		back	= false;
315 
316 	if (NULL != pobj) {
317 		back = true;
318 		if (NULL != pobj->play) {
319 			if ((uint8_t)0x00 == pobj->play->active) {
320 				back = false;
321 			}
322 		}
323 	}
324 
325 	return back;
326 }
327 
328 
329 
330 wxBitmapType
wxdobj_image_type(wxChar const * fn)331 wxdobj_image_type(wxChar const *fn)
332 {
333 	wxChar const				*suffix;
334 	Wxd_suffix_and_type_t const	*tptr;
335 	wxBitmapType				 back	= wxBITMAP_TYPE_INVALID;
336 
337 	suffix = dk4strx_get_path_suffix(fn, NULL);
338 	if (NULL != suffix) {
339 		tptr = image_type_suffixes;
340 		while ((NULL != tptr->suffix) && (wxBITMAP_TYPE_INVALID == back)) {
341 			if (0 == dk4strx_casecmp(tptr->suffix, suffix)) {
342 				back = tptr->t;
343 			}
344 			else {
345 				tptr++;
346 			}
347 		}
348 	}
349 	return back;
350 }
351 
352 
353 
354 void
wxdobj_det_init_bb(Wxd_bb_t * pdst)355 wxdobj_det_init_bb(Wxd_bb_t *pdst)
356 {
357 
358 	if (NULL != pdst) {
359 		DK4_MEMRES(pdst,sizeof(Wxd_bb_t));
360 		pdst->xl	= (int32_t)0L;
361 		pdst->xr	= (int32_t)0L;
362 		pdst->yb	= (int32_t)0L;
363 		pdst->yt	= (int32_t)0L;
364 	}
365 }
366 
367 
368 void
wxdobj_det_init_text(Wxd_det_text_t * pdst)369 wxdobj_det_init_text(Wxd_det_text_t *pdst)
370 {
371 
372 	if (NULL != pdst) {
373 		DK4_MEMRES(pdst,sizeof(Wxd_det_text_t));
374 		pdst->t		= NULL;
375 		pdst->tsc	= NULL;
376 		pdst->font	= NULL;
377 		pdst->x		= (int32_t)0L;
378 		pdst->y		= (int32_t)0L;
379 		pdst->fsz	= (uint16_t)12U;
380 		pdst->a		= (int16_t)0;
381 		pdst->find	= (uint8_t)0U;
382 		pdst->al	= WXD_TA_LEFT;
383 		pdst->fl	= 0x01;
384 		pdst->font	= NULL;
385 	}
386 }
387 
388 
389 
390 void
wxdobj_det_init_poly(Wxd_det_pl_t * pdst)391 wxdobj_det_init_poly(Wxd_det_pl_t *pdst)
392 {
393 
394 	if (NULL != pdst) {
395 		DK4_MEMRES(pdst,sizeof(Wxd_det_pl_t));
396 		pdst->p = NULL;
397 		pdst->n = (uint16_t)0U;
398 	}
399 }
400 
401 
402 
403 void
wxdobj_det_init_spline(Wxd_det_xs_t * pdst)404 wxdobj_det_init_spline(Wxd_det_xs_t *pdst)
405 {
406 
407 	if (NULL != pdst) {
408 		DK4_MEMRES(pdst,sizeof(Wxd_det_xs_t));
409 		pdst->p = NULL;
410 		pdst->n = (uint16_t)0U;
411 	}
412 }
413 
414 
415 
416 void
wxdobj_det_init_arc(Wxd_det_arc_t * pdst)417 wxdobj_det_init_arc(Wxd_det_arc_t *pdst)
418 {
419 
420 	if (NULL != pdst) {
421 		DK4_MEMRES(pdst,sizeof(Wxd_det_arc_t));
422 		pdst->a		= 0.0;
423 		pdst->b		= 360.0;
424 		pdst->x		= 0.0;
425 		pdst->y		= 0.0;
426 		pdst->r		= 0.0;
427 		pdst->x1	= (int32_t)0L;
428 		pdst->y1	= (int32_t)0L;
429 		pdst->x2	= (int32_t)0L;
430 		pdst->y2	= (int32_t)0L;
431 		pdst->x3	= (int32_t)0L;
432 		pdst->y3	= (int32_t)0L;
433 		pdst->d		= (int8_t)0;
434 	}
435 }
436 
437 
438 
439 void
wxdobj_det_init_ellipse(Wxd_det_ellipse_t * pdst)440 wxdobj_det_init_ellipse(Wxd_det_ellipse_t *pdst)
441 {
442 
443 	if (NULL != pdst) {
444 		DK4_MEMRES(pdst,sizeof(Wxd_det_ellipse_t));
445 		pdst->x  = (int32_t)0L;
446 		pdst->y  = (int32_t)0L;
447 		pdst->rx = (uint32_t)0UL;
448 		pdst->ry = (uint32_t)0UL;
449 		pdst->a  = (int16_t)0;
450 	}
451 }
452 
453 
454 
455 void
wxdobj_det_init_box(Wxd_det_box_t * pdst)456 wxdobj_det_init_box(Wxd_det_box_t *pdst)
457 {
458 
459 	if (NULL != pdst) {
460 		DK4_MEMRES(pdst,sizeof(Wxd_det_box_t));
461 		wxdobj_det_init_bb(&(pdst->b));
462 		pdst->r = (uint32_t)0UL;
463 	}
464 }
465 
466 
467 
468 void
wxdobj_det_init_image(Wxd_det_image_t * pdst)469 wxdobj_det_init_image(Wxd_det_image_t *pdst)
470 {
471 
472 	if (NULL != pdst) {
473 		DK4_MEMRES(pdst,sizeof(Wxd_det_image_t));
474 		pdst->fn	= NULL;
475 		pdst->bm	= NULL;
476 		dk4bb_init(&(pdst->pl));
477 		wxdobj_det_init_bb(&(pdst->br));
478 		pdst->xres	= -1.0;
479 		pdst->yres	= -1.0;
480 		pdst->fl	= WXD_IMFL_ASPECT	| WXD_IMFL_USE_ALPHA
481 					| WXD_IMFL_IMG_INT	| WXD_IMFL_USE_DCT;
482 		pdst->r2g	= (int8_t)(-1);
483 		pdst->r2c	= (int8_t)(-1);
484 		pdst->t		= wxBITMAP_TYPE_INVALID;
485 	}
486 }
487 
488 
489 
490 void
wxdobj_det_init_dot(Wxd_det_dot_t * pdst)491 wxdobj_det_init_dot(Wxd_det_dot_t *pdst)
492 {
493 
494 	if (NULL != pdst) {
495 		DK4_MEMRES(pdst,sizeof(Wxd_det_dot_t));
496 		pdst->x	= (int32_t)0L;
497 		pdst->y	= (int32_t)0L;
498 		pdst->d	= (uint16_t)0U;
499 	}
500 }
501 
502 
503 
504 /**	Initialize object, use template if specified.
505 	@param	pdst	Object to initialize.
506 	@param	ot		Object type.
507 	@param	ptpl	Template object, may be NULL.
508 */
509 void
wxdobj_obj_init(Wxd_object_t * pdst,int ot,Wxd_object_t const * ptpl)510 wxdobj_obj_init(Wxd_object_t *pdst, int ot, Wxd_object_t const *ptpl)
511 {
512 
513 	if (NULL != ptpl) {
514 		/*
515 			Apply template settings
516 		*/
517 		DK4_MEMCPY(pdst,ptpl,sizeof(Wxd_object_t));
518 	}
519 	else {
520 		/*
521 			Apply default settings
522 		*/
523 		DK4_MEMRES(pdst,sizeof(Wxd_object_t));
524 		pdst->lay	= 0;
525 		pdst->lw	= 2;
526 		pdst->fc[0]	= (uint8_t)255U;
527 		pdst->fc[1]	= (uint8_t)255U;
528 		pdst->fc[2]	= (uint8_t)255U;
529 		pdst->sc[0]	= (uint8_t)0U;
530 		pdst->sc[1]	= (uint8_t)0U;
531 		pdst->sc[2]	= (uint8_t)0U;
532 		pdst->cs	= (uint8_t)(WXD_LC_BUTTED);
533 		pdst->fs	= (uint8_t)(WXD_FS_NONE);
534 		pdst->ls	= (uint8_t)(WXD_LS_SOLID);
535 		pdst->sl	= (uint8_t)4U;
536 		pdst->js	= (uint8_t)(WXD_LJ_MITERED);
537 		pdst->ml	= (uint8_t)8U;
538 		pdst->aft	= (uint8_t)0U;
539 		pdst->afl	= (uint8_t)16U;
540 		pdst->afw	= (uint8_t)8U;
541 		pdst->abt	= (uint8_t)0U;
542 		pdst->abl	= (uint8_t)16U;
543 		pdst->abw	= (uint8_t)8U;
544 		pdst->mark	= (uint8_t)0U;
545 	}
546 	pdst->pa   = NULL;
547 	pdst->psti = NULL;
548 	pdst->play = NULL;
549 	pdst->ot   = (int8_t)ot;
550 	dk4bb_init(&(pdst->bb));
551 	/*
552 		Use default values for details if no template was specified
553 		or template object type does not match
554 	*/
555 	if ((NULL == ptpl) || ((NULL != ptpl) && (ot != ptpl->ot))) {
556 		switch (ot) {
557 			case WXD_OT_GROUP_BEGIN : {
558 			} break;
559 			case WXD_OT_TEXT : {
560 				wxdobj_det_init_text(&((pdst->det).t));
561 			} break;
562 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
563 				wxdobj_det_init_poly(&((pdst->det).p));
564 			} break;
565 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
566 				wxdobj_det_init_spline(&((pdst->det).s));
567 			} break;
568 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
569 				wxdobj_det_init_arc(&((pdst->det).a));
570 			} break;
571 			case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
572 				wxdobj_det_init_ellipse(&((pdst->det).e));
573 			} break;
574 			case WXD_OT_BOX : {
575 				wxdobj_det_init_box(&((pdst->det).b));
576 			} break;
577 			case WXD_OT_IMAGE : {
578 				wxdobj_det_init_image(&((pdst->det).i));
579 			} break;
580 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
581 				wxdobj_det_init_dot(&((pdst->det).d));
582 			} break;
583 		}
584 	}
585 	/*
586 		Make sure not to re-use dynamic objects from template.
587 	*/
588 	switch (ot) {
589 		case WXD_OT_GROUP_BEGIN : {
590 			(pdst->det).g.s_e = NULL;
591 			(pdst->det).g.i_e = NULL;
592 		} break;
593 		case WXD_OT_TEXT : {
594 			(pdst->det).t.t		= NULL;
595 			(pdst->det).t.tsc	= NULL;
596 			/*
597 				2020-01-05	Set font to NULL too.
598 			*/
599 			(pdst->det).t.font	= NULL;
600 		} break;
601 		case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
602 			(pdst->det).p.n = (uint16_t)0U;
603 			(pdst->det).p.p = NULL;
604 		} break;
605 		case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
606 			(pdst->det).s.n = (uint16_t)0U;
607 			(pdst->det).s.p = NULL;
608 		} break;
609 		case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
610 		} break;
611 		case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
612 		} break;
613 		case WXD_OT_BOX : {
614 		} break;
615 		case WXD_OT_IMAGE : {
616 			(pdst->det).i.fn = NULL;
617 			(pdst->det).i.bm = NULL;
618 		} break;
619 		case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
620 		} break;
621 	}
622 }
623 
624 
625 
626 /**	Check whether a layer is used in a drawing, remove layer if unused.
627 	@param	pdrw	Drawing to check and modify.
628 	@param	play	Layer to check and probably remove.
629 */
630 
631 static
632 void
i_check_layer_structure_removal(Wxd_drawing_t * pdrw,Wxd_layer_t * play)633 i_check_layer_structure_removal(Wxd_drawing_t *pdrw, Wxd_layer_t *play)
634 {
635 	Wxd_object_t	*pobj;
636 
637 	play->used = 0x00;
638 	dk4sto_it_reset(pdrw->i_flat);
639 	do {
640 		pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
641 		if (NULL != pobj) {
642 			if (NULL != pobj->play) {
643 				pobj->play->used = 0x01;
644 			}
645 		}
646 	} while (NULL != pobj);
647 	if (0x00 == play->used) {
648 		dk4sto_remove(pdrw->s_layers, play, NULL);
649 		dk4sto_it_reset(pdrw->i_layers);
650 		dk4mem_free(play);
651 	}
652 
653 }
654 
655 
656 
657 /**	Find group for object.
658 	@param	pdrw	Drawing containing the object.
659 	@param	pobj	Object to search for.
660 	@return	Valid pointer on success, NULL if not found.
661 
662 */
663 
664 static
665 Wxd_object_t *
i_find_group_for(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)666 i_find_group_for(Wxd_drawing_t *pdrw, Wxd_object_t *pobj)
667 {
668 	Wxd_object_t	*back	=	NULL;	/* Result */
669 	Wxd_object_t	*pgrc	=	NULL;	/* Group candidate */
670 	Wxd_object_t	*pgrp	=	NULL;	/* Current (sub)group tested */
671 	Wxd_object_t	*pno	=	NULL;	/* Next object */
672 	void			*pt		=	NULL;	/* Test whether object contained */
673 
674 	dk4sto_it_reset(pdrw->i_stru);
675 	do {
676 		pgrc = (Wxd_object_t *)dk4sto_it_next(pdrw->i_stru);
677 		if (NULL != pgrc) {
678 			if (WXD_OT_GROUP_BEGIN == pgrc->ot) {
679 				if (NULL != dk4sto_it_find_exact((pgrc->det).g.i_e, pobj)) {
680 					/*
681 						Object found in top-level group
682 					*/
683 					back = pgrc;
684 				}
685 				else {
686 					/*
687 						Must search group structure recursively
688 					*/
689 					pgrp = pgrc;
690 					dk4sto_it_reset((pgrp->det).g.i_e);
691 					while ((NULL != pgrp) && (NULL == back)) {
692 						pno = (Wxd_object_t *)dk4sto_it_next((pgrp->det).g.i_e);
693 						if (NULL != pno) {
694 							if (WXD_OT_GROUP_BEGIN == pno->ot) {
695 								pt =
696 								dk4sto_it_find_exact((pno->det).g.i_e, pobj);
697 								if (NULL != pt) {
698 									back = pno;
699 								}
700 								else {
701 									pgrp = pno;
702 									dk4sto_it_reset((pgrp->det).g.i_e);
703 								}
704 							}
705 						}
706 						else {
707 							/*
708 								No more objects in group, go up 1 level
709 							*/
710 							pgrp = pgrp->pa;
711 						}
712 					}
713 				}
714 			}
715 		}
716 	} while ((NULL != pgrc) && (NULL == back));
717 #if	TRACE_DEBUG
718 	if (NULL == back) {
719 	}
720 #endif
721 
722 	return back;
723 }
724 
725 
726 
727 void
wxdobj_obj_delete(Wxd_object_t * pobj)728 wxdobj_obj_delete(Wxd_object_t *pobj)
729 {
730 
731 	if (NULL != pobj) {
732 		switch ( (int)(pobj->ot) ) {
733 			case WXD_OT_GROUP_BEGIN : {
734 				if (NULL != (pobj->det).g.i_e) {
735 					dk4sto_it_close((pobj->det).g.i_e);
736 				}
737 				if (NULL != (pobj->det).g.s_e) {
738 					dk4sto_close((pobj->det).g.s_e);
739 				}
740 				(pobj->det).g.s_e = NULL;
741 				(pobj->det).g.i_e = NULL;
742 			} break;
743 			case WXD_OT_TEXT : {
744 				dk4mem_release((pobj->det).t.t);
745 				dk4mem_release((pobj->det).t.tsc);
746 			} break;
747 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
748 				dk4mem_release((pobj->det).p.p);
749 			} break;
750 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
751 				dk4mem_release((pobj->det).s.p);
752 			} break;
753 			case WXD_OT_IMAGE : {
754 				dk4mem_release((pobj->det).i.fn);
755 				if (NULL != (pobj->det).i.bm) {
756 					delete (pobj->det).i.bm;
757 					(pobj->det).i.bm = NULL;
758 				}
759 #if	TRACE_DEBUG
760 				else {
761 				}
762 #endif
763 			} break;
764 #if	TRACE_DEBUG
765 			case WXD_OT_O_ARC : {
766 			} break;
767 			case WXD_OT_C_ARC : {
768 			} break;
769 			case WXD_OT_CIRCLE : {
770 			} break;
771 			case WXD_OT_ELLIPSE : {
772 			} break;
773 			case WXD_OT_BOX : {
774 			} break;
775 			case WXD_OT_DOT_FILLED : {
776 			} break;
777 			case WXD_OT_DOT_WHITE : {
778 			} break;
779 			default : {
780 			} break;
781 #endif
782 		}
783 		dk4mem_free(pobj);
784 	}
785 #if	TRACE_DEBUG
786 	else {
787 	}
788 #endif
789 
790 }
791 
792 
793 
794 /**	Internally delete a group structure recursively.
795 	@param	pgrp	Group structure object to delete
796 					(must not be NULL, must be WXD_OT_GROUP_BEGIN type,
797 					s_e and i_e must not be NULL).
798 */
799 static
800 void
grp_delete_recursive(Wxd_object_t * pgrp)801 grp_delete_recursive(Wxd_object_t *pgrp)
802 {
803 	Wxd_object_t	*no;		/* Next object */
804 	Wxd_object_t	*ng;		/* Next group */
805 
806 	dk4sto_it_reset((pgrp->det).g.i_e);
807 	while (NULL != pgrp) {
808 		no = (Wxd_object_t *)dk4sto_it_next((pgrp->det).g.i_e);
809 		if (NULL != no) {
810 			if (WXD_OT_GROUP_BEGIN == no->ot) {
811 				if ((NULL != (no->det).g.s_e) && (NULL != (no->det).g.i_e)) {
812 					dk4sto_it_reset((no->det).g.i_e);
813 					pgrp = no;
814 				}
815 				else {
816 					dk4sto_remove((pgrp->det).g.s_e, no, NULL);
817 					dk4sto_it_reset((pgrp->det).g.i_e);
818 #if	0
819 					if (NULL != (no->det).g.s_e) {
820 						dk4sto_close((no->det).g.s_e);
821 						(no->det).g.s_e = NULL;
822 					}
823 					dk4mem_free(no);
824 #endif
825 					wxdobj_obj_delete(no);
826 				}
827 			}
828 			else {
829 				no->pa = NULL;
830 				dk4sto_remove((pgrp->det).g.s_e, no, NULL);
831 				dk4sto_it_reset((pgrp->det).g.i_e);
832 			}
833 		}
834 		else {
835 			ng = pgrp->pa;
836 			if (NULL != ng) {
837 				dk4sto_remove((ng->det).g.s_e, pgrp, NULL);
838 				dk4sto_it_reset((ng->det).g.i_e);
839 			}
840 #if	0
841 			dk4sto_it_close((pgrp->det).g.i_e);
842 			(pgrp->det).g.i_e = NULL;
843 			dk4sto_close((pgrp->det).g.s_e);
844 			(pgrp->det).g.s_e = NULL;
845 			dk4mem_free(pgrp);
846 #endif
847 			wxdobj_obj_delete(pgrp);
848 			pgrp = ng;
849 		}
850 	}
851 
852 }
853 
854 
855 
856 void
wxdobj_grp_delete_recursive(Wxd_object_t * pgrp)857 wxdobj_grp_delete_recursive(Wxd_object_t *pgrp)
858 {
859 
860 	if (NULL != pgrp) {
861 		if (WXD_OT_GROUP_BEGIN == pgrp->ot) {
862 			if ((NULL != (pgrp->det).g.s_e) && (NULL != (pgrp->det).g.i_e)) {
863 				grp_delete_recursive(pgrp);
864 			}
865 			else {
866 				if (NULL != (pgrp->det).g.s_e) {
867 					dk4sto_close((pgrp->det).g.s_e);
868 					(pgrp->det).g.s_e = NULL;
869 				}
870 				dk4mem_free(pgrp);
871 			}
872 		}
873 	}
874 	else {
875 	}
876 
877 }
878 
879 
880 
881 void
wxdobj_drw_delete(Wxd_drawing_t * pdrw)882 wxdobj_drw_delete(Wxd_drawing_t *pdrw)
883 {
884 	Wxd_object_t		*pgrp;		/* Current group to delete */
885 	Wxd_stipple_t		*pstip;		/* Current stipple to delete */
886 	Wxd_layer_t			*play;		/* Current layer to delete */
887 	Wxd_font_t			*pfont;		/* Current font to delete */
888 
889 	if (NULL != pdrw) {
890 		/*
891 			Delete structured information
892 		*/
893 
894 		if (NULL != pdrw->s_stru) {
895 			if (NULL != pdrw->i_stru) {
896 				dk4sto_it_reset(pdrw->i_stru);
897 				do {
898 					pgrp = (Wxd_object_t *)dk4sto_it_next(pdrw->i_stru);
899 					if (NULL != pgrp) {
900 						if (WXD_OT_GROUP_BEGIN == pgrp->ot) {
901 							wxdobj_grp_delete_recursive(pgrp);
902 						}
903 						else {
904 							pgrp->pa = NULL;
905 						}
906 					}
907 				} while (NULL != pgrp);
908 				dk4sto_it_close(pdrw->i_stru);
909 				pdrw->i_stru = NULL;
910 			}
911 			dk4sto_close(pdrw->s_stru);
912 			pdrw->s_stru = NULL;
913 		}
914 
915 		/*
916 			Delete stipples
917 		*/
918 
919 		if (NULL != pdrw->s_stip) {
920 			if (NULL != pdrw->i_stip) {
921 				dk4sto_it_reset(pdrw->i_stip);
922 				do {
923 					pstip = (Wxd_stipple_t *)dk4sto_it_next(pdrw->i_stip);
924 					if (NULL != pstip) {
925 
926 						if (NULL != pstip->bm) {
927 							delete (pstip->bm);
928 							pstip->bm = NULL;
929 						}
930 						else {
931 						}
932 						dk4mem_free(pstip);
933 					}
934 				} while (NULL != pstip);
935 				dk4sto_it_close(pdrw->i_stip);
936 				pdrw->i_stip = NULL;
937 			}
938 #if	TRACE_DEBUG
939 			else {
940 			}
941 #endif
942 			dk4sto_close(pdrw->s_stip);
943 			pdrw->s_stip = NULL;
944 		}
945 #if	TRACE_DEBUG
946 		else {
947 		}
948 #endif
949 
950 		/*
951 			Delete layers
952 		*/
953 
954 		if (NULL != pdrw->s_layers) {
955 			if (NULL != pdrw->i_layers) {
956 				dk4sto_it_reset(pdrw->i_layers);
957 				do {
958 					play = (Wxd_layer_t *)dk4sto_it_next(pdrw->i_layers);
959 					if (NULL != play) {
960 
961 						dk4mem_free(play);
962 					}
963 				} while (NULL != play);
964 				dk4sto_it_close(pdrw->i_layers);
965 				pdrw->i_layers = NULL;
966 			}
967 			dk4sto_close(pdrw->s_layers);
968 			pdrw->s_layers = NULL;
969 		}
970 
971 		/*
972 			Delete flat list and objects
973 		*/
974 
975 		if (NULL != pdrw->s_flat) {
976 			if (NULL != pdrw->i_flat) {
977 				dk4sto_it_reset(pdrw->i_flat);
978 				do {
979 					pgrp = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
980 					if (NULL != pgrp) {
981 						wxdobj_obj_delete(pgrp);
982 					}
983 				} while (NULL != pgrp);
984 				dk4sto_it_close(pdrw->i_flat);
985 				pdrw->i_flat = NULL;
986 			}
987 			dk4sto_close(pdrw->s_flat);
988 			pdrw->s_flat = NULL;
989 		}
990 
991 
992 		/*
993 			Delete font structures
994 		*/
995 		if (NULL != pdrw->s_fonts) {
996 			if (NULL != pdrw->i_fonts) {
997 				dk4sto_it_reset(pdrw->i_fonts);
998 				do {
999 					pfont = (Wxd_font_t *)dk4sto_it_next(pdrw->i_fonts);
1000 					if (NULL != pfont) {
1001 
1002 						wxdfont_delete(pfont);
1003 					}
1004 				} while (NULL != pfont);
1005 				dk4sto_it_close(pdrw->i_fonts);
1006 				pdrw->i_fonts = NULL;
1007 			}
1008 			dk4sto_close(pdrw->s_fonts);
1009 			pdrw->s_fonts = NULL;
1010 		}
1011 
1012 		dk4mem_free(pdrw);
1013 
1014 	}
1015 #if	TRACE_DEBUG
1016 	else {
1017 	}
1018 #endif
1019 
1020 }
1021 
1022 
1023 
1024 void
wxdobj_drw_set_xsubs(Wxd_drawing_t * pdrw,size_t xs)1025 wxdobj_drw_set_xsubs(Wxd_drawing_t *pdrw, size_t xs)
1026 {
1027 	if (NULL != pdrw) {
1028 		if ((size_t)2U > xs) {
1029 			xs = (size_t)2U;
1030 		}
1031 		pdrw->xsubs = xs;
1032 	}
1033 }
1034 
1035 
1036 
1037 void
wxdobj_drw_require_redraw(Wxd_drawing_t * pdrw,int level)1038 wxdobj_drw_require_redraw(Wxd_drawing_t *pdrw, int level)
1039 {
1040 
1041 	if (NULL != pdrw) {
1042 		if (level > pdrw->redraw) {
1043 			pdrw->redraw = level;
1044 		}
1045 	}
1046 
1047 }
1048 
1049 
1050 
1051 int
wxdobj_drw_get_required_redraw_level(Wxd_drawing_t * pdrw,int level)1052 wxdobj_drw_get_required_redraw_level(Wxd_drawing_t	*pdrw, int level)
1053 {
1054 
1055 	if (NULL != pdrw) {
1056 		if (pdrw->redraw > level) {
1057 			level = pdrw->redraw;
1058 		}
1059 	}
1060 	return level;
1061 }
1062 
1063 
1064 
1065 void
wxdobj_drw_reset_required_redraw_level(Wxd_drawing_t * pdrw)1066 wxdobj_drw_reset_required_redraw_level(Wxd_drawing_t *pdrw)
1067 {
1068 
1069 	if (NULL != pdrw) {
1070 		pdrw->redraw = WXD_REFRESH_NONE;
1071 	}
1072 
1073 }
1074 
1075 
1076 
1077 Wxd_drawing_t *
wxdobj_drw_new(void)1078 wxdobj_drw_new(void)
1079 {
1080 	Wxd_drawing_t	*back	= NULL;
1081 	bool			 ok		= false;
1082 
1083 	back = dk4mem_new(Wxd_drawing_t,1,NULL);
1084 	if (NULL != back) {
1085 		/*
1086 			Initialize drawing members
1087 		*/
1088 		back->s_stru = back->s_flat = back->s_stip =
1089 		back->s_layers = back->s_fonts = NULL;
1090 		back->i_stru = back->i_flat = back->i_stip =
1091 		back->i_layers = back->i_fonts = NULL;
1092 		(back->bb).xl	=         0L;
1093 		(back->bb).yb	=         0L;
1094 		(back->bb).xr	= 130048000L;
1095 		(back->bb).yt	=  73152000L;
1096 		back->xsubs		= (size_t)8U;
1097 		back->cx       =  65024000L;
1098 		back->cy       =  36576000L;
1099 		back->baselw   =    101600L;
1100 		back->bleft    =  16256000L;
1101 		back->bright   =  16256000L;
1102 		back->bbottom  =  16256000L;
1103 		back->btop     =  16256000L;
1104 		back->fv_maj   =         1U;
1105 		back->fv_min   =         0U;
1106 		back->zl       =          0;
1107 		back->gridunit =         0U;
1108 		back->gridbase =         0U;
1109 		back->s_stru   = dk4sto_open(NULL);
1110 		back->s_flat   = dk4sto_open(NULL);
1111 		back->s_stip   = dk4sto_open(NULL);
1112 		back->s_layers = dk4sto_open(NULL);
1113 		back->s_fonts  = dk4sto_open(NULL);
1114 		/*
1115 			After loading a drawing the first repaint must do a
1116 			complete redraw.
1117 		*/
1118 		back->redraw   =  WXD_REFRESH_GRID;
1119 		/*
1120 			Allocate storages and iterators.
1121 		*/
1122 		if (
1123 			(NULL != back->s_stru) && (NULL != back->s_flat)
1124 			&& (NULL != back->s_stip) && (NULL != back->s_layers)
1125 			&& (NULL != back->s_fonts)
1126 		) {
1127 			dk4sto_set_comp(back->s_stru, drawobj_compare_object, 0);
1128 			dk4sto_set_comp(back->s_flat, drawobj_compare_object, 0);
1129 			dk4sto_set_comp(back->s_stip, drawobj_compare_stipples, 0);
1130 			dk4sto_set_comp(back->s_layers, drawobj_compare_layers, 0);
1131 			dk4sto_set_comp(back->s_fonts, wxdfont_compare, 0);
1132 			back->i_stru = dk4sto_it_open(back->s_stru, NULL);
1133 			back->i_flat = dk4sto_it_open(back->s_flat, NULL);
1134 			back->i_stip = dk4sto_it_open(back->s_stip, NULL);
1135 			back->i_layers = dk4sto_it_open(back->s_layers, NULL);
1136 			back->i_fonts  = dk4sto_it_open(back->s_fonts, NULL);
1137 			if (
1138 				(NULL != back->i_stru) && (NULL != back->i_flat)
1139 				&& (NULL != back->i_stip) && (NULL != back->i_layers)
1140 				&& (NULL != back->i_fonts)
1141 			) {
1142 				ok = true;
1143 			}
1144 		}
1145 		/*
1146 			Check whether initialization completed successfully
1147 		*/
1148 		if(!(ok)) {
1149 			wxdobj_drw_delete(back);
1150 			back = NULL;
1151 		}
1152 	}
1153 
1154 	return back;
1155 }
1156 
1157 
1158 
1159 #if	0
1160 static
1161 Wxd_object_t *
1162 wxdobj_obj_new_text(
1163 	wxChar const		*t,
1164 	wxChar const		*tsc,
1165 	Wxd_object_t const	*ptpl
1166 )
1167 {
1168 	Wxd_object_t *back	= NULL;
1169 
1170 	if (NULL != t) {
1171 		back = dk4mem_new(Wxd_object_t,1,NULL);
1172 		if (NULL != back) {
1173 			wxdobj_obj_init(back, WXD_OT_TEXT, ptpl);
1174 			(back->det).t.t = dk4strx_dup(t, NULL);
1175 			if (NULL == (back->det).t.t) {
1176 				dk4mem_free(back);
1177 				back = NULL;
1178 			}
1179 			else {
1180 				if (NULL != tsc) {
1181 					(back->det).t.tsc = dk4strx_dup(tsc, NULL);
1182 					if (NULL == (back->det).t.tsc) {
1183 						wxdobj_obj_delete(back);
1184 						back = NULL;
1185 					}
1186 				}
1187 			}
1188 		}
1189 #if	TRACE_DEBUG
1190 		else {
1191 		}
1192 #endif
1193 	}
1194 	return back;
1195 }
1196 #endif
1197 
1198 
1199 
1200 static
1201 Wxd_object_t *
wxdobj_obj_new_polyany(uint16_t np,int ot,Wxd_object_t const * ptpl)1202 wxdobj_obj_new_polyany(uint16_t np, int ot, Wxd_object_t const *ptpl)
1203 {
1204 	Wxd_object_t *back	= NULL;
1205 
1206 	back = dk4mem_new(Wxd_object_t,1,NULL);
1207 	if (NULL != back) {
1208 		wxdobj_obj_init(back, ot, ptpl);
1209 		(back->det).p.n = np;
1210 		(back->det).p.p = NULL;
1211 		(back->det).p.p = dk4mem_new(Wxd_point_t,((size_t)np),NULL);
1212 		if (NULL == (back->det).p.p) {
1213 			dk4mem_free(back);
1214 			back = NULL;
1215 		}
1216 	}
1217 	return back;
1218 }
1219 
1220 
1221 
1222 Wxd_object_t *
wxdobj_obj_new_polyline(uint16_t np,Wxd_object_t const * ptpl)1223 wxdobj_obj_new_polyline(uint16_t np, Wxd_object_t const *ptpl)
1224 {
1225 	Wxd_object_t *back	= NULL;
1226 
1227 	if ((uint16_t)1U < np) {
1228 		back = wxdobj_obj_new_polyany(np, WXD_OT_POLYLINE, ptpl);
1229 	}
1230 	return back;
1231 }
1232 
1233 
1234 
1235 Wxd_object_t *
wxdobj_obj_new_polygon(uint16_t np,Wxd_object_t const * ptpl)1236 wxdobj_obj_new_polygon(uint16_t np, Wxd_object_t const *ptpl)
1237 {
1238 	Wxd_object_t	*back	= NULL;
1239 
1240 	if ((uint16_t)1U < np) {
1241 		back = wxdobj_obj_new_polyany(np, WXD_OT_POLYGON, ptpl);
1242 	}
1243 	return back;
1244 }
1245 
1246 
1247 
1248 Wxd_object_t *
wxdobj_obj_new_spline(uint16_t np,int cl,Wxd_object_t const * ptpl)1249 wxdobj_obj_new_spline(uint16_t np, int cl, Wxd_object_t const *ptpl)
1250 {
1251 	Wxd_object_t	*back = NULL;
1252 
1253 	if ((uint16_t)1U < np) {
1254 		back = dk4mem_new(Wxd_object_t,1,NULL);
1255 		if (NULL != back) {
1256 			wxdobj_obj_init(
1257 				back, ((0 != cl) ? (WXD_OT_C_SPLINE) : (WXD_OT_O_SPLINE)), ptpl
1258 			);
1259 			(back->det).s.n = np;
1260 			(back->det).s.p = dk4mem_new(Wxd_spline_point_t,((size_t)np),NULL);
1261 			if (NULL == (back->det).s.p) {
1262 				dk4mem_free(back);
1263 				back = NULL;
1264 			}
1265 		}
1266 #if	TRACE_DEBUG
1267 		else {
1268 		}
1269 #endif
1270 	}
1271 	return back;
1272 }
1273 
1274 
1275 
1276 Wxd_object_t *
wxdobj_obj_new_arc(int cl,Wxd_object_t const * ptpl)1277 wxdobj_obj_new_arc(int cl, Wxd_object_t const *ptpl)
1278 {
1279 	Wxd_object_t	*back	= NULL;
1280 
1281 	back = dk4mem_new(Wxd_object_t,1,NULL);
1282 	if (NULL != back) {
1283 		wxdobj_obj_init(
1284 			back, ((0 != cl) ? (WXD_OT_C_ARC) : (WXD_OT_O_ARC)), ptpl
1285 		);
1286 	}
1287 #if	TRACE_DEBUG
1288 	else {
1289 	}
1290 #endif
1291 
1292 	return back;
1293 }
1294 
1295 
1296 
1297 Wxd_object_t *
wxdobj_obj_new_circle(Wxd_object_t const * ptpl)1298 wxdobj_obj_new_circle(Wxd_object_t const *ptpl)
1299 {
1300 	Wxd_object_t	*back = NULL;
1301 
1302 	back = dk4mem_new(Wxd_object_t,1,NULL);
1303 	if (NULL != back) {
1304 		wxdobj_obj_init(back, WXD_OT_CIRCLE, ptpl);
1305 	}
1306 #if	TRACE_DEBUG
1307 	else {
1308 	}
1309 #endif
1310 
1311 	return back;
1312 }
1313 
1314 
1315 
1316 Wxd_object_t *
wxdobj_obj_new_ellipse(Wxd_object_t const * ptpl)1317 wxdobj_obj_new_ellipse(Wxd_object_t const *ptpl)
1318 {
1319 	Wxd_object_t	*back = NULL;
1320 
1321 	back = dk4mem_new(Wxd_object_t,1,NULL);
1322 	if (NULL != back) {
1323 		wxdobj_obj_init(back, WXD_OT_ELLIPSE, ptpl);
1324 	}
1325 #if	TRACE_DEBUG
1326 	else {
1327 	}
1328 #endif
1329 
1330 	return back;
1331 }
1332 
1333 
1334 
1335 Wxd_object_t *
wxdobj_obj_new_box(Wxd_object_t const * ptpl)1336 wxdobj_obj_new_box(Wxd_object_t const *ptpl)
1337 {
1338 	Wxd_object_t	*back = NULL;
1339 
1340 	back = dk4mem_new(Wxd_object_t,1,NULL);
1341 	if (NULL != back) {
1342 		wxdobj_obj_init(back, WXD_OT_BOX, ptpl);
1343 	}
1344 #if	TRACE_DEBUG
1345 	else {
1346 	}
1347 #endif
1348 
1349 	return back;
1350 }
1351 
1352 
1353 
1354 Wxd_object_t *
wxdobj_obj_new_image(wxChar const * fn,Wxd_object_t const * ptpl)1355 wxdobj_obj_new_image(wxChar const *fn, Wxd_object_t const *ptpl)
1356 {
1357 	Wxd_object_t	*back = NULL;
1358 
1359 	if (NULL != fn) {
1360 		back = dk4mem_new(Wxd_object_t,1,NULL);
1361 		if (NULL != back) {
1362 			wxdobj_obj_init(back, WXD_OT_IMAGE, ptpl);
1363 			(back->det).i.fn = dk4strx_dup(fn, NULL);
1364 			if (NULL == (back->det).i.fn) {
1365 				wxdobj_obj_delete(back);
1366 				back = NULL;
1367 			}
1368 		}
1369 	}
1370 #if	TRACE_DEBUG
1371 	else {
1372 	}
1373 #endif
1374 
1375 	return back;
1376 }
1377 
1378 
1379 
1380 Wxd_object_t *
wxdobj_obj_new_dot(int wh,Wxd_object_t const * ptpl)1381 wxdobj_obj_new_dot(int wh, Wxd_object_t const *ptpl)
1382 {
1383 	Wxd_object_t	*back = NULL;
1384 
1385 	back = dk4mem_new(Wxd_object_t,1,NULL);
1386 	if (NULL != back) {
1387 		wxdobj_obj_init(
1388 			back, ((0 != wh) ? (WXD_OT_DOT_WHITE) : (WXD_OT_DOT_FILLED)), ptpl
1389 		);
1390 		/*	Bugfix 2021-06-13
1391 			Increasing the layer number must happen before registering
1392 			the dot object for layers and stipples.
1393 		*/
1394 		if (DK4_I16_MAX > back->lay) {
1395 			back->lay = (int16_t)(back->lay + 1);
1396 		}
1397 	}
1398 #if	TRACE_DEBUG
1399 	else {
1400 	}
1401 #endif
1402 
1403 	return back;
1404 }
1405 
1406 
1407 
1408 Wxd_object_t *
wxdobj_obj_new_textlabel(wxChar const * te,Wxd_object_t const * ptpl)1409 wxdobj_obj_new_textlabel(wxChar const *te, Wxd_object_t const *ptpl)
1410 {
1411 	Wxd_object_t	*back	= NULL;
1412 
1413 	if (NULL != te) {
1414 		back = dk4mem_new(Wxd_object_t,1,NULL);
1415 		if (NULL != back) {
1416 			wxdobj_obj_init(back, WXD_OT_TEXT, ptpl);
1417 			if (NULL != ptpl) {
1418 				back->fc[0] = ptpl->sc[0];
1419 				back->fc[1] = ptpl->sc[1];
1420 				back->fc[2] = ptpl->sc[2];
1421 			}
1422 			(back->det).t.t = dk4strx_dup(te, NULL);
1423 			if (NULL == (back->det).t.t) {
1424 				 wxdobj_obj_delete(back);
1425 				 back = NULL;
1426 			}
1427 		}
1428 #if	TRACE_DEBUG
1429 		else {
1430 		}
1431 #endif
1432 	}
1433 #if	TRACE_DEBUG
1434 	else {
1435 	}
1436 #endif
1437 
1438 	return back;
1439 }
1440 
1441 
1442 
1443 int
wxdobj_needs_stipple(Wxd_object_t * pobj)1444 wxdobj_needs_stipple(
1445 	Wxd_object_t	*pobj
1446 )
1447 {
1448 	int		 back = 0;
1449 
1450 	switch ( (int)(pobj->ot) ) {
1451 		case WXD_OT_POLYGON :
1452 		case WXD_OT_C_SPLINE :
1453 		case WXD_OT_C_ARC :
1454 		case WXD_OT_CIRCLE :
1455 		case WXD_OT_ELLIPSE :
1456 		case WXD_OT_BOX : {
1457 
1458 			if (WXD_FS_PURE < pobj->fs) {
1459 				back = 1;
1460 			}
1461 		} break;
1462 	}
1463 	return back;
1464 }
1465 
1466 
1467 
1468 /**	Find existing stipple structure for object or create a new one.
1469 	@param	pdrw	Drawing.
1470 	@param	pobj	Object.
1471 	@return	Address of stipple on success, NULL on error.
1472 */
1473 
1474 static
1475 Wxd_stipple_t *
i_find_stipple_structure(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)1476 i_find_stipple_structure(
1477 	Wxd_drawing_t	*pdrw,
1478 	Wxd_object_t	*pobj
1479 )
1480 {
1481 	Wxd_stipple_t		 teststip;
1482 	Wxd_stipple_t		*back;
1483 
1484 	teststip.cd[0]	= pobj->fs;
1485 	teststip.cd[1]	= pobj->fc[0];
1486 	teststip.cd[2]	= pobj->fc[1];
1487 	teststip.cd[3]	= pobj->fc[2];
1488 	teststip.cd[4]	= pobj->sc[0];
1489 	teststip.cd[5]	= pobj->sc[1];
1490 	teststip.cd[6]	= pobj->sc[2];
1491 	teststip.cd[7]	= 0x01;
1492 	teststip.bm		= NULL;
1493 
1494 	back = (Wxd_stipple_t *)dk4sto_it_find_like(
1495 		pdrw->i_stip, (const void *)(&teststip), 0
1496 	);
1497 	if (NULL == back) {
1498 		back = dk4mem_new(Wxd_stipple_t,1,NULL);
1499 		if (NULL != back) {
1500 			DK4_MEMCPY(back,&teststip,sizeof(Wxd_stipple_t));
1501 			back->bm = NULL;
1502 			if (0 == dk4sto_add(pdrw->s_stip, (void *)back, NULL)) {
1503 				dk4mem_free(back);
1504 				back = NULL;
1505 			}
1506 #if	TRACE_DEBUG
1507 			else {
1508 			}
1509 #endif
1510 		}
1511 #if	TRACE_DEBUG
1512 		else {
1513 		}
1514 #endif
1515 	}
1516 	return back;
1517 }
1518 
1519 
1520 
1521 static
1522 int
i_find_layer_structure(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)1523 i_find_layer_structure(Wxd_drawing_t *pdrw, Wxd_object_t *pobj)
1524 {
1525 	Wxd_layer_t		*ptest;
1526 	int			 	 back	= 0;
1527 
1528 	if (NULL == pobj->play) {
1529 		ptest = (Wxd_layer_t *)dk4sto_it_find_like(
1530 			pdrw->i_layers, &(pobj->lay), 1
1531 		);
1532 		if (NULL != ptest) {
1533 			pobj->play = ptest;
1534 			back = 1;
1535 		}
1536 		else {
1537 			ptest = dk4mem_new(Wxd_layer_t,1,NULL);
1538 			if (NULL != ptest) {
1539 				ptest->lay = pobj->lay;
1540 				ptest->active = 0x01;
1541 				ptest->used   = 0x01;
1542 				if (0 != dk4sto_add(pdrw->s_layers, ptest, NULL)) {
1543 					pobj->play = ptest;
1544 					back = 1;
1545 				}
1546 				else {
1547 					dk4mem_free(ptest);
1548 				}
1549 			}
1550 #if TRACE_DEBUG
1551 			else {
1552 			}
1553 #endif
1554 		}
1555 	}
1556 	else {
1557 		back = 1;
1558 	}
1559 	return back;
1560 }
1561 
1562 
1563 
1564 static
1565 int
wxdobj_drw_layer_and_stipple(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)1566 wxdobj_drw_layer_and_stipple(
1567 	Wxd_drawing_t	*pdrw,
1568 	Wxd_object_t	*pobj
1569 )
1570 {
1571 	int			 back	= 1;
1572 
1573 	if (NULL == pobj->play) {
1574 		if (0 == i_find_layer_structure(pdrw, pobj)) {
1575 			back = 0;
1576 		}
1577 	}
1578 	if (0 != wxdobj_needs_stipple(pobj)) {
1579 		if (NULL == pobj->psti) {
1580 			pobj->psti = i_find_stipple_structure(pdrw, pobj);
1581 			if (NULL == pobj->psti) {
1582 				back = 0;
1583 			}
1584 #if	TRACE_DEBUG
1585 			else {
1586 
1587 
1588 			}
1589 #endif
1590 		}
1591 	}
1592 	return back;
1593 }
1594 
1595 
1596 
1597 int
wxdobj_drw_register_object(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,Wxd_object_t * pobj)1598 wxdobj_drw_register_object(
1599 	Wxd_drawing_t	*pdrw,
1600 	Wxd_object_t	*pgrp,
1601 	Wxd_object_t	*pobj
1602 )
1603 {
1604 	int		 back	= 0;
1605 
1606 	if ((NULL != pdrw) && (NULL != pobj)) {
1607 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
1608 			/*
1609 				Group objects go to structured storage only, no layer structure
1610 			*/
1611 			if (NULL != pgrp) {
1612 				if (0 != dk4sto_add((pgrp->det).g.s_e, pobj, NULL)) {
1613 					pobj->pa = pgrp;
1614 					back = 1;
1615 				}
1616 #if	TRACE_DEBUG
1617 				else {
1618 				}
1619 #endif
1620 			}
1621 			else {
1622 				if (0 != dk4sto_add(pdrw->s_stru, pobj, NULL)) {
1623 					back = 1;
1624 				}
1625 #if	TRACE_DEBUG
1626 				else {
1627 				}
1628 #endif
1629 			}
1630 		}
1631 		else {
1632 			if (0 != wxdobj_drw_layer_and_stipple(pdrw, pobj)) {
1633 				/*
1634 					Non-group elements are added to flat and structured storage
1635 				*/
1636 				if (0 != dk4sto_add(pdrw->s_flat, pobj, NULL)) {
1637 					/*
1638 						Add to structured storage,
1639 						either group or top-level storage.
1640 					*/
1641 					if (NULL != pgrp) {
1642 						if (0 != dk4sto_add((pgrp->det).g.s_e, pobj, NULL)) {
1643 							back = 1;
1644 							pobj->pa = pgrp;
1645 						}
1646 						else {
1647 							dk4sto_remove(pdrw->s_flat, pobj, NULL);
1648 						}
1649 					}
1650 					else {
1651 						if (0 != dk4sto_add(pdrw->s_stru, pobj, NULL)) {
1652 							back = 1;
1653 						}
1654 						else {
1655 							dk4sto_remove(pdrw->s_flat, pobj, NULL);
1656 						}
1657 					}
1658 				}
1659 #if	TRACE_DEBUG
1660 				else {
1661 				}
1662 #endif
1663 			}
1664 		}
1665 	}
1666 #if	TRACE_DEBUG
1667 	else {
1668 	}
1669 #endif
1670 
1671 	return back;
1672 }
1673 
1674 
1675 
1676 Wxd_object_t *
wxdobj_drw_add_group(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp)1677 wxdobj_drw_add_group(
1678 	Wxd_drawing_t	*pdrw,
1679 	Wxd_object_t	*pgrp
1680 )
1681 {
1682 	Wxd_object_t *back = NULL;
1683 
1684 	if (NULL != pdrw) {
1685 		back = dk4mem_new(Wxd_object_t,1,NULL);
1686 		if (NULL != back) {
1687 			wxdobj_obj_init(back, WXD_OT_GROUP_BEGIN, NULL);
1688 			(back->det).g.s_e = dk4sto_open(NULL);
1689 			if (NULL != (back->det).g.s_e) {
1690 				dk4sto_set_comp(
1691 					(back->det).g.s_e, drawobj_compare_object,
1692 					WXD2LAT_OBJ_COMPARE_CR_PROPERTIES
1693 				);
1694 				(back->det).g.i_e = dk4sto_it_open((back->det).g.s_e, NULL);
1695 				if (NULL != (back->det).g.i_e) {
1696 					if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
1697 						wxdobj_obj_delete(back);
1698 						back = NULL;
1699 					}
1700 				}
1701 				else {
1702 					wxdobj_obj_delete(back);
1703 					back = NULL;
1704 				}
1705 			}
1706 			else {
1707 				wxdobj_obj_delete(back);
1708 				back = NULL;
1709 			}
1710 		}
1711 #if	TRACE_DEBUG
1712 		else {
1713 		}
1714 #endif
1715 	}
1716 #if	TRACE_DEBUG
1717 	else {
1718 	}
1719 #endif
1720 
1721 	return back;
1722 }
1723 
1724 
1725 
1726 Wxd_object_t *
wxdobj_add_polyline(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,uint16_t np,int cl,Wxd_object_t const * ptpl)1727 wxdobj_add_polyline(
1728 	Wxd_drawing_t		*pdrw,
1729 	Wxd_object_t		*pgrp,
1730 	uint16_t			 np,
1731 	int					 cl,
1732 	Wxd_object_t const	*ptpl
1733 )
1734 {
1735 	Wxd_object_t	*back	= NULL;
1736 
1737 	if (NULL != pdrw) {
1738 		if (0 != cl) {
1739 			back = wxdobj_obj_new_polygon(np, ptpl);
1740 		}
1741 		else {
1742 			back = wxdobj_obj_new_polyline(np, ptpl);
1743 		}
1744 		if (NULL != back) {
1745 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
1746 				wxdobj_obj_delete(back);
1747 				back = NULL;
1748 			}
1749 		}
1750 	}
1751 
1752 	return back;
1753 }
1754 
1755 
1756 
1757 bool
wxdobj_add_polypoint(Wxd_object_t * pobj,uint16_t pind,dk4_er_t * erp)1758 wxdobj_add_polypoint(
1759 	Wxd_object_t	*pobj,
1760 	uint16_t		 pind,
1761 	dk4_er_t		*erp
1762 )
1763 {
1764 	dk4_er_t	 er;				/* Error report */
1765 	Wxd_point_t	*pnew;				/* New allocated points array */
1766 	size_t		 btc;				/* Bytes to copy */
1767 	uint16_t	 nn;				/* New array size */
1768 	uint16_t	 num;				/* Number of elements to move */
1769 	uint16_t	 i;					/* Index of element to copy */
1770 	bool		 back	= false;
1771 
1772 	if (
1773 		(NULL != pobj)
1774 		&& (
1775 			(WXD_OT_POLYLINE == pobj->ot)
1776 			|| (WXD_OT_POLYGON == pobj->ot)
1777 		)
1778 		&& (NULL != (pobj->det).p.p)
1779 	) {
1780 		dk4error_init(&er);
1781 		nn = dk4ma_uint16_t_add((pobj->det).p.n, 1U, &er);
1782 		if (DK4_E_NONE == er.ec) {
1783 			pnew = dk4mem_new(Wxd_point_t,((size_t)nn),&er);
1784 			if (NULL != pnew) {
1785 				back = true;
1786 				btc = sizeof(Wxd_point_t) * (size_t)((pobj->det).p.n);
1787 				DK4_MEMCPY(pnew,(pobj->det).p.p,btc);
1788 				dk4mem_free((pobj->det).p.p);
1789 				(pobj->det).p.p = pnew;
1790 				if (pind < (pobj->det).p.n) {
1791 					num = (uint16_t)((pobj->det).p.n - pind);
1792 					for (i = 0; i < num; i++) {
1793 						((pobj->det).p.p)[(pobj->det).p.n - i].x =
1794 						((pobj->det).p.p)[(pobj->det).p.n - i - 1].x;
1795 						((pobj->det).p.p)[(pobj->det).p.n - i].y =
1796 						((pobj->det).p.p)[(pobj->det).p.n - i - 1].y;
1797 					}
1798 				}
1799 				else {
1800 					((pobj->det).p.p)[(pobj->det).p.n].x =
1801 					((pobj->det).p.p)[(pobj->det).p.n - 1].x;
1802 					((pobj->det).p.p)[(pobj->det).p.n].y =
1803 					((pobj->det).p.p)[(pobj->det).p.n - 1].y;
1804 				}
1805 				(pobj->det).p.n = nn;
1806 			}
1807 			else {
1808 				/* ERROR: Memory (already reported) */
1809 			}
1810 		}
1811 		else {
1812 			dk4error_copy(erp, &er);
1813 		}
1814 	}
1815 	else {
1816 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1817 	}
1818 	return back;
1819 }
1820 
1821 
1822 
1823 bool
wxdobj_del_polypoint(Wxd_object_t * pobj,uint16_t pind,dk4_er_t * erp)1824 wxdobj_del_polypoint(
1825 	Wxd_object_t	*pobj,
1826 	uint16_t		 pind,
1827 	dk4_er_t		*erp
1828 )
1829 {
1830 	Wxd_point_t		*pnew;
1831 	size_t			 btc;
1832 	uint16_t		 num;
1833 	uint16_t		 i;
1834 	uint16_t		 nn;
1835 	bool			 back = false;
1836 
1837 
1838 	if (
1839 		(NULL != pobj)
1840 		&& (
1841 			(WXD_OT_POLYLINE == pobj->ot)
1842 			|| (WXD_OT_POLYGON == pobj->ot)
1843 		)
1844 	) {
1845 
1846 		back = true;
1847 		if (pind < ((pobj->det).p.n - 1U)) {
1848 			num = (uint16_t)((pobj->det).p.n - 1U - pind);
1849 			for (i = 0U; i < num; i++) {
1850 				((pobj->det).p.p)[pind + i].x =
1851 				((pobj->det).p.p)[pind + i + 1U].x;
1852 				((pobj->det).p.p)[pind + i].y =
1853 				((pobj->det).p.p)[pind + i + 1U].y;
1854 			}
1855 		}
1856 #if	TRACE_DEBUG
1857 		else {
1858 		}
1859 #endif
1860 		nn = (uint16_t)((pobj->det).p.n - 1U);
1861 		pnew = dk4mem_new(Wxd_point_t,((size_t)nn),erp);
1862 		if (NULL != pnew) {
1863 			btc = sizeof(Wxd_point_t) * ((size_t)nn);
1864 			DK4_MEMCPY(pnew,(pobj->det).p.p,btc);
1865 			dk4mem_free((pobj->det).p.p);
1866 			(pobj->det).p.p = pnew;
1867 		}
1868 #if	TRACE_DEBUG
1869 		else {
1870 		}
1871 #endif
1872 		(pobj->det).p.n = (uint16_t)((pobj->det).p.n - 1U);
1873 
1874 	}
1875 	else {
1876 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1877 	}
1878 
1879 
1880 	return back;
1881 }
1882 
1883 
1884 
1885 Wxd_object_t *
wxdobj_add_spline(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,uint16_t np,int cl,Wxd_object_t const * ptpl)1886 wxdobj_add_spline(
1887 	Wxd_drawing_t		*pdrw,
1888 	Wxd_object_t		*pgrp,
1889 	uint16_t			 np,
1890 	int					 cl,
1891 	Wxd_object_t const	*ptpl
1892 )
1893 {
1894 	Wxd_object_t	*back	= NULL;
1895 
1896 	if (NULL != pdrw) {
1897 		back = wxdobj_obj_new_spline(np, cl, ptpl);
1898 		if (NULL != back) {
1899 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
1900 				wxdobj_obj_delete(back);
1901 				back = NULL;
1902 			}
1903 		}
1904 	}
1905 
1906 	return back;
1907 }
1908 
1909 
1910 
1911 bool
wxdobj_add_splinepoint(Wxd_object_t * pobj,uint16_t pind,dk4_er_t * erp)1912 wxdobj_add_splinepoint(
1913 	Wxd_object_t	*pobj,
1914 	uint16_t		 pind,
1915 	dk4_er_t		*erp
1916 )
1917 {
1918 	dk4_er_t			 er;				/* Error report */
1919 	Wxd_spline_point_t	*pnew;				/* New allocated points array */
1920 	size_t				 btc;				/* Bytes to copy */
1921 	uint16_t			 nn;				/* New array size */
1922 	uint16_t			 num;				/* Number of elements to move */
1923 	uint16_t			 i;					/* Index of element to copy */
1924 	bool				 back	= false;
1925 
1926 	if (
1927 		(NULL != pobj)
1928 		&& (
1929 			(WXD_OT_O_SPLINE == pobj->ot)
1930 			|| (WXD_OT_C_SPLINE == pobj->ot)
1931 		)
1932 		&& (NULL != (pobj->det).s.p)
1933 	) {
1934 		dk4error_init(&er);
1935 		nn = dk4ma_uint16_t_add((pobj->det).s.n, 1U, &er);
1936 		if (DK4_E_NONE == er.ec) {
1937 			pnew = dk4mem_new(Wxd_spline_point_t,((size_t)nn),&er);
1938 			if (NULL != pnew) {
1939 				back = true;
1940 				btc = sizeof(Wxd_spline_point_t) * (size_t)((pobj->det).s.n);
1941 				DK4_MEMCPY(pnew,(pobj->det).s.p,btc);
1942 				dk4mem_free((pobj->det).s.p);
1943 				(pobj->det).s.p = pnew;
1944 				if (pind < (pobj->det).s.n) {
1945 					num = (uint16_t)((pobj->det).s.n - pind);
1946 					for (i = 0; i < num; i++) {
1947 						((pobj->det).s.p)[(pobj->det).s.n - i].x =
1948 						((pobj->det).s.p)[(pobj->det).s.n - i - 1].x;
1949 						((pobj->det).s.p)[(pobj->det).s.n - i].y =
1950 						((pobj->det).s.p)[(pobj->det).s.n - i - 1].y;
1951 						((pobj->det).s.p)[(pobj->det).s.n - i].s =
1952 						((pobj->det).s.p)[(pobj->det).s.n - i - 1].s;
1953 					}
1954 				}
1955 				else {
1956 					((pobj->det).s.p)[(pobj->det).s.n].x =
1957 					((pobj->det).s.p)[(pobj->det).s.n - 1].x;
1958 					((pobj->det).s.p)[(pobj->det).s.n].y =
1959 					((pobj->det).s.p)[(pobj->det).s.n - 1].y;
1960 					((pobj->det).s.p)[(pobj->det).s.n].s =
1961 					((pobj->det).s.p)[(pobj->det).s.n - 1].s;
1962 				}
1963 				(pobj->det).s.n = nn;
1964 			}
1965 			else {
1966 				/* ERROR: Memory (already reported) */
1967 			}
1968 		}
1969 		else {
1970 			dk4error_copy(erp, &er);
1971 		}
1972 	}
1973 	else {
1974 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1975 	}
1976 	return back;
1977 }
1978 
1979 
1980 
1981 bool
wxdobj_del_splinepoint(Wxd_object_t * pobj,uint16_t pind,dk4_er_t * erp)1982 wxdobj_del_splinepoint(
1983 	Wxd_object_t	*pobj,
1984 	uint16_t		 pind,
1985 	dk4_er_t		*erp
1986 )
1987 {
1988 	Wxd_spline_point_t		*pnew;
1989 	size_t					 btc;
1990 	uint16_t				 num;
1991 	uint16_t				 i;
1992 	uint16_t				 nn;
1993 	bool					 back = false;
1994 
1995 
1996 	if (
1997 		(NULL != pobj)
1998 		&& (
1999 			(WXD_OT_O_SPLINE == pobj->ot)
2000 			|| (WXD_OT_C_SPLINE == pobj->ot)
2001 		)
2002 	) {
2003 
2004 		back = true;
2005 		if (pind < ((pobj->det).s.n - 1U)) {
2006 			num = (uint16_t)((pobj->det).s.n - 1U - pind);
2007 			for (i = 0U; i < num; i++) {
2008 				((pobj->det).s.p)[pind + i].x =
2009 				((pobj->det).s.p)[pind + i + 1U].x;
2010 				((pobj->det).s.p)[pind + i].y =
2011 				((pobj->det).s.p)[pind + i + 1U].y;
2012 				((pobj->det).s.p)[pind + i].s =
2013 				((pobj->det).s.p)[pind + i + 1U].s;
2014 			}
2015 		}
2016 #if	TRACE_DEBUG
2017 		else {
2018 		}
2019 #endif
2020 		nn = (uint16_t)((pobj->det).s.n - 1U);
2021 		pnew = dk4mem_new(Wxd_spline_point_t,((size_t)nn),erp);
2022 		if (NULL != pnew) {
2023 			btc = sizeof(Wxd_spline_point_t) * ((size_t)nn);
2024 			DK4_MEMCPY(pnew,(pobj->det).s.p,btc);
2025 			dk4mem_free((pobj->det).s.p);
2026 			(pobj->det).s.p = pnew;
2027 		}
2028 #if	TRACE_DEBUG
2029 		else {
2030 		}
2031 #endif
2032 		(pobj->det).s.n = (uint16_t)((pobj->det).s.n - 1U);
2033 
2034 	}
2035 	else {
2036 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2037 	}
2038 
2039 
2040 	return back;
2041 }
2042 
2043 
2044 
2045 Wxd_object_t *
wxdobj_add_arc(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,int cl,Wxd_object_t const * ptpl)2046 wxdobj_add_arc(
2047 	Wxd_drawing_t		*pdrw,
2048 	Wxd_object_t		*pgrp,
2049 	int					 cl,
2050 	Wxd_object_t const	*ptpl
2051 )
2052 {
2053 	Wxd_object_t	*back	=	NULL;
2054 
2055 	if (NULL != pdrw) {
2056 		back = wxdobj_obj_new_arc(cl, ptpl);
2057 		if (NULL != back) {
2058 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2059 				wxdobj_obj_delete(back);
2060 				back = NULL;
2061 			}
2062 		}
2063 	}
2064 
2065 	return back;
2066 }
2067 
2068 
2069 
2070 Wxd_object_t *
wxdobj_add_circle(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,Wxd_object_t const * ptpl)2071 wxdobj_add_circle(
2072 	Wxd_drawing_t		*pdrw,
2073 	Wxd_object_t		*pgrp,
2074 	Wxd_object_t const	*ptpl
2075 )
2076 {
2077 	Wxd_object_t	*back	= NULL;
2078 
2079 	if (NULL != pdrw) {
2080 		back = wxdobj_obj_new_circle(ptpl);
2081 		if (NULL != back) {
2082 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2083 				wxdobj_obj_delete(back);
2084 				back = NULL;
2085 			}
2086 		}
2087 	}
2088 
2089 	return back;
2090 }
2091 
2092 
2093 
2094 Wxd_object_t *
wxdobj_add_ellipse(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,Wxd_object_t const * ptpl)2095 wxdobj_add_ellipse(
2096 	Wxd_drawing_t		*pdrw,
2097 	Wxd_object_t		*pgrp,
2098 	Wxd_object_t const	*ptpl
2099 )
2100 {
2101 	Wxd_object_t	*back	= NULL;
2102 
2103 	if (NULL != pdrw) {
2104 		back = wxdobj_obj_new_ellipse(ptpl);
2105 		if (NULL != back) {
2106 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2107 				wxdobj_obj_delete(back);
2108 				back = NULL;
2109 			}
2110 		}
2111 	}
2112 
2113 	return back;
2114 }
2115 
2116 
2117 
2118 Wxd_object_t *
wxdobj_add_box(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,Wxd_object_t const * ptpl)2119 wxdobj_add_box(
2120 	Wxd_drawing_t		*pdrw,
2121 	Wxd_object_t		*pgrp,
2122 	Wxd_object_t const	*ptpl
2123 )
2124 {
2125 	Wxd_object_t	*back	= NULL;
2126 
2127 	if (NULL != pdrw) {
2128 		back = wxdobj_obj_new_box(ptpl);
2129 		if (NULL != back) {
2130 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2131 				wxdobj_obj_delete(back);
2132 				back = NULL;
2133 			}
2134 		}
2135 	}
2136 
2137 	return back;
2138 }
2139 
2140 
2141 
2142 Wxd_object_t *
wxdobj_add_image(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,wxChar const * fn,Wxd_object_t const * ptpl)2143 wxdobj_add_image(
2144 	Wxd_drawing_t		*pdrw,
2145 	Wxd_object_t		*pgrp,
2146 	wxChar const		*fn,
2147 	Wxd_object_t const	*ptpl
2148 )
2149 {
2150 	Wxd_object_t	*back	= NULL;
2151 
2152 	if (NULL != pdrw) {
2153 		back = wxdobj_obj_new_image(fn, ptpl);
2154 		if (NULL != back) {
2155 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2156 				wxdobj_obj_delete(back);
2157 				back = NULL;
2158 			}
2159 		}
2160 	}
2161 
2162 	return back;
2163 }
2164 
2165 
2166 
2167 Wxd_object_t *
wxdobj_add_dot(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,int wh,Wxd_object_t const * ptpl)2168 wxdobj_add_dot(
2169 	Wxd_drawing_t		*pdrw,
2170 	Wxd_object_t		*pgrp,
2171 	int					 wh,
2172 	Wxd_object_t const	*ptpl
2173 )
2174 {
2175 	Wxd_object_t	*back	= NULL;
2176 
2177 	if (NULL != pdrw) {
2178 		back = wxdobj_obj_new_dot(wh, ptpl);
2179 		if (NULL != back) {
2180 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2181 				wxdobj_obj_delete(back);
2182 				back = NULL;
2183 			}
2184 		}
2185 	}
2186 
2187 	return back;
2188 }
2189 
2190 
2191 
2192 Wxd_object_t *
wxdobj_add_textlabel(Wxd_drawing_t * pdrw,Wxd_object_t * pgrp,wxChar const * te,Wxd_object_t const * ptpl)2193 wxdobj_add_textlabel(
2194 	Wxd_drawing_t		*pdrw,
2195 	Wxd_object_t		*pgrp,
2196 	wxChar const		*te,
2197 	Wxd_object_t const	*ptpl
2198 )
2199 {
2200 	Wxd_object_t	*back	= NULL;
2201 
2202 	if ((NULL != pdrw) && (NULL != te)) {
2203 		back = wxdobj_obj_new_textlabel(te, ptpl);
2204 		if (NULL != back) {
2205 			if (0 == wxdobj_drw_register_object(pdrw, pgrp, back)) {
2206 				wxdobj_obj_delete(back);
2207 				back= NULL;
2208 			}
2209 		}
2210 	}
2211 
2212 	return back;
2213 }
2214 
2215 
2216 
2217 Wxd_object_t *
wxdobj_find_group_for(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)2218 wxdobj_find_group_for(Wxd_drawing_t *pdrw, Wxd_object_t *pobj)
2219 {
2220 	Wxd_object_t	*back	 =	NULL;
2221 
2222 	if ((NULL != pdrw) && (NULL != pobj)) {
2223 		back = i_find_group_for(pdrw, pobj);
2224 	}
2225 
2226 	return back;
2227 }
2228 
2229 
2230 
2231 int
wxdobj_find_layer_structure(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)2232 wxdobj_find_layer_structure(Wxd_drawing_t *pdrw, Wxd_object_t *pobj)
2233 {
2234 	int		 back	= 0;
2235 
2236 	if ((NULL != pdrw) && (NULL != pobj)) {
2237 		back = i_find_layer_structure(pdrw, pobj);
2238 	}
2239 	return back;
2240 }
2241 
2242 
2243 
2244 /**	Modify object layer internally.
2245 	@param	pdrw	Drawing to modify.
2246 	@param	pobj	Object to modify.
2247 	@param	nl		New layer differing from objects current layer.
2248 	@return	1 on success, 0 on error.
2249 */
2250 
2251 static
2252 int
i_modify_layer(Wxd_drawing_t * pdrw,Wxd_object_t * pobj,int16_t nl)2253 i_modify_layer(
2254 	Wxd_drawing_t	*pdrw,
2255 	Wxd_object_t	*pobj,
2256 	int16_t			 nl
2257 )
2258 {
2259 	Wxd_layer_t		*playold;		/* Old layer structure */
2260 	Wxd_object_t	*pgrp;			/* Group containing the object */
2261 	int		 		 back	= 0;	/* Result */
2262 
2263 	playold = pobj->play;
2264 	pobj->play = NULL;
2265 	if (NULL != dk4sto_it_find_exact(pdrw->i_flat, pobj)) {
2266 		/*
2267 			In flat list
2268 		*/
2269 		if (NULL != dk4sto_it_find_exact(pdrw->i_stru, pobj)) {
2270 			/*
2271 				Top-level element
2272 			*/
2273 			dk4sto_remove(pdrw->s_stru, pobj, NULL);
2274 			dk4sto_remove(pdrw->s_flat, pobj, NULL);
2275 			pobj->lay = nl;
2276 			back = wxdobj_drw_register_object(pdrw, NULL, pobj);
2277 			if (0 == back) {
2278 				wxdobj_obj_delete(pobj);
2279 			}
2280 			wxdobj_drw_require_redraw(pdrw, WXD_REFRESH_DRAWING);
2281 		}
2282 		else {
2283 			/*
2284 				Member of a group
2285 			*/
2286 			pgrp = i_find_group_for(pdrw, pobj);
2287 			if (NULL != pgrp) {
2288 				/*
2289 					Group found
2290 				*/
2291 				dk4sto_remove((pgrp->det).g.s_e, pobj, NULL);
2292 				dk4sto_remove(pdrw->s_flat, pobj, NULL);
2293 				pobj->lay = nl;
2294 				back = wxdobj_drw_register_object(pdrw, pgrp, pobj);
2295 				if (0 == back) {
2296 					wxdobj_obj_delete(pobj);
2297 				}
2298 				wxdobj_drw_require_redraw(pdrw, WXD_REFRESH_DRAWING);
2299 			}
2300 			else {
2301 				/*
2302 					Group not found
2303 				*/
2304 			}
2305 		}
2306 	}
2307 	else {
2308 		/*
2309 			Not in flat list
2310 		*/
2311 	}
2312 	/*
2313 		Find layer structure
2314 	*/
2315 	if (0 != back) {
2316 		back = i_find_layer_structure(pdrw, pobj);
2317 	}
2318 
2319 	/* Remove playold from drawing if not used by other objects */
2320 	if (NULL != playold) { i_check_layer_structure_removal(pdrw, playold); }
2321 
2322 	return back;
2323 }
2324 
2325 
2326 
2327 int
wxdobj_modify_layer(Wxd_drawing_t * pdrw,Wxd_object_t * pobj,int16_t nl)2328 wxdobj_modify_layer(
2329 	Wxd_drawing_t	*pdrw,
2330 	Wxd_object_t	*pobj,
2331 	int16_t			 nl
2332 )
2333 {
2334 	int		 back	= 0;
2335 
2336 	if ((NULL != pdrw) && (NULL != pobj)) {
2337 		if (pobj->lay != nl) {
2338 			back = i_modify_layer(pdrw, pobj, nl);
2339 		}
2340 		else {
2341 			back = 1;
2342 		}
2343 	}
2344 #if	TRACE_DEBUG
2345 	else {
2346 	}
2347 #endif
2348 
2349 	return back;
2350 }
2351 
2352 
2353 
2354 
2355 void
wxdobj_bb_correct(Wxd_bb_t * bbptr,uint16_t * ppoint)2356 wxdobj_bb_correct(Wxd_bb_t *bbptr, uint16_t *ppoint)
2357 {
2358 	int32_t	x;
2359 
2360 	if (NULL != bbptr) {
2361 		if (bbptr->xl > bbptr->xr) {
2362 			if (bbptr->yb > bbptr->yt) {
2363 				x = bbptr->xl;
2364 				bbptr->xl = bbptr->xr;
2365 				bbptr->xr = x;
2366 				x = bbptr->yb;
2367 				bbptr->yb = bbptr->yt;
2368 				bbptr->yt = x;
2369 				if (NULL != ppoint) {
2370 					switch ( (int)(*ppoint) ) {
2371 						case 3 : {
2372 							*ppoint = (uint16_t)0U;
2373 						} break;
2374 						case 2 : {
2375 							*ppoint = (uint16_t)0U;
2376 						} break;
2377 						case 1 : {
2378 							*ppoint = (uint16_t)3U;
2379 						} break;
2380 						default : {
2381 							*ppoint = (uint16_t)2U;
2382 						} break;
2383 					}
2384 				}
2385 			}
2386 			else {
2387 				x = bbptr->xl;
2388 				bbptr->xl = bbptr->xr;
2389 				bbptr->xr = x;
2390 				if (NULL != ppoint) {
2391 					switch ( (int)(*ppoint) ) {
2392 						case 3 : {
2393 							*ppoint = (uint16_t)2U;
2394 						} break;
2395 						case 2 : {
2396 							*ppoint = (uint16_t)3U;
2397 						} break;
2398 						case 1 : {
2399 							*ppoint = (uint16_t)0U;
2400 						} break;
2401 						default : {
2402 							*ppoint = (uint16_t)1U;
2403 						} break;
2404 					}
2405 				}
2406 			}
2407 		}
2408 		else {
2409 			if (bbptr->yb > bbptr->yt) {
2410 				x = bbptr->yb;
2411 				bbptr->yb = bbptr->yt;
2412 				bbptr->yt = x;
2413 				if (NULL != ppoint) {
2414 					switch ( (int)(*ppoint) ) {
2415 						case 3 : {
2416 							*ppoint = (uint16_t)0U;
2417 						} break;
2418 						case 2 : {
2419 							*ppoint = (uint16_t)1U;
2420 						} break;
2421 						case 1 : {
2422 							*ppoint = (uint16_t)2U;
2423 						} break;
2424 						default : {
2425 							*ppoint = (uint16_t)3U;
2426 						} break;
2427 					}
2428 				}
2429 			}
2430 		}
2431 	}
2432 }
2433 
2434 
2435 
2436 bool
wxdobj_bb_is_null_area(Wxd_bb_t * bbptr)2437 wxdobj_bb_is_null_area(Wxd_bb_t *bbptr)
2438 {
2439 	bool		 back = false;
2440 
2441 	if (NULL != bbptr) {
2442 		if (bbptr->xl >= bbptr->xr) {
2443 			back = true;
2444 		}
2445 		if (bbptr->yb >= bbptr->yt) {
2446 			back = true;
2447 		}
2448 	}
2449 	return back;
2450 }
2451 
2452 
2453 
2454 static
2455 int32_t
wxdobj_i32_max(int32_t a,int32_t b)2456 wxdobj_i32_max(int32_t a, int32_t b)
2457 {
2458 	return ((a >= b) ? (a) : (b));
2459 }
2460 
2461 
2462 
2463 static
2464 int32_t
wxdobj_i32_min(int32_t a,int32_t b)2465 wxdobj_i32_min(int32_t a, int32_t b)
2466 {
2467 	return ((a <= b) ? (a) : (b));
2468 }
2469 
2470 
2471 
2472 bool
wxdobj_bb_intersection(Wxd_bb_t * res,Wxd_bb_t const * a,Wxd_bb_t const * b)2473 wxdobj_bb_intersection(
2474 	Wxd_bb_t		*res,
2475 	Wxd_bb_t const	*a,
2476 	Wxd_bb_t const	*b
2477 )
2478 {
2479 	if ((NULL == res) || (NULL == a) || (NULL == b)) {
2480 		return false;
2481 	}
2482 	if (a->xr < b->xl) return false;
2483 	if (b->xr < a->xl) return false;
2484 	if (a->yt < b->yb) return false;
2485 	if (b->yt < a->yb) return false;
2486 	res->xl = wxdobj_i32_max(a->xl, b->xl);
2487 	res->xr = wxdobj_i32_min(a->xr, b->xr);
2488 	res->yb = wxdobj_i32_max(a->yb, b->yb);
2489 	res->yt = wxdobj_i32_min(a->yt, b->yt);
2490 	return true;
2491 }
2492 
2493 
2494 
2495 static
2496 dk4_bif_t *
wxdobj_image_bif_open(Wxd_object_t * pobj,int dkenc,int wxenc)2497 wxdobj_image_bif_open(
2498 	Wxd_object_t	*pobj,
2499 	int				 dkenc,
2500 	int				 wxenc
2501 )
2502 {
2503 	dkChar			 fnb[DK4_MAX_PATH];
2504 	dk4_bif_t		*back	= NULL;
2505 	const size_t	 szfnb = DK4_SIZEOF(fnb,dkChar);
2506 	int				 res;
2507 
2508 	res = dk4recwx_wxchar_to_dkchar(
2509 		fnb, szfnb, dkenc, (pobj->det).i.fn, wxenc, NULL
2510 	);
2511 	if (0 != res) {
2512 		back = dk4bif_open(fnb, 1, NULL, NULL);
2513 	}
2514 #if	TRACE_DEBUG
2515 	else {
2516 	}
2517 #endif
2518 
2519 	return back;
2520 }
2521 
2522 
2523 
2524 void
wxdobj_image_placement(Wxd_object_t * pobj)2525 wxdobj_image_placement(
2526 	Wxd_object_t	*pobj
2527 )
2528 {
2529 	double		iw;		/* Image width */
2530 	double		ih;		/* Image height */
2531 	double		sw;		/* Scale factor for width */
2532 	double		sh;		/* Scale factor for height */
2533 	double		l;		/* Length */
2534 	double		b;		/* Border */
2535 
2536 
2537 
2538 
2539 
2540 	if (0 != ((uint16_t)(WXD_IMFL_ASPECT) & (pobj->det).i.fl)) {
2541 
2542 		wxSize wxsz = ((pobj->det).i.bm)->GetSize();
2543 		iw = (double)(wxsz.GetWidth());
2544 		ih = (double)(wxsz.GetHeight());
2545 		if (
2546 			(0.0 < (pobj->det).i.xres) && (0.0 < (pobj->det).i.yres)
2547 			&& ((pobj->det).i.xres != (pobj->det).i.yres)
2548 		) {
2549 			iw = iw / (pobj->det).i.xres;
2550 			ih = ih / (pobj->det).i.yres;
2551 		}
2552 		sw = (
2553 			(double)((pobj->det).i.br.xr) - (double)((pobj->det).i.br.xl)
2554 		) / iw;
2555 		sh = (
2556 			(double)((pobj->det).i.br.yt) - (double)((pobj->det).i.br.yb)
2557 		) / ih;
2558 		if (sw <= sh) {
2559 			(pobj->det).i.pl.xmin = (pobj->det).i.br.xl;
2560 			(pobj->det).i.pl.xmax = (pobj->det).i.br.xr;
2561 			l = sw * ih;
2562 			b = (double)((pobj->det).i.br.yt) - (double)((pobj->det).i.br.yb);
2563 			b = (b - l) / 2.0;
2564 			(pobj->det).i.pl.ymin = (pobj->det).i.br.yb + b;
2565 			(pobj->det).i.pl.ymax = (pobj->det).i.br.yt - b;
2566 		}
2567 		else {
2568 			(pobj->det).i.pl.ymin = (pobj->det).i.br.yb;
2569 			(pobj->det).i.pl.ymax = (pobj->det).i.br.yt;
2570 			l = sh * iw;
2571 			b = (double)((pobj->det).i.br.xr) - (double)((pobj->det).i.br.xl);
2572 			b = (b - l) / 2.0;
2573 			(pobj->det).i.pl.xmin = (pobj->det).i.br.xl + b;
2574 			(pobj->det).i.pl.xmax = (pobj->det).i.br.xr - b;
2575 		}
2576 	}
2577 	else {
2578 		(pobj->det).i.pl.xmin = (pobj->det).i.br.xl;
2579 		(pobj->det).i.pl.xmax = (pobj->det).i.br.xr;
2580 		(pobj->det).i.pl.ymin = (pobj->det).i.br.yb;
2581 		(pobj->det).i.pl.ymax = (pobj->det).i.br.yt;
2582 	}
2583 
2584 
2585 
2586 
2587 
2588 }
2589 
2590 
2591 
2592 void
wxdobj_load_image(Wxd_object_t * pobj,int dkenc,int wxenc)2593 wxdobj_load_image(
2594 	Wxd_object_t	*pobj,
2595 	int				 dkenc,
2596 	int				 wxenc
2597 )
2598 {
2599 	dk4_bif_t	*bifptr;
2600 	wxString	 strfn((pobj->det).i.fn);
2601 
2602 	if (NULL == (pobj->det).i.bm) {
2603 		(pobj->det).i.xres = -1.0;
2604 		(pobj->det).i.yres = -1.0;
2605 		(pobj->det).i.t = wxdobj_image_type((pobj->det).i.fn);
2606 		if (wxBITMAP_TYPE_INVALID != (pobj->det).i.t) {
2607 			(pobj->det).i.bm = new wxBitmap(
2608 				strfn, (pobj->det).i.t
2609 			);
2610 			if (NULL != (pobj->det).i.bm) {
2611 				if (!(((pobj->det).i.bm)->IsOk())) {
2612 					delete ((pobj->det).i.bm);
2613 					(pobj->det).i.bm = NULL;
2614 				}
2615 			}
2616 			if (NULL != (pobj->det).i.bm) {
2617 				if (0 != ((uint16_t)(WXD_IMFL_ASPECT) & (pobj->det).i.fl)) {
2618 
2619 					bifptr = wxdobj_image_bif_open(pobj, dkenc, wxenc);
2620 					if (NULL != bifptr) {
2621 						(pobj->det).i.xres = dk4bif_get_xres(bifptr);
2622 						(pobj->det).i.yres = dk4bif_get_yres(bifptr);
2623 
2624 
2625 						dk4bif_close(bifptr);
2626 					}
2627 				}
2628 #if	TRACE_DEBUG
2629 				else {
2630 				}
2631 #endif
2632 				wxdobj_image_placement(pobj);
2633 			}
2634 #if	TRACE_DEBUG
2635 			else {
2636 			}
2637 #endif
2638 		}
2639 #if	TRACE_DEBUG
2640 		else {
2641 		}
2642 #endif
2643 	}
2644 #if	TRACE_DEBUG
2645 	else {
2646 	}
2647 #endif
2648 
2649 }
2650 
2651 
2652 
2653 void
wxdobj_unmark_recursively(Wxd_object_t * pobj,uint8_t marker)2654 wxdobj_unmark_recursively(Wxd_object_t *pobj, uint8_t marker)
2655 {
2656 	Wxd_object_t	*po;
2657 
2658 	if (NULL != pobj) {
2659 #if 0
2660 		pobj->mark &= (~(marker));
2661 #endif
2662 		pobj->mark = (uint8_t)((pobj->mark) & (~(marker)));
2663 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
2664 			dk4sto_it_reset((pobj->det).g.i_e);
2665 			do {
2666 				po = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
2667 				if (NULL != po) {
2668 					wxdobj_unmark_recursively(po, marker);
2669 				}
2670 			} while (NULL != po);
2671 		}
2672 	}
2673 
2674 }
2675 
2676 
2677 
2678 void
wxdobj_unmark_all(Wxd_drawing_t * pdrw,uint8_t marker)2679 wxdobj_unmark_all(Wxd_drawing_t *pdrw, uint8_t marker)
2680 {
2681 	Wxd_object_t *pobj;
2682 
2683 	uint8_t		  mask;
2684 
2685 	mask = (uint8_t)(~(marker));
2686 	dk4sto_it_reset(pdrw->i_flat);
2687 	do {
2688 		pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
2689 		if (NULL != pobj) {
2690 			pobj->mark &= mask;
2691 		}
2692 	} while (NULL != pobj);
2693 	dk4sto_it_reset(pdrw->i_stru);
2694 	do {
2695 		pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_stru);
2696 		if (NULL != pobj) {
2697 			pobj->mark &= mask;
2698 		}
2699 	} while (NULL != pobj);
2700 
2701 }
2702 
2703 
2704 
2705 void
wxdobj_mark_recursively(Wxd_object_t * pobj,uint8_t marker)2706 wxdobj_mark_recursively(Wxd_object_t *pobj, uint8_t marker)
2707 {
2708 	Wxd_object_t	*po;
2709 
2710 	if (NULL != pobj) {
2711 		pobj->mark |= marker;
2712 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
2713 			dk4sto_it_reset((pobj->det).g.i_e);
2714 			do {
2715 				po = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
2716 				if (NULL != po) {
2717 					wxdobj_mark_recursively(po, marker);
2718 				}
2719 			} while (NULL != po);
2720 		}
2721 	}
2722 
2723 }
2724 
2725 
2726 
2727 /**	Find sector for point relative to box.
2728 	@param	pbox	Box.
2729 	@param	r		Rounded corners radius.
2730 	@param	ppt		Point.
2731 	@return	Sector number, one from:
2732 	- 0: Point is lower left than box center.
2733 	- 1: Point is centered below box.
2734 	- 2: Point is lower right than box center.
2735 	- 3: Point is left from box center.
2736 	- 4: Point is in box center.
2737 	- 5: Point is right from box center.
2738 	- 6: Point is upper left from box center.
2739 	- 7: Point is centered over box.
2740 	- 8: Point is upper right from box center.
2741 */
2742 static
2743 int
wxdobj_box_sector(Wxd_bb_t * pbox,uint32_t r,dk4_gra_point_t * ppt)2744 wxdobj_box_sector(Wxd_bb_t *pbox, uint32_t r, dk4_gra_point_t *ppt)
2745 {
2746 	int		 back = 4;
2747 
2748 	if (ppt->x < (double)(pbox->xl) + (double)r) {
2749 		/* X: left */
2750 		if (ppt->y < (double)(pbox->yb) + (double)r) {
2751 			back = 0;
2752 		}
2753 		else {
2754 			if (ppt->y > (double)(pbox->yt) - (double)r) {
2755 				back = 6;
2756 			}
2757 			else {
2758 				back = 3;
2759 			}
2760 		}
2761 	}
2762 	else {
2763 		if (ppt->x > (double)(pbox->xr) - (double)r) {
2764 			/* X: right */
2765 			if (ppt->y < (double)(pbox->yb) + (double)r) {
2766 				back = 2;
2767 			}
2768 			else {
2769 				if (ppt->y > (double)(pbox->yt) - (double)r) {
2770 					back = 8;
2771 				}
2772 				else {
2773 					back = 5;
2774 				}
2775 			}
2776 		}
2777 		else {
2778 			/* X: centered */
2779 			if (ppt->y < (double)(pbox->yb) + (double)r) {
2780 				back = 1;
2781 			}
2782 			else {
2783 				if (ppt->y > (double)(pbox->yt) - (double)r) {
2784 					back = 7;
2785 				}
2786 			}
2787 
2788 		}
2789 	}
2790 	return back;
2791 }
2792 
2793 
2794 
2795 double
wxdobj_dist_box(Wxd_bb_t * pbox,uint32_t r,dk4_gra_point_t * ppt,bool bCtrlPt,uint16_t * pIndex)2796 wxdobj_dist_box(
2797 	Wxd_bb_t		*pbox,
2798 	uint32_t		 r,
2799 	dk4_gra_point_t	*ppt,
2800 	bool			 bCtrlPt,
2801 	uint16_t		*pIndex
2802 )
2803 {
2804 	dk4_gra_point_t	pta;
2805 	dk4_gra_point_t	ptb;
2806 	double			d;
2807 	double			back	= -1.0;
2808 	uint16_t		n;
2809 
2810 	if (bCtrlPt) {
2811 		pta.x = (double)(pbox->xl);
2812 		pta.y = (double)(pbox->yb);
2813 		back = dk4gratool_dist_point_point(&pta, ppt, NULL);
2814 		n = 0;
2815 		pta.x = (double)(pbox->xr);
2816 		pta.y = (double)(pbox->yb);
2817 		d = dk4gratool_dist_point_point(&pta, ppt, NULL);
2818 		if (d < back) {
2819 			back = d;
2820 			n = 1;
2821 		}
2822 		pta.x = (double)(pbox->xr);
2823 		pta.y = (double)(pbox->yt);
2824 		d = dk4gratool_dist_point_point(&pta, ppt, NULL);
2825 		if (d < back) {
2826 			back = d;
2827 			n = 2;
2828 		}
2829 		pta.x = (double)(pbox->xl);
2830 		pta.y = (double)(pbox->yt);
2831 		d = dk4gratool_dist_point_point(&pta, ppt, NULL);
2832 		if (d < back) {
2833 			back = d;
2834 			n = 3;
2835 		}
2836 		if (NULL != pIndex) {
2837 			*pIndex = n;
2838 		}
2839 	}
2840 	else {
2841 		if ((uint32_t)0UL == r) {
2842 			pta.x = (double)(pbox->xl);
2843 			pta.y = (double)(pbox->yb);
2844 			ptb.x = (double)(pbox->xr);
2845 			ptb.y = (double)(pbox->yb);
2846 			back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2847 			pta.x = (double)(pbox->xr);
2848 			pta.y = (double)(pbox->yt);
2849 			d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2850 			if ((0.0 <= d) && (d < back)) { back = d; }
2851 			ptb.x = (double)(pbox->xl);
2852 			ptb.y = (double)(pbox->yt);
2853 			d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2854 			if ((0.0 <= d) && (d < back)) { back = d; }
2855 			pta.x = (double)(pbox->xl);
2856 			pta.y = (double)(pbox->yb);
2857 			d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2858 			if ((0.0 <= d) && (d < back)) { back = d; }
2859 		}
2860 		else {
2861 			switch (wxdobj_box_sector(pbox, r, ppt)) {
2862 				case 0: {
2863 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yb);
2864 					back = dk4gratool_dist_point_point(&pta, ppt, NULL);
2865 					back = fabs(back - (double)r);
2866 				} break;
2867 				case 1: {
2868 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yb);
2869 					ptb.x = (double)(pbox->xr); ptb.y = (double)(pbox->yb);
2870 					back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2871 				} break;
2872 				case 2: {
2873 					pta.x = (double)(pbox->xr); pta.y = (double)(pbox->yb);
2874 					back = dk4gratool_dist_point_point(&pta, ppt, NULL);
2875 					back = fabs(back - (double)r);
2876 				} break;
2877 				case 3: {
2878 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yb);
2879 					ptb.x = (double)(pbox->xl); ptb.y = (double)(pbox->yt);
2880 					back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2881 				} break;
2882 				case 5: {
2883 					pta.x = (double)(pbox->xr); pta.y = (double)(pbox->yb);
2884 					ptb.x = (double)(pbox->xr); ptb.y = (double)(pbox->yt);
2885 					back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2886 				} break;
2887 				case 6: {
2888 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yt);
2889 					back = dk4gratool_dist_point_point(&pta, ppt, NULL);
2890 					back = fabs(back - (double)r);
2891 				} break;
2892 				case 7: {
2893 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yt);
2894 					ptb.x = (double)(pbox->xr); ptb.y = (double)(pbox->yt);
2895 					back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2896 				} break;
2897 				case 8: {
2898 					pta.x = (double)(pbox->xr); pta.y = (double)(pbox->yt);
2899 					back = dk4gratool_dist_point_point(&pta, ppt, NULL);
2900 					back = fabs(back - (double)r);
2901 				} break;
2902 				default : {
2903 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yb);
2904 					ptb.x = (double)(pbox->xr); ptb.y = (double)(pbox->yb);
2905 					back = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2906 					pta.x = (double)(pbox->xr); pta.y = (double)(pbox->yt);
2907 					d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2908 					if ((0.0 <= d) && (d < back)) { back = d; }
2909 					ptb.x = (double)(pbox->xl); ptb.y = (double)(pbox->yt);
2910 					d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2911 					if ((0.0 <= d) && (d < back)) { back = d; }
2912 					pta.x = (double)(pbox->xl); pta.y = (double)(pbox->yb);
2913 					d = dk4gratool_dist_point_track(&pta, &ptb, ppt, NULL);
2914 					if ((0.0 <= d) && (d < back)) { back = d; }
2915 				} break;
2916 			}
2917 		}
2918 	}
2919 
2920 	return back;
2921 }
2922 
2923 
2924 
2925 bool
wxdobj_ctrlpt_dist_box(Wxd_bb_t * pbox,dk4_gra_point_t * ppt,uint16_t * pIndex,double dlim)2926 wxdobj_ctrlpt_dist_box(
2927 	Wxd_bb_t		*pbox,
2928 	dk4_gra_point_t	*ppt,
2929 	uint16_t		*pIndex,
2930 	double			 dlim
2931 )
2932 {
2933 	double			d;
2934 	uint16_t		ind			=	(uint16_t)0U;
2935 	bool			back		=	false;
2936 
2937 	d = wxdobj_dist_box(pbox, (uint32_t)0UL, ppt, true, &ind);
2938 	if (dlim >= d) {
2939 		*pIndex	=	ind;
2940 		back	=	true;
2941 	}
2942 	return back;
2943 }
2944 
2945 
2946 
2947 static
2948 double
wxdobj_dist_dot(Wxd_object_t * pobj,dk4_gra_point_t * grapt)2949 wxdobj_dist_dot(
2950 	Wxd_object_t	*pobj,
2951 	dk4_gra_point_t	*grapt
2952 )
2953 {
2954 	dk4_gra_point_t	 pta;
2955 	double			 back	= 0.0;
2956 	double			 r;
2957 
2958 	pta.x = (double)((pobj->det).d.x);
2959 	pta.y = (double)((pobj->det).d.y);
2960 	back  = dk4gratool_dist_point_point(grapt, &pta, NULL);
2961 	/* (d / 2) * (16256000 / 160) */
2962 	r = 50800.0 * (double)((pobj->det).d.d);
2963 	if (WXD_OT_DOT_WHITE == pobj->ot) {
2964 		r += 101600.0;
2965 	}
2966 	if (back > r) {
2967 		back = back - r;
2968 	}
2969 	return back;
2970 }
2971 
2972 
2973 
2974 double
wxdobj_distance_to_point(Wxd_object_t * pobj,Wxd_point_t const * ppt,bool bCtrlPt,uint16_t * pIndex)2975 wxdobj_distance_to_point(
2976 	Wxd_object_t		*pobj,
2977 	Wxd_point_t const	*ppt,
2978 	bool				 bCtrlPt,
2979 	uint16_t			*pIndex
2980 )
2981 {
2982 	dk4_gra_point_t	grapt;			/* Point to test in double coords */
2983 	dk4_gra_point_t	pta;			/* Section start point */
2984 	dk4_gra_point_t	ptb;			/* Section end point */
2985 	double			back = -1.0;	/* Result distance */
2986 	double			d;				/* Distance in current test */
2987 	double			alpha;			/* Ellipse rotation in degree */
2988 	uint16_t		i;				/* Traverse point array */
2989 
2990 	grapt.x = (double)(ppt->x);
2991 	grapt.y = (double)(ppt->y);
2992 	switch ( pobj->ot ) {
2993 		case WXD_OT_TEXT : {
2994 			pta.x = (double)((pobj->det).t.x);
2995 			pta.y = (double)((pobj->det).t.y);
2996 			back  = dk4gratool_dist_point_point(&grapt, &pta, NULL);
2997 			if (bCtrlPt && (NULL != pIndex)) { *pIndex = (uint16_t)0U; }
2998 		} break;
2999 		case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
3000 			if ((NULL != (pobj->det).p.p) && (1 < (pobj->det).p.n)) {
3001 				if (bCtrlPt) {
3002 					for (i = 0; i < (pobj->det).p.n; i++) {
3003 						pta.x = (double)(((pobj->det).p.p)[i].x);
3004 						pta.y = (double)(((pobj->det).p.p)[i].y);
3005 						d = dk4gratool_dist_point_point(&pta, &grapt, NULL);
3006 						if (0 == i) {
3007 							back = d;
3008 							if (NULL != pIndex) { *pIndex = (uint16_t)0U; }
3009 						}
3010 						else {
3011 							if (d < back) {
3012 								back = d;
3013 								if (NULL != pIndex) { *pIndex = (uint16_t)i; }
3014 							}
3015 						}
3016 					}
3017 				}
3018 				else {
3019 					pta.x = (double)(((pobj->det).p.p)[0].x);
3020 					pta.y = (double)(((pobj->det).p.p)[0].y);
3021 					for (i = 0; i < ((pobj->det).p.n - (uint16_t)1U); i++) {
3022 						ptb.x =
3023 						(double)(((pobj->det).p.p)[i + (uint16_t)1U].x);
3024 						ptb.y =
3025 						(double)(((pobj->det).p.p)[i + (uint16_t)1U].y);
3026 						d = dk4gratool_dist_point_track(&pta,&ptb,&grapt,NULL);
3027 						if (0.0 < d) {
3028 							if ((0.0 > back) || (d < back)) { back = d; }
3029 						}
3030 						DK4_MEMCPY(&pta,&ptb,sizeof(dk4_gra_point_t));
3031 					}
3032 					if (WXD_OT_POLYGON == pobj->ot) {
3033 						ptb.x = (double)(((pobj->det).p.p)[0].x);
3034 						ptb.y = (double)(((pobj->det).p.p)[0].y);
3035 						d = dk4gratool_dist_point_track(&pta,&ptb,&grapt,NULL);
3036 						if (0.0 < d) {
3037 							if ((0.0 > back) || (d < back)) { back = d; }
3038 						}
3039 					}
3040 				}
3041 			}
3042 		} break;
3043 		case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
3044 			if ((NULL != (pobj->det).s.p) && (1 < (pobj->det).s.n)) {
3045 				if (bCtrlPt) {
3046 					for (i = 0; i < (pobj->det).s.n; i++) {
3047 						pta.x = (double)(((pobj->det).s.p)[i].x);
3048 						pta.y = (double)(((pobj->det).s.p)[i].y);
3049 						d = dk4gratool_dist_point_point(&pta, &grapt, NULL);
3050 						if (0 == i) {
3051 							back = d;
3052 							if (NULL != pIndex) { *pIndex = (uint16_t)0U; }
3053 						}
3054 						else {
3055 							if (d < back) {
3056 								back = d;
3057 								if (NULL != pIndex) { *pIndex = (uint16_t)i; }
3058 							}
3059 						}
3060 					}
3061 				}
3062 				else {
3063 					pta.x = (double)(((pobj->det).s.p)[0].x);
3064 					pta.y = (double)(((pobj->det).s.p)[0].y);
3065 					for (i = 0; i < ((pobj->det).s.n - (uint16_t)1U); i++) {
3066 						ptb.x =
3067 						(double)(((pobj->det).s.p)[i + (uint16_t)1U].x);
3068 						ptb.y =
3069 						(double)(((pobj->det).s.p)[i + (uint16_t)1U].y);
3070 						d = dk4gratool_dist_point_track(&pta,&ptb,&grapt,NULL);
3071 						if (0.0 < d) {
3072 							if ((0.0 > back) || (d < back)) { back = d; }
3073 						}
3074 						DK4_MEMCPY(&pta,&ptb,sizeof(dk4_gra_point_t));
3075 					}
3076 					if (WXD_OT_C_SPLINE == pobj->ot) {
3077 						ptb.x = (double)(((pobj->det).s.p)[0].x);
3078 						ptb.y = (double)(((pobj->det).s.p)[0].y);
3079 						d = dk4gratool_dist_point_track(&pta,&ptb,&grapt,NULL);
3080 						if (0.0 < d) {
3081 							if ((0.0 > back) || (d < back)) { back = d; }
3082 						}
3083 					}
3084 				}
3085 			}
3086 		} break;
3087 		case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
3088 			pta.x = (double)((pobj->det).a.x1);
3089 			pta.y = (double)((pobj->det).a.y1);
3090 			back  = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3091 			if (NULL != pIndex) { *pIndex = (uint16_t)0U; }
3092 			pta.x = (double)((pobj->det).a.x2);
3093 			pta.y = (double)((pobj->det).a.y2);
3094 			d     = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3095 			if ((0.0 <= d) && (d < back)) {
3096 				back = d;
3097 				if (NULL != pIndex) { *pIndex = (uint16_t)1U; }
3098 			}
3099 			pta.x = (double)((pobj->det).a.x3);
3100 			pta.y = (double)((pobj->det).a.y3);
3101 			d     = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3102 			if ((0.0 <= d) && (d < back)) {
3103 				back = d;
3104 				if (NULL != pIndex) { *pIndex = (uint16_t)2U; }
3105 			}
3106 			if ((WXD_OT_C_ARC == pobj->ot) && (!(bCtrlPt))) {
3107 				if (0 != (pobj->det).a.d) {
3108 					pta.x = (double)((pobj->det).a.x1);
3109 					pta.y = (double)((pobj->det).a.y1);
3110 					ptb.x = (pobj->det).a.x;
3111 					ptb.y = (pobj->det).a.y;
3112 					d = dk4gratool_dist_point_track(&pta, &ptb, &grapt, NULL);
3113 					if ((0.0 <= d) && (d < back)) { back = d; }
3114 					pta.x = (double)((pobj->det).a.x3);
3115 					pta.y = (double)((pobj->det).a.y3);
3116 					d = dk4gratool_dist_point_track(&pta, &ptb, &grapt, NULL);
3117 					if ((0.0 <= d) && (d < back)) { back = d; }
3118 				}
3119 			}
3120 		} break;
3121 		case WXD_OT_CIRCLE : {
3122 			if (bCtrlPt) {
3123 				for (i = 0; i < 4; i++) {
3124 					switch (i) {
3125 						case 0 : {
3126 							pta.x = (double)((pobj->det).e.rx);
3127 							pta.y = 0.0;
3128 						} break;
3129 						case 1 : {
3130 							pta.x = 0.0;
3131 							pta.y = (double)((pobj->det).e.rx);
3132 						} break;
3133 						case 2 : {
3134 							pta.x = 0.0 - (double)((pobj->det).e.rx);
3135 							pta.y = 0.0;
3136 						} break;
3137 						case 3 : {
3138 							pta.x = 0.0;
3139 							pta.y = 0.0 - (double)((pobj->det).e.rx);
3140 						} break;
3141 					}
3142 					pta.x += (double)((pobj->det).e.x);
3143 					pta.y += (double)((pobj->det).e.y);
3144 					d = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3145 					if (0 == i) {
3146 						back = d;
3147 						if (NULL != pIndex) { *pIndex = i; }
3148 					}
3149 					else {
3150 						if (d < back) {
3151 							back = d;
3152 							if (NULL != pIndex) { *pIndex = i; }
3153 						}
3154 					}
3155 				}
3156 				if (NULL != pIndex) {
3157 
3158 				}
3159 
3160 			}
3161 			else {
3162 				pta.x = (double)((pobj->det).e.x);
3163 				pta.y = (double)((pobj->det).e.y);
3164 				d = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3165 				d = d - (double)((pobj->det).e.rx);
3166 				back = fabs(d);
3167 				if (NULL != pIndex) { *pIndex = (uint16_t)0U; }
3168 			}
3169 		} break;
3170 		case WXD_OT_ELLIPSE : {
3171 			if (bCtrlPt) {
3172 				alpha = (M_PI * (double)((pobj->det).e.a)) / 180.0;
3173 				for (i = 0; i < 4; i++) {
3174 					switch (i) {
3175 						case 0 : {
3176 							pta.x = (double)((pobj->det).e.rx);
3177 							pta.y = 0.0;
3178 						} break;
3179 						case 1 : {
3180 							pta.x = 0.0;
3181 							pta.y = (double)((pobj->det).e.ry);
3182 						} break;
3183 						case 2 : {
3184 							pta.x = 0.0 - (double)((pobj->det).e.rx);
3185 							pta.y = 0.0;
3186 						} break;
3187 						case 3 : {
3188 							pta.x = 0.0;
3189 							pta.y = 0.0 - (double)((pobj->det).e.ry);
3190 						} break;
3191 					}
3192 					dk4gratool_rotate_point(&pta, alpha);
3193 					pta.x += (double)((pobj->det).e.x);
3194 					pta.y += (double)((pobj->det).e.y);
3195 					d = dk4gratool_dist_point_point(&grapt, &pta, NULL);
3196 					if (0 == i) {
3197 						back = d;
3198 						if (NULL != pIndex) { *pIndex = i; }
3199 					}
3200 					else {
3201 						if (d < back) {
3202 							back = d;
3203 							if (NULL != pIndex) { *pIndex = i; }
3204 						}
3205 					}
3206 				}
3207 				if (NULL != pIndex) {
3208 
3209 				}
3210 			}
3211 			else {
3212 				pta.x = (double)((pobj->det).e.x);
3213 				pta.y = (double)((pobj->det).e.y);
3214 				back = dk4gratool_dist_point_ellipse(
3215 					&pta,(double)((pobj->det).e.rx),(double)((pobj->det).e.ry),
3216 					((M_PI * (double)((pobj->det).e.a)) / 180.0), &grapt, NULL
3217 				);
3218 			}
3219 		} break;
3220 		case WXD_OT_BOX : {
3221 			back = wxdobj_dist_box(
3222 				&((pobj->det).b.b), (pobj->det).b.r, &grapt, bCtrlPt, pIndex
3223 			);
3224 		} break;
3225 		case WXD_OT_IMAGE : {
3226 			back = wxdobj_dist_box(
3227 				&((pobj->det).i.br), 0UL, &grapt, bCtrlPt, pIndex
3228 			);
3229 		} break;
3230 		case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
3231 			back  = wxdobj_dist_dot(pobj, &grapt);
3232 			if (NULL != pIndex) { *pIndex = (uint16_t)0U; }
3233 		} break;
3234 	}
3235 	return back;
3236 }
3237 
3238 
3239 
3240 Wxd_stipple_t *
wxdobj_find_stipple_structure(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)3241 wxdobj_find_stipple_structure(
3242 	Wxd_drawing_t	*pdrw,
3243 	Wxd_object_t	*pobj
3244 )
3245 {
3246 	if ((NULL != pdrw) && (NULL != pobj)) {
3247 		return (i_find_stipple_structure(pdrw,pobj));
3248 	}
3249 	return NULL;
3250 }
3251 
3252 
3253 
3254 void
wxdobj_remove_unused_stipples(Wxd_drawing_t * pdrw)3255 wxdobj_remove_unused_stipples(
3256 	Wxd_drawing_t	*pdrw
3257 )
3258 {
3259 	Wxd_stipple_t	*pstip;
3260 	Wxd_object_t	*pobj;
3261 	bool			 changed;
3262 
3263 	/*
3264 		Mark all stipples as unused
3265 	*/
3266 	dk4sto_it_reset(pdrw->i_stip);
3267 	do {
3268 		pstip = (Wxd_stipple_t *)dk4sto_it_next(pdrw->i_stip);
3269 		if (NULL != pstip) {
3270 			pstip->cd[7] = 0x00;
3271 		}
3272 	} while (NULL != pstip);
3273 	/*
3274 		Mark used stipples
3275 	*/
3276 	dk4sto_it_reset(pdrw->i_flat);
3277 	do {
3278 		pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
3279 		if (NULL != pobj) {
3280 			if (NULL != pobj->psti) {
3281 				pobj->psti->cd[7] = 0x01;
3282 			}
3283 		}
3284 	} while (NULL != pobj);
3285 	/*
3286 		Remove stipples not marked as used
3287 	*/
3288 	do {
3289 		changed = false;
3290 		dk4sto_it_reset(pdrw->i_stip);
3291 		do {
3292 			pstip = (Wxd_stipple_t *)dk4sto_it_next(pdrw->i_stip);
3293 			if (NULL != pstip) {
3294 				if (0x00 == pstip->cd[7]) {
3295 
3296 #if	TRACE_DEBUG
3297 					for (size_t i = 0; i < 8; i++) {
3298 
3299 					}
3300 
3301 #endif
3302 					changed = true;
3303 					dk4sto_remove(pdrw->s_stip, pstip, NULL);
3304 					if (NULL != pstip->bm) {
3305 						delete (pstip->bm);
3306 					}
3307 					dk4mem_free(pstip);
3308 				}
3309 			}
3310 		} while ((NULL != pstip) && (!(changed)));
3311 	} while (changed);
3312 
3313 }
3314 
3315 
3316 
3317 void
wxdobj_remove_unused_fonts(Wxd_drawing_t * pdrw)3318 wxdobj_remove_unused_fonts(
3319 	Wxd_drawing_t	*pdrw
3320 )
3321 {
3322 	Wxd_font_t		*pfont;
3323 	Wxd_object_t	*pobj;
3324 	bool			 changed;
3325 
3326 	/*	Mark all fonts as unused
3327 	*/
3328 	dk4sto_it_reset(pdrw->i_fonts);
3329 	do {
3330 		pfont = (Wxd_font_t *)dk4sto_it_next(pdrw->i_fonts);
3331 		if (NULL != pfont) {
3332 			pfont->used = false;
3333 		}
3334 	} while (NULL != pfont);
3335 	/*
3336 		Mark used fonts
3337 	*/
3338 	dk4sto_it_reset(pdrw->i_flat);
3339 	do {
3340 		pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
3341 		if (NULL != pobj) {
3342 			if (WXD_OT_TEXT == pobj->ot) {
3343 				if (NULL != (pobj->det).t.font) {
3344 					((pobj->det).t.font)->used = true;
3345 				}
3346 			}
3347 		}
3348 	} while (NULL != pobj);
3349 	/*
3350 		Remove fonts not marked as used
3351 	*/
3352 	do {
3353 		changed = false;
3354 		dk4sto_it_reset(pdrw->i_fonts);
3355 		do {
3356 			pfont = (Wxd_font_t *)dk4sto_it_next(pdrw->i_fonts);
3357 			if (NULL != pfont) {
3358 				if (!(pfont->used)) {
3359 					changed = true;
3360 					dk4sto_remove(pdrw->s_fonts, pfont, NULL);
3361 					if (NULL != pfont->font) {
3362 						delete (pfont->font);
3363 						pfont->font = NULL;
3364 					}
3365 					dk4mem_free(pfont);
3366 				}
3367 			}
3368 		} while ((NULL != pfont) && (!(changed)));
3369 	} while (changed);
3370 
3371 }
3372 
3373 
3374 
3375 size_t
wxdobj_get_number_of_layers(Wxd_drawing_t * pdrw)3376 wxdobj_get_number_of_layers(
3377 	Wxd_drawing_t	*pdrw
3378 )
3379 {
3380 	size_t	back = 0U;
3381 
3382 	if (NULL != pdrw) {
3383 		if (NULL != pdrw->i_layers) {
3384 			dk4sto_it_reset(pdrw->i_layers);
3385 			while (NULL != dk4sto_it_next(pdrw->i_layers)) { back++; }
3386 		}
3387 	}
3388 	return back;
3389 }
3390 
3391 
3392 
3393 void
wxdobj_obj_delete_from_drawing(Wxd_drawing_t * pdrw,Wxd_object_t * pobj)3394 wxdobj_obj_delete_from_drawing(
3395 	Wxd_drawing_t	*pdrw,
3396 	Wxd_object_t	*pobj
3397 )
3398 {
3399 	Wxd_object_t	*po;
3400 	Wxd_object_t	*pn;
3401 
3402 	if ((NULL != pdrw) && (NULL != pobj)) {
3403 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
3404 			dk4sto_remove(pdrw->s_stru, (void *)pobj, NULL);
3405 			pobj->pa = NULL;
3406 			dk4sto_it_reset((pobj->det).g.i_e);
3407 			while (NULL != pobj) {
3408 				po = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
3409 				if (NULL != po) {
3410 					if (WXD_OT_GROUP_BEGIN == po->ot) {
3411 						if (
3412 							(NULL != (po->det).g.s_e)
3413 							&& (NULL != (po->det).g.i_e)
3414 						) {
3415 							dk4sto_it_reset((po->det).g.i_e);
3416 							po->pa = pobj;
3417 							pobj = po;
3418 						}
3419 						else {
3420 							wxdobj_obj_delete(po);
3421 						}
3422 					}
3423 					else {
3424 						dk4sto_remove(pdrw->s_flat, (void *)po, NULL);
3425 						wxdobj_obj_delete(po);
3426 					}
3427 				}
3428 				else {
3429 					pn = pobj->pa;
3430 					wxdobj_obj_delete(pobj);
3431 					pobj = pn;
3432 				}
3433 
3434 			}
3435 		}
3436 		else {
3437 			dk4sto_remove(pdrw->s_stru, (void *)pobj, NULL);
3438 			dk4sto_remove(pdrw->s_flat, (void *)pobj, NULL);
3439 			wxdobj_obj_delete(pobj);
3440 		}
3441 	}
3442 	else {
3443 		if (NULL != pobj) {
3444 			wxdobj_obj_delete(pobj);
3445 		}
3446 	}
3447 
3448 }
3449 
3450 
3451 
3452 int
wxdobj_shift(Wxd_object_t * pobj,Wxd_point_t * ppt,int doit)3453 wxdobj_shift(Wxd_object_t *pobj, Wxd_point_t *ppt, int doit)
3454 {
3455 	dk4_er_t	er;
3456 	int32_t	 	xdiff	= (int32_t)0L;
3457 	int32_t	 	ydiff	= (int32_t)0L;
3458 	int		 	back	= 0;
3459 	uint16_t	i		= 0;
3460 
3461 	if (NULL != pobj) {
3462 		if (NULL != ppt) {
3463 			xdiff = ppt->x;
3464 			ydiff = ppt->y;
3465 			if (((int32_t)0L != xdiff) || ((int32_t)0L != ydiff)) {
3466 				dk4error_init(&er);
3467 				back = 1;
3468 				switch (pobj->ot) {
3469 					case WXD_OT_TEXT : {
3470 						if (0 != doit) {
3471 							(pobj->det).t.x = dk4ma_int32_t_add(
3472 								(pobj->det).t.x, xdiff, &er
3473 							);
3474 							(pobj->det).t.y = dk4ma_int32_t_add(
3475 								(pobj->det).t.y, ydiff, &er
3476 							);
3477 						}
3478 						else {
3479 							(void)dk4ma_int32_t_add(
3480 								(pobj->det).t.x, xdiff, &er
3481 							);
3482 							(void)dk4ma_int32_t_add(
3483 								(pobj->det).t.y, ydiff, &er
3484 							);
3485 						}
3486 					} break;
3487 					case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
3488 
3489 						if (
3490 							(NULL != (pobj->det).p.p)
3491 							&& ((uint16_t)0U < (pobj->det).p.n)
3492 						) {
3493 							for (i = 0; i < (pobj->det).p.n; i++) {
3494 								if (0 != doit) {
3495 									((pobj->det).p.p)[i].x =
3496 									dk4ma_int32_t_add(
3497 										((pobj->det).p.p)[i].x, xdiff, &er
3498 									);
3499 									((pobj->det).p.p)[i].y =
3500 									dk4ma_int32_t_add(
3501 										((pobj->det).p.p)[i].y, ydiff, &er
3502 									);
3503 								}
3504 								else {
3505 									(void)dk4ma_int32_t_add(
3506 										((pobj->det).p.p)[i].x, xdiff, &er
3507 									);
3508 									(void)dk4ma_int32_t_add(
3509 										((pobj->det).p.p)[i].y, ydiff, &er
3510 									);
3511 								}
3512 							}
3513 						}
3514 					} break;
3515 					case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
3516 
3517 						if (
3518 							(NULL != (pobj->det).s.p)
3519 							&& ((uint16_t)0U < (pobj->det).s.n)
3520 						) {
3521 							for (i = 0; i < (pobj->det).s.n; i++) {
3522 								if (0 != doit) {
3523 									((pobj->det).s.p)[i].x =
3524 									dk4ma_int32_t_add(
3525 										((pobj->det).s.p)[i].x, xdiff, &er
3526 									);
3527 									((pobj->det).s.p)[i].y =
3528 									dk4ma_int32_t_add(
3529 										((pobj->det).s.p)[i].y, ydiff, &er
3530 									);
3531 								}
3532 								else {
3533 									(void)dk4ma_int32_t_add(
3534 										((pobj->det).s.p)[i].x, xdiff, &er
3535 									);
3536 									(void)dk4ma_int32_t_add(
3537 										((pobj->det).s.p)[i].y, ydiff, &er
3538 									);
3539 								}
3540 							}
3541 						}
3542 					} break;
3543 					case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
3544 
3545 						if (0 != doit) {
3546 							(pobj->det).a.x1 = dk4ma_int32_t_add(
3547 								(pobj->det).a.x1, xdiff, &er
3548 							);
3549 							(pobj->det).a.y1 = dk4ma_int32_t_add(
3550 								(pobj->det).a.y1, ydiff, &er
3551 							);
3552 							(pobj->det).a.x2 = dk4ma_int32_t_add(
3553 								(pobj->det).a.x2, xdiff, &er
3554 							);
3555 							(pobj->det).a.y2 = dk4ma_int32_t_add(
3556 								(pobj->det).a.y2, ydiff, &er
3557 							);
3558 							(pobj->det).a.x3 = dk4ma_int32_t_add(
3559 								(pobj->det).a.x3, xdiff, &er
3560 							);
3561 							(pobj->det).a.y3 = dk4ma_int32_t_add(
3562 								(pobj->det).a.y3, ydiff, &er
3563 							);
3564 							(pobj->det).a.x += (double)xdiff;
3565 							(pobj->det).a.y += (double)ydiff;
3566 						}
3567 						else {
3568 							(void)dk4ma_int32_t_add((pobj->det).a.x1,xdiff,&er);
3569 							(void)dk4ma_int32_t_add((pobj->det).a.y1,ydiff,&er);
3570 							(void)dk4ma_int32_t_add((pobj->det).a.x2,xdiff,&er);
3571 							(void)dk4ma_int32_t_add((pobj->det).a.y2,ydiff,&er);
3572 							(void)dk4ma_int32_t_add((pobj->det).a.x3,xdiff,&er);
3573 							(void)dk4ma_int32_t_add((pobj->det).a.y3,ydiff,&er);
3574 						}
3575 					} break;
3576 					case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
3577 
3578 						if (0 != doit) {
3579 							(pobj->det).e.x = dk4ma_int32_t_add(
3580 								(pobj->det).e.x, xdiff, &er
3581 							);
3582 							(pobj->det).e.y = dk4ma_int32_t_add(
3583 								(pobj->det).e.y, ydiff, &er
3584 							);
3585 						}
3586 						else {
3587 							(void)dk4ma_int32_t_add((pobj->det).e.x,xdiff,&er);
3588 							(void)dk4ma_int32_t_add((pobj->det).e.y,ydiff,&er);
3589 						}
3590 					} break;
3591 					case WXD_OT_BOX : {
3592 
3593 						if (0 != doit) {
3594 							(pobj->det).b.b.xl = dk4ma_int32_t_add(
3595 								(pobj->det).b.b.xl, xdiff, &er
3596 							);
3597 							(pobj->det).b.b.xr = dk4ma_int32_t_add(
3598 								(pobj->det).b.b.xr, xdiff, &er
3599 							);
3600 							(pobj->det).b.b.yb = dk4ma_int32_t_add(
3601 								(pobj->det).b.b.yb, ydiff, &er
3602 							);
3603 							(pobj->det).b.b.yt = dk4ma_int32_t_add(
3604 								(pobj->det).b.b.yt, ydiff, &er
3605 							);
3606 						}
3607 						else {
3608 							(void)dk4ma_int32_t_add(
3609 								(pobj->det).b.b.xl, xdiff, &er
3610 							);
3611 							(void)dk4ma_int32_t_add(
3612 								(pobj->det).b.b.xr, xdiff, &er
3613 							);
3614 							(void)dk4ma_int32_t_add(
3615 								(pobj->det).b.b.yb, ydiff, &er
3616 							);
3617 							(void)dk4ma_int32_t_add(
3618 								(pobj->det).b.b.yt, ydiff, &er
3619 							);
3620 						}
3621 					} break;
3622 					case WXD_OT_IMAGE : {
3623 
3624 						if (0 != doit) {
3625 							(pobj->det).i.br.xl = dk4ma_int32_t_add(
3626 								(pobj->det).i.br.xl, xdiff, &er
3627 							);
3628 							(pobj->det).i.br.xr = dk4ma_int32_t_add(
3629 								(pobj->det).i.br.xr, xdiff, &er
3630 							);
3631 							(pobj->det).i.br.yb = dk4ma_int32_t_add(
3632 								(pobj->det).i.br.yb, ydiff, &er
3633 							);
3634 							(pobj->det).i.br.yt = dk4ma_int32_t_add(
3635 								(pobj->det).i.br.yt, ydiff, &er
3636 							);
3637 							/*	Re-calculate image placement
3638 							*/
3639 							wxdobj_image_placement(pobj);
3640 						}
3641 						else {
3642 							(void)dk4ma_int32_t_add(
3643 								(pobj->det).i.br.xl, xdiff, &er
3644 							);
3645 							(void)dk4ma_int32_t_add(
3646 								(pobj->det).i.br.xr, xdiff, &er
3647 							);
3648 							(void)dk4ma_int32_t_add(
3649 								(pobj->det).i.br.yb, ydiff, &er
3650 							);
3651 							(void)dk4ma_int32_t_add(
3652 								(pobj->det).i.br.yt, ydiff, &er
3653 							);
3654 						}
3655 					} break;
3656 					case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
3657 
3658 						if (0 != doit) {
3659 							(pobj->det).d.x = dk4ma_int32_t_add(
3660 								(pobj->det).d.x, xdiff, &er
3661 							);
3662 							(pobj->det).d.y = dk4ma_int32_t_add(
3663 								(pobj->det).d.y, ydiff, &er
3664 							);
3665 						}
3666 						else {
3667 							(void)dk4ma_int32_t_add((pobj->det).d.x,xdiff,&er);
3668 							(void)dk4ma_int32_t_add((pobj->det).d.y,ydiff,&er);
3669 						}
3670 					} break;
3671 				}
3672 				if (DK4_E_NONE != er.ec) {
3673 					back = 0;
3674 				}
3675 			}
3676 			else {
3677 				back = 1;
3678 			}
3679 		}
3680 		else {
3681 			back = 1;
3682 		}
3683 	}
3684 
3685 	return back;
3686 }
3687 
3688 
3689 
3690 int
wxdobj_shift_marked(Wxd_drawing_t * pdrw,Wxd_point_t * ppt,int doit)3691 wxdobj_shift_marked(Wxd_drawing_t *pdrw, Wxd_point_t *ppt, int doit)
3692 {
3693 	Wxd_object_t	*pobj;
3694 	int		 		 back	= 0;
3695 
3696 	if (NULL != pdrw) {
3697 		back = 1;
3698 		dk4sto_it_reset(pdrw->i_flat);
3699 		do {
3700 			pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
3701 			if (NULL != pobj) {
3702 				if ((uint8_t)0U != (OBJ_MARKER_1 & (pobj->mark))) {
3703 					if (0 == wxdobj_shift(pobj, ppt, doit)) {
3704 						back = 0;
3705 					}
3706 				}
3707 			}
3708 		} while (NULL != pobj);
3709 	}
3710 
3711 	return back;
3712 }
3713 
3714 
3715 
3716 Wxd_object_t *
wxdobj_copy(Wxd_object_t * psrc)3717 wxdobj_copy(Wxd_object_t *psrc)
3718 {
3719 	Wxd_object_t	*back	= NULL;
3720 	wxBitmap		*obm	= NULL;
3721 	size_t			 npt;
3722 
3723 	if (NULL != psrc) {
3724 		if (WXD_OT_GROUP_BEGIN != psrc->ot) {
3725 			back = dk4mem_new(Wxd_object_t,1,NULL);
3726 			if (NULL != back) {
3727 				DK4_MEMCPY(back,psrc,sizeof(Wxd_object_t));
3728 				back->pa = NULL;
3729 				switch (psrc->ot) {
3730 					case WXD_OT_TEXT : {
3731 						/* t.t, t.tsc */
3732 						(back->det).t.t	  = NULL;
3733 						(back->det).t.tsc = NULL;
3734 						(back->det).t.t	  = dk4strx_dup((psrc->det).t.t, NULL);
3735 						if (NULL != (back->det).t.t) {
3736 							if (NULL != (psrc->det).t.tsc) {
3737 								(back->det).t.tsc =
3738 								dk4strx_dup((psrc->det).t.tsc, NULL);
3739 								if (NULL == (back->det).t.tsc) {
3740 									wxdobj_obj_delete(back);
3741 									back = NULL;
3742 								}
3743 							}
3744 						}
3745 						else {
3746 							wxdobj_obj_delete(back);
3747 							back = NULL;
3748 						}
3749 					} break;
3750 					case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
3751 						/* p.p */
3752 						npt = (size_t)((psrc->det).p.n);
3753 						(back->det).p.p	 = dk4mem_new(Wxd_point_t, npt, NULL);
3754 						if (NULL != (back->det).p.p) {
3755 							npt *= sizeof(Wxd_point_t);
3756 							DK4_MEMCPY((back->det).p.p,(psrc->det).p.p,npt);
3757 						}
3758 						else {
3759 							wxdobj_obj_delete(back);
3760 							back = NULL;
3761 						}
3762 					} break;
3763 					case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
3764 						/* s.p */
3765 						npt = (size_t)((psrc->det).s.n);
3766 						(back->det).s.p =
3767 						dk4mem_new(Wxd_spline_point_t,npt,NULL);
3768 						if (NULL != (back->det).s.p) {
3769 							npt *= sizeof(Wxd_spline_point_t);
3770 							DK4_MEMCPY((back->det).s.p,(psrc->det).s.p,npt);
3771 						}
3772 						else {
3773 							wxdobj_obj_delete(back);
3774 							back = NULL;
3775 						}
3776 					} break;
3777 					case WXD_OT_IMAGE : {
3778 						/* i.fn, i.bm */
3779 						(back->det).i.fn	= NULL;
3780 						(back->det).i.bm	= NULL;
3781 						obm = (psrc->det).i.bm;
3782 						(back->det).i.fn = dk4strx_dup((psrc->det).i.fn, NULL);
3783 						if (NULL != (back->det).i.fn) {
3784 							(back->det).i.bm =
3785 							new wxBitmap(
3786 							obm->GetSubBitmap(
3787 								wxRect(0, 0, obm->GetWidth(), obm->GetHeight())
3788 							)
3789 							);
3790 							if (NULL == (back->det).i.bm) {
3791 								wxdobj_obj_delete(back);
3792 								back = NULL;
3793 							}
3794 							else {
3795 								if (!(((back->det).i.bm)->IsOk())) {
3796 									wxdobj_obj_delete(back);
3797 									back = NULL;
3798 								}
3799 							}
3800 						}
3801 						else {
3802 							wxdobj_obj_delete(back);
3803 							back = NULL;
3804 						}
3805 					} break;
3806 				}
3807 			}
3808 		}
3809 	}
3810 	return back;
3811 }
3812 
3813 
3814 
3815 /**	Test whether the entire group contents can be shifted by given vector.
3816 	@param	pgrsrc	Group containing objects to shift.
3817 	@param	psh		Shift vector.
3818 	@param	doit	Flag: Really do shift operation, 0=test only.
3819 	@return	1 on success, 0 on error (numeric overflow).
3820 */
3821 
3822 static
3823 int
wxdobj_i_group_shift(Wxd_object_t * pgrsrc,Wxd_point_t * psh,int doit)3824 wxdobj_i_group_shift(
3825 	Wxd_object_t	*pgrsrc,
3826 	Wxd_point_t		*psh,
3827 	int				 doit
3828 )
3829 {
3830 	Wxd_object_t	*pno;
3831 	int				 back	= 1;
3832 
3833 	pgrsrc->pa = NULL;
3834 	dk4sto_it_reset((pgrsrc->det).g.i_e);
3835 	while ((1 == back) && (NULL != pgrsrc)) {
3836 		pno = (Wxd_object_t *)dk4sto_it_next((pgrsrc->det).g.i_e);
3837 		if (NULL != pno) {
3838 			if (WXD_OT_GROUP_BEGIN == pno->ot) {
3839 				if (
3840 					(NULL != (pgrsrc->det).g.s_e)
3841 					&& (NULL != (pgrsrc->det).g.i_e)
3842 				) {
3843 					pno->pa = pgrsrc;
3844 					pgrsrc = pno;
3845 					dk4sto_it_reset((pgrsrc->det).g.i_e);
3846 				}
3847 			}
3848 			else {
3849 				if (0 == wxdobj_shift(pno, psh, doit)) {
3850 					back = 0;
3851 				}
3852 			}
3853 		}
3854 		else {
3855 			pgrsrc = pgrsrc->pa;
3856 		}
3857 	}
3858 	return back;
3859 }
3860 
3861 
3862 
3863 /**	Test whether the entire group contents can be shifted by given vector.
3864 	@param	pgrsrc	Group containing objects to shift.
3865 	@param	psh		Shift vector.
3866 	@return	1 on success, 0 on error (numeric overflow).
3867 */
3868 
3869 static
3870 int
wxdobj_group_test_shift(Wxd_object_t * pgrsrc,Wxd_point_t * psh)3871 wxdobj_group_test_shift(
3872 	Wxd_object_t	*pgrsrc,
3873 	Wxd_point_t		*psh
3874 )
3875 {
3876 	int			 back	= 0;
3877 
3878 	if (NULL != pgrsrc) {
3879 		if (NULL != psh) {
3880 			if (((int32_t)0L != psh->x) || ((int32_t)0L != psh->y)) {
3881 				back = wxdobj_i_group_shift(pgrsrc, psh, 0);
3882 			}
3883 			else {
3884 				back = 1;
3885 			}
3886 		}
3887 		else {
3888 			back = 1;
3889 		}
3890 	}
3891 
3892 	return back;
3893 }
3894 
3895 
3896 
3897 
3898 /**	Copy group contents recursively.
3899 	Both source and destination group object must be root group
3900 	objects having no parent.
3901 	@param	pdrw	Drawing containing both groups.
3902 	@param	pgrdst	Destination group.
3903 	@param	pgrsrc	Source group.
3904 	@param	psh		Shift vector for the copy.
3905 	@return	1 on success, 0 on error.
3906 */
3907 
3908 static
3909 int
wxdobj_i_group_copy(Wxd_drawing_t * pdrw,Wxd_object_t * pgrdst,Wxd_object_t * pgrsrc,Wxd_point_t * psh)3910 wxdobj_i_group_copy(
3911 	Wxd_drawing_t	*pdrw,
3912 	Wxd_object_t	*pgrdst,
3913 	Wxd_object_t	*pgrsrc,
3914 	Wxd_point_t		*psh
3915 )
3916 {
3917 	Wxd_object_t	*pso;
3918 	Wxd_object_t	*pdo;
3919 	int				 back	= 1;
3920 
3921 	dk4sto_it_reset((pgrsrc->det).g.i_e);
3922 	while ((NULL != pgrsrc) && (NULL != pgrdst) && (1 == back)) {
3923 		pso = (Wxd_object_t *)dk4sto_it_next((pgrsrc->det).g.i_e);
3924 		if (NULL != pso) {
3925 			if (WXD_OT_GROUP_BEGIN == pso->ot) {
3926 				if (
3927 					(NULL != (pso->det).g.s_e)
3928 					&& (NULL != (pso->det).g.i_e)
3929 				) {
3930 					pdo = wxdobj_drw_add_group(pdrw, pgrdst);
3931 					if (NULL != pdo) {
3932 						dk4sto_it_reset((pso->det).g.i_e);
3933 						pgrsrc = pso;
3934 						pgrdst = pdo;
3935 					}
3936 					else {
3937 						back = 0;
3938 					}
3939 				}
3940 			}
3941 			else {
3942 				pdo = wxdobj_copy(pso);
3943 				if (NULL != pdo) {
3944 					if (0 != wxdobj_drw_register_object(pdrw, pgrdst, pdo)) {
3945 						wxdobj_shift(pdo, psh, 1);
3946 					}
3947 					else {
3948 						wxdobj_obj_delete(pdo);
3949 						back = 0;
3950 					}
3951 				}
3952 				else {
3953 					back = 0;
3954 				}
3955 			}
3956 		}
3957 		else {
3958 			pgrsrc = pgrsrc->pa;
3959 			pgrdst = pgrdst->pa;
3960 		}
3961 	}
3962 
3963 	return back;
3964 }
3965 
3966 
3967 
3968 int
wxdobj_copy_recursive(Wxd_drawing_t * pdrw,Wxd_object_t * pobj,Wxd_point_t * psh)3969 wxdobj_copy_recursive(
3970 	Wxd_drawing_t	*pdrw,
3971 	Wxd_object_t	*pobj,
3972 	Wxd_point_t		*psh
3973 )
3974 {
3975 	Wxd_object_t	*pno;
3976 	Wxd_object_t	*png;
3977 	int				 back = 0;
3978 
3979 	if ((NULL != pdrw) && (NULL != pobj)) {
3980 		if (WXD_OT_GROUP_BEGIN != pobj->ot) {
3981 			/*
3982 				Copy simple object
3983 			*/
3984 			if (0 != wxdobj_shift(pobj, psh, 0)) {
3985 				pno = wxdobj_copy(pobj);
3986 				if (NULL != pno) {
3987 					wxdobj_shift(pno, psh, 1);
3988 					if (0 != wxdobj_drw_register_object(pdrw, NULL, pno)) {
3989 						back = 1;
3990 						wxdobj_bb_simple_object(pdrw, pno);
3991 					}
3992 					else {
3993 						wxdobj_obj_delete(pno);
3994 						/* ERROR: Memory */
3995 #if	0
3996 						dk4error_set_simple_error_code(
3997 							&m_oErrorReport, DK4_E_MEMORY_ALLOCATION_FAILED
3998 						);
3999 #endif
4000 						back = 0;
4001 					}
4002 				}
4003 				else {
4004 					/* ERROR: Memory */
4005 #if	0
4006 					dk4error_set_simple_error_code(
4007 						&m_oErrorReport, DK4_E_MEMORY_ALLOCATION_FAILED
4008 					);
4009 #endif
4010 					back = 0;
4011 				}
4012 			}
4013 			else {
4014 				/* ERROR: Failed to shift */
4015 #if	0
4016 				dk4error_set_simple_error_code(
4017 					&m_oErrorReport, WXD_E_OVERFLOW_COORDINATES
4018 				);
4019 #endif
4020 				back = 0;
4021 			}
4022 		}
4023 		else {
4024 			/*
4025 				Copy a group of objects, probably including subgroups...
4026 			*/
4027 			if (0 != wxdobj_group_test_shift(pobj, psh)) {
4028 				png = wxdobj_drw_add_group(pdrw, NULL);
4029 				if (NULL != png) {
4030 					back = wxdobj_i_group_copy(pdrw, png, pobj, psh);
4031 					wxdobj_bb_modified_object(pdrw, png);
4032 				}
4033 				else {
4034 					/* ERROR: Memory */
4035 #if	0
4036 					dk4error_set_simple_error_code(
4037 						&m_oErrorReport, DK4_E_MEMORY_ALLOCATION_FAILED
4038 					);
4039 #endif
4040 					back = false;
4041 				}
4042 			}
4043 			else {
4044 				/* ERROR: Failed to shift */
4045 #if	0
4046 				dk4error_set_simple_error_code(
4047 					&m_oErrorReport, WXD_E_OVERFLOW_COORDINATES
4048 				);
4049 #endif
4050 				back = false;
4051 			}
4052 		}
4053 	}
4054 
4055 	return back;
4056 }
4057 
4058 
4059 
4060 Wxd_object_t *
wxdobj_point_move_find_object(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,double dlim)4061 wxdobj_point_move_find_object(
4062 	Wxd_drawing_t		*pdrw,
4063 	Wxd_point_t const	*ppt,
4064 	uint16_t			*pindex,
4065 	double				 dlim
4066 )
4067 {
4068 	Wxd_object_t	*back	= NULL;	/* Object to modify */
4069 	Wxd_object_t	*pcand	= NULL;	/* Current object to test */
4070 	double			 backd;			/* Distance to back */
4071 	double			 candd;			/* Distance to cand */
4072 	double			 backx	= 0.0;	/* Distance to back */
4073 	double			 candx;			/* Distance to cand */
4074 	uint16_t		 backi;			/* Point index on back */
4075 	uint16_t		 candi;			/* Point index on cand */
4076 
4077 	if ((NULL != pdrw) && (NULL != ppt) && (NULL != pindex)) {
4078 		dk4sto_it_reset(pdrw->i_flat);
4079 		do {
4080 			pcand = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
4081 			if (NULL != pcand) {
4082 				if (wxdobj_is_active(pcand)) {
4083 				switch ( (int)(pcand->ot) ) {
4084 					case WXD_OT_TEXT :
4085 					case WXD_OT_POLYLINE :
4086 					case WXD_OT_O_SPLINE :
4087 					case WXD_OT_O_ARC :
4088 					case WXD_OT_POLYGON :
4089 					case WXD_OT_C_SPLINE :
4090 					case WXD_OT_C_ARC :
4091 					case WXD_OT_CIRCLE :
4092 					case WXD_OT_ELLIPSE :
4093 					case WXD_OT_BOX :
4094 					case WXD_OT_IMAGE :
4095 					case WXD_OT_DOT_FILLED :
4096 					case WXD_OT_DOT_WHITE : {
4097 						candd = wxdobj_distance_to_point(pcand,ppt,true,&candi);
4098 						candx = wxdobj_distance_to_point(pcand, ppt);
4099 
4100 						if (dlim >= candd) {
4101 							if (NULL == back) {
4102 								back  = pcand;
4103 								backd = candd;
4104 								backx = candx;
4105 								backi = candi;
4106 							}
4107 							else {
4108 								if (backd > candd) {
4109 									back  = pcand;
4110 									backd = candd;
4111 									backx = candx;
4112 									backi = candi;
4113 								}
4114 								else {
4115 									if ((!(backd < candd)) && (backx > candx)) {
4116 
4117 										back  = pcand;
4118 										backd = candd;
4119 										backx = candx;
4120 										backi = candi;
4121 									}
4122 #if	TRACE_DEBUG
4123 									else {
4124 									}
4125 #endif
4126 								}
4127 							}
4128 						}
4129 #if	TRACE_DEBUG
4130 						else {
4131 						}
4132 #endif
4133 					} break;
4134 				}
4135 				}
4136 			}
4137 		} while (NULL != pcand);
4138 		if (NULL != back) {
4139 			*pindex = backi;
4140 		}
4141 	}
4142 
4143 	return back;
4144 }
4145 
4146 
4147 
4148 Wxd_object_t *
wxdobj_modify_spline_find_object(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,double dlim)4149 wxdobj_modify_spline_find_object(
4150 	Wxd_drawing_t		*pdrw,
4151 	Wxd_point_t const	*ppt,
4152 	uint16_t			*pindex,
4153 	double				 dlim
4154 )
4155 {
4156 	Wxd_object_t	*back	= NULL;	/* Object to modify */
4157 	Wxd_object_t	*pcand	= NULL;	/* Current object to test */
4158 	double			 backd;			/* Distance to back */
4159 	double			 candd;			/* Distance to cand */
4160 	double			 backx;			/* Distance to back */
4161 	double			 candx;			/* Distance to cand */
4162 	uint16_t		 backi;			/* Point index on back */
4163 	uint16_t		 candi;			/* Point index on cand */
4164 
4165 	if ((NULL != pdrw) && (NULL != ppt) && (NULL != pindex)) {
4166 		dk4sto_it_reset(pdrw->i_flat);
4167 		do {
4168 			pcand = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
4169 			if (NULL != pcand) {
4170 				if (wxdobj_is_active(pcand)) {
4171 				switch ( (int)(pcand->ot) ) {
4172 					case WXD_OT_O_SPLINE :
4173 					case WXD_OT_C_SPLINE :
4174 					{
4175 						candd = wxdobj_distance_to_point(pcand,ppt,true,&candi);
4176 						candx = wxdobj_distance_to_point(pcand, ppt);
4177 
4178 						if (dlim >= candd) {
4179 							if (NULL == back) {
4180 								back  = pcand;
4181 								backd = candd;
4182 								backx = candx;
4183 								backi = candi;
4184 							}
4185 							else {
4186 								if (backd > candd) {
4187 									back  = pcand;
4188 									backd = candd;
4189 									backx = candx;
4190 									backi = candi;
4191 								}
4192 								else {
4193 									if ((!(backd < candd)) && (backx > candx)) {
4194 
4195 										back  = pcand;
4196 										backd = candd;
4197 										backx = candx;
4198 										backi = candi;
4199 									}
4200 #if	TRACE_DEBUG
4201 									else {
4202 									}
4203 #endif
4204 								}
4205 							}
4206 						}
4207 #if	TRACE_DEBUG
4208 						else {
4209 						}
4210 #endif
4211 					} break;
4212 				}
4213 				}
4214 			}
4215 		} while (NULL != pcand);
4216 		if (NULL != back) {
4217 			*pindex = backi;
4218 		}
4219 	}
4220 
4221 	return back;
4222 }
4223 
4224 
4225 
4226 
4227 Wxd_object_t *
wxdobj_rotate_find_object(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,double dlim)4228 wxdobj_rotate_find_object(
4229 	Wxd_drawing_t		*pdrw,
4230 	Wxd_point_t const	*ppt,
4231 	uint16_t			*pindex,
4232 	double				 dlim
4233 )
4234 {
4235 	Wxd_object_t	*back	= NULL;	/* Object to modify */
4236 	Wxd_object_t	*pcand	= NULL;	/* Current object to test */
4237 	double			 backd;			/* Distance to back */
4238 	/*	FALSE POSITIVE reported by some compilers:
4239 		warning: 'backd' may be used uninitialized in this function
4240 		Initially back is NULL. The back and backd variables are
4241 		always set together (back is not set without setting backd).
4242 		So backd is initialized if back is not NULL.
4243 	*/
4244 	double			 candd;			/* Distance to cand */
4245 	double			 backx	= 0.0;	/* Distance to back */
4246 	double			 candx;			/* Distance to cand */
4247 	uint16_t		 backi;			/* Point index on back */
4248 	uint16_t		 candi;			/* Point index on cand */
4249 	bool			 is_rotatable;	/* Object is rotatable */
4250 
4251 	if ((NULL != pdrw) && (NULL != ppt) && (NULL != pindex)) {
4252 		dk4sto_it_reset(pdrw->i_flat);
4253 		do {
4254 			pcand = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
4255 			if (NULL != pcand) {
4256 				if (wxdobj_is_active(pcand)) {
4257 					is_rotatable = false;
4258 					switch ( (int)(pcand->ot) ) {
4259 						case WXD_OT_TEXT :
4260 						case WXD_OT_POLYLINE :
4261 						case WXD_OT_O_SPLINE :
4262 						case WXD_OT_O_ARC :
4263 						case WXD_OT_POLYGON :
4264 						case WXD_OT_C_SPLINE :
4265 						case WXD_OT_C_ARC :
4266 						case WXD_OT_CIRCLE :
4267 						case WXD_OT_ELLIPSE :
4268 						case WXD_OT_BOX :
4269 						case WXD_OT_IMAGE : {
4270 							is_rotatable = true;
4271 						} break;
4272 						case WXD_OT_DOT_FILLED :
4273 						case WXD_OT_DOT_WHITE : {
4274 							if (NULL != pcand->pa) {
4275 								is_rotatable = true;
4276 							}
4277 						} break;
4278 					}
4279 					if (is_rotatable) {
4280 						candd = wxdobj_distance_to_point(pcand,ppt,true,&candi);
4281 						candx = wxdobj_distance_to_point(pcand, ppt);
4282 
4283 						if (dlim >= candd) {
4284 							if (NULL == back) {
4285 								back  = pcand;
4286 								backd = candd;
4287 								backx = candx;
4288 								backi = candi;
4289 							}
4290 							else {
4291 								if (backd > candd) {
4292 									back  = pcand;
4293 									backd = candd;
4294 									backx = candx;
4295 									backi = candi;
4296 								}
4297 								else {
4298 									if ((!(backd < candd)) && (backx > candx)) {
4299 
4300 										back  = pcand;
4301 										backd = candd;
4302 										backx = candx;
4303 										backi = candi;
4304 									}
4305 #if	TRACE_DEBUG
4306 									else {
4307 									}
4308 #endif
4309 								}
4310 							}
4311 						}
4312 #if	TRACE_DEBUG
4313 						else {
4314 						}
4315 #endif
4316 					}
4317 				}
4318 			}
4319 		} while (NULL != pcand);
4320 		if (NULL != back) {
4321 			*pindex = backi;
4322 		}
4323 	}
4324 
4325 	return back;
4326 }
4327 
4328 
4329 
4330 /**	Check whether to insert the new point before the selected point
4331 	or append after the selected point.
4332 	@param	pobj	Object to modify.
4333 	@param	ppt		Mouse position, not grid-aligned.
4334 	@param	ileft	Index of "left side" point.
4335 	@param	ipoint	Index of selected point.
4336 	@param	iright	Index of "right side" point.
4337 	@param	pbapp	Address of flag to set for appending (true) or
4338 					inserting (false).
4339 */
4340 
4341 static
4342 void
wxdobj_point_add_find_poly_point(Wxd_object_t * pobj,Wxd_point_t const * ppt,uint16_t ileft,uint16_t ipoint,uint16_t iright,bool * pbapp)4343 wxdobj_point_add_find_poly_point(
4344 	Wxd_object_t		*pobj,
4345 	Wxd_point_t const	*ppt,
4346 	uint16_t			 ileft,
4347 	uint16_t			 ipoint,
4348 	uint16_t			 iright,
4349 	bool				*pbapp
4350 )
4351 {
4352 	dk4_gra_point_t		pta;
4353 	dk4_gra_point_t		ptb;
4354 	dk4_gra_point_t		ptc;
4355 	dk4_gra_point_t		ptt;
4356 	double				da;
4357 	double				db;
4358 
4359 	pta.x = (double)(((pobj->det).p.p)[ileft].x);
4360 	pta.y = (double)(((pobj->det).p.p)[ileft].y);
4361 	ptb.x = (double)(((pobj->det).p.p)[iright].x);
4362 	ptb.y = (double)(((pobj->det).p.p)[iright].y);
4363 	ptc.x = (double)(((pobj->det).p.p)[ipoint].x);
4364 	ptc.y = (double)(((pobj->det).p.p)[ipoint].y);
4365 	ptt.x = (double)(ppt->x);
4366 	ptt.y = (double)(ppt->y);
4367 	da = dk4gratool_dist_point_track(&pta, &ptc, &ptt, NULL);
4368 	db = dk4gratool_dist_point_track(&ptb, &ptc, &ptt, NULL);
4369 	*pbapp = (db < da);
4370 
4371 }
4372 
4373 
4374 
4375 /**	Check whether to insert the new point before the selected point
4376 	or append after the selected point.
4377 	@param	pobj	Object to modify.
4378 	@param	ppt		Mouse position, not grid-aligned.
4379 	@param	ileft	Index of "left side" point.
4380 	@param	ipoint	Index of selected point.
4381 	@param	iright	Index of "right side" point.
4382 	@param	pbapp	Address of flag to set for appending (true) or
4383 					inserting (false).
4384 */
4385 
4386 static
4387 void
wxdobj_point_add_find_spline_point(Wxd_object_t * pobj,Wxd_point_t const * ppt,uint16_t ileft,uint16_t ipoint,uint16_t iright,bool * pbapp)4388 wxdobj_point_add_find_spline_point(
4389 	Wxd_object_t		*pobj,
4390 	Wxd_point_t const	*ppt,
4391 	uint16_t			 ileft,
4392 	uint16_t			 ipoint,
4393 	uint16_t			 iright,
4394 	bool				*pbapp
4395 )
4396 {
4397 	dk4_gra_point_t		pta;
4398 	dk4_gra_point_t		ptb;
4399 	dk4_gra_point_t		ptc;
4400 	dk4_gra_point_t		ptt;
4401 	double				da;
4402 	double				db;
4403 
4404 	pta.x = (double)(((pobj->det).s.p)[ileft].x);
4405 	pta.y = (double)(((pobj->det).s.p)[ileft].y);
4406 	ptb.x = (double)(((pobj->det).s.p)[iright].x);
4407 	ptb.y = (double)(((pobj->det).s.p)[iright].y);
4408 	ptc.x = (double)(((pobj->det).s.p)[ipoint].x);
4409 	ptc.y = (double)(((pobj->det).s.p)[ipoint].y);
4410 	ptt.x = (double)(ppt->x);
4411 	ptt.y = (double)(ppt->y);
4412 	da = dk4gratool_dist_point_track(&pta, &ptc, &ptt, NULL);
4413 	db = dk4gratool_dist_point_track(&ptb, &ptc, &ptt, NULL);
4414 	*pbapp = (db < da);
4415 
4416 }
4417 
4418 
4419 
4420 /**	Find object to add points to or delete points from.
4421 	@param	pdrw	Drawing to search.
4422 	@param	ppt		Mouse position.
4423 	@param	pindex	Address of index variable to set on success.
4424 	@param	dlim	Distance limit.
4425 	@param	doadd	Flag: Find object to add points to.
4426 	@return	Object found.
4427 */
4428 static
4429 Wxd_object_t *
wxdobj_point_del_find_object_internal(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,double dlim,int doadd)4430 wxdobj_point_del_find_object_internal(
4431 	Wxd_drawing_t		*pdrw,
4432 	Wxd_point_t const	*ppt,
4433 	uint16_t			*pindex,
4434 	double				 dlim,
4435 	int					 doadd
4436 )
4437 {
4438 	Wxd_object_t	*back	= NULL;	/* Object to modify */
4439 	Wxd_object_t	*pcand	= NULL;	/* Current object to test */
4440 	double			 backd;			/* Distance to back */
4441 	/*	FALSE POSITIVE reported by some compilers:
4442 		warning: 'backd' may be used uninitialized in this function
4443 		Initially back is NULL. The back and backd variables are
4444 		always set together (back is not set without setting backd).
4445 		So backd is initialized if back is not NULL.
4446 	*/
4447 	double			 candd;			/* Distance to cand */
4448 	double			 backx	= 0.0;	/* Distance to back */
4449 	double			 candx;			/* Distance to cand */
4450 	uint16_t		 backi;			/* Point index on back */
4451 	uint16_t		 candi;			/* Point index on cand */
4452 	bool			 btest;
4453 	if ((NULL != pdrw) && (NULL != ppt) && (NULL != pindex)) {
4454 		backi = (uint16_t)0U;
4455 		dk4sto_it_reset(pdrw->i_flat);
4456 		do {
4457 			pcand = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
4458 			if (NULL != pcand) {
4459 				btest = false;
4460 				/*	For open splines and polylines we need at least
4461 					2 points remaining after deleting a point.
4462 					For closed splines and polygons we need at least
4463 					3 points remaining after deleting a point.
4464 
4465 					2020-08-28
4466 					When adding point there must be less than UINT16_MAX
4467 					existing points.
4468 				*/
4469 				switch ( (int)(pcand->ot) ) {
4470 					case WXD_OT_POLYLINE : {
4471 						if (0 != doadd) {
4472 							if (UINT16_MAX > (pcand->det).p.n) {
4473 								btest = true;
4474 							}
4475 						}
4476 						else {
4477 							if ((uint16_t)2U < (pcand->det).p.n) {
4478 								btest = true;
4479 							}
4480 						}
4481 					} break;
4482 					case WXD_OT_POLYGON : {
4483 						if (0 != doadd) {
4484 							if (UINT16_MAX > (pcand->det).p.n) {
4485 								btest = true;
4486 							}
4487 						}
4488 						else {
4489 							if ((uint16_t)3U < (pcand->det).p.n) {
4490 								btest = true;
4491 							}
4492 						}
4493 					} break;
4494 					case WXD_OT_O_SPLINE : {
4495 						if (0 != doadd) {
4496 							if (UINT16_MAX > (pcand->det).s.n) {
4497 								btest = true;
4498 							}
4499 						}
4500 						else {
4501 							if ((uint16_t)2U < (pcand->det).s.n) {
4502 								btest = true;
4503 							}
4504 						}
4505 					} break;
4506 					case WXD_OT_C_SPLINE : {
4507 						if (0 != doadd) {
4508 							if (UINT16_MAX > (pcand->det).s.n) {
4509 								btest = true;
4510 							}
4511 						}
4512 						else {
4513 							if ((uint16_t)3U < (pcand->det).s.n) {
4514 								btest = true;
4515 							}
4516 						}
4517 					} break;
4518 				}
4519 				if (btest) {
4520 					if (!wxdobj_is_active(pcand)) {
4521 						btest = false;
4522 					}
4523 				}
4524 				if (btest) {
4525 					candd = wxdobj_distance_to_point(pcand, ppt, true, &candi);
4526 					candx = wxdobj_distance_to_point(pcand, ppt);
4527 					if (dlim >= candd) {
4528 						if (NULL == back) {
4529 							back  = pcand;
4530 							backd = candd;
4531 							backx = candx;
4532 							backi = candi;
4533 						}
4534 						else {
4535 							if (backd > candd) {
4536 								back  = pcand;
4537 								backd = candd;
4538 								backx = candx;
4539 								backi = candi;
4540 							}
4541 							else {
4542 								if ((!(backd < candd)) && (backx > candx)) {
4543 									back  = pcand;
4544 									backd = candd;
4545 									backx = candx;
4546 									backi = candi;
4547 								}
4548 #if	TRACE_DEBUG
4549 								else {
4550 								}
4551 #endif
4552 							}
4553 						}
4554 					}
4555 #if	TRACE_DEBUG
4556 					else {
4557 					}
4558 #endif
4559 				}
4560 			}
4561 		} while (NULL != pcand);
4562 		if (NULL != back) {
4563 			*pindex = backi;
4564 		}
4565 	}
4566 	return back;
4567 
4568 }
4569 
4570 
4571 Wxd_object_t *
wxdobj_point_add_find_object(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,bool * pbapp,double dlim)4572 wxdobj_point_add_find_object(
4573 	Wxd_drawing_t		*pdrw,
4574 	Wxd_point_t const	*ppt,
4575 	uint16_t			*pindex,
4576 	bool				*pbapp,
4577 	double				 dlim
4578 )
4579 {
4580 	dk4_gra_point_t		 pta;
4581 	dk4_gra_point_t		 ptb;
4582 	dk4_gra_point_t		 ptt;
4583 	Wxd_object_t		*back		=	NULL;
4584 	double				 da;
4585 	double				 db;
4586 	uint16_t			 ileft		=	(uint16_t)0U;
4587 	uint16_t			 iright		=	(uint16_t)0U;
4588 	bool				 bAppend	=	false;
4589 
4590 	back = wxdobj_point_del_find_object_internal(pdrw, ppt, pindex, dlim, 1);
4591 	if (NULL != back) {
4592 		ileft	= (uint16_t)(*pindex - 1U);
4593 		iright	= (uint16_t)(*pindex + 1U);
4594 		switch ( (int)(back->ot) ) {
4595 			case WXD_OT_POLYLINE : {
4596 				if ((uint16_t)0U < *pindex) {
4597 					if ( ((back->det).p.n - (uint16_t)1U) > *pindex) {
4598 
4599 						wxdobj_point_add_find_poly_point(
4600 							back, ppt, ileft, *pindex, iright, &bAppend
4601 						);
4602 					}
4603 					else {
4604 						pta.x = (double)(((back->det).p.p)[ileft].x);
4605 						pta.y = (double)(((back->det).p.p)[ileft].y);
4606 						ptb.x = (double)(((back->det).p.p)[*pindex].x);
4607 						ptb.y = (double)(((back->det).p.p)[*pindex].y);
4608 						ptt.x = (double)(ppt->x);
4609 						ptt.y = (double)(ppt->y);
4610 						da = dk4gratool_dist_point_point(&ptb, &pta, NULL);
4611 						db = dk4gratool_dist_point_point(&ptt, &pta, NULL);
4612 						bAppend = (db > da);
4613 					}
4614 				}
4615 				else {
4616 					pta.x = (double)(((back->det).p.p)[0].x);
4617 					pta.y = (double)(((back->det).p.p)[0].y);
4618 					ptb.x = (double)(((back->det).p.p)[1].x);
4619 					ptb.y = (double)(((back->det).p.p)[1].y);
4620 					ptt.x = (double)(ppt->x);
4621 					ptt.y = (double)(ppt->y);
4622 					da = dk4gratool_dist_point_point(&pta, &ptb, NULL);
4623 					db = dk4gratool_dist_point_point(&ptt, &ptb, NULL);
4624 					bAppend = (db <= da);
4625 				}
4626 			} break;
4627 			case WXD_OT_O_SPLINE : {
4628 				if ((uint16_t)0U < *pindex) {
4629 					if ( ((back->det).s.n - (uint16_t)1U) > *pindex) {
4630 
4631 						wxdobj_point_add_find_spline_point(
4632 							back, ppt, ileft, *pindex, iright, &bAppend
4633 						);
4634 					}
4635 					else {
4636 						pta.x = (double)(((back->det).s.p)[ileft].x);
4637 						pta.y = (double)(((back->det).s.p)[ileft].y);
4638 						ptb.x = (double)(((back->det).s.p)[*pindex].x);
4639 						ptb.y = (double)(((back->det).s.p)[*pindex].y);
4640 						ptt.x = (double)(ppt->x);
4641 						ptt.y = (double)(ppt->y);
4642 						da = dk4gratool_dist_point_point(&ptb, &pta, NULL);
4643 						db = dk4gratool_dist_point_point(&ptt, &pta, NULL);
4644 						bAppend = (db > da);
4645 					}
4646 				}
4647 				else {
4648 					pta.x = (double)(((back->det).s.p)[0].x);
4649 					pta.y = (double)(((back->det).s.p)[0].y);
4650 					ptb.x = (double)(((back->det).s.p)[1].x);
4651 					ptb.y = (double)(((back->det).s.p)[1].y);
4652 					ptt.x = (double)(ppt->x);
4653 					ptt.y = (double)(ppt->y);
4654 					da = dk4gratool_dist_point_point(&pta, &ptb, NULL);
4655 					db = dk4gratool_dist_point_point(&ptt, &ptb, NULL);
4656 					bAppend = (db <= da);
4657 				}
4658 			} break;
4659 			case WXD_OT_POLYGON : {
4660 				if ((uint16_t)0U < *pindex) {
4661 					if ( ((back->det).p.n - (uint16_t)1U) <= *pindex) {
4662 
4663 						iright = (uint16_t)0U;
4664 					}
4665 				}
4666 				else {
4667 					ileft = (uint16_t)((back->det).p.n - 1U);
4668 				}
4669 				wxdobj_point_add_find_poly_point(
4670 					back, ppt, ileft, *pindex, iright, &bAppend
4671 				);
4672 			} break;
4673 			case WXD_OT_C_SPLINE : {
4674 				if ((uint16_t)0U < *pindex) {
4675 					if ( ((back->det).s.n - (uint16_t)1U) <= *pindex) {
4676 						iright = (uint16_t)0U;
4677 					}
4678 				}
4679 				else {
4680 					ileft = (uint16_t)((back->det).s.n - 1U);
4681 				}
4682 				wxdobj_point_add_find_spline_point(
4683 					back, ppt, ileft, *pindex, iright, &bAppend
4684 				);
4685 			} break;
4686 		}
4687 		*pbapp = bAppend;
4688 	}
4689 	return back;
4690 }
4691 
4692 
4693 
4694 Wxd_object_t *
wxdobj_point_del_find_object(Wxd_drawing_t * pdrw,Wxd_point_t const * ppt,uint16_t * pindex,double dlim)4695 wxdobj_point_del_find_object(
4696 	Wxd_drawing_t		*pdrw,
4697 	Wxd_point_t const	*ppt,
4698 	uint16_t			*pindex,
4699 	double				 dlim
4700 )
4701 {
4702 	return (wxdobj_point_del_find_object_internal(pdrw, ppt, pindex, dlim, 0));
4703 }
4704 
4705 
4706 
4707 static
4708 void
wxdobj_get_box_control_point(Wxd_point_t * pdst,Wxd_bb_t const * psrc,uint16_t pind)4709 wxdobj_get_box_control_point(
4710 	Wxd_point_t		*pdst,
4711 	Wxd_bb_t const	*psrc,
4712 	uint16_t		 pind
4713 )
4714 {
4715 	switch ( (int)pind ) {
4716 		case 3 : {
4717 			pdst->x = psrc->xl; pdst->y = psrc->yt;
4718 		} break;
4719 		case 2 : {
4720 			pdst->x = psrc->xr; pdst->y = psrc->yt;
4721 		} break;
4722 		case 1 : {
4723 			pdst->x = psrc->xr; pdst->y = psrc->yb;
4724 		} break;
4725 		default : {
4726 			pdst->x = psrc->xl; pdst->y = psrc->yb;
4727 		} break;
4728 	}
4729 }
4730 
4731 
4732 
4733 static
4734 void
wxdobj_set_box_control_point(Wxd_bb_t * pdst,Wxd_point_t const * psrc,uint16_t pind)4735 wxdobj_set_box_control_point(
4736 	Wxd_bb_t 			*pdst,
4737 	Wxd_point_t const	*psrc,
4738 	uint16_t			 pind
4739 )
4740 {
4741 	switch ( (int)pind ) {
4742 		case 3 : {
4743 			pdst->xl = psrc->x; pdst->yt = psrc->y;
4744 		} break;
4745 		case 2 : {
4746 			pdst->xr = psrc->x; pdst->yt = psrc->y;
4747 		} break;
4748 		case 1 : {
4749 			pdst->xr = psrc->x; pdst->yb = psrc->y;
4750 		} break;
4751 		default : {
4752 			pdst->xl = psrc->x; pdst->yb = psrc->y;
4753 		} break;
4754 	}
4755 }
4756 
4757 
4758 
4759 static
4760 void
wxdobj_set_ellipse_control_point(Wxd_object_t * pdst,Wxd_point_t const * psrc,uint16_t pind,dk4_er_t * erp)4761 wxdobj_set_ellipse_control_point(
4762 	Wxd_object_t 		*pdst,
4763 	Wxd_point_t	const	*psrc,
4764 	uint16_t			 pind,
4765 	dk4_er_t			*erp
4766 )
4767 {
4768 	int32_t		r;
4769 	int16_t		rot;
4770 	double		dx;
4771 	double		dy;
4772 	double		a;
4773 
4774 
4775 
4776 	dx = (double)(psrc->x) - (double)((pdst->det).e.x);
4777 	dy = (double)(psrc->y) - (double)((pdst->det).e.y);
4778 
4779 
4780 	r = dk4ma_int32_from_double(
4781 		dk4ma_rint(sqrt(dx * dx + dy * dy)), erp
4782 	);
4783 	a = atan2(dy, dx);
4784 	if (dk4ma_is_finite(a)) {
4785 		rot = dk4ma_int16_from_double(
4786 			dk4ma_rint((180.0 * a) / M_PI), erp
4787 		);
4788 		while (-360 > rot) { rot = (int16_t)(rot + 360); }
4789 		while ( 360 < rot) { rot = (int16_t)(rot - 360); }
4790 
4791 		switch ( (int)pind ) {
4792 			case 3 : {
4793 				(pdst->det).e.ry = r;
4794 				rot = (int16_t)(rot - 270);
4795 				while (-360 > rot) { rot = (int16_t)(rot + 360); }
4796 			} break;
4797 			case 2 : {
4798 				(pdst->det).e.rx = r;
4799 				rot = (int16_t)(rot - 180);
4800 				while (-360 > rot) { rot = (int16_t)(rot + 360); }
4801 			} break;
4802 			case 1 : {
4803 				(pdst->det).e.ry = r;
4804 				rot = (int16_t)(rot - 90);
4805 				while (-360 > rot) { rot = (int16_t)(rot + 360); }
4806 			} break;
4807 			default : {
4808 				(pdst->det).e.rx = r;
4809 			} break;
4810 		}
4811 		(pdst->det).e.a = rot;
4812 	}
4813 	else {
4814 		dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
4815 	}
4816 }
4817 
4818 
4819 
4820 bool
wxdobj_get_control_point(Wxd_point_t * pdst,Wxd_object_t const * psrc,uint16_t pind)4821 wxdobj_get_control_point(
4822 	Wxd_point_t			*pdst,
4823 	Wxd_object_t const	*psrc,
4824 	uint16_t			 pind
4825 )
4826 {
4827 	dk4_er_t		er;					/* Error report */
4828 	dk4_gra_point_t	pta;				/* Graphics point */
4829 	bool			back	= false;	/* Function result */
4830 
4831 	if ((NULL != pdst) && (NULL != psrc)) {
4832 		switch ( (int)(psrc->ot) ) {
4833 			case WXD_OT_TEXT : {
4834 				pdst->x = (psrc->det).t.x;
4835 				pdst->y = (psrc->det).t.y;
4836 				back = true;
4837 			} break;
4838 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
4839 				if ((NULL != (psrc->det).p.p) && (pind < (psrc->det).p.n)) {
4840 					pdst->x = ((psrc->det).p.p)[pind].x;
4841 					pdst->y = ((psrc->det).p.p)[pind].y;
4842 					back = true;
4843 				}
4844 			} break;
4845 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
4846 				if ((NULL != (psrc->det).s.p) && (pind < (psrc->det).s.n)) {
4847 					pdst->x = ((psrc->det).s.p)[pind].x;
4848 					pdst->y = ((psrc->det).s.p)[pind].y;
4849 					back = true;
4850 				}
4851 			} break;
4852 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
4853 				if (2U == pind) {
4854 					pdst->x = (psrc->det).a.x3;
4855 					pdst->y = (psrc->det).a.y3;
4856 					back = true;
4857 				}
4858 				else {
4859 					if (1U == pind) {
4860 						pdst->x = (psrc->det).a.x2;
4861 						pdst->y = (psrc->det).a.y2;
4862 						back = true;
4863 					}
4864 					else {
4865 						pdst->x = (psrc->det).a.x1;
4866 						pdst->y = (psrc->det).a.y1;
4867 						back = true;
4868 					}
4869 				}
4870 			} break;
4871 			case WXD_OT_CIRCLE : {
4872 				if ((uint32_t)(DK4_I32_MAX) >= (psrc->det).e.rx) {
4873 					dk4error_init(&er);
4874 					switch ( (int)pind ) {
4875 						case 3 : {
4876 							pdst->x = (psrc->det).e.x;
4877 							pdst->y = dk4ma_int32_t_sub(
4878 								(psrc->det).e.y,(int32_t)((psrc->det).e.rx),&er
4879 							);
4880 						} break;
4881 						case 2 : {
4882 							pdst->x = dk4ma_int32_t_sub(
4883 								(psrc->det).e.x,(int32_t)((psrc->det).e.rx),&er
4884 							);
4885 							pdst->y = (psrc->det).e.y;
4886 						} break;
4887 						case 1 : {
4888 							pdst->x = (psrc->det).e.x;
4889 							pdst->y = dk4ma_int32_t_add(
4890 								(psrc->det).e.y,(int32_t)((psrc->det).e.rx),&er
4891 							);
4892 						} break;
4893 						default : {
4894 							pdst->x = dk4ma_int32_t_add(
4895 								(psrc->det).e.x,(int32_t)((psrc->det).e.rx),&er
4896 							);
4897 							pdst->y = (psrc->det).e.y;
4898 						} break;
4899 					}
4900 					if (DK4_E_NONE == er.ec) {
4901 						back = true;
4902 					}
4903 				}
4904 			} break;
4905 			case WXD_OT_ELLIPSE : {
4906 				dk4error_init(&er);
4907 				if ((int16_t)0 == (psrc->det).e.a) {	/* Not rotated */
4908 					if (
4909 						((uint32_t)(DK4_I32_MAX) >= (psrc->det).e.rx)
4910 						&& ((uint32_t)(DK4_I32_MAX) >= (psrc->det).e.ry)
4911 					) {
4912 						switch ( (int)pind ) {
4913 							case 3 : {
4914 								pdst->x = (psrc->det).e.x;
4915 								pdst->y = dk4ma_int32_t_sub(
4916 									(psrc->det).e.y,
4917 									(int32_t)((psrc->det).e.ry), &er
4918 								);
4919 							} break;
4920 							case 2 : {
4921 								pdst->x = dk4ma_int32_t_sub(
4922 									(psrc->det).e.x,
4923 									(int32_t)((psrc->det).e.rx), &er
4924 								);
4925 								pdst->y = (psrc->det).e.y;
4926 							} break;
4927 							case 1 : {
4928 								pdst->x = (psrc->det).e.x;
4929 								pdst->y = dk4ma_int32_t_add(
4930 									(psrc->det).e.y,
4931 									(int32_t)((psrc->det).e.ry), &er
4932 								);
4933 							} break;
4934 							default : {
4935 								pdst->x = dk4ma_int32_t_add(
4936 									(psrc->det).e.x,
4937 									(int32_t)((psrc->det).e.rx), &er
4938 								);
4939 								pdst->y = (psrc->det).e.y;
4940 							} break;
4941 						}
4942 					}
4943 					if (DK4_E_NONE == er.ec) {
4944 						back = true;
4945 					}
4946 				}
4947 				else {									/* Rotated */
4948 					switch ( (int)pind ) {
4949 						case 3 : {
4950 							pta.x = 0.0;
4951 							pta.y = 0.0 - (double)((psrc->det).e.ry);
4952 						} break;
4953 						case 2 : {
4954 							pta.x = 0.0 - (double)((psrc->det).e.rx);
4955 							pta.y = 0.0;
4956 						} break;
4957 						case 1 : {
4958 							pta.x = 0.0;
4959 							pta.y = (double)((psrc->det).e.ry);
4960 						} break;
4961 						default : {
4962 							pta.x = (double)((psrc->det).e.rx);
4963 							pta.y = 0.0;
4964 						} break;
4965 					}
4966 					dk4gratool_rotate_point(
4967 						&pta, ((M_PI * (double)((psrc->det).e.a)) / 180.0)
4968 					);
4969 					pta.x += (double)((psrc->det).e.x);
4970 					pta.y += (double)((psrc->det).e.y);
4971 					pdst->x = dk4ma_int32_from_double(dk4ma_rint(pta.x), &er);
4972 					pdst->y = dk4ma_int32_from_double(dk4ma_rint(pta.y), &er);
4973 					if (DK4_E_NONE == er.ec) {
4974 						back =  true;
4975 					}
4976 				}
4977 			} break;
4978 			case WXD_OT_BOX : {
4979 				wxdobj_get_box_control_point(pdst, &((psrc->det).b.b), pind);
4980 				back =  true;
4981 			} break;
4982 			case WXD_OT_IMAGE : {
4983 				wxdobj_get_box_control_point(pdst, &((psrc->det).i.br), pind);
4984 				back = true;
4985 			} break;
4986 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
4987 				pdst->x = (psrc->det).d.x;
4988 				pdst->y = (psrc->det).d.y;
4989 				back = true;
4990 			} break;
4991 		}
4992 	}
4993 	return back;
4994 }
4995 
4996 
4997 
4998 bool
wxdobj_set_control_point(Wxd_object_t * pdst,Wxd_point_t const * psrc,uint16_t pind)4999 wxdobj_set_control_point(
5000 	Wxd_object_t 		*pdst,
5001 	Wxd_point_t	const	*psrc,
5002 	uint16_t			 pind
5003 )
5004 {
5005 	dk4_er_t	er;					/* Error report */
5006 	double		dx;					/* X difference control point, center */
5007 	double		dy;					/* Y difference control point, center */
5008 	int32_t		newr;				/* New radius */
5009 	bool		back	= false;	/* Function result */
5010 
5011 	if ((NULL != pdst) && (NULL != psrc)) {
5012 
5013 
5014 		switch ( (int)(pdst->ot) ) {
5015 			case WXD_OT_TEXT : {
5016 				(pdst->det).t.x = psrc->x;
5017 				(pdst->det).t.y = psrc->y;
5018 				back = true;
5019 			} break;
5020 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
5021 				if ((NULL != (pdst->det).p.p) && (pind < (pdst->det).p.n)) {
5022 					((pdst->det).p.p)[pind].x = psrc->x;
5023 					((pdst->det).p.p)[pind].y = psrc->y;
5024 					back = true;
5025 				}
5026 			} break;
5027 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
5028 				if ((NULL != (pdst->det).s.p) && (pind < (pdst->det).s.n)) {
5029 					((pdst->det).s.p)[pind].x = psrc->x;
5030 					((pdst->det).s.p)[pind].y = psrc->y;
5031 					back = true;
5032 				}
5033 			} break;
5034 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
5035 				if (2U == pind) {
5036 					(pdst->det).a.x3 = psrc->x;
5037 					(pdst->det).a.y3 = psrc->y;
5038 					back = true;
5039 				}
5040 				else {
5041 					if (1U == pind) {
5042 						(pdst->det).a.x2 = psrc->x;
5043 						(pdst->det).a.y2 = psrc->y;
5044 						back = true;
5045 					}
5046 					else {
5047 						(pdst->det).a.x1 = psrc->x;
5048 						(pdst->det).a.y1 = psrc->y;
5049 						back = true;
5050 					}
5051 				}
5052 				wxdarc_calculation(
5053 					&((pdst->det).a.x),
5054 					&((pdst->det).a.y),
5055 					&((pdst->det).a.r),
5056 					&((pdst->det).a.a),
5057 					&((pdst->det).a.b),
5058 					&((pdst->det).a.d),
5059 					(pdst->det).a.x1,
5060 					(pdst->det).a.y1,
5061 					(pdst->det).a.x2,
5062 					(pdst->det).a.y2,
5063 					(pdst->det).a.x3,
5064 					(pdst->det).a.y3
5065 				);
5066 			} break;
5067 			case WXD_OT_CIRCLE : {
5068 				dk4error_init(&er);
5069 #if	0
5070 				/*	2020-03-24	Modification
5071 					Clang static analyzer complains about this line because
5072 					newr is overwritten in all the if/else branches below.
5073 				*/
5074 				newr = (int32_t)0L;
5075 #endif
5076 				if ((pdst->det).e.x == psrc->x) {
5077 					newr = dk4ma_int32_t_abs(
5078 						dk4ma_int32_t_sub((pdst->det).e.y, psrc->y, &er), &er
5079 					);
5080 				}
5081 				else {
5082 					if ((pdst->det).e.y == psrc->y) {
5083 						newr = dk4ma_int32_t_abs(
5084 							dk4ma_int32_t_sub((pdst->det).e.x,psrc->x,&er), &er
5085 						);
5086 					}
5087 					else {
5088 						dx = (double)((pdst->det).e.x) - (double)(psrc->x);
5089 						dy = (double)((pdst->det).e.y) - (double)(psrc->y);
5090 						newr = dk4ma_int32_from_double(
5091 							sqrt(dx * dx + dy * dy), &er
5092 						);
5093 					}
5094 				}
5095 				if (DK4_E_NONE == er.ec) {
5096 					(pdst->det).e.rx = newr;
5097 					back = true;
5098 				}
5099 			} break;
5100 			case WXD_OT_ELLIPSE : {
5101 
5102 				dk4error_init(&er);
5103 				switch ( (int)pind ) {
5104 					case 3 : {
5105 						if ((pdst->det).e.x == psrc->x) {
5106 							if (psrc->y <= (pdst->det).e.y) {
5107 								(pdst->det).e.a = 0;
5108 								(pdst->det).e.ry = dk4ma_int32_t_sub(
5109 									(pdst->det).e.y, psrc->y, &er
5110 								);
5111 							}
5112 							else {
5113 								(pdst->det).e.a = 180;
5114 								(pdst->det).e.ry = dk4ma_int32_t_sub(
5115 									psrc->y, (pdst->det).e.y, &er
5116 								);
5117 							}
5118 						}
5119 						else {
5120 							if ((pdst->det).e.y == psrc->y) {
5121 								if (psrc->x >= (pdst->det).e.x) {
5122 									(pdst->det).e.a = 90;
5123 									(pdst->det).e.ry = dk4ma_int32_t_sub(
5124 										psrc->x, (pdst->det).e.x, &er
5125 									);
5126 								}
5127 								else {
5128 									(pdst->det).e.a = -90;
5129 									(pdst->det).e.ry = dk4ma_int32_t_sub(
5130 										(pdst->det).e.x, psrc->x, &er
5131 									);
5132 								}
5133 							}
5134 							else {
5135 								wxdobj_set_ellipse_control_point(
5136 									pdst, psrc, pind, &er
5137 								);
5138 							}
5139 						}
5140 					} break;
5141 					case 2 : {
5142 						if ((pdst->det).e.y == psrc->y) {
5143 							if (psrc->x <= (pdst->det).e.x) {
5144 								(pdst->det).e.a = 0;
5145 								(pdst->det).e.rx = dk4ma_int32_t_sub(
5146 									(pdst->det).e.x, psrc->x, &er
5147 								);
5148 							}
5149 							else {
5150 								(pdst->det).e.a = 180;
5151 								(pdst->det).e.rx = dk4ma_int32_t_sub(
5152 									psrc->x, (pdst->det).e.x, &er
5153 								);
5154 							}
5155 						}
5156 						else {
5157 							if ((pdst->det).e.x == psrc->x) {
5158 								if (psrc->y <= (pdst->det).e.y) {
5159 									(pdst->det).e.a = 90;
5160 									(pdst->det).e.rx = dk4ma_int32_t_sub(
5161 										(pdst->det).e.y, psrc->y, &er
5162 									);
5163 								}
5164 								else {
5165 									(pdst->det).e.a = -90;
5166 									(pdst->det).e.rx = dk4ma_int32_t_sub(
5167 										psrc->y, (pdst->det).e.y, &er
5168 									);
5169 								}
5170 							}
5171 							else {
5172 								wxdobj_set_ellipse_control_point(
5173 									pdst, psrc, pind, &er
5174 								);
5175 							}
5176 						}
5177 					} break;
5178 					case 1 : {
5179 						if ((pdst->det).e.x == psrc->x) {
5180 							if (psrc->y >= (pdst->det).e.y) {
5181 								(pdst->det).e.a = 0;
5182 								(pdst->det).e.ry = dk4ma_int32_t_sub(
5183 									psrc->y, (pdst->det).e.y, &er
5184 								);
5185 							}
5186 							else {
5187 								(pdst->det).e.a = 180;
5188 								(pdst->det).e.ry = dk4ma_int32_t_sub(
5189 									(pdst->det).e.y, psrc->y, &er
5190 								);
5191 							}
5192 						}
5193 						else {
5194 							if ((pdst->det).e.y == psrc->y) {
5195 								if (psrc->x <= (pdst->det).e.x) {
5196 									(pdst->det).e.a = 90;
5197 									(pdst->det).e.ry = dk4ma_int32_t_sub(
5198 										(pdst->det).e.x, psrc->x, &er
5199 									);
5200 								}
5201 								else {
5202 									(pdst->det).e.a = -90;
5203 									(pdst->det).e.ry = dk4ma_int32_t_sub(
5204 										psrc->x, (pdst->det).e.x, &er
5205 									);
5206 								}
5207 							}
5208 							else {
5209 								wxdobj_set_ellipse_control_point(
5210 									pdst, psrc, pind, &er
5211 								);
5212 							}
5213 						}
5214 					} break;
5215 					default : {
5216 						if ((pdst->det).e.y == psrc->y) {
5217 							if (psrc->x >= (pdst->det).e.x) {
5218 								(pdst->det).e.a = 0;
5219 								(pdst->det).e.rx = dk4ma_int32_t_sub(
5220 									psrc->x, (pdst->det).e.x, &er
5221 								);
5222 							}
5223 							else {
5224 								(pdst->det).e.a = 180;
5225 								(pdst->det).e.rx = dk4ma_int32_t_sub(
5226 									(pdst->det).e.x, psrc->x, &er
5227 								);
5228 							}
5229 						}
5230 						else {
5231 							if ((pdst->det).e.x == psrc->x) {
5232 								if (psrc->y >= (pdst->det).e.y) {
5233 									(pdst->det).e.a = 90;
5234 									(pdst->det).e.rx = dk4ma_int32_t_sub(
5235 										psrc->y, (pdst->det).e.y, &er
5236 									);
5237 								}
5238 								else {
5239 									(pdst->det).e.a = -90;
5240 									(pdst->det).e.rx = dk4ma_int32_t_sub(
5241 										(pdst->det).e.y, psrc->y, &er
5242 									);
5243 								}
5244 							}
5245 							else {
5246 								wxdobj_set_ellipse_control_point(
5247 									pdst, psrc, pind, &er
5248 								);
5249 							}
5250 						}
5251 					} break;
5252 				}
5253 				if (DK4_E_NONE == er.ec) {
5254 					back = true;
5255 				}
5256 			} break;
5257 			case WXD_OT_BOX : {
5258 				wxdobj_set_box_control_point(&((pdst->det).b.b), psrc, pind);
5259 				back = true;
5260 			} break;
5261 			case WXD_OT_IMAGE : {
5262 				wxdobj_set_box_control_point(&((pdst->det).i.br), psrc, pind);
5263 				back = true;
5264 			} break;
5265 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
5266 				(pdst->det).d.x = psrc->x;
5267 				(pdst->det).d.y = psrc->y;
5268 				back = true;
5269 			} break;
5270 		}
5271 	}
5272 	return back;
5273 }
5274 
5275 
5276 
5277 void
wxdobj_delete_control_point(Wxd_object_t * pdst,uint16_t pind)5278 wxdobj_delete_control_point(
5279 	Wxd_object_t 		*pdst,
5280 	uint16_t			 pind
5281 )
5282 {
5283 	Wxd_point_t			*ptrppt;	/* New poly points array */
5284 	Wxd_spline_point_t	*ptrspl;	/* New spline points array */
5285 	double				 olds;		/* Old s value */
5286 	size_t				 sz;		/* Number of points to allocate */
5287 	uint16_t			 i;			/* Traverse control points */
5288 	bool				 bCanDo;	/* Can delete point from this object */
5289 	bool				 bBorder;	/* Deleted point was border point */
5290 
5291 	if (NULL != pdst) {
5292 		bCanDo = false;
5293 		switch ( (int)(pdst->ot) ) {
5294 			case WXD_OT_POLYLINE : {
5295 				if ((uint16_t)2U < (pdst->det).p.n) { bCanDo = true; }
5296 			} break;
5297 			case WXD_OT_POLYGON : {
5298 				if ((uint16_t)3U < (pdst->det).p.n) { bCanDo = true; }
5299 			} break;
5300 			case WXD_OT_O_SPLINE : {
5301 				if ((uint16_t)2U < (pdst->det).s.n) { bCanDo = true; }
5302 			} break;
5303 			case WXD_OT_C_SPLINE : {
5304 				if ((uint16_t)3U < (pdst->det).s.n) { bCanDo = true; }
5305 			} break;
5306 		}
5307 		if (bCanDo) {
5308 			switch ( (int)(pdst->ot) ) {
5309 				case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
5310 					ptrppt = NULL;
5311 					sz = (size_t)((pdst->det).p.n);
5312 					sz--;
5313 					ptrppt = dk4mem_new(Wxd_point_t, sz, NULL);
5314 					if (NULL != ptrppt) {
5315 						DK4_MEMCPY(\
5316 							ptrppt, (pdst->det).p.p,\
5317 							(sz * sizeof(Wxd_point_t))\
5318 						);
5319 						if ((size_t)pind < sz) {
5320 							DK4_MEMCPY(\
5321 								&(ptrppt[pind]),\
5322 								&(((pdst->det).p.p)[pind + (uint16_t)1U]),\
5323 								(\
5324 									sizeof(Wxd_point_t) * (sz - (size_t)pind)\
5325 								)\
5326 							);
5327 						}
5328 						dk4mem_free((pdst->det).p.p);
5329 						(pdst->det).p.p = ptrppt;
5330 						(pdst->det).p.n = (uint16_t)sz;
5331 					}
5332 					else {
5333 						if ((size_t)pind < sz) {
5334 							/*	Can not do one large memcpy as source
5335 								and destination range would overlap.
5336 							*/
5337 							for (i = pind; (size_t)i < sz; i++) {
5338 								DK4_MEMCPY(\
5339 									&(((pdst->det).p.p)[i]),\
5340 									&(((pdst->det).p.p)[i + (uint16_t)1U]),\
5341 									sizeof(Wxd_point_t)\
5342 								);
5343 							}
5344 						}
5345 						(pdst->det).p.n = (uint16_t)sz;
5346 					}
5347 				} break;
5348 				case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
5349 					ptrspl = NULL;
5350 					sz = (size_t)((pdst->det).s.n);
5351 					sz--;
5352 					olds = ((pdst->det).s.p)[pind].s;
5353 					bBorder = false;
5354 					if (
5355 						(((pdst->det).s.n - (uint16_t)1U) == pind)
5356 						|| ((uint16_t)0U == pind)
5357 					) {
5358 						bBorder = true;
5359 					}
5360 					ptrspl = dk4mem_new(Wxd_spline_point_t, sz, NULL);
5361 					if (NULL != ptrspl) {
5362 						DK4_MEMCPY(\
5363 							ptrspl, (pdst->det).s.p,\
5364 							(sz * sizeof(Wxd_spline_point_t))\
5365 						);
5366 						if ((size_t)pind < sz) {
5367 							DK4_MEMCPY(\
5368 								&(ptrspl[pind]),\
5369 								&(((pdst->det).s.p)[pind + (uint16_t)1U]),\
5370 								(\
5371 									sizeof(Wxd_spline_point_t)\
5372 									* (sz - (size_t)pind)\
5373 								)\
5374 							);
5375 						}
5376 						dk4mem_free((pdst->det).s.p);
5377 						(pdst->det).s.p = ptrspl;
5378 						(pdst->det).s.n = (uint16_t)sz;
5379 					}
5380 					else {
5381 						if ((size_t)pind < sz) {
5382 							/*	Can not do one large memcpy as source
5383 								and destination range would overlap.
5384 							*/
5385 							for (i = pind; (size_t)i < sz; i++) {
5386 								DK4_MEMCPY(\
5387 									&(((pdst->det).s.p)[i]),\
5388 									&(((pdst->det).s.p)[i + (uint16_t)1U]),\
5389 									sizeof(Wxd_spline_point_t)\
5390 								);
5391 							}
5392 						}
5393 						(pdst->det).s.n = (uint16_t)sz;
5394 					}
5395 					if (bBorder) {
5396 						if ((uint16_t)0U == pind) {
5397 							((pdst->det).s.p)[0].s = olds;
5398 						}
5399 						else {
5400 							((pdst->det).s.p)[sz - (size_t)1U].s = olds;
5401 						}
5402 					}
5403 				} break;
5404 			}
5405 		}
5406 	}
5407 
5408 }
5409 
5410 
5411 
5412 bool
wxdobj_add_control_point(Wxd_object_t * pdst,uint16_t pind,Wxd_point_t const * ppt)5413 wxdobj_add_control_point(
5414 	Wxd_object_t 		*pdst,
5415 	uint16_t			 pind,
5416 	Wxd_point_t const	*ppt
5417 )
5418 {
5419 	Wxd_spline_point_t	*ptrspl;
5420 	Wxd_point_t			*ptrppt;
5421 	size_t				 oldsz;
5422 	size_t				 newsz;
5423 	bool				 back	=	false;
5424 	bool				 bCanDo	=	false;
5425 
5426 	if (NULL != pdst) {
5427 		switch ( (int)(pdst->ot) ) {
5428 			case WXD_OT_POLYLINE :
5429 			case WXD_OT_POLYGON : {
5430 				if ((uint16_t)0xFFFFU > (pdst->det).p.n) {
5431 					if (pind <= (pdst->det).p.n) {
5432 						oldsz = (size_t)((pdst->det).p.n);
5433 						newsz = oldsz + (size_t)1U;
5434 						ptrppt = dk4mem_new(Wxd_point_t,newsz,NULL);
5435 						if (NULL != ptrppt) {
5436 							DK4_MEMCPY(\
5437 								ptrppt, (pdst->det).p.p,\
5438 								(oldsz * sizeof(Wxd_point_t))\
5439 							);
5440 							if ((size_t)pind < oldsz) {
5441 								DK4_MEMCPY(\
5442 									&(ptrppt[pind + (uint16_t)1U]),\
5443 									&(((pdst->det).p.p)[pind]),\
5444 									(\
5445 										(oldsz - (size_t)pind)\
5446 										* sizeof(Wxd_point_t)\
5447 									)\
5448 								);
5449 							}
5450 							dk4mem_free((pdst->det).p.p);
5451 							(pdst->det).p.p = ptrppt;
5452 							(pdst->det).p.n = (uint16_t)newsz;
5453 							((pdst->det).p.p)[pind].x = ppt->x;
5454 							((pdst->det).p.p)[pind].y = ppt->y;
5455 							back = true;
5456 						}
5457 						else {
5458 							/* ERROR: Memory */
5459 #if	0
5460 							dk4error_set_simple_error_code(
5461 								&m_oErrorReport, DK4_E_MEMORY_ALLOCATION_FAILED
5462 							);
5463 #endif
5464 							back = false;
5465 						}
5466 					}
5467 					else {
5468 						/* ERROR: New point index out of range (bug) */
5469 #if	0
5470 						dk4error_set_simple_error_code(
5471 							&m_oErrorReport, WXD_E_BUG_POINT_OOR
5472 						);
5473 #endif
5474 						back = false;
5475 					}
5476 				}
5477 				else {
5478 					/* ERROR: Too many points */
5479 #if	0
5480 					dk4error_set_simple_error_code(
5481 						&m_oErrorReport, WXD_E_TOO_MANY_POINTS
5482 					);
5483 #endif
5484 					back = false;
5485 				}
5486 			} break;
5487 			case WXD_OT_O_SPLINE :
5488 			case WXD_OT_C_SPLINE : {
5489 				if ((uint16_t)0xFFFFU > (pdst->det).s.n) {
5490 					if (pind <= (pdst->det).s.n) {
5491 						oldsz = (size_t)((pdst->det).s.n);
5492 						newsz = oldsz + (size_t)1U;
5493 						ptrspl = dk4mem_new(Wxd_spline_point_t,newsz,NULL);
5494 						if (NULL != ptrspl) {
5495 							DK4_MEMCPY(\
5496 								ptrspl, (pdst->det).s.p,\
5497 								(oldsz * sizeof(Wxd_spline_point_t))\
5498 							);
5499 							if ((size_t)pind < oldsz) {
5500 								DK4_MEMCPY(\
5501 									&(ptrspl[pind + (uint16_t)1U]),\
5502 									&(((pdst->det).s.p)[pind]),\
5503 									(\
5504 										(oldsz - (size_t)pind)\
5505 										* sizeof(Wxd_spline_point_t)\
5506 									)\
5507 								);
5508 							}
5509 							dk4mem_free((pdst->det).s.p);
5510 							(pdst->det).s.p = ptrspl;
5511 							(pdst->det).s.n = (uint16_t)newsz;
5512 							((pdst->det).s.p)[pind].x = ppt->x;
5513 							((pdst->det).s.p)[pind].y = ppt->y;
5514 							back = true;
5515 							if ((uint16_t)0U == pind) {
5516 								((pdst->det).s.p)[0].s = 0.0;
5517 								((pdst->det).s.p)[1].s =
5518 								((pdst->det).s.p)[2].s;
5519 							}
5520 							else {
5521 								if (((pdst->det).s.n - (uint16_t)1U) == pind) {
5522 									((pdst->det).s.p)[pind].s = 0.0;
5523 									((pdst->det).s.p)[pind - (uint16_t)1U].s =
5524 									((pdst->det).s.p)[pind - (uint16_t)2U].s;
5525 								}
5526 							}
5527 						}
5528 						else {
5529 							/* ERROR: Memory */
5530 #if	0
5531 							dk4error_set_simple_error_code(
5532 								&m_oErrorReport, DK4_E_MEMORY_ALLOCATION_FAILED
5533 							);
5534 #endif
5535 							back = false;
5536 						}
5537 					}
5538 					else {
5539 						/* ERROR: New point index out of range (bug) */
5540 #if	0
5541 						dk4error_set_simple_error_code(
5542 							&m_oErrorReport, WXD_E_BUG_POINT_OOR
5543 						);
5544 #endif
5545 						back = false;
5546 					}
5547 				}
5548 				else {
5549 					/* ERROR: Too many points */
5550 #if	0
5551 					dk4error_set_simple_error_code(
5552 						&m_oErrorReport, WXD_E_TOO_MANY_POINTS
5553 					);
5554 #endif
5555 					back = false;
5556 				}
5557 			} break;
5558 		}
5559 		if (bCanDo) {
5560 		}
5561 	}
5562 	return back;
5563 }
5564 
5565 
5566 
5567 bool
wxdobj_control_pt_to_bb(Wxd_bb_t * pbox,Wxd_object_t const * pobj)5568 wxdobj_control_pt_to_bb(
5569 	Wxd_bb_t		*pbox,
5570 	Wxd_object_t const	*pobj
5571 )
5572 {
5573 	bool 		back	= false;
5574 	uint16_t	i;
5575 	if (NULL != pbox) {
5576 		wxdobj_det_init_bb(pbox);
5577 		if (NULL != pobj) {
5578 			switch ( (int)(pobj->ot) ) {
5579 				case WXD_OT_TEXT : {
5580 					wxdobj_bb_set_point(
5581 						pbox, (pobj->det).t.x, (pobj->det).t.y
5582 					);
5583 					back = true;
5584 				} break;
5585 				case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
5586 					if ((0U < (pobj->det).p.n) && (NULL != (pobj->det).p.p)) {
5587 						for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
5588 							if ((uint16_t)0U != i) {
5589 								wxdobj_bb_add_point(
5590 									pbox,
5591 									((pobj->det).p.p)[i].x,
5592 									((pobj->det).p.p)[i].y
5593 								);
5594 							}
5595 							else {
5596 								wxdobj_bb_set_point(
5597 									pbox,
5598 									((pobj->det).p.p)[i].x,
5599 									((pobj->det).p.p)[i].y
5600 								);
5601 							}
5602 						}
5603 						back = true;
5604 					}
5605 				} break;
5606 				case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
5607 					if ((0U < (pobj->det).s.n) && (NULL != (pobj->det).s.p)) {
5608 						for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
5609 							if ((uint16_t)0U != i) {
5610 								wxdobj_bb_add_point(
5611 									pbox,
5612 									((pobj->det).s.p)[i].x,
5613 									((pobj->det).s.p)[i].y
5614 								);
5615 							}
5616 							else {
5617 								wxdobj_bb_set_point(
5618 									pbox,
5619 									((pobj->det).s.p)[i].x,
5620 									((pobj->det).s.p)[i].y
5621 								);
5622 							}
5623 						}
5624 						back = true;
5625 					}
5626 				} break;
5627 				case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
5628 					wxdobj_bb_set_point(
5629 						pbox, (pobj->det).a.x1, (pobj->det).a.y1
5630 					);
5631 					wxdobj_bb_add_point(
5632 						pbox, (pobj->det).a.x2, (pobj->det).a.y2
5633 					);
5634 					wxdobj_bb_add_point(
5635 						pbox, (pobj->det).a.x3, (pobj->det).a.y3
5636 					);
5637 					back = true;
5638 				} break;
5639 				case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
5640 					wxdobj_bb_set_point(
5641 						pbox, (pobj->det).e.x, (pobj->det).e.y
5642 					);
5643 					back = true;
5644 				} break;
5645 				case WXD_OT_BOX : {
5646 					DK4_MEMCPY(pbox,&((pobj->det).b.b),sizeof(Wxd_bb_t));
5647 					back = true;
5648 				} break;
5649 				case WXD_OT_IMAGE : {
5650 					DK4_MEMCPY(pbox,&((pobj->det).i.br),sizeof(Wxd_bb_t));
5651 					back = true;
5652 				} break;
5653 				case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
5654 					wxdobj_bb_set_point(
5655 						pbox, (pobj->det).d.x, (pobj->det).d.y
5656 					);
5657 					back = true;
5658 				} break;
5659 			}
5660 		}
5661 	}
5662 	return back;
5663 }
5664 
5665 
5666 
5667 bool
wxdobj_recursive_pt_to_bb(Wxd_bb_t * pbox,Wxd_object_t * pobj)5668 wxdobj_recursive_pt_to_bb(
5669 	Wxd_bb_t		*pbox,
5670 	Wxd_object_t	*pobj
5671 )
5672 {
5673 	Wxd_bb_t		 bb;
5674 	Wxd_object_t	*pCur;				/* Current group to process */
5675 	Wxd_object_t	*pCand;				/* Next object (group or not) */
5676 	bool			 back	= false;	/* Result */
5677 	bool			 bCC	= false;	/* Can continue in loop */
5678 	bool			 bRes	= false;	/* Operation result */
5679 	bool			 bValue	= false;	/* Have value in bb */
5680 
5681 	if (NULL != pbox) {
5682 		wxdobj_det_init_bb(pbox);
5683 	}
5684 	if ((NULL != pbox) && (NULL != pobj)) {
5685 		switch ( pobj->ot) {
5686 			case WXD_OT_GROUP_BEGIN : {
5687 				wxdobj_det_init_bb(&bb);
5688 				if (
5689 					(NULL != (pobj->det).g.s_e)
5690 					&& (NULL != (pobj->det).g.i_e)
5691 				)
5692 				{
5693 					dk4sto_it_reset((pobj->det).g.i_e);
5694 					back = bCC = true;
5695 					pCur = pobj;
5696 					while ((bCC) && (NULL != pCur)) {
5697 						pCand =
5698 						(Wxd_object_t *)dk4sto_it_next((pCur->det).g.i_e);
5699 						if (NULL != pCand) {
5700 							switch (pCand->ot) {
5701 								case WXD_OT_GROUP_BEGIN : {
5702 									pCand->pa = pCur;
5703 									if (
5704 										(NULL != (pCand->det).g.s_e)
5705 										&& (NULL != (pCand->det).g.i_e)
5706 									) {
5707 										dk4sto_it_reset((pCand->det).g.i_e);
5708 										pCur = pCand;
5709 									}
5710 								} break;
5711 								case WXD_OT_TEXT :
5712 								case WXD_OT_POLYLINE :
5713 								case WXD_OT_O_SPLINE :
5714 								case WXD_OT_O_ARC :
5715 								case WXD_OT_POLYGON :
5716 								case WXD_OT_C_SPLINE :
5717 								case WXD_OT_C_ARC :
5718 								case WXD_OT_CIRCLE :
5719 								case WXD_OT_ELLIPSE :
5720 								case WXD_OT_BOX :
5721 								case WXD_OT_IMAGE :
5722 								case WXD_OT_DOT_FILLED :
5723 								case WXD_OT_DOT_WHITE : {
5724 									wxdobj_det_init_bb(&bb);
5725 									bRes = wxdobj_control_pt_to_bb(&bb, pCand);
5726 									if (bRes) {
5727 										if (bValue) {
5728 											wxdobj_bb_add_bb(pbox, &bb);
5729 										}
5730 										else {
5731 											DK4_MEMCPY(\
5732 												pbox,&bb,sizeof(Wxd_bb_t)\
5733 											);
5734 											bValue = true;
5735 										}
5736 									}
5737 									else {
5738 										back = false;
5739 									}
5740 								} break;
5741 							}
5742 						}
5743 						else {
5744 							if ((NULL == pCur->pa) || (pobj == pCur)) {
5745 								bCC		= false;
5746 								pCur	= NULL;
5747 							}
5748 							else {
5749 								pCur = pCur->pa;
5750 							}
5751 						}
5752 					}
5753 				}
5754 			} break;
5755 			case WXD_OT_TEXT :
5756 			case WXD_OT_POLYLINE :
5757 			case WXD_OT_O_SPLINE :
5758 			case WXD_OT_O_ARC :
5759 			case WXD_OT_POLYGON :
5760 			case WXD_OT_C_SPLINE :
5761 			case WXD_OT_C_ARC :
5762 			case WXD_OT_CIRCLE :
5763 			case WXD_OT_ELLIPSE :
5764 			case WXD_OT_BOX :
5765 			case WXD_OT_IMAGE :
5766 			case WXD_OT_DOT_FILLED :
5767 			case WXD_OT_DOT_WHITE : {
5768 				back = wxdobj_control_pt_to_bb(pbox, pobj);
5769 			} break;
5770 		}
5771 	}
5772 	return back;
5773 }
5774 
5775 
5776 
5777 bool
wxdobj_flip_object(Wxd_object_t * pobj,Wxd_bb_t const * pbox,bool bVert,bool bRealRun)5778 wxdobj_flip_object(
5779 	Wxd_object_t	*pobj,
5780 	Wxd_bb_t const	*pbox,
5781 	bool			 bVert,
5782 	bool			 bRealRun
5783 )
5784 {
5785 	dk4_er_t	er;
5786 	uint16_t	i;
5787 	bool		back = false;
5788 
5789 	if ((NULL != pobj) && (NULL != pbox)) {
5790 		dk4error_init(&er);
5791 		switch ( (int)(pobj->ot) ) {
5792 			case WXD_OT_TEXT : {
5793 				if (bRealRun) {
5794 					if (bVert) {
5795 						(pobj->det).t.y = wxdobj_flip_coordinate(
5796 							pbox->yb, pbox->yt, (pobj->det).t.y, &er
5797 						);
5798 						(pobj->det).t.a = (int16_t)(0 - (pobj->det).t.a);
5799 					}
5800 					else {
5801 						(pobj->det).t.x = wxdobj_flip_coordinate(
5802 							pbox->xl, pbox->xr, (pobj->det).t.x, &er
5803 						);
5804 						(pobj->det).t.a = (int16_t)(180 - (pobj->det).t.a);
5805 						switch ( (int)((pobj->det).t.al) ) {
5806 							case WXD_TA_RIGHT : {
5807 								(pobj->det).t.al = (uint8_t)(WXD_TA_LEFT);
5808 							} break;
5809 							case WXD_TA_CENTERED : {
5810 								(pobj->det).t.al = (uint8_t)(WXD_TA_CENTERED);
5811 							} break;
5812 							default : {
5813 								(pobj->det).t.al = (uint8_t)(WXD_TA_RIGHT);
5814 							} break;
5815 						}
5816 					}
5817 					while ((int16_t)(-360) >= (pobj->det).t.a) {
5818 						(pobj->det).t.a = (int16_t)(
5819 							(pobj->det).t.a + 360
5820 						);
5821 					}
5822 					while ((int16_t)360    <= (pobj->det).t.a) {
5823 						(pobj->det).t.a = (int16_t)(
5824 							(pobj->det).t.a - 360
5825 						);
5826 					}
5827 				}
5828 				else {
5829 					if (bVert) {
5830 						(void)wxdobj_flip_coordinate(
5831 							pbox->yb, pbox->yt, (pobj->det).t.y, &er
5832 						);
5833 					}
5834 					else {
5835 						(void)wxdobj_flip_coordinate(
5836 							pbox->xl, pbox->xr, (pobj->det).t.x, &er
5837 						);
5838 					}
5839 				}
5840 				if (DK4_E_NONE == er.ec) { back = true; }
5841 			} break;
5842 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
5843 				if ((NULL != (pobj->det).p.p) && (0U < (pobj->det).p.n)) {
5844 					if (bRealRun) {
5845 						if (bVert) {
5846 							for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
5847 								((pobj->det).p.p)[i].y = wxdobj_flip_coordinate(
5848 									pbox->yb, pbox->yt,
5849 									((pobj->det).p.p)[i].y, &er
5850 								);
5851 							}
5852 						}
5853 						else {
5854 							for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
5855 								((pobj->det).p.p)[i].x = wxdobj_flip_coordinate(
5856 									pbox->xl, pbox->xr,
5857 									((pobj->det).p.p)[i].x, &er
5858 								);
5859 							}
5860 						}
5861 					}
5862 					else {
5863 						if (bVert) {
5864 							for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
5865 								(void)wxdobj_flip_coordinate(
5866 									pbox->yb, pbox->yt,
5867 									((pobj->det).p.p)[i].y, &er
5868 								);
5869 							}
5870 						}
5871 						else {
5872 							for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
5873 								(void)wxdobj_flip_coordinate(
5874 									pbox->xl, pbox->xr,
5875 									((pobj->det).p.p)[i].x, &er
5876 								);
5877 							}
5878 						}
5879 					}
5880 					if (DK4_E_NONE == er.ec) { back = true; }
5881 				}
5882 			} break;
5883 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
5884 				if ((NULL != (pobj->det).s.p) && (0U < (pobj->det).s.n)) {
5885 					if (bRealRun) {
5886 						if (bVert) {
5887 							for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
5888 								((pobj->det).s.p)[i].y = wxdobj_flip_coordinate(
5889 									pbox->yb, pbox->yt,
5890 									((pobj->det).s.p)[i].y, &er
5891 								);
5892 							}
5893 						}
5894 						else {
5895 							for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
5896 								((pobj->det).s.p)[i].x = wxdobj_flip_coordinate(
5897 									pbox->xl, pbox->xr,
5898 									((pobj->det).s.p)[i].x, &er
5899 								);
5900 							}
5901 						}
5902 					}
5903 					else {
5904 						if (bVert) {
5905 							for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
5906 								(void)wxdobj_flip_coordinate(
5907 									pbox->yb, pbox->yt,
5908 									((pobj->det).s.p)[i].y, &er
5909 								);
5910 							}
5911 						}
5912 						else {
5913 							for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
5914 								(void)wxdobj_flip_coordinate(
5915 									pbox->xl, pbox->xr,
5916 									((pobj->det).s.p)[i].x, &er
5917 								);
5918 							}
5919 						}
5920 					}
5921 					if (DK4_E_NONE == er.ec) { back = true; }
5922 				}
5923 			} break;
5924 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
5925 				if (bRealRun) {
5926 					if (bVert) {
5927 						(pobj->det).a.y1 = wxdobj_flip_coordinate(
5928 							pbox->yb, pbox->yt, (pobj->det).a.y1, &er
5929 						);
5930 						(pobj->det).a.y2 = wxdobj_flip_coordinate(
5931 							pbox->yb, pbox->yt, (pobj->det).a.y2, &er
5932 						);
5933 						(pobj->det).a.y3 = wxdobj_flip_coordinate(
5934 							pbox->yb, pbox->yt, (pobj->det).a.y3, &er
5935 						);
5936 					}
5937 					else {
5938 						(pobj->det).a.x1 = wxdobj_flip_coordinate(
5939 							pbox->xl, pbox->xr, (pobj->det).a.x1, &er
5940 						);
5941 						(pobj->det).a.x2 = wxdobj_flip_coordinate(
5942 							pbox->xl, pbox->xr, (pobj->det).a.x2, &er
5943 						);
5944 						(pobj->det).a.x3 = wxdobj_flip_coordinate(
5945 							pbox->xl, pbox->xr, (pobj->det).a.x3, &er
5946 						);
5947 					}
5948 					wxdarc_calculation(
5949 						&((pobj->det).a.x),
5950 						&((pobj->det).a.y),
5951 						&((pobj->det).a.r),
5952 						&((pobj->det).a.a),
5953 						&((pobj->det).a.b),
5954 						&((pobj->det).a.d),
5955 						(pobj->det).a.x1,
5956 						(pobj->det).a.y1,
5957 						(pobj->det).a.x2,
5958 						(pobj->det).a.y2,
5959 						(pobj->det).a.x3,
5960 						(pobj->det).a.y3
5961 					);
5962 				}
5963 				else {
5964 					if (bVert) {
5965 						(void)wxdobj_flip_coordinate(
5966 							pbox->yb, pbox->yt, (pobj->det).a.y1, &er
5967 						);
5968 						(void)wxdobj_flip_coordinate(
5969 							pbox->yb, pbox->yt, (pobj->det).a.y2, &er
5970 						);
5971 						(void)wxdobj_flip_coordinate(
5972 							pbox->yb, pbox->yt, (pobj->det).a.y3, &er
5973 						);
5974 					}
5975 					else {
5976 						(void)wxdobj_flip_coordinate(
5977 							pbox->xl, pbox->xr, (pobj->det).a.x1, &er
5978 						);
5979 						(void)wxdobj_flip_coordinate(
5980 							pbox->xl, pbox->xr, (pobj->det).a.x2, &er
5981 						);
5982 						(void)wxdobj_flip_coordinate(
5983 							pbox->xl, pbox->xr, (pobj->det).a.x3, &er
5984 						);
5985 					}
5986 				}
5987 				if (DK4_E_NONE == er.ec) { back = true; }
5988 			} break;
5989 			case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
5990 				if (bRealRun) {
5991 					if (bVert) {
5992 						(pobj->det).e.y = wxdobj_flip_coordinate(
5993 							pbox->yb, pbox->yt, (pobj->det).e.y, &er
5994 						);
5995 					}
5996 					else {
5997 						(pobj->det).e.x = wxdobj_flip_coordinate(
5998 							pbox->xl, pbox->xr, (pobj->det).e.x, &er
5999 						);
6000 					}
6001 					if (
6002 						(WXD_OT_ELLIPSE == pobj->ot)
6003 						&& ((int16_t)0 != (pobj->det).e.a)
6004 					) {
6005 						if (bVert) {
6006 							(pobj->det).e.a = (int16_t)(0 - (pobj->det).e.a);
6007 						}
6008 						else {
6009 							(pobj->det).e.a = (int16_t)(180 - (pobj->det).e.a);
6010 						}
6011 						while ((int16_t)(-360) >= (pobj->det).t.a) {
6012 							(pobj->det).t.a = (int16_t)(
6013 								(pobj->det).t.a + 360
6014 							);
6015 						}
6016 						while ((int16_t)360    <= (pobj->det).t.a) {
6017 							(pobj->det).t.a = (int16_t)(
6018 								(pobj->det).t.a - 360
6019 							);
6020 						}
6021 					}
6022 				}
6023 				else {
6024 					if (bVert) {
6025 						(void)wxdobj_flip_coordinate(
6026 							pbox->yb, pbox->yt, (pobj->det).e.y, &er
6027 						);
6028 					}
6029 					else {
6030 						(void)wxdobj_flip_coordinate(
6031 							pbox->xl, pbox->xr, (pobj->det).e.x, &er
6032 						);
6033 					}
6034 				}
6035 				if (DK4_E_NONE == er.ec) { back = true; }
6036 			} break;
6037 			case WXD_OT_BOX : {
6038 				if (bRealRun) {
6039 					if (bVert) {
6040 						(pobj->det).b.b.yb = wxdobj_flip_coordinate(
6041 							pbox->yb, pbox->yt, (pobj->det).b.b.yb, &er
6042 						);
6043 						(pobj->det).b.b.yt = wxdobj_flip_coordinate(
6044 							pbox->yb, pbox->yt, (pobj->det).b.b.yt, &er
6045 						);
6046 					}
6047 					else {
6048 						(pobj->det).b.b.xl = wxdobj_flip_coordinate(
6049 							pbox->xl, pbox->xr, (pobj->det).b.b.xl, &er
6050 						);
6051 						(pobj->det).b.b.xr = wxdobj_flip_coordinate(
6052 							pbox->xl, pbox->xr, (pobj->det).b.b.xr, &er
6053 						);
6054 					}
6055 					wxdobj_bb_correct(&((pobj->det).b.b));
6056 				}
6057 				else {
6058 					if (bVert) {
6059 						(void)wxdobj_flip_coordinate(
6060 							pbox->yb, pbox->yt, (pobj->det).b.b.yb, &er
6061 						);
6062 						(void)wxdobj_flip_coordinate(
6063 							pbox->yb, pbox->yt, (pobj->det).b.b.yt, &er
6064 						);
6065 					}
6066 					else {
6067 						(void)wxdobj_flip_coordinate(
6068 							pbox->xl, pbox->xr, (pobj->det).b.b.xl, &er
6069 						);
6070 						(void)wxdobj_flip_coordinate(
6071 							pbox->xl, pbox->xr, (pobj->det).b.b.xr, &er
6072 						);
6073 					}
6074 				}
6075 				if (DK4_E_NONE == er.ec) { back = true; }
6076 			} break;
6077 			case WXD_OT_IMAGE : {
6078 				if (bRealRun) {
6079 					if (bVert) {
6080 						(pobj->det).i.br.yb = wxdobj_flip_coordinate(
6081 							pbox->yb, pbox->yt, (pobj->det).i.br.yb, &er
6082 						);
6083 						(pobj->det).i.br.yt = wxdobj_flip_coordinate(
6084 							pbox->yb, pbox->yt, (pobj->det).i.br.yt, &er
6085 						);
6086 					}
6087 					else {
6088 						(pobj->det).i.br.xl = wxdobj_flip_coordinate(
6089 							pbox->xl, pbox->xr, (pobj->det).i.br.xl, &er
6090 						);
6091 						(pobj->det).i.br.xr = wxdobj_flip_coordinate(
6092 							pbox->xl, pbox->xr, (pobj->det).i.br.xr, &er
6093 						);
6094 					}
6095 					wxdobj_bb_correct(&((pobj->det).i.br));
6096 				}
6097 				else {
6098 					if (bVert) {
6099 						(void)wxdobj_flip_coordinate(
6100 							pbox->yb, pbox->yt, (pobj->det).i.br.yb, &er
6101 						);
6102 						(void)wxdobj_flip_coordinate(
6103 							pbox->yb, pbox->yt, (pobj->det).i.br.yt, &er
6104 						);
6105 					}
6106 					else {
6107 						(void)wxdobj_flip_coordinate(
6108 							pbox->xl, pbox->xr, (pobj->det).i.br.xl, &er
6109 						);
6110 						(void)wxdobj_flip_coordinate(
6111 							pbox->xl, pbox->xr, (pobj->det).i.br.xr, &er
6112 						);
6113 					}
6114 				}
6115 				if (DK4_E_NONE == er.ec) { back = true; }
6116 			} break;
6117 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
6118 				if (bRealRun) {
6119 					if (bVert) {
6120 						(pobj->det).d.y = wxdobj_flip_coordinate(
6121 							pbox->yb, pbox->yt, (pobj->det).d.y, &er
6122 						);
6123 					}
6124 					else {
6125 						(pobj->det).d.x = wxdobj_flip_coordinate(
6126 							pbox->xl, pbox->xr, (pobj->det).d.x, &er
6127 						);
6128 					}
6129 				}
6130 				else {
6131 					if (bVert) {
6132 						(void)wxdobj_flip_coordinate(
6133 							pbox->yb, pbox->yt, (pobj->det).d.y, &er
6134 						);
6135 					}
6136 					else {
6137 						(void)wxdobj_flip_coordinate(
6138 							pbox->xl, pbox->xr, (pobj->det).d.x, &er
6139 						);
6140 					}
6141 				}
6142 				if (DK4_E_NONE == er.ec) { back = true; }
6143 			} break;
6144 		}
6145 	}
6146 	return back;
6147 }
6148 
6149 
6150 
6151 bool
wxdobj_flip_recursively(Wxd_object_t * pobj,bool bVert,bool bRealRun)6152 wxdobj_flip_recursively(
6153 	Wxd_object_t	*pobj,
6154 	bool			 bVert,
6155 	bool			 bRealRun
6156 )
6157 {
6158 	Wxd_bb_t		 bb;				/* Element bounding box */
6159 	Wxd_object_t	*pCur;				/* Current group to handle */
6160 	Wxd_object_t	*pCand;				/* Candidate, next object to handle */
6161 	bool			 bCC	= false;	/* Can continue */
6162 	bool			 back	= false;	/* Function result */
6163 	bool			 bRes	= false;	/* Operation result */
6164 
6165 	if (NULL != pobj) {
6166 		back = wxdobj_recursive_pt_to_bb(&bb, pobj);
6167 		if (back) {
6168 			switch ( pobj->ot ) {
6169 				case WXD_OT_GROUP_BEGIN : {
6170 					back = false;
6171 					if (
6172 						(NULL != (pobj->det).g.s_e)
6173 						&& (NULL != (pobj->det).g.i_e)
6174 					) {
6175 						dk4sto_it_reset((pobj->det).g.i_e);
6176 						pCur = pobj;
6177 						back = bCC = true;
6178 						while ((NULL != pCur) && (bCC)) {
6179 							pCand =
6180 							(Wxd_object_t *)dk4sto_it_next((pCur->det).g.i_e);
6181 							if (NULL != pCand) {
6182 								switch ( pCand->ot ) {
6183 									case WXD_OT_GROUP_BEGIN : {
6184 										pCand->pa = pCur;
6185 										if (
6186 											(NULL != (pCand->det).g.s_e)
6187 											&& (NULL != (pCand->det).g.i_e)
6188 										) {
6189 											dk4sto_it_reset((pCand->det).g.i_e);
6190 											pCur = pCand;
6191 										}
6192 									} break;
6193 									case WXD_OT_TEXT :
6194 									case WXD_OT_POLYLINE :
6195 									case WXD_OT_O_SPLINE :
6196 									case WXD_OT_O_ARC :
6197 									case WXD_OT_POLYGON :
6198 									case WXD_OT_C_SPLINE :
6199 									case WXD_OT_C_ARC :
6200 									case WXD_OT_CIRCLE :
6201 									case WXD_OT_ELLIPSE :
6202 									case WXD_OT_BOX :
6203 									case WXD_OT_IMAGE :
6204 									case WXD_OT_DOT_FILLED :
6205 									case WXD_OT_DOT_WHITE : {
6206 										bRes = wxdobj_flip_object(
6207 											pCand, &bb, bVert, bRealRun
6208 										);
6209 										if (!(bRes)) { back = false; }
6210 									} break;
6211 								}
6212 							}
6213 							else {
6214 								if (
6215 									(NULL == pCur->pa)
6216 									|| (pobj == pCur)
6217 								) {
6218 									bCC = false;
6219 									pCur = NULL;
6220 								}
6221 								else {
6222 									pCur = pCur->pa;
6223 								}
6224 							}
6225 						}
6226 					}
6227 				} break;
6228 				case WXD_OT_TEXT :
6229 				case WXD_OT_POLYLINE :
6230 				case WXD_OT_O_SPLINE :
6231 				case WXD_OT_O_ARC :
6232 				case WXD_OT_POLYGON :
6233 				case WXD_OT_C_SPLINE :
6234 				case WXD_OT_C_ARC :
6235 				case WXD_OT_CIRCLE :
6236 				case WXD_OT_ELLIPSE :
6237 				case WXD_OT_BOX :
6238 				case WXD_OT_IMAGE :
6239 				case WXD_OT_DOT_FILLED :
6240 				case WXD_OT_DOT_WHITE : {
6241 					back = wxdobj_flip_object(pobj, &bb, bVert, bRealRun);
6242 				} break;
6243 			}
6244 		}
6245 		else {
6246 		}
6247 	}
6248 
6249 	return back;
6250 }
6251 
6252 
6253 
6254 bool
wxdobj_is_marked(Wxd_object_t const * pobj,uint8_t marker)6255 wxdobj_is_marked(Wxd_object_t const *pobj, uint8_t marker)
6256 {
6257 	bool		back = false;
6258 
6259 	if (NULL != pobj) {
6260 		if ((uint8_t)0U != (marker & (pobj->mark))) {
6261 			back = true;
6262 		}
6263 	}
6264 
6265 	return back;
6266 }
6267 
6268 
6269 
6270 int
wxdobj_num_marked_2(Wxd_drawing_t * pdrw)6271 wxdobj_num_marked_2(Wxd_drawing_t *pdrw)
6272 {
6273 	Wxd_object_t	*pobj;
6274 	int				 back	= 0;
6275 
6276 	if (NULL != pdrw) {
6277 		dk4sto_it_reset(pdrw->i_stru);
6278 		do {
6279 			pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_stru);
6280 			if (NULL != pobj) {
6281 				if (wxdobj_is_marked(pobj, OBJ_MARKER_2)) {
6282 					back++;
6283 				}
6284 			}
6285 		} while ((NULL != pobj) && (2 > back));
6286 	}
6287 
6288 	return back;
6289 }
6290 
6291 
6292 
6293 #if	TRACE_DEBUG
6294 static
6295 void
wxdobj_report_bb(dk4_bb_t const * pbb)6296 wxdobj_report_bb(dk4_bb_t const *pbb)
6297 {
6298 #if	TRACE_DEBUG
6299 
6300 	if (0 != dk4bb_have_x(pbb)) {
6301 
6302 	}
6303 	else {
6304 
6305 	}
6306 	if (0 != dk4bb_have_y(pbb)) {
6307 
6308 	}
6309 	else {
6310 
6311 	}
6312 
6313 #endif
6314 }
6315 #endif
6316 
6317 
6318 
6319 static
6320 bool
wxdobj_bb_simple_text(Wxd_object_t * pobj)6321 wxdobj_bb_simple_text(Wxd_object_t *pobj)
6322 {
6323 
6324 	dk4bb_init(&(pobj->bb));
6325 	dk4bb_add_point(
6326 		&(pobj->bb),
6327 		(double)((pobj->det).t.x), (double)((pobj->det).t.y)
6328 	);
6329 
6330 
6331 	return true;
6332 }
6333 
6334 
6335 
6336 static
6337 bool
wxdobj_bb_simple_polyline(Wxd_object_t * pobj)6338 wxdobj_bb_simple_polyline(Wxd_object_t *pobj)
6339 {
6340 	uint16_t	u;
6341 	bool		back = false;
6342 
6343 	dk4bb_init(&(pobj->bb));
6344 	if ((NULL != (pobj->det).p.p) && ((uint16_t)0U < (pobj->det).p.n)) {
6345 		back = true;
6346 		for (u = (uint16_t)0U; u < (pobj->det).p.n; u++) {
6347 			dk4bb_add_point(
6348 				&(pobj->bb),
6349 				(double)(((pobj->det).p.p)[u].x),
6350 				(double)(((pobj->det).p.p)[u].y)
6351 			);
6352 		}
6353 	}
6354 
6355 
6356 	return back;
6357 }
6358 
6359 
6360 
6361 static
6362 bool
wxdobj_bb_simple_spline(Wxd_object_t * pobj,size_t subsegs)6363 wxdobj_bb_simple_spline(
6364 	Wxd_object_t		*pobj,
6365 	size_t				 subsegs
6366 )
6367 {
6368 	double			aa[4];		/* Subsegment start */
6369 	double			ab[4];		/* Subsegment end */
6370 	dk4_xsp_2d_t	xsp;		/* X-spline structure for calculations */
6371 	double			divisor;	/* Divisor for derivatives */
6372 	double			t;			/* Current "time" */
6373 	size_t			ssegno;		/* Current subsegment */
6374 	uint16_t		nsegs;		/* Number of segments in spline */
6375 	uint16_t		a;			/* Point A index */
6376 	uint16_t		b;			/* Point B index */
6377 	uint16_t		c;			/* Point C index */
6378 	uint16_t		d;			/* Point D index */
6379 	bool			back = false;
6380 
6381 	divisor = 3.0 * ((double)subsegs);
6382 	dk4bb_init(&(pobj->bb));
6383 	if ((NULL != (pobj->det).s.p) && ((uint16_t)1U < (pobj->det).s.n)) {
6384 		back = true;
6385 		nsegs = (pobj->det).s.n;
6386 		if (WXD_OT_C_SPLINE != pobj->ot) { nsegs--; }
6387 
6388 		dk4xsp2d_reset(&xsp);
6389 		for (b = (uint16_t)0U; b < nsegs; b++) {
6390 
6391 			if (b < ((pobj->det).s.n - (uint16_t)1U)) {
6392 				c = (uint16_t)(b + 1U);
6393 			}
6394 			else {
6395 				c = 0;
6396 			}
6397 			if (
6398 				(1.0e-7 > fabs(((pobj->det).s.p)[b].s))
6399 				&& (1.0e-7 > fabs(((pobj->det).s.p)[c].s))
6400 			) {
6401 				dk4bb_add_point(
6402 					&(pobj->bb), ((pobj->det).s.p)[b].x, ((pobj->det).s.p)[b].y
6403 				);
6404 				dk4bb_add_point(
6405 					&(pobj->bb), ((pobj->det).s.p)[c].x, ((pobj->det).s.p)[c].y
6406 				);
6407 			}
6408 			else {
6409 				dk4xsp2d_reset_points(&xsp);
6410 				dk4xsp2d_set_point(
6411 					&xsp,
6412 					(double)(((pobj->det).s.p)[b].x),
6413 					(double)(((pobj->det).s.p)[b].y),
6414 					((pobj->det).s.p)[b].s,
6415 					1
6416 				);
6417 				dk4xsp2d_set_point(
6418 					&xsp,
6419 					(double)(((pobj->det).s.p)[c].x),
6420 					(double)(((pobj->det).s.p)[c].y),
6421 					((pobj->det).s.p)[c].s,
6422 					2
6423 				);
6424 				if (b < ((pobj->det).s.n - (uint16_t)2U)) {
6425 					d = (uint16_t)(b + 2U);
6426 					dk4xsp2d_set_point(
6427 						&xsp,
6428 						(double)(((pobj->det).s.p)[d].x),
6429 						(double)(((pobj->det).s.p)[d].y),
6430 						((pobj->det).s.p)[d].s,
6431 						3
6432 					);
6433 				}
6434 				else {
6435 					if (WXD_OT_C_SPLINE == pobj->ot) {
6436 						d = (uint16_t)(b - ((pobj->det).s.n - 2U));
6437 
6438 						dk4xsp2d_set_point(
6439 							&xsp,
6440 							(double)(((pobj->det).s.p)[d].x),
6441 							(double)(((pobj->det).s.p)[d].y),
6442 							((pobj->det).s.p)[d].s,
6443 							3
6444 						);
6445 					}
6446 				}
6447 				if ((uint16_t)0U < b) {
6448 					a = (uint16_t)(b - 1U);
6449 					dk4xsp2d_set_point(
6450 						&xsp,
6451 						(double)(((pobj->det).s.p)[a].x),
6452 						(double)(((pobj->det).s.p)[a].y),
6453 						((pobj->det).s.p)[a].s,
6454 						0
6455 					);
6456 				}
6457 				else {
6458 					if (WXD_OT_C_SPLINE == pobj->ot) {
6459 						a = (uint16_t)((pobj->det).s.n - 1U);
6460 
6461 						dk4xsp2d_set_point(
6462 							&xsp,
6463 							(double)(((pobj->det).s.p)[a].x),
6464 							(double)(((pobj->det).s.p)[a].y),
6465 							((pobj->det).s.p)[a].s,
6466 							0
6467 						);
6468 					}
6469 				}
6470 				/*
6471 					Minimum number of sub segments is 2
6472 				*/
6473 				if ((size_t)2U > subsegs) { subsegs = (size_t)2U; }
6474 				/*
6475 					Start point of segment
6476 				*/
6477 				dk4xsp2d_calculate_value_derivative(aa, &xsp, 0.0, NULL);
6478 				aa[1] = aa[1] / divisor;
6479 				aa[3] = aa[3] / divisor;
6480 				for (ssegno = (size_t)0U; ssegno < subsegs; ssegno++) {
6481 					if ((subsegs - (size_t)1U) == ssegno) {
6482 						t = 1.0;
6483 					}
6484 					else {
6485 						t = ((double)(ssegno + (size_t)1U)) / ((double)subsegs);
6486 					}
6487 					dk4xsp2d_calculate_value_derivative(ab, &xsp, t, NULL);
6488 					ab[1] = ab[1] / divisor;
6489 					ab[3] = ab[3] / divisor;
6490 					dk4bb_add_bezier(
6491 						&(pobj->bb),
6492 						aa[0], aa[2], (aa[0] + aa[1]), (aa[2] + aa[3]),
6493 						(ab[0] - ab[1]), (ab[2] - ab[3]), ab[0], ab[2]
6494 					);
6495 					DK4_MEMCPY(aa,ab,sizeof(aa));
6496 				}
6497 			}
6498 		}
6499 	}
6500 
6501 
6502 	return back;
6503 }
6504 
6505 
6506 
6507 static
6508 bool
wxdobj_bb_simple_arc(Wxd_object_t * pobj)6509 wxdobj_bb_simple_arc(Wxd_object_t *pobj)
6510 {
6511 	double		a;
6512 	double		b;
6513 	size_t		i;
6514 	int			c;
6515 
6516 	dk4bb_init(&(pobj->bb));
6517 	dk4bb_add_point(
6518 		&(pobj->bb), (double)((pobj->det).a.x1), (double)((pobj->det).a.y1)
6519 	);
6520 	dk4bb_add_point(
6521 		&(pobj->bb), (double)((pobj->det).a.x2), (double)((pobj->det).a.y2)
6522 	);
6523 	dk4bb_add_point(
6524 		&(pobj->bb), (double)((pobj->det).a.x3), (double)((pobj->det).a.y3)
6525 	);
6526 	if ((int8_t)0 != (pobj->det).a.d) {
6527 		if ((pobj->det).a.a <= (pobj->det).a.b) {
6528 			a = (pobj->det).a.a;
6529 			b = (pobj->det).a.b;
6530 		}
6531 		else {
6532 			a = (pobj->det).a.b;
6533 			b = (pobj->det).a.a;
6534 		}
6535 		c = 0;
6536 		for (i = (size_t)0U; i < sz_arc_angles; i++) {
6537 			if (a <= arc_angles[i]) {
6538 				if (arc_angles[i] <= b) {
6539 					switch (c) {
6540 						case 3 : {
6541 							dk4bb_add_y(
6542 								&(pobj->bb), ((pobj->det).a.y - (pobj->det).a.r)
6543 							);
6544 						} break;
6545 						case 2 : {
6546 							dk4bb_add_x(
6547 								&(pobj->bb), ((pobj->det).a.x - (pobj->det).a.r)
6548 							);
6549 						} break;
6550 						case 1 : {
6551 							dk4bb_add_y(
6552 								&(pobj->bb), ((pobj->det).a.y + (pobj->det).a.r)
6553 							);
6554 						} break;
6555 						default : {
6556 							dk4bb_add_x(
6557 								&(pobj->bb), ((pobj->det).a.x + (pobj->det).a.r)
6558 							);
6559 						} break;
6560 					}
6561 				}
6562 			}
6563 			if (4 <= ++c) { c = 0; }
6564 		}
6565 		if (WXD_OT_C_ARC == pobj->ot) {
6566 			dk4bb_add_point(&(pobj->bb), (pobj->det).a.x, (pobj->det).a.y);
6567 		}
6568 	}
6569 
6570 
6571 	return true;
6572 }
6573 
6574 
6575 
6576 static
6577 bool
wxdobj_bb_simple_circle(Wxd_object_t * pobj)6578 wxdobj_bb_simple_circle(Wxd_object_t *pobj)
6579 {
6580 
6581 	dk4bb_init(&(pobj->bb));
6582 	dk4bb_add_point(
6583 		&(pobj->bb),
6584 		((double)((pobj->det).e.x) - (double)((pobj->det).e.rx)),
6585 		((double)((pobj->det).e.y) - (double)((pobj->det).e.rx))
6586 	);
6587 	dk4bb_add_point(
6588 		&(pobj->bb),
6589 		((double)((pobj->det).e.x) + (double)((pobj->det).e.rx)),
6590 		((double)((pobj->det).e.y) + (double)((pobj->det).e.rx))
6591 	);
6592 
6593 
6594 	return true;
6595 }
6596 
6597 
6598 
6599 static
6600 bool
wxdobj_bb_simple_ellipse(Wxd_object_t * pobj)6601 wxdobj_bb_simple_ellipse(Wxd_object_t *pobj)
6602 {
6603 
6604 	dk4bb_init(&(pobj->bb));
6605 	dk4bb_add_rotated_ellipse(
6606 		&(pobj->bb),
6607 		(double)((pobj->det).e.x),
6608 		(double)((pobj->det).e.y),
6609 		(double)((pobj->det).e.rx),
6610 		(double)((pobj->det).e.ry),
6611 		((M_PI * ((double)((pobj->det).e.a))) / 180.0)
6612 	);
6613 
6614 
6615 	return true;
6616 }
6617 
6618 
6619 
6620 static
6621 bool
wxdobj_bb_simple_box(Wxd_object_t * pobj)6622 wxdobj_bb_simple_box(Wxd_object_t *pobj)
6623 {
6624 
6625 	dk4bb_init(&(pobj->bb));
6626 	dk4bb_add_point(
6627 		&(pobj->bb),
6628 		(double)((pobj->det).b.b.xl), (double)((pobj->det).b.b.yb)
6629 	);
6630 	dk4bb_add_point(
6631 		&(pobj->bb),
6632 		(double)((pobj->det).b.b.xr), (double)((pobj->det).b.b.yt)
6633 	);
6634 
6635 
6636 	return true;
6637 }
6638 
6639 
6640 
6641 static
6642 bool
wxdobj_bb_simple_image(Wxd_object_t * pobj)6643 wxdobj_bb_simple_image(Wxd_object_t *pobj)
6644 {
6645 
6646 	dk4bb_init(&(pobj->bb));
6647 	dk4bb_add_point(
6648 		&(pobj->bb),
6649 		(double)((pobj->det).i.br.xl), (double)((pobj->det).i.br.yb)
6650 	);
6651 	dk4bb_add_point(
6652 		&(pobj->bb),
6653 		(double)((pobj->det).i.br.xr), (double)((pobj->det).i.br.yt)
6654 	);
6655 
6656 
6657 	return true;
6658 }
6659 
6660 
6661 
6662 static
6663 bool
wxdobj_bb_simple_dot(Wxd_drawing_t const * pdrw,Wxd_object_t * pobj)6664 wxdobj_bb_simple_dot(Wxd_drawing_t const *pdrw, Wxd_object_t *pobj)
6665 {
6666 #if	1
6667 	double		r;
6668 #endif
6669 
6670 	dk4bb_init(&(pobj->bb));
6671 #if	1
6672 	r = (((double)((pobj->det).d.d) * (double)(pdrw->baselw)) / 2.0);
6673 	dk4bb_add_point(
6674 		&(pobj->bb),
6675 		((double)((pobj->det).d.x) - r), ((double)((pobj->det).d.y) - r)
6676 	);
6677 	dk4bb_add_point(
6678 		&(pobj->bb),
6679 		((double)((pobj->det).d.x) + r), ((double)((pobj->det).d.y) + r)
6680 	);
6681 #else
6682 	dk4bb_add_point(&(pobj->bb), (pobj->det).d.x, (pobj->det).d.y);
6683 #endif
6684 
6685 
6686 	return true;
6687 }
6688 
6689 
6690 
6691 bool
wxdobj_bb_simple_object(Wxd_drawing_t const * pdrw,Wxd_object_t * pobj)6692 wxdobj_bb_simple_object(
6693 	Wxd_drawing_t const	*pdrw,
6694 	Wxd_object_t		*pobj
6695 )
6696 {
6697 	bool		back	= false;
6698 
6699 	if (NULL != pobj) {
6700 		switch ( (int)(pobj->ot) ) {
6701 			case WXD_OT_TEXT : {
6702 				back = wxdobj_bb_simple_text(pobj);
6703 			} break;
6704 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
6705 				back = wxdobj_bb_simple_polyline(pobj);
6706 			} break;
6707 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
6708 				back = wxdobj_bb_simple_spline(pobj, pdrw->xsubs);
6709 			} break;
6710 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
6711 				back = wxdobj_bb_simple_arc(pobj);
6712 			} break;
6713 			case WXD_OT_CIRCLE : {
6714 				back = wxdobj_bb_simple_circle(pobj);
6715 			} break;
6716 			case WXD_OT_ELLIPSE : {
6717 				back = wxdobj_bb_simple_ellipse(pobj);
6718 			} break;
6719 			case WXD_OT_BOX : {
6720 				back = wxdobj_bb_simple_box(pobj);
6721 			} break;
6722 			case WXD_OT_IMAGE : {
6723 				back = wxdobj_bb_simple_image(pobj);
6724 			} break;
6725 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
6726 				back = wxdobj_bb_simple_dot(pdrw, pobj);
6727 			} break;
6728 		}
6729 	}
6730 
6731 	return back;
6732 }
6733 
6734 
6735 
6736 bool
wxdobj_bb_group_structural(Wxd_drawing_t const * pdrw,Wxd_object_t * pobj)6737 wxdobj_bb_group_structural(
6738 	Wxd_drawing_t const	*pdrw,
6739 	Wxd_object_t		*pobj
6740 )
6741 {
6742 	Wxd_object_t	*po;
6743 	bool			 back	= false;
6744 
6745 	if (NULL != pobj) {
6746 		dk4bb_init(&(pobj->bb));
6747 	}
6748 	if ((NULL != pdrw) && (NULL != pobj)) {
6749 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
6750 			back = true;
6751 			dk4sto_it_reset((pobj->det).g.i_e);
6752 			do {
6753 				po = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
6754 				if (NULL != po) {
6755 					if (WXD_OT_GROUP_BEGIN == po->ot) {
6756 						if (!wxdobj_bb_group_structural(pdrw, po)) {
6757 							back = false;
6758 						}
6759 					}
6760 
6761 					dk4bb_add_bb(&(pobj->bb), &(po->bb));
6762 				}
6763 			} while (NULL != po);
6764 		}
6765 
6766 	}
6767 
6768 	return back;
6769 }
6770 
6771 
6772 
6773 bool
wxdobj_bb_group_and_contents(Wxd_drawing_t const * pdrw,Wxd_object_t * pobj)6774 wxdobj_bb_group_and_contents(
6775 	Wxd_drawing_t const	*pdrw,
6776 	Wxd_object_t		*pobj
6777 )
6778 {
6779 	Wxd_object_t	*po;
6780 	bool			 back	= false;
6781 
6782 	if (NULL != pobj) {
6783 		dk4bb_init(&(pobj->bb));
6784 	}
6785 	if ((NULL != pdrw) && (NULL != pobj)) {
6786 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
6787 			back = true;
6788 			dk4sto_it_reset((pobj->det).g.i_e);
6789 			do {
6790 				po = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
6791 				if (NULL != po) {
6792 					if (WXD_OT_GROUP_BEGIN == po->ot) {
6793 						if (!wxdobj_bb_group_and_contents(pdrw, po)) {
6794 							back = false;
6795 						}
6796 					}
6797 					else {
6798 						if (!wxdobj_bb_simple_object(pdrw, po)) {
6799 							back = false;
6800 						}
6801 					}
6802 
6803 					dk4bb_add_bb(&(pobj->bb), &(po->bb));
6804 				}
6805 			} while (NULL != po);
6806 		}
6807 
6808 	}
6809 
6810 	return back;
6811 }
6812 
6813 
6814 
6815 bool
wxdobj_bb_modified_object(Wxd_drawing_t const * pdrw,Wxd_object_t * pobj)6816 wxdobj_bb_modified_object(
6817 	Wxd_drawing_t const	*pdrw,
6818 	Wxd_object_t		*pobj
6819 )
6820 {
6821 	bool		back = false;
6822 
6823 	if (NULL != pobj) {
6824 		dk4bb_init(&(pobj->bb));
6825 	}
6826 	if ((NULL != pdrw) && (NULL != pobj)) {
6827 		if (WXD_OT_GROUP_BEGIN == pobj->ot) {
6828 			/*
6829 				If a group was modified (i.e. moved) rebuild
6830 				bounding box information completely
6831 			*/
6832 			back = wxdobj_bb_group_and_contents(pdrw, pobj);
6833 		}
6834 		else {
6835 			/*
6836 				Rebuild bounding box information for simple object
6837 			*/
6838 			back = wxdobj_bb_simple_object(pdrw, pobj);
6839 			if (NULL != pobj->pa) {
6840 				/*
6841 					If object is member of a group rebuild bounding box
6842 					information in structural nodes
6843 				*/
6844 				while (NULL != pobj->pa) { pobj = pobj->pa; }
6845 				if (!wxdobj_bb_group_structural(pdrw, pobj)) {
6846 					back = false;
6847 				}
6848 			}
6849 		}
6850 	}
6851 
6852 	return back;
6853 }
6854 
6855 
6856 
6857 bool
wxdobj_bb_for_drawing(Wxd_drawing_t * pdrw)6858 wxdobj_bb_for_drawing(
6859 	Wxd_drawing_t	*pdrw
6860 )
6861 {
6862 	Wxd_object_t	*pobj;
6863 	bool		 	 back	= false;
6864 
6865 	if (NULL != pdrw) {
6866 		back = true;
6867 		dk4sto_it_reset(pdrw->i_flat);
6868 		do {
6869 			pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_flat);
6870 			if (NULL != pobj) {
6871 				if (!wxdobj_bb_simple_object(pdrw, pobj)) {
6872 					back = false;
6873 				}
6874 			}
6875 		} while (NULL != pobj);
6876 		dk4sto_it_reset(pdrw->i_stru);
6877 		do {
6878 			pobj = (Wxd_object_t *)dk4sto_it_next(pdrw->i_stru);
6879 			if (NULL != pobj) {
6880 				if (WXD_OT_GROUP_BEGIN == pobj->ot) {
6881 
6882 					if (!wxdobj_bb_group_structural(pdrw, pobj)) {
6883 						back = false;
6884 					}
6885 				}
6886 			}
6887 		} while (NULL != pobj);
6888 	}
6889 
6890 	return back;
6891 }
6892 
6893 
6894 
6895 bool
wxdobj_text_is_latex(Wxd_object_t const * pobj)6896 wxdobj_text_is_latex(Wxd_object_t const *pobj)
6897 {
6898 	bool	back = false;
6899 	if (NULL != pobj) {
6900 		if (WXD_OT_TEXT == pobj->ot) {
6901 			if (
6902 				WXD_TEXT_FLAG_NONE
6903 				!= (WXD_TEXT_FLAG_LATEX & ((pobj->det).t.fl))
6904 			) {
6905 				back = true;
6906 			}
6907 		}
6908 	}
6909 	return back;
6910 }
6911 
6912 
6913 
6914 bool
wxdobj_can_convert(int destot,const Wxd_object_t * pobj)6915 wxdobj_can_convert(
6916 	int					 destot,
6917 	const Wxd_object_t	*pobj
6918 )
6919 {
6920 	bool		back	= false;
6921 
6922 	if (NULL != pobj) {
6923 		switch (destot) {
6924 			case WXD_OT_POLYLINE : {
6925 				switch ( (int)(pobj->ot) ) {
6926 					case WXD_OT_BOX :
6927 					case WXD_OT_POLYLINE :
6928 					case WXD_OT_O_SPLINE :
6929 					case WXD_OT_O_ARC :
6930 					case WXD_OT_POLYGON :
6931 					case WXD_OT_C_SPLINE :
6932 					case WXD_OT_C_ARC : {
6933 						back = true;
6934 					} break;
6935 				}
6936 			} break;
6937 			case WXD_OT_O_SPLINE : {
6938 				switch ( (int)(pobj->ot) ) {
6939 					case WXD_OT_BOX :
6940 					case WXD_OT_POLYLINE :
6941 					case WXD_OT_O_SPLINE :
6942 					case WXD_OT_O_ARC :
6943 					case WXD_OT_POLYGON :
6944 					case WXD_OT_C_SPLINE :
6945 					case WXD_OT_C_ARC : {
6946 						back = true;
6947 					} break;
6948 				}
6949 			} break;
6950 			case WXD_OT_O_ARC : {
6951 				switch ( (int)(pobj->ot) ) {
6952 					case WXD_OT_C_ARC :
6953 					case WXD_OT_O_ARC : {
6954 						back =  true;
6955 					} break;
6956 					case WXD_OT_POLYLINE :
6957 					case WXD_OT_POLYGON : {
6958 						if ((uint16_t)3U == (pobj->det).p.n) {
6959 							back = true;
6960 						}
6961 					} break;
6962 					case WXD_OT_O_SPLINE :
6963 					case WXD_OT_C_SPLINE : {
6964 						if ((uint16_t)3U == (pobj->det).s.n) {
6965 							back = true;
6966 						}
6967 					} break;
6968 				}
6969 			} break;
6970 			case WXD_OT_POLYGON : {
6971 				switch ( (int)(pobj->ot) ) {
6972 					case WXD_OT_BOX :
6973 					case WXD_OT_POLYLINE :
6974 					case WXD_OT_O_SPLINE :
6975 					case WXD_OT_O_ARC :
6976 					case WXD_OT_POLYGON :
6977 					case WXD_OT_C_SPLINE :
6978 					case WXD_OT_C_ARC : {
6979 						back = true;
6980 					} break;
6981 				}
6982 			} break;
6983 			case WXD_OT_C_SPLINE : {
6984 				switch ( (int)(pobj->ot) ) {
6985 					case WXD_OT_BOX :
6986 					case WXD_OT_POLYLINE :
6987 					case WXD_OT_O_SPLINE :
6988 					case WXD_OT_O_ARC :
6989 					case WXD_OT_POLYGON :
6990 					case WXD_OT_C_SPLINE :
6991 					case WXD_OT_C_ARC : {
6992 						back = true;
6993 					} break;
6994 				}
6995 
6996 			} break;
6997 			case WXD_OT_C_ARC : {
6998 				switch ( (int)(pobj->ot) ) {
6999 					case WXD_OT_C_ARC :
7000 					case WXD_OT_O_ARC : {
7001 						back =  true;
7002 					} break;
7003 					case WXD_OT_POLYLINE :
7004 					case WXD_OT_POLYGON : {
7005 						if ((uint16_t)3U == (pobj->det).p.n) {
7006 							back = true;
7007 						}
7008 					} break;
7009 					case WXD_OT_O_SPLINE :
7010 					case WXD_OT_C_SPLINE : {
7011 						if ((uint16_t)3U == (pobj->det).s.n) {
7012 							back = true;
7013 						}
7014 					} break;
7015 				}
7016 			} break;
7017 			case WXD_OT_DOT_FILLED : {
7018 				switch ( (int)(pobj->ot) ) {
7019 					case WXD_OT_DOT_FILLED :
7020 					case WXD_OT_DOT_WHITE :
7021 					case WXD_OT_CIRCLE : {
7022 						back = true;
7023 					} break;
7024 				}
7025 			} break;
7026 			case WXD_OT_DOT_WHITE :  {
7027 				switch ( (int)(pobj->ot) ) {
7028 					case WXD_OT_DOT_FILLED :
7029 					case WXD_OT_DOT_WHITE :
7030 					case WXD_OT_CIRCLE : {
7031 						back = true;
7032 					} break;
7033 				}
7034 			} break;
7035 		}
7036 	}
7037 	return back;
7038 }
7039 
7040 
7041 
7042 /**	Rotate one point relatively to a center point by 90 degree.
7043 	@param	x		Point x coordinate (in and out).
7044 	@paam	y		Point y coordinate (in and out).
7045 	@param	x0		Center point x coordinate.
7046 	@param	y0		Center point y coordinate.
7047 	@param	neg		Negative direction (false=positive direction).
7048 	@param	doit	Really modify point (false=test only).
7049 	@return	True on success, false on error.
7050 */
7051 static
7052 bool
wxdobj_rotate_point(int32_t & x,int32_t & y,int32_t x0,int32_t y0,bool neg,bool doit)7053 wxdobj_rotate_point(
7054 	int32_t	&	x,
7055 	int32_t	&	y,
7056 	int32_t		x0,
7057 	int32_t		y0,
7058 	bool		neg,
7059 	bool		doit
7060 )
7061 {
7062 	dk4_er_t	er;
7063 	int32_t		dx;
7064 	int32_t		dy;
7065 	int32_t		nx;
7066 	int32_t		ny;
7067 	bool		back	= false;
7068 
7069 	if ((x == x0) && (y == y0)) {
7070 		back = true;
7071 	}
7072 	else {
7073 		dk4error_init(&er);
7074 		dx = dk4ma_int32_t_sub(x, x0, &er);
7075 		dy = dk4ma_int32_t_sub(y, y0, &er);
7076 		if (neg) {
7077 			nx = dk4ma_int32_t_add(x0, dy, &er);
7078 			ny = dk4ma_int32_t_sub(y0, dx, &er);
7079 		}
7080 		else {
7081 			nx = dk4ma_int32_t_sub(x0, dy, &er);
7082 			ny = dk4ma_int32_t_add(y0, dx, &er);
7083 		}
7084 		if (DK4_E_NONE == er.ec) {
7085 			back = true;
7086 			if (doit) {
7087 				x = nx;
7088 				y = ny;
7089 			}
7090 		}
7091 	}
7092 	return back;
7093 }
7094 
7095 
7096 
7097 static
7098 bool
wxdobj_rotate_text(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7099 wxdobj_rotate_text(
7100 	Wxd_object_t	*pobj,
7101 	int32_t			 x0,
7102 	int32_t			 y0,
7103 	bool			 neg,
7104 	bool			 doit
7105 )
7106 {
7107 	bool		back;
7108 	back = wxdobj_rotate_point(
7109 		(pobj->det).t.x, (pobj->det).t.y, x0, y0, neg, doit
7110 	);
7111 	if (doit) {
7112 		if (neg) {
7113 			(pobj->det).t.a = (int16_t)(
7114 				(pobj->det).t.a - 90
7115 			);
7116 			if ((int16_t)0 > (pobj->det).t.a) {
7117 				(pobj->det).t.a = (int16_t)(
7118 					(pobj->det).t.a + 360
7119 				);
7120 			}
7121 		}
7122 		else {
7123 			(pobj->det).t.a = (int16_t)(
7124 				(pobj->det).t.a + 90
7125 			);
7126 			if ((int16_t)360 < (pobj->det).t.a) {
7127 				(pobj->det).t.a = (int16_t)(
7128 					(pobj->det).t.a - 360
7129 				);
7130 			}
7131 		}
7132 	}
7133 	return back;
7134 }
7135 
7136 
7137 
7138 static
7139 bool
wxdobj_rotate_polyline(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7140 wxdobj_rotate_polyline(
7141 	Wxd_object_t	*pobj,
7142 	int32_t			 x0,
7143 	int32_t			 y0,
7144 	bool			 neg,
7145 	bool			 doit
7146 )
7147 {
7148 	uint16_t	i;
7149 	bool		back = false;
7150 	bool		res;
7151 	if ((NULL != (pobj->det).p.p) && ((uint16_t)0U < (pobj->det).p.n)) {
7152 		back = true;
7153 		for (i = (uint16_t)0U; i < (pobj->det).p.n; i++) {
7154 			res = wxdobj_rotate_point(
7155 				((pobj->det).p.p)[i].x,((pobj->det).p.p)[i].y,x0,y0,neg,doit
7156 			);
7157 			if (!(res)) { back = false; }
7158 		}
7159 	}
7160 	return back;
7161 }
7162 
7163 
7164 
7165 static
7166 bool
wxdobj_rotate_spline(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7167 wxdobj_rotate_spline(
7168 	Wxd_object_t	*pobj,
7169 	int32_t			 x0,
7170 	int32_t			 y0,
7171 	bool			 neg,
7172 	bool			 doit
7173 )
7174 {
7175 	uint16_t	i;
7176 	bool		back = false;
7177 	bool		res;
7178 	if ((NULL != (pobj->det).s.p) && ((uint16_t)0U < (pobj->det).s.n)) {
7179 		back = true;
7180 		for (i = (uint16_t)0U; i < (pobj->det).s.n; i++) {
7181 			res = wxdobj_rotate_point(
7182 				((pobj->det).s.p)[i].x,((pobj->det).s.p)[i].y,x0,y0,neg,doit
7183 			);
7184 			if (!(res)) { back = false; }
7185 		}
7186 	}
7187 	return back;
7188 }
7189 
7190 
7191 
7192 static
7193 bool
wxdobj_rotate_arc(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7194 wxdobj_rotate_arc(
7195 	Wxd_object_t	*pobj,
7196 	int32_t			 x0,
7197 	int32_t			 y0,
7198 	bool			 neg,
7199 	bool			 doit
7200 )
7201 {
7202 	bool back = true;
7203 	bool res;
7204 	res = wxdobj_rotate_point((pobj->det).a.x1,(pobj->det).a.y1,x0,y0,neg,doit);
7205 	if (!(res)) { back = false; }
7206 	res = wxdobj_rotate_point((pobj->det).a.x2,(pobj->det).a.y2,x0,y0,neg,doit);
7207 	if (!(res)) { back = false; }
7208 	res = wxdobj_rotate_point((pobj->det).a.x3,(pobj->det).a.y3,x0,y0,neg,doit);
7209 	if (!(res)) { back = false; }
7210 	if (doit) {
7211 		wxdarc_calculation(
7212 			&((pobj->det).a.x), &((pobj->det).a.y), &((pobj->det).a.r),
7213 			&((pobj->det).a.a), &((pobj->det).a.b), &((pobj->det).a.d),
7214 			(pobj->det).a.x1, (pobj->det).a.y1, (pobj->det).a.x2,
7215 			(pobj->det).a.y2, (pobj->det).a.x3, (pobj->det).a.y3
7216 		);
7217 
7218 	}
7219 	return back;
7220 }
7221 
7222 
7223 
7224 static
7225 bool
wxdobj_rotate_ellipse(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7226 wxdobj_rotate_ellipse(
7227 	Wxd_object_t	*pobj,
7228 	int32_t			 x0,
7229 	int32_t			 y0,
7230 	bool			 neg,
7231 	bool			 doit
7232 )
7233 {
7234 	bool	back = false;
7235 	back = wxdobj_rotate_point(
7236 		(pobj->det).e.x, (pobj->det).e.y, x0, y0, neg, doit
7237 	);
7238 	if (doit && (WXD_OT_ELLIPSE == pobj->ot)) {
7239 		if (neg) {
7240 			(pobj->det).e.a = (int16_t)(
7241 				(pobj->det).e.a - 90
7242 			);
7243 			if ((int16_t)0 > (pobj->det).e.a) {
7244 				(pobj->det).e.a = (int16_t)(
7245 					(pobj->det).e.a  + 360
7246 				);
7247 			}
7248 		}
7249 		else {
7250 			(pobj->det).e.a = (int16_t)(
7251 				(pobj->det).e.a + 90
7252 			);
7253 			if ((int16_t)360 < (pobj->det).e.a) {
7254 				(pobj->det).e.a = (int16_t)(
7255 					(pobj->det).e.a - 360
7256 				);
7257 			}
7258 		}
7259 	}
7260 	return back;
7261 }
7262 
7263 
7264 
7265 static
7266 bool
wxdobj_rotate_bb(Wxd_bb_t * pbb,int32_t x0,int32_t y0,bool neg,bool doit)7267 wxdobj_rotate_bb(
7268 	Wxd_bb_t		*pbb,
7269 	int32_t			 x0,
7270 	int32_t			 y0,
7271 	bool			 neg,
7272 	bool			 doit
7273 )
7274 {
7275 	bool back = true;
7276 	bool res;
7277 	res = wxdobj_rotate_point(pbb->xl, pbb->yb, x0, y0, neg, doit);
7278 	if (!(res)) { back = false; }
7279 	res = wxdobj_rotate_point(pbb->xr, pbb->yt, x0, y0, neg, doit);
7280 	if (!(res)) { back = false; }
7281 	if (doit) {
7282 		wxdobj_bb_correct(pbb);
7283 	}
7284 	return back;
7285 }
7286 
7287 
7288 
7289 static
7290 bool
wxdobj_rotate_simple_object(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7291 wxdobj_rotate_simple_object(
7292 	Wxd_object_t	*pobj,
7293 	int32_t			 x0,
7294 	int32_t			 y0,
7295 	bool			 neg,
7296 	bool			 doit
7297 )
7298 {
7299 	bool		back	= false;
7300 	if (NULL != pobj) {
7301 		switch ( (int)(pobj->ot) ) {
7302 			case WXD_OT_TEXT : {
7303 				back = wxdobj_rotate_text(pobj, x0, y0, neg, doit);
7304 			} break;
7305 			case WXD_OT_POLYLINE : case WXD_OT_POLYGON : {
7306 				back = wxdobj_rotate_polyline(pobj, x0, y0, neg, doit);
7307 			} break;
7308 			case WXD_OT_O_SPLINE : case WXD_OT_C_SPLINE : {
7309 				back = wxdobj_rotate_spline(pobj, x0, y0, neg, doit);
7310 			} break;
7311 			case WXD_OT_O_ARC : case WXD_OT_C_ARC : {
7312 				back = wxdobj_rotate_arc(pobj, x0, y0, neg, doit);
7313 			} break;
7314 			case WXD_OT_CIRCLE : case WXD_OT_ELLIPSE : {
7315 				back = wxdobj_rotate_ellipse(pobj, x0, y0, neg, doit);
7316 			} break;
7317 			case WXD_OT_BOX : {
7318 				back = wxdobj_rotate_bb(&((pobj->det).b.b), x0, y0, neg, doit);
7319 			} break;
7320 			case WXD_OT_IMAGE : {
7321 				back = wxdobj_rotate_bb(&((pobj->det).i.br), x0, y0, neg, doit);
7322 				if (doit) { wxdobj_image_placement(pobj); }
7323 			} break;
7324 			case WXD_OT_DOT_FILLED : case WXD_OT_DOT_WHITE : {
7325 				back = wxdobj_rotate_point(
7326 					(pobj->det).d.x, (pobj->det).d.y, x0, y0, neg, doit
7327 				);
7328 			} break;
7329 		}
7330 	}
7331 	return back;
7332 }
7333 
7334 
7335 
7336 static
7337 bool
wxdobj_rotate_structural_object(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7338 wxdobj_rotate_structural_object(
7339 	Wxd_object_t	*pobj,
7340 	int32_t			 x0,
7341 	int32_t			 y0,
7342 	bool			 neg,
7343 	bool			 doit
7344 )
7345 {
7346 	Wxd_object_t	*o;
7347 	bool	back = false;
7348 	bool	res;
7349 	if (WXD_OT_GROUP_BEGIN == pobj->ot) {
7350 		back = true;
7351 		dk4sto_it_reset((pobj->det).g.i_e);
7352 		do {
7353 			o = (Wxd_object_t *)dk4sto_it_next((pobj->det).g.i_e);
7354 			if (NULL != o) {
7355 				switch ( (int)(o->ot) ) {
7356 					case WXD_OT_GROUP_BEGIN : {
7357 						res = wxdobj_rotate_structural_object(
7358 							o, x0, y0, neg, doit
7359 						);
7360 					} break;
7361 					default : {
7362 						res = wxdobj_rotate_simple_object(
7363 							o, x0, y0, neg, doit
7364 						);
7365 					} break;
7366 				}
7367 				if (!(res)) { back = false; }
7368 			}
7369 		} while (NULL != o);
7370 	}
7371 	return back;
7372 }
7373 
7374 
7375 
7376 bool
wxdobj_rotate_object(Wxd_object_t * pobj,int32_t x0,int32_t y0,bool neg,bool doit)7377 wxdobj_rotate_object(
7378 	Wxd_object_t	*pobj,
7379 	int32_t			 x0,
7380 	int32_t			 y0,
7381 	bool			 neg,
7382 	bool			 doit
7383 )
7384 {
7385 	bool	back = false;
7386 	if (NULL != pobj) {
7387 		switch ( (int)(pobj->ot) ) {
7388 			case WXD_OT_GROUP_BEGIN : {
7389 				back = wxdobj_rotate_structural_object(
7390 					pobj, x0, y0, neg, doit
7391 				);
7392 			} break;
7393 			default : {
7394 				back = wxdobj_rotate_simple_object(
7395 					pobj, x0, y0, neg, doit
7396 				);
7397 			} break;
7398 		}
7399 	}
7400 	return back;
7401 }
7402 
7403 
7404 
7405 bool
wxdobj_bb_equal(Wxd_bb_t const * pa,Wxd_bb_t const * pb)7406 wxdobj_bb_equal(Wxd_bb_t const *pa, Wxd_bb_t const *pb)
7407 {
7408 	bool		back = false;
7409 
7410 	if ((NULL != pa) && (NULL != pb)) {
7411 
7412 
7413 		if (
7414 			(pa->xl == pb->xl) && (pa->xr == pb->xr)
7415 			&& (pa->yb == pb->yb) && (pa->yt == pb->yt)
7416 		) {
7417 			back = true;
7418 		}
7419 	}
7420 	return back;
7421 }
7422 
7423 
7424 /* vim: set ai sw=4 ts=4 : */
7425 
7426