1 /*
2 Copyright (C) 2017-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: dk4gra.ctr
12 */
13
14 /** @file dk4gra.c The dk4gra module.
15 */
16
17
18
19 #include "dk4conf.h"
20
21 #if DK4_HAVE_FCNTL_H
22 #ifndef FCNTL_H_INCLUDED
23 #include <fcntl.h>
24 #define FCNTL_H_INCLUDED 1
25 #endif
26 #endif
27
28 #if DK4_HAVE_IO_H
29 #ifndef IO_H_INCLUDED
30 #include <io.h>
31 #define IO_H_INCLUDED 1
32 #endif
33 #endif
34
35 #if DK4_HAVE_MATH_H
36 #ifndef MATH_H_INCLUDED
37 #if DK4_ON_WINDOWS
38 #ifndef _USE_MATH_DEFINES
39 #define _USE_MATH_DEFINES 1
40 #endif
41 #endif
42 #include <math.h>
43 #define MATH_H_INCLUDED 1
44 #endif
45 #endif
46
47 #if DK4_HAVE_FLOAT_H
48 #ifndef FLOAT_H_INCLUDED
49 #include <float.h>
50 #define FLOAT_H_INCLUDED 1
51 #endif
52 #endif
53
54 #if DK4_HAVE_ERRNO_H
55 #ifndef ERRNO_H_INCLUDED
56 #include <errno.h>
57 #define ERRNO_H_INCLUDED 1
58 #endif
59 #endif
60
61 #ifndef DK4MATH_H_INCLUDED
62 #include <libdk4c/dk4math.h>
63 #endif
64
65 #ifndef DK4UC2L_H_INCLUDED
66 #include <libdk4lat/dk4uc2l.h>
67 #endif
68
69 #ifndef DK4GRA_H_INCLUDED
70 #include <libdk4gra/dk4gra.h>
71 #endif
72
73 #ifndef DK4GRAT_H_INCLUDED
74 #include <libdk4gra/dk4grat.h>
75 #endif
76
77 #ifndef GRA_H_INCLUDED
78 #include <libdk4gra/gra.h>
79 #endif
80
81 #ifndef DK4BIF_H_INCLUDED
82 #include <libdk4bif/dk4bif.h>
83 #endif
84
85 #ifndef DK4FOPD_H_INCLUDED
86 #include <libdk4c/dk4fopd.h>
87 #endif
88
89 #ifndef DK4FOPT_H_INCLUDED
90 #include <libdk4c/dk4fopt.h>
91 #endif
92
93 #ifndef DK4ISADM_H_INCLUDED
94 #include <libdk4c/dk4isadm.h>
95 #endif
96
97 #if DK4_HAVE_ASSERT_H
98 #ifndef ASSERT_H_INCLUDED
99 #include <assert.h>
100 #define ASSERT_H_INCLUDED 1
101 #endif
102 #endif
103
104
105
106
107
108
109 static
110 void
dk4gra_i_save_attributes(dk4_gra_t * gra)111 dk4gra_i_save_attributes(
112 dk4_gra_t *gra
113 )
114 {
115 #if DK4_USE_ASSERT
116 assert(NULL != gra);
117 #endif
118 switch (gra->dr) {
119 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
120 dk4gra_eps_save_attributes(gra);
121 } break;
122 case DK4_GRA_DRIVER_PGF : {
123 dk4gra_pgf_save_attributes(gra);
124 } break;
125 default : {
126 dk4gra_pdf_save_attributes(gra);
127 } break;
128 }
129 }
130
131
132
133 static
134 void
dk4gra_i_restore_attributes(dk4_gra_t * gra)135 dk4gra_i_restore_attributes(
136 dk4_gra_t *gra
137 )
138 {
139 #if DK4_USE_ASSERT
140 assert(NULL != gra);
141 #endif
142 switch (gra->dr) {
143 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
144 dk4gra_eps_restore_attributes(gra);
145 } break;
146 case DK4_GRA_DRIVER_PGF : {
147 dk4gra_pgf_restore_attributes(gra);
148 } break;
149 default : {
150 dk4gra_pdf_restore_attributes(gra);
151 } break;
152 }
153 }
154
155
156
157 static
158 void
dk4gra_i_reset_attributes(dk4_gra_t * gra)159 dk4gra_i_reset_attributes(
160 dk4_gra_t *gra
161 )
162 {
163 #if DK4_USE_ASSERT
164 assert(NULL != gra);
165 #endif
166 switch (gra->dr) {
167 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
168 dk4gra_eps_reset_attributes(gra);
169 } break;
170 case DK4_GRA_DRIVER_PGF : {
171 dk4gra_pgf_reset_attributes(gra);
172 } break;
173 default : {
174 dk4gra_pdf_reset_attributes(gra);
175 } break;
176 }
177 }
178
179
180
181 static
182 double
dk4gra_i_to_range(double x,double min,double max)183 dk4gra_i_to_range(double x, double min, double max)
184 {
185 if (min > x) { x = min; }
186 if (max < x) { x = max; }
187 return x;
188 }
189
190
191
192 void
dk4gra_close(dk4_gra_t * gra)193 dk4gra_close(
194 dk4_gra_t *gra
195 )
196 {
197
198 #if DK4_USE_ASSERT
199 assert(NULL != gra);
200 #endif
201 if (NULL == gra) {
202 goto finished;
203 }
204 switch (gra->dr) {
205 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
206 dk4gra_eps_close(gra);
207 } break;
208 case DK4_GRA_DRIVER_PGF : {
209 dk4gra_pgf_close(gra);
210 } break;
211 default : {
212 dk4gra_pdf_close(gra);
213 } break;
214 }
215 finished:
216
217 return;
218 }
219
220
221
222 dk4_gra_t *
dk4gra_open_pdf(const dkChar * fn,size_t w,size_t h,int docfl,dk4_er_t * erp)223 dk4gra_open_pdf(
224 const dkChar *fn,
225 size_t w,
226 size_t h,
227 int docfl,
228 dk4_er_t *erp
229 )
230 {
231 dk4_gra_t *back = NULL;
232
233 #if DK4_USE_ASSERT
234 assert(NULL != fn);
235 #endif
236 if ((0 == w) || (0 == h)) {
237 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
238 goto finished;
239 }
240 back = dk4gra_pdf_open(fn, w, h, docfl, erp);
241 finished:
242
243 return back;
244 }
245
246
247
248 dk4_gra_t *
dk4gra_open_ps(const dkChar * fn,size_t w,size_t h,int docfl,dk4_er_t * erp)249 dk4gra_open_ps(
250 const dkChar *fn,
251 size_t w,
252 size_t h,
253 int docfl,
254 dk4_er_t *erp
255 )
256 {
257 dk4_gra_t *back = NULL;
258
259 #if DK4_USE_ASSERT
260 assert(NULL != fn);
261 #endif
262 if ((0 == w) || (0 == h)) {
263 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
264 goto finished;
265 }
266 back = dk4gra_eps_open(fn, w, h, docfl, erp);
267 finished:
268
269 return back;
270 }
271
272
273
274
275 dk4_gra_t *
dk4gra_open_pgf(const dkChar * fn,size_t w,size_t h,int docfl,int sa,dk4_er_t * erp)276 dk4gra_open_pgf(
277 const dkChar *fn,
278 size_t w,
279 size_t h,
280 int docfl,
281 int sa,
282 dk4_er_t *erp
283 )
284 {
285 dk4_gra_t *back = NULL;
286
287 #if DK4_USE_ASSERT
288 assert(NULL != fn);
289 #endif
290 if ((0 == w) || (0 == h)) {
291 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
292 goto finished;
293 }
294 back = dk4gra_pgf_open(fn, w, h, docfl, sa, erp);
295 finished:
296
297 return back;
298 }
299
300
301
302 void
dk4gra_set_color_conversion(dk4_gra_t * gra,dk4_cs_conv_ctx_t const * ctx,int * backptr,dk4_er_t * erp)303 dk4gra_set_color_conversion(
304 dk4_gra_t *gra,
305 dk4_cs_conv_ctx_t const *ctx,
306 int *backptr,
307 dk4_er_t *erp
308 )
309 {
310 int back = 0;
311 #if DK4_USE_ASSERT
312 assert(NULL != gra);
313 #endif
314 if ((NULL != gra) && (NULL != ctx)) {
315 DK4_MEMCPY(&(gra->cscctx),ctx,sizeof(dk4_cs_conv_ctx_t));
316 back = 1;
317 }
318 else {
319 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
320 }
321 if ((0 == back) && (NULL != backptr)) { *backptr = 0; }
322 }
323
324
325
326 void
dk4gra_write_file_and_close(FILE * fout,dk4_gra_t * gra,int * backptr,dk4_er_t * erp)327 dk4gra_write_file_and_close(
328 FILE *fout,
329 dk4_gra_t *gra,
330 int *backptr,
331 dk4_er_t *erp
332 )
333 {
334 int back = 0;
335
336 #if DK4_USE_ASSERT
337 assert(NULL != gra);
338 assert(NULL != fout);
339 #endif
340 if (NULL == gra) {
341 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
342 goto finished;
343 }
344 if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) {
345 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
346 dk4gra_close(gra);
347 goto finished;
348 }
349 if ((0 == gra->pages) || (NULL == gra->curpg)) {
350 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
351 dk4gra_close(gra);
352 goto finished;
353 }
354
355 switch (gra->dr) {
356 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
357 back = dk4gra_eps_write_file_and_close(fout, gra, erp);
358 } break;
359 case DK4_GRA_DRIVER_PGF : {
360 back = dk4gra_pgf_write_file_and_close(fout, gra, erp);
361 } break;
362 default : {
363 back = dk4gra_pdf_write_file_and_close(fout, gra, erp);
364 } break;
365 }
366
367 finished:
368
369 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
370 }
371
372
373
374 void
dk4gra_write_and_close(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)375 dk4gra_write_and_close(
376 dk4_gra_t *gra,
377 int *backptr,
378 dk4_er_t *erp
379 )
380 {
381 FILE *fout = NULL; /* Output file to write */
382 int tests = DK4_FOPEN_SC_USER; /* Tests for opening file */
383 int back = 0;
384 #if DK4_ON_WINDOWS
385 int oldm = _O_TEXT; /* Previous DOS stdout mode */
386 #endif
387
388 #if DK4_USE_ASSERT
389 assert(NULL != gra);
390 #endif
391 if (NULL == gra) {
392 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
393 goto finished;
394 }
395 if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) {
396 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
397 dk4gra_close(gra);
398 goto finished;
399 }
400 if ((0 == gra->pages) || (NULL == gra->curpg)) {
401 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
402 dk4gra_close(gra);
403 goto finished;
404 }
405
406 /* Open and write output file if name specified, otherwise
407 write to standard output.
408 */
409 if (NULL != gra->fn) {
410 if (0 != dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
411 fout = dk4fopen(gra->fn, dkT("wb"), tests, erp);
412 if (NULL != fout) {
413 back = 1;
414 dk4gra_write_file_and_close(fout, gra, &back, erp);
415 if (0 != fclose(fout)) {
416 dk4error_set_simple_error_code(erp, DK4_E_CLOSE_FAILED);
417 back = 0;
418 }
419 }
420 else {
421 dk4gra_close(gra);
422 }
423 }
424 else {
425 back = 1;
426 #if DK4_ON_WINDOWS
427 oldm = _setmode(_fileno(stdout), _O_BINARY);
428 #endif
429 dk4gra_write_file_and_close(stdout, gra, &back, erp);
430 #if DK4_ON_WINDOWS
431 _setmode(_fileno(stdout), oldm);
432 #endif
433 }
434
435 finished:
436
437 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
438 }
439
440
441
442 void
dk4gra_page_with_flags(dk4_gra_t * gra,int flags,int * backptr,dk4_er_t * erp)443 dk4gra_page_with_flags(
444 dk4_gra_t *gra,
445 int flags,
446 int *backptr,
447 dk4_er_t *erp
448 )
449 {
450 int back = 0;
451
452 #if DK4_USE_ASSERT
453 assert(NULL != gra);
454 #endif
455 if (NULL == gra) {
456
457 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
458 goto finished;
459 }
460 gra->cur_x = 0.0;
461 gra->cur_y = 0.0;
462 if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) {
463
464 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
465 goto finished;
466 }
467 switch (gra->dr) {
468 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
469
470 back = dk4gra_eps_page(gra, flags, erp);
471 } break;
472 case DK4_GRA_DRIVER_PGF : {
473
474 back = dk4gra_pgf_page(gra, flags, erp);
475 } break;
476 default : {
477
478 back = dk4gra_pdf_page(gra, flags, erp);
479 } break;
480 }
481 finished:
482
483 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
484 }
485
486
487
488 void
dk4gra_page(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)489 dk4gra_page(
490 dk4_gra_t *gra,
491 int *backptr,
492 dk4_er_t *erp
493 )
494 {
495 #if DK4_USE_ASSERT
496 assert(NULL != gra);
497 #endif
498 dk4gra_page_with_flags(gra, gra->docfl, backptr, erp);
499 }
500
501
502
503 void
dk4gra_i_gsave(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)504 dk4gra_i_gsave(
505 dk4_gra_t *gra,
506 int *backptr,
507 dk4_er_t *erp
508 )
509 {
510 #if DK4_USE_ASSERT
511 assert(NULL != gra);
512 #endif
513 switch (gra->dr) {
514 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
515 if (0 == dk4gra_eps_gsave(gra, erp)) {
516 if (NULL != backptr) { *backptr = 0; }
517 }
518 } break;
519 case DK4_GRA_DRIVER_PGF : {
520 if (0 == dk4gra_pgf_gsave(gra, erp)) {
521 if (NULL != backptr) { *backptr = 0; }
522 }
523 } break;
524 default : {
525 if (0 == dk4gra_pdf_gsave(gra, erp)) {
526 if (NULL != backptr) { *backptr = 0; }
527 }
528 } break;
529 }
530 }
531
532
533
534 void
dk4gra_i_grestore(dk4_gra_t * gra,int res,int * backptr,dk4_er_t * erp)535 dk4gra_i_grestore(
536 dk4_gra_t *gra,
537 int res,
538 int *backptr,
539 dk4_er_t *erp
540 )
541 {
542 #if DK4_USE_ASSERT
543 assert(NULL != gra);
544 #endif
545 switch (gra->dr) {
546 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
547 if (0 == dk4gra_eps_grestore(gra, erp)) {
548 if (NULL != backptr) { *backptr = 0; }
549 }
550 } break;
551 case DK4_GRA_DRIVER_PGF : {
552 if (0 == dk4gra_pgf_grestore(gra, erp)) {
553 if (NULL != backptr) { *backptr = 0; }
554 }
555 } break;
556 default : {
557 if (0 == dk4gra_pdf_grestore(gra, erp)) {
558 if (NULL != backptr) { * backptr = 0; }
559 }
560 } break;
561 }
562 if ((0 != gra->gscp) && (0 != res)) {
563 dk4gra_i_reset_attributes(gra);
564 }
565 }
566
567
568
569 void
dk4gra_i_prepare_fill(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)570 dk4gra_i_prepare_fill(
571 dk4_gra_t *gra,
572 int *backptr,
573 dk4_er_t *erp
574 )
575 {
576 #if DK4_USE_ASSERT
577 assert(NULL != gra);
578 #endif
579 switch (gra->dr) {
580 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
581 if (0 == dk4gra_eps_prepare_fill(gra, erp)) {
582 if (NULL != backptr) { *backptr = 0; }
583 }
584 } break;
585 case DK4_GRA_DRIVER_PGF : {
586 if (0 == dk4gra_pgf_prepare_fill(gra, erp)) {
587 if (NULL != backptr) { *backptr = 0; }
588 }
589 } break;
590 default : {
591 if (0 == dk4gra_pdf_prepare_fill(gra, erp)) {
592 if (NULL != backptr) { *backptr = 0; }
593 }
594 } break;
595 }
596 }
597
598
599 void
dk4gra_i_prepare_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)600 dk4gra_i_prepare_stroke(
601 dk4_gra_t *gra,
602 int *backptr,
603 dk4_er_t *erp
604 )
605 {
606 #if DK4_USE_ASSERT
607 assert(NULL != gra);
608 #endif
609 switch (gra->dr) {
610 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
611 if (0 == dk4gra_eps_prepare_stroke(gra, erp)) {
612 if (NULL != backptr) { *backptr = 0; }
613 }
614 } break;
615 case DK4_GRA_DRIVER_PGF : {
616 if (0 == dk4gra_pgf_prepare_stroke(gra, erp)) {
617 if (NULL != backptr) { *backptr = 0; }
618 }
619 } break;
620 default : {
621 if (0 == dk4gra_pdf_prepare_stroke(gra, erp)) {
622 if (NULL != backptr) { *backptr = 0; }
623 }
624 } break;
625 }
626 }
627
628
629 void
dk4gra_i_prepare_fill_and_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)630 dk4gra_i_prepare_fill_and_stroke(
631 dk4_gra_t *gra,
632 int *backptr,
633 dk4_er_t *erp
634 )
635 {
636 #if DK4_USE_ASSERT
637 assert(NULL != gra);
638 #endif
639 switch (gra->dr) {
640 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
641 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
642 if (NULL != backptr) { *backptr = 0; }
643 } break;
644 case DK4_GRA_DRIVER_PGF : {
645 if (0 == dk4gra_pgf_prepare_fill_and_stroke(gra, erp)) {
646 if (NULL != backptr) { *backptr = 0; }
647 }
648 } break;
649 default : {
650 if (0 == dk4gra_pdf_prepare_fill_and_stroke(gra, erp)) {
651 if (NULL != backptr) { *backptr = 0; }
652 }
653 } break;
654 }
655 }
656
657
658
659 void
dk4gra_i_fill(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)660 dk4gra_i_fill(
661 dk4_gra_t *gra,
662 int *backptr,
663 dk4_er_t *erp
664 )
665 {
666 #if DK4_USE_ASSERT
667 assert(NULL != gra);
668 #endif
669 switch (gra->dr) {
670 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
671 if (0 == dk4gra_eps_fill(gra, erp)) {
672 if (NULL != backptr) { *backptr = 0; }
673 }
674 } break;
675 case DK4_GRA_DRIVER_PGF : {
676 if (0 == dk4gra_pgf_fill(gra, erp)) {
677 if (NULL != backptr) { *backptr = 0; }
678 }
679 } break;
680 default : {
681 if (0 == dk4gra_pdf_fill(gra, erp)) {
682 if (NULL != backptr) { *backptr = 0; }
683 }
684 } break;
685 }
686 }
687
688
689
690 void
dk4gra_i_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)691 dk4gra_i_stroke(
692 dk4_gra_t *gra,
693 int *backptr,
694 dk4_er_t *erp
695 )
696 {
697 #if DK4_USE_ASSERT
698 assert(NULL != gra);
699 #endif
700 switch (gra->dr) {
701 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
702 if (0 == dk4gra_eps_stroke(gra, erp)) {
703 if (NULL != backptr) { *backptr = 0; }
704 }
705 } break;
706 case DK4_GRA_DRIVER_PGF : {
707 if (0 == dk4gra_pgf_stroke(gra, erp)) {
708 if (NULL != backptr) { *backptr = 0; }
709 }
710 } break;
711 default : {
712 if (0 == dk4gra_pdf_stroke(gra, erp)) {
713 if (NULL != backptr) { *backptr = 0; }
714 }
715 } break;
716 }
717 }
718
719
720
721 void
dk4gra_i_fill_and_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)722 dk4gra_i_fill_and_stroke(
723 dk4_gra_t *gra,
724 int *backptr,
725 dk4_er_t *erp
726 )
727 {
728 #if DK4_USE_ASSERT
729 assert(NULL != gra);
730 #endif
731 switch (gra->dr) {
732 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
733 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
734 if (NULL != backptr) {*backptr = 0; }
735 } break;
736 case DK4_GRA_DRIVER_PGF : {
737 if (0 == dk4gra_pgf_fill_and_stroke(gra, erp)) {
738 if (NULL != backptr) { *backptr = 0; }
739 }
740 } break;
741 default : {
742 if (0 == dk4gra_pdf_fill_and_stroke(gra, erp)) {
743 if (NULL != backptr) {*backptr = 0; }
744 }
745 } break;
746 }
747 }
748
749
750
751 void
dk4gra_i_clip(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)752 dk4gra_i_clip(
753 dk4_gra_t *gra,
754 int *backptr,
755 dk4_er_t *erp
756 )
757 {
758 #if DK4_USE_ASSERT
759 assert(NULL != gra);
760 #endif
761 switch (gra->dr) {
762 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
763 if (0 == dk4gra_eps_clip(gra, erp)) {
764 if (NULL != backptr) { *backptr = 0; }
765 }
766 } break;
767 case DK4_GRA_DRIVER_PGF : {
768 if (0 == dk4gra_pgf_clip(gra, erp)) {
769 if (NULL != backptr) { *backptr = 0; }
770 }
771 } break;
772 default : {
773 if (0 == dk4gra_pdf_clip(gra, erp)) {
774 if (NULL != backptr) { *backptr = 0; }
775 }
776 } break;
777 }
778 }
779
780
781
782 void
dk4gra_set_eorule(dk4_gra_t * gra,int val)783 dk4gra_set_eorule(
784 dk4_gra_t *gra,
785 int val
786 )
787 {
788 #if DK4_USE_ASSERT
789 assert(NULL != gra);
790 #endif
791 if (NULL != gra) {
792 gra->eor = val;
793 }
794 }
795
796
797
798 void
dk4gra_i_newpath_moveto(dk4_gra_t * gra,double x,double y,int * backptr,dk4_er_t * erp)799 dk4gra_i_newpath_moveto(
800 dk4_gra_t *gra,
801 double x,
802 double y,
803 int *backptr,
804 dk4_er_t *erp
805 )
806 {
807
808 #if DK4_USE_ASSERT
809 assert(NULL != gra);
810 #endif
811 switch (gra->dr) {
812 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
813
814 if (0 == dk4gra_eps_newpath_moveto(gra, x, y, erp)) {
815 if (NULL != backptr) { *backptr = 0; }
816 }
817 } break;
818 case DK4_GRA_DRIVER_PGF : {
819
820 if (0 == dk4gra_pgf_newpath_moveto(gra, x, y, erp)) {
821 if (NULL != backptr) { *backptr = 0; }
822 }
823 } break;
824 default : {
825
826 if (0 == dk4gra_pdf_newpath_moveto(gra, x, y, erp)) {
827 if (NULL != backptr) { *backptr = 0; }
828 }
829 } break;
830 }
831
832 }
833
834
835
836 void
dk4gra_i_lineto(dk4_gra_t * gra,double x,double y,int * backptr,dk4_er_t * erp)837 dk4gra_i_lineto(
838 dk4_gra_t *gra,
839 double x,
840 double y,
841 int *backptr,
842 dk4_er_t *erp
843 )
844 {
845
846 #if DK4_USE_ASSERT
847 assert(NULL != gra);
848 #endif
849 switch (gra->dr) {
850 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
851 if (0 == dk4gra_eps_lineto(gra, x, y, erp)) {
852 if (NULL != backptr) { *backptr = 0; }
853 }
854 } break;
855 case DK4_GRA_DRIVER_PGF : {
856 if (0 == dk4gra_pgf_lineto(gra, x, y, erp)) {
857 if (NULL != backptr) { *backptr = 0; }
858 }
859 } break;
860 default : {
861 if (0 == dk4gra_pdf_lineto(gra, x, y, erp)) {
862 if (NULL != backptr) { *backptr = 0; }
863 }
864 } break;
865 }
866
867 }
868
869
870
871 void
dk4gra_i_curveto(dk4_gra_t * gra,double xc1,double yc1,double xc2,double yc2,double x,double y,int * backptr,dk4_er_t * erp)872 dk4gra_i_curveto(
873 dk4_gra_t *gra,
874 double xc1,
875 double yc1,
876 double xc2,
877 double yc2,
878 double x,
879 double y,
880 int *backptr,
881 dk4_er_t *erp
882 )
883 {
884
885 #if DK4_USE_ASSERT
886 assert(NULL != gra);
887 #endif
888 switch (gra->dr) {
889 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
890 if (0 == dk4gra_eps_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) {
891 if (NULL != backptr) { *backptr = 0; }
892 }
893 } break;
894 case DK4_GRA_DRIVER_PGF : {
895 if (0 == dk4gra_pgf_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) {
896 if (NULL != backptr) { *backptr = 0; }
897 }
898 } break;
899 default : {
900 if (0 == dk4gra_pdf_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) {
901 if (NULL != backptr) { *backptr = 0; }
902 }
903 } break;
904 }
905
906 }
907
908
909
910 void
dk4gra_i_closepath(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)911 dk4gra_i_closepath(
912 dk4_gra_t *gra,
913 int *backptr,
914 dk4_er_t *erp
915 )
916 {
917
918 #if DK4_USE_ASSERT
919 assert(NULL != gra);
920 #endif
921 switch (gra->dr) {
922 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
923 if (0 == dk4gra_eps_closepath(gra, erp)) {
924 if (NULL != backptr) { *backptr = 0; }
925 }
926 } break;
927 case DK4_GRA_DRIVER_PGF : {
928 if (0 == dk4gra_pgf_closepath(gra, erp)) {
929 if (NULL != backptr) { *backptr = 0; }
930 }
931 } break;
932 default : {
933 if (0 == dk4gra_pdf_closepath(gra, erp)) {
934 if (NULL != backptr) { *backptr = 0; }
935 }
936 } break;
937 }
938
939 }
940
941
942
943 void
dk4gra_i_ellipse(dk4_gra_t * gra,double xc,double yc,double rx,double ry,double rot,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)944 dk4gra_i_ellipse(
945 dk4_gra_t *gra,
946 double xc,
947 double yc,
948 double rx,
949 double ry,
950 double rot,
951 dk4_bb_t *bbptr,
952 int *backptr,
953 dk4_er_t *erp
954 )
955 {
956 dk4_gra_point_t points[DK4_GRA_CIRCLE_POINTS]; /* Points for circle */
957 size_t i; /* Index of current point */
958 size_t c1; /* Index of first control point after point */
959 size_t c2; /* Index of second control point after point */
960 size_t c3; /* Index of third control point after point */
961 #if DK4_USE_ASSERT
962 assert(NULL != gra);
963 #endif
964
965 /* 2017-10-31
966 The TikZ and PGF manual explains that the pgfpathellipse command will
967 apply coordinate transformations to all coordinates.
968 So better calculate the curve ourselves.
969 */
970
971 if ( 0 == dk4gratool_points_for_ellipse(
972 points, DK4_GRA_CIRCLE_POINTS, xc, yc, rx, ry, rot, erp
973 )
974 ) {
975 if (NULL != backptr) { *backptr = 0; }
976 goto finished;
977 }
978 /* Construct path as cycle of Bezier segments
979 */
980 for (i = 0; i < ((DK4_GRA_CIRCLE_POINTS) / 3); i++) {
981 if (0 == i) {
982 dk4gra_i_newpath_moveto(gra,points[0].x,points[0].y,backptr,erp);
983 }
984 c1 = 3 * i + 1;
985 c2 = 3 * i + 2;
986 c3 = 3 * i + 3;
987 if (DK4_GRA_CIRCLE_POINTS <= c3) { c3 = 0; }
988 dk4gra_i_curveto(
989 gra, points[c1].x, points[c1].y,
990 points[c2].x, points[c2].y, points[c3].x, points[c3].y, backptr, erp
991 );
992 }
993 dk4gra_i_closepath(gra, backptr, erp);
994 if (NULL != bbptr) {
995 for (i = 0; i < ((DK4_GRA_CIRCLE_POINTS) / 3); i++) {
996 c1 = 3 * i + 1;
997 c2 = 3 * i + 2;
998 c3 = 3 * i + 3;
999 if (DK4_GRA_CIRCLE_POINTS <= c3) { c3 = 0; }
1000 dk4bb_add_bezier(
1001 bbptr,
1002 points[i].x, points[i].y, points[c1].x, points[c1].y,
1003 points[c2].x, points[c2].y, points[c3].x, points[c3].y
1004 );
1005 }
1006
1007
1008
1009
1010
1011 dk4bb_add_rotated_ellipse(bbptr, xc, yc, rx, ry, rot);
1012
1013
1014
1015
1016
1017 }
1018
1019 finished:
1020 return;
1021 }
1022
1023
1024
1025 void
dk4gra_i_circle(dk4_gra_t * gra,double xc,double yc,double r,int * backptr,dk4_er_t * erp)1026 dk4gra_i_circle(
1027 dk4_gra_t *gra,
1028 double xc,
1029 double yc,
1030 double r,
1031 int *backptr,
1032 dk4_er_t *erp
1033 )
1034 {
1035
1036 #if DK4_USE_ASSERT
1037 assert(NULL != gra);
1038 #endif
1039 switch (gra->dr) {
1040 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1041 if (0 == dk4gra_eps_circle(gra, xc, yc, r, erp)) {
1042 if (NULL != backptr) { *backptr = 0; }
1043 }
1044 } break;
1045 case DK4_GRA_DRIVER_PGF : {
1046 if (0 == dk4gra_pgf_circle(gra, xc, yc, r, erp)) {
1047 if (NULL != backptr) { *backptr = 0; }
1048 }
1049 } break;
1050 default : {
1051 dk4gra_i_ellipse(gra, xc, yc, r, r, 0.0, NULL, backptr, erp);
1052 } break;
1053 }
1054
1055 }
1056
1057
1058
1059 void
dk4gra_i_rectangle(dk4_gra_t * gra,double xl,double xr,double yb,double yt,double r,int * backptr,dk4_er_t * erp)1060 dk4gra_i_rectangle(
1061 dk4_gra_t *gra,
1062 double xl,
1063 double xr,
1064 double yb,
1065 double yt,
1066 double r,
1067 int *backptr,
1068 dk4_er_t *erp
1069 )
1070 {
1071 double dx; /* Width */
1072 double dy; /* Height */
1073 double xc1; /* Control point coordinates for rounded corners */
1074 double yc1;
1075 double xc2;
1076 double yc2;
1077
1078 #if DK4_USE_ASSERT
1079 assert(NULL != gra);
1080 #endif
1081
1082
1083
1084 if (0.0 < r) {
1085 dx = xr - xl;
1086 dy = yt - yb;
1087 dx = 0.4999 * fabs(dx);
1088 dy = 0.4999 * fabs(dy);
1089 if (r > dx) {
1090 r = dx;
1091 #if 0
1092 /* Silently correct radius
1093 */
1094 if (NULL != backptr) {
1095 *backptr = 0;
1096 }
1097 #endif
1098 }
1099 if (r > dy) {
1100 r = dy;
1101 #if 0
1102 /* Silently correct radius
1103 */
1104 if (NULL != backptr) {
1105 *backptr = 0;
1106 }
1107 #endif
1108 }
1109 }
1110 switch (gra->dr) {
1111 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1112 if (0 == dk4gra_eps_rectangle(gra, xl, xr, yb, yt, r, erp)) {
1113 if (NULL != backptr) {
1114 *backptr = 0;
1115 }
1116 }
1117 } break;
1118 case DK4_GRA_DRIVER_PGF : {
1119 if (0 == dk4gra_pgf_rectangle(gra, xl, xr, yb, yt, r, erp)) {
1120 if (NULL != backptr) {
1121 *backptr = 0;
1122 }
1123 }
1124 } break;
1125 default : {
1126 if (0.0 >= r) {
1127 dk4gra_i_newpath_moveto(gra, xl, yb, backptr, erp);
1128 dk4gra_i_lineto(gra, xr, yb, backptr, erp);
1129 dk4gra_i_lineto(gra, xr, yt, backptr, erp);
1130 dk4gra_i_lineto(gra, xl, yt, backptr, erp);
1131 dk4gra_i_closepath(gra, backptr, erp);
1132 }
1133 else {
1134 dk4gra_i_newpath_moveto(gra, (xl + r), yb, backptr, erp);
1135 dk4gra_i_lineto(gra, (xr - r), yb, backptr, erp);
1136 xc1 = xr - (1.0 - KAPPA_4) * r;
1137 yc1 = yb;
1138 xc2 = xr;
1139 yc2 = yb + (1.0 - KAPPA_4) * r;
1140 dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,xr,(yb+r),backptr,erp);
1141 dk4gra_i_lineto(gra, xr, (yt - r), backptr, erp);
1142 xc1 = xr;
1143 yc1 = yt - (1.0 - KAPPA_4) * r;
1144 xc2 = xr - (1.0 - KAPPA_4) * r;
1145 yc2 = yt;
1146 dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,(xr-r),yt,backptr,erp);
1147 dk4gra_i_lineto(gra, (xl+r), yt, backptr, erp);
1148 xc1 = xl + (1.0 - KAPPA_4) * r;
1149 yc1 = yt;
1150 xc2 = xl;
1151 yc2 = yt - (1.0 - KAPPA_4) * r;
1152 dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,xl,(yt-r),backptr,erp);
1153 dk4gra_i_lineto(gra, xl, (yb + r), backptr, erp);
1154 xc1 = xl;
1155 yc1 = yb + (1.0 - KAPPA_4) * r;
1156 xc2 = xl + (1.0 - KAPPA_4) * r;
1157 yc2 = yb;
1158 dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,(xl+r),yb,backptr,erp);
1159 dk4gra_i_closepath(gra, backptr, erp);
1160 }
1161 } break;
1162 }
1163
1164 }
1165
1166
1167
1168 void
dk4gra_i_arc(dk4_gra_t * gra,double xc,double yc,double ra,double start,double end,int cl,int * backptr,dk4_er_t * erp)1169 dk4gra_i_arc(
1170 dk4_gra_t *gra,
1171 double xc,
1172 double yc,
1173 double ra,
1174 double start,
1175 double end,
1176 int cl,
1177 int *backptr,
1178 dk4_er_t *erp
1179 )
1180 {
1181 double angdiff; /* Angle difference end - start */
1182 double x0; /* Start of current arc segment */
1183 double y0; /* Start of current arc segment */
1184 double dxdt0; /* First x derivative at start */
1185 double dydt0; /* First y derivative at start */
1186 double x1; /* End of current arg segment */
1187 double y1; /* End of current arg segment */
1188 double dxdt1; /* First x derivative at end */
1189 double dydt1; /* First y derivative at end */
1190 double segcalc; /* Number of segments */
1191 double seglgt; /* Angle per segment */
1192 double kappa; /* Kappa value */
1193 double segend; /* Angle at end of segment */
1194 size_t segments; /* Number of segments */
1195 size_t i; /* Current segment to draw */
1196
1197 #if DK4_USE_ASSERT
1198 assert(NULL != gra);
1199 #endif
1200 switch (gra->dr) {
1201 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1202 if (0 == dk4gra_eps_arc(gra, xc, yc, ra, start, end, cl, erp)) {
1203 if (NULL != backptr) { *backptr = 0; }
1204 }
1205 } break;
1206 /* 2017-10-31
1207 The TikZ and PGF manual warns the computation done by the
1208 pgfpatharcto command are numerically very unstable and the arc
1209 will not necessary end at the intended end point.
1210 So we do not use that command and do the necessary calculations
1211 ourselves in the default branch.
1212 */
1213 default : {
1214 start *= M_PI;
1215 end *= M_PI;
1216 start /= 180.0;
1217 end /= 180.0;
1218 angdiff = end - start;
1219 segcalc = angdiff * 4.0 / M_PI;
1220 segments = (size_t)ceil(segcalc);
1221 seglgt = angdiff / (double)segments;
1222 kappa = dk4gratool_kappa_for_angle(seglgt);
1223 x0 = xc + ra * cos(start);
1224 y0 = yc + ra * sin(start);
1225 dxdt0 = -1.0 * ra * seglgt * sin(start);
1226 dydt0 = ra * seglgt * cos(start);
1227 dk4gra_i_newpath_moveto(gra, x0, y0, backptr, erp);
1228 for (i = 0; i < segments; i++) {
1229 segend = start + angdiff * (double)(i + 1) / (double)segments;
1230 x1 = xc + ra * cos(segend);
1231 y1 = yc + ra * sin(segend);
1232 dxdt1 = -1.0 * ra * seglgt * sin(segend);
1233 dydt1 = ra * seglgt * cos(segend);
1234 dk4gra_i_curveto(gra,
1235 x0 + kappa * dxdt0,
1236 y0 + kappa * dydt0,
1237 x1 - kappa * dxdt1,
1238 y1 - kappa * dydt1,
1239 x1,
1240 y1,
1241 backptr, erp
1242 );
1243 x0 = x1;
1244 y0 = y1;
1245 dxdt0 = dxdt1;
1246 dydt0 = dydt1;
1247 }
1248 if (0 != cl) {
1249 dk4gra_i_lineto(gra, xc, yc, backptr, erp);
1250 dk4gra_i_closepath(gra, backptr, erp);
1251 }
1252 } break;
1253 }
1254
1255 }
1256
1257
1258 void
dk4gra_gsave(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1259 dk4gra_gsave(
1260 dk4_gra_t *gra,
1261 int *backptr,
1262 dk4_er_t *erp
1263 )
1264 {
1265 int back = 0;
1266
1267 #if DK4_USE_ASSERT
1268 assert(NULL != gra);
1269 #endif
1270 if (NULL == gra) {
1271 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1272 goto finished;
1273 }
1274 if (NULL == gra->curpg) {
1275 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1276 goto finished;
1277 }
1278 back = 1;
1279 dk4gra_i_gsave(gra, &back, erp);
1280
1281 finished:
1282
1283 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1284 }
1285
1286
1287
1288 void
dk4gra_grestore(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1289 dk4gra_grestore(
1290 dk4_gra_t *gra,
1291 int *backptr,
1292 dk4_er_t *erp
1293 )
1294 {
1295 int back = 0;
1296
1297 #if DK4_USE_ASSERT
1298 assert(NULL != gra);
1299 #endif
1300 if (NULL == gra) {
1301 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1302 goto finished;
1303 }
1304 if (NULL == gra->curpg) {
1305 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1306 goto finished;
1307 }
1308 back = 1;
1309 dk4gra_i_grestore(gra, 1, &back, erp);
1310
1311 finished:
1312
1313 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1314 }
1315
1316
1317
1318 void
dk4gra_set_gs_for_pattern_only(dk4_gra_t * gra,int val,dk4_er_t * erp)1319 dk4gra_set_gs_for_pattern_only(
1320 dk4_gra_t *gra,
1321 int val,
1322 dk4_er_t *erp
1323 )
1324 {
1325 #if DK4_USE_ASSERT
1326 assert(NULL != gra);
1327 #endif
1328 if (NULL != gra) {
1329 gra->gscp = ((0 != val) ? (1) : (0));
1330 }
1331 else {
1332 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1333 }
1334 }
1335
1336
1337
1338 void
dk4gra_set_line_width(dk4_gra_t * gra,double lw,int * backptr,dk4_er_t * erp)1339 dk4gra_set_line_width(
1340 dk4_gra_t *gra,
1341 double lw,
1342 int *backptr,
1343 dk4_er_t *erp
1344 )
1345 {
1346 int back = 0;
1347
1348 #if DK4_USE_ASSERT
1349 assert(NULL != gra);
1350 #endif
1351 if (NULL == gra) {
1352 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1353 goto finished;
1354 }
1355 if (NULL == gra->curpg) {
1356 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1357 goto finished;
1358 }
1359 switch (gra->dr) {
1360 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1361 back = dk4gra_eps_set_line_width(gra, lw, erp);
1362 } break;
1363 case DK4_GRA_DRIVER_PGF : {
1364 back = dk4gra_pgf_set_line_width(gra, lw, erp);
1365 } break;
1366 default : {
1367 back = dk4gra_pdf_set_line_width(gra, lw, erp);
1368 } break;
1369 }
1370 finished:
1371
1372 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1373 }
1374
1375
1376
1377 void
dk4gra_set_line_style(dk4_gra_t * gra,dk4_gra_ls_t ls,double sv,int * backptr,dk4_er_t * erp)1378 dk4gra_set_line_style(
1379 dk4_gra_t *gra,
1380 dk4_gra_ls_t ls,
1381 double sv,
1382 int *backptr,
1383 dk4_er_t *erp
1384 )
1385 {
1386 int back = 0;
1387
1388 #if DK4_USE_ASSERT
1389 assert(NULL != gra);
1390 #endif
1391 if (NULL == gra) {
1392 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1393 goto finished;
1394 }
1395 if (NULL == gra->curpg) {
1396 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1397 goto finished;
1398 }
1399 switch (gra->dr) {
1400 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1401 back = dk4gra_eps_set_line_style(gra, ls, sv, erp);
1402 } break;
1403 case DK4_GRA_DRIVER_PGF : {
1404 back = dk4gra_pgf_set_line_style(gra, ls, sv, erp);
1405 } break;
1406 default : {
1407 back = dk4gra_pdf_set_line_style(gra, ls, sv, erp);
1408 } break;
1409 }
1410 finished:
1411
1412 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1413 }
1414
1415
1416
1417 void
dk4gra_set_line_cap(dk4_gra_t * gra,dk4_gra_lc_t lc,int * backptr,dk4_er_t * erp)1418 dk4gra_set_line_cap(
1419 dk4_gra_t *gra,
1420 dk4_gra_lc_t lc,
1421 int *backptr,
1422 dk4_er_t *erp
1423 )
1424 {
1425 int back = 0;
1426
1427 #if DK4_USE_ASSERT
1428 assert(NULL != gra);
1429 #endif
1430 if (NULL == gra) {
1431 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1432 goto finished;
1433 }
1434 if (NULL == gra->curpg) {
1435 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1436 goto finished;
1437 }
1438 switch (gra->dr) {
1439 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1440 back = dk4gra_eps_set_line_cap(gra, lc, erp);
1441 } break;
1442 case DK4_GRA_DRIVER_PGF : {
1443 back = dk4gra_pgf_set_line_cap(gra, lc, erp);
1444 } break;
1445 default : {
1446 back = dk4gra_pdf_set_line_cap(gra, lc, erp);
1447 } break;
1448 }
1449 finished:
1450
1451 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1452 }
1453
1454
1455
1456 void
dk4gra_set_line_join(dk4_gra_t * gra,dk4_gra_lj_t lj,double ml,int * backptr,dk4_er_t * erp)1457 dk4gra_set_line_join(
1458 dk4_gra_t *gra,
1459 dk4_gra_lj_t lj,
1460 double ml,
1461 int *backptr,
1462 dk4_er_t *erp
1463 )
1464 {
1465 int back = 0;
1466
1467 #if DK4_USE_ASSERT
1468 assert(NULL != gra);
1469 #endif
1470 if (NULL == gra) {
1471 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1472 goto finished;
1473 }
1474 if (NULL == gra->curpg) {
1475 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1476 goto finished;
1477 }
1478 switch (gra->dr) {
1479 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1480 back = dk4gra_eps_set_line_join(gra, lj, ml, erp);
1481 } break;
1482 case DK4_GRA_DRIVER_PGF : {
1483 back = dk4gra_pgf_set_line_join(gra, lj, ml, erp);
1484 } break;
1485 default : {
1486 back = dk4gra_pdf_set_line_join(gra, lj, ml, erp);
1487 } break;
1488 }
1489 finished:
1490
1491 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1492 }
1493
1494
1495
1496 void
dk4gra_set_fill_gray(dk4_gra_t * gra,double g,int * backptr,dk4_er_t * erp)1497 dk4gra_set_fill_gray(
1498 dk4_gra_t *gra,
1499 double g,
1500 int *backptr,
1501 dk4_er_t *erp
1502 )
1503 {
1504 int back = 0;
1505
1506 #if DK4_USE_ASSERT
1507 assert(NULL != gra);
1508 #endif
1509 if (NULL == gra) {
1510 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1511 goto finished;
1512 }
1513 if (NULL == gra->curpg) {
1514 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1515 goto finished;
1516 }
1517 g = dk4gra_i_to_range(g, 0.0, 1.0);
1518 switch (gra->dr) {
1519 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1520 back = dk4gra_eps_set_fill_gray(gra, g, erp);
1521 } break;
1522 case DK4_GRA_DRIVER_PGF : {
1523 back = dk4gra_pgf_set_fill_gray(gra, g, erp);
1524 } break;
1525 default : {
1526 back = dk4gra_pdf_set_fill_gray(gra, g, erp);
1527 } break;
1528 }
1529 finished:
1530
1531 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1532 }
1533
1534
1535
1536 void
dk4gra_set_fill_rgb(dk4_gra_t * gra,double r,double g,double b,int * backptr,dk4_er_t * erp)1537 dk4gra_set_fill_rgb(
1538 dk4_gra_t *gra,
1539 double r,
1540 double g,
1541 double b,
1542 int *backptr,
1543 dk4_er_t *erp
1544 )
1545 {
1546 double array1[4];
1547 double array2[4];
1548 double array3[4];
1549 size_t i;
1550 int back = 0;
1551
1552 #if DK4_USE_ASSERT
1553 assert(NULL != gra);
1554 #endif
1555 if (NULL == gra) {
1556 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1557 goto finished;
1558 }
1559 if (NULL == gra->curpg) {
1560 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1561 goto finished;
1562 }
1563 r = dk4gra_i_to_range(r, 0.0, 1.0);
1564 g = dk4gra_i_to_range(g, 0.0, 1.0);
1565 b = dk4gra_i_to_range(b, 0.0, 1.0);
1566 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
1567 for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; }
1568 array1[0] = r; array1[1] = g; array1[2] = b;
1569 dk4cs_color_convert(
1570 array2, DK4_CS_GRAY, 4, array1, DK4_CS_RGB, 3,
1571 array3, 3, &(gra->cscctx), erp
1572 );
1573 array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0);
1574 switch (gra->dr) {
1575 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1576 back = dk4gra_eps_set_fill_gray(gra, array2[0], erp);
1577 } break;
1578 case DK4_GRA_DRIVER_PGF : {
1579 back = dk4gra_pgf_set_fill_gray(gra, array2[0], erp);
1580 } break;
1581 default : {
1582 back = dk4gra_pdf_set_fill_gray(gra, array2[0], erp);
1583 } break;
1584 }
1585 }
1586 else {
1587 switch (gra->dr) {
1588 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1589 back = dk4gra_eps_set_fill_rgb(gra, r, g, b, erp);
1590 } break;
1591 case DK4_GRA_DRIVER_PGF : {
1592 back = dk4gra_pgf_set_fill_rgb(gra, r, g, b, erp);
1593 } break;
1594 default : {
1595 back = dk4gra_pdf_set_fill_rgb(gra, r, g, b, erp);
1596 } break;
1597 }
1598 }
1599
1600 finished:
1601
1602 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1603 }
1604
1605
1606
1607 void
dk4gra_set_fill_cmyk(dk4_gra_t * gra,double c,double m,double y,double k,int * backptr,dk4_er_t * erp)1608 dk4gra_set_fill_cmyk(
1609 dk4_gra_t *gra,
1610 double c,
1611 double m,
1612 double y,
1613 double k,
1614 int *backptr,
1615 dk4_er_t *erp
1616 )
1617 {
1618 double array1[4];
1619 double array2[4];
1620 double array3[4];
1621 size_t i;
1622 int back = 0;
1623
1624 #if DK4_USE_ASSERT
1625 assert(NULL != gra);
1626 #endif
1627 if (NULL == gra) {
1628 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1629 goto finished;
1630 }
1631 if (NULL == gra->curpg) {
1632 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1633 goto finished;
1634 }
1635 c = dk4gra_i_to_range(c, 0.0, 1.0);
1636 m = dk4gra_i_to_range(m, 0.0, 1.0);
1637 y = dk4gra_i_to_range(y, 0.0, 1.0);
1638 k = dk4gra_i_to_range(k, 0.0, 1.0);
1639 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
1640 for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; }
1641 array1[0] = c; array1[1] = m; array1[2] = y; array1[3] = k;
1642 dk4cs_color_convert(
1643 array2, DK4_CS_GRAY, 4, array1, DK4_CS_CMYK, 4,
1644 array3, 4, &(gra->cscctx), erp
1645 );
1646 array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0);
1647 switch (gra->dr) {
1648 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1649 back = dk4gra_eps_set_fill_gray(gra, array2[0], erp);
1650 } break;
1651 case DK4_GRA_DRIVER_PGF : {
1652 back = dk4gra_pgf_set_fill_gray(gra, array2[0], erp);
1653 } break;
1654 default : {
1655 back = dk4gra_pdf_set_fill_gray(gra, array2[0], erp);
1656 } break;
1657 }
1658 }
1659 else {
1660 switch (gra->dr) {
1661 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1662 back = dk4gra_eps_set_fill_cmyk(gra, c, m, y, k, erp);
1663 } break;
1664 case DK4_GRA_DRIVER_PGF : {
1665 back = dk4gra_pgf_set_fill_cmyk(gra, c, m, y, k, erp);
1666 } break;
1667 default : {
1668 back = dk4gra_pdf_set_fill_cmyk(gra, c, m, y, k, erp);
1669 } break;
1670 }
1671 }
1672
1673 finished:
1674
1675 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1676 }
1677
1678
1679
1680 void
dk4gra_set_stroke_gray(dk4_gra_t * gra,double g,int * backptr,dk4_er_t * erp)1681 dk4gra_set_stroke_gray(
1682 dk4_gra_t *gra,
1683 double g,
1684 int *backptr,
1685 dk4_er_t *erp
1686 )
1687 {
1688 int back = 0;
1689
1690 #if DK4_USE_ASSERT
1691 assert(NULL != gra);
1692 #endif
1693 if (NULL == gra) {
1694 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1695 goto finished;
1696 }
1697 if (NULL == gra->curpg) {
1698 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1699 goto finished;
1700 }
1701 g = dk4gra_i_to_range(g, 0.0, 1.0);
1702 switch (gra->dr) {
1703 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1704 back = dk4gra_eps_set_stroke_gray(gra, g, erp);
1705 } break;
1706 case DK4_GRA_DRIVER_PGF : {
1707 back = dk4gra_pgf_set_stroke_gray(gra, g, erp);
1708 } break;
1709 default : {
1710 back = dk4gra_pdf_set_stroke_gray(gra, g, erp);
1711 } break;
1712 }
1713 finished:
1714
1715 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1716 }
1717
1718
1719
1720 void
dk4gra_set_stroke_rgb(dk4_gra_t * gra,double r,double g,double b,int * backptr,dk4_er_t * erp)1721 dk4gra_set_stroke_rgb(
1722 dk4_gra_t *gra,
1723 double r,
1724 double g,
1725 double b,
1726 int *backptr,
1727 dk4_er_t *erp
1728 )
1729 {
1730 double array1[4];
1731 double array2[4];
1732 double array3[4];
1733 size_t i;
1734 int back = 0;
1735
1736 #if DK4_USE_ASSERT
1737 assert(NULL != gra);
1738 #endif
1739 if (NULL == gra) {
1740 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1741 goto finished;
1742 }
1743 if (NULL == gra->curpg) {
1744 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1745 goto finished;
1746 }
1747 r = dk4gra_i_to_range(r, 0.0, 1.0);
1748 g = dk4gra_i_to_range(g, 0.0, 1.0);
1749 b = dk4gra_i_to_range(b, 0.0, 1.0);
1750 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
1751 /*
1752 Force gray
1753 */
1754 for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; }
1755 array1[0] = r; array1[1] = g; array1[2] = b;
1756 dk4cs_color_convert(
1757 array2, DK4_CS_GRAY, 4, array1, DK4_CS_RGB, 3,
1758 array3, 3, &(gra->cscctx), erp
1759 );
1760 array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0);
1761 switch (gra->dr) {
1762 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1763 back = dk4gra_eps_set_stroke_gray(gra, array2[0], erp);
1764 } break;
1765 case DK4_GRA_DRIVER_PGF : {
1766 back = dk4gra_pgf_set_stroke_gray(gra, array2[0], erp);
1767 } break;
1768 default : {
1769 back = dk4gra_pdf_set_stroke_gray(gra, array2[0], erp);
1770 } break;
1771 }
1772 }
1773 else {
1774 /*
1775 RGB allowed
1776 */
1777 switch (gra->dr) {
1778 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1779 back = dk4gra_eps_set_stroke_rgb(gra, r, g, b, erp);
1780 } break;
1781 case DK4_GRA_DRIVER_PGF : {
1782 back = dk4gra_pgf_set_stroke_rgb(gra, r, g, b, erp);
1783 } break;
1784 default : {
1785 back = dk4gra_pdf_set_stroke_rgb(gra, r, g, b, erp);
1786 } break;
1787 }
1788 }
1789
1790 finished:
1791
1792 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1793 }
1794
1795
1796
1797 void
dk4gra_set_stroke_cmyk(dk4_gra_t * gra,double c,double m,double y,double k,int * backptr,dk4_er_t * erp)1798 dk4gra_set_stroke_cmyk(
1799 dk4_gra_t *gra,
1800 double c,
1801 double m,
1802 double y,
1803 double k,
1804 int *backptr,
1805 dk4_er_t *erp
1806 )
1807 {
1808 double array1[4];
1809 double array2[4];
1810 double array3[4];
1811 size_t i;
1812 int back = 0;
1813
1814 #if DK4_USE_ASSERT
1815 assert(NULL != gra);
1816 #endif
1817 if (NULL == gra) {
1818 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1819 goto finished;
1820 }
1821 if (NULL == gra->curpg) {
1822 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1823 goto finished;
1824 }
1825 c = dk4gra_i_to_range(c, 0.0, 1.0);
1826 m = dk4gra_i_to_range(m, 0.0, 1.0);
1827 y = dk4gra_i_to_range(y, 0.0, 1.0);
1828 k = dk4gra_i_to_range(k, 0.0, 1.0);
1829 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
1830 /*
1831 Force gray
1832 */
1833 for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; }
1834 array1[0] = c; array1[1] = m; array1[2] = y; array1[3] = k;
1835 dk4cs_color_convert(
1836 array2, DK4_CS_GRAY, 4, array1, DK4_CS_CMYK, 3,
1837 array3, 3, &(gra->cscctx), erp
1838 );
1839 array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0);
1840 switch (gra->dr) {
1841 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1842 back = dk4gra_eps_set_stroke_gray(gra, array2[0], erp);
1843 } break;
1844 case DK4_GRA_DRIVER_PGF : {
1845 back = dk4gra_pgf_set_stroke_gray(gra, array2[0], erp);
1846 } break;
1847 default : {
1848 back = dk4gra_pdf_set_stroke_gray(gra, array2[0], erp);
1849 } break;
1850 }
1851 }
1852 else {
1853 /*
1854 CMYK allowed
1855 */
1856 switch (gra->dr) {
1857 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1858 back = dk4gra_eps_set_stroke_cmyk(gra, c, m, y, k, erp);
1859 } break;
1860 case DK4_GRA_DRIVER_PGF : {
1861 back = dk4gra_pgf_set_stroke_cmyk(gra, c, m, y, k, erp);
1862 } break;
1863 default : {
1864 back = dk4gra_pdf_set_stroke_cmyk(gra, c, m, y, k, erp);
1865 } break;
1866 }
1867 }
1868
1869 finished:
1870
1871 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1872 }
1873
1874
1875
1876
1877 void
dk4gra_prepare_fill(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1878 dk4gra_prepare_fill(
1879 dk4_gra_t *gra,
1880 int *backptr,
1881 dk4_er_t *erp
1882 )
1883 {
1884 int back = 0;
1885
1886 #if DK4_USE_ASSERT
1887 assert(NULL != gra);
1888 #endif
1889 if (NULL == gra) {
1890 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1891 goto finished;
1892 }
1893 if (NULL == gra->curpg) {
1894 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1895 goto finished;
1896 }
1897 back = 1;
1898 dk4gra_i_prepare_fill(gra, &back, erp);
1899
1900 finished:
1901
1902 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1903 }
1904
1905
1906
1907 void
dk4gra_prepare_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1908 dk4gra_prepare_stroke(
1909 dk4_gra_t *gra,
1910 int *backptr,
1911 dk4_er_t *erp
1912 )
1913 {
1914 int back = 0;
1915
1916 #if DK4_USE_ASSERT
1917 assert(NULL != gra);
1918 #endif
1919 if (NULL == gra) {
1920 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1921 goto finished;
1922 }
1923 if (NULL == gra->curpg) {
1924 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1925 goto finished;
1926 }
1927 back = 1;
1928 dk4gra_i_prepare_stroke(gra, &back, erp);
1929
1930 finished:
1931
1932 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1933 }
1934
1935
1936
1937 void
dk4gra_prepare_fill_and_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1938 dk4gra_prepare_fill_and_stroke(
1939 dk4_gra_t *gra,
1940 int *backptr,
1941 dk4_er_t *erp
1942 )
1943 {
1944 int back = 0;
1945
1946 #if DK4_USE_ASSERT
1947 assert(NULL != gra);
1948 #endif
1949 if (NULL == gra) {
1950 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1951 goto finished;
1952 }
1953 if (NULL == gra->curpg) {
1954 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1955 goto finished;
1956 }
1957 back = 1;
1958 dk4gra_i_prepare_fill_and_stroke(gra, &back, erp);
1959
1960 finished:
1961
1962 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
1963 }
1964
1965
1966
1967 int
dk4gra_can_fill_and_stroke(const dk4_gra_t * gra)1968 dk4gra_can_fill_and_stroke(
1969 const dk4_gra_t *gra
1970 )
1971 {
1972 int back = 0;
1973
1974 #if DK4_USE_ASSERT
1975 assert(NULL != gra);
1976 #endif
1977 switch (gra->dr) {
1978 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
1979 back = 0;
1980 } break;
1981 case DK4_GRA_DRIVER_PGF : {
1982 back = 1;
1983 } break;
1984 default : {
1985 back = 1;
1986 } break;
1987 }
1988
1989 return back;
1990 }
1991
1992
1993
1994 void
dk4gra_fill(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)1995 dk4gra_fill(
1996 dk4_gra_t *gra,
1997 int *backptr,
1998 dk4_er_t *erp
1999 )
2000 {
2001 int back = 0;
2002
2003 #if DK4_USE_ASSERT
2004 assert(NULL != gra);
2005 #endif
2006 if (NULL == gra) {
2007 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2008 goto finished;
2009 }
2010 if (NULL == gra->curpg) {
2011 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2012 goto finished;
2013 }
2014 back = 1;
2015 dk4gra_i_fill(gra, &back, erp);
2016
2017 finished:
2018
2019 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2020 }
2021
2022
2023
2024 void
dk4gra_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)2025 dk4gra_stroke(
2026 dk4_gra_t *gra,
2027 int *backptr,
2028 dk4_er_t *erp
2029 )
2030 {
2031 int back = 0;
2032
2033 #if DK4_USE_ASSERT
2034 assert(NULL != gra);
2035 #endif
2036 if (NULL == gra) {
2037 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2038 goto finished;
2039 }
2040 if (NULL == gra->curpg) {
2041 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2042 goto finished;
2043 }
2044 back = 1;
2045 dk4gra_i_stroke(gra, &back, erp);
2046
2047 finished:
2048
2049 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2050 }
2051
2052
2053
2054 void
dk4gra_fill_and_stroke(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)2055 dk4gra_fill_and_stroke(
2056 dk4_gra_t *gra,
2057 int *backptr,
2058 dk4_er_t *erp
2059 )
2060 {
2061 int back = 0;
2062
2063 #if DK4_USE_ASSERT
2064 assert(NULL != gra);
2065 #endif
2066 if (NULL == gra) {
2067 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2068 goto finished;
2069 }
2070 if (NULL == gra->curpg) {
2071 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2072 goto finished;
2073 }
2074 back = 1;
2075 dk4gra_i_fill_and_stroke(gra, &back, erp);
2076
2077 finished:
2078
2079 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2080 }
2081
2082
2083
2084 void
dk4gra_clip(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)2085 dk4gra_clip(
2086 dk4_gra_t *gra,
2087 int *backptr,
2088 dk4_er_t *erp
2089 )
2090 {
2091 int back = 0;
2092
2093 #if DK4_USE_ASSERT
2094 assert(NULL != gra);
2095 #endif
2096 if (NULL == gra) {
2097 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2098 goto finished;
2099 }
2100 if (NULL == gra->curpg) {
2101 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2102 goto finished;
2103 }
2104 back = 1;
2105 dk4gra_i_clip(gra, &back, erp);
2106
2107 finished:
2108
2109 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2110 }
2111
2112
2113
2114 void
dk4gra_newpath_moveto(dk4_gra_t * gra,double x,double y,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2115 dk4gra_newpath_moveto(
2116 dk4_gra_t *gra,
2117 double x,
2118 double y,
2119 dk4_bb_t *bbptr,
2120 int *backptr,
2121 dk4_er_t *erp
2122 )
2123 {
2124 int back = 0;
2125
2126 #if DK4_USE_ASSERT
2127 assert(NULL != gra);
2128 #endif
2129 if (NULL == gra) {
2130 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2131 goto finished;
2132 }
2133 gra->cur_x = x;
2134 gra->cur_y = y;
2135 if (NULL != bbptr) {
2136 dk4bb_add_x(bbptr, x);
2137 dk4bb_add_y(bbptr, y);
2138 }
2139 if (NULL == gra->curpg) {
2140 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2141 goto finished;
2142 }
2143 back = 1;
2144 dk4gra_i_newpath_moveto(gra, x, y, &back, erp);
2145 finished:
2146
2147 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2148 }
2149
2150
2151
2152 void
dk4gra_lineto(dk4_gra_t * gra,double x,double y,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2153 dk4gra_lineto(
2154 dk4_gra_t *gra,
2155 double x,
2156 double y,
2157 dk4_bb_t *bbptr,
2158 int *backptr,
2159 dk4_er_t *erp
2160 )
2161 {
2162 int back = 0;
2163
2164 #if DK4_USE_ASSERT
2165 assert(NULL != gra);
2166 #endif
2167 if (NULL == gra) {
2168 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2169 goto finished;
2170 }
2171 gra->cur_x = x;
2172 gra->cur_y = y;
2173 if (NULL != bbptr) {
2174 dk4bb_add_x(bbptr, x);
2175 dk4bb_add_y(bbptr, y);
2176 }
2177 if (NULL == gra->curpg) {
2178 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2179 goto finished;
2180 }
2181 back = 1;
2182 dk4gra_i_lineto(gra, x, y, &back, erp);
2183 finished:
2184
2185 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2186 }
2187
2188
2189
2190 void
dk4gra_curveto(dk4_gra_t * gra,double xc1,double yc1,double xc2,double yc2,double x,double y,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2191 dk4gra_curveto(
2192 dk4_gra_t *gra,
2193 double xc1,
2194 double yc1,
2195 double xc2,
2196 double yc2,
2197 double x,
2198 double y,
2199 dk4_bb_t *bbptr,
2200 int *backptr,
2201 dk4_er_t *erp
2202 )
2203 {
2204 int back = 0;
2205
2206 #if DK4_USE_ASSERT
2207 assert(NULL != gra);
2208 #endif
2209 if (NULL == gra) {
2210 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2211 goto finished;
2212 }
2213 if (NULL != bbptr) {
2214 dk4bb_add_bezier(
2215 bbptr, gra->cur_x, gra->cur_y, xc1, yc1, xc2, yc2, x, y
2216 );
2217 }
2218 gra->cur_x = x;
2219 gra->cur_y = y;
2220 if (NULL == gra->curpg) {
2221 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2222 goto finished;
2223 }
2224 back = 1;
2225 dk4gra_i_curveto(gra, xc1, yc1, xc2, yc2, x, y, &back, erp);
2226 finished:
2227
2228 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2229 }
2230
2231
2232
2233 void
dk4gra_closepath(dk4_gra_t * gra,int * backptr,dk4_er_t * erp)2234 dk4gra_closepath(
2235 dk4_gra_t *gra,
2236 int *backptr,
2237 dk4_er_t *erp
2238 )
2239 {
2240 int back = 0;
2241
2242 #if DK4_USE_ASSERT
2243 assert(NULL != gra);
2244 #endif
2245 if (NULL == gra) {
2246 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2247 goto finished;
2248 }
2249 if (NULL == gra->curpg) {
2250 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2251 goto finished;
2252 }
2253 back = 1;
2254 dk4gra_i_closepath(gra, &back, erp);
2255 finished:
2256
2257 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2258 }
2259
2260
2261
2262 void
dk4gra_circle(dk4_gra_t * gra,double xc,double yc,double r,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2263 dk4gra_circle(
2264 dk4_gra_t *gra,
2265 double xc,
2266 double yc,
2267 double r,
2268 dk4_bb_t *bbptr,
2269 int *backptr,
2270 dk4_er_t *erp
2271 )
2272 {
2273 int back = 0;
2274
2275 #if DK4_USE_ASSERT
2276 assert(NULL != gra);
2277 #endif
2278 if ((NULL == gra) || (0.0 >= r)) {
2279 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2280 goto finished;
2281 }
2282 if (NULL != bbptr) {
2283 dk4bb_add_x(bbptr, xc - r); dk4bb_add_x(bbptr, xc + r);
2284 dk4bb_add_y(bbptr, yc - r); dk4bb_add_y(bbptr, yc + r);
2285 }
2286 if (NULL == gra->curpg) {
2287 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2288 goto finished;
2289 }
2290 back = 1;
2291 dk4gra_i_circle(gra, xc, yc, r, &back, erp);
2292
2293 finished:
2294
2295 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2296 }
2297
2298
2299 void
dk4gra_rectangle(dk4_gra_t * gra,double xl,double xr,double yb,double yt,double r,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2300 dk4gra_rectangle(
2301 dk4_gra_t *gra,
2302 double xl,
2303 double xr,
2304 double yb,
2305 double yt,
2306 double r,
2307 dk4_bb_t *bbptr,
2308 int *backptr,
2309 dk4_er_t *erp
2310 )
2311 {
2312 int back = 0;
2313
2314 #if DK4_USE_ASSERT
2315 assert(NULL != gra);
2316 #endif
2317 if (NULL == gra) {
2318 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2319 goto finished;
2320 }
2321 if (NULL != bbptr) {
2322 dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr);
2323 dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt);
2324 }
2325 if (NULL == gra->curpg) {
2326 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2327 goto finished;
2328 }
2329 back = 1;
2330 dk4gra_i_rectangle(gra, xl, xr, yb, yt, r, &back, erp);
2331
2332 finished:
2333
2334 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2335 }
2336
2337
2338
2339 void
dk4gra_arc(dk4_gra_t * gra,double xc,double yc,double ra,double start,double end,int cl,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2340 dk4gra_arc(
2341 dk4_gra_t *gra,
2342 double xc,
2343 double yc,
2344 double ra,
2345 double start,
2346 double end,
2347 int cl,
2348 dk4_bb_t *bbptr,
2349 int *backptr,
2350 dk4_er_t *erp
2351 )
2352 {
2353 int back = 0;
2354
2355 #if DK4_USE_ASSERT
2356 assert(NULL != gra);
2357 #endif
2358 if ((NULL == gra) || (0.0 >= ra)) {
2359 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2360 goto finished;
2361 }
2362 if (NULL != bbptr) {
2363 dk4bb_add_x(bbptr, xc + ra * cos((M_PI * start)/ 180.0));
2364 dk4bb_add_y(bbptr, yc + ra * sin((M_PI * start)/ 180.0));
2365 dk4bb_add_x(bbptr, xc + ra * cos((M_PI * end)/ 180.0));
2366 dk4bb_add_y(bbptr, yc + ra * sin((M_PI * end)/ 180.0));
2367 }
2368 if (NULL == gra->curpg) {
2369 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2370 goto finished;
2371 }
2372 back = 1;
2373 dk4gra_i_arc(gra, xc, yc, ra, start, end, cl, &back, erp);
2374 finished:
2375
2376 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2377 }
2378
2379
2380
2381 void
dk4gra_ellipse(dk4_gra_t * gra,double xc,double yc,double rx,double ry,double rot,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2382 dk4gra_ellipse(
2383 dk4_gra_t *gra,
2384 double xc,
2385 double yc,
2386 double rx,
2387 double ry,
2388 double rot,
2389 dk4_bb_t *bbptr,
2390 int *backptr,
2391 dk4_er_t *erp
2392 )
2393 {
2394 int back = 0;
2395
2396 #if DK4_USE_ASSERT
2397 assert(NULL != gra);
2398 #endif
2399 rot *= M_PI;
2400 rot /= 180.0;
2401 if ((NULL == gra) || (0.0 >= rx) || (0.0 >= ry)) {
2402 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2403 goto finished;
2404 }
2405 if (NULL == gra->curpg) {
2406 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2407 goto finished;
2408 }
2409 back = 1;
2410 dk4gra_i_ellipse(gra, xc, yc, rx, ry, rot, bbptr, &back, erp);
2411
2412 finished:
2413
2414 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2415 }
2416
2417
2418
2419 void
dk4gra_pattern(dk4_gra_t * gra,double xl,double xr,double yb,double yt,dk4_gra_pattern_t pn,int * backptr,dk4_er_t * erp)2420 dk4gra_pattern(
2421 dk4_gra_t *gra,
2422 double xl,
2423 double xr,
2424 double yb,
2425 double yt,
2426 dk4_gra_pattern_t pn,
2427 int *backptr,
2428 dk4_er_t *erp
2429 )
2430 {
2431 double val[16]; /* Values passed to EPS pattern functions */
2432 double y01; /* Temporary value */
2433 double y02; /* Temporary value */
2434 dk4_gra_lc_t lc; /* Line cap used while drawing the pattern */
2435 dk4_gra_lj_t lj; /* Line join used while drawing the pattern */
2436 dk4_gra_ls_t ls; /* Line style used while drawing the pattern */
2437 int back = 0;
2438
2439 #if DK4_USE_ASSERT
2440 assert(NULL != gra);
2441 #endif
2442 if (NULL == gra) {
2443 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2444 goto finished;
2445 }
2446 if (NULL == gra->curpg) {
2447 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2448 goto finished;
2449 }
2450 /* Extend pattern area for line width
2451 */
2452 #if VERSION_BEFORE_20181212
2453 xl -= 0.9; xr += 0.9; yb -= 0.9; yt += 0.9;
2454 #else
2455 xl -= gra->patlw; xr += gra->patlw; yb -= gra->patlw; yt += gra->patlw;
2456 #endif
2457 /*
2458 Calculate arguments for EPS pattern functions
2459 */
2460 val[0] = xl;
2461 val[1] = xr;
2462 val[2] = yb;
2463 val[3] = yt;
2464 val[4] = 3.6;
2465 switch (pn) {
2466 case DK4_GRA_PATTERN_30_DEGREE_RIGHT : {
2467 /* ys = yb - (xe - xs) / sqrt(3) */
2468 val[2] -= ((val[1] - val[0]) / sqrt(3.0));
2469 val[4] = 7.2 / sqrt(3.0);
2470 y01 = val[2] - val[0] / sqrt(3.0);
2471 y02 = y01 / val[4];
2472 y02 = floor(y02);
2473 y02 = y02 * val[4];
2474 val[2] -= (y01 - y02);
2475 } break;
2476 case DK4_GRA_PATTERN_30_DEGREE_SIEVE : {
2477 /* ys = yb - (xe - xs) / sqrt(3) */
2478 val[2] -= ((val[1] - val[0]) / sqrt(3.0));
2479 val[4] = 7.2 / sqrt(3.0);
2480 y01 = val[2] + val[1] / sqrt(3.0);
2481 y02 = y01 / val[4];
2482 y02 = floor(y02);
2483 y02 = y02 * val[4];
2484 val[2] -= (y01 - y02);
2485 y01 = val[0] - val[2] * sqrt(3.0);
2486 y02 = y01 / 7.2;
2487 y02 = floor(y02);
2488 y02 = y02 * 7.2;
2489 val[0] -= (y01 - y02);
2490 val[2] -= val[4];
2491 } break;
2492 case DK4_GRA_PATTERN_45_DEGREE_LEFT : {
2493 val[2] -= (val[1] - val[0]);
2494 val[4] = 3.6 * M_SQRT2;
2495 y01 = val[2] + val[1];
2496 y02 = y01 / val[4];
2497 y02 = floor(y02);
2498 y02 *= val[4];
2499 val[2] -= (y01 - y02);
2500 } break;
2501 case DK4_GRA_PATTERN_45_DEGREE_RIGHT : {
2502 val[2] -= (val[1] - val[0]);
2503 val[4] = 3.6 * M_SQRT2;
2504 y01 = val[2] - val[0];
2505 y02 = y01 / val[4];
2506 y02 = floor(y02);
2507 y02 *= val[4];
2508 val[2] -= (y01 - y02);
2509 } break;
2510 case DK4_GRA_PATTERN_45_DEGREE_SIEVE : {
2511 val[2] -= (val[1] - val[0]);
2512 val[4] = 3.6 * M_SQRT2;
2513 y01 = val[2] + val[1];
2514 y02 = y01 / val[4];
2515 y02 = floor(y02);
2516 y02 *= val[4];
2517 val[2] -= (y01 - y02);
2518 y01 = val[0] - val[2];
2519 y02 = y01 / val[4];
2520 y02 = floor(y02);
2521 y02 *= val[4];
2522 val[0] -= (y01 - y02);
2523 val[2] -= val[4];
2524 } break;
2525 case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : {
2526 y01 = val[2] / 7.2;
2527 y01 = floor(y01);
2528 val[2] = y01 * 7.2;
2529 y01 = val[0] / 14.4;
2530 y01 = floor(y01);
2531 val[0] = y01 * 14.4;
2532 val[4] = 7.2;
2533 } break;
2534 case DK4_GRA_PATTERN_VERTICAL_BRICKS : {
2535 y01 = val[2] / 14.4;
2536 y01 = floor(y01);
2537 val[2] = y01 * 14.4;
2538 y01 = val[0] / 7.2;
2539 y01 = floor(y01);
2540 val[0] = y01 * 7.2;
2541 val[4] = 7.2;
2542 } break;
2543 case DK4_GRA_PATTERN_HORIZONTAL_LINES : {
2544 y01 = val[2] / 3.6;
2545 y01 = floor(y01);
2546 val[2] = y01 * 3.6;
2547 } break;
2548 case DK4_GRA_PATTERN_VERTICAL_LINES : {
2549 y01 = val[0] / 3.6;
2550 y01 = floor(y01);
2551 val[0] = y01 * 3.6;
2552 } break;
2553 case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : {
2554 y01 = val[2] / 3.6;
2555 y01 = floor(y01);
2556 val[2] = y01 * 3.6;
2557 y01 = val[0] / 3.6;
2558 y01 = floor(y01);
2559 val[0] = y01 * 3.6;
2560 } break;
2561 case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : {
2562 y01 = val[2] / 28.8;
2563 y01 = floor(y01);
2564 val[2] = y01 * 28.8;
2565 y01 = val[0] / 14.4;
2566 y01 = floor(y01);
2567 val[0] = y01 * 14.4;
2568 val[4] = 7.2;
2569 } break;
2570 case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : {
2571 y01 = val[2] / 28.8;
2572 y01 = floor(y01);
2573 val[2] = y01 * 28.8;
2574 y01 = val[0] / 14.4;
2575 y01 = floor(y01);
2576 val[0] = y01 * 14.4;
2577 val[4] = 7.2;
2578 } break;
2579 case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : {
2580 y01 = val[2] / 14.4;
2581 y01 = floor(y01);
2582 val[2] = y01 * 14.4;
2583 y01 = val[0] / 28.8;
2584 y01 = floor(y01);
2585 val[0] = y01 * 28.8;
2586 val[4] = 7.2;
2587 } break;
2588 case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : {
2589 y01 = val[2] / 14.4;
2590 y01 = floor(y01);
2591 val[2] = y01 * 14.4;
2592 y01 = val[0] / 28.8;
2593 y01 = floor(y01);
2594 val[0] = y01 * 28.8;
2595 val[4] = 7.2;
2596 } break;
2597 case DK4_GRA_PATTERN_LARGE_FISH_SCALES : {
2598 /* xs xe ys ye dx dy r a1 a2 */
2599 val[4] = 14.54;
2600 val[5] = 3.7;
2601 val[6] = 9.0;
2602 val[7] = 216.1;
2603 val[8] = 323.9;
2604 y01 = val[0] / val[4];
2605 y01 = floor(y01);
2606 val[0] = y01 * val[4];
2607 y01 = val[2] / (2 * val[5]);
2608 y01 = floor(y01);
2609 val[2] = 2.0 * y01 * val[5];
2610 } break;
2611 case DK4_GRA_PATTERN_SMALL_FISH_SCALES : {
2612 /* xs xe ys ye dx dy r a1 a2 */
2613 val[4] = 7.2;
2614 val[5] = 3.6;
2615 val[6] = 3.6;
2616 val[7] = 180.0;
2617 val[8] = 360.0;
2618 y01 = val[0] / val[4];
2619 y01 = floor(y01);
2620 val[0] = y01 * val[4];
2621 y01 = val[2] / (2 * val[5]);
2622 y01 = floor(y01);
2623 val[2] = 2.0 * y01 * val[5];
2624 } break;
2625 case DK4_GRA_PATTERN_CIRCLES : {
2626 val[4] = 7.2;
2627 y01 = val[0] / 14.4;
2628 y01 = floor(y01);
2629 val[0] = 14.4 * y01;
2630 y01 = val[2] / 14.4;
2631 y01 = floor(y01);
2632 val[2] = 14.4 * y01;
2633 } break;
2634 case DK4_GRA_PATTERN_HEXAGONS : {
2635 /* xs xe ys ye dx dy */
2636 val[4] = 21.6;
2637 val[5] = 12.47;
2638 y01 = val[0] / 21.6;
2639 y01 = floor(y01);
2640 val[0] = y01 * 21.6;
2641 y01 = val[2] / 12.47;
2642 y01 = floor(y01);
2643 val[2] = y01 * 12.47;
2644 } break;
2645 case DK4_GRA_PATTERN_OCTAGONS : {
2646 /* xs xe ys ye dx co */
2647 /* 2020-08-10 Bugfix
2648 Pattern size too small, increased now.
2649 */
2650 val[4] = 14.4; /* previously 7.2; */
2651 val[5] = 4.22; /* previously 2.11; */
2652 y01 = val[0] / val[4];
2653 y01 = floor(y01);
2654 val[0] = y01 * val[4];
2655 y01 = val[2] / val[4];
2656 y01 = floor(y01);
2657 val[2] = y01 * val[4];
2658 } break;
2659 case DK4_GRA_PATTERN_HORIZONTAL_TIRES : {
2660 val[4] = 7.2;
2661 y01 = val[0] / val[4];
2662 y01 = floor(y01);
2663 val[0] = y01 * val[4];
2664 y01 = val[2] / val[4];
2665 y01 = floor(y01);
2666 val[2] = y01 * val[4];
2667 } break;
2668 case DK4_GRA_PATTERN_VERTICAL_TIRES : {
2669 val[4] = 7.2;
2670 y01 = val[0] / val[4];
2671 y01 = floor(y01);
2672 val[0] = y01 * val[4];
2673 y01 = val[2] / val[4];
2674 y01 = floor(y01);
2675 val[2] = y01 * val[4];
2676 } break;
2677 /* DK4_GRA_PATTERN_30_DEGREE_LEFT */
2678 default : {
2679 /* ys = yb - (xe - xs) / sqrt(3) */
2680 val[2] -= ((val[1] - val[0]) / sqrt(3.0));
2681 val[4] = 7.2 / sqrt(3.0);
2682 y01 = val[2] + val[1] / sqrt(3.0);
2683 y02 = y01 / val[4];
2684 y02 = floor(y02);
2685 y02 = y02 * val[4];
2686 val[2] -= (y01 - y02);
2687 } break;
2688 }
2689
2690 back = 1;
2691
2692 /* Save attributes and graphics state
2693 */
2694 dk4gra_i_save_attributes(gra);
2695 dk4gra_i_gsave(gra, &back, erp);
2696
2697 /* Set attributes for stroking
2698 */
2699 dk4gra_set_line_width(gra, gra->patlw, &back, erp);
2700 lc = DK4_GRA_LC_ROUNDED;
2701 dk4gra_set_line_cap(gra, lc, &back, erp);
2702 lj = DK4_GRA_LJ_MITERED;
2703 switch (pn) {
2704 case DK4_GRA_PATTERN_LARGE_FISH_SCALES:
2705 case DK4_GRA_PATTERN_SMALL_FISH_SCALES: {
2706 lj = DK4_GRA_LJ_ROUNDED;
2707 } break;
2708 default : {
2709 /* Intentionally empty to avoid compiler warnings. */
2710 } break;
2711 }
2712 dk4gra_set_line_join(gra, lj, 10.0, &back, erp);
2713 ls = DK4_GRA_LS_SOLID;
2714 dk4gra_set_line_style(gra, ls, 3.6, &back, erp);
2715 dk4gra_prepare_stroke(gra, &back, erp);
2716
2717 /*
2718 Driver specific pattern functions
2719 */
2720 switch (gra->dr) {
2721 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
2722 if (0 == dk4gra_eps_pattern(gra, pn, val, erp)) {
2723 back = 0;
2724 }
2725 } break;
2726 default : {
2727 dk4gra_i_pattern(gra, xl, xr, yb, yt, pn, val, &back, erp);
2728 } break;
2729 }
2730
2731 /* Restore graphics state and attributes
2732 */
2733 dk4gra_i_grestore(gra, 0, &back, erp);
2734 dk4gra_i_restore_attributes(gra);
2735
2736
2737 finished:
2738
2739 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
2740 }
2741
2742
2743
2744 void
dk4gra_bif_cotra_image(dk4_gra_t * gra,double * cotra,dk4_bif_t * bif,const dkChar * fn,size_t fno,int ifl,int * backptr,dk4_er_t * erp)2745 dk4gra_bif_cotra_image(
2746 dk4_gra_t *gra,
2747 double *cotra,
2748 dk4_bif_t *bif,
2749 const dkChar *fn,
2750 size_t fno,
2751 int ifl,
2752 int *backptr,
2753 dk4_er_t *erp
2754 )
2755 {
2756
2757 int cs; /* Color space */
2758 int back = 0;
2759 dk4_px_bit_depth_t bpc; /* Number of bits per component */
2760
2761
2762 #if DK4_USE_ASSERT
2763 assert(NULL != gra);
2764 assert(NULL != bif);
2765 assert(NULL != cotra);
2766 #endif
2767 /*
2768 Check arguments
2769 */
2770 if ((NULL == gra) || (NULL == cotra) || (NULL == bif)) {
2771 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2772 goto finished;
2773 }
2774 /* When enforcing grayscaled output, do not write colored image
2775 */
2776 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
2777 ifl &= (~(DK4_GRA_IMG_FLAG_COLOR));
2778 }
2779 /* Direct re-use of DCT encoded data requires a file name
2780 */
2781 if (NULL == fn) {
2782 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2783 }
2784 /* Direct re-use of DCT encoded data requires given bits per component
2785 */
2786 bpc = dk4bif_get_original_bit_depth(bif);
2787 if (8 != bpc) {
2788 if (4 != bpc) {
2789 if (2 != bpc) {
2790 if (1 != bpc) {
2791 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2792 }
2793 }
2794 }
2795 }
2796 /* Direct re-use of DCT encoded data restricts color spaces
2797 */
2798 cs = dk4bif_get_color_space(bif);
2799 if (DK4_CS_GRAY != cs) {
2800 if (DK4_CS_RGB != cs) {
2801 if (DK4_CS_CMYK != cs) {
2802 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2803 }
2804 }
2805 }
2806 /* Direct re-use of DCT encoded data impossible for colored
2807 images when enforcing grayscaled output
2808 */
2809 if ((DK4_CS_GRAY != cs) && (0 == (DK4_GRA_IMG_FLAG_COLOR & ifl))) {
2810 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2811 }
2812
2813 switch (gra->dr) {
2814 case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : {
2815 back = dk4gra_eps_bif_fig_image(
2816 gra, cotra, bif, fn,
2817 ifl, erp
2818 );
2819 } break;
2820 case DK4_GRA_DRIVER_PGF : {
2821 if (NULL != fn) {
2822 back = dk4gra_pgf_bif_fig_image(
2823 gra, cotra, bif, fn,
2824 ifl, erp
2825 );
2826 }
2827 else {
2828 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2829 }
2830 } break;
2831 default : { /* PDF */
2832 back = dk4gra_pdf_bif_fig_image(
2833 gra, cotra, bif, fn, fno,
2834 ifl, erp
2835 );
2836 } break;
2837 }
2838
2839 finished:
2840
2841 if ((0 == back) && (NULL != backptr)) { *backptr = 0; }
2842 }
2843
2844
2845 void
dk4gra_bif_fig_image(dk4_gra_t * gra,double xl,double xr,double yb,double yt,dk4_bif_t * bif,const dkChar * fn,size_t fno,int pos,int ifl,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)2846 dk4gra_bif_fig_image(
2847 dk4_gra_t *gra,
2848 double xl,
2849 double xr,
2850 double yb,
2851 double yt,
2852 dk4_bif_t *bif,
2853 const dkChar *fn,
2854 size_t fno,
2855 int pos,
2856 int ifl,
2857 dk4_bb_t *bbptr,
2858 int *backptr,
2859 dk4_er_t *erp
2860 )
2861 {
2862 double val[8]; /* Values passed to low level functions */
2863 double w; /* Image width */
2864 double h; /* Image height */
2865 double xres; /* X resolution */
2866 double yres; /* Y resolution */
2867 int res; /* Operation result */
2868 int cs; /* Color space */
2869 int back = 0;
2870 dk4_px_bit_depth_t bpc;
2871
2872 #if DK4_USE_ASSERT
2873 assert(NULL != gra);
2874 assert(NULL != bif);
2875 #endif
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897 /* 2018-03-19
2898 Removed (NULL == fn)
2899 */
2900 if ((NULL == gra) || (NULL == bif)) {
2901 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2902 goto finished;
2903 }
2904 if ((xr <= xl) || (yt <= yb)) {
2905 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2906 goto finished;
2907 }
2908 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
2909 ifl &= (~(DK4_GRA_IMG_FLAG_COLOR));
2910 }
2911 if (NULL != bbptr) {
2912 dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr);
2913 dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt);
2914 }
2915 /* Select frame
2916 */
2917 if (0 == dk4bif_set_current_frame(bif, fno)) {
2918 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2919 goto finished;
2920 }
2921 /* Retrieve image dimensions
2922 */
2923 w = (double)dk4bif_get_width(bif);
2924 h = (double)dk4bif_get_height(bif);
2925 if (0 == (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl)) {
2926 xres = dk4bif_get_xres(bif);
2927 yres = dk4bif_get_yres(bif);
2928 if ((isgreater(xres, 0.0)) && (isgreater(yres, 0.0))) {
2929 w = (72.0 * w) / xres;
2930 h = (72.0 * h) / yres;
2931 #if DK4_HAVE_ISFINITE
2932 if ((!(isfinite(w))) || (!(isfinite(h)))) {
2933 w = (double)dk4bif_get_width(bif);
2934 h = (double)dk4bif_get_height(bif);
2935 }
2936 #else
2937 #if DK4_HAVE__FINITE
2938 if ((!(_finite(w))) || (!(_finite(h)))) {
2939 w = (double)dk4bif_get_width(bif);
2940 h = (double)dk4bif_get_height(bif);
2941 }
2942 #endif
2943 #endif
2944 }
2945 }
2946 /*
2947 Calculate coordinate system transformations
2948 */
2949 res = dk4gratool_calculate_transformations(
2950 val, xl, xr, yb, yt, w, h,
2951 ((0 == (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl)) ? (1) : (0)),
2952 pos, erp
2953 );
2954 if (0 == res) {
2955 goto finished;
2956 }
2957 /* Direct re-use of DCT encoded data from JPEG requires file name
2958 */
2959 if (NULL == fn) {
2960 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2961 }
2962 /* DCT encoding restricts usable number of bits per component
2963 */
2964 bpc = dk4bif_get_original_bit_depth(bif);
2965 if (8 != bpc) {
2966 if (4 != bpc) {
2967 if (2 != bpc) {
2968 if (1 != bpc) {
2969 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2970 }
2971 }
2972 }
2973 }
2974 /* DCT encoding restricts color spaces
2975 */
2976 cs = dk4bif_get_color_space(bif);
2977 if (DK4_CS_GRAY != cs) {
2978 if (DK4_CS_RGB != cs) {
2979 if (DK4_CS_CMYK != cs) {
2980 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2981 }
2982 }
2983 }
2984 /* Direct re-use of DCT encoded data from colored image
2985 not possible when enforcing grayscaled output
2986 */
2987 if ((DK4_CS_GRAY != cs) && (0 == (DK4_GRA_IMG_FLAG_COLOR & ifl))) {
2988 ifl &= (~(DK4_GRA_IMG_FLAG_DCT));
2989 }
2990 /* Can not specify frame number in PGF output, only frame 0
2991 can be used
2992 */
2993 if ((DK4_GRA_DRIVER_PGF == gra->dr) && (0 != fno)) {
2994 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2995 goto finished;
2996 }
2997 /* Call function to produce output with given coordinates transformation
2998 */
2999 back = 1;
3000 dk4gra_bif_cotra_image(
3001 gra, val, bif, fn, fno,
3002 ifl, &back, erp
3003 );
3004
3005 finished:
3006
3007 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
3008 }
3009
3010
3011
3012 void
dk4gra_bif_image(dk4_gra_t * gra,double xl,double xr,double yb,double yt,dk4_bif_t * bif,const dkChar * fn,size_t fno,int ifl,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)3013 dk4gra_bif_image(
3014 dk4_gra_t *gra,
3015 double xl,
3016 double xr,
3017 double yb,
3018 double yt,
3019 dk4_bif_t *bif,
3020 const dkChar *fn,
3021 size_t fno,
3022 int ifl,
3023 dk4_bb_t *bbptr,
3024 int *backptr,
3025 dk4_er_t *erp
3026 )
3027 {
3028 double xres = 1.0; /* X resolution */
3029 double yres = 1.0; /* Y resolution */
3030 double w; /* Width */
3031 double h; /* Height */
3032 double xdiff; /* Available X space */
3033 double ydiff; /* Available Y space */
3034 int pos = 0; /* Image position */
3035 int back = 0;
3036
3037 #if DK4_USE_ASSERT
3038 assert(NULL != gra);
3039 assert(NULL != bif);
3040 #endif
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061 /* 2018-03-19
3062 Removed (NULL == fn)
3063 */
3064 if ((NULL == gra) || (NULL == bif)) {
3065 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3066 goto finished;
3067 }
3068 if ((xr <= xl) || (yt <= yb)) {
3069 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3070 goto finished;
3071 }
3072 if (NULL != bbptr) {
3073 dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr);
3074 dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt);
3075 }
3076 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
3077 ifl &= (~(DK4_GRA_IMG_FLAG_COLOR));
3078 }
3079 if (0 == (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl)) {
3080 if (0 != (DK4_GRA_IMG_FLAG_ALLOW_ROTATION & ifl)) {
3081 if (0 != dk4bif_set_current_frame(bif, fno)) {
3082 xdiff = fabs(xr - xl);
3083 ydiff = fabs(yt - yb);
3084 w = (double)dk4bif_get_width(bif);
3085 h = (double)dk4bif_get_height(bif);
3086 if (0 == (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl)) {
3087 xres = dk4bif_get_xres(bif);
3088 yres = dk4bif_get_yres(bif);
3089 if ((isgreater(xres, 0.0)) && (isgreater(yres, 0.0))) {
3090 w = (72.0 * w) / xres;
3091 h = (72.0 * h) / yres;
3092 }
3093 }
3094 #if DK4_HAVE_ISFINITE
3095 if ((isfinite(w)) && (isfinite(h)))
3096 #else
3097 #if DK4_HAVE__FINITE
3098 if ((_finite(w)) && (_finite(h)))
3099 #else
3100
3101 #endif
3102 #endif
3103 {
3104 if ((isgreater(w, h)) && (isless(xdiff, ydiff))) {
3105 pos = 1;
3106 }
3107 else {
3108 if ((isless(w, h)) && (isgreater(xdiff, ydiff))) {
3109 pos = 1;
3110 }
3111 }
3112 }
3113 #if (DK4_HAVE_ISFINITE) || (DK4_HAVE__FINITE)
3114 else {
3115 /* ERROR: Width and height calculation failed */
3116 dk4error_set_simple_error_code(erp,DK4_E_MATH_OVERFLOW);
3117 }
3118 #endif
3119 }
3120 else {
3121 /* ERROR: Frame number does not exist! */
3122 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3123 }
3124 back = 1;
3125 dk4gra_bif_fig_image(
3126 gra, xl, xr, yb, yt, bif, fn, fno,
3127 pos, ifl, bbptr, &back, erp
3128 );
3129 }
3130 else {
3131 back = 1;
3132 dk4gra_bif_fig_image(
3133 gra, xl, xr, yb, yt, bif, fn, fno,
3134 pos, ifl, bbptr, &back, erp
3135 );
3136 }
3137 }
3138 else {
3139 back = 1;
3140 dk4gra_bif_fig_image(
3141 gra, xl, xr, yb, yt, bif, fn, fno,
3142 pos, ifl, bbptr, &back, erp
3143 );
3144 }
3145 finished:
3146
3147 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
3148 }
3149
3150
3151
3152 void
dk4gra_fig_image(dk4_gra_t * gra,double xl,double xr,double yb,double yt,const dkChar * fn,size_t fno,dk4_cs_conv_ctx_t * ctx,int pos,int ifl,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)3153 dk4gra_fig_image(
3154 dk4_gra_t *gra,
3155 double xl,
3156 double xr,
3157 double yb,
3158 double yt,
3159 const dkChar *fn,
3160 size_t fno,
3161 dk4_cs_conv_ctx_t *ctx,
3162 int pos,
3163 int ifl,
3164 dk4_bb_t *bbptr,
3165 int *backptr,
3166 dk4_er_t *erp
3167 )
3168 {
3169 dk4_bif_t *bifptr = NULL; /* Bitmap image file */
3170 int ho = 0; /* Flag: Read header only */
3171 int back = 0;
3172
3173 #if DK4_USE_ASSERT
3174 assert(NULL != gra);
3175 assert(NULL != fn);
3176 #endif
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197 if ((NULL == gra) || (NULL == fn)) {
3198 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3199 goto finished;
3200 }
3201 if ((xr <= xl) || (yt <= yb)) {
3202 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3203 goto finished;
3204 }
3205 if (NULL == ctx) {
3206 ctx = &(gra->cscctx);
3207 }
3208 if (NULL != bbptr) {
3209 dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr);
3210 dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt);
3211 }
3212 if (DK4_GRA_DRIVER_PGF == gra->dr) {
3213 ho = 1;
3214 }
3215 if (
3216 (0 != (DK4_GRA_IMG_FLAG_DCT & ifl))
3217 && (DK4_BIF_TYPE_JPEG == dk4bif_type_for_suffix(fn))
3218 ) {
3219 if (0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) {
3220 ho = 1;
3221 }
3222 }
3223 bifptr = dk4bif_open(fn, ho, ctx, erp);
3224 if (NULL == bifptr) {
3225 goto finished;
3226 }
3227 back = 1;
3228 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
3229 ifl &= (~(DK4_GRA_IMG_FLAG_COLOR));
3230 }
3231 dk4gra_bif_fig_image(
3232 gra, xl, xr, yb, yt, bifptr, fn, fno,
3233 pos, ifl, bbptr, &back, erp
3234 );
3235
3236 finished:
3237 if (NULL != bifptr) {
3238 dk4bif_close(bifptr);
3239 }
3240
3241 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
3242 }
3243
3244
3245
3246 void
dk4gra_image(dk4_gra_t * gra,double xl,double xr,double yb,double yt,const dkChar * fn,size_t fno,dk4_cs_conv_ctx_t * ctx,int ifl,dk4_bb_t * bbptr,int * backptr,dk4_er_t * erp)3247 dk4gra_image(
3248 dk4_gra_t *gra,
3249 double xl,
3250 double xr,
3251 double yb,
3252 double yt,
3253 const dkChar *fn,
3254 size_t fno,
3255 dk4_cs_conv_ctx_t *ctx,
3256 int ifl,
3257 dk4_bb_t *bbptr,
3258 int *backptr,
3259 dk4_er_t *erp
3260 )
3261 {
3262 dk4_bif_t *bifptr = NULL; /* Bitmap image */
3263 int back = 0; /* Function result */
3264 int ho = 0; /* Flag: Read image header only */
3265
3266 #if DK4_USE_ASSERT
3267 assert(NULL != gra);
3268 assert(NULL != fn);
3269 #endif
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290 /*
3291 Check argument
3292 */
3293 if ((NULL == gra) || (NULL == fn)) {
3294 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3295 goto finished;
3296 }
3297 if ((xr <= xl) || (yt <= yb)) {
3298 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
3299 goto finished;
3300 }
3301 if (NULL == ctx) {
3302 ctx = &(gra->cscctx);
3303 }
3304 if (NULL != bbptr) {
3305 dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr);
3306 dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt);
3307 }
3308 /* Open bitmap file
3309 */
3310 if (DK4_GRA_DRIVER_PGF == gra->dr) {
3311 ho = 1;
3312 }
3313 if (
3314 (0 != (DK4_GRA_IMG_FLAG_DCT & ifl))
3315 && (DK4_BIF_TYPE_JPEG == dk4bif_type_for_suffix(fn))
3316 ) {
3317 if (0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) {
3318 ho = 1;
3319 }
3320 }
3321 bifptr = dk4bif_open(fn, ho, ctx, erp);
3322 if (NULL == bifptr) {
3323 goto finished;
3324 }
3325 /* Process bitmap file
3326 */
3327 back = 1;
3328 if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) {
3329 ifl &= (~(DK4_GRA_IMG_FLAG_COLOR));
3330 }
3331 dk4gra_bif_image(
3332 gra, xl, xr, yb, yt, bifptr, fn, fno,
3333 ifl, bbptr, &back, erp
3334 );
3335
3336 /* Clean up and exit
3337 */
3338 finished:
3339
3340 if (NULL != bifptr) {
3341 dk4bif_close(bifptr);
3342 }
3343
3344 if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
3345 }
3346
3347
3348
3349 void
dk4gra_set_pattern_line_width(dk4_gra_t * gra,double plw)3350 dk4gra_set_pattern_line_width(
3351 dk4_gra_t *gra,
3352 double plw
3353 )
3354 {
3355 #if DK4_USE_ASSERT
3356 assert(NULL != gra);
3357 #endif
3358 if (NULL != gra) {
3359 if (0.0 < plw) {
3360 gra->patlw = plw;
3361 }
3362 }
3363 }
3364
3365
3366
3367 /* vim: set ai sw=4 ts=4 : */
3368