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: dk4grat.ctr
12 */
13
14 /** @file dk4grat.c The dk4grat 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 DK4STR8_H_INCLUDED
37 #include <libdk4base/dk4str8.h>
38 #endif
39
40 #ifndef DK4STRD_H_INCLUDED
41 #include <libdk4base/dk4strd.h>
42 #endif
43
44 #ifndef DK4GRA_H_INCLUDED
45 #include <libdk4gra/dk4gra.h>
46 #endif
47
48 #ifndef DK4GRAT_H_INCLUDED
49 #include <libdk4gra/dk4grat.h>
50 #endif
51
52 #ifndef GRA_H_INCLUDED
53 #include <libdk4gra/gra.h>
54 #endif
55
56 #ifndef DK4STRM_H_INCLUDED
57 #include <libdk4c/dk4strm.h>
58 #endif
59
60 #ifndef DK4MAO8D_H_INCLUDED
61 #include <libdk4maio8d/dk4mao8d.h>
62 #endif
63
64 #ifndef DK4MAO8DNS_H_INCLUDED
65 #include <libdk4c/dk4mao8dns.h>
66 #endif
67
68 #ifndef DK4MATH_H_INCLUDED
69 #include <libdk4c/dk4math.h>
70 #endif
71
72 #ifndef DK4ITER_H_INCLUDED
73 #include <libdk4c/dk4iter.h>
74 #endif
75
76 #ifndef DK4BITSH_H_INCLUDED
77 #include <libdk4c/dk4bitsh.h>
78 #endif
79
80 #ifndef DK4EDSTM_H_INCLUDED
81 #include <libdk4c/dk4edstm.h>
82 #endif
83
84 #ifndef DK4FONTC_H_INCLUDED
85 #include <libdk4gra/dk4fontc.h>
86 #endif
87
88 #ifndef DK4UNUSED_H_INCLUDED
89 #include <libdk4base/dk4unused.h>
90 #endif
91
92 #if DK4_HAVE_ASSERT_H
93 #ifndef ASSERT_H_INCLUDED
94 #include <assert.h>
95 #define ASSERT_H_INCLUDED 1
96 #endif
97 #endif
98
99
100
101
102
103
104 /** Masks to request a single bit from a dk4_px_t value.
105 */
106 static const dk4_px_t dk4gratool_bit_values[] = {
107 0x0001, 0x0002, 0x0004, 0x0008,
108 0x0010, 0x0020, 0x0040, 0x0080,
109 0x0100, 0x0200, 0x0400, 0x0800
110 };
111
112
113
114 /** Start of standalone document, part 1.
115 */
116 static const char * const dk4gratool_text1[] = {
117 /* 0 */
118 "% PPPT_FONT_SETUP_BEGIN\n",
119
120 /* 1 */
121 "\\usepackage[T1]{fontenc}\n",
122
123 /* 2 */
124 "\\usepackage{mathptmx}\n",
125
126 /* 3 */
127 "\\usepackage[scaled=.92]{helvet}\n",
128
129 /* 4 */
130 "\\usepackage{courier}\n",
131
132 /* 5 */
133 "% PPPT_FONT_SETUP_END\n",
134
135 NULL
136
137 };
138
139
140
141 /** Start of standalone document, part 1.
142 */
143 static const char * const dk4gratool_text3[] = {
144 /* 0 */
145 "% PPPT_PACKAGES_BEGIN\n",
146
147 /* 1 */
148 "\\usepackage{textcomp}\n",
149
150 /* 2 */
151 "\\usepackage[intlimits]{amsmath}\n",
152
153 /* 3 */
154 "\\usepackage{fancybox}\n",
155
156 /* 4 */
157 "\\usepackage{graphicx}\n",
158
159 /* 5 */
160 "\\usepackage{xcolor}\n",
161
162 /* 6 */
163 "% PPPT_PACKAGES_END\n",
164
165 NULL
166
167 };
168
169
170
171 /** Start of standalone document, part 1.
172 */
173 static const char * const dk4gratool_text4[] = {
174 /* 0 */
175 "% PPPT_PDF_INFO_BEGIN\n",
176
177 /* 1 */
178 "% \\usepackage{hyperref}\n",
179
180 /* 2 */
181 "% \\hypersetup{\n",
182
183 /* 3 */
184 "% pdfauthor={Anonymous author},\n",
185
186 /* 4 */
187 "% pdftitle={Document title},\n",
188
189 /* 5 */
190 "% pdfsubject={Document subject},\n",
191
192 /* 6 */
193 "% pdfkeywords={Key,word,another}\n",
194
195 /* 7 */
196 "% }\n",
197
198 /* 8 */
199 "% PPPT_PDF_INFO_END\n",
200
201 NULL
202
203 };
204
205
206 /** Start of standalone document, part 2.
207 */
208 static const char * const dk4gratool_text2[] = {
209 /* 0 */
210 "\\pagestyle{empty}\n",
211
212 /* 1 */
213 "\\setlength{\\voffset}{-1in}\n",
214
215 /* 2 */
216 "\\setlength{\\topmargin}{0bp}\n",
217
218 /* 3 */
219 "\\setlength{\\headheight}{0bp}\n",
220
221 /* 4 */
222 "\\setlength{\\headsep}{0bp}\n",
223
224 /* 5 */
225 "\\setlength{\\topskip}{0bp}\n",
226
227 /* 6 */
228 "\\setlength{\\hoffset}{-1in}\n",
229
230 /* 7 */
231 "\\setlength{\\oddsidemargin}{0bp}\n",
232
233 /* 8 */
234 "\\setlength{\\evensidemargin}{0bp}\n",
235
236 /* 9 */
237 "\\setlength{\\marginparwidth}{0bp}\n",
238
239 /* 10 */
240 "\\setlength{\\marginparsep}{0bp}\n",
241
242 /* 11 */
243 "\\setlength{\\textwidth}{\\paperwidth}\n",
244
245 /* 12 */
246 "\\setlength{\\textheight}{\\paperheight}\n",
247
248 /* 13 */
249 "\\setlength{\\parskip}{0bp}\n",
250
251 /* 14 */
252 "\\setlength{\\parindent}{0bp}\n",
253
254 /* 15 */
255 "\\setlength{\\pdfpagewidth}{\\paperwidth}\n",
256
257 /* 16 */
258 "\\setlength{\\pdfpageheight}{\\paperheight}\n",
259
260 NULL
261
262 };
263
264
265
266 /** Constant text fragments.
267 */
268 static const char * const dk4gratool_kw[] = {
269 /* 0 */ "\n",
270 /* 1 */ "\\setlength{\\paperwidth}{",
271 /* 2 */ "\\setlength{\\paperheight}{",
272 /* 3 */ "bp}\n",
273 /* 4 */ "\\end{document}\n",
274 /* 5 */ "\\usepackage{pgfcore}\n",
275 /* 6 */ "\\color[cmyk]{",
276 /* 7 */ "\\color[gray]{",
277 /* 8 */ "\\color[rgb]{",
278 /* 9 */ "}",
279 /* 10 */ ",",
280 /* 11 */ "\\newfont{\\PPPTfo",
281 /* 12 */ "}{",
282 /* 13 */ "pt}%\n",
283 /* 14 */ " at ",
284 /* 15 */ "\\providecommand{\\PPPTfo",
285 /* 16 */ "}{}%\n",
286 /* 17 */ "\\renewcommand{\\PPPTfo",
287 /* 18 */ "}{\\normalfont",
288 /* 19 */ "\\selectfont}%\n",
289 /* 20 */ "\\fontfamily{",
290 /* 21 */ "}",
291 /* 22 */ "\\ttdefault",
292 /* 23 */ "\\sfdefault",
293 /* 24 */ "\\rmdefault",
294 /* 25 */ "\\fontseries{\\bfdefault}",
295 /* 26 */ "\\fontseries{\\mddefault}",
296 /* 27 */ "\\fontshape{\\itdefault}",
297 /* 28 */ "\\fontshape{\\updefault}",
298 /* 29 */ "\\fontsize{",
299 /* 30 */ "pt}{",
300 /* 31 */ "pt}",
301 /* 32 */ "\\begin{document}%\n",
302 /* 33 */ "\\documentclass[12pt]{article}\n",
303 /* 34 */ "\\documentclass[",
304 /* 35 */ "pt]{article}\n",
305 /* 36 */ "% PPPT_FONT_SETUP_BEGIN\n",
306 /* 37 */ "% PPPT_FONT_SETUP_END\n",
307 /* 38 */ "% PPPT_PACKAGES_BEGIN\n",
308 /* 39 */ "% PPPT_PACKAGES_END\n",
309 NULL
310 };
311
312
313
314 /** Alphabet used to translate numbers to uniqe names.
315 */
316 static const char dk4gratool_alphabet[] = {
317 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
318 };
319
320
321 dk4_gra_t *
dk4gratool_open(const dkChar * fn,size_t w,size_t h,int docfl,dk4_er_t * erp)322 dk4gratool_open(
323 const dkChar *fn,
324 size_t w,
325 size_t h,
326 int docfl,
327 dk4_er_t *erp
328 )
329 {
330 dk4_gra_t *back = NULL;
331
332 #if DK4_USE_ASSERT
333 assert(NULL != fn);
334 assert(0 < w);
335 assert(0 < h);
336 #endif
337 back = dk4mem_new(dk4_gra_t,1,erp);
338 if (NULL != back) {
339 /*
340 Initialize all components to defaults
341 */
342 dk4cs_context_init(&(back->cscctx), erp);
343 back->s_pages = NULL;
344 back->i_pages = NULL;
345 back->fn = NULL;
346 back->curpg = NULL;
347 back->pages = 0;
348 back->dr = DK4_GRA_DRIVER_PDF;
349 back->gscp = 0;
350 back->eor = 1;
351 back->w = w;
352 back->h = h;
353 back->cur_x = 0.0;
354 back->cur_y = 0.0;
355 back->patlw = 0.9;
356 back->le = 0;
357 back->lec = 0;
358 back->len = 0;
359 back->docfl = docfl;
360
361 /*
362 Allocate memory for data copies
363 */
364 if (NULL != fn) {
365 back->fn = dk4str_dup(fn, erp);
366 if (NULL == back->fn) {
367 dk4mem_free(back);
368 back = NULL;
369 }
370 }
371 }
372
373 return back;
374 }
375
376
377
378 void
dk4gratool_close(dk4_gra_t * gptr)379 dk4gratool_close(
380 dk4_gra_t *gptr
381 )
382 {
383
384 #if DK4_USE_ASSERT
385 assert(NULL != gptr);
386 #endif
387 if (NULL != gptr) {
388 if (NULL != gptr->fn) {
389 dk4mem_free(gptr->fn);
390 gptr->fn = NULL;
391 }
392 dk4mem_free(gptr);
393 }
394
395 }
396
397
398
399 int
dk4gratool_points_for_circle(dk4_gra_point_t * ptr,size_t sz,double r,dk4_er_t * erp)400 dk4gratool_points_for_circle(
401 dk4_gra_point_t *ptr,
402 size_t sz,
403 double r,
404 dk4_er_t *erp
405 )
406 {
407 double kr; /* Product of kappa and radius */
408 double krsq2; /* Product of kappa and radius divided by sqrt(2) */
409 int back = 0;
410
411 #if DK4_USE_ASSERT
412 assert(NULL != ptr);
413 assert((24 == sz) || (12 == sz));
414 assert(0.0 < r);
415 #endif
416 if ((NULL == ptr) || ((24 != sz) && (12 != sz)) || (0.0 >= r)) {
417 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
418 goto finished;
419 }
420 ptr[0].x = r;
421 ptr[0].y = 0.0;
422 if (24 == sz) {
423 kr = KAPPA_8 * r;
424 krsq2 = kr / M_SQRT2;
425 ptr[ 1].x = r;
426 ptr[ 1].y = kr;
427 ptr[ 3].x = r / M_SQRT2;
428 ptr[ 3].y = r / M_SQRT2;
429 ptr[ 2].x = ptr[3].x + krsq2;
430 ptr[ 2].y = ptr[3].y - krsq2;
431 ptr[ 4].x = ptr[3].x - krsq2;
432 ptr[ 4].y = ptr[3].y + krsq2;
433 ptr[ 5].x = kr;
434 ptr[ 5].y = r;
435 ptr[ 6].x = 0.0;
436 ptr[ 6].y = r;
437 ptr[ 7].x = 0.0 - kr;
438 ptr[ 7].y = r;
439 ptr[ 9].x = 0.0 - ptr[3].x;
440 ptr[ 9].y = ptr[3].y;
441 ptr[ 8].x = ptr[9].x + krsq2;
442 ptr[ 8].y = ptr[9].y + krsq2;
443 ptr[10].x = ptr[9].x - krsq2;
444 ptr[10].y = ptr[9].y - krsq2;
445 ptr[11].x = 0.0 - r;
446 ptr[11].y = kr;
447 ptr[12].x = 0.0 - r;
448 ptr[12].y = 0.0;
449 ptr[13].x = 0.0 - r;
450 ptr[13].y = 0.0 - kr;
451 ptr[15].x = ptr[9].x;
452 ptr[15].y = 0.0 - ptr[3].x;
453 ptr[14].x = ptr[15].x - krsq2;
454 ptr[14].y = ptr[15].y + krsq2;
455 ptr[16].x = ptr[15].x + krsq2;
456 ptr[16].y = ptr[15].y - krsq2;
457 ptr[17].x = 0.0 - kr;
458 ptr[17].y = 0.0 - r;
459 ptr[18].x = 0.0;
460 ptr[18].y = 0.0 - r;
461 ptr[19].x = kr;
462 ptr[19].y = 0.0 - r;
463 ptr[21].x = ptr[3].x;
464 ptr[21].y = 0.0 - ptr[3].y;
465 ptr[20].x = ptr[21].x - krsq2;
466 ptr[20].y = ptr[21].y - krsq2;
467 ptr[22].x = ptr[21].x + krsq2;
468 ptr[22].y = ptr[21].y + krsq2;
469 ptr[23].x = r;
470 ptr[23].y = 0.0 - kr;
471 }
472 else {
473 kr = KAPPA_4 * r;
474 ptr[ 1].x = r;
475 ptr[ 1].y = kr;
476 ptr[ 2].x = kr;
477 ptr[ 2].y = r;
478 ptr[ 3].x = 0.0;
479 ptr[ 3].y = r;
480 ptr[ 4].x = 0.0 - kr;
481 ptr[ 4].y = r;
482 ptr[ 5].x = 0.0 - r;
483 ptr[ 5].y = kr;
484 ptr[ 6].x = 0.0 - r;
485 ptr[ 6].y = 0.0;
486 ptr[ 7].x = 0.0 - r;
487 ptr[ 7].y = 0.0 - kr;
488 ptr[ 8].x = 0.0 - kr;
489 ptr[ 8].y = 0.0 - r;
490 ptr[ 9].x = 0.0;
491 ptr[ 9].y = 0.0 - r;
492 ptr[10].x = kr;
493 ptr[10].y = 0.0 - r;
494 ptr[11].x = r;
495 ptr[11].y = 0.0 - kr;
496 }
497 back = 1;
498
499 finished:
500
501 return back;
502 }
503
504
505
506 int
dk4gratool_points_for_ellipse(dk4_gra_point_t * ptr,size_t sz,double xc,double yc,double rx,double ry,double alpha,dk4_er_t * erp)507 dk4gratool_points_for_ellipse(
508 dk4_gra_point_t *ptr,
509 size_t sz,
510 double xc,
511 double yc,
512 double rx,
513 double ry,
514 double alpha,
515 dk4_er_t *erp
516 )
517 {
518 double coeff; /* Coefficient ry/rx */
519 size_t i; /* Index to traverse all points */
520 int back = 0; /* Result */
521
522 #if DK4_USE_ASSERT
523 assert(NULL != ptr);
524 assert((24 == sz) || (12 == sz));
525 assert(0.0 < rx);
526 assert(0.0 < ry);
527 #endif
528 /*
529 Check arguments
530 */
531 if (
532 (NULL == ptr) || ((24 != sz) && (12 != sz))
533 || (0.0 >= rx) || (0.0 >= ry)
534 ) {
535 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
536 goto finished;
537 }
538 /*
539 Create circle data
540 */
541 back = dk4gratool_points_for_circle(ptr, sz, rx, erp);
542 if (0 == back) { goto finished; }
543 /*
544 Scale y values for radius ry
545 */
546 coeff = ry / rx;
547 for (i = 0; i < sz; i++) {
548 ptr[i].y *= coeff;
549 }
550 /* Rotate the points if necessary
551 */
552 if (DK4_GRA_EPSILON_COORDINATES < fabs(alpha)) {
553 for (i = 0; i < sz; i++) {
554 dk4gratool_rotate_point(&(ptr[i]), alpha);
555 }
556 }
557 /* Shift to specified center point
558 */
559 for (i = 0; i < sz; i++) {
560 ptr[i].x += xc;
561 ptr[i].y += yc;
562 }
563 /* Check all coordinates for finite values.
564 */
565 for (i = 0; i < sz; i++) {
566 #if DK4_HAVE_ISFINITE
567 if ((!(isfinite(ptr[i].x))) || (!(isfinite(ptr[i].y)))) {
568 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
569 back = 0;
570 }
571 #else
572 #if DK4_HAVE__FINITE
573 if ((!(_finite(ptr[i].x))) || (!(_finite(ptr[i].y)))) {
574 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
575 back = 0;
576 }
577 #else
578
579 #endif
580 #endif
581 }
582
583 finished:
584 return back;
585 }
586
587
588
589 void
dk4gratool_rotate_point(dk4_gra_point_t * pt,double rot)590 dk4gratool_rotate_point(dk4_gra_point_t *pt, double rot)
591 {
592 double r; /* Point radius */
593 double a; /* Point angle */
594
595 #if DK4_USE_ASSERT
596 assert(NULL != pt);
597 #endif
598 r = sqrt(pt->x * pt->x + pt->y * pt->y);
599 a = atan2(pt->y, pt->x);
600 a += rot;
601 pt->x = r * cos(a);
602 pt->y = r * sin(a);
603
604 }
605
606
607
608 void
dk4gratool_initialize_attributes(dk4gra_attributes_t * pattr)609 dk4gratool_initialize_attributes(
610 dk4gra_attributes_t *pattr
611 )
612 {
613
614 #if DK4_USE_ASSERT
615 assert(NULL != pattr);
616 #endif
617 if (NULL != pattr) {
618 pattr->lc_active = -1;
619 pattr->lc_requested = DK4_GRA_LC_BUTTED;
620 pattr->lj_active = -1;
621 pattr->lj_requested = DK4_GRA_LJ_MITERED;
622 pattr->ls_active = -1;
623 pattr->ls_requested = DK4_GRA_LS_SOLID;
624 pattr->lw_active = -1.0;
625 pattr->lw_requested = 0.9;
626 pattr->sv_active = -1.0;
627 pattr->sv_requested = 4.0;
628 pattr->ml_active = 10.0;
629 pattr->ml_requested = 10.0;
630 pattr->eor_active = -1;
631 pattr->eor_requested = 0;
632 dk4mem_reset(&(pattr->col_stroke_active), sizeof(dk4gra_col_t), NULL);
633 pattr->col_stroke_active.what = DK4_GRA_COL_SPEC_NONE;
634 dk4mem_cpy(
635 &(pattr->col_fill_active), &(pattr->col_stroke_active),
636 sizeof(dk4gra_col_t), NULL
637 );
638 dk4mem_cpy(
639 &(pattr->col_stroke_requested), &(pattr->col_stroke_active),
640 sizeof(dk4gra_col_t), NULL
641 );
642 pattr->col_stroke_requested.what = DK4_GRA_COL_SPEC_GRAY;
643 pattr->col_stroke_requested.data.gray = 0.0;
644 dk4mem_cpy(
645 &(pattr->col_fill_requested), &(pattr->col_stroke_requested),
646 sizeof(dk4gra_col_t), NULL
647 );
648
649 }
650
651 }
652
653
654
655 void
dk4gratool_reset_active_attributes(dk4gra_attributes_t * pattr)656 dk4gratool_reset_active_attributes(
657 dk4gra_attributes_t *pattr
658 )
659 {
660 #if DK4_USE_ASSERT
661 assert(NULL != pattr);
662 #endif
663 pattr->col_stroke_active.what = DK4_GRA_COL_SPEC_NONE;
664 pattr->col_fill_active.what = DK4_GRA_COL_SPEC_NONE;
665 pattr->lw_active = -1.0;
666 pattr->sv_active = -1.0;
667 pattr->ml_active = -1.0;
668 pattr->lc_active = -1;
669 pattr->lj_active = -1;
670 pattr->ls_active = -1;
671 pattr->eor_active = -1;
672 }
673
674
675
676 void
dk4gratool_set_color_requested(dk4gra_col_t * pcol,int colsp,double c1,double c2,double c3,double c4)677 dk4gratool_set_color_requested(
678 dk4gra_col_t *pcol,
679 int colsp,
680 double c1,
681 double c2,
682 double c3,
683 double c4
684 )
685 {
686 #if DK4_USE_ASSERT
687 assert(NULL != pcol);
688 #endif
689 pcol->what = colsp;
690 switch (colsp) {
691 case DK4_GRA_COL_SPEC_CMYK : {
692 pcol->data.cmyk.c = c1;
693 pcol->data.cmyk.m = c2;
694 pcol->data.cmyk.y = c3;
695 pcol->data.cmyk.k = c4;
696 } break;
697 case DK4_GRA_COL_SPEC_RGB : {
698 pcol->data.rgb.r = c1;
699 pcol->data.rgb.g = c2;
700 pcol->data.rgb.b = c3;
701 } break;
702 case DK4_GRA_COL_SPEC_GRAY : {
703 pcol->data.gray = c1;
704 } break;
705 }
706 }
707
708
709
710 int
dk4gratool_colors_differ(dk4gra_col_t * p1,dk4gra_col_t * p2)711 dk4gratool_colors_differ(
712 dk4gra_col_t *p1,
713 dk4gra_col_t *p2
714 )
715 {
716 int back = 1;
717 #if DK4_USE_ASSERT
718 assert(NULL != p1);
719 assert(NULL != p2);
720 #endif
721 if (p1->what == p2->what) {
722 switch (p1->what) {
723 case DK4_GRA_COL_SPEC_CMYK : {
724 back = 0;
725 if (1.0e-3 < fabs(p1->data.cmyk.c - p2->data.cmyk.c)) {
726 back = 1;
727 }
728 if (1.0e-3 < fabs(p1->data.cmyk.m - p2->data.cmyk.m)) {
729 back = 1;
730 }
731 if (1.0e-3 < fabs(p1->data.cmyk.y - p2->data.cmyk.y)) {
732 back = 1;
733 }
734 if (1.0e-3 < fabs(p1->data.cmyk.k - p2->data.cmyk.k)) {
735 back = 1;
736 }
737 } break;
738 case DK4_GRA_COL_SPEC_RGB : {
739 back = 0;
740 if (1.0e-3 < fabs(p1->data.rgb.r - p2->data.rgb.r)) {
741 back = 1;
742 }
743 if (1.0e-3 < fabs(p1->data.rgb.g - p2->data.rgb.g)) {
744 back = 1;
745 }
746 if (1.0e-3 < fabs(p1->data.rgb.b - p2->data.rgb.b)) {
747 back = 1;
748 }
749 } break;
750 case DK4_GRA_COL_SPEC_GRAY : {
751 if (1.0e-3 >= fabs(p1->data.gray - p2->data.gray)) {
752 back = 0;
753 }
754 } break;
755 }
756 }
757 return back;
758 }
759
760
761
762 int
dk4gratool_line_style_differs(int ls_a,int ls_r,double sv_a,double sv_r,int lwc)763 dk4gratool_line_style_differs(
764 int ls_a,
765 int ls_r,
766 double sv_a,
767 double sv_r,
768 int lwc
769 )
770 {
771 int back = 1;
772
773 if (ls_a == ls_r) {
774 back = 0;
775 if (DK4_GRA_LS_SOLID != ls_a) {
776 if (0 != lwc) {
777 back = 1;
778 }
779 else {
780 if (1.0e-3 < fabs(sv_a - sv_r)) {
781 back = 1;
782 }
783 }
784 }
785 }
786
787 return back;
788 }
789
790
791
792 int
dk4gratool_calculate_transformations(double * dst,double xl,double xr,double yb,double yt,double w,double h,int kar,int pos,dk4_er_t * erp)793 dk4gratool_calculate_transformations(
794 double *dst,
795 double xl,
796 double xr,
797 double yb,
798 double yt,
799 double w,
800 double h,
801 int kar,
802 int pos,
803 dk4_er_t *erp
804 )
805 {
806 double dx; /* Available X space */
807 double dy; /* Available Y space */
808 size_t i; /* Traverse transformation values */
809 int back = 0;
810
811 #if DK4_USE_ASSERT
812 assert(NULL != dst);
813 assert(xr > xl);
814 assert(yt > yb);
815 assert(0.0 < w);
816 assert(0.0 < h);
817 #endif
818 if ((xr <= xl) || (yt <= yb) || (0.0 >= w) || (0.0 >= h)) {
819 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
820 goto finished;
821 }
822 for (i = 0; i < 5; i++) { dst[i] = 0.0; }
823 dx = xr - xl;
824 dy = yt - yb;
825 switch (pos) {
826 case 1: {
827 dst[2] = 90.0;
828 if (0 != kar) {
829 if ((w * dx) > (h * dy)) { /* Y fully used, space in X */
830 dx = (h * dy) / w;
831 dst[0] = xr - (xr - xl - dx) / 2.0;
832 dst[1] = yb;
833 }
834 else { /* X fully used, space in Y */
835 dy = (w * dx) / h;
836 dst[0] = xr;
837 dst[1] = yb + (yt - yb - dy) / 2.0;
838 }
839 dst[3] = dy;
840 dst[4] = dx;
841 }
842 else {
843 dst[0] = xr;
844 dst[1] = yb;
845 dst[3] = yt - yb;
846 dst[4] = xr - xl;
847 }
848 } break;
849 case 2: {
850 dst[2] = 180.0;
851 if (0 != kar) {
852 if ((w * dy) > (h * dx)) { /* X fully used, space in Y */
853 dy = (h * dx) / w;
854 dst[0] = xr;
855 dst[1] = yt - (yt - yb - dy) / 2.0;
856 }
857 else {
858 dx = (w * dy) / h;
859 dst[0] = xr - (xr - xl - dx) / 2.0;
860 dst[1] = yt;
861 }
862 dst[3] = dx;
863 dst[4] = dy;
864 }
865 else {
866 dst[0] = xr;
867 dst[1] = yt;
868 dst[3] = xr - xl;
869 dst[4] = yt - yb;
870 }
871 } break;
872 case 3: {
873 dst[2] = 270.0;
874 if (0 != kar) {
875 if ((w * dx) > (h * dy)) { /* Y fully used, space in X */
876 dx = (h * dy) / w;
877 dst[0] = xl + (xr - xl - dx) / 2.0;
878 dst[1] = yt;
879 }
880 else { /* X fully used, space in Y */
881 dy = (w * dx) / h;
882 dst[0] = xl;
883 dst[1] = yt - (yt - yb - dy) / 2.0;
884 }
885 dst[3] = dy;
886 dst[4] = dx;
887 }
888 else {
889 dst[0] = xl;
890 dst[1] = yt;
891 dst[3] = yt - yb;
892 dst[4] = xr - xl;
893
894 }
895 } break;
896 case 4: {
897 dst[2] = 90.0;
898 if (0 != kar) {
899 if ((w * dx) > (h * dy)) { /* Y fully used, space in X */
900 dx = (h * dy) / w;
901 dst[0] = xr - (xr - xl - dx) / 2.0;
902 dst[1] = yt;
903 }
904 else { /* X fully used, space in Y */
905 dy = (w * dx) / h;
906 dst[0] = xr;
907 dst[1] = yt - (yt - yb - dy) / 2.0;
908 }
909 dst[3] = 0.0 - dy;
910 dst[4] = dx;
911 }
912 else {
913 dst[0] = xr;
914 dst[1] = yt;
915 dst[3] = yb - yt;
916 dst[4] = xr - xl;
917 }
918 } break;
919 case 5: {
920 if (0 != kar) {
921 if ((w * dy) > (h * dx)) { /* X fully used, space in Y */
922 dy = (h * dx) / w;
923 dst[0] = xr;
924 dst[1] = yb + (yt - yb - dy) / 2.0;
925 }
926 else { /* Y fully used, space in X */
927 dx = (w * dy) / h;
928 dst[0] = xr - (xr - xl - dx) / 2.0;
929 dst[1] = yb;
930 }
931 dst[3] = 0.0 - dx;
932 dst[4] = dy;
933
934 }
935 else {
936 dst[0] = xr;
937 dst[1] = yb;
938 dst[3] = xl - xr;
939 dst[4] = yt - yb;
940 }
941 } break;
942 case 6: {
943 dst[2] = 90.0;
944 if (0 != kar) {
945 if ((w * dx) > (h * dy)) { /* Y fully used, space in X */
946 dx = (h * dy) / w;
947 dst[0] = xl + (xr - xl - dx) / 2.0;
948 dst[1] = yb;
949 }
950 else { /* X fully used, space in Y */
951 dy = (w * dx) / h;
952 dst[0] = xl;
953 dst[1] = yb + (yt - yb - dy) / 2.0;
954 }
955 dst[3] = dy;
956 dst[4] = 0.0 - dx;
957 }
958 else {
959 dst[0] = xl;
960 dst[1] = yb;
961 dst[3] = yt - yb;
962 dst[4] = xl - xr;
963 }
964 } break;
965 case 7: {
966 if (0 != kar) {
967 if ((w * dy) > (h * dx)) { /* X fully used, space in Y */
968 dy = (h * dx) / w;
969 dst[0] = xl;
970 dst[1] = yt - (yt - yb - dy) / 2.0;
971 }
972 else { /* Y fully used, space in X */
973 dx = (w * dy) / h;
974 dst[0] = xl + (xr - xl - dx) / 2.0;
975 dst[1] = yt;
976 }
977 dst[3] = dx;
978 dst[4] = 0.0 - dy;
979
980 }
981 else {
982 dst[0] = xl;
983 dst[1] = yt;
984 dst[3] = xr - xl;
985 dst[4] = yb - yt;
986 }
987 } break;
988 default : { /* 0 */
989 if (0 != kar) {
990 if ((w * dy) > (h * dx)) { /* X fully used, space in Y */
991 dy = (h * dx) / w;
992 dst[0] = xl;
993 dst[1] = yb + (yt - yb - dy) / 2.0;
994 }
995 else { /* Y fully used, space in X */
996 dx = (w * dy) / h;
997 dst[0] = xl + (xr - xl - dx) / 2.0;
998 dst[1] = yb;
999 }
1000 dst[3] = dx;
1001 dst[4] = dy;
1002 }
1003 else {
1004 dst[0] = xl;
1005 dst[1] = yb;
1006 dst[3] = (xr - xl);
1007 dst[4] = (yt - yb);
1008 }
1009 } break;
1010 }
1011
1012 back = 1;
1013 for (i = 0; i < 5; i++) {
1014 #if DK4_HAVE_ISFINITE
1015 if (!(isfinite(dst[i]))) {
1016 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
1017 back = 0;
1018 }
1019 #else
1020 #if DK4_HAVE__FINITE
1021 if (!(_finite(dst[i]))) {
1022 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
1023 back = 0;
1024 }
1025 #endif
1026 #endif
1027 }
1028
1029 finished:
1030
1031 return back;
1032 }
1033
1034
1035
1036 void
dk4gratool_stream_string(dk4_stream_t * os,const char * str,int * backptr,dk4_er_t * erp)1037 dk4gratool_stream_string(
1038 dk4_stream_t *os,
1039 const char *str,
1040 int *backptr,
1041 dk4_er_t *erp
1042 )
1043 {
1044 #if DK4_USE_ASSERT
1045 assert(NULL != os);
1046 assert(NULL != str);
1047 #endif
1048 if (0 == dk4stream_write_char_string(os, str, erp)) {
1049 if (NULL != backptr) { *backptr = 0; }
1050 }
1051 }
1052
1053
1054
1055 void
dk4gratool_stream_double(dk4_stream_t * os,double val,int * backptr,dk4_er_t * erp)1056 dk4gratool_stream_double(
1057 dk4_stream_t *os,
1058 double val,
1059 int *backptr,
1060 dk4_er_t *erp
1061 )
1062 {
1063 #if DK4_USE_ASSERT
1064 assert(NULL != os);
1065 #endif
1066 if (0 == dk4ma_write_c8_double_no_sci_to_stream(os,val,1.0e-8,0,1,erp)) {
1067 if (NULL != backptr) { *backptr = 0; }
1068 }
1069 }
1070
1071
1072
1073 void
dk4gratool_stream_uint(dk4_stream_t * os,dk4_um_t val,size_t padsz,int * backptr,dk4_er_t * erp)1074 dk4gratool_stream_uint(
1075 dk4_stream_t *os,
1076 dk4_um_t val,
1077 size_t padsz,
1078 int *backptr,
1079 dk4_er_t *erp
1080 )
1081 {
1082 char buf[16*sizeof(dk4_um_t)]; /* Buffer for val as text */
1083 #if DK4_USE_ASSERT
1084 assert(NULL != os);
1085 #endif
1086 if (0 != dk4ma_write_c8_decimal_unsigned(buf,sizeof(buf),val,padsz,erp)) {
1087 dk4gratool_stream_string(os, buf, backptr, erp);
1088 }
1089 else {
1090 if (NULL != backptr) { *backptr = 0; }
1091 }
1092 }
1093
1094
1095
1096 void
dk4gratool_stream_num_alpha(dk4_stream_t * os,size_t val,int * backptr,dk4_er_t * erp)1097 dk4gratool_stream_num_alpha(
1098 dk4_stream_t *os,
1099 size_t val,
1100 int *backptr,
1101 dk4_er_t *erp
1102 )
1103 {
1104 size_t kwi; /* Index of number in alphabet */
1105 #if DK4_USE_ASSERT
1106 assert(NULL != os);
1107 #endif
1108 do {
1109 kwi = val % (size_t)26U;
1110 val = val / (size_t)26U;
1111 if (0 == dk4stream_write_byte(os, dk4gratool_alphabet[kwi], erp)) {
1112 if (NULL != backptr) { *backptr = 0; }
1113 }
1114 } while (0 < val);
1115 }
1116
1117
1118
1119 void
dk4gratool_stream_color(dk4_stream_t * os,dk4gra_col_t const * col,int * backptr,dk4_er_t * erp)1120 dk4gratool_stream_color(
1121 dk4_stream_t *os,
1122 dk4gra_col_t const *col,
1123 int *backptr,
1124 dk4_er_t *erp
1125 )
1126 {
1127 #if DK4_USE_ASSERT
1128 assert(NULL != os);
1129 assert(NULL != col);
1130 #endif
1131 switch (col->what) {
1132 case DK4_GRA_COL_SPEC_CMYK : {
1133 dk4gratool_stream_string(os, dk4gratool_kw[6], backptr, erp);
1134 dk4gratool_stream_double(os, col->data.cmyk.c, backptr, erp);
1135 dk4gratool_stream_string(os, dk4gratool_kw[10], backptr, erp);
1136 dk4gratool_stream_double(os, col->data.cmyk.m, backptr, erp);
1137 dk4gratool_stream_string(os, dk4gratool_kw[10], backptr, erp);
1138 dk4gratool_stream_double(os, col->data.cmyk.y, backptr, erp);
1139 dk4gratool_stream_string(os, dk4gratool_kw[10], backptr, erp);
1140 dk4gratool_stream_double(os, col->data.cmyk.k, backptr, erp);
1141 dk4gratool_stream_string(os, dk4gratool_kw[9], backptr, erp);
1142 } break;
1143 case DK4_GRA_COL_SPEC_GRAY : {
1144 dk4gratool_stream_string(os, dk4gratool_kw[7], backptr, erp);
1145 dk4gratool_stream_double(os, col->data.gray, backptr, erp);
1146 dk4gratool_stream_string(os, dk4gratool_kw[9], backptr, erp);
1147 } break;
1148 default : { /* RGB */
1149 dk4gratool_stream_string(os, dk4gratool_kw[8], backptr, erp);
1150 dk4gratool_stream_double(os, col->data.rgb.r, backptr, erp);
1151 dk4gratool_stream_string(os, dk4gratool_kw[10], backptr, erp);
1152 dk4gratool_stream_double(os, col->data.rgb.g, backptr, erp);
1153 dk4gratool_stream_string(os, dk4gratool_kw[10], backptr, erp);
1154 dk4gratool_stream_double(os, col->data.rgb.b, backptr, erp);
1155 dk4gratool_stream_string(os, dk4gratool_kw[9], backptr, erp);
1156 } break;
1157 }
1158 }
1159
1160
1161
1162 double
dk4gratool_kappa_for_angle(double alpha)1163 dk4gratool_kappa_for_angle(double alpha)
1164 {
1165 double back;
1166
1167 alpha = fabs(alpha);
1168 back = (2.0 * sqrt(8.0 * (1.0 - cos(alpha))) - 4.0 * sin(alpha))
1169 / (3.0 * alpha * (1.0 - cos(alpha)));
1170
1171 return back;
1172 }
1173
1174
1175
1176 dk4_px_t
dk4gratool_bit(size_t i)1177 dk4gratool_bit(
1178 size_t i
1179 )
1180 {
1181 return (dk4gratool_bit_values[i]);
1182 }
1183
1184
1185
1186 void
dk4gratool_put_pixel_value(dk4_stream_t * strm,dk4_bit_shift_t * bs,dk4_px_t pixval,dk4_px_bit_depth_t bpc,int * backptr,dk4_er_t * erp)1187 dk4gratool_put_pixel_value(
1188 dk4_stream_t *strm,
1189 dk4_bit_shift_t *bs,
1190 dk4_px_t pixval,
1191 dk4_px_bit_depth_t bpc,
1192 int *backptr,
1193 dk4_er_t *erp
1194 )
1195 {
1196 int res;
1197 dk4_px_bit_depth_t i;
1198
1199 #if DK4_USE_ASSERT
1200 assert(NULL != strm);
1201 assert(NULL != bs);
1202 #endif
1203 for (i = 0; i < bpc; i++) {
1204 res = dk4bit_shift_add(
1205 bs,
1206 (
1207 (0 != (pixval & (dk4gratool_bit((size_t)(bpc - 1 - i)))))
1208 ? (1) : (0)
1209 ),
1210 NULL
1211 );
1212 if (DK4_EDSTM_FINISHED == res) {
1213 res = dk4stream_write_byte(
1214 strm, (char)dk4bit_shift_output(bs, NULL), erp
1215 );
1216 if (0 == res) {
1217 if (NULL != backptr) { *backptr = 0; }
1218 }
1219 }
1220 }
1221
1222 }
1223
1224
1225
1226 /** Write paragraph of text to output.
1227 @param ostrm Output stream.
1228 @param strar String array.
1229 @param bptr Address of success variable to reset on error.
1230 @param erp Error report, may be NULL.
1231 */
1232 static
1233 void
dk4gratool_paragraph_to_stream(dk4_stream_t * ostrm,const char * const * strar,int * bptr,dk4_er_t * erp)1234 dk4gratool_paragraph_to_stream(
1235 dk4_stream_t *ostrm,
1236 const char * const *strar,
1237 int *bptr,
1238 dk4_er_t *erp
1239 )
1240 {
1241 #if DK4_USE_ASSERT
1242 assert(NULL != ostrm);
1243 assert(NULL != strar);
1244 #endif
1245 if ((NULL != ostrm) && (NULL != strar)) {
1246 while (NULL != *strar) {
1247 dk4gratool_stream_string(ostrm, *(strar++), bptr, erp);
1248 }
1249 }
1250 }
1251
1252
1253
1254 void
dk4gratool_start_standalone_document(dk4_stream_t * ostrm,dk4_gra_t * gra,int pgf,double dfs,dk4_sto_t * s_f,dk4_sto_it_t * i_f,dk4_sto_t * s_p,dk4_sto_it_t * i_p,dk4_sto_t * s_o,dk4_sto_it_t * i_o,int * bptr,dk4_er_t * erp)1255 dk4gratool_start_standalone_document(
1256 dk4_stream_t *ostrm,
1257 dk4_gra_t *gra,
1258 int pgf,
1259 double dfs,
1260 dk4_sto_t *s_f,
1261 dk4_sto_it_t *i_f,
1262 dk4_sto_t *s_p,
1263 dk4_sto_it_t *i_p,
1264 dk4_sto_t *s_o,
1265 dk4_sto_it_t *i_o,
1266 int *bptr,
1267 dk4_er_t *erp
1268 )
1269 {
1270 dk4_gra_preamble_line_t *pl;
1271 int res;
1272
1273 #if DK4_USE_ASSERT
1274 assert(NULL != ostrm);
1275 assert(NULL != gra);
1276 assert(0.0 < dfs);
1277 #endif
1278 /*
1279 Document class
1280 */
1281
1282 if (0.0 < dfs) {
1283 dk4gratool_stream_string(ostrm, dk4gratool_kw[34], bptr, erp);
1284 res = dk4ma_write_c8_double_no_sci_to_stream(
1285 ostrm, dfs, 1.0e-1, 0, 0, erp
1286 );
1287 if (0 == res) { if (NULL != bptr) { *bptr = 0; } }
1288 dk4gratool_stream_string(ostrm, dk4gratool_kw[35], bptr, erp);
1289 }
1290 else {
1291 dk4gratool_stream_string(ostrm, dk4gratool_kw[33], bptr, erp);
1292 }
1293 /*
1294 Font setup
1295 */
1296 if ((NULL != s_f) && (NULL != i_f)) {
1297 dk4gratool_stream_string(ostrm, dk4gratool_kw[36], bptr, erp);
1298 dk4sto_it_reset(i_f);
1299 do {
1300 pl = (dk4_gra_preamble_line_t *)dk4sto_it_next(i_f);
1301 if (NULL != pl) {
1302 dk4gratool_stream_string(ostrm, pl->text, bptr, erp);
1303 dk4gratool_stream_string(ostrm, dk4gratool_kw[0], bptr, erp);
1304 }
1305 } while (NULL != pl);
1306 dk4gratool_stream_string(ostrm, dk4gratool_kw[37], bptr, erp);
1307 }
1308 else {
1309 dk4gratool_paragraph_to_stream(ostrm, dk4gratool_text1, bptr, erp);
1310 }
1311 /*
1312 Additional packages
1313 */
1314 if ((NULL != s_p) && (NULL != i_p)) {
1315 dk4gratool_stream_string(ostrm, dk4gratool_kw[38], bptr, erp);
1316 dk4sto_it_reset(i_p);
1317 do {
1318 pl = (dk4_gra_preamble_line_t *)dk4sto_it_next(i_p);
1319 if (NULL != pl) {
1320 dk4gratool_stream_string(ostrm, pl->text, bptr, erp);
1321 dk4gratool_stream_string(ostrm, dk4gratool_kw[0], bptr, erp);
1322 }
1323 } while (NULL != pl);
1324 dk4gratool_stream_string(ostrm, dk4gratool_kw[39], bptr, erp);
1325 }
1326 else {
1327 dk4gratool_paragraph_to_stream(ostrm, dk4gratool_text3, bptr, erp);
1328 }
1329 dk4gratool_paragraph_to_stream(ostrm, dk4gratool_text4, bptr, erp);
1330 /*
1331 /setlength{/paperwidth{xxxbp}
1332 */
1333 dk4gratool_stream_string(ostrm, dk4gratool_kw[1], bptr, erp);
1334 dk4gratool_stream_uint(ostrm, gra->w, 0, bptr, erp);
1335 dk4gratool_stream_string(ostrm, dk4gratool_kw[3], bptr, erp);
1336 /*
1337 /setlength{/paperheight{xxxbp}
1338 */
1339 dk4gratool_stream_string(ostrm, dk4gratool_kw[2], bptr, erp);
1340 dk4gratool_stream_uint(ostrm, gra->h, 0, bptr, erp);
1341 dk4gratool_stream_string(ostrm, dk4gratool_kw[3], bptr, erp);
1342 /*
1343 /usepackage{pgfcore}
1344 */
1345 if (0 != pgf) {
1346 dk4gratool_stream_string(ostrm, dk4gratool_kw[5], bptr, erp);
1347 }
1348 /*
1349 Instructions for setup
1350 */
1351 dk4gratool_paragraph_to_stream(ostrm, dk4gratool_text2, bptr, erp);
1352 /*
1353 Additional other setup lines
1354 */
1355 if ((NULL != s_o) && (NULL != i_o)) {
1356 dk4sto_it_reset(i_o);
1357 do {
1358 pl = (dk4_gra_preamble_line_t *)dk4sto_it_next(i_o);
1359 if (NULL != pl) {
1360 dk4gratool_stream_string(ostrm, pl->text, bptr, erp);
1361 dk4gratool_stream_string(ostrm, dk4gratool_kw[0], bptr, erp);
1362 }
1363 } while (NULL != pl);
1364 }
1365 /*
1366 /begin{document}
1367 */
1368 dk4gratool_stream_string(ostrm, dk4gratool_kw[32], bptr, erp);
1369
1370 }
1371
1372
1373
1374 void
dk4gratool_end_standalone_document(dk4_stream_t * ostrm,int * bptr,dk4_er_t * erp)1375 dk4gratool_end_standalone_document(
1376 dk4_stream_t *ostrm,
1377 int *bptr,
1378 dk4_er_t *erp
1379 )
1380 {
1381 #if DK4_USE_ASSERT
1382 assert(NULL != ostrm);
1383 #endif
1384 dk4gratool_stream_string(ostrm, dk4gratool_kw[4], bptr, erp);
1385 }
1386
1387
1388
1389 /** Write definition for one font from collector to output stream.
1390 @param ostrm Output stream.
1391 @param foi Font item to write.
1392 @param bptr Address of success variable to reset on error.
1393 @param erp Error report, may be NULL.
1394 */
1395 static
1396 void
dk4gratool_font_one_definition(dk4_stream_t * ostrm,dk4_font_item_t const * foi,int * bptr,dk4_er_t * erp)1397 dk4gratool_font_one_definition(
1398 dk4_stream_t *ostrm,
1399 dk4_font_item_t const *foi,
1400 int *bptr,
1401 dk4_er_t *erp
1402 )
1403 {
1404 const char *lfn = NULL; /* LaTeX font name */
1405 int ffl = 0; /* Font number or font features */
1406 int ff = 0; /* Font features mask */
1407 #if DK4_USE_ASSERT
1408 assert(NULL != ostrm);
1409 assert(NULL != foi);
1410 #endif
1411 if (DK4_GRA_TF_EXACT_SIZE == foi->fex) {
1412 lfn = dk4font_get_latex_font_name(dk4font_number_from_int(foi->fno));
1413 dk4gratool_stream_string(ostrm, dk4gratool_kw[11], bptr, erp);
1414 dk4gratool_stream_num_alpha(ostrm, foi->nf, bptr, erp);
1415 dk4gratool_stream_string(ostrm, dk4gratool_kw[12], bptr, erp);
1416 dk4gratool_stream_string(ostrm, lfn, bptr, erp);
1417 dk4gratool_stream_string(ostrm, dk4gratool_kw[14], bptr, erp);
1418 dk4gratool_stream_double(ostrm, foi->fsz, bptr, erp);
1419 dk4gratool_stream_string(ostrm, dk4gratool_kw[13], bptr, erp);
1420 }
1421 else {
1422 /* providecommand */
1423 dk4gratool_stream_string(ostrm, dk4gratool_kw[15], bptr, erp);
1424 dk4gratool_stream_num_alpha(ostrm, foi->nf, bptr, erp);
1425 dk4gratool_stream_string(ostrm, dk4gratool_kw[16], bptr, erp);
1426 /* renewcommand */
1427 dk4gratool_stream_string(ostrm, dk4gratool_kw[17], bptr, erp);
1428 dk4gratool_stream_num_alpha(ostrm, foi->nf, bptr, erp);
1429 dk4gratool_stream_string(ostrm, dk4gratool_kw[18], bptr, erp);
1430 /* Font size */
1431 switch (foi->fex) {
1432 case DK4_GRA_TF_SIMILAR_SIZE : case DK4_GRA_TF_NONE_SIZE : {
1433 dk4gratool_stream_string(ostrm, dk4gratool_kw[29], bptr, erp);
1434 dk4gratool_stream_double(ostrm, foi->fsz, bptr, erp);
1435 dk4gratool_stream_string(ostrm, dk4gratool_kw[30], bptr, erp);
1436 dk4gratool_stream_double(ostrm, (1.2 * foi->fsz), bptr, erp);
1437 dk4gratool_stream_string(ostrm, dk4gratool_kw[31], bptr, erp);
1438 } break;
1439 default : {
1440 /* Intentionally empty to avoid compiler warnings. */
1441 } break;
1442 }
1443 /* Font family, series and shape */
1444 switch (foi->fex) {
1445 case DK4_GRA_TF_EXACT_NONE :
1446 case DK4_GRA_TF_SIMILAR_SIZE :
1447 case DK4_GRA_TF_SIMILAR_NONE : {
1448 dk4gratool_stream_string(ostrm, dk4gratool_kw[20], bptr, erp);
1449 if (DK4_GRA_TF_EXACT_NONE == foi->fex) {
1450 dk4gratool_stream_string(
1451 ostrm,
1452 dk4font_get_latex_family_name(
1453 dk4font_number_from_int(foi->fno)
1454 ),
1455 bptr,
1456 erp
1457 );
1458 }
1459 else {
1460 switch (DK4_FONT_FEATURE_FT_MASK & (foi->fno)) {
1461 case DK4_FONT_FEATURE_SYMBOL : {
1462 dk4gratool_stream_string(
1463 ostrm, dk4gratool_kw[24], bptr, erp
1464 );
1465 } break;
1466 case DK4_FONT_FEATURE_TTY : {
1467 dk4gratool_stream_string(
1468 ostrm, dk4gratool_kw[22], bptr, erp
1469 );
1470 } break;
1471 case DK4_FONT_FEATURE_SANS_SERIF : {
1472 dk4gratool_stream_string(
1473 ostrm, dk4gratool_kw[23], bptr, erp
1474 );
1475 } break;
1476 default : { /* roman */
1477 dk4gratool_stream_string(
1478 ostrm, dk4gratool_kw[24], bptr, erp
1479 );
1480 } break;
1481 }
1482 /* 2019-05-14 Bugfix
1483 To find the type we must and-combine the font
1484 features with the mask bit as above.
1485 */
1486 #if 0
1487 if (0 != (DK4_FONT_FEATURE_TTY & (foi->fno))) {
1488 dk4gratool_stream_string(
1489 ostrm, dk4gratool_kw[22], bptr, erp
1490 );
1491 }
1492 else {
1493 if (0 != (DK4_FONT_FEATURE_SANS_SERIF & (foi->fno))) {
1494 dk4gratool_stream_string(
1495 ostrm, dk4gratool_kw[23], bptr, erp
1496 );
1497 }
1498 else {
1499 dk4gratool_stream_string(
1500 ostrm, dk4gratool_kw[24], bptr, erp
1501 );
1502 }
1503 }
1504 #endif
1505 }
1506 dk4gratool_stream_string(ostrm, dk4gratool_kw[21], bptr, erp);
1507 ffl = foi->fno;
1508 if (DK4_GRA_TF_EXACT_NONE == foi->fex) {
1509 ffl = dk4font_get_features(
1510 dk4font_number_from_int(foi->fno)
1511 );
1512 }
1513 if (0 != (DK4_FONT_FEATURE_BOLD & ffl)) {
1514 dk4gratool_stream_string(ostrm,dk4gratool_kw[25],bptr,erp);
1515 }
1516 else {
1517 dk4gratool_stream_string(ostrm,dk4gratool_kw[26],bptr,erp);
1518 }
1519 ff = DK4_FONT_FEATURE_ITALIC | DK4_FONT_FEATURE_OBLIQUE;
1520 if (0 != (ff & ffl)) {
1521 dk4gratool_stream_string(ostrm,dk4gratool_kw[27],bptr,erp);
1522 }
1523 else {
1524 dk4gratool_stream_string(ostrm,dk4gratool_kw[28],bptr,erp);
1525 }
1526 } break;
1527 default : {
1528 /* Intentionally empty to avoid compiler warnings. */
1529 } break;
1530 }
1531 dk4gratool_stream_string(ostrm, dk4gratool_kw[19], bptr, erp);
1532 }
1533 }
1534
1535
1536
1537 void
dk4gratool_font_definitions(dk4_stream_t * ostrm,dk4_font_collector_t * fontc,int * bptr,dk4_er_t * erp)1538 dk4gratool_font_definitions(
1539 dk4_stream_t *ostrm,
1540 dk4_font_collector_t *fontc,
1541 int *bptr,
1542 dk4_er_t *erp
1543 )
1544 {
1545 dk4_font_item_t *foi; /* Current font item to write */
1546 #if DK4_USE_ASSERT
1547 assert(NULL != ostrm);
1548 assert(NULL != fontc);
1549 #endif
1550 dk4sto_it_reset(fontc->i_fn);
1551 do {
1552 foi = (dk4_font_item_t *)dk4sto_it_next(fontc->i_fn);
1553 if (NULL != foi) {
1554 dk4gratool_font_one_definition(ostrm, foi, bptr, erp);
1555 }
1556 } while (NULL != foi);
1557 }
1558
1559
1560
1561 int
dk4gratool_compare_preamble_lines(void const * l,void const * r,int DK4_ARG_UNUSED (cr))1562 dk4gratool_compare_preamble_lines(
1563 void const *l,
1564 void const *r,
1565 int DK4_ARG_UNUSED(cr)
1566 )
1567 {
1568 dk4_gra_preamble_line_t const *pl;
1569 dk4_gra_preamble_line_t const *pr;
1570 int back = 0;
1571
1572 DK4_UNUSED_ARG(cr)
1573 if (NULL != l) {
1574 if (NULL != r) {
1575 pl = (dk4_gra_preamble_line_t const *)l;
1576 pr = (dk4_gra_preamble_line_t const *)r;
1577 if (pl->lineno > pr->lineno) {
1578 back = 1;
1579 }
1580 else {
1581 if (pl->lineno < pr->lineno) {
1582 back = -1;
1583 }
1584 }
1585 }
1586 else {
1587 back = 1;
1588 }
1589 }
1590 else {
1591 if (NULL != r) {
1592 back = -1;
1593 }
1594 }
1595 return back;
1596 }
1597
1598
1599
1600 void
dk4gratool_preamble_delete(dk4_gra_preamble_line_t * ptr)1601 dk4gratool_preamble_delete(
1602 dk4_gra_preamble_line_t *ptr
1603 )
1604 {
1605
1606 #if DK4_USE_ASSERT
1607 assert(NULL != ptr);
1608 #endif
1609 if (NULL != ptr) {
1610 if (NULL != ptr->text) {
1611 dk4mem_free(ptr->text);
1612 }
1613 dk4mem_free(ptr);
1614 }
1615
1616 }
1617
1618
1619
1620 dk4_gra_preamble_line_t *
dk4gratool_preamble_new(char const * textline,size_t lineno,dk4_er_t * erp)1621 dk4gratool_preamble_new(
1622 char const *textline,
1623 size_t lineno,
1624 dk4_er_t *erp
1625 )
1626 {
1627 dk4_gra_preamble_line_t *back = NULL;
1628
1629 #if DK4_USE_ASSERT
1630 assert(NULL != textline);
1631 #endif
1632 if (NULL != textline) {
1633 back = dk4mem_new(dk4_gra_preamble_line_t,1,erp);
1634 if (NULL != back) {
1635 back->lineno = lineno;
1636 back->text = dk4str8_dup(textline, erp);
1637 if (NULL == back->text) {
1638 dk4mem_free(back);
1639 back = NULL;
1640 }
1641 }
1642 #if TRACE_DEBUG
1643 else {
1644 }
1645 #endif
1646 }
1647 else {
1648 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1649 }
1650
1651 return back;
1652 }
1653
1654
1655
1656 double
dk4gratool_dist_point_point(dk4_gra_point_t const * a,dk4_gra_point_t const * b,dk4_er_t * erp)1657 dk4gratool_dist_point_point(
1658 dk4_gra_point_t const *a,
1659 dk4_gra_point_t const *b,
1660 dk4_er_t *erp
1661 )
1662 {
1663 double back = -1;
1664 double dx;
1665 double dy;
1666 #if DK4_USE_ASSERT
1667 assert(NULL != a);
1668 assert(NULL != b);
1669 #endif
1670 if ((NULL != a) && (NULL != b)) {
1671 dx = b->x - a->x;
1672 dy = b->y - a->y;
1673 back = sqrt(dx * dx + dy * dy);
1674 }
1675 else {
1676 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1677 }
1678 return back;
1679 }
1680
1681
1682
1683 /** Calculate square value.
1684 @param x Original value.
1685 @return Square value.
1686 */
1687
1688 static
1689 double
dbl_sq(double x)1690 dbl_sq(double x)
1691 {
1692 return (x * x);
1693 }
1694
1695
1696 double
dk4gratool_dist_point_track(dk4_gra_point_t const * a,dk4_gra_point_t const * b,dk4_gra_point_t const * p,dk4_er_t * erp)1697 dk4gratool_dist_point_track(
1698 dk4_gra_point_t const *a,
1699 dk4_gra_point_t const *b,
1700 dk4_gra_point_t const *p,
1701 dk4_er_t *erp
1702 )
1703 {
1704 dk4_gra_point_t q;
1705 double back = -1.0;
1706 double z;
1707 double n;
1708 double t;
1709 #if DK4_USE_ASSERT
1710 assert(NULL != a);
1711 assert(NULL != b);
1712 assert(NULL != p);
1713 #endif
1714 if ((NULL != a) && (NULL != b) && (NULL != p)) {
1715 z = (b->y - a->y) * p->y - a->y * b->y + dbl_sq(a->y);
1716 z += (b->x - a->x) * p->x - a->x * b->x + dbl_sq(a->x);
1717 n = dbl_sq(b->y) - 2.0 * a->y * b->y + dbl_sq(a->y);
1718 n += dbl_sq(b->x) - 2.0 * a->x * b->x + dbl_sq(a->x);
1719 t = z / n;
1720 if ((0 != dk4ma_is_finite(t)) && (0.0 <= t) && (1.0 >= t)) {
1721 q.x = a->x + t * (b->x - a->x);
1722 q.y = a->y + t * (b->y - a->y);
1723 back = dk4gratool_dist_point_point(&q, p, erp);
1724 }
1725 else {
1726 z = dk4gratool_dist_point_point(a, p, erp);
1727 n = dk4gratool_dist_point_point(b, p, erp);
1728 back = ((z <= n) ? (z) : (n));
1729 }
1730 }
1731 else {
1732 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1733 }
1734 return back;
1735 }
1736
1737
1738
1739 double
dk4gratool_dist_point_ellipse_simple(double rx,double ry,dk4_gra_point_t const * p)1740 dk4gratool_dist_point_ellipse_simple(
1741 double rx,
1742 double ry,
1743 dk4_gra_point_t const *p
1744 )
1745 {
1746 double px;
1747 double back = -1.0;
1748
1749 #if DK4_USE_ASSERT
1750 assert(NULL != p);
1751 assert(0.0 < rx);
1752 assert(0.0 < ry);
1753 #endif
1754 px = (ry * p->x) / rx;
1755 back = sqrt((px * px) + (p->y * p->y));
1756 back = fabs(back - ry);
1757 back = (back * rx) / ry;
1758
1759 return back;
1760 }
1761
1762
1763
1764 double
dk4gratool_dist_point_ellipse(dk4_gra_point_t const * c,double rx,double ry,double rot,dk4_gra_point_t const * p,dk4_er_t * erp)1765 dk4gratool_dist_point_ellipse(
1766 dk4_gra_point_t const *c,
1767 double rx,
1768 double ry,
1769 double rot,
1770 dk4_gra_point_t const *p,
1771 dk4_er_t *erp
1772 )
1773 {
1774 dk4_gra_point_t myp;
1775 double back = -1.0;
1776 #if DK4_USE_ASSERT
1777 assert(NULL != c);
1778 assert(NULL != p);
1779 assert(0.0 < rx);
1780 assert(0.0 < ry);
1781 #endif
1782 if ((NULL != c) && (NULL != p) && (0.0 < rx) && (0.0 < ry)) {
1783 DK4_MEMCPY(&myp,p,sizeof(dk4_gra_point_t));
1784 myp.x -= c->x;
1785 myp.y -= c->y;
1786 if (1.0e-8 <= fabs(rot)) {
1787 dk4gratool_rotate_point(&myp, (0.0 - rot));
1788 }
1789 back = dk4gratool_dist_point_ellipse_simple(rx, ry, &myp);
1790 }
1791 else {
1792 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
1793 }
1794 return back;
1795 }
1796
1797
1798
1799 /* vim: set ai sw=4 ts=4 : */
1800
1801