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