1 /*
2 Copyright (C) 2013-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: f2lto.ctr
12 */
13
14 /** @file f2lto.c The f2lto module.
15 */
16
17
18 #include <libdk3c/dk3all.h>
19 #include <libdk3c/dk3bezcu.h>
20 #include <fig2lat/fig2lat.h>
21 #include <fig2lat/f2lud.h>
22 #include <fig2lat/f2lsvg.h>
23 #include <libdk3fig/dk3figto.h>
24 #if 0
25 #include <libdk3c/dkt-version.h>
26 #endif
27 #include <libdk4base/dk4vers.h>
28 #include <libdk3fig/dk3font.h>
29 #include <libdk3bmeps/dk3bm.h>
30 #include <libdk3bmeps/dk3bmeps.h>
31
32
33
34
35
36
37 /** LaTeX encodings for 0x00-0xFF.
38 */
39 static char const * const f2l_tool_l2l_enc[] = {
40 /* 000 00 */ "",
41 /* 001 01 */ "",
42 /* 002 02 */ "",
43 /* 003 03 */ "",
44 /* 004 04 */ "",
45 /* 005 05 */ "",
46 /* 006 06 */ "",
47 /* 007 07 */ "",
48 /* 008 08 */ "",
49 /* 009 09 */ "\t",
50 /* 010 0a */ "\\\\*",
51 /* 011 0b */ "",
52 /* 012 0c */ "",
53 /* 013 0d */ "",
54 /* 014 0e */ "",
55 /* 015 0f */ "",
56 /* 016 10 */ "",
57 /* 017 11 */ "",
58 /* 018 12 */ "",
59 /* 019 13 */ "",
60 /* 020 14 */ "",
61 /* 021 15 */ "",
62 /* 022 16 */ "",
63 /* 023 17 */ "",
64 /* 024 18 */ "",
65 /* 025 19 */ "",
66 /* 026 1a */ "",
67 /* 027 1b */ "",
68 /* 028 1c */ "",
69 /* 029 1d */ "",
70 /* 030 1e */ "",
71 /* 031 1f */ "",
72 /* 032 20 */ " ",
73 /* 033 21 */ "!",
74 /* 034 22 */ "\\textquotedbl{}",
75 /* 035 23 */ "\\#",
76 /* 036 24 */ "\\textdollar{}",
77 /* 037 25 */ "\\%",
78 /* 038 26 */ "\\&",
79 /* 039 27 */ "\\textquoteright{}",
80 /* 040 28 */ "(",
81 /* 041 29 */ ")",
82 /* 042 2a */ "\\textasteriskcentered{}",
83 /* 043 2b */ "+",
84 /* 044 2c */ ",",
85 /* 045 2d */ "-",
86 /* 046 2e */ ".",
87 /* 047 2f */ "/",
88 /* 048 30 */ "0",
89 /* 049 31 */ "1",
90 /* 050 32 */ "2",
91 /* 051 33 */ "3",
92 /* 052 34 */ "4",
93 /* 053 35 */ "5",
94 /* 054 36 */ "6",
95 /* 055 37 */ "7",
96 /* 056 38 */ "8",
97 /* 057 39 */ "9",
98 /* 058 3a */ ":",
99 /* 059 3b */ ";",
100 /* 060 3c */ "\\textless{}",
101 /* 061 3d */ "=",
102 /* 062 3e */ "\\textgreater{}",
103 /* 063 3f */ "?",
104 /* 064 40 */ "@",
105 /* 065 41 */ "A",
106 /* 066 42 */ "B",
107 /* 067 43 */ "C",
108 /* 068 44 */ "D",
109 /* 069 45 */ "E",
110 /* 070 46 */ "F",
111 /* 071 47 */ "G",
112 /* 072 48 */ "H",
113 /* 073 49 */ "I",
114 /* 074 4a */ "J",
115 /* 075 4b */ "K",
116 /* 076 4c */ "L",
117 /* 077 4d */ "M",
118 /* 078 4e */ "N",
119 /* 079 4f */ "O",
120 /* 080 50 */ "P",
121 /* 081 51 */ "Q",
122 /* 082 52 */ "R",
123 /* 083 53 */ "S",
124 /* 084 54 */ "T",
125 /* 085 55 */ "U",
126 /* 086 56 */ "V",
127 /* 087 57 */ "W",
128 /* 088 58 */ "X",
129 /* 089 59 */ "Y",
130 /* 090 5a */ "Z",
131 /* 091 5b */ "[",
132 /* 092 5c */ "\\textbackslash{}",
133 /* 093 5d */ "]",
134 /* 094 5e */ "\\textasciicircum{}",
135 /* 095 5f */ "\\textunderscore{}",
136 /* 096 60 */ "\\textasciigrave{}",
137 /* 097 61 */ "a",
138 /* 098 62 */ "b",
139 /* 099 63 */ "c",
140 /* 100 64 */ "d",
141 /* 101 65 */ "e",
142 /* 102 66 */ "f",
143 /* 103 67 */ "g",
144 /* 104 68 */ "h",
145 /* 105 69 */ "i",
146 /* 106 6a */ "j",
147 /* 107 6b */ "k",
148 /* 108 6c */ "l",
149 /* 109 6d */ "m",
150 /* 110 6e */ "n",
151 /* 111 6f */ "o",
152 /* 112 70 */ "p",
153 /* 113 71 */ "q",
154 /* 114 72 */ "r",
155 /* 115 73 */ "s",
156 /* 116 74 */ "t",
157 /* 117 75 */ "u",
158 /* 118 76 */ "v",
159 /* 119 77 */ "w",
160 /* 120 78 */ "x",
161 /* 121 79 */ "y",
162 /* 122 7a */ "z",
163 /* 123 7b */ "\\textbraceleft{}",
164 /* 124 7c */ "\\textbar{}",
165 /* 125 7d */ "\\textbraceright{}",
166 /* 126 7e */ "\\textasciitilde{}",
167 /* 127 7f */ "",
168 /* 128 80 */ "",
169 /* 129 81 */ "",
170 /* 130 82 */ "",
171 /* 131 83 */ "",
172 /* 132 84 */ "",
173 /* 133 85 */ "",
174 /* 134 86 */ "",
175 /* 135 87 */ "",
176 /* 136 88 */ "",
177 /* 137 89 */ "",
178 /* 138 8a */ "",
179 /* 139 8b */ "",
180 /* 140 8c */ "",
181 /* 141 8d */ "",
182 /* 142 8e */ "",
183 /* 143 8f */ "",
184 /* 144 90 */ "",
185 /* 145 91 */ "",
186 /* 146 92 */ "",
187 /* 147 93 */ "",
188 /* 148 94 */ "",
189 /* 149 95 */ "",
190 /* 150 96 */ "",
191 /* 151 97 */ "",
192 /* 152 98 */ "",
193 /* 153 99 */ "",
194 /* 154 9a */ "",
195 /* 155 9b */ "",
196 /* 156 9c */ "",
197 /* 157 9d */ "",
198 /* 158 9e */ "",
199 /* 159 9f */ "",
200 /* 160 a0 */ "",
201 /* 161 a1 */ "\\textexclamdown{}",
202 /* 162 a2 */ "\\textcentoldstyle{}",
203 /* 163 a3 */ "\\textstirling{}",
204 /* 164 a4 */ "\\textcurrency{}",
205 /* 165 a5 */ "\\textyen{}",
206 /* 166 a6 */ "\\textbrokenbar{}",
207 /* 167 a7 */ "\\textsection{}",
208 /* 168 a8 */ "\\textasciidieresis{}",
209 /* 169 a9 */ "\\textcopyright{}",
210 /* 170 aa */ "\\textordfeminine{}",
211 /* 171 ab */ "\\quillemotleft{}",
212 /* 172 ac */ "\\textlnot{}",
213 /* 173 ad */ "",
214 /* 174 ae */ "\\textregistered{}",
215 /* 175 af */ "\\textasciimacron{}",
216 /* 176 b0 */ "\\textdegree{}",
217 /* 177 b1 */ "\\textpm{}",
218 /* 178 b2 */ "\\texttwosuperior{}",
219 /* 179 b3 */ "\\textthreesuperior{}",
220 /* 180 b4 */ "\\textasciiacute{}",
221 /* 181 b5 */ "\\textmu{}",
222 /* 182 b6 */ "\\P{}",
223 /* 183 b7 */ "\\textperiodcentered{}",
224 /* 184 b8 */ "\\c{}",
225 /* 185 b9 */ "\\textonesuperior{}",
226 /* 186 ba */ "\\textordmasculine{}",
227 /* 187 bb */ "\\quillemotright{}",
228 /* 188 bc */ "\\textonequarter{}",
229 /* 189 bd */ "\\textonehalf{}",
230 /* 190 be */ "\\textthreequarters{}",
231 /* 191 bf */ "?`",
232 /* 192 c0 */ "\\`{A}",
233 /* 193 c1 */ "\\'{A}",
234 /* 194 c2 */ "\\^{A}",
235 /* 195 c3 */ "\\~{A}",
236 /* 196 c4 */ "\\\"{A}",
237 /* 197 c5 */ "\\AA{}",
238 /* 198 c6 */ "\\AE{}",
239 /* 199 c7 */ "\\c{C}",
240 /* 200 c8 */ "\\`{E}",
241 /* 201 c9 */ "\\'{E}",
242 /* 202 ca */ "\\^{E}",
243 /* 203 cb */ "\\\"{E}",
244 /* 204 cc */ "\\`{I}",
245 /* 205 cd */ "\\'{I}",
246 /* 206 ce */ "\\^{I}",
247 /* 207 cf */ "\\\"{I}",
248 /* 208 d0 */ "\\DH{}",
249 /* 209 d1 */ "\\~{N}",
250 /* 210 d2 */ "\\`{O}",
251 /* 211 d3 */ "\\'{O}",
252 /* 212 d4 */ "\\^{O}",
253 /* 213 d5 */ "\\~{O}",
254 /* 214 d6 */ "\\\"{O}",
255 /* 215 d7 */ "\\texttimes{}",
256 /* 216 d8 */ "\\O{}",
257 /* 217 d9 */ "\\`{U}",
258 /* 218 da */ "\\'{U}",
259 /* 219 db */ "\\^{U}",
260 /* 220 dc */ "\\\"{U}",
261 /* 221 dd */ "\\'{Y}",
262 /* 222 de */ "\\TH{}",
263 /* 223 df */ "\\ss{}",
264 /* 224 e0 */ "\\`{a}",
265 /* 225 e1 */ "\\'{a}",
266 /* 226 e2 */ "\\^{a}",
267 /* 227 e3 */ "\\~{a}",
268 /* 228 e4 */ "\\\"{a}",
269 /* 229 e5 */ "\\aa{}",
270 /* 230 e6 */ "\\ae{}",
271 /* 231 e7 */ "\\c{c}",
272 /* 232 e8 */ "\\`{e}",
273 /* 233 e9 */ "\\'{e}",
274 /* 234 ea */ "\\^{e}",
275 /* 235 eb */ "\\\"{e}",
276 /* 236 ec */ "\\`{i}",
277 /* 237 ed */ "\\'{i}",
278 /* 238 ee */ "\\^{i}",
279 /* 239 ef */ "\\\"{i}",
280 /* 240 f0 */ "\\dh{}",
281 /* 241 f1 */ "\\~{n}",
282 /* 242 f2 */ "\\`{o}",
283 /* 243 f3 */ "\\'{o}",
284 /* 244 f4 */ "\\^{o}",
285 /* 245 f5 */ "\\~{o}",
286 /* 246 f6 */ "\\\"{o}",
287 /* 247 f7 */ "\\textdiv{}",
288 /* 248 f8 */ "\\o{}",
289 /* 249 f9 */ "\\`{u}",
290 /* 250 fa */ "\\'{u}",
291 /* 251 fb */ "\\^{u}",
292 /* 252 fc */ "\\\"{u}",
293 /* 253 fd */ "\\'{y}",
294 /* 254 fe */ "\\th{}",
295 /* 255 ff */ "\\\"{y}"
296 };
297
298
299 /** Keywords used by the module.
300 */
301 static char const * const f2lto_c8_kw[] = {
302 /* 0 */
303 "\\begin{picture}(0,0)\n",
304
305 /* 1 */
306 "\\end{picture}%\n",
307
308 /* 2 */
309 "\\includegraphics{",
310
311 /* 3 */
312 "}\n",
313
314 /* 4 */
315 "\\setlength{\\unitlength}{1bp}%\n",
316
317 /* 5 */
318 "\\begin{picture}(%ld,%ld)\n",
319
320 /* 6 */
321 "\\newfont{",
322
323 /* 7 */
324 "}{",
325
326 /* 8 */
327 "}%\n",
328
329 /* 9 */
330 "\\FigToLatFont",
331
332 /* 10 */
333 "ptmr",
334
335 /* 11 */
336 " at ",
337
338 /* 12 */
339 "pt",
340
341 /* 13 */
342 "\\put(",
343
344 /* 14 */
345 ",",
346
347 /* 15 */
348 "){",
349
350 /* 16 */
351 "}",
352
353 /* 17 */
354 "\\rotatebox{",
355
356 /* 18 */
357 "\\makebox(0,0)[",
358
359 /* 19 */
360 "]{",
361
362 /* 20 */
363 "lb",
364
365 /* 21 */
366 "b",
367
368 /* 22 */
369 "rb",
370
371 /* 23 */
372 "\\smash{",
373
374 /* 24 */
375 "\\mbox{",
376
377 /* 25 */
378 "\\color[rgb]{",
379
380 /* 26 */
381 "\n",
382
383 /* 27 */
384 "\\reset@font",
385
386 /* 28 */
387 "\\selectfont",
388
389 /* 29 */
390 "\\fontsize{",
391
392 /* 30 */
393 "\\fontfamily{\\rmdefault}",
394
395 /* 31 */
396 "\\fontfamily{\\sfdefault}",
397
398 /* 32 */
399 "\\fontfamily{\\ttdefault}",
400
401 /* 33 */
402 "\\fontseries{\\mddefault}",
403
404 /* 34 */
405 "\\fontseries{\\bfdefault}",
406
407 /* 35 */
408 "\\fontshape{\\updefault}",
409
410 /* 36 */
411 "\\fontshape{\\itdefault}",
412
413 /* 37 */
414 "\\fontfamily{\\familydefault}",
415
416 /* 38 */
417 "{",
418
419 /* 39 */
420 "\\end{document}\n",
421
422 /* 40 */
423 "\\documentclass[%lgpt]{article}\n",
424
425 /* 41 */
426 "\\setlength{\\paperwidth}{%ldbp}\n",
427
428 /* 42 */
429 "\\setlength{\\paperheight}{%ldbp}\n",
430
431 /* 43 */
432 "\\usepackage{pgfcore}\n",
433
434 /* 44 */
435 "f2lfonts.tex",
436
437 /* 45 */
438 "f2lother.tex",
439
440 /* 46 */
441 "r",
442
443 NULL
444
445 };
446
447
448
449 /** LaTeX preamble, part 1 (font encoding and font selection packages).
450 */
451 static char const * const f2l_tool_preamble_1[] = {
452 "% begin font setup",
453 "\\usepackage[T1]{fontenc}",
454 "\\usepackage{mathptmx}",
455 "\\usepackage[scaled=.92]{helvet}",
456 "\\usepackage{courier}",
457 "% end font setup",
458 NULL
459
460 };
461
462
463
464 /** LaTex preamble, part 2 (other packages).
465 */
466 static char const * const f2l_tool_preamble_2[] = {
467 "% begin other packages",
468 "\\usepackage{textcomp}",
469 "\\usepackage[intlimits]{amsmath}",
470 "% end other packages",
471 NULL
472
473 };
474
475
476
477 /** LaTeX preamble, part 3 (graphics and color).
478 */
479 static char const * const f2l_tool_preamble_3[] = {
480 "\\usepackage{graphicx}",
481 "\\usepackage{color}",
482 NULL
483
484 };
485
486
487
488 /** LaTeX preamble, part 4 (set borders to 0).
489 */
490 static char const * const f2l_tool_preamble_4[] = {
491 "\\pagestyle{empty}",
492 "\\setlength{\\voffset}{-1in}",
493 "\\setlength{\\topmargin}{0bp}",
494 "\\setlength{\\headheight}{0bp}",
495 "\\setlength{\\headsep}{0bp}",
496 "\\setlength{\\topskip}{0bp}",
497 "\\setlength{\\hoffset}{-1in}",
498 "\\setlength{\\oddsidemargin}{0bp}",
499 "\\setlength{\\evensidemargin}{0bp}",
500 "\\setlength{\\marginparwidth}{0bp}",
501 "\\setlength{\\marginparsep}{0bp}",
502 "\\setlength{\\textwidth}{\\paperwidth}",
503 "\\setlength{\\textheight}{\\paperheight}",
504 "\\setlength{\\parskip}{0bp}",
505 "\\setlength{\\parindent}{0bp}",
506 "\\setlength{\\pdfpagewidth}{\\paperwidth}",
507 "\\setlength{\\pdfpageheight}{\\paperheight}",
508 "\\begin{document}%",
509 NULL
510
511 };
512
513
514
515 f2l_text_handling_t *
f2l_tool_register_font(dk3_sto_t * sFonts,dk3_sto_it_t * iFonts,unsigned long * nFonts,int fontno,double fontsize,dk3_app_t * app)516 f2l_tool_register_font(
517 dk3_sto_t *sFonts,
518 dk3_sto_it_t *iFonts,
519 unsigned long *nFonts,
520 int fontno,
521 double fontsize,
522 dk3_app_t *app
523 )
524 {
525 f2l_text_handling_t myth; /* New text handling. */
526 f2l_text_handling_t *back = NULL;
527
528 if((sFonts) && (iFonts) && (nFonts)) {
529 myth.fontSize = fontsize;
530 myth.fontNumber = 0UL;
531 myth.psFontNo = fontno;
532 back = (f2l_text_handling_t *)dk3sto_it_find_like(iFonts,(void *)(&myth),0);
533 if(!(back)) {
534 back = dk3_new_app(f2l_text_handling_t,1,app);
535 if(back) {
536 back->fontSize = fontsize;
537 back->fontNumber = *(nFonts);
538 back->psFontNo = fontno;
539 if(fontno < 0) { back->psFontNo = 0; }
540 if(fontno > 34) { back->psFontNo = 34; }
541 if(dk3sto_add(sFonts, (void *)back)) {
542 *nFonts += 1UL;
543 if(0UL == *nFonts) {
544 back = NULL; /* Overflow */
545 }
546 } else {
547 dk3_delete(back);
548 back = NULL;
549 }
550 } else {
551 }
552 } else {
553 }
554 }
555 return back;
556 }
557
558
559
560 void
f2l_tool_write_font_name(FILE * of,unsigned long fontno,unsigned long nFonts)561 f2l_tool_write_font_name(
562 FILE *of,
563 unsigned long fontno,
564 unsigned long nFonts
565 )
566 {
567 char buffer[64]; /* Buffer for number converted to string. */
568 char *ptr; /* Current character in buffer. */
569 size_t lgt; /* Length of current number. */
570 size_t l1; /* Length of maximum number. */
571 size_t i; /* Used to write leading zeros. */
572
573 if(of) {
574 fputs(f2lto_c8_kw[9], of);
575 sprintf(buffer, "%lu", nFonts);
576 lgt = strlen(buffer);
577 sprintf(buffer, "%lu", fontno);
578 l1 = strlen(buffer);
579 for(i = l1; i < lgt; i++) { fputc('A', of); }
580 ptr = buffer;
581 while(*ptr) {
582 switch(*ptr) {
583 case '9': { fputc('J', of); } break;
584 case '8': { fputc('I', of); } break;
585 case '7': { fputc('H', of); } break;
586 case '6': { fputc('G', of); } break;
587 case '5': { fputc('F', of); } break;
588 case '4': { fputc('E', of); } break;
589 case '3': { fputc('D', of); } break;
590 case '2': { fputc('C', of); } break;
591 case '1': { fputc('B', of); } break;
592 default: { fputc('A', of); } break;
593 }
594 ptr++;
595 }
596 }
597 }
598
599
600
601 void
f2l_tool_start_tex_part_with_picture(FILE * of,f2l_job_t * job,char const * shortOutFile,dk3_sto_it_t * iFonts,unsigned long nFonts,int wp)602 f2l_tool_start_tex_part_with_picture(
603 FILE *of,
604 f2l_job_t *job,
605 char const *shortOutFile,
606 dk3_sto_it_t *iFonts,
607 unsigned long nFonts,
608 int wp
609 )
610 {
611 f2l_text_handling_t *th; /* Current text handling. */
612 char const *psfontname; /* PS font name. */
613 double fs; /* Font size. */
614
615 if(wp) {
616 /* begin{picture}(0,0) */
617 fputs(f2lto_c8_kw[0], of);
618 fputs(f2lto_c8_kw[2], of);
619 fputs(shortOutFile, of);
620 fputs(f2lto_c8_kw[3], of);
621 /* end{picture} */
622 fputs(f2lto_c8_kw[1], of);
623 fputs(f2lto_c8_kw[4], of);
624 }
625 if((iFonts) && (nFonts)) {
626 dk3sto_it_reset(iFonts);
627 while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(iFonts))) {
628 fputs(f2lto_c8_kw[6], of);
629 /* Write font name */
630 f2l_tool_write_font_name(of, th->fontNumber, nFonts);
631 fputs(f2lto_c8_kw[7], of);
632 /* Write font description */
633 psfontname = dk3font_get_tex_font_name(th->psFontNo);
634 if(!(psfontname)) { psfontname = f2lto_c8_kw[10]; }
635 fputs(psfontname, of);
636 fputs(f2lto_c8_kw[11], of);
637 fs = th->fontSize;
638 if(job->nts > 0.0) {
639 fs = fs * job->nts;
640 }
641 fs = dk3ma_d_restrict_digits(fs, 2);
642 dk3ma_print_double_c8_no_sci(of, fs);
643 fputs(f2lto_c8_kw[12], of);
644 fputs(f2lto_c8_kw[8], of);
645 }
646 }
647 if(wp) {
648 fprintf(of, f2lto_c8_kw[5], job->lwidth, job->lheight);
649 }
650 }
651
652
653
654
655 void
f2l_tool_start_tex_part(FILE * of,f2l_job_t * job,char const * shortOutFile,dk3_sto_it_t * iFonts,unsigned long nFonts)656 f2l_tool_start_tex_part(
657 FILE *of,
658 f2l_job_t *job,
659 char const *shortOutFile,
660 dk3_sto_it_t *iFonts,
661 unsigned long nFonts
662 )
663 {
664 f2l_tool_start_tex_part_with_picture(
665 of, job, shortOutFile, iFonts, nFonts, 1
666 );
667 }
668
669
670
671 void
f2l_tool_end_tex_part(FILE * of)672 f2l_tool_end_tex_part(
673 FILE *of
674 )
675 {
676 fputs(f2lto_c8_kw[1], of);
677 }
678
679
680
681 /** Write font size to output file.
682 @param of Output file.
683 @param fs Font size.
684 @param sp Line base to line base distance.
685 */
686 static
687 void
f2l_tool_write_font_size(FILE * of,double fs,double sp)688 f2l_tool_write_font_size(
689 FILE *of,
690 double fs,
691 double sp
692 )
693 {
694
695 fputs(f2lto_c8_kw[29], of);
696 dk3ma_print_double_c8_no_sci(of, fs);
697 fputs(f2lto_c8_kw[12], of);
698 fputs(f2lto_c8_kw[7], of);
699 dk3ma_print_double_c8_no_sci(of, sp);
700 fputs(f2lto_c8_kw[12], of);
701 fputs(f2lto_c8_kw[16], of);
702 }
703
704
705
706 /** Write instruction to select a font by features to LaTeX output.
707 @param of Output file.
708 @param job Job structure.
709 @param fontSize Font size.
710 @param fontFeatures Font features.
711 @param useFamily Flag: Choose font family.
712 */
713 static
714 void
f2l_tool_font_select_by_features(FILE * of,f2l_job_t * job,double fontSize,int fontFeatures,int useFamily)715 f2l_tool_font_select_by_features(
716 FILE *of,
717 f2l_job_t *job,
718 double fontSize,
719 int fontFeatures,
720 int useFamily
721 )
722 {
723 double fs; /* Font size. */
724 double sp; /* Line base to line base distance. */
725
726 fs = fontSize;
727 if(job->nts > 0.0) {
728 fs = fs * job->nts;
729 }
730 sp = 1.2 * fs;
731 fs = dk3ma_d_restrict_digits(fs, 2);
732 sp = dk3ma_d_restrict_digits(sp, 2);
733 if(useFamily) {
734 /*
735 Complete font selection.
736 */
737 if(job->resfont) {
738 fputs(f2lto_c8_kw[27], of);
739 }
740 /* Font size. */
741 f2l_tool_write_font_size(of, fs, sp);
742 /* Font family */
743 switch(fontFeatures & DK3_FONT_FAMILY) {
744 case DK3_FONT_TYPEWRITER: {
745 fputs(f2lto_c8_kw[32], of);
746 } break;
747 case DK3_FONT_SANS_SERIF: {
748 fputs(f2lto_c8_kw[31], of);
749 } break;
750 default: {
751 fputs(f2lto_c8_kw[30], of);
752 } break;
753 }
754 /* Font series */
755 fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_BOLD) ? 34 : 33], of);
756 /* Font shape */
757 /* 2013-01-22 Correction to test with DK3_FONT_ITOB.
758 */
759 fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_ITOB) ? 36 : 35], of);
760 } else {
761 /*
762 Adjust the size only.
763 */
764 f2l_tool_write_font_size(of, fs, sp);
765 fputs(f2lto_c8_kw[37], of);
766 fputs(f2lto_c8_kw[33], of);
767 fputs(f2lto_c8_kw[35], of);
768 }
769 fputs(f2lto_c8_kw[28], of);
770 }
771
772
773
774 /** Write commands to choose a font.
775 @param of Output file.
776 @param job Job structure.
777 @param drw Drawing structure.
778 @param obj Text object.
779 @param nFonts Total number of PS fonts.
780 */
781 static
782 void
f2l_tool_font_selection(FILE * of,f2l_job_t * job,dk3_fig_obj_t * obj,unsigned long nFonts)783 f2l_tool_font_selection(
784 FILE *of,
785 f2l_job_t *job,
786 dk3_fig_obj_t *obj,
787 unsigned long nFonts
788 )
789 {
790 f2l_text_handling_t *th; /* Text handling. */
791 int ff; /* Font flags. */
792 int fontFeatures; /* Font features. */
793
794 ff = (obj->dt).txt.ff;
795 /*
796 No font selection... for special text.
797 */
798 if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
799 if((ff & DK3_FIG_FONT_FLAG_PS) && (obj->dsd)) {
800 /*
801 Use one of the defined fonts.
802 */
803 th = (f2l_text_handling_t *)(obj->dsd);
804 f2l_tool_write_font_name(of, th->fontNumber, nFonts);
805 } else {
806 /*
807 Select font by features.
808 */
809 fontFeatures = DK3_FONT_ROMAN;
810 if(ff & DK3_FIG_FONT_FLAG_PS) {
811 /*
812 Switch from PS font to font with similar features.
813 */
814 fontFeatures = dk3font_get_features((obj->dt).txt.fo);
815 f2l_tool_font_select_by_features(
816 of, job, (obj->dt).txt.fs, fontFeatures, 1
817 );
818 } else {
819 /*
820 Use LaTeX font with specified features.
821 */
822 switch((obj->dt).txt.fo) {
823 case 0: {
824 f2l_tool_font_select_by_features(
825 of, job, (obj->dt).txt.fs, fontFeatures, 0
826 );
827 } break;
828 case 1: {
829 f2l_tool_font_select_by_features(
830 of, job, (obj->dt).txt.fs, fontFeatures, 1
831 );
832 } break;
833 case 2: {
834 fontFeatures |= DK3_FONT_BOLD;
835 f2l_tool_font_select_by_features(
836 of, job, (obj->dt).txt.fs, fontFeatures, 1
837 );
838 } break;
839 case 3: {
840 fontFeatures |= DK3_FONT_ITALIC;
841 f2l_tool_font_select_by_features(
842 of, job, (obj->dt).txt.fs, fontFeatures, 1
843 );
844 } break;
845 case 4: {
846 fontFeatures = DK3_FONT_SANS_SERIF;
847 f2l_tool_font_select_by_features(
848 of, job, (obj->dt).txt.fs, fontFeatures, 1
849 );
850 } break;
851 case 5: {
852 fontFeatures = DK3_FONT_TYPEWRITER;
853 f2l_tool_font_select_by_features(
854 of, job, (obj->dt).txt.fs, fontFeatures, 1
855 );
856 } break;
857 default: {
858 f2l_tool_font_select_by_features(
859 of, job, (obj->dt).txt.fs, fontFeatures, 1
860 );
861 } break;
862 }
863 }
864 }
865 }
866 }
867
868
869
870 void
f2l_tool_tex_string(FILE * of,char const * txt)871 f2l_tool_tex_string(
872 FILE *of,
873 char const *txt
874 )
875 {
876 char const *ptr; /* Current input character to process. */
877 char const *sptr; /* Output string for current input character. */
878 char c; /* Current input character. */
879 unsigned char uc; /* Current input character conv to unsigned char. */
880 unsigned un; /* Current input character converted to unsigned. */
881
882 ptr = txt;
883 while(*ptr) {
884 c = *(ptr++);
885 uc = (unsigned char)c;
886 un = (unsigned)uc;
887 while(un > 255) {
888 un = un - 256;
889 }
890 sptr = f2l_tool_l2l_enc[un];
891 if(sptr) {
892 fputs(sptr, of);
893 }
894 }
895 }
896
897
898
899 /** Write string, convert to UTF-8 if necessary.
900 @param txt String to write.
901 @param fipo Output file.
902 */
903 static
904 void
f2lto_utf8_out(char const * txt,FILE * fipo)905 f2lto_utf8_out(char const *txt, FILE *fipo)
906 {
907 unsigned char buf[16];
908 char const *cptr;
909 dk3_c32_t c32;
910 size_t sz;
911 size_t i;
912 char c;
913
914 cptr = txt;
915 while(*cptr) {
916 c = *(cptr++);
917 c32 = (dk3_c32_t)c;
918 c32 &= 0x000000FFUL;
919 if(dk3enc_dk_to_ul((unsigned long)c32) < 128UL) {
920 fputc(c, fipo);
921 } else {
922 sz = dk3enc_uc2utf8(c32, buf, sizeof(buf));
923 if(0 < sz) {
924 for(i = 0; i < sz; i++) {
925 fputc(buf[i], fipo);
926 }
927 }
928 }
929 }
930 }
931
932
933
934 void
f2l_tool_inner_text_object(FILE * of,f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,unsigned long nFonts)935 f2l_tool_inner_text_object(
936 FILE *of,
937 f2l_job_t *job,
938 dk3_fig_drawing_t *drw,
939 dk3_fig_obj_t *obj,
940 unsigned long nFonts
941 )
942 {
943 dk3_rgb_color_t rgb; /* Color cell for text color. */
944
945 rgb.r = rgb.g = rgb.b = 0.0;
946 dk3fig_tool_find_color(&rgb, drw, obj->pc, 20);
947 if(job->smash) {
948 /* \smash{ */
949 fputs(f2lto_c8_kw[23], of);
950 }
951 if(job->mbox) {
952 /* \mbox{ */
953 fputs(f2lto_c8_kw[24], of);
954 }
955 fputs(f2lto_c8_kw[38], of);
956 /* font selection */
957 f2l_tool_font_selection(of, job, obj, nFonts);
958 fputs(f2lto_c8_kw[25], of);
959 /* red */
960 dk3ma_print_double_c8_no_sci(of, rgb.r);
961 fputs(f2lto_c8_kw[14], of);
962 /* green */
963 dk3ma_print_double_c8_no_sci(of, rgb.g);
964 fputs(f2lto_c8_kw[14], of);
965 /* blue */
966 dk3ma_print_double_c8_no_sci(of, rgb.b);
967 fputs(f2lto_c8_kw[16], of);
968 /* text */
969 if(((obj->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
970 if(job->stu8) {
971 f2lto_utf8_out((obj->dt).txt.st, of);
972 } else {
973 fputs((obj->dt).txt.st, of);
974 }
975 } else {
976 f2l_tool_tex_string(of, (obj->dt).txt.st);
977 }
978 fputs(f2lto_c8_kw[16], of);
979 if(job->mbox) {
980 /* } */
981 fputs(f2lto_c8_kw[16], of);
982 }
983 if(job->smash) {
984 /* } */
985 fputs(f2lto_c8_kw[16], of);
986 }
987 }
988
989
990 void
f2l_tool_text_object(FILE * of,f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double x,double y,unsigned long nFonts)991 f2l_tool_text_object(
992 FILE *of,
993 f2l_job_t *job,
994 dk3_fig_drawing_t *drw,
995 dk3_fig_obj_t *obj,
996 double x,
997 double y,
998 unsigned long nFonts
999 )
1000 {
1001 double an; /* Rotation in degree. */
1002 double ian; /* Rotation as integer. */
1003 int haverotation = 0; /* Flag: Have rotation. */
1004
1005 /* \put( */
1006 fputs(f2lto_c8_kw[13], of);
1007 /* x position */
1008 dk3ma_print_double_c8_no_sci(of, x);
1009 /* , */
1010 fputs(f2lto_c8_kw[14], of);
1011 /* y position */
1012 dk3ma_print_double_c8_no_sci(of, y);
1013 /* ){ */
1014 fputs(f2lto_c8_kw[15], of);
1015 if(fabs((obj->dt).txt.an) > 1.0e-6) {
1016 haverotation = 1;
1017 an = ((obj->dt).txt.an * 180.0) / M_PI;
1018 ian = dk3ma_d_rint(an);
1019 if(fabs(an - ian) < 1.0e-3) {
1020 an = ian;
1021 }
1022 /* \rotatebox{ */
1023 fputs(f2lto_c8_kw[17], of);
1024 /* degrees */
1025 dk3ma_print_double_c8_no_sci(of, an);
1026 /* }{ */
1027 fputs(f2lto_c8_kw[7], of);
1028 }
1029 /* \makebox(0,0)[ */
1030 fputs(f2lto_c8_kw[18], of);
1031 /* justification */
1032 switch(obj->st) {
1033 case 2: {
1034 fputs(f2lto_c8_kw[22], of);
1035 } break;
1036 case 1: {
1037 fputs(f2lto_c8_kw[21], of);
1038 } break;
1039 default: {
1040 fputs(f2lto_c8_kw[20], of);
1041 } break;
1042 }
1043 /* ]{ */
1044 fputs(f2lto_c8_kw[19], of);
1045 f2l_tool_inner_text_object(of, job, drw, obj, nFonts);
1046 /* } */
1047 fputs(f2lto_c8_kw[16], of);
1048 if(haverotation) {
1049 /* } */
1050 fputs(f2lto_c8_kw[16], of);
1051 }
1052 /* } */
1053 fputs(f2lto_c8_kw[16], of);
1054 fputs(f2lto_c8_kw[26], of);
1055 }
1056
1057
1058
1059 void
f2l_tool_image_delete(f2l_image_t * im)1060 f2l_tool_image_delete(f2l_image_t *im)
1061 {
1062
1063 if(im) {
1064 dk3_release(im->filename);
1065 im->xo = NULL;
1066 im->width = 0UL;
1067 im->height = 0UL;
1068 im->xres = 0.0;
1069 im->yres = 0.0;
1070 im->imageNumber = 0UL;
1071 im->lineno = 0UL;
1072 dk3_delete(im);
1073 }
1074 }
1075
1076
1077
1078 f2l_image_t *
f2l_tool_image_new(char const * filename,dk3_app_t * app,unsigned long li)1079 f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li)
1080 {
1081 dk3_ufi_t ufi; /* Unique file identifier. */
1082 f2l_image_t *back = NULL;
1083
1084 if((filename) && (app)) {
1085 if(dk3ufi_c8_get(&ufi, filename)) {
1086 back = dk3_new_app(f2l_image_t,1,app);
1087 if(back) {
1088 dk3mem_cpy((void *)(&(back->ufi)), (void *)(&ufi), sizeof(dk3_ufi_t));
1089 back->xo = NULL;
1090 back->width = 0UL;
1091 back->height = 0UL;
1092 back->xres = 0.0;
1093 back->yres = 0.0;
1094 back->imageNumber = 0UL;
1095 back->lineno = li;
1096 back->filename = dk3str_c8_dup_app(filename, app);
1097 if(!(back->filename)) {
1098 f2l_tool_image_delete(back);
1099 back = NULL;
1100 }
1101 }
1102 }
1103 }
1104 return back;
1105 }
1106
1107
1108
1109 int
f2l_tool_compare_images(void const * l,void const * r,int cr)1110 f2l_tool_compare_images(void const *l, void const *r, int cr)
1111 {
1112 f2l_image_t const *pl; /* Left object. */
1113 f2l_image_t const *pr; /* Right object. */
1114 int back = 0;
1115
1116 if(l) {
1117 if(r) {
1118 pl = (f2l_image_t const *)l;
1119 pr = (f2l_image_t const *)r;
1120 switch(cr) {
1121 case 1: {
1122 back = dk3ufi_compare((void *)(&(pl->ufi)), r, 0);
1123 } break;
1124 default: {
1125 back = dk3ufi_compare((void *)(&(pl->ufi)), (void *)(&(pr->ufi)), 0);
1126 } break;
1127 }
1128 } else { back = 1; }
1129 } else {
1130 if(r) { back = -1; }
1131 }
1132 return back;
1133 }
1134
1135
1136
1137 void
f2l_tool_set_exit_status(f2l_job_t * job,int exval)1138 f2l_tool_set_exit_status(f2l_job_t *job, int exval)
1139 {
1140 if(job) {
1141 if(0 == job->exval) {
1142 job->exval = exval;
1143 }
1144 }
1145 }
1146
1147
1148
1149 /** Write entire section of text to output file.
1150 @param of Output file.
1151 @param txt Pointer to array of text lines, NULL-finalized.
1152 */
1153 static
1154 void
f2l_tool_add_text_section_to_file(FILE * of,char const * const * txt)1155 f2l_tool_add_text_section_to_file(FILE *of, char const * const *txt)
1156 {
1157 char const * const *ptr; /* Current line to add. */
1158
1159 ptr = txt;
1160 while(*ptr) {
1161 fputs(*ptr, of);
1162 fputc('\n', of);
1163 ptr++;
1164 }
1165 }
1166
1167
1168
1169 /** Write preamble part to output file, either the contents of a
1170 file (if found) or a default text.
1171 @param of Output file.
1172 @param fileName Name of file containing the preamble part.
1173 @param preamble Default preamble text if fileName is not found.
1174 */
1175 static
1176 void
fl2_tool_write_preamble_part_or_file(FILE * of,char const * fileName,char const * const * preamble)1177 fl2_tool_write_preamble_part_or_file(
1178 FILE *of,
1179 char const *fileName,
1180 char const * const *preamble
1181 )
1182 {
1183 char line[1024]; /* Line buffer to read input file. */
1184 FILE *fipo; /* Input file. */
1185 int done = 0; /* Flag: Successfully handled file. */
1186
1187 fipo = fopen(fileName, f2lto_c8_kw[46]);
1188 if(fipo) {
1189 done = 1;
1190 while(fgets(line, sizeof(line), fipo)) {
1191 dk3str_c8_chomp(line, NULL);
1192 fputs(line, of);
1193 fputc('\n', of);
1194 }
1195 fclose(fipo);
1196 } else {
1197 }
1198 if(!(done)) {
1199 f2l_tool_add_text_section_to_file(of, preamble);
1200 }
1201
1202 }
1203
1204
1205
1206 void
f2l_tool_begin_latex_document(FILE * of,f2l_job_t * job)1207 f2l_tool_begin_latex_document(
1208 FILE *of,
1209 f2l_job_t *job
1210 )
1211 {
1212 fprintf(of, f2lto_c8_kw[40], job->tts);
1213 #if 0
1214 f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_1);
1215 #else
1216 fl2_tool_write_preamble_part_or_file(
1217 of, f2lto_c8_kw[44], f2l_tool_preamble_1
1218 );
1219 #endif
1220 #if 0
1221 f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_2);
1222 #else
1223 fl2_tool_write_preamble_part_or_file(
1224 of, f2lto_c8_kw[45], f2l_tool_preamble_2
1225 );
1226 #endif
1227 f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_3);
1228 switch(job->dr) {
1229 case FIG2LAT_DRIVER_PGF:
1230 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
1231 fputs(f2lto_c8_kw[43], of);
1232 } break;
1233 }
1234 fprintf(of, f2lto_c8_kw[41], job->lwidth);
1235 fprintf(of, f2lto_c8_kw[42], job->lheight);
1236 f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_4);
1237 }
1238
1239
1240
1241 void
f2l_tool_end_latex_document(FILE * of)1242 f2l_tool_end_latex_document(
1243 FILE *of
1244 )
1245 {
1246 fputs(f2lto_c8_kw[39], of);
1247 }
1248
1249
1250
1251 int
f2lto_find_draw_direction(dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)1252 f2lto_find_draw_direction(
1253 dk3_fig_drawing_t *drw,
1254 dk3_fig_obj_t *obj,
1255 int *ec
1256 )
1257 {
1258 dk3_fig_poly_point_t *po; /* Point set. */
1259 size_t np; /* Number of points. */
1260 int back = 0;
1261
1262 if(DK3_FIG_SRCTYPE_JFIG != drw->srctype) {
1263 po = (obj->dt).pol.po;
1264 np = (obj->dt).pol.np;
1265 if(4 <= np) {
1266 if(po[1].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
1267 /* 0 on the left, 1 on the right */
1268 if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
1269 back = 0;
1270 } else {
1271 back = 1;
1272 }
1273 } else {
1274 if(po[1].x < (dk3ma_d_sub_ok(po[0].x, 0.5, ec))) {
1275 /* 0 on the right, 1 on the left. */
1276 if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
1277 back = 2;
1278 } else {
1279 back = 3;
1280 }
1281 } else {
1282 /* 0 and 1 in one row. */
1283 if(po[2].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
1284 /* 0 and 1 left */
1285 if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
1286 back = 0;
1287 } else {
1288 back = 1;
1289 }
1290 } else {
1291 /* 0 and 1 right */
1292 if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
1293 back = 2;
1294 } else {
1295 back = 3;
1296 }
1297 }
1298 }
1299 }
1300 if((obj->dt).pol.flf) {
1301 back += 4;
1302 } else {
1303 }
1304 } else {
1305 }
1306 } else {
1307 }
1308 return back;
1309 }
1310
1311
1312
1313 double
f2lto_find_gap_length(f2l_job_t * job,double lw,double lsv)1314 f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv)
1315 {
1316 double back;
1317 if(job->cols) {
1318 back = lsv;
1319 } else {
1320 back = 0.5 * lw + 0.5 * lsv;
1321 if((0.5 * back) > lw) {
1322 back = 2.0 * lw;
1323 }
1324 }
1325 return back;
1326 }
1327
1328