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: dk4greps.ctr
12 */
13 
14 /**	@file dk4greps.c The dk4greps module.
15 */
16 
17 
18 #include "dk4conf.h"
19 
20 #if	DK4_HAVE_MATH_H
21 #ifndef	MATH_H_INCLUDED
22 #if	DK4_ON_WINDOWS
23 #ifndef	_USE_MATH_DEFINES
24 #define	_USE_MATH_DEFINES 1
25 #endif
26 #endif
27 #include <math.h>
28 #define	MATH_H_INCLUDED 1
29 #endif
30 #endif
31 
32 #ifndef	DK4MEM_H_INCLUDED
33 #include <libdk4base/dk4mem.h>
34 #endif
35 
36 #ifndef	DK4MEMBF_H_INCLUDED
37 #include <libdk4c/dk4membf.h>
38 #endif
39 
40 #ifndef	DK4MBSTRM_H_INCLUDED
41 #include <libdk4c/dk4mbstrm.h>
42 #endif
43 
44 #ifndef	DK4GRA_H_INCLUDED
45 #include <libdk4gra/dk4gra.h>
46 #endif
47 
48 #ifndef	GRA_H_INCLUDED
49 #include <libdk4gra/gra.h>
50 #endif
51 
52 #ifndef	DK4MAO8D_H_INCLUDED
53 #include <libdk4maio8d/dk4mao8d.h>
54 #endif
55 
56 #ifndef	DK4MAO8DNS_H_INCLUDED
57 #include <libdk4c/dk4mao8dns.h>
58 #endif
59 
60 #if DK4_HAVE_ASSERT_H
61 #ifndef	ASSERT_H_INCLUDED
62 #include <assert.h>
63 #define	ASSERT_H_INCLUDED 1
64 #endif
65 #endif
66 
67 
68 
69 
70 
71 
72 /**	Constant text fragments.
73 */
74 static const char * const dk4gra_eps_c8_kw[] = {
75 /* 0 */
76 "\n",
77 
78 /* 1 */
79 "gsave\n",
80 
81 /* 2 */
82 "grestore\n",
83 
84 /* 3 */
85 " ",
86 
87 /* 4 */
88 " setlinewidth\n",
89 
90 /* 5 */
91 " setcmykcolor\n",
92 
93 /* 6 */
94 " setrgbcolor\n",
95 
96 /* 7 */
97 " setgray\n",
98 
99 /* 8 */
100 "[] 0 setdash\n",
101 
102 /* 9 */
103 "[",
104 
105 /* 10 */
106 "]",
107 
108 /* 11 */
109 " setdash\n",
110 
111 /* 12 */
112 "0 setlinecap\n",
113 
114 /* 13 */
115 "1 setlinecap\n",
116 
117 /* 14 */
118 "2 setlinecap\n",
119 
120 /* 15 */
121 "0 setlinejoin\n",
122 
123 /* 16 */
124 "1 setlinejoin\n",
125 
126 /* 17 */
127 "2 setlinejoin\n",
128 
129 /* 18 */
130 "fill\n",
131 
132 /* 19 */
133 "eofill\n",
134 
135 /* 20 */
136 "stroke\n",
137 
138 /* 21 */
139 "clip\n",
140 
141 /* 22 */
142 "eoclip\n",
143 
144 /* 23 */
145 "newpath\n",
146 
147 /* 24 */
148 " moveto\n",
149 
150 /* 25 */
151 " lineto\n",
152 
153 /* 26 */
154 " curveto\n",
155 
156 /* 27 */
157 "closepath\n",
158 
159 /* 28 */
160 " 0 360 arc closepath\n",
161 
162 /* 29 */
163 " arc\n",
164 
165 /* 30 */
166 "%!PS-Adobe-3.0 EPSF-3.0\n",
167 
168 /* 31 */
169 "%!PS-Adobe-2.0 EPSF-2.0\n",
170 
171 /* 32 */
172 "%!PS-Adobe-3.0\n",
173 
174 /* 33 */
175 "%!PS-Adobe-2.0\n",
176 
177 /* 34 */
178 "%%LanguageLevel: 3\n",
179 
180 /* 35 */
181 "%%LanguageLevel: 2\n",
182 
183 /* 36 */
184 "%%BoundingBox: 0 0 ",
185 
186 /* 37 */
187 "%%Pages: ",
188 
189 /* 38 */
190 "%%PageOrder: Ascend\n",
191 
192 /* 39 */
193 "%%DocumentData: Clean7Bit\n",
194 
195 /* 40 */
196 "%%EndComments\n%%BeginProlog\n%%EndProlog\n",
197 
198 /* 41 */
199 "%%Trailer\n%%EOF\n",
200 
201 /* 42 */
202 "%%Page: ",
203 
204 /* 43 */
205 " dict begin\n",
206 
207 /* 44 */
208 "end\n",
209 
210 /* 45 */
211 "showpage\n",
212 
213 /* 46 */
214 "0 0 moveto\n",
215 
216 /* 47 */
217 "0",
218 
219 /* 48 */
220 "1 setlinecap\n",
221 
222 /* 49 */
223 "1 setgray\n",
224 
225 /* 50 */
226 " setmiterlimit\n",
227 
228 /* 51 */
229 "%%BeginSetup\n",
230 
231 /* 52 */
232 "%%EndSetup\n",
233 
234 /* 53 */
235 "%%BeginFeature: *PageSize BmppPage\n",
236 
237 /* 54 */
238 "%%EndFeature\n",
239 
240 /* 55 */
241 "<< /PageSize [",
242 
243 /* 56 */
244 "] /ImagingBBox null >> setpagedevice\n",
245 
246 /* 57 */
247 "%%BeginFeature: *Duplex DuplexNoTumble\n",
248 
249 /* 58 */
250 "<< /Duplex true /Tumble false >> setpagedevice\n",
251 
252 /* 59 */
253 "%%BeginFeature: *Duplex DuplexTumble\n",
254 
255 /* 60 */
256 "<< /Duplex true /Tumble true >> setpagedevice\n",
257 
258 NULL
259 
260 };
261 
262 
263 
264 /**	Write double value to page memory stream.
265 	@param	bptr	Current page.
266 	@param	v		Value to write.
267 	@param	backptr	Address of success variable to reset on errors.
268 	@param	erp		Error report, may be NULL.
269 	@return	1 on success, 0 on error.
270 
271 	Error codes:
272 	- DK4_E_INVALID_ARGUMENTS<br>
273 	  if os is NULL.
274 	- DK4_E_WRITE_FAILED<br>
275 	  if writing one ore multiple bytes to the stream failed,
276 	- DK4_E_FLUSH_FAILED<br>
277 	  if flushing data downwards failed,
278 	- DK4_E_MATH_OVERFLOW<br>
279 	  if the exponent is out of range for integer values,<br>
280 	- DK4_E_SYNTAX<br>
281 	  if input contains invalid characters.
282 */
283 static
284 void
dk4gra_eps_double_value(dk4_gra_ps_page_t * bptr,double v,int * backptr,dk4_er_t * erp)285 dk4gra_eps_double_value(
286 	dk4_gra_ps_page_t	*bptr,
287 	double				 v,
288 	int					*backptr,
289 	dk4_er_t			*erp
290 
291 )
292 {
293 #if	DK4_USE_ASSERT
294 	assert(NULL != bptr);
295 #endif
296 	dk4gratool_stream_double(bptr->memstrm, v, backptr, erp);
297 }
298 
299 
300 
301 /**	Write a fixed keyword from dk4gra_eps_c8_kw to page memory stream.
302 	@param	bptr	Current page.
303 	@param	i		Index of keyword in array.
304 	@param	backptr	Address of success variable to reset on errors.
305 	@param	erp		Error report, may be NULL.
306 	@return	1 on success, 0 on error.
307 
308 	Error codes:
309 	- DK4_E_INVALID_ARGUMENTS<br>
310 	  if str is NULL or the stream is not opened for writing,
311 	- DK4_E_WRITE_FAILED<br>
312 	  if writing one ore multiple bytes to the stream failed,
313 	- DK4_E_FLUSH_FAILED<br>
314 	  if flushing data downwards failed.
315 */
316 static
317 void
dk4gra_eps_kw(dk4_gra_ps_page_t * bptr,size_t i,int * backptr,dk4_er_t * erp)318 dk4gra_eps_kw(
319 	dk4_gra_ps_page_t	*bptr,
320 	size_t				 i,
321 	int					*backptr,
322 	dk4_er_t			*erp
323 )
324 {
325 #if	DK4_USE_ASSERT
326 	assert(NULL != bptr);
327 #endif
328 	dk4gratool_stream_string(bptr->memstrm, dk4gra_eps_c8_kw[i], backptr, erp);
329 }
330 
331 
332 /**	Delete a PS/EPS page structure.
333 	@param	bptr	Page structure to delete.
334 */
335 static
336 void
dk4gra_eps_page_delete(dk4_gra_ps_page_t * bptr)337 dk4gra_eps_page_delete(
338 	dk4_gra_ps_page_t	*bptr
339 )
340 {
341 
342 #if	DK4_USE_ASSERT
343 	assert(NULL != bptr);
344 #endif
345 	if (NULL != bptr) {
346 		/*
347 			Release all resources
348 		*/
349 		if (NULL != bptr->memstrm) {
350 			dk4stream_close(bptr->memstrm, NULL);
351 		}
352 		bptr->memstrm = NULL;
353 		if (NULL != bptr->membuf) {
354 			dk4membuf_close(bptr->membuf);
355 		}
356 		bptr->membuf = NULL;
357 		/*
358 			Free memory for page structure itself
359 		*/
360 		dk4mem_free(bptr);
361 	}
362 
363 }
364 
365 
366 
367 /**	Create new page structure, allocated related resources.
368 	@param	pageno	Page number of new page.
369 	@param	flags	Page flags.
370 	@param	erp		Error report, may be NULL.
371 	@return	Valid pointer to new page structure on success, NULL on error.
372 
373 	Error codes:
374 	- DK4_E_MATH_OVERFLOW<br>
375 	  on numeric overflow when calculating the product of elsize and nelem,
376 	- DK4_E_MEMORY_ALLOCATION_FAILED<br>
377 	  with mem.elsize and mem.nelem set if there is not enough memory
378 	  available.
379 */
380 static
381 dk4_gra_ps_page_t *
dk4gra_eps_page_new(size_t pageno,int flags,dk4_er_t * erp)382 dk4gra_eps_page_new(
383 	size_t		 pageno,
384 	int			 flags,
385 	dk4_er_t	*erp
386 )
387 {
388 	dk4_gra_ps_page_t	*back	= NULL;
389 	size_t				 i		= 0;		/* Traverse patterns */
390 	int					 ok		= 0;
391 
392 	back = dk4mem_new(dk4_gra_ps_page_t,1,erp);
393 	if (NULL != back) {
394 		/*
395 			Initialize all components
396 		*/
397 		dk4gratool_initialize_attributes(&(back->attr));
398 		back->membuf	= NULL;
399 		back->memstrm	= NULL;
400 		back->flags		= flags;
401 		for (i = 0; i < 22; i++) {
402 			back->patu[i] = 0x00;
403 		}
404 		back->pageno = pageno;
405 		back->spip = 0;
406 		back->cont = 0;
407 		/*
408 			Allocate resources for memory buffer and stream
409 		*/
410 		back->membuf = dk4membuf_open(erp);
411 		if (NULL != back->membuf) {
412 			back->memstrm = dk4stream_open_membuf_writer(back->membuf, erp);
413 			if (NULL != back->memstrm) {
414 				ok = 1;
415 			}
416 		}
417 		if (0 == ok) {
418 			dk4gra_eps_page_delete(back);
419 			back = NULL;
420 		}
421 	}
422 
423 	return back;
424 }
425 
426 
427 
428 /**	Write several double values to page memory stream and add keyword.
429 	@param	bptr	Current page.
430 	@param	da		Array of double values.
431 	@param	szda	Number of elements in array.
432 	@param	kwi		Index of keyword to add.
433 	@param	backptr	Address of success variable to reset on errors.
434 	@param	erp		Error report, may be NULL.
435 
436 	Error codes:
437 	- DK4_E_INVALID_ARGUMENTS<br>
438 	  if gra, bptr or da or the current page or the page stream on the
439 	  current page is NULL,
440 	- DK4_E_WRITE_FAILED<br>
441 	  if writing one ore multiple bytes to the stream failed,
442 	- DK4_E_FLUSH_FAILED<br>
443 	  if flushing data downwards failed.
444 	- DK4_E_MATH_OVERFLOW<br>
445 	  if the exponent in one of the double values is out of range for
446 	  integer values,<br>
447 	- DK4_E_SYNTAX<br>
448 	  if the text representation of the double value
449 	  contains invalid characters.
450 */
451 static
452 void
dk4gra_eps_values_and_keyword(dk4_gra_ps_page_t * bptr,double * da,size_t szda,size_t kwi,int * backptr,dk4_er_t * erp)453 dk4gra_eps_values_and_keyword(
454 	dk4_gra_ps_page_t	*bptr,
455 	double				*da,
456 	size_t				 szda,
457 	size_t				 kwi,
458 	int					*backptr,
459 	dk4_er_t			*erp
460 )
461 {
462 	size_t		i;				/* Traverse da */
463 	int			back	= 1;
464 #if	DK4_USE_ASSERT
465 	assert(NULL != bptr);
466 	assert(NULL != da);
467 	assert(0 < szda);
468 #endif
469 	for (i = 0; i < szda; i++) {
470 		if (0 != i) {
471 			dk4gra_eps_kw(bptr, 3, &back, erp);
472 		}
473 		dk4gra_eps_double_value(bptr, da[i], &back, erp);
474 	}
475 	if (0 < kwi) {
476 		dk4gra_eps_kw(bptr, kwi, &back, erp);
477 	}
478 	if ((NULL != backptr) && (0 == back)) { *backptr = 0; }
479 }
480 
481 
482 
483 /**	Set new color if necessary.
484 	@param	bptr				Current page.
485 	@param	p_col_active		Currently active color.
486 	@param	p_col_requested		Requested color.
487 	@param	erp					Error report, may be NULL.
488 	@return	1 on success, 0 on error.
489 
490 	Error codes:
491 	- DK4_E_INVALID_ARGUMENTS<br>
492 	  if gra, bptr or da or the current page or the page stream on the
493 	  current page is NULL,
494 	- DK4_E_WRITE_FAILED<br>
495 	  if writing one ore multiple bytes to the stream failed,
496 	- DK4_E_FLUSH_FAILED<br>
497 	  if flushing data downwards failed.
498 	- DK4_E_MATH_OVERFLOW<br>
499 	  if the exponent in one of the double values is out of range for
500 	  integer values,<br>
501 	- DK4_E_SYNTAX<br>
502 	  if the text representation of the double value
503 	  contains invalid characters.
504 */
505 static
506 int
dk4gra_eps_set_color_if_necessary(dk4_gra_ps_page_t * bptr,dk4gra_col_t * p_col_active,dk4gra_col_t * p_col_requested,dk4_er_t * erp)507 dk4gra_eps_set_color_if_necessary(
508 	dk4_gra_ps_page_t	*bptr,
509 	dk4gra_col_t		*p_col_active,
510 	dk4gra_col_t		*p_col_requested,
511 	dk4_er_t			*erp
512 )
513 {
514 	double	 val[4];			/* Color components */
515 	int		 back	= 0;
516 
517 #if	DK4_USE_ASSERT
518 	assert(NULL != bptr);
519 	assert(NULL != p_col_active);
520 	assert(NULL != p_col_requested);
521 #endif
522 	if (0 == dk4gratool_colors_differ(p_col_active, p_col_requested)) {
523 		back = 1;
524 		goto finished;
525 	}
526 	dk4mem_cpy(p_col_active, p_col_requested, sizeof(dk4gra_col_t), NULL);
527 	switch (p_col_active->what) {
528 		case DK4_GRA_COL_SPEC_CMYK : {
529 			val[0] = p_col_active->data.cmyk.c;
530 			val[1] = p_col_active->data.cmyk.m;
531 			val[2] = p_col_active->data.cmyk.y;
532 			val[3] = p_col_active->data.cmyk.k;
533 			back = 1;
534 			dk4gra_eps_values_and_keyword(bptr, val, 4, 5, &back, erp);
535 		} break;
536 		case DK4_GRA_COL_SPEC_RGB : {
537 			val[0] = p_col_active->data.rgb.r;
538 			val[1] = p_col_active->data.rgb.g;
539 			val[2] = p_col_active->data.rgb.b;
540 			back = 1;
541 			dk4gra_eps_values_and_keyword(bptr, val, 3, 6, &back, erp);
542 		} break;
543 		case DK4_GRA_COL_SPEC_GRAY : {
544 			val[0] = p_col_active->data.gray;
545 			back = 1;
546 			dk4gra_eps_values_and_keyword(bptr, val, 1, 7, &back, erp);
547 		} break;
548 	}
549 
550 	finished:
551 
552 	return back;
553 }
554 
555 
556 
557 /**	Write dash setup.
558 	@param	bptr	Current page in gra.
559 	@param	da		Array of double values for stroke and gap lengths.
560 	@param	sz		Number of elements in array.
561 	@param	offset	Offset to start dash pattern.
562 	@param	erp		Error report, may be NULL.
563 	@return	1 on success, 0 on error.
564 
565 	Error codes:
566 	- DK4_E_INVALID_ARGUMENTS<br>
567 	  if the contents stream of the current page
568 	  is NULL or the stream is not opened for writing,
569 	- DK4_E_WRITE_FAILED<br>
570 	  if writing one ore multiple bytes to the stream failed,
571 	- DK4_E_FLUSH_FAILED<br>
572 	  if flushing data downwards failed.
573 	- DK4_E_MATH_OVERFLOW<br>
574 	  if the exponent of a doublevalue is out of range for integer values,<br>
575 	- DK4_E_SYNTAX<br>
576 	  if a double value converted to string contains invalid characters.
577 */
578 static
579 int
dk4gra_eps_dash_out(dk4_gra_ps_page_t * bptr,double * da,size_t sz,double offset,dk4_er_t * erp)580 dk4gra_eps_dash_out(
581 	dk4_gra_ps_page_t	*bptr,
582 	double				*da,
583 	size_t				 sz,
584 	double				 offset,
585 	dk4_er_t			*erp
586 )
587 {
588 	size_t	 i;				/* Traverse dash length array da */
589 	int		 back	= 1;
590 
591 #if	DK4_USE_ASSERT
592 	assert(NULL != bptr);
593 	assert(NULL != da);
594 	assert(0 < sz);
595 #endif
596 	dk4gra_eps_kw(bptr, 9, &back, erp);
597 	for (i = 0; i < sz; i++) {
598 		if (0 != i) {
599 			dk4gra_eps_kw(bptr, 3, &back, erp);
600 		}
601 		dk4gra_eps_double_value(bptr, da[i], &back, erp);
602 	}
603 	dk4gra_eps_kw(bptr, 10, &back, erp);
604 	dk4gra_eps_kw(bptr, 3, &back, erp);
605 	dk4gra_eps_double_value(bptr, offset, &back, erp);
606 	dk4gra_eps_kw(bptr, 11, &back, erp);
607 	return back;
608 }
609 
610 
611 
612 /**	Put string to output file, on error set return code and error code.
613 	@param	fout	Output file.
614 	@param	str		String to write.
615 	@param	pret	Address of return code variable.
616 	@param	erp		Error report, may be NULL.
617 
618 	Error codes:
619 	- DK4_E_WRITE_FAILED<br>
620 	  if the write attempt failed.
621 */
622 static
623 void
dk4gra_eps_string_to_file(FILE * fout,const char * str,int * pret,dk4_er_t * erp)624 dk4gra_eps_string_to_file(
625 	FILE		*fout,
626 	const char	*str,
627 	int			*pret,
628 	dk4_er_t	*erp
629 )
630 {
631 #if	DK4_USE_ASSERT
632 	assert(NULL != fout);
633 	assert(NULL != str);
634 #endif
635 	if (EOF == fputs(str, fout)) {
636 		*pret = 0;
637 		dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
638 	}
639 }
640 
641 
642 
643 /**	Construct path for page border.
644 	@param	fout	Output file to write.
645 	@param	gra		Output structure.
646 	@param	backptr	Address of success variable to reset on errors.
647 	@param	erp		Error report, may be NULL.
648 
649 	Error codes:
650 	- DK4_E_INVALID_ARGUMENTS<br>
651 	  if arguments are invalid,
652 	- DK4_E_BUFFER_TOO_SMALL<br>
653 	  if the destination buffer size is too small for the result,
654 	- DK4_E_BUG<br>
655 	  if an internal buffer is too small (should not happen),
656 	- DK4_E_WRITE_FAILED<br>
657 	  if the write attempt failed.
658 */
659 static
660 void
dk4gra_eps_page_border_path(FILE * fout,dk4_gra_t * gra,int * backptr,dk4_er_t * erp)661 dk4gra_eps_page_border_path(
662 	FILE		*fout,
663 	dk4_gra_t	*gra,
664 	int			*backptr,
665 	dk4_er_t	*erp
666 )
667 {
668 	char	b1[16*sizeof(dk4_um_t)];	/* Width as text */
669 	char	b2[16*sizeof(dk4_um_t)];	/* Height as text */
670 #if	DK4_USE_ASSERT
671 	assert(NULL != gra);
672 	assert(NULL != fout);
673 #endif
674 	(void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), gra->w, 0, erp);
675 	(void)dk4ma_write_c8_decimal_unsigned(b2, sizeof(b2), gra->h, 0, erp);
676 	/* 0 0 moveto */
677 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[23], backptr, erp);
678 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[46], backptr, erp);
679 	/* w 0 lineto */
680 	dk4gra_eps_string_to_file(fout, b1, backptr, erp);
681 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp);
682 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[47], backptr, erp);
683 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp);
684 	/* w h lineto */
685 	dk4gra_eps_string_to_file(fout, b1, backptr, erp);
686 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp);
687 	dk4gra_eps_string_to_file(fout, b2, backptr, erp);
688 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp);
689 	/* 0 h lineto */
690 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[47], backptr, erp);
691 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp);
692 	dk4gra_eps_string_to_file(fout, b2, backptr, erp);
693 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp);
694 	/* closepath */
695 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[27], backptr, erp);
696 }
697 
698 
699 /**	Write one page to output file.
700 	@param	fout	Output file.
701 	@param	gra		Output structure.
702 	@param	bptr	Current page.
703 	@param	erp		Error report, may be NULL.
704 	@return	1 on success, 0 on error.
705 */
706 static
707 int
dk4gra_eps_one_page_to_file(FILE * fout,dk4_gra_t * gra,dk4_gra_ps_page_t * bptr,dk4_er_t * erp)708 dk4gra_eps_one_page_to_file(
709 	FILE				*fout,
710 	dk4_gra_t			*gra,
711 	dk4_gra_ps_page_t	*bptr,
712 	dk4_er_t			*erp
713 )
714 {
715 	char		 		 b1[8*sizeof(dk4_um_t)];	/* Page no as text */
716 	char		 		 b2[8*sizeof(dk4_um_t)];	/* Pages number as text */
717 	const char * const	*pproc;						/* Pattern procedure name */
718 	size_t				 numpat		=	0;			/* Number of used pats */
719 	size_t				 i			=	0;			/* Traverse used pats */
720 	int					 back		=	1;
721 
722 #if	DK4_USE_ASSERT
723 	assert(NULL != gra);
724 	assert(NULL != fout);
725 #endif
726 	/*	%%Page: 1 1
727 	*/
728 	if (0 != gra->out.ps.dsc) {
729 		(void)dk4ma_write_c8_decimal_unsigned(
730 			b1, sizeof(b1), (bptr->pageno + 1), 0, erp
731 		);
732 		(void)dk4ma_write_c8_decimal_unsigned(
733 			b2, sizeof(b2), gra->pages, 0, erp
734 		);
735 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[42], &back, erp);
736 		dk4gra_eps_string_to_file(fout, b1, &back, erp);
737 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp);
738 		dk4gra_eps_string_to_file(fout, b2, &back, erp);
739 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp);
740 	}
741 
742 	/*	Count number of used patterns.
743 	*/
744 	for (i = 0; i <= DK4_GRA_PATTERN_MAX; i++) {
745 		if (0 != bptr->patu[i]) { numpat++; }
746 	}
747 
748 	/*	xxx dict begin
749 	*/
750 	if (0 != numpat) {
751 		(void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), numpat, 0, erp);
752 		dk4gra_eps_string_to_file(fout, b1, &back, erp);
753 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[43], &back, erp);
754 		for (i = 0; i <= DK4_GRA_PATTERN_MAX; i++) {
755 			if (0 != bptr->patu[i]) {
756 				pproc = dk4gra_eps_pattern_procedure(i);
757 				while (NULL != *pproc) {
758 					if (EOF == fputs(*(pproc++), fout)) { back = 0; }
759 					if (EOF == fputc('\n', fout)) { back = 0; }
760 				}
761 			}
762 		}
763 	}
764 
765 	/*	gsave
766 	*/
767 	if (0 == bptr->spip) {
768 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[1], &back, erp);
769 	}
770 
771 	/*	clip path
772 	*/
773 	if (
774 		(0 == ((bptr->flags) & DK4_GRA_PAGE_FLAG_NO_CLIP))
775 		&& (0 == bptr->spip)
776 	) {
777 		/* construct path */
778 		dk4gra_eps_page_border_path(fout, gra, &back, erp);
779 		/* clip */
780 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[21], &back, erp);
781 	}
782 
783 	/*	white page background
784 	*/
785 	if (
786 		(0 == ((bptr->flags) & DK4_GRA_PAGE_FLAG_NO_BG))
787 		&& (0 == bptr->spip)
788 	) {
789 		/* white color */
790 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[49], &back, erp);
791 		bptr->attr.col_stroke_active.what = DK4_GRA_COL_SPEC_GRAY;
792 		bptr->attr.col_stroke_active.data.gray = 1.0;
793 		/* construct path */
794 		dk4gra_eps_page_border_path(fout, gra, &back, erp);
795 		/* fill */
796 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[18], &back, erp);
797 	}
798 
799 	/*	page contents
800 	*/
801 	if (NULL != bptr->memstrm) {
802 		if (0 == dk4stream_close(bptr->memstrm, erp)) {
803 			back = 0;
804 		}
805 		bptr->memstrm = NULL;
806 	}
807 	if (NULL != bptr->membuf) {
808 		if (0 == dk4membuf_to_file(fout, bptr->membuf, erp)) {
809 			back = 0;
810 		}
811 	}
812 
813 	/*	grestore
814 	*/
815 	if (0 == bptr->spip) {
816 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[2], &back, erp);
817 	}
818 
819 	/*	end
820 	*/
821 	if (0 != numpat) {
822 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[44], &back, erp);
823 	}
824 
825 	/*	showpage
826 	*/
827 	if ((DK4_GRA_DRIVER_EPS != gra->dr) && (0 == bptr->spip)) {
828 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[45], &back, erp);
829 	}
830 
831 	return back;
832 }
833 
834 
835 
836 /**	Write pattern instance.
837 	@param	bptr	Current page.
838 	@param	da		Array of values.
839 	@param	szda	Size of da array (number of elements).
840 	@param	pname	Pattern name.
841 	@param	erp		Error report, may be NULL.
842 	@return	1 on success, 0 on error.
843 */
844 static
845 int
dk4gra_eps_write_pattern_instance(dk4_gra_ps_page_t * bptr,const double * da,size_t szda,const char * pname,dk4_er_t * erp)846 dk4gra_eps_write_pattern_instance(
847 	dk4_gra_ps_page_t	*bptr,
848 	const double		*da,
849 	size_t				 szda,
850 	const char			*pname,
851 	dk4_er_t			*erp
852 )
853 {
854 	size_t	 i;				/* Traverse da array */
855 	int		 res;			/* Operation result */
856 	int		 back = 1;
857 #if	DK4_USE_ASSERT
858 	assert(NULL != bptr);
859 	assert(NULL != da);
860 	assert(0 < szda);
861 	assert(NULL != pname);
862 #endif
863 	for (i = 0; i < szda; i++) {
864 		if (0 != i) {
865 			dk4gra_eps_kw(bptr, 3, &back, erp);
866 		}
867 		res = dk4ma_write_c8_double_no_sci_to_stream(
868 			bptr->memstrm, *(da++), DK4_GRA_EPSILON_COORDINATES, 0, 1, erp
869 		);
870 		if (0 == res) { back = 0; }
871 	}
872 	if (0 < i) {
873 		dk4gra_eps_kw(bptr, 3, &back, erp);
874 	}
875 	res = dk4stream_write_char_string(bptr->memstrm, pname, erp);
876 	if (0 == res) { back = 0; }
877 	dk4gra_eps_kw(bptr, 0, &back, erp);
878 	return back;
879 }
880 
881 
882 
883 /**	Compare page structures by number or a page against a number.
884 	@param	l	Left page object.
885 	@param	r	Right page object or page number.
886 	@param	cr	Comparison criteria (0=page/page, 1=page/number).
887 	@return	Comparison result.
888 */
889 static
890 int
dk4gra_eps_compare_pages_by_number(const void * l,const void * r,int cr)891 dk4gra_eps_compare_pages_by_number(const void *l, const void *r, int cr)
892 {
893 	const	dk4_gra_ps_page_t	*pl;		/* Left side object */
894 	const	dk4_gra_ps_page_t	*pr;		/* Right side object */
895 	const	size_t				*ppno;		/* Address of a page number */
896 
897 	int		 back	= 0;
898 	if (NULL != l) {
899 		if (NULL != r) {
900 			pl = (const dk4_gra_ps_page_t *)l;
901 			switch (cr) {
902 				case 1: {
903 					ppno = (const size_t *)r;
904 					if (pl->pageno > *ppno) {
905 						back = 1;
906 					}
907 					else {
908 						if (pl->pageno < *ppno) {
909 							back = -1;
910 						}
911 					}
912 				} break;
913 				default : {
914 					pr = (const dk4_gra_ps_page_t *)r;
915 					if (pl->pageno > pr->pageno) {
916 						back = 1;
917 					}
918 					else {
919 						if (pl->pageno < pr->pageno) {
920 							back = -1;
921 						}
922 					}
923 				} break;
924 			}
925 		}
926 		else {
927 			back = 1;
928 		}
929 	}
930 	else {
931 		if (NULL != r) {
932 			back = -1;
933 		}
934 	}
935 	return back;
936 }
937 
938 
939 
940 /**	Write PS/EPS contents to file.
941 	@param	fout	File, opened for write access.
942 	@param	gra		Output structure.
943 	@param	erp		Error report, may be NULL.
944 
945 	Error codes:
946 	- DK4_E_WRITE_FAILED<br>
947 	  if the write attempt failed.
948 	- DK4_E_FLUSH_FAILED<br>
949 	  if flushing data downwards failed,
950 	- DK4_E_CLOSE_FAILED<br>
951 	  if closing downward data failed,
952 	- DK4_E_BUFFER_TOO_SMALL<br>
953 	  if an internal buffer in this function is too small (should not happen).
954 	- DK4_E_BUG<br>
955 	  if an internal buffer in dk4ma_write_c8_decimal_unsigned()
956 	  is too small (should not happen).
957 */
958 static
959 int
dk4gra_eps_file(FILE * fout,dk4_gra_t * gra,dk4_er_t * erp)960 dk4gra_eps_file(
961 	FILE		*fout,
962 	dk4_gra_t	*gra,
963 	dk4_er_t	*erp
964 )
965 {
966 	char				 b1[8*sizeof(dk4_um_t)];	/* Buffer for numbers */
967 	char				 b2[8*sizeof(dk4_um_t)];	/* Buffer for numbers */
968 	dk4_gra_ps_page_t	*bptr;						/* Current page */
969 	int					 back	= 1;
970 
971 #if	DK4_USE_ASSERT
972 	assert(NULL != gra);
973 	assert(NULL != fout);
974 #endif
975 	/*	Document header
976 		---------------
977 	*/
978 
979 	/*	%!PS-Adobe-2.0 (EPSF...)
980 	*/
981 	if (DK4_GRA_DRIVER_EPS == gra->dr) {
982 		dk4gra_eps_string_to_file(
983 			fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (30) : (31)],
984 			&back, erp
985 		);
986 	}
987 	else {
988 		dk4gra_eps_string_to_file(
989 			fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (32) : (33)],
990 			&back, erp
991 		);
992 	}
993 
994 	/*	%%LanguageLevel
995 	*/
996 	dk4gra_eps_string_to_file(
997 		fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (34) : (35)],
998 		&back, erp
999 	);
1000 
1001 	/*	%%BoundingBox
1002 	*/
1003 	(void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), gra->w, 0, erp);
1004 	(void)dk4ma_write_c8_decimal_unsigned(b2, sizeof(b2), gra->h, 0, erp);
1005 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[36], &back, erp);
1006 	dk4gra_eps_string_to_file(fout, b1, &back, erp);
1007 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp);
1008 	dk4gra_eps_string_to_file(fout, b2, &back, erp);
1009 	dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp);
1010 
1011 
1012 	if (0 != gra->out.ps.dsc) {
1013 
1014 		/*	%%Title			-- ignored
1015 		*/
1016 
1017 		/*	%%Creator		-- ignored
1018 		*/
1019 
1020 		/*	%%CreationDate	-- ignored
1021 		*/
1022 
1023 		/*	%%Pages
1024 		*/
1025 		(void)dk4ma_write_c8_decimal_unsigned(
1026 			b1, sizeof(b1), gra->pages, 0, erp
1027 		);
1028 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[37], &back, erp);
1029 		dk4gra_eps_string_to_file(fout, b1, &back, erp);
1030 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp);
1031 
1032 
1033 		/*	%%PageOrder
1034 		*/
1035 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[38], &back, erp);
1036 
1037 		/*	%%DocumentData
1038 		*/
1039 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[39], &back, erp);
1040 
1041 		/*	%%EndComments BeginProlog EndProlog
1042 		*/
1043 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[40], &back, erp);
1044 
1045 		/*	Page setup for PS documents
1046 		*/
1047 		if (DK4_GRA_DRIVER_PS == gra->dr) {
1048 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[51], &back, erp);
1049 			/*
1050 				Paper size
1051 			*/
1052 			(void)dk4ma_write_c8_decimal_unsigned(b1,sizeof(b1),gra->w,0,erp);
1053 			(void)dk4ma_write_c8_decimal_unsigned(b2,sizeof(b2),gra->h,0,erp);
1054 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[53], &back, erp);
1055 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[55], &back, erp);
1056 			dk4gra_eps_string_to_file(fout, b1, &back, erp);
1057 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp);
1058 			dk4gra_eps_string_to_file(fout, b2, &back, erp);
1059 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[56], &back, erp);
1060 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[54], &back, erp);
1061 			/*
1062 				Duplex (and tumble)
1063 			*/
1064 			if (0 != (DK4_GRA_DOC_FLAG_TUMBLE & (gra->docfl))) {
1065 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[59],&back,erp);
1066 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[60],&back,erp);
1067 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[54],&back,erp);
1068 			}
1069 			else {
1070 				if (0 != (DK4_GRA_DOC_FLAG_DUPLEX & (gra->docfl))) {
1071 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[57],&back,erp);
1072 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[58],&back,erp);
1073 				dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[54],&back,erp);
1074 				}
1075 			}
1076 			dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[52], &back, erp);
1077 		}
1078 
1079 	}
1080 
1081 	/*	Pages
1082 		-----
1083 	*/
1084 	dk4sto_it_reset(gra->i_pages);
1085 	do {
1086 		bptr = (dk4_gra_ps_page_t *)dk4sto_it_next(gra->i_pages);
1087 		if (NULL != bptr) {
1088 			if (0 == dk4gra_eps_one_page_to_file(fout, gra, bptr, erp)) {
1089 				back = 0;
1090 			}
1091 		}
1092 	} while (NULL != bptr);
1093 
1094 
1095 	/*	Document trailer
1096 		----------------
1097 	*/
1098 
1099 	if (0 != gra->out.ps.dsc) {
1100 		/*	%%Trailer	%%EOF
1101 		*/
1102 		dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[41], &back, erp);
1103 	}
1104 
1105 	/*	Ctrl-D
1106 	*/
1107 	if (DK4_GRA_DRIVER_PS == gra->dr) {
1108 		if (EOF == fputc(0x04, fout)) {
1109 			back = 0;
1110 			dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
1111 		}
1112 	}
1113 
1114 
1115 	return back;
1116 }
1117 
1118 
1119 
1120 void
dk4gra_eps_close(dk4_gra_t * gra)1121 dk4gra_eps_close(
1122 	dk4_gra_t		*gra
1123 )
1124 {
1125 	dk4_gra_ps_page_t	*bptr;		/* Current page to release */
1126 
1127 
1128 #if	DK4_USE_ASSERT
1129 	assert(NULL != gra);
1130 #endif
1131 	if (NULL == gra) {
1132 		goto finished;
1133 	}
1134 	if (NULL != gra->s_pages) {
1135 		if (NULL != gra->i_pages) {
1136 			dk4sto_it_reset(gra->i_pages);
1137 			do {
1138 				bptr = (dk4_gra_ps_page_t *)dk4sto_it_next(gra->i_pages);
1139 				if (NULL != bptr) {
1140 					dk4gra_eps_page_delete(bptr);
1141 				}
1142 			} while (NULL != bptr);
1143 			dk4sto_it_close(gra->i_pages);
1144 			gra->i_pages = NULL;
1145 		}
1146 		dk4sto_close(gra->s_pages);
1147 		gra->s_pages = NULL;
1148 	}
1149 	dk4gratool_close(gra);
1150 
1151 	finished:
1152 
1153 	return;
1154 }
1155 
1156 
1157 
1158 dk4_gra_t *
dk4gra_eps_open(const dkChar * fn,size_t w,size_t h,int docfl,dk4_er_t * erp)1159 dk4gra_eps_open(
1160 	const dkChar	*fn,
1161 	size_t			 w,
1162 	size_t			 h,
1163 	int				 docfl,
1164 	dk4_er_t		*erp
1165 )
1166 {
1167 	dk4_gra_t	*back	= NULL;
1168 	int			 ok		= 0;
1169 
1170 #if	DK4_USE_ASSERT
1171 	assert(NULL != fn);
1172 #endif
1173 
1174 	/*	Open output structure, set up default components
1175 	*/
1176 	back = dk4gratool_open(fn, w, h, docfl, erp);
1177 	if (NULL == back) {
1178 		goto finished;
1179 	}
1180 
1181 	/*	Set driver
1182 	*/
1183 	if (0 != (DK4_GRA_DOC_FLAG_EPS & docfl)) {
1184 		back->dr = DK4_GRA_DRIVER_EPS;
1185 	}
1186 	else {
1187 		back->dr = DK4_GRA_DRIVER_PS;
1188 	}
1189 	if (0 != (DK4_GRA_DOC_FLAG_PS_DSC & docfl)) {
1190 		back->out.ps.dsc = 1;
1191 	}
1192 	if (0 != (DK4_GRA_DOC_FLAG_PS2 & docfl)) {
1193 		back->out.ps.llev = 2;
1194 	}
1195 	else {
1196 		back->out.ps.llev = 3;
1197 	}
1198 	back->out.ps.fspd = 0;
1199 	back->out.ps.fdu  = 0;
1200 	back->out.ps.ftu  = 0;
1201 
1202 	/*	Set up container and iterator for pages
1203 	*/
1204 	back->s_pages = dk4sto_open(erp);
1205 	if (NULL == back->s_pages) {
1206 		goto finished;
1207 	}
1208 	(void)dk4sto_set_comp(back->s_pages, dk4gra_eps_compare_pages_by_number, 0);
1209 	back->i_pages = dk4sto_it_open(back->s_pages, erp);
1210 	if (NULL == back->i_pages) {
1211 		goto finished;
1212 	}
1213 
1214 	/*	Indicate success to cleanup section
1215 	*/
1216 	ok = 1;
1217 
1218 	/*	End of function, clean up if not successful
1219 	*/
1220 	finished:
1221 	if ((NULL != back) && (0 == ok)) {
1222 		dk4gra_eps_close(back);
1223 		back = NULL;
1224 	}
1225 
1226 	return back;
1227 }
1228 
1229 
1230 
1231 int
dk4gra_eps_write_file_and_close(FILE * fout,dk4_gra_t * gra,dk4_er_t * erp)1232 dk4gra_eps_write_file_and_close(
1233 	FILE			*fout,
1234 	dk4_gra_t		*gra,
1235 	dk4_er_t		*erp
1236 )
1237 {
1238 	int		 back = 0;
1239 
1240 #if	DK4_USE_ASSERT
1241 	assert(NULL != gra);
1242 	assert(NULL != fout);
1243 #endif
1244 	back = dk4gra_eps_file(fout, gra, erp);
1245 	dk4gra_eps_close(gra);
1246 
1247 	return back;
1248 }
1249 
1250 
1251 
1252 int
dk4gra_eps_page(dk4_gra_t * gra,int flags,dk4_er_t * erp)1253 dk4gra_eps_page(
1254 	dk4_gra_t		*gra,
1255 	int				 flags,
1256 	dk4_er_t		*erp
1257 )
1258 {
1259 	dk4_gra_ps_page_t	*curpg;		/* New current page */
1260 	int		 			 back = 0;
1261 
1262 #if	DK4_USE_ASSERT
1263 	assert(NULL != gra);
1264 #endif
1265 	/*
1266 		Check number of pages already defined
1267 	*/
1268 	if (SIZE_MAX == gra->pages) {
1269 		dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
1270 		goto finished;
1271 	}
1272 	if ((DK4_GRA_DRIVER_EPS == gra->dr) && (0 != gra->pages)) {
1273 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1274 		goto finished;
1275 	}
1276 	/*	Create new page and add to containter and mark as current page
1277 	*/
1278 	curpg = dk4gra_eps_page_new(gra->pages, flags, erp);
1279 	if (NULL == curpg) {
1280 		goto finished;
1281 	}
1282 	/*	Add new page to pages container
1283 	*/
1284 	if (0 == dk4sto_add(gra->s_pages, curpg, erp)) {
1285 		dk4gra_eps_page_delete(curpg);
1286 		goto finished;
1287 	}
1288 	/*	Set new page as current page, indicate success
1289 	*/
1290 	gra->curpg = curpg;
1291 	gra->pages += 1;
1292 	back = 1;
1293 
1294 	finished:
1295 
1296 	return back;
1297 }
1298 
1299 
1300 
1301 int
dk4gra_eps_gsave(dk4_gra_t * gra,dk4_er_t * erp)1302 dk4gra_eps_gsave(
1303 	dk4_gra_t		*gra,
1304 	dk4_er_t		*erp
1305 )
1306 {
1307 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1308 	int					 back = 0;
1309 
1310 #if	DK4_USE_ASSERT
1311 	assert(NULL != gra);
1312 #endif
1313 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1314 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1315 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1316 		goto finished;
1317 	}
1318 	back = 1;
1319 	dk4gra_eps_kw(bptr, 1, &back, erp);
1320 	bptr->cont = 1;
1321 
1322 	finished:
1323 
1324 	return back;
1325 }
1326 
1327 
1328 
1329 int
dk4gra_eps_grestore(dk4_gra_t * gra,dk4_er_t * erp)1330 dk4gra_eps_grestore(
1331 	dk4_gra_t		*gra,
1332 	dk4_er_t		*erp
1333 )
1334 {
1335 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1336 	int					 back = 0;
1337 
1338 #if	DK4_USE_ASSERT
1339 	assert(NULL != gra);
1340 #endif
1341 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1342 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1343 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1344 		goto finished;
1345 	}
1346 	back = 1;
1347 	dk4gra_eps_kw(bptr, 2, &back, erp);
1348 	bptr->cont = 1;
1349 
1350 	finished:
1351 
1352 	return back;
1353 }
1354 
1355 
1356 
1357 int
dk4gra_eps_set_line_width(dk4_gra_t * gra,double lw,dk4_er_t * erp)1358 dk4gra_eps_set_line_width(
1359 	dk4_gra_t		*gra,
1360 	double			 lw,
1361 	dk4_er_t		*erp
1362 )
1363 {
1364 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1365 	int					 back = 0;
1366 
1367 #if	DK4_USE_ASSERT
1368 	assert(NULL != gra);
1369 #endif
1370 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1371 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1372 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1373 		goto finished;
1374 	}
1375 	bptr->attr.lw_requested = lw;
1376 	back = 1;
1377 	bptr->cont = 1;
1378 
1379 	finished:
1380 
1381 	return back;
1382 }
1383 
1384 
1385 
1386 int
dk4gra_eps_set_line_style(dk4_gra_t * gra,int ls,double sv,dk4_er_t * erp)1387 dk4gra_eps_set_line_style(
1388 	dk4_gra_t		*gra,
1389 	int				 ls,
1390 	double			 sv,
1391 	dk4_er_t		*erp
1392 )
1393 {
1394 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1395 	int					 back = 0;
1396 
1397 #if	DK4_USE_ASSERT
1398 	assert(NULL != gra);
1399 #endif
1400 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1401 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1402 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1403 		goto finished;
1404 	}
1405 	bptr->attr.ls_requested = ls;
1406 	bptr->attr.sv_requested = sv;
1407 	back = 1;
1408 	bptr->cont = 1;
1409 
1410 	finished:
1411 
1412 	return back;
1413 }
1414 
1415 
1416 
1417 int
dk4gra_eps_set_line_cap(dk4_gra_t * gra,int lc,dk4_er_t * erp)1418 dk4gra_eps_set_line_cap(
1419 	dk4_gra_t		*gra,
1420 	int				 lc,
1421 	dk4_er_t		*erp
1422 )
1423 {
1424 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1425 	int					 back = 0;
1426 
1427 #if	DK4_USE_ASSERT
1428 	assert(NULL != gra);
1429 #endif
1430 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1431 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1432 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1433 		goto finished;
1434 	}
1435 	bptr->attr.lc_requested = lc;
1436 	back = 1;
1437 	bptr->cont = 1;
1438 
1439 	finished:
1440 
1441 	return back;
1442 }
1443 
1444 
1445 
1446 int
dk4gra_eps_set_line_join(dk4_gra_t * gra,int lj,double ml,dk4_er_t * erp)1447 dk4gra_eps_set_line_join(
1448 	dk4_gra_t		*gra,
1449 	int				 lj,
1450 	double			 ml,
1451 	dk4_er_t		*erp
1452 )
1453 {
1454 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1455 	int					 back = 0;
1456 
1457 #if	DK4_USE_ASSERT
1458 	assert(NULL != gra);
1459 #endif
1460 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1461 	if ((NULL == bptr->memstrm) || (bptr->spip)) {
1462 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1463 		goto finished;
1464 	}
1465 	bptr->attr.lj_requested = lj;
1466 	bptr->attr.ml_requested = ml;
1467 	back = 1;
1468 	if (1.0 > bptr->attr.ml_requested) {
1469 		bptr->attr.ml_requested = 1.0;
1470 		back = 0;
1471 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1472 	}
1473 	bptr->cont = 1;
1474 
1475 	finished:
1476 
1477 	return back;
1478 }
1479 
1480 
1481 
1482 int
dk4gra_eps_set_fill_gray(dk4_gra_t * gra,double g,dk4_er_t * erp)1483 dk4gra_eps_set_fill_gray(
1484 	dk4_gra_t		*gra,
1485 	double			 g,
1486 	dk4_er_t		*erp
1487 )
1488 {
1489 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1490 	int					 back = 0;
1491 
1492 #if	DK4_USE_ASSERT
1493 	assert(NULL != gra);
1494 #endif
1495 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1496 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1497 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1498 		goto finished;
1499 	}
1500 	dk4gratool_set_color_requested(
1501 		&(bptr->attr.col_fill_requested),
1502 		DK4_GRA_COL_SPEC_GRAY, g, 0.0, 0.0, 0.0
1503 	);
1504 	back = 1;
1505 	bptr->cont = 1;
1506 
1507 	finished:
1508 
1509 	return back;
1510 }
1511 
1512 
1513 
1514 int
dk4gra_eps_set_fill_rgb(dk4_gra_t * gra,double r,double g,double b,dk4_er_t * erp)1515 dk4gra_eps_set_fill_rgb(
1516 	dk4_gra_t		*gra,
1517 	double			 r,
1518 	double			 g,
1519 	double			 b,
1520 	dk4_er_t		*erp
1521 )
1522 {
1523 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1524 	int					 back = 0;
1525 
1526 #if	DK4_USE_ASSERT
1527 	assert(NULL != gra);
1528 #endif
1529 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1530 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1531 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1532 		goto finished;
1533 	}
1534 	dk4gratool_set_color_requested(
1535 		&(bptr->attr.col_fill_requested),
1536 		DK4_GRA_COL_SPEC_RGB, r, g, b, 0.0
1537 	);
1538 	back = 1;
1539 	bptr->cont = 1;
1540 
1541 	finished:
1542 
1543 	return back;
1544 }
1545 
1546 
1547 
1548 int
dk4gra_eps_set_fill_cmyk(dk4_gra_t * gra,double c,double m,double y,double k,dk4_er_t * erp)1549 dk4gra_eps_set_fill_cmyk(
1550 	dk4_gra_t		*gra,
1551 	double			 c,
1552 	double			 m,
1553 	double			 y,
1554 	double			 k,
1555 	dk4_er_t		*erp
1556 )
1557 {
1558 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1559 	int					 back = 0;
1560 
1561 #if	DK4_USE_ASSERT
1562 	assert(NULL != gra);
1563 #endif
1564 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1565 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1566 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1567 		goto finished;
1568 	}
1569 	dk4gratool_set_color_requested(
1570 		&(bptr->attr.col_fill_requested),
1571 		DK4_GRA_COL_SPEC_CMYK, c, m, y, k
1572 	);
1573 	back = 1;
1574 	bptr->cont = 1;
1575 
1576 	finished:
1577 
1578 	return back;
1579 }
1580 
1581 
1582 
1583 int
dk4gra_eps_set_stroke_gray(dk4_gra_t * gra,double g,dk4_er_t * erp)1584 dk4gra_eps_set_stroke_gray(
1585 	dk4_gra_t		*gra,
1586 	double			 g,
1587 	dk4_er_t		*erp
1588 )
1589 {
1590 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1591 	int					 back = 0;
1592 
1593 #if	DK4_USE_ASSERT
1594 	assert(NULL != gra);
1595 #endif
1596 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1597 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1598 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1599 		goto finished;
1600 	}
1601 	dk4gratool_set_color_requested(
1602 		&(bptr->attr.col_stroke_requested),
1603 		DK4_GRA_COL_SPEC_GRAY, g, 0.0, 0.0, 0.0
1604 	);
1605 	back = 1;
1606 	bptr->cont = 1;
1607 
1608 	finished:
1609 
1610 	return back;
1611 }
1612 
1613 
1614 
1615 int
dk4gra_eps_set_stroke_rgb(dk4_gra_t * gra,double r,double g,double b,dk4_er_t * erp)1616 dk4gra_eps_set_stroke_rgb(
1617 	dk4_gra_t		*gra,
1618 	double			 r,
1619 	double			 g,
1620 	double			 b,
1621 	dk4_er_t		*erp
1622 )
1623 {
1624 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1625 	int					 back = 0;
1626 
1627 #if	DK4_USE_ASSERT
1628 	assert(NULL != gra);
1629 #endif
1630 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1631 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1632 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1633 		goto finished;
1634 	}
1635 	dk4gratool_set_color_requested(
1636 		&(bptr->attr.col_stroke_requested),
1637 		DK4_GRA_COL_SPEC_RGB, r, g, b, 0.0
1638 	);
1639 	back = 1;
1640 	bptr->cont = 1;
1641 
1642 	finished:
1643 
1644 	return back;
1645 }
1646 
1647 
1648 
1649 int
dk4gra_eps_set_stroke_cmyk(dk4_gra_t * gra,double c,double m,double y,double k,dk4_er_t * erp)1650 dk4gra_eps_set_stroke_cmyk(
1651 	dk4_gra_t		*gra,
1652 	double			 c,
1653 	double			 m,
1654 	double			 y,
1655 	double			 k,
1656 	dk4_er_t		*erp
1657 )
1658 {
1659 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1660 	int					 back = 0;
1661 
1662 #if	DK4_USE_ASSERT
1663 	assert(NULL != gra);
1664 #endif
1665 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1666 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1667 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1668 		goto finished;
1669 	}
1670 	dk4gratool_set_color_requested(
1671 		&(bptr->attr.col_stroke_requested),
1672 		DK4_GRA_COL_SPEC_CMYK, c, m, y, k
1673 	);
1674 	back = 1;
1675 	bptr->cont = 1;
1676 
1677 	finished:
1678 
1679 	return back;
1680 }
1681 
1682 
1683 
1684 int
dk4gra_eps_prepare_fill(dk4_gra_t * gra,dk4_er_t * erp)1685 dk4gra_eps_prepare_fill(
1686 	dk4_gra_t	*gra,
1687 	dk4_er_t	*erp
1688 )
1689 {
1690 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1691 	int					 back = 0;
1692 
1693 #if	DK4_USE_ASSERT
1694 	assert(NULL != gra);
1695 #endif
1696 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1697 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1698 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1699 		goto finished;
1700 	}
1701 	/*
1702 		Fill color
1703 	*/
1704 	back = dk4gra_eps_set_color_if_necessary(
1705 		bptr,
1706 		&(bptr->attr.col_stroke_active), &(bptr->attr.col_fill_requested),
1707 		erp
1708 	);
1709 	bptr->cont = 1;
1710 
1711 	finished:
1712 
1713 	return back;
1714 }
1715 
1716 
1717 
1718 int
dk4gra_eps_prepare_stroke(dk4_gra_t * gra,dk4_er_t * erp)1719 dk4gra_eps_prepare_stroke(
1720 	dk4_gra_t	*gra,
1721 	dk4_er_t	*erp
1722 )
1723 {
1724 	double				 da[8];			/* Dash array */
1725 	dk4_gra_ps_page_t	*bptr;			/* Current page */
1726 	double				 gw;			/* Gap width */
1727 	size_t				 lci;			/* Line cap index */
1728 	int					 res;			/* Operation result */
1729 	int					 back	= 0;	/* Function result */
1730 	int					 lwc	= 0;	/* Flag: Line width was changed */
1731 
1732 #if	DK4_USE_ASSERT
1733 	assert(NULL != gra);
1734 #endif
1735 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1736 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1737 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1738 		goto finished;
1739 	}
1740 	/*	Stroke color
1741 	*/
1742 	back = dk4gra_eps_set_color_if_necessary(
1743 		bptr,
1744 		&(bptr->attr.col_stroke_active), &(bptr->attr.col_stroke_requested),
1745 		erp
1746 	);
1747 	/*	Line width
1748 	*/
1749 	if (
1750 		DK4_GRA_EPSILON_LINEWIDTH
1751 		< fabs(bptr->attr.lw_active - bptr->attr.lw_requested)
1752 	) {
1753 		dk4gra_eps_double_value(bptr, bptr->attr.lw_requested, &back, erp);
1754 		dk4gra_eps_kw(bptr, 4, &back, erp);
1755 		lwc = 1;
1756 		bptr->attr.lw_active = bptr->attr.lw_requested;
1757 	}
1758 	/*	Line style
1759 	*/
1760 	res = dk4gratool_line_style_differs(
1761 		bptr->attr.ls_active, bptr->attr.ls_requested,
1762 		bptr->attr.sv_active, bptr->attr.sv_requested,
1763 		lwc
1764 	);
1765 	if (0 != res) {
1766 		bptr->attr.ls_active = bptr->attr.ls_requested;
1767 		bptr->attr.sv_active = bptr->attr.sv_requested;
1768 		gw = (bptr->attr.sv_active + bptr->attr.lw_active) / 2.0;
1769 		if ((2.0 * bptr->attr.lw_active) < gw) {
1770 			gw = 2.0 * bptr->attr.lw_active;
1771 		}
1772 		switch (bptr->attr.lc_requested) {
1773 			case DK4_GRA_LC_ROUNDED : case DK4_GRA_LC_PROJECTING : {
1774 				gw += bptr->attr.lw_requested;
1775 			} break;
1776 		}
1777 		switch (bptr->attr.ls_active) {
1778 			case DK4_GRA_LS_DASH : {
1779 				da[0] = bptr->attr.sv_active;
1780 				da[1] = gw;
1781 				res = dk4gra_eps_dash_out(
1782 					bptr, da, 2, (bptr->attr.sv_active / 2.0), erp
1783 				);
1784 				if (0 == res) { back = 0; }
1785 			} break;
1786 			case DK4_GRA_LS_DOT : {
1787 				da[0] = da[1] = bptr->attr.lw_active;
1788 				res = dk4gra_eps_dash_out(bptr, da, 2, 0.0, erp);
1789 				if (0 == res) { back = 0; }
1790 			} break;
1791 			case DK4_GRA_LS_DASH_DOT : {
1792 				da[0] = bptr->attr.sv_active;
1793 				da[1] = gw;
1794 				da[2] = bptr->attr.lw_active;
1795 				da[3] = gw;
1796 				res = dk4gra_eps_dash_out(
1797 					bptr, da, 4, (bptr->attr.sv_active / 2.0), erp
1798 				);
1799 				if (0 == res) { back = 0; }
1800 			} break;
1801 			case DK4_GRA_LS_DASH_DOT_DOT : {
1802 				da[0] = bptr->attr.sv_active;
1803 				da[1] = gw;
1804 				da[2] = bptr->attr.lw_active;
1805 				da[3] = gw;
1806 				da[4] = bptr->attr.lw_active;
1807 				da[5] = gw;
1808 				res = dk4gra_eps_dash_out(
1809 					bptr, da, 6, (bptr->attr.sv_active / 2.0), erp
1810 				);
1811 				if (0 == res) { back = 0; }
1812 			} break;
1813 			case DK4_GRA_LS_DASH_DOT_DOT_DOT : {
1814 				da[0] = bptr->attr.sv_active;
1815 				da[1] = gw;
1816 				da[2] = bptr->attr.lw_active;
1817 				da[3] = gw;
1818 				da[4] = bptr->attr.lw_active;
1819 				da[5] = gw;
1820 				da[6] = bptr->attr.lw_active;
1821 				da[7] = gw;
1822 				res = dk4gra_eps_dash_out(
1823 					bptr, da, 8, (bptr->attr.sv_active / 2.0), erp
1824 				);
1825 				if (0 == res) { back = 0; }
1826 			} break;
1827 			default : {
1828 				dk4gra_eps_kw(bptr, 8, &back, erp);
1829 			} break;
1830 		}
1831 	}
1832 	/*	Line cap
1833 	*/
1834 	if (bptr->attr.lc_active != bptr->attr.lc_requested) {
1835 		bptr->attr.lc_active = bptr->attr.lc_requested;
1836 		switch (bptr->attr.lc_active) {
1837 			case DK4_GRA_LC_ROUNDED : {
1838 				lci = 13;
1839 			} break;
1840 			case DK4_GRA_LC_PROJECTING : {
1841 				lci = 14;
1842 			} break;
1843 			default : {
1844 				lci = 12;
1845 			} break;
1846 		}
1847 		dk4gra_eps_kw(bptr, lci, &back, erp);
1848 	}
1849 	/*	Line join
1850 	*/
1851 	if (bptr->attr.lj_active != bptr->attr.lj_requested) {
1852 		bptr->attr.lj_active = bptr->attr.lj_requested;
1853 		switch (bptr->attr.lj_active) {
1854 			case DK4_GRA_LJ_ROUNDED : {
1855 				lci = 16;
1856 			} break;
1857 			case DK4_GRA_LJ_BEVELED : {
1858 				lci = 17;
1859 			} break;
1860 			default : {
1861 				lci = 15;
1862 			} break;
1863 		}
1864 		dk4gra_eps_kw(bptr, lci, &back, erp);
1865 	}
1866 	/*	Miter limit, only if line join is mitered
1867 	*/
1868 	if (DK4_GRA_LJ_MITERED == bptr->attr.lj_active) {
1869 		if (
1870 			DK4_GRA_EPSILON_MITERLIMIT
1871 			< fabs(bptr->attr.ml_active - bptr->attr.ml_requested)
1872 		) {
1873 			dk4gra_eps_values_and_keyword(
1874 				bptr, &(bptr->attr.ml_requested), 1, 50, &back, erp
1875 			);
1876 			bptr->attr.ml_active = bptr->attr.ml_requested;
1877 		}
1878 	}
1879 	bptr->cont = 1;
1880 
1881 	finished:
1882 
1883 	return back;
1884 }
1885 
1886 
1887 
1888 int
dk4gra_eps_fill(dk4_gra_t * gra,dk4_er_t * erp)1889 dk4gra_eps_fill(
1890 	dk4_gra_t		*gra,
1891 	dk4_er_t		*erp
1892 )
1893 {
1894 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1895 	int					 back = 0;
1896 
1897 #if	DK4_USE_ASSERT
1898 	assert(NULL != gra);
1899 #endif
1900 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1901 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1902 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1903 		goto finished;
1904 	}
1905 	back = 1;
1906 	dk4gra_eps_kw(bptr, ((0 != gra->eor) ? (19) : (18)), &back, erp);
1907 	bptr->cont = 1;
1908 
1909 	finished:
1910 
1911 	return back;
1912 }
1913 
1914 
1915 
1916 int
dk4gra_eps_stroke(dk4_gra_t * gra,dk4_er_t * erp)1917 dk4gra_eps_stroke(
1918 	dk4_gra_t		*gra,
1919 	dk4_er_t		*erp
1920 )
1921 {
1922 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1923 	int					 back = 0;
1924 
1925 #if	DK4_USE_ASSERT
1926 	assert(NULL != gra);
1927 #endif
1928 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1929 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1930 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1931 		goto finished;
1932 	}
1933 	back = 1;
1934 	dk4gra_eps_kw(bptr, 20, &back, erp);
1935 	bptr->cont = 1;
1936 
1937 	finished:
1938 
1939 	return back;
1940 }
1941 
1942 
1943 
1944 int
dk4gra_eps_clip(dk4_gra_t * gra,dk4_er_t * erp)1945 dk4gra_eps_clip(
1946 	dk4_gra_t		*gra,
1947 	dk4_er_t		*erp
1948 )
1949 {
1950 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1951 	int					 back = 0;
1952 
1953 #if	DK4_USE_ASSERT
1954 	assert(NULL != gra);
1955 #endif
1956 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1957 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1958 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1959 		goto finished;
1960 	}
1961 	back = 1;
1962 	dk4gra_eps_kw(bptr, ((0 != gra->eor) ? (22) : (21)), &back, erp);
1963 	bptr->cont = 1;
1964 
1965 	finished:
1966 
1967 	return back;
1968 }
1969 
1970 
1971 
1972 int
dk4gra_eps_pattern(dk4_gra_t * gra,int pn,double * xval,dk4_er_t * erp)1973 dk4gra_eps_pattern(
1974 	dk4_gra_t		*gra,
1975 	int				 pn,
1976 	double			*xval,
1977 	dk4_er_t		*erp
1978 )
1979 {
1980 	dk4_gra_ps_page_t	*bptr;		/* Current page */
1981 	const char			*pname;		/* Pattern name */
1982 	int					 back = 0;
1983 	int					 res;		/* Operation result */
1984 
1985 #if	DK4_USE_ASSERT
1986 	assert(NULL != gra);
1987 #endif
1988 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
1989 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
1990 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1991 		goto finished;
1992 	}
1993 	if ((0 > pn) || (DK4_GRA_PATTERN_MAX < pn)) {
1994 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1995 		goto finished;
1996 	}
1997 	/*	pn checked in previous step
1998 	*/
1999 	pname = dk4gra_eps_pattern_name((size_t)pn);
2000 	if (NULL == pname) {
2001 		dk4error_set_simple_error_code(erp, DK4_E_BUG);
2002 		goto finished;
2003 	}
2004 	bptr->patu[pn] = 0x01;
2005 
2006 	back = 1;
2007 
2008 	switch (pn) {
2009 		case DK4_GRA_PATTERN_30_DEGREE_RIGHT : {
2010 			/* ys = yb - (xe - xs) / sqrt(3) */
2011 			res = dk4gra_eps_write_pattern_instance(
2012 				bptr, xval, 5, pname, erp
2013 			); if (0 == res) { back = 0; }
2014 		} break;
2015 		case DK4_GRA_PATTERN_30_DEGREE_SIEVE : {
2016 			/* ys = yb - (xe - xs) / sqrt(3) */
2017 			res = dk4gra_eps_write_pattern_instance(
2018 				bptr, xval, 5, pname, erp
2019 			); if (0 == res) { back = 0; }
2020 		} break;
2021 		case DK4_GRA_PATTERN_45_DEGREE_LEFT : {
2022 			res = dk4gra_eps_write_pattern_instance(
2023 				bptr, xval, 5, pname, erp
2024 			); if (0 == res) { back = 0; }
2025 		} break;
2026 		case DK4_GRA_PATTERN_45_DEGREE_RIGHT : {
2027 			res = dk4gra_eps_write_pattern_instance(
2028 				bptr, xval, 5, pname, erp
2029 			); if (0 == res) { back = 0; }
2030 		} break;
2031 		case DK4_GRA_PATTERN_45_DEGREE_SIEVE : {
2032 			res = dk4gra_eps_write_pattern_instance(
2033 				bptr, xval, 5, pname, erp
2034 			); if (0 == res) { back = 0; }
2035 		} break;
2036 		case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : {
2037 			res = dk4gra_eps_write_pattern_instance(
2038 				bptr, xval, 5, pname, erp
2039 			); if (0 == res) { back = 0; }
2040 		} break;
2041 		case DK4_GRA_PATTERN_VERTICAL_BRICKS : {
2042 			res = dk4gra_eps_write_pattern_instance(
2043 				bptr, xval, 5, pname, erp
2044 			); if (0 == res) { back = 0; }
2045 		} break;
2046 		case DK4_GRA_PATTERN_HORIZONTAL_LINES : {
2047 			res = dk4gra_eps_write_pattern_instance(
2048 				bptr, xval, 5, pname, erp
2049 			); if (0 == res) { back = 0; }
2050 		} break;
2051 		case DK4_GRA_PATTERN_VERTICAL_LINES : {
2052 			res = dk4gra_eps_write_pattern_instance(
2053 				bptr, xval, 5, pname, erp
2054 			); if (0 == res) { back = 0; }
2055 		} break;
2056 		case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : {
2057 			res = dk4gra_eps_write_pattern_instance(
2058 				bptr, xval, 5, pname, erp
2059 			); if (0 == res) { back = 0; }
2060 		} break;
2061 		case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : {
2062 			res = dk4gra_eps_write_pattern_instance(
2063 				bptr, xval, 5, pname, erp
2064 			); if (0 == res) { back = 0; }
2065 		} break;
2066 		case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : {
2067 			res = dk4gra_eps_write_pattern_instance(
2068 				bptr, xval, 5, pname, erp
2069 			); if (0 == res) { back = 0; }
2070 		} break;
2071 		case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : {
2072 			res = dk4gra_eps_write_pattern_instance(
2073 				bptr, xval, 5, pname, erp
2074 			); if (0 == res) { back = 0; }
2075 		} break;
2076 		case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : {
2077 			res = dk4gra_eps_write_pattern_instance(
2078 				bptr, xval, 5, pname, erp
2079 			); if (0 == res) { back = 0; }
2080 		} break;
2081 		case DK4_GRA_PATTERN_LARGE_FISH_SCALES : {
2082 			/* xs xe ys ye dx dy r a1 a2 */
2083 			res = dk4gra_eps_write_pattern_instance(
2084 				bptr, xval, 9, pname, erp
2085 			); if (0 == res) { back = 0; }
2086 		} break;
2087 		case DK4_GRA_PATTERN_SMALL_FISH_SCALES : {
2088 			/* xs xe ys ye dx dy r a1 a2 */
2089 			res = dk4gra_eps_write_pattern_instance(
2090 				bptr, xval, 9, pname, erp
2091 			); if (0 == res) { back = 0; }
2092 		} break;
2093 		case DK4_GRA_PATTERN_CIRCLES : {
2094 			res = dk4gra_eps_write_pattern_instance(
2095 				bptr, xval, 5, pname, erp
2096 			); if (0 == res) { back = 0; }
2097 		} break;
2098 		case DK4_GRA_PATTERN_HEXAGONS : {
2099 			/* xs xe ys ye dx dy */
2100 			res = dk4gra_eps_write_pattern_instance(
2101 				bptr, xval, 6, pname, erp
2102 			); if (0 == res) { back = 0; }
2103 		} break;
2104 		case DK4_GRA_PATTERN_OCTAGONS : {
2105 			/* xs xe ys ye dx co */
2106 			res = dk4gra_eps_write_pattern_instance(
2107 				bptr, xval, 6, pname, erp
2108 			); if (0 == res) { back = 0; }
2109 		} break;
2110 		case DK4_GRA_PATTERN_HORIZONTAL_TIRES : {
2111 			res = dk4gra_eps_write_pattern_instance(
2112 				bptr, xval, 5, pname, erp
2113 			); if (0 == res) { back = 0; }
2114 		} break;
2115 		case DK4_GRA_PATTERN_VERTICAL_TIRES : {
2116 			res = dk4gra_eps_write_pattern_instance(
2117 				bptr, xval, 5, pname, erp
2118 			); if (0 == res) { back = 0; }
2119 		} break;
2120 		/* DK4_GRA_PATTERN_30_DEGREE_LEFT */
2121 		default : {
2122 			/* ys = yb - (xe - xs) / sqrt(3) */
2123 			res = dk4gra_eps_write_pattern_instance(
2124 				bptr, xval, 5, pname, erp
2125 			); if (0 == res) { back = 0; }
2126 		} break;
2127 	}
2128 	bptr->cont  = 1;
2129 
2130 	finished:
2131 
2132 	return back;
2133 }
2134 
2135 
2136 
2137 int
dk4gra_eps_newpath_moveto(dk4_gra_t * gra,double x,double y,dk4_er_t * erp)2138 dk4gra_eps_newpath_moveto(
2139 	dk4_gra_t		*gra,
2140 	double			 x,
2141 	double			 y,
2142 	dk4_er_t		*erp
2143 )
2144 {
2145 	double				 val[4];		/* Array for function call */
2146 	dk4_gra_ps_page_t	*bptr;			/* Current page */
2147 	int					 back = 0;
2148 
2149 #if	DK4_USE_ASSERT
2150 	assert(NULL != gra);
2151 #endif
2152 
2153 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2154 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2155 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2156 		goto finished;
2157 	}
2158 	back = 1;
2159 	dk4gra_eps_kw(bptr, 23, &back, erp);
2160 	val[0] = x; val[1] = y;
2161 	dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp);
2162 	bptr->cont = 1;
2163 
2164 	finished:
2165 
2166 	return back;
2167 }
2168 
2169 
2170 
2171 int
dk4gra_eps_lineto(dk4_gra_t * gra,double x,double y,dk4_er_t * erp)2172 dk4gra_eps_lineto(
2173 	dk4_gra_t		*gra,
2174 	double			 x,
2175 	double			 y,
2176 	dk4_er_t		*erp
2177 )
2178 {
2179 	double				 val[4];		/* Array for function call */
2180 	dk4_gra_ps_page_t	*bptr;			/* Current page */
2181 	int					 back = 0;
2182 
2183 #if	DK4_USE_ASSERT
2184 	assert(NULL != gra);
2185 #endif
2186 
2187 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2188 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2189 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2190 		goto finished;
2191 	}
2192 	val[0] = x; val[1] = y;
2193 	back  = 1;
2194 	dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2195 	bptr->cont = 1;
2196 
2197 	finished:
2198 
2199 	return back;
2200 }
2201 
2202 
2203 
2204 int
dk4gra_eps_curveto(dk4_gra_t * gra,double xc1,double yc1,double xc2,double yc2,double x,double y,dk4_er_t * erp)2205 dk4gra_eps_curveto(
2206 	dk4_gra_t		*gra,
2207 	double			 xc1,
2208 	double			 yc1,
2209 	double			 xc2,
2210 	double			 yc2,
2211 	double			 x,
2212 	double			 y,
2213 	dk4_er_t		*erp
2214 )
2215 {
2216 	double				 val[8];		/* Array for function call */
2217 	dk4_gra_ps_page_t	*bptr;			/* Current page */
2218 	int					 back = 0;
2219 
2220 #if	DK4_USE_ASSERT
2221 	assert(NULL != gra);
2222 #endif
2223 
2224 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2225 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2226 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2227 		goto finished;
2228 	}
2229 	val[0] = xc1; val[1] = yc1; val[2] = xc2; val[3] = yc2;
2230 	val[4] = x;   val[5] = y;
2231 	back = 1;
2232 	dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp);
2233 	bptr->cont = 1;
2234 
2235 	finished:
2236 
2237 	return back;
2238 }
2239 
2240 
2241 
2242 int
dk4gra_eps_closepath(dk4_gra_t * gra,dk4_er_t * erp)2243 dk4gra_eps_closepath(
2244 	dk4_gra_t		*gra,
2245 	dk4_er_t		*erp
2246 )
2247 {
2248 	dk4_gra_ps_page_t	*bptr;		/* Current page */
2249 	int					 back = 0;
2250 
2251 #if	DK4_USE_ASSERT
2252 	assert(NULL != gra);
2253 #endif
2254 
2255 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2256 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2257 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2258 		goto finished;
2259 	}
2260 	back = 1;
2261 	dk4gra_eps_kw(bptr, 27, &back, erp);
2262 	bptr->cont = 1;
2263 
2264 	finished:
2265 
2266 	return back;
2267 }
2268 
2269 
2270 
2271 int
dk4gra_eps_circle(dk4_gra_t * gra,double xc,double yc,double r,dk4_er_t * erp)2272 dk4gra_eps_circle(
2273 	dk4_gra_t		*gra,
2274 	double			 xc,
2275 	double			 yc,
2276 	double			 r,
2277 	dk4_er_t		*erp
2278 )
2279 {
2280 	double				 val[8];	/* Array for function call */
2281 	dk4_gra_ps_page_t	*bptr;		/* Current page */
2282 	int					 back = 0;
2283 
2284 #if	DK4_USE_ASSERT
2285 	assert(NULL != gra);
2286 #endif
2287 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2288 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2289 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2290 		goto finished;
2291 	}
2292 	back = 1;
2293 	dk4gra_eps_kw(bptr, 23, &back, erp);
2294 	val[0] = xc + r;
2295 	val[1] = yc;
2296 	dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp);
2297 	val[0] = xc; val[1] = yc; val[2] = r;
2298 	dk4gra_eps_values_and_keyword(bptr, val, 3, 28, &back, erp);
2299 	bptr->cont = 1;
2300 
2301 	finished:
2302 
2303 	return back;
2304 }
2305 
2306 
2307 
2308 int
dk4gra_eps_rectangle(dk4_gra_t * gra,double xl,double xr,double yb,double yt,double r,dk4_er_t * erp)2309 dk4gra_eps_rectangle(
2310 	dk4_gra_t		*gra,
2311 	double			 xl,
2312 	double			 xr,
2313 	double			 yb,
2314 	double			 yt,
2315 	double			 r,
2316 	dk4_er_t		*erp
2317 )
2318 {
2319 	double				 val[8];	/* Array for function call */
2320 	dk4_gra_ps_page_t	*bptr;		/* Current page */
2321 	int					 back = 0;
2322 
2323 #if	DK4_USE_ASSERT
2324 	assert(NULL != gra);
2325 #endif
2326 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2327 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2328 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2329 		goto finished;
2330 	}
2331 
2332 	/*	Correct radius if necessary
2333 	*/
2334 	back = 1;
2335 
2336 	/*	Output
2337 	*/
2338 	dk4gra_eps_kw(bptr, 23, &back, erp);
2339 	if (0.0 < r) {
2340 		val[0] = xl + r;
2341 		val[1] = yb;
2342 		dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp);
2343 		val[0] = xr - r;
2344 		val[1] = yb;
2345 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2346 		val[0] = xr - (1.0 - KAPPA_4) * r;
2347 		val[1] = yb;
2348 		val[2] = xr;
2349 		val[3] = yb + (1.0 - KAPPA_4) * r;
2350 		val[4] = xr;
2351 		val[5] = yb + r;
2352 		dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp);
2353 		val[0] = xr;
2354 		val[1] = yt - r;
2355 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2356 		val[0] = xr;
2357 		val[1] = yt - (1.0 - KAPPA_4) * r;
2358 		val[2] = xr - (1.0 - KAPPA_4) * r;
2359 		val[3] = yt;
2360 		val[4] = xr - r;
2361 		val[5] = yt;
2362 		dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp);
2363 		val[0] = xl + r;
2364 		val[1] = yt;
2365 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2366 		val[0] = xl + (1.0 - KAPPA_4) * r;
2367 		val[1] = yt;
2368 		val[2] = xl;
2369 		val[3] = yt - (1.0 - KAPPA_4) * r;
2370 		val[4] = xl;
2371 		val[5] = yt - r;
2372 		dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp);
2373 		val[0] = xl;
2374 		val[1] = yb + r;
2375 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2376 		val[0] = xl;
2377 		val[1] = yb + (1.0 - KAPPA_4) * r;
2378 		val[2] = xl + (1.0 - KAPPA_4) * r;
2379 		val[3] = yb;
2380 		val[4] = xl + r;
2381 		val[5] = yb;
2382 		dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp);
2383 		dk4gra_eps_kw(bptr, 27, &back, erp);
2384 	}
2385 	else {
2386 		val[0] = xl; val[1] = yb;
2387 		dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp);
2388 		val[0] = xr; val[1] = yb;
2389 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2390 		val[0] = xr; val[1] = yt;
2391 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2392 		val[0] = xl; val[1] = yt;
2393 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2394 		dk4gra_eps_kw(bptr, 27, &back, erp);
2395 	}
2396 	bptr->cont = 1;
2397 
2398 	finished:
2399 
2400 	return back;
2401 }
2402 
2403 
2404 
2405 int
dk4gra_eps_arc(dk4_gra_t * gra,double xc,double yc,double ra,double start,double end,int cl,dk4_er_t * erp)2406 dk4gra_eps_arc(
2407 	dk4_gra_t		*gra,
2408 	double			 xc,
2409 	double			 yc,
2410 	double			 ra,
2411 	double			 start,
2412 	double			 end,
2413 	int				 cl,
2414 	dk4_er_t		*erp
2415 )
2416 {
2417 	double				 val[8];	/* Array for function call */
2418 	dk4_gra_ps_page_t	*bptr;		/* Current page */
2419 	double				 xstart;	/* Start X coordinate */
2420 	double				 ystart;	/* Start Y coordinate */
2421 	int					 back = 0;
2422 
2423 #if	DK4_USE_ASSERT
2424 	assert(NULL != gra);
2425 #endif
2426 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2427 	if ((NULL == bptr->memstrm) || (0 != bptr->spip)) {
2428 		dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
2429 		goto finished;
2430 	}
2431 	xstart = (M_PI * start) / 180.0;
2432 	ystart = xstart;
2433 	xstart = xc + ra * cos(xstart);
2434 	ystart = yc + ra * sin(ystart);
2435 	back = 1;
2436 	dk4gra_eps_kw(bptr, 23, &back, erp);
2437 	val[0] = xstart; val[1] = ystart;
2438 	dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp);
2439 	val[0] = xc; val[1] = yc; val[2] = ra; val[3] = start; val[4] = end;
2440 	dk4gra_eps_values_and_keyword(bptr, val, 5, 29, &back, erp);
2441 	if (0 != cl) {
2442 		val[0] = xc; val[1] = yc;
2443 		dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp);
2444 		dk4gra_eps_kw(bptr, 27, &back, erp);
2445 	}
2446 	bptr->cont = 1;
2447 
2448 	finished:
2449 
2450 	return back;
2451 }
2452 
2453 
2454 
2455 void
dk4gra_eps_save_attributes(dk4_gra_t * gra)2456 dk4gra_eps_save_attributes(
2457 	dk4_gra_t	*gra
2458 )
2459 {
2460 	dk4_gra_ps_page_t	*bptr;	/* Current page */
2461 #if	DK4_USE_ASSERT
2462 	assert(NULL != gra);
2463 #endif
2464 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2465 	dk4mem_cpy(
2466 		&(bptr->catt),
2467 		&(bptr->attr),
2468 		sizeof(dk4gra_attributes_t),
2469 		NULL
2470 	);
2471 }
2472 
2473 
2474 
2475 void
dk4gra_eps_restore_attributes(dk4_gra_t * gra)2476 dk4gra_eps_restore_attributes(
2477 	dk4_gra_t	*gra
2478 )
2479 {
2480 	dk4_gra_ps_page_t	*bptr;	/* Current page */
2481 #if	DK4_USE_ASSERT
2482 	assert(NULL != gra);
2483 #endif
2484 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2485 	dk4mem_cpy(
2486 		&(bptr->attr),
2487 		&(bptr->catt),
2488 		sizeof(dk4gra_attributes_t),
2489 		NULL
2490 	);
2491 }
2492 
2493 
2494 
2495 void
dk4gra_eps_reset_attributes(dk4_gra_t * gra)2496 dk4gra_eps_reset_attributes(
2497 	dk4_gra_t	*gra
2498 )
2499 {
2500 	dk4_gra_ps_page_t	*bptr;	/* Current page */
2501 #if	DK4_USE_ASSERT
2502 	assert(NULL != gra);
2503 #endif
2504 	bptr = (dk4_gra_ps_page_t *)(gra->curpg);
2505 	dk4gratool_reset_active_attributes(&(bptr->attr));
2506 }
2507 
2508 /* vim: set ai sw=4 ts=4 : */
2509