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