1 /*
2 Copyright (C) 2012-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: f2lud.ctr
12 */
13
14 /** @file f2lud.c The f2lud module.
15 */
16
17
18 #include <libdk3c/dk3all.h>
19 #include <libdk3c/dk3bezcu.h>
20 #include <fig2lat/fig2lat.h>
21 #include <libdk3c/dk3xsp.h>
22 #include <fig2lat/f2lud.h>
23 #include <fig2lat/f2lsvg.h>
24 #include <fig2lat/f2lpgf.h>
25 #include <fig2lat/f2lpdf.h>
26 #include <fig2lat/f2leps.h>
27 #include <libdk3fig/dk3figto.h>
28 #if 0
29 #include <libdk3c/dkt-version.h>
30 #endif
31 #include <libdk4base/dk4vers.h>
32 #include <fig2lat/f2ludpat.h>
33 #include <fig2lat/f2lpara.h>
34 #include <libdk3c/dk3unused.h>
35
36
37
38
39
40
41
42 /** Keywords used by the module.
43 */
44 static char const * const f2lud_c8_kw[] = {
45 /* 0 */
46 "fig object begin %lu, line %lu, type %ld %ld, layer %d",
47
48 /* 1 */
49 "fig object end %lu",
50
51 /* 2 */
52 "arrowhead forward begin, type=%d, fill=%d, length=%lg, width=%lg",
53
54 /* 3 */
55 "arrowhead forward end",
56
57 /* 4 */
58 "arrowhead backward begin, type=%d, fill=%d, length=%lg, width=%lg",
59
60 /* 5 */
61 "arrowhead backward end",
62
63 /* 6 */
64 "path object begin, type %ld %ld",
65
66 /* 7 */
67 "path object end",
68
69 NULL
70
71 };
72
73
74
75 /** Write debug line to output file.
76 @param job Job structure.
77 @param msg Text line without newline at end.
78 */
79 static
80 void
f2lud_debug(f2l_job_t * job,char const * msg)81 f2lud_debug(
82 f2l_job_t *job,
83 char const *msg
84 )
85 {
86 switch(job->dr) {
87 case FIG2LAT_DRIVER_EPS_STANDALONE: {
88 f2leps_eps_pure_debug(job, msg);
89 } break;
90 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
91 f2lpgf_tex_debug(job, msg);
92 } break;
93 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
94 f2lpdf_tex_with_pdf_debug(job, msg);
95 } break;
96 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
97 f2lpdf_pdf_with_tex_debug(job, msg);
98 } break;
99 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
100 f2leps_eps_with_tex_debug(job, msg);
101 } break;
102 /* @DRIVER@ universal */
103 default: { /* PGF */
104 f2lpgf_pgf_debug(job, msg);
105 } break;
106 }
107 }
108
109
110
111 /** Calculate factors for coordinates transformations.
112 @param job Job structure.
113 @param drw Drawing structure.
114 @return 1 on success, 0 on error.
115 */
116 static
117 int
f2lud_coordinates_transformation(f2l_job_t * job,dk3_fig_drawing_t * drw)118 f2lud_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
119 {
120 double xmin; /* Minimum x in output space. */
121 double xmax; /* Maximum x in output space. */
122 double ymin; /* Minimum y in output space. */
123 double ymax; /* Maximum y in output space. */
124 double xdelta; /* Used width in output space. */
125 double ydelta; /* Used height in output space. */
126 double width; /* Bounding box width in output space. */
127 double height; /* Bounding box height in output space. */
128 int mec = 0; /* Mathematical error code. */
129 int back = 1;
130
131 (job->ct2d).mx = dk3ma_d_div_ok( 72.0, drw->res, &mec);
132 (job->ct2d).my = dk3ma_d_div_ok(-72.0, drw->res, &mec);
133 xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
134 xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
135 ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
136 ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
137 xdelta = dk3ma_d_sub_ok(xmax, xmin, &mec);
138 ydelta = dk3ma_d_sub_ok(ymax, ymin, &mec);
139 job->width = width = ceil(xdelta);
140 job->height = height = ceil(ydelta);
141 job->lwidth = dk3ma_d_to_l_ok(width, &mec);
142 job->lheight = dk3ma_d_to_l_ok(height, &mec);
143 (job->ct2d).nx = 0.5 * dk3ma_d_sub_ok(width, xdelta, &mec);
144 (job->ct2d).ny = 0.5 * dk3ma_d_sub_ok(height, ydelta, &mec);
145 (job->ct2d).nx = dk3ma_d_sub_ok((job->ct2d).nx, xmin, &mec);
146 (job->ct2d).ny = dk3ma_d_sub_ok((job->ct2d).ny, ymin, &mec);
147
148
149 if(mec) {
150 back = 0;
151 /* ERROR: Math problem */
152 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
153 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
154 }
155 return back;
156 }
157
158
159
160 /** Driver-specific initialization.
161 @param job Job structure.
162 @param drw Drawing structure.
163 @return 1 on success, 0 on error.
164 */
165 static
166 int
f2lud_driver_initialize(f2l_job_t * job,dk3_fig_drawing_t * drw)167 f2lud_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
168 {
169 int back;
170
171 back = f2lud_coordinates_transformation(job, drw);
172 if(back) {
173 switch(job->dr) {
174 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
175 back = f2lpgf_tex_initialize(job, drw);
176 } break;
177 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
178 back = f2lpdf_tex_with_pdf_initialize(job, drw);
179 } break;
180 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
181 back = f2lpdf_pdf_with_tex_initialize(job, drw);
182 } break;
183 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
184 back = f2leps_eps_with_tex_initialize(job, drw);
185 } break;
186 case FIG2LAT_DRIVER_EPS_STANDALONE: {
187 back = f2leps_eps_pure_initialize(job, drw);
188 } break;
189 /* @DRIVER@ universal */
190 default: { /* PGF */
191 back = f2lpgf_pgf_initialize(job, drw);
192 } break;
193 }
194 }
195 return back;
196 }
197
198
199
200 /** Release resources allocated by f2lud_driver_initialize().
201 @param job Job structure.
202 @param drw Drawing structure.
203 */
204 static
205 void
f2lud_driver_end(f2l_job_t * job,dk3_fig_drawing_t * drw)206 f2lud_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
207 {
208
209 switch(job->dr) {
210 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
211 f2lpgf_tex_end(job, drw);
212 } break;
213 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
214 f2lpdf_tex_with_pdf_end(job, drw);
215 } break;
216 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
217 f2lpdf_pdf_with_tex_end(job, drw);
218 } break;
219 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
220 f2leps_eps_with_tex_end(job, drw);
221 } break;
222 case FIG2LAT_DRIVER_EPS_STANDALONE: {
223 f2leps_eps_pure_end(job, drw);
224 } break;
225 /* @DRIVER@ universal */
226 default: { /* PGF */
227 f2lpgf_pgf_end(job, drw);
228 } break;
229 }
230
231 }
232
233
234
235 /** Open output files.
236 @param job Job structure.
237 @return 1 on success, 0 on error.
238 */
239 static
240 int
f2lud_open_output_files(f2l_job_t * job)241 f2lud_open_output_files(f2l_job_t *job)
242 {
243 int back = 0;
244
245 switch(job->dr) {
246 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
247 back = f2lpgf_tex_open_output_files(job);
248 } break;
249 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
250 back = f2lpdf_tex_with_pdf_open_output_files(job);
251 } break;
252 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
253 back = f2lpdf_pdf_with_tex_open_output_files(job);
254 } break;
255 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
256 back = f2leps_eps_with_tex_open_output_files(job);
257 } break;
258 case FIG2LAT_DRIVER_EPS_STANDALONE: {
259 back = f2leps_eps_pure_open_output_files(job);
260 } break;
261 /* @DRIVER@ universal */
262 default: { /* PGF */
263 back = f2lpgf_pgf_open_output_files(job);
264 } break;
265 }
266 return back;
267 }
268
269
270
271 /** Close output files.
272 @param job Job structure.
273 */
274 static
275 void
f2lud_close_output_files(f2l_job_t * job)276 f2lud_close_output_files(f2l_job_t *job)
277 {
278
279 switch(job->dr) {
280 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
281 f2lpgf_tex_close_output_files(job);
282 } break;
283 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
284 f2lpdf_tex_with_pdf_close_output_files(job);
285 } break;
286 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
287 f2lpdf_pdf_with_tex_close_output_files(job);
288 } break;
289 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
290 f2leps_eps_with_tex_close_output_files(job);
291 } break;
292 case FIG2LAT_DRIVER_EPS_STANDALONE: {
293 f2leps_eps_pure_close_output_files(job);
294 } break;
295 /* @DRIVER@ universal */
296 default: { /* PGF */
297 f2lpgf_pgf_close_output_files(job);
298 } break;
299 }
300 }
301
302
303
304 /** Write start of output.
305 @param job Job structure.
306 @param drw Drawing structure.
307 @return 1 on success, 0 on error.
308 */
309 static
310 int
f2lud_start_processing(f2l_job_t * job,dk3_fig_drawing_t * drw)311 f2lud_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
312 {
313 int back = 0;
314
315 switch(job->dr) {
316 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
317 back = f2lpgf_tex_start_processing(job, drw);
318 } break;
319 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
320 back = f2lpdf_tex_with_pdf_start_processing(job, drw);
321 } break;
322 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
323 back = f2lpdf_pdf_with_tex_start_processing(job, drw);
324 } break;
325 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
326 back = f2leps_eps_with_tex_start_processing(job, drw);
327 } break;
328 case FIG2LAT_DRIVER_EPS_STANDALONE: {
329 back = f2leps_eps_pure_start_processing(job, drw);
330 } break;
331 /* @DRIVER@ universal */
332 default: { /* PGF */
333 back = f2lpgf_pgf_start_processing(job, drw);
334 } break;
335 }
336 return back;
337 }
338
339
340
341 /** Write end of output.
342 @param job Job structure.
343 @param drw Drawing structure.
344 */
345 static
346 void
f2lud_end_processing(f2l_job_t * job,dk3_fig_drawing_t * drw)347 f2lud_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
348 {
349
350 switch(job->dr) {
351 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
352 f2lpgf_tex_end_processing(job, drw);
353 } break;
354 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
355 f2lpdf_tex_with_pdf_end_processing(job, drw);
356 } break;
357 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
358 f2lpdf_pdf_with_tex_end_processing(job, drw);
359 } break;
360 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
361 f2leps_eps_with_tex_end_processing(job, drw);
362 } break;
363 case FIG2LAT_DRIVER_EPS_STANDALONE: {
364 f2leps_eps_pure_end_processing(job, drw);
365 } break;
366 /* @DRIVER@ universal */
367 default: { /* PGF */
368 f2lpgf_pgf_end_processing(job, drw);
369 } break;
370 }
371 }
372
373
374
375 /** Process one text object.
376 @param job Job structure.
377 @param drw Drawing structure.
378 @param obj Current object to process.
379 */
380 static
381 void
f2lud_text_object(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)382 f2lud_text_object(
383 f2l_job_t *job,
384 dk3_fig_drawing_t *drw,
385 dk3_fig_obj_t *obj
386 )
387 {
388 double x; /* X position of text object. */
389 double y; /* Y position of text object. */
390 int ec = 0; /* Mathematical error code. */
391
392 if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
393 x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &ec);
394 y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &ec);
395 switch(job->dr) {
396 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
397 f2lpgf_tex_text_object(job, drw, obj, x, y);
398 } break;
399 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
400 f2lpdf_tex_with_pdf_text_object(job, drw, obj, x, y);
401 } break;
402 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
403 f2lpdf_pdf_with_tex_text_object(job, drw, obj, x, y);
404 } break;
405 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
406 f2leps_eps_with_tex_text_object(job, drw, obj, x, y);
407 } break;
408 case FIG2LAT_DRIVER_EPS_STANDALONE: {
409 f2leps_eps_pure_text_object(job, drw, obj, x, y);
410 } break;
411 /* @DRIVER@ universal */
412 default: { /* PGF */
413 f2lpgf_pgf_text_object(job, drw, obj, x, y);
414 } break;
415 }
416 }
417 if(ec) {
418 /* ERROR: Math problem! */
419 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
420 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
421 }
422
423 }
424
425
426
427 /** Find bounding box for output coordinates.
428 @param bb Bounding box to set up.
429 @param job Job structure.
430 @param drw Drawing structure.
431 @param obj Polygon/polyline object.
432 @param ec Pointer to error code variable.
433 */
434 static
435 void
f2lud_find_bounding_box(dk3_bb_t * bb,f2l_job_t * job,dk3_fig_drawing_t * DK3_SILENCE_ARG_UNUSED (drw),dk3_fig_obj_t * obj,int * ec)436 f2lud_find_bounding_box(
437 dk3_bb_t *bb,
438 f2l_job_t *job,
439 dk3_fig_drawing_t * DK3_SILENCE_ARG_UNUSED(drw),
440 dk3_fig_obj_t *obj,
441 int *ec
442 )
443 {
444 dk3_fig_poly_point_t *po; /* Current point. */
445 size_t np; /* Number of points. */
446 size_t i; /* Index of current point. */
447
448 DK3_UNUSED_ARG(drw)
449 po = (obj->dt).pol.po;
450 np = (obj->dt).pol.np;
451 dk3bb_reset(bb);
452 for(i = 0; i < np; i++) {
453 dk3bb_add_x(bb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
454 dk3bb_add_y(bb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
455 po++;
456 }
457 }
458
459
460
461 /** Process one image object.
462 @param job Job structure.
463 @param drw Drawing structure.
464 @param obj Current object to process.
465 */
466 static
467 void
f2lud_image_object(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)468 f2lud_image_object(
469 f2l_job_t *job,
470 dk3_fig_drawing_t *drw,
471 dk3_fig_obj_t *obj
472 )
473 {
474 dk3_bb_t outbb; /* Image bounding box in output space. */
475 int ec = 0; /* Error code variable. */
476 int drawdir = 0; /* Drawing direction for embedded image. */
477
478 dk3bb_reset(&outbb);
479 f2lud_find_bounding_box(&outbb, job, drw, obj, &ec);
480 drawdir = f2lto_find_draw_direction(drw, obj, &ec);
481 switch(job->dr) {
482 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
483 f2lpgf_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
484 } break;
485 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
486 f2lpdf_tex_with_pdf_image_object(job, drw, obj, &outbb, drawdir, &ec);
487 } break;
488 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
489 f2lpdf_pdf_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
490 } break;
491 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
492 f2leps_eps_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
493 } break;
494 case FIG2LAT_DRIVER_EPS_STANDALONE: {
495 f2leps_eps_pure_image_object(job, drw, obj, &outbb, drawdir, &ec);
496 } break;
497 /* @DRIVER@ universal */
498 default: { /* PGF */
499 f2lpgf_pgf_image_object(job, drw, obj, &outbb, drawdir, &ec);
500 } break;
501 }
502 if(ec) {
503 /* ERROR: Math error! */
504 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
505 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
506 }
507 }
508
509
510
511 void
f2lud_newpath(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)512 f2lud_newpath(
513 f2l_job_t *job,
514 dk3_fig_drawing_t *drw,
515 dk3_fig_obj_t *obj
516 )
517 {
518
519 switch(job->dr) {
520 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
521 f2lpgf_tex_newpath(job, drw, obj);
522 } break;
523 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
524 f2lpdf_tex_with_pdf_newpath(job, drw, obj);
525 } break;
526 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
527 f2lpdf_pdf_with_tex_newpath(job, drw, obj);
528 } break;
529 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
530 f2leps_eps_with_tex_newpath(job, drw, obj);
531 } break;
532 case FIG2LAT_DRIVER_EPS_STANDALONE: {
533 f2leps_eps_pure_newpath(job, drw, obj);
534 } break;
535 /* @DRIVER@ universal */
536 default: { /* PGF */
537 f2lpgf_pgf_newpath(job, drw, obj);
538 } break;
539 }
540 }
541
542
543
544 void
f2lud_moveto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double x,double y)545 f2lud_moveto(
546 f2l_job_t *job,
547 dk3_fig_drawing_t *drw,
548 dk3_fig_obj_t *obj,
549 double x,
550 double y
551 )
552 {
553
554 switch(job->dr) {
555 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
556 f2lpgf_tex_moveto(job, drw, obj, x, y);
557 } break;
558 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
559 f2lpdf_tex_with_pdf_moveto(job, drw, obj, x, y);
560 } break;
561 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
562 f2lpdf_pdf_with_tex_moveto(job, drw, obj, x, y);
563 } break;
564 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
565 f2leps_eps_with_tex_moveto(job, drw, obj, x, y);
566 } break;
567 case FIG2LAT_DRIVER_EPS_STANDALONE: {
568 f2leps_eps_pure_moveto(job, drw, obj, x, y);
569 } break;
570 /* @DRIVER@ universal */
571 default: { /* PGF */
572 f2lpgf_pgf_moveto(job, drw, obj, x, y);
573 } break;
574 }
575 }
576
577
578
579 void
f2lud_lineto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double x,double y)580 f2lud_lineto(
581 f2l_job_t *job,
582 dk3_fig_drawing_t *drw,
583 dk3_fig_obj_t *obj,
584 double x,
585 double y
586 )
587 {
588
589 switch(job->dr) {
590 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
591 f2lpgf_tex_lineto(job, drw, obj, x, y);
592 } break;
593 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
594 f2lpdf_tex_with_pdf_lineto(job, drw, obj, x, y);
595 } break;
596 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
597 f2lpdf_pdf_with_tex_lineto(job, drw, obj, x, y);
598 } break;
599 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
600 f2leps_eps_with_tex_lineto(job, drw, obj, x, y);
601 } break;
602 case FIG2LAT_DRIVER_EPS_STANDALONE: {
603 f2leps_eps_pure_lineto(job, drw, obj, x, y);
604 } break;
605 /* @DRIVER@ universal */
606 default: { /* PGF */
607 f2lpgf_pgf_lineto(job, drw, obj, x, y);
608 } break;
609 }
610 }
611
612
613
614 void
f2lud_curveto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double xcs,double ycs,double xce,double yce,double xe,double ye)615 f2lud_curveto(
616 f2l_job_t *job,
617 dk3_fig_drawing_t *drw,
618 dk3_fig_obj_t *obj,
619 double xcs,
620 double ycs,
621 double xce,
622 double yce,
623 double xe,
624 double ye
625 )
626 {
627
628 switch(job->dr) {
629 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
630 f2lpgf_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
631 } break;
632 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
633 f2lpdf_tex_with_pdf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
634 } break;
635 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
636 f2lpdf_pdf_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
637 } break;
638 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
639 f2leps_eps_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
640 } break;
641 case FIG2LAT_DRIVER_EPS_STANDALONE: {
642 f2leps_eps_pure_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
643 } break;
644 /* @DRIVER@ universal */
645 default: { /* PGF */
646 f2lpgf_pgf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
647 } break;
648 }
649 }
650
651
652
653 void
f2lud_fig_moveto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double x,double y,int * ec)654 f2lud_fig_moveto(
655 f2l_job_t *job,
656 dk3_fig_drawing_t *drw,
657 dk3_fig_obj_t *obj,
658 double x,
659 double y,
660 int *ec
661 )
662 {
663 double nx; /* Destination x in output space. */
664 double ny; /* Destination y in output space. */
665
666 nx = dk3ct_2d_x(&(job->ct2d), x, ec);
667 ny = dk3ct_2d_y(&(job->ct2d), y, ec);
668 f2lud_moveto(job, drw, obj, nx, ny);
669
670 }
671
672
673
674 void
f2lud_fig_lineto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double x,double y,int * ec)675 f2lud_fig_lineto(
676 f2l_job_t *job,
677 dk3_fig_drawing_t *drw,
678 dk3_fig_obj_t *obj,
679 double x,
680 double y,
681 int *ec
682 )
683 {
684 double nx; /* Destination x in output space. */
685 double ny; /* Destination y in output space. */
686
687 nx = dk3ct_2d_x(&(job->ct2d), x, ec);
688 ny = dk3ct_2d_y(&(job->ct2d), y, ec);
689 f2lud_lineto(job, drw, obj, nx, ny);
690
691 }
692
693
694
695 void
f2lud_fig_curveto(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double xcs,double ycs,double xce,double yce,double xe,double ye,int * ec)696 f2lud_fig_curveto(
697 f2l_job_t *job,
698 dk3_fig_drawing_t *drw,
699 dk3_fig_obj_t *obj,
700 double xcs,
701 double ycs,
702 double xce,
703 double yce,
704 double xe,
705 double ye,
706 int *ec
707 )
708 {
709 double nxcs; /* First control point x in output space. */
710 double nycs; /* First control point y in output space. */
711 double nxce; /* Second control point x in output space. */
712 double nyce; /* Second control point y in output space. */
713 double nxe; /* End point x in output space. */
714 double nye; /* End point y in output space. */
715
716 nxcs = dk3ct_2d_x(&(job->ct2d), xcs, ec);
717 nycs = dk3ct_2d_y(&(job->ct2d), ycs, ec);
718 nxce = dk3ct_2d_x(&(job->ct2d), xce, ec);
719 nyce = dk3ct_2d_y(&(job->ct2d), yce, ec);
720 nxe = dk3ct_2d_x(&(job->ct2d), xe, ec);
721 nye = dk3ct_2d_y(&(job->ct2d), ye, ec);
722 f2lud_curveto(job, drw, obj, nxcs, nycs, nxce, nyce, nxe, nye);
723
724 }
725
726
727
728 void
f2lud_closepath(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)729 f2lud_closepath(
730 f2l_job_t *job,
731 dk3_fig_drawing_t *drw,
732 dk3_fig_obj_t *obj
733 )
734 {
735
736 switch(job->dr) {
737 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
738 f2lpgf_tex_closepath(job, drw, obj);
739 } break;
740 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
741 f2lpdf_tex_with_pdf_closepath(job, drw, obj);
742 } break;
743 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
744 f2lpdf_pdf_with_tex_closepath(job, drw, obj);
745 } break;
746 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
747 f2leps_eps_with_tex_closepath(job, drw, obj);
748 } break;
749 case FIG2LAT_DRIVER_EPS_STANDALONE: {
750 f2leps_eps_pure_closepath(job, drw, obj);
751 } break;
752 /* @DRIVER@ universal */
753 default: { /* PGF */
754 f2lpgf_pgf_closepath(job, drw, obj);
755 } break;
756 }
757 }
758
759
760
761 /** Issue "fill" command.
762 @param job Job structure.
763 @param drw Drawing structure.
764 @param obj Current object to process.
765 */
766 void
f2lud_fill(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)767 f2lud_fill(
768 f2l_job_t *job,
769 dk3_fig_drawing_t *drw,
770 dk3_fig_obj_t *obj
771 )
772 {
773
774 switch(job->dr) {
775 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
776 f2lpgf_tex_fill(job, drw, obj);
777 } break;
778 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
779 f2lpdf_tex_with_pdf_fill(job, drw, obj);
780 } break;
781 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
782 f2lpdf_pdf_with_tex_fill(job, drw, obj);
783 } break;
784 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
785 f2leps_eps_with_tex_fill(job, drw, obj);
786 } break;
787 case FIG2LAT_DRIVER_EPS_STANDALONE: {
788 f2leps_eps_pure_fill(job, drw, obj);
789 } break;
790 /* @DRIVER@ universal */
791 default: { /* PGF */
792 f2lpgf_pgf_fill(job, drw, obj);
793 } break;
794 }
795 }
796
797
798
799 /** Issue combined "fill" and "clip" command.
800 @param job Job structure.
801 @param drw Drawing structure.
802 @param obj Current object to process.
803 */
804 static
805 void
f2lud_fill_clip(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)806 f2lud_fill_clip(
807 f2l_job_t *job,
808 dk3_fig_drawing_t *drw,
809 dk3_fig_obj_t *obj
810 )
811 {
812
813 switch(job->dr) {
814 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
815 f2lpgf_tex_fill_clip(job, drw, obj);
816 } break;
817 case FIG2LAT_DRIVER_PGF: {
818 f2lpgf_pgf_fill_clip(job, drw, obj);
819 } break;
820 /* @DRIVER@ universal */
821 }
822 }
823
824
825
826 /** Issue combined "fill", "stroke", and "clip" command.
827 @param job Job structure.
828 @param drw Drawing structure.
829 @param obj Current object to process.
830 */
831 static
832 void
f2lud_fill_stroke_clip(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)833 f2lud_fill_stroke_clip(
834 f2l_job_t *job,
835 dk3_fig_drawing_t *drw,
836 dk3_fig_obj_t *obj
837 )
838 {
839
840 switch(job->dr) {
841 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
842 f2lpgf_tex_fill_stroke_clip(job, drw, obj);
843 } break;
844 case FIG2LAT_DRIVER_PGF: {
845 f2lpgf_pgf_fill_stroke_clip(job, drw, obj);
846 } break;
847 /* @DRIVER@ universal */
848 }
849 }
850
851
852
853 /** Issue combined "fill" and "stroke" command.
854 @param job Job structure.
855 @param drw Drawing structure.
856 @param obj Current object to process.
857 */
858 static
859 void
f2lud_fill_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)860 f2lud_fill_stroke(
861 f2l_job_t *job,
862 dk3_fig_drawing_t *drw,
863 dk3_fig_obj_t *obj
864 )
865 {
866
867 switch(job->dr) {
868 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
869 f2lpgf_tex_fill_stroke(job, drw, obj);
870 } break;
871 case FIG2LAT_DRIVER_PGF: {
872 f2lpgf_pgf_fill_stroke(job, drw, obj);
873 } break;
874 /* @DRIVER@ universal */
875 }
876 }
877
878
879
880 void
f2lud_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)881 f2lud_stroke(
882 f2l_job_t *job,
883 dk3_fig_drawing_t *drw,
884 dk3_fig_obj_t *obj
885 )
886 {
887
888 switch(job->dr) {
889 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
890 f2lpgf_tex_stroke(job, drw, obj);
891 } break;
892 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
893 f2lpdf_tex_with_pdf_stroke(job, drw, obj);
894 } break;
895 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
896 f2lpdf_pdf_with_tex_stroke(job, drw, obj);
897 } break;
898 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
899 f2leps_eps_with_tex_stroke(job, drw, obj);
900 } break;
901 case FIG2LAT_DRIVER_EPS_STANDALONE: {
902 f2leps_eps_pure_stroke(job, drw, obj);
903 } break;
904 /* @DRIVER@ universal */
905 default: { /* PGF */
906 f2lpgf_pgf_stroke(job, drw, obj);
907 } break;
908 }
909 }
910
911
912
913 /** Issue "clip" command.
914 @param job Job structure.
915 @param drw Drawing structure.
916 @param obj Current object to process.
917 */
918 static
919 void
f2lud_clip(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)920 f2lud_clip(
921 f2l_job_t *job,
922 dk3_fig_drawing_t *drw,
923 dk3_fig_obj_t *obj
924 )
925 {
926
927 switch(job->dr) {
928 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
929 f2lpgf_tex_clip(job, drw, obj);
930 } break;
931 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
932 f2lpdf_tex_with_pdf_clip(job, drw, obj);
933 } break;
934 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
935 f2lpdf_pdf_with_tex_clip(job, drw, obj);
936 } break;
937 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
938 f2leps_eps_with_tex_clip(job, drw, obj);
939 } break;
940 case FIG2LAT_DRIVER_EPS_STANDALONE: {
941 f2leps_eps_pure_clip(job, drw, obj);
942 } break;
943 /* @DRIVER@ universal */
944 default: { /* PGF */
945 f2lpgf_pgf_clip(job, drw, obj);
946 } break;
947 }
948 }
949
950
951
952 /** Issue "gsave" command.
953 @param job Job structure.
954 @param drw Drawing structure.
955 @param obj Current object to process.
956 */
957 static
958 void
f2lud_gsave(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)959 f2lud_gsave(
960 f2l_job_t *job,
961 dk3_fig_drawing_t *drw,
962 dk3_fig_obj_t *obj
963 )
964 {
965
966 switch(job->dr) {
967 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
968 f2lpgf_tex_gsave(job, drw, obj);
969 } break;
970 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
971 f2lpdf_tex_with_pdf_gsave(job, drw, obj);
972 } break;
973 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
974 f2lpdf_pdf_with_tex_gsave(job, drw, obj);
975 } break;
976 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
977 f2leps_eps_with_tex_gsave(job, drw, obj);
978 } break;
979 case FIG2LAT_DRIVER_EPS_STANDALONE: {
980 f2leps_eps_pure_gsave(job, drw, obj);
981 } break;
982 /* @DRIVER@ universal */
983 default: { /* PGF */
984 f2lpgf_pgf_gsave(job, drw, obj);
985 } break;
986 }
987 }
988
989
990
991 /** Issue "grestore" command.
992 @param job Job structure.
993 @param drw Drawing structure.
994 @param obj Current object to process.
995 */
996 static
997 void
f2lud_grestore(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)998 f2lud_grestore(
999 f2l_job_t *job,
1000 dk3_fig_drawing_t *drw,
1001 dk3_fig_obj_t *obj
1002 )
1003 {
1004
1005 switch(job->dr) {
1006 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
1007 f2lpgf_tex_grestore(job, drw, obj);
1008 } break;
1009 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
1010 f2lpdf_tex_with_pdf_grestore(job, drw, obj);
1011 } break;
1012 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
1013 f2lpdf_pdf_with_tex_grestore(job, drw, obj);
1014 } break;
1015 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
1016 f2leps_eps_with_tex_grestore(job, drw, obj);
1017 } break;
1018 case FIG2LAT_DRIVER_EPS_STANDALONE: {
1019 f2leps_eps_pure_grestore(job, drw, obj);
1020 } break;
1021 /* @DRIVER@ universal */
1022 default: { /* PGF */
1023 f2lpgf_pgf_grestore(job, drw, obj);
1024 } break;
1025 }
1026 }
1027
1028
1029
1030 /** Create path for ellipse object.
1031 @param job Job structure.
1032 @param drw Drawing structure.
1033 @param obj Current object to process.
1034 @param ec Pointe to error code variable, may be NULL.
1035 */
1036 static
1037 void
f2lud_create_ellipse_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)1038 f2lud_create_ellipse_path(
1039 f2l_job_t *job,
1040 dk3_fig_drawing_t *drw,
1041 dk3_fig_obj_t *obj,
1042 int *ec
1043 )
1044 {
1045 dk3_fig_poly_point_t po[12]; /* Points in Fig space. */
1046 double myan; /* Rotation angle in Fig space. */
1047 size_t i; /* Index of current point to modify. */
1048
1049 po[0].x = (obj->dt).ell.rx;
1050 po[0].y = 0.0;
1051 po[1].x = (obj->dt).ell.rx;
1052 po[1].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.ry;
1053 po[2].x = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.rx;
1054 po[2].y = (obj->dt).ell.ry;
1055 po[3].x = 0.0;
1056 po[3].y = (obj->dt).ell.ry;
1057 po[4].x = 0.0 - po[2].x;
1058 po[4].y = po[2].y;
1059 po[5].x = 0.0 - po[1].x;
1060 po[5].y = po[1].y;
1061 po[6].x = 0.0 - po[0].x;
1062 po[6].y = 0.0;
1063 po[7].x = po[6].x;
1064 po[7].y = 0.0 - po[5].y;
1065 po[8].x = po[4].x;
1066 po[8].y = 0.0 - po[2].y;
1067 po[9].x = 0.0;
1068 po[9].y = 0.0 - po[3].y;
1069 po[10].x = po[2].x;
1070 po[10].y = po[9].y;
1071 po[11].x = po[1].x;
1072 po[11].y = po[7].y;
1073 switch(obj->st) {
1074 case 1: case 2: {
1075 if(1.0e-6 < fabs((obj->dt).ell.an)) {
1076 if(1.0e-6 < fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,ec)))
1077 {
1078 myan = -1.0 * (obj->dt).ell.an;
1079 for(i = 0; i < 12; i++) {
1080 dk3fig_tool_rotate_point(&(po[i]), myan, ec);
1081 }
1082 }
1083 }
1084 } break;
1085 }
1086 for(i = 0; i < 12; i++) {
1087 dk3fig_tool_shift_point(&(po[i]), (obj->dt).ell.cx, (obj->dt).ell.cy, ec);
1088 }
1089 f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
1090 f2lud_fig_curveto(
1091 job, drw, obj,
1092 po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y,
1093 ec
1094 );
1095 f2lud_fig_curveto(
1096 job, drw, obj,
1097 po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y,
1098 ec
1099 );
1100 f2lud_fig_curveto(
1101 job, drw, obj,
1102 po[7].x, po[7].y, po[8].x, po[8].y, po[9].x, po[9].y,
1103 ec
1104 );
1105 f2lud_fig_curveto(
1106 job, drw, obj,
1107 po[10].x, po[10].y, po[11].x, po[11].y, po[0].x, po[0].y,
1108 ec
1109 );
1110
1111 }
1112
1113
1114
1115 /** Create path for polygon object.
1116 @param job Job structure.
1117 @param drw Drawing structure.
1118 @param obj Current object to process.
1119 @param ec Pointe to error code variable, may be NULL.
1120 */
1121 static
1122 void
f2lud_create_polygon_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)1123 f2lud_create_polygon_path(
1124 f2l_job_t *job,
1125 dk3_fig_drawing_t *drw,
1126 dk3_fig_obj_t *obj,
1127 int *ec
1128 )
1129 {
1130 dk3_fig_poly_point_t *po; /* Current point to process. */
1131 size_t np; /* Number of points. */
1132 size_t i; /* Index of current point. */
1133
1134 po = (obj->dt).pol.po;
1135 np = (obj->dt).pol.np;
1136 for(i = 0; i < np; i++) {
1137 if(0 == i) {
1138 f2lud_fig_moveto(job, drw, obj, po->x, po->y, ec);
1139 } else {
1140 f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
1141 }
1142 po++;
1143 }
1144 if(obj->cl) {
1145 po = (obj->dt).pol.po;
1146 f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
1147 }
1148 }
1149
1150
1151
1152 /** Create path for box object.
1153 @param job Job structure.
1154 @param drw Drawing structure.
1155 @param obj Current object to process.
1156 @param ec Pointe to error code variable, may be NULL.
1157 */
1158 static
1159 void
f2lud_create_box_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)1160 f2lud_create_box_path(
1161 f2l_job_t *job,
1162 dk3_fig_drawing_t *drw,
1163 dk3_fig_obj_t *obj,
1164 int *ec
1165 )
1166 {
1167 dk3_bb_t outbb; /* Box coordinates in output space. */
1168
1169 dk3bb_reset(&outbb);
1170 f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
1171 f2lud_moveto(job, drw, obj, outbb.xmin, outbb.ymin);
1172 f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymin);
1173 f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymax);
1174 f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymax);
1175 f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymin);
1176
1177 }
1178
1179
1180
1181 /** Create path for arc box object.
1182 @param job Job structure.
1183 @param drw Drawing structure.
1184 @param obj Current object to process.
1185 @param ec Pointe to error code variable, may be NULL.
1186 */
1187 static
1188 void
f2lud_create_arc_box_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)1189 f2lud_create_arc_box_path(
1190 f2l_job_t *job,
1191 dk3_fig_drawing_t *drw,
1192 dk3_fig_obj_t *obj,
1193 int *ec
1194 )
1195 {
1196 dk3_fig_poly_point_t po[16]; /* Box points in output space. */
1197 dk3_bb_t outbb; /* Box coordinates in output space. */
1198 double r; /* Corner radius in output space. */
1199 double maxr; /* Maximum value for corner radius. */
1200 double corner; /* Factor control to end. */
1201 double rc; /* Dist of control to end in output space. */
1202
1203 dk3bb_reset(&outbb);
1204 f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
1205 #if VERSION_BEFORE_20140808
1206 r = dk3ct_2d_r(&(job->ct2d), (obj->dt).pol.ra, ec);
1207 #else
1208 r = 0.9 * (obj->dt).pol.ra;
1209 #endif
1210 maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec));
1211 if(r > maxr) r = maxr;
1212 maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec));
1213 if(r > maxr) r = maxr;
1214 corner = 1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER;
1215 rc = r * corner;
1216 /* Bottom line */
1217 po[0].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
1218 po[0].y = outbb.ymin;
1219 po[1].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
1220 po[1].y = po[0].y;
1221 /* Lower right corner control points */
1222 po[2].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
1223 po[2].y = po[0].y;
1224 po[3].x = outbb.xmax;
1225 po[3].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
1226 /* Right line */
1227 po[4].x = outbb.xmax;
1228 po[4].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
1229 po[5].x = outbb.xmax;
1230 po[5].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
1231 /* Upper right corner control points */
1232 po[6].x = outbb.xmax;
1233 po[6].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
1234 po[7].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
1235 po[7].y = outbb.ymax;
1236 /* Top line */
1237 po[8].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
1238 po[8].y = outbb.ymax;
1239 po[9].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
1240 po[9].y = outbb.ymax;
1241 /* Upper left corner control points */
1242 po[10].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
1243 po[10].y = outbb.ymax;
1244 po[11].x = outbb.xmin;
1245 po[11].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
1246 /* Left line */
1247 po[12].x = outbb.xmin;
1248 po[12].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
1249 po[13].x = outbb.xmin;
1250 po[13].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
1251 /* Lower left corner control points */
1252 po[14].x = outbb.xmin;
1253 po[14].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
1254 po[15].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
1255 po[15].y = outbb.ymin;
1256 f2lud_moveto(job, drw, obj, po[0].x, po[0].y);
1257 f2lud_lineto(job, drw, obj, po[1].x, po[1].y);
1258 f2lud_curveto(
1259 job, drw, obj,
1260 po[2].x, po[2].y, po[3].x, po[3].y, po[4].x, po[4].y
1261 );
1262 f2lud_lineto(job, drw, obj, po[5].x, po[5].y);
1263 f2lud_curveto(
1264 job, drw, obj,
1265 po[6].x, po[6].y, po[7].x, po[7].y, po[8].x, po[8].y
1266 );
1267 f2lud_lineto(job, drw, obj, po[9].x, po[9].y);
1268 f2lud_curveto(
1269 job, drw, obj,
1270 po[10].x, po[10].y, po[11].x, po[11].y, po[12].x, po[12].y
1271 );
1272 f2lud_lineto(job, drw, obj, po[13].x, po[13].y);
1273 f2lud_curveto(
1274 job, drw, obj,
1275 po[14].x, po[14].y, po[15].x, po[15].y, po[0].x, po[0].y
1276 );
1277
1278 }
1279
1280
1281
1282 /** Create path for the last partial X-spline segment from closed X-spline.
1283 @param job Job structure.
1284 @param drw Fig drawing.
1285 @param obj Fig object.
1286 @param sp Spline points array.
1287 @param np Number of spline points.
1288 @param i Current segment index.
1289 @param te Parameter t for end point.
1290 @param isfirst Flag: First segment.
1291 @param iscl Flag: Closed spline.
1292 @param primary Flag: Primary (1=primary object, 0=arrowhead).
1293 @param ec Pointer to error code variable, may be NULL.
1294 */
1295 static
1296 void
f2lud_final_spline_segment(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,dk3_fig_spline_point_t * sp,size_t np,size_t i,double te,int isfirst,int DK3_SILENCE_ARG_UNUSED (iscl),int primary,int * ec)1297 f2lud_final_spline_segment(
1298 f2l_job_t *job,
1299 dk3_fig_drawing_t *drw,
1300 dk3_fig_obj_t *obj,
1301 dk3_fig_spline_point_t *sp,
1302 size_t np,
1303 size_t i,
1304 double te,
1305 int isfirst,
1306 int DK3_SILENCE_ARG_UNUSED(iscl),
1307 int primary,
1308 int *ec
1309 )
1310 {
1311 dk3_xspline_segment_t seg; /* Segment for caluclation. */
1312 dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
1313 dk3_fig_spline_point_t *pb = NULL; /* Start. */
1314 dk3_fig_spline_point_t *pc = NULL; /* End. */
1315 dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
1316 double myte; /* t for end. */
1317 double dnumsegs; /* Number of segments. */
1318 double factor; /* Scale factor for deriv. */
1319 double t; /* Current t. */
1320 double x; /* Bezier end x. */
1321 double y; /* Bezier end y. */
1322 double dxdt; /* Bezier dx/dt at end. */
1323 double dydt; /* Bezier dy/dt at end. */
1324 double lastx = 0.0; /* Bezier start x. */
1325 double lasty = 0.0; /* Bezier start y. */
1326 double lastdxdt = 0.0; /* dx/dt at start. */
1327 double lastdydt = 0.0; /* dy/dt at end. */
1328 size_t nsegs; /* Number of segments. */
1329 size_t iseg; /* Current segment. */
1330 int res; /* Calculation result. */
1331
1332 DK3_UNUSED_ARG(iscl)
1333 myte = dk3ma_d_sub_ok(te, floor(te), ec);
1334 dnumsegs = myte * (double)dk3fig_tool_xssbs(drw, primary);
1335 dnumsegs = ceil(dnumsegs);
1336 nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
1337 pb = &(sp[i]);
1338 pc = &(sp[i + 1]);
1339 if(0 < i) {
1340 pa = &(sp[i - 1]);
1341 }
1342 if(i < (np - 2)) {
1343 pd = &(sp[i + 2]);
1344 }
1345 factor = myte / (double)nsegs;
1346 dk3xsp_reset(&seg);
1347 if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
1348 dk3xsp_set(&seg, pa, pb, pc, pd);
1349 if(dk3xsp_calculate(&seg, 0.0, 1)) {
1350 lastx = dk3xsp_get_x(&seg);
1351 lasty = dk3xsp_get_y(&seg);
1352 lastdxdt = dk3xsp_get_dxdt(&seg);
1353 lastdydt = dk3xsp_get_dydt(&seg);
1354 lastdxdt = (factor * lastdxdt) / 3.0;
1355 lastdydt = (factor * lastdydt) / 3.0;
1356 /* Move to start point.
1357 */
1358 if(isfirst) {
1359 f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
1360 }
1361 /* Further curve only if te > 1.0e-6.
1362 For smaller te draw straight line.
1363 */
1364 if(1.0e-6 < myte) {
1365 for(iseg = 0; iseg < nsegs; iseg++) {
1366 if(iseg < (nsegs - 1)) {
1367 t = (double)(iseg + 1) / (double)nsegs;
1368 t = t * myte;
1369 } else {
1370 t = myte;
1371 }
1372 res = dk3xsp_calculate(&seg, t, 1);
1373 if(!(res)) {
1374 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1375 }
1376 x = dk3xsp_get_x(&seg);
1377 y = dk3xsp_get_y(&seg);
1378 dxdt = dk3xsp_get_dxdt(&seg);
1379 dydt = dk3xsp_get_dydt(&seg);
1380 dxdt = (factor * dxdt) / 3.0;
1381 dydt = (factor * dydt) / 3.0;
1382 f2lud_fig_curveto(
1383 job, drw, obj,
1384 dk3ma_d_add_ok(lastx, lastdxdt, ec),
1385 dk3ma_d_add_ok(lasty, lastdydt, ec),
1386 dk3ma_d_sub_ok(x, dxdt, ec),
1387 dk3ma_d_sub_ok(y, dydt, ec),
1388 x, y,
1389 ec
1390 );
1391 lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
1392 }
1393 } else {
1394 res = dk3xsp_calculate(&seg, myte, 0);
1395 if(!(res)) {
1396 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1397 /* ERROR: Math */
1398 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
1399 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1400 }
1401 x = dk3xsp_get_x(&seg);
1402 y = dk3xsp_get_y(&seg);
1403 f2lud_fig_lineto(job, drw, obj, x, y, ec);
1404 }
1405 } else {
1406 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1407 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1408 }
1409
1410 }
1411
1412
1413
1414 /** Create path for the first partial X-spline segment from closed X-spline.
1415 @param job Job structure.
1416 @param drw Fig drawing.
1417 @param obj Fig object.
1418 @param sp Spline points array.
1419 @param np Number of spline points.
1420 @param i Current segment index.
1421 @param ts Parameter t for start point.
1422 @param isfirst Flag: First segment.
1423 @param iscl Flag: Closed spline.
1424 @param primary Flag: Primary (1=primary object, 0=arrowhead).
1425 @param ec Pointer to error code variable, may be NULL.
1426 */
1427 static
1428 void
f2lud_first_spline_segment(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,dk3_fig_spline_point_t * sp,size_t np,size_t i,double ts,int isfirst,int DK3_SILENCE_ARG_UNUSED (iscl),int primary,int * ec)1429 f2lud_first_spline_segment(
1430 f2l_job_t *job,
1431 dk3_fig_drawing_t *drw,
1432 dk3_fig_obj_t *obj,
1433 dk3_fig_spline_point_t *sp,
1434 size_t np,
1435 size_t i,
1436 double ts,
1437 int isfirst,
1438 int DK3_SILENCE_ARG_UNUSED(iscl),
1439 int primary,
1440 int *ec
1441 )
1442 {
1443 dk3_xspline_segment_t seg; /* Segment for caluclation. */
1444 dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
1445 dk3_fig_spline_point_t *pb = NULL; /* Start. */
1446 dk3_fig_spline_point_t *pc = NULL; /* End. */
1447 dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
1448 double myts; /* t for start. */
1449 double dnumsegs; /* Number of segments. */
1450 double factor; /* Scale factor for deriv. */
1451 double t; /* Current t. */
1452 double x; /* Bezier end x. */
1453 double y; /* Bezier end y. */
1454 double dxdt; /* Bezier dx/dt at end. */
1455 double dydt; /* Bezier dy/dt at end. */
1456 double lastx = 0.0; /* Bezier start x. */
1457 double lasty = 0.0; /* Bezier start y. */
1458 double lastdxdt = 0.0; /* dx/dt at start. */
1459 double lastdydt = 0.0; /* dy/dt at end. */
1460 size_t nsegs; /* Number of segments. */
1461 size_t iseg; /* Current segment. */
1462 int res; /* Calculation result. */
1463
1464 DK3_UNUSED_ARG(iscl)
1465 myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
1466 dnumsegs = (1.0 - myts) * (double)dk3fig_tool_xssbs(drw, primary);
1467 dnumsegs = ceil(dnumsegs);
1468 nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
1469 pb = &(sp[i]);
1470 pc = &(sp[i + 1]);
1471 if(0 < i) {
1472 pa = &(sp[i - 1]);
1473 }
1474 if(i < (np - 2)) {
1475 pd = &(sp[i + 2]);
1476 }
1477 factor = (1.0 - myts) / (double)nsegs;
1478 dk3xsp_reset(&seg);
1479 if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
1480 dk3xsp_set(&seg, pa, pb, pc, pd);
1481 if(dk3xsp_calculate(&seg, myts, 1)) {
1482 /* If necessary move to the start point.
1483 */
1484 lastx = dk3xsp_get_x(&seg);
1485 lasty = dk3xsp_get_y(&seg);
1486 lastdxdt = dk3xsp_get_dxdt(&seg);
1487 lastdydt = dk3xsp_get_dydt(&seg);
1488 lastdxdt = (factor * lastdxdt) / 3.0;
1489 lastdydt = (factor * lastdydt) / 3.0;
1490 if(isfirst) {
1491 f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
1492 }
1493 if(1.0e-6 < (1.0 - myts)) {
1494 for(iseg = 0; iseg < nsegs; iseg++) {
1495 if(iseg < (nsegs - 1)) {
1496 t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
1497 } else {
1498 t = 1.0;
1499 }
1500 res = dk3xsp_calculate(&seg, t, 1);
1501 if(!(res)) {
1502 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1503 }
1504 x = dk3xsp_get_x(&seg);
1505 y = dk3xsp_get_y(&seg);
1506 dxdt = dk3xsp_get_dxdt(&seg);
1507 dydt = dk3xsp_get_dydt(&seg);
1508 dxdt = (factor * dxdt) / 3.0;
1509 dydt = (factor * dydt) / 3.0;
1510 f2lud_fig_curveto(
1511 job, drw, obj,
1512 dk3ma_d_add_ok(lastx, lastdxdt, ec),
1513 dk3ma_d_add_ok(lasty, lastdydt, ec),
1514 dk3ma_d_sub_ok(x, dxdt, ec),
1515 dk3ma_d_sub_ok(y, dydt, ec),
1516 x, y,
1517 ec
1518 );
1519 lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
1520 }
1521 } else {
1522 res = dk3xsp_calculate(&seg, 1.0, 0);
1523 if(!(res)) {
1524 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1525 /* ERROR: Math */
1526 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
1527 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1528 }
1529 x = dk3xsp_get_x(&seg);
1530 y = dk3xsp_get_y(&seg);
1531 f2lud_fig_lineto(job, drw, obj, x, y, ec);
1532 }
1533 } else {
1534 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1535 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1536 }
1537
1538 }
1539
1540
1541
1542
1543 /** Create path for the single partial X-spline segment cutted on both ends
1544 from closed X-spline.
1545 @param job Job structure.
1546 @param drw Fig drawing.
1547 @param obj Fig object.
1548 @param sp Spline points array.
1549 @param np Number of spline points.
1550 @param i Current segment index.
1551 @param ts Parameter t for start point.
1552 @param te Parameter t for end point.
1553 @param isfirst Flag: First segment.
1554 @param iscl Flag: Closed spline.
1555 @param primary Flag: Primary (1=primary object, 0=arrowhead).
1556 @param ec Pointer to error code variable, may be NULL.
1557 */
1558 static
1559 void
f2lud_single_spline_segment(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,dk3_fig_spline_point_t * sp,size_t np,size_t i,double ts,double te,int isfirst,int DK3_SILENCE_ARG_UNUSED (iscl),int primary,int * ec)1560 f2lud_single_spline_segment(
1561 f2l_job_t *job,
1562 dk3_fig_drawing_t *drw,
1563 dk3_fig_obj_t *obj,
1564 dk3_fig_spline_point_t *sp,
1565 size_t np,
1566 size_t i,
1567 double ts,
1568 double te,
1569 int isfirst,
1570 int DK3_SILENCE_ARG_UNUSED(iscl),
1571 int primary,
1572 int *ec
1573 )
1574 {
1575 dk3_xspline_segment_t seg; /* Segment for caluclation. */
1576 dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
1577 dk3_fig_spline_point_t *pb = NULL; /* Start. */
1578 dk3_fig_spline_point_t *pc = NULL; /* End. */
1579 dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
1580 double myte; /* t for end. */
1581 double myts; /* t for start. */
1582 double dnumsegs; /* Number of segments. */
1583 double factor; /* Scale factor for deriv. */
1584 double t; /* Current t. */
1585 double x; /* Bezier end x. */
1586 double y; /* Bezier end y. */
1587 double dxdt; /* Bezier dx/dt at end. */
1588 double dydt; /* Bezier dy/dt at end. */
1589 double lastx = 0.0; /* Bezier start x. */
1590 double lasty = 0.0; /* Bezier start y. */
1591 double lastdxdt = 0.0; /* dx/dt at start. */
1592 double lastdydt = 0.0; /* dy/dt at end. */
1593 size_t nsegs; /* Number of segments. */
1594 size_t iseg; /* Current segment. */
1595 int res; /* Calculation result. */
1596
1597 DK3_UNUSED_ARG(iscl)
1598 myte = dk3ma_d_sub_ok(te, floor(te), ec);
1599 myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
1600 dnumsegs = (myte - myts) * (double)dk3fig_tool_xssbs(drw, primary);
1601 dnumsegs = ceil(dnumsegs);
1602 nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
1603 pb = &(sp[i]);
1604 pc = &(sp[i + 1]);
1605 if(0 < i) {
1606 pa = &(sp[i - 1]);
1607 }
1608 if(i < (np - 2)) {
1609 pd = &(sp[i + 2]);
1610 }
1611 factor = (myte - myts) / ((double)nsegs);
1612 dk3xsp_reset(&seg);
1613 if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
1614 dk3xsp_set(&seg, pa, pb, pc, pd);
1615 if(dk3xsp_calculate(&seg, myts, 1)) {
1616 lastx = dk3xsp_get_x(&seg);
1617 lasty = dk3xsp_get_y(&seg);
1618 lastdxdt = dk3xsp_get_dxdt(&seg);
1619 lastdydt = dk3xsp_get_dydt(&seg);
1620 lastdxdt = (factor * lastdxdt) / 3.0;
1621 lastdydt = (factor * lastdydt) / 3.0;
1622 if(isfirst) {
1623 f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
1624 }
1625 if(1.0e-6 < (myte - myts)) {
1626 for(iseg = 0; iseg < nsegs; iseg++) {
1627 if(iseg < (nsegs - 1)) {
1628 t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
1629 } else {
1630 t = myte;
1631 }
1632 res = dk3xsp_calculate(&seg, t, 1);
1633 if(!(res)) {
1634 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1635 }
1636 x = dk3xsp_get_x(&seg);
1637 y = dk3xsp_get_y(&seg);
1638 dxdt = dk3xsp_get_dxdt(&seg);
1639 dydt = dk3xsp_get_dydt(&seg);
1640 dxdt = (factor * dxdt) / 3.0;
1641 dydt = (factor * dydt) / 3.0;
1642 f2lud_fig_curveto(
1643 job, drw, obj,
1644 dk3ma_d_add_ok(lastx, lastdxdt, ec),
1645 dk3ma_d_add_ok(lasty, lastdydt, ec),
1646 dk3ma_d_sub_ok(x, dxdt, ec),
1647 dk3ma_d_sub_ok(y, dydt, ec),
1648 x, y,
1649 ec
1650 );
1651 lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
1652 }
1653 } else {
1654 res = dk3xsp_calculate(&seg, myte, 0);
1655 if(!(res)) {
1656 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1657 /* ERROR: Calculation failed! */
1658 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
1659 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1660 }
1661 x = dk3xsp_get_x(&seg);
1662 y = dk3xsp_get_y(&seg);
1663 f2lud_fig_lineto(job, drw, obj, x, y, ec);
1664 }
1665 } else {
1666 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1667 /* ERROR: Calculation failed! */
1668 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
1669 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
1670 }
1671
1672 }
1673
1674
1675
1676
1677 /** Create path for one complete X-spline segment from closed X-spline.
1678 @param job Job structure.
1679 @param drw Fig drawing.
1680 @param obj Fig object.
1681 @param sp Spline points array.
1682 @param np Number of spline points.
1683 @param i Current segment index.
1684 @param isfirst Flag: First segment.
1685 @param iscl Flag: Closed spline.
1686 @param primary Flag: Primary (1=primary object, 0=arrowhead).
1687 @param ec Pointer to error code variable, may be NULL.
1688 */
1689 static
1690 void
f2lud_full_spline_segment(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,dk3_fig_spline_point_t * sp,size_t np,size_t i,int isfirst,int iscl,int primary,int * ec)1691 f2lud_full_spline_segment(
1692 f2l_job_t *job,
1693 dk3_fig_drawing_t *drw,
1694 dk3_fig_obj_t *obj,
1695 dk3_fig_spline_point_t *sp,
1696 size_t np,
1697 size_t i,
1698 int isfirst,
1699 int iscl,
1700 int primary,
1701 int *ec
1702 )
1703 {
1704 dk3_xspline_segment_t seg; /* Segment for caluclation. */
1705 dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
1706 dk3_fig_spline_point_t *pb = NULL; /* Start. */
1707 dk3_fig_spline_point_t *pc = NULL; /* End. */
1708 dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
1709 double factor; /* Scale factor for deriv. */
1710 double t; /* Current t. */
1711 double x; /* Bezier end x. */
1712 double y; /* Bezier end y. */
1713 double dxdt; /* Bezier dx/dt at end. */
1714 double dydt; /* Bezier dy/dt at end. */
1715 double lastx = 0.0; /* Bezier start x. */
1716 double lasty = 0.0; /* Bezier start y. */
1717 double lastdxdt = 0.0; /* dx/dt at start. */
1718 double lastdydt = 0.0; /* dy/dt at end. */
1719 size_t xsss; /* Number of segments. */
1720 size_t iseg; /* Current segment. */
1721 size_t ic;
1722 size_t id;
1723 int res; /* Calculation result. */
1724
1725 if(i < ((iscl) ? np : (np - 1))) {
1726 pb = &(sp[i]);
1727 ic = i + 1; while(ic >= np) { ic = ic - np; }
1728 pc = &(sp[ic]);
1729 if(i > 0) {
1730 pa = &(sp[i - 1]);
1731 } else {
1732 if(iscl) {
1733 pa = &(sp[np - 1]);
1734 }
1735 }
1736 if(i < (np - 2)) {
1737 pd = &(sp[i + 2]);
1738 } else {
1739 if(iscl) {
1740 id = i + 2; while(id >= np) { id = id - np; }
1741 pd = &(sp[id]);
1742 }
1743 }
1744 xsss = dk3fig_tool_xssbs(drw, primary);
1745 factor = 1.0 / (double)xsss;
1746 dk3xsp_reset(&seg);
1747 if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
1748 dk3xsp_set(&seg, pa, pb, pc, pd);
1749 if(dk3xsp_calculate(&seg, 0.0, 1)) {
1750 lastx = dk3xsp_get_x(&seg);
1751 lasty = dk3xsp_get_y(&seg);
1752 lastdxdt = dk3xsp_get_dxdt(&seg);
1753 lastdydt = dk3xsp_get_dydt(&seg);
1754 lastdxdt = (factor * lastdxdt) / 3.0;
1755 lastdydt = (factor * lastdydt) / 3.0;
1756 if(isfirst) {
1757 f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
1758 }
1759 for(iseg = 0; iseg < xsss; iseg++) {
1760 if(iseg < (xsss - 1)) {
1761 t = (double)(iseg + 1) / (double)xsss;
1762 } else {
1763 t = 1.0;
1764 }
1765 res = dk3xsp_calculate(&seg, t, 1);
1766 if(!(res)) {
1767 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1768 }
1769 x = dk3xsp_get_x(&seg);
1770 y = dk3xsp_get_y(&seg);
1771 dxdt = dk3xsp_get_dxdt(&seg);
1772 dydt = dk3xsp_get_dydt(&seg);
1773 dxdt = (factor * dxdt) / 3.0;
1774 dydt = (factor * dydt) / 3.0;
1775 f2lud_fig_curveto(
1776 job, drw, obj,
1777 dk3ma_d_add_ok(lastx, lastdxdt, ec),
1778 dk3ma_d_add_ok(lasty, lastdydt, ec),
1779 dk3ma_d_sub_ok(x, dxdt, ec),
1780 dk3ma_d_sub_ok(y, dydt, ec),
1781 x,
1782 y,
1783 ec
1784 );
1785 lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
1786 }
1787 } else {
1788 if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
1789 }
1790 } else {
1791 /* ERROR: BUG: Wrong i */
1792 }
1793 }
1794
1795
1796
1797 /** Create path for open spline object.
1798 @param job Job structure.
1799 @param drw Drawing structure.
1800 @param obj Current object to process.
1801 @param primary Flag: Primary object (1=object, 0=arrowhead).
1802 @param ec Pointe to error code variable, may be NULL.
1803 */
1804 static
1805 void
f2lud_create_open_spline_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)1806 f2lud_create_open_spline_path(
1807 f2l_job_t *job,
1808 dk3_fig_drawing_t *drw,
1809 dk3_fig_obj_t *obj,
1810 int primary,
1811 int *ec
1812 )
1813 {
1814 dk3_fig_spline_point_t *sp; /* Spline points. */
1815 size_t np; /* Number of points. */
1816 size_t i; /* Current segment index. */
1817 size_t min; /* Minimum t value. */
1818 size_t max; /* Maximum t value. */
1819
1820 sp = (obj->dt).spl.po;
1821 np = (obj->dt).spl.np;
1822
1823 if(job->coah) {
1824 for(i = 0; i < (np - 1); i++) {
1825 f2lud_full_spline_segment(
1826 job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
1827 );
1828 }
1829 } else {
1830 if(obj->ab) {
1831 /* 2013-11-23
1832 ROUNDING DOWNWARDS INTENDED.
1833 We want to find the start segment.
1834 */
1835 min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
1836 if(obj->af) {
1837 if((obj->dt).spl.te >= (obj->dt).spl.ts) {
1838 /* 2013-11-23
1839 ROUNDING DOWNWARDS INTENDED.
1840 We want to find the last full segment to draw.
1841 */
1842 max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
1843 if(max > min) {
1844 f2lud_first_spline_segment(
1845 job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
1846 );
1847 /* 2012-12-04 Bugfix: Only to max.
1848 */
1849 #if VERSION_BEFORE_20121204
1850 for(i = (min + 1); i < (np - 1); i++) {
1851 f2lud_full_spline_segment(
1852 job, drw, obj, sp, np, i, 0, 0, primary, ec
1853 );
1854 }
1855 #else
1856 for(i = (min + 1); i < max; i++) {
1857 f2lud_full_spline_segment(
1858 job, drw, obj, sp, np, i, 0, 0, primary, ec
1859 );
1860 }
1861 #endif
1862 f2lud_final_spline_segment(
1863 job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
1864 );
1865 } else {
1866 f2lud_single_spline_segment(
1867 job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
1868 1, 0, primary, ec
1869 );
1870 }
1871 } else {
1872 /* ERROR: Arrowheads too long for spline! */
1873 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
1874 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX);
1875 }
1876 } else {
1877 f2lud_first_spline_segment(
1878 job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
1879 );
1880 for(i = (min + 1); i < (np - 1); i++) {
1881 f2lud_full_spline_segment(
1882 job, drw, obj, sp, np, i, 0, 0, primary, ec
1883 );
1884 }
1885 }
1886 } else {
1887 if(obj->af) {
1888 /* 2013-11-23
1889 ROUNDING DOWNWARDS INTENDED.
1890 We want to find the last full segment.
1891 */
1892 max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
1893 if(max < (np - 1)) {
1894 if(max > 0) {
1895 for(i = 0; i < max; i++) {
1896 f2lud_full_spline_segment(
1897 job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
1898 );
1899 }
1900 f2lud_final_spline_segment(
1901 job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
1902 );
1903 } else {
1904 f2lud_final_spline_segment(
1905 job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
1906 );
1907 }
1908 } else {
1909 /* ERROR: Illegal max value! */
1910 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
1911 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
1912 }
1913 } else {
1914 for(i = 0; i < (np - 1); i++) {
1915 f2lud_full_spline_segment(
1916 job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
1917 );
1918 }
1919 }
1920 }
1921 }
1922
1923 }
1924
1925
1926
1927 /** Create path for open spline object.
1928 @param job Job structure.
1929 @param drw Drawing structure.
1930 @param obj Current object to process.
1931 @param primary Flag: Primary object (1=object, 0=arrowhead).
1932 @param ec Pointe to error code variable, may be NULL.
1933 */
1934 static
1935 void
f2lud_create_open_fast_spline_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int DK3_SILENCE_ARG_UNUSED (primary),int * ec)1936 f2lud_create_open_fast_spline_path(
1937 f2l_job_t *job,
1938 dk3_fig_drawing_t *drw,
1939 dk3_fig_obj_t *obj,
1940 int DK3_SILENCE_ARG_UNUSED(primary),
1941 int *ec
1942 )
1943 {
1944 dk3_fig_spline_point_t *po;
1945 size_t np;
1946 size_t ib;
1947 size_t ic;
1948 double dxdtb;
1949 double dydtb;
1950 double dxdtc;
1951 double dydtc;
1952
1953 DK3_UNUSED_ARG(primary)
1954 po = (obj->dt).spl.po;
1955 np = (obj->dt).spl.np;
1956 if (np > 1) {
1957 for (ib = 0; ib < (np - 1); ib++) {
1958 ic = ib + 1;
1959 if (0 == ib) {
1960 /* MOVETO */
1961 f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
1962 }
1963 if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
1964 /* LINETO */
1965 f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
1966 } else {
1967 dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
1968 dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
1969 if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
1970 dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
1971 dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
1972 } else {
1973 if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
1974 dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
1975 dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
1976 }
1977 }
1978 if ((ic < (np - 1)) && (1.0 + fabs(po[ic].s) < 1.0e-6)) {
1979 dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
1980 dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
1981 } else {
1982 if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
1983 dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
1984 dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
1985 }
1986 }
1987 /* CURVETO */
1988 f2lud_fig_curveto(
1989 job, drw, obj,
1990 dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
1991 dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
1992 dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
1993 dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
1994 po[ic].x,
1995 po[ic].y,
1996 ec
1997 );
1998 }
1999 }
2000 }
2001 }
2002
2003
2004
2005 /** Create path for closed spline object.
2006 @param job Job structure.
2007 @param drw Drawing structure.
2008 @param obj Current object to process.
2009 @param primary Flag: Primary object (1=object, 0=arrowhead).
2010 @param ec Pointe to error code variable, may be NULL.
2011 */
2012 static
2013 void
f2lud_create_closed_spline_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)2014 f2lud_create_closed_spline_path(
2015 f2l_job_t *job,
2016 dk3_fig_drawing_t *drw,
2017 dk3_fig_obj_t *obj,
2018 int primary,
2019 int *ec
2020 )
2021 {
2022 dk3_fig_spline_point_t *sp; /* Spline points. */
2023 size_t np; /* Number of points. */
2024 size_t i; /* Current segment index. */
2025
2026 sp = (obj->dt).spl.po;
2027 np = (obj->dt).spl.np;
2028 for(i = 0; i < np; i++) {
2029 f2lud_full_spline_segment(
2030 job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
2031 );
2032 }
2033
2034 }
2035
2036 /** Create path for closed spline object.
2037 @param job Job structure.
2038 @param drw Drawing structure.
2039 @param obj Current object to process.
2040 @param primary Flag: Primary object (1=object, 0=arrowhead).
2041 @param ec Pointe to error code variable, may be NULL.
2042 */
2043 static
2044 void
f2lud_create_closed_fast_spline_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int DK3_SILENCE_ARG_UNUSED (primary),int * ec)2045 f2lud_create_closed_fast_spline_path(
2046 f2l_job_t *job,
2047 dk3_fig_drawing_t *drw,
2048 dk3_fig_obj_t *obj,
2049 int DK3_SILENCE_ARG_UNUSED(primary),
2050 int *ec
2051 )
2052 {
2053 dk3_fig_spline_point_t *po;
2054 size_t np;
2055 size_t ib;
2056 size_t ic;
2057 size_t ia;
2058 size_t id;
2059 double dxdtb;
2060 double dydtb;
2061 double dxdtc;
2062 double dydtc;
2063
2064 DK3_UNUSED_ARG(primary)
2065 po = (obj->dt).spl.po;
2066 np = (obj->dt).spl.np;
2067 if (2 < np) {
2068 for (ib = 0; ib < np; ib++) {
2069 ic = ib + 1;
2070 id = ib + 2;
2071 if (ic >= np) { ic = ic - np; }
2072 if (id >= np) { id = id - np; }
2073 if (0 < ib) {
2074 ia = ib - 1;
2075 } else {
2076 ia = np - 1;
2077 }
2078 if (0 == ib) {
2079 /* MOVETO */
2080 f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
2081 }
2082 if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
2083 /* LINETO */
2084 f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
2085 } else {
2086 dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
2087 dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
2088 if (fabs(1.0 + po[ib].s) < 1.0e-6) {
2089 dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
2090 dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
2091 } else {
2092 if (fabs(1.0 + po[ic].s) < 1.0e-6) {
2093 dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
2094 dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
2095 }
2096 }
2097 if (fabs(1.0 + po[ic].s) < 1.0e-6) {
2098 dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
2099 dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
2100 } else {
2101 if (fabs(1.0 + po[ib].s) < 1.0e-6) {
2102 dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
2103 dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
2104 }
2105 }
2106 /* CURVETO */
2107 f2lud_fig_curveto(
2108 job, drw, obj,
2109 dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
2110 dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
2111 dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
2112 dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
2113 po[ic].x,
2114 po[ic].y,
2115 ec
2116 );
2117 }
2118 }
2119 }
2120
2121 }
2122
2123
2124
2125 /** Create path for open arc object.
2126 @param job Job structure.
2127 @param drw Drawing structure.
2128 @param obj Current object to process.
2129 @param iscl Flag: Closed arc.
2130 @param ec Pointe to error code variable, may be NULL.
2131 */
2132 static
2133 void
f2lud_create_arc_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int iscl,int * ec)2134 f2lud_create_arc_path(
2135 f2l_job_t *job,
2136 dk3_fig_drawing_t *drw,
2137 dk3_fig_obj_t *obj,
2138 int iscl,
2139 int *ec
2140 )
2141 {
2142 double sx; /* Start x. */
2143 double sy; /* Start y. */
2144 double cx; /* Center x. */
2145 double cy; /* Center y. */
2146 double r; /* Radius. */
2147 double as; /* Arc start angle in radians. */
2148 double ae; /* Arc end angle in radians. */
2149 double lastx; /* Segment start x. */
2150 double lasty; /* Segment start y. */
2151 double lastkdxdt; /* X difference to first control. */
2152 double lastkdydt; /* Y difference to first control. */
2153 double x; /* Segment end x. */
2154 double y; /* Segment end y. */
2155 double kdxdt; /* X difference to last control. */
2156 double kdydt; /* Y difference to last control. */
2157 double dnumsegs; /* Number of segments. */
2158 double alpha; /* Arc angle in radians. */
2159 double alphaseg; /* Segment angle in radians. */
2160 double kappa; /* Factor for derivative. */
2161 double alphaend; /* Segment end angle in radians. */
2162 size_t nsegs; /* Number of segments. */
2163 size_t i; /* Index of current segment. */
2164
2165 cx = (obj->dt).arc.xc;
2166 cy = (obj->dt).arc.yc;
2167 r = (obj->dt).arc.ra;
2168 if((obj->dt).arc.as < (obj->dt).arc.ae) {
2169 as = (obj->dt).arc.as;
2170 ae = (obj->dt).arc.ae;
2171 } else {
2172 as = (obj->dt).arc.ae;
2173 ae = (obj->dt).arc.as;
2174 }
2175 alpha = dk3ma_d_sub_ok(ae, as, ec);
2176 dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
2177
2178 nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
2179 alphaseg = alpha / ((double)nsegs);
2180 kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
2181 sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
2182 sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
2183 f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
2184 lastkdxdt = dk3ma_d_mul_ok(
2185 kappa,
2186 (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
2187 ec
2188 );
2189 lastkdydt = dk3ma_d_mul_ok(
2190 kappa,
2191 (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
2192 ec
2193 );
2194 for(i = 0; i < nsegs; i++) {
2195 if(i < (nsegs - 1)) {
2196 alphaend = dk3ma_d_add_ok(
2197 as,
2198 dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
2199 ec
2200 );
2201 } else {
2202 alphaend = ae;
2203 }
2204 x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
2205 y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
2206 kdxdt = dk3ma_d_mul_ok(
2207 kappa,
2208 (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
2209 ec
2210 );
2211 kdydt = dk3ma_d_mul_ok(
2212 kappa,
2213 (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
2214 ec
2215 );
2216 f2lud_fig_curveto(
2217 job, drw, obj,
2218 dk3ma_d_add_ok(lastx, lastkdxdt, ec),
2219 dk3ma_d_add_ok(lasty, lastkdydt, ec),
2220 dk3ma_d_sub_ok(x, kdxdt, ec),
2221 dk3ma_d_sub_ok(y, kdydt, ec),
2222 x, y,
2223 ec
2224 );
2225 lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
2226 }
2227 /* For closed arc draw the lines.
2228 */
2229 if(iscl) {
2230 f2lud_fig_lineto(job, drw, obj, cx, cy, ec);
2231 f2lud_fig_lineto(job, drw, obj, sx, sy, ec);
2232 }
2233
2234 }
2235
2236
2237
2238 /** Create path for half circle object.
2239 @param job Job structure.
2240 @param drw Drawing structure.
2241 @param obj Current object to process.
2242 @param ec Pointe to error code variable, may be NULL.
2243 */
2244 static
2245 void
f2lud_create_half_circle_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int * ec)2246 f2lud_create_half_circle_path(
2247 f2l_job_t *job,
2248 dk3_fig_drawing_t *drw,
2249 dk3_fig_obj_t *obj,
2250 int *ec
2251 )
2252 {
2253 dk3_fig_poly_point_t po[7]; /* Points to construct path. */
2254 size_t i; /* Current point index */
2255
2256 po[0].x = 0.0;
2257 po[0].y = (obj->dt).hci.ra;
2258 po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
2259 po[1].y = (obj->dt).hci.ra;
2260 po[2].x = -1.0 * (obj->dt).hci.ra;
2261 po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
2262 po[3].x = -1.0 * (obj->dt).hci.ra;
2263 po[3].y = 0.0;
2264 po[4].x = -1.0 * (obj->dt).hci.ra;
2265 po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
2266 po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
2267 po[5].y = -1.0 * (obj->dt).hci.ra;
2268 po[6].x = 0.0;
2269 po[6].y = -1.0 * (obj->dt).hci.ra;
2270 if(1.0e-6 < fabs((obj->dt).hci.an)) {
2271 for(i = 0; i < 7; i++) {
2272 dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, ec);
2273 }
2274 }
2275 for(i = 0; i < 7; i++) {
2276 dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, ec);
2277 }
2278 f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
2279 f2lud_fig_curveto(
2280 job, drw, obj, po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y, ec
2281 );
2282 f2lud_fig_curveto(
2283 job, drw, obj, po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y, ec
2284 );
2285 if(obj->st) {
2286 f2lud_fig_lineto(job, drw, obj, po[0].x, po[0].y, ec);
2287 }
2288
2289 }
2290
2291
2292
2293 /** Create path for object.
2294 @param job Job structure.
2295 @param drw Drawing structure.
2296 @param obj Current object to process.
2297 @param ec Pointe to error code variable, may be NULL.
2298 @param primary Flag: Primary object (1=object, 0=arrowhead).
2299 */
2300 static
2301 void
f2lud_create_path(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)2302 f2lud_create_path(
2303 f2l_job_t *job,
2304 dk3_fig_drawing_t *drw,
2305 dk3_fig_obj_t *obj,
2306 int primary,
2307 int *ec
2308 )
2309 {
2310
2311 switch(obj->ot) {
2312 case DK3_FIG_OBJ_ELLIPSE: {
2313 f2lud_create_ellipse_path(job, drw, obj, ec);
2314 } break;
2315 case DK3_FIG_OBJ_POLYLINE: {
2316 switch(obj->st) {
2317 case 1: { /* Polyline */
2318 f2lud_create_polygon_path(job, drw, obj, ec);
2319 } break;
2320 case 2: { /* Box */
2321 f2lud_create_box_path(job, drw, obj, ec);
2322 } break;
2323 case 3: { /* Polygon */
2324 f2lud_create_polygon_path(job, drw, obj, ec);
2325 } break;
2326 case 4: { /* Arc-box */
2327 f2lud_create_arc_box_path(job, drw, obj, ec);
2328 } break;
2329 }
2330 } break;
2331 case DK3_FIG_OBJ_SPLINE: {
2332 switch(obj->st) {
2333 case 0: case 2: case 4: { /* open spline */
2334 f2lud_create_open_spline_path(job, drw, obj, primary, ec);
2335 } break;
2336 case 1: case 3: case 5: { /* closed spline */
2337 f2lud_create_closed_spline_path(job, drw, obj, primary, ec);
2338 } break;
2339 }
2340 } break;
2341 case DK3_FIG_OBJ_ARC: {
2342 switch(obj->st) {
2343 case 1: { /* open arc */
2344 f2lud_create_arc_path(job, drw, obj, 0, ec);
2345 } break;
2346 default: { /* closed arc */
2347 f2lud_create_arc_path(job, drw, obj, 1, ec);
2348 } break;
2349 }
2350 } break;
2351 case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
2352 f2lud_create_half_circle_path(job, drw, obj, ec);
2353 } break;
2354 case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
2355 switch(obj->st) {
2356 case 0: case 2: case 4: { /* open spline */
2357 f2lud_create_open_fast_spline_path(job, drw, obj, primary, ec);
2358 } break;
2359 case 1: case 3: case 5: { /* closed spline */
2360 f2lud_create_closed_fast_spline_path(job, drw, obj, primary, ec);
2361 } break;
2362 }
2363 } break;
2364 }
2365 }
2366
2367
2368
2369 /** Set color (stroke color for pdf/pgf).
2370 If we already have a color 1 equal to the new color
2371 the operation is skipped.
2372 @param job Conversion job structure.
2373 @param drw Drawing structure.
2374 @param colno Color number.
2375 @param fillstyle Fill style used in the object.
2376 Depending on the fillstyle it might be necessary
2377 to create a shade of the color.
2378 */
2379 static
2380 void
f2lud_set_color_1(f2l_job_t * job,dk3_fig_drawing_t * drw,int colno,int fillstyle)2381 f2lud_set_color_1(
2382 f2l_job_t *job,
2383 dk3_fig_drawing_t *drw,
2384 int colno,
2385 int fillstyle
2386 )
2387 {
2388 dk3_rgb_color_t rgb; /* Color structure to fill. */
2389 int muc = 1; /* Flag: Must configure. */
2390 #if 0
2391 int ec = 0; /* Error code variable. */
2392 #endif
2393
2394 dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
2395 #if 0
2396 if((job->gs).hc1) {
2397 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c1.r, &ec))) {
2398 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c1.g, &ec))) {
2399 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c1.b, &ec))) {
2400 if(0 == ec) {
2401 muc = 0;
2402 }
2403 }
2404 }
2405 }
2406 }
2407 #else
2408 muc = dk3fig_tool_must_set_color(
2409 (job->gs).hc1, (job->gs).c1.r, (job->gs).c1.g, (job->gs).c1.b,
2410 rgb.r, rgb.g, rgb.b
2411 );
2412 #endif
2413 if(muc) {
2414 switch(job->dr) {
2415 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2416 f2lpgf_tex_set_color_1(job, drw, &rgb);
2417 } break;
2418 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2419 f2lpdf_tex_with_pdf_set_color_1(job, drw, &rgb);
2420 } break;
2421 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2422 f2leps_eps_with_tex_set_color_1(job, drw, &rgb);
2423 } break;
2424 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2425 f2lpdf_pdf_with_tex_set_color_1(job, drw, &rgb);
2426 } break;
2427 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2428 f2leps_eps_pure_set_color_1(job, drw, &rgb);
2429 } break;
2430 /* @DRIVER@ universal */
2431 default: {
2432 f2lpgf_pgf_set_color_1(job, drw, &rgb);
2433 } break;
2434 }
2435 (job->gs).c1.r = rgb.r;
2436 (job->gs).c1.g = rgb.g;
2437 (job->gs).c1.b = rgb.b;
2438 (job->gs).hc1 = 1;
2439 }
2440
2441 }
2442
2443
2444
2445 /** Set non-stroking color for pdf/pgf.
2446 If we already have a color 2 equal to the new color
2447 the operation is skipped.
2448 @param job Job structure.
2449 @param drw Drawing structure.
2450 @param colno Color number.
2451 @param fillstyle Fill style used in the object.
2452 Depending on the fillstyle it might be necessary
2453 to create a shade of the color.
2454 */
2455 static
2456 void
f2lud_set_color_2(f2l_job_t * job,dk3_fig_drawing_t * drw,int colno,int fillstyle)2457 f2lud_set_color_2(
2458 f2l_job_t *job,
2459 dk3_fig_drawing_t *drw,
2460 int colno,
2461 int fillstyle
2462 )
2463 {
2464 dk3_rgb_color_t rgb; /* Color structure to fill. */
2465 #if 0
2466 int ec = 0; /* Error code variable. */
2467 #endif
2468 int muc = 1; /* Flag: Must configure. */
2469
2470
2471 dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
2472 #if 0
2473 if((job->gs).hc2) {
2474 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c2.r, &ec))) {
2475 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c2.g, &ec))) {
2476 if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c2.b, &ec))) {
2477 if(0 == ec) {
2478 muc = 0;
2479 }
2480 }
2481 }
2482 }
2483 }
2484 #else
2485 muc = dk3fig_tool_must_set_color(
2486 (job->gs).hc2, (job->gs).c2.r, (job->gs).c2.g, (job->gs).c2.b,
2487 rgb.r, rgb.g, rgb.b
2488 );
2489 #endif
2490 if(muc) {
2491 switch(job->dr) {
2492 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2493 f2lpgf_tex_set_color_2(job, drw, &rgb);
2494 } break;
2495 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2496 f2lpdf_tex_with_pdf_set_color_2(job, drw, &rgb);
2497 } break;
2498 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2499 f2leps_eps_with_tex_set_color_2(job, drw, &rgb);
2500 } break;
2501 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2502 f2lpdf_pdf_with_tex_set_color_2(job, drw, &rgb);
2503 } break;
2504 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2505 f2leps_eps_pure_set_color_2(job, drw, &rgb);
2506 } break;
2507 /* @DRIVER@ universal */
2508 default: {
2509 f2lpgf_pgf_set_color_2(job, drw, &rgb);
2510 } break;
2511 }
2512 (job->gs).c2.r = rgb.r;
2513 (job->gs).c2.g = rgb.g;
2514 (job->gs).c2.b = rgb.b;
2515 (job->gs).hc2 = 1;
2516 }
2517
2518 }
2519
2520
2521
2522 /** Internal function to set line width.
2523 The line width is not set again if we already
2524 have a current line width equal to the new line width.
2525 @param job Job structure.
2526 @param drw Drawing structure.
2527 @param obj Current object.
2528 @param lw New line width in output coordinates.
2529 */
2530 static
2531 void
f2lud_internal_set_line_width(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,double lw)2532 f2lud_internal_set_line_width(
2533 f2l_job_t *job,
2534 dk3_fig_drawing_t *drw,
2535 dk3_fig_obj_t *obj,
2536 double lw
2537 )
2538 {
2539 int mc = 1; /* Flag: Must configure. */
2540 int ec = 0; /* Error code variable. */
2541
2542 if((job->gs).hlw) {
2543 if(1.0e-6 > fabs(dk3ma_d_sub_ok(lw, (job->gs).lw, &ec))) {
2544 if(0 == ec) {
2545 mc = 0;
2546 }
2547 }
2548 }
2549 if(mc) {
2550 switch(job->dr) {
2551 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2552 f2lpgf_tex_set_line_width(job, drw, obj, lw);
2553 } break;
2554 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2555 f2lpdf_tex_with_pdf_set_line_width(job, drw, obj, lw);
2556 } break;
2557 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2558 f2leps_eps_with_tex_set_line_width(job, drw, obj, lw);
2559 } break;
2560 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2561 f2lpdf_pdf_with_tex_set_line_width(job, drw, obj, lw);
2562 } break;
2563 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2564 f2leps_eps_pure_set_line_width(job, drw, obj, lw);
2565 } break;
2566 /* @DRIVER@ universal */
2567 default: {
2568 f2lpgf_pgf_set_line_width(job, drw, obj, lw);
2569 } break;
2570 }
2571 (job->gs).lw = lw;
2572 (job->gs).hlw = 1;
2573 }
2574
2575 }
2576
2577
2578
2579 /** Set line dash (line style and dash/gap length).
2580 The operation is skipped if the current line style and style
2581 value is equal to the new one.
2582 @param job Job structure.
2583 @param drw Drawing structure.
2584 @param obj Fig object.
2585 @param ls Line style.
2586 @param sv Style value (dash/gap) length in output units.
2587 */
2588 static
2589 void
f2lud_internal_set_line_dash(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int ls,double sv)2590 f2lud_internal_set_line_dash(
2591 f2l_job_t *job,
2592 dk3_fig_drawing_t *drw,
2593 dk3_fig_obj_t *obj,
2594 int ls,
2595 double sv
2596 )
2597 {
2598 double mysv; /* Style value converted to output space. */
2599 double mylw; /* Line width in Fig and output space. */
2600 int mc = 1; /* Flag: Must configure. */
2601 int ec = 0; /* Error code variable. */
2602
2603 mysv = 0.9 * sv;
2604 mylw = dk3fig_tool_get_lw(drw, obj, &ec);
2605 /* Convert line width to output space.
2606 */
2607 mylw = dk3ct_2d_r(&(job->ct2d), mylw, &ec);
2608 if((job->gs).hls) {
2609 if((job->gs).ls == ls) {
2610 if(DK3_FIG_LS_SOLID == ls) {
2611 mc = 0;
2612 } else {
2613 if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).sv, mysv, &ec))) {
2614 if(0 == ec) {
2615 if(DK3_FIG_LS_DASHED == ls) {
2616 mc = 0;
2617 } else {
2618 if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).slw, mylw, &ec))) {
2619 if(0 == ec) {
2620 mc = 0;
2621 }
2622 }
2623 }
2624 }
2625 }
2626 }
2627 }
2628 }
2629 if(mc) {
2630 switch(job->dr) {
2631 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2632 f2lpgf_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
2633 } break;
2634 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2635 f2lpdf_tex_with_pdf_set_line_style(job, drw, obj, ls, mysv, mylw);
2636 } break;
2637 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2638 f2leps_eps_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
2639 } break;
2640 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2641 f2lpdf_pdf_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
2642 } break;
2643 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2644 f2leps_eps_pure_set_line_style(job, drw, obj, ls, mysv, mylw);
2645 } break;
2646 /* @DRIVER@ universal */
2647 default: {
2648 f2lpgf_pgf_set_line_style(job, drw, obj, ls, mysv, mylw);
2649 } break;
2650 }
2651 (job->gs).ls = ls; (job->gs).sv = mysv; (job->gs).slw = mylw;
2652 (job->gs).hls = 1;
2653 }
2654
2655 }
2656
2657
2658
2659 /** Set line ends.
2660 The operation is skipped if the current line end is equal
2661 to the new one.
2662 @param job Job structure.
2663 @param drw Drawing structure.
2664 @param obj Current object.
2665 @param le Line end style.
2666 */
2667 static
2668 void
f2lud_set_line_end(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int le)2669 f2lud_set_line_end(
2670 f2l_job_t *job,
2671 dk3_fig_drawing_t *drw,
2672 dk3_fig_obj_t *obj,
2673 int le
2674 )
2675 {
2676 int mc = 1; /* Flag: Must configure. */
2677
2678 if((job->gs).hlc) {
2679 if((job->gs).lc == le) {
2680 mc = 0;
2681 }
2682 }
2683 if(mc) {
2684 switch(job->dr) {
2685 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2686 f2lpgf_tex_set_line_end(job, drw, obj, le);
2687 } break;
2688 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2689 f2lpdf_tex_with_pdf_set_line_end(job, drw, obj, le);
2690 } break;
2691 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2692 f2leps_eps_with_tex_set_line_end(job, drw, obj, le);
2693 } break;
2694 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2695 f2lpdf_pdf_with_tex_set_line_end(job, drw, obj, le);
2696 } break;
2697 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2698 f2leps_eps_pure_set_line_end(job, drw, obj, le);
2699 } break;
2700 /* @DRIVER@ universal */
2701 default: {
2702 f2lpgf_pgf_set_line_end(job, drw, obj, le);
2703 } break;
2704 }
2705 (job->gs).lc = le; (job->gs).hlc = 1;
2706 }
2707
2708 }
2709
2710
2711
2712 /** Set line join.
2713 The operation is skipped if the current line join is equal
2714 to the new one.
2715 @param job Job structure.
2716 @param drw Drawing structure.
2717 @param obj Current object.
2718 @param lj Line end style.
2719 */
2720 static
2721 void
f2lud_set_line_join(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int lj)2722 f2lud_set_line_join(
2723 f2l_job_t *job,
2724 dk3_fig_drawing_t *drw,
2725 dk3_fig_obj_t *obj,
2726 int lj
2727 )
2728 {
2729 int mc = 1; /* Flag: Must configure. */
2730
2731 if((job->gs).hlj) {
2732 if((job->gs).lj == lj) {
2733 mc = 0;
2734 }
2735 }
2736 if(mc) {
2737 switch(job->dr) {
2738 case FIG2LAT_DRIVER_TEX_FULL_PGF: {
2739 f2lpgf_tex_set_line_join(job, drw, obj, lj);
2740 } break;
2741 case FIG2LAT_DRIVER_TEX_FULL_PDF: {
2742 f2lpdf_tex_with_pdf_set_line_join(job, drw, obj, lj);
2743 } break;
2744 case FIG2LAT_DRIVER_EPS_WITH_TEX: {
2745 f2leps_eps_with_tex_set_line_join(job, drw, obj, lj);
2746 } break;
2747 case FIG2LAT_DRIVER_PDF_WITH_TEX: {
2748 f2lpdf_pdf_with_tex_set_line_join(job, drw, obj, lj);
2749 } break;
2750 case FIG2LAT_DRIVER_EPS_STANDALONE: {
2751 f2leps_eps_pure_set_line_join(job, drw, obj, lj);
2752 } break;
2753 /* @DRIVER@ universal */
2754 default: {
2755 f2lpgf_pgf_set_line_join(job, drw, obj, lj);
2756 } break;
2757 }
2758 (job->gs).lj = lj; (job->gs).hlj = 1;
2759 }
2760
2761 }
2762
2763
2764
2765 /** Set up line style, line width, line ends and line join for pattern.
2766 @param job Job structure.
2767 @param drw Drawing structure.
2768 @param obj Current object to process.
2769 */
2770 static
2771 void
f2lud_set_pattern_line_style(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)2772 f2lud_set_pattern_line_style(
2773 f2l_job_t *job,
2774 dk3_fig_drawing_t *drw,
2775 dk3_fig_obj_t *obj
2776 )
2777 {
2778
2779 #if VERSION_BEFORE_20140330
2780 f2lud_internal_set_line_width(job, drw, obj, ((job->lighten) ? 0.45 : 0.9));
2781 #else
2782 f2lud_internal_set_line_width(job, drw, obj, job->lwbp);
2783 #endif
2784 f2lud_internal_set_line_dash(job, drw, obj, DK3_FIG_LS_SOLID, -1.0);
2785 f2lud_set_line_end(job, drw, obj, DK3_FIG_LC_BUTT);
2786 f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
2787 #if 0
2788 /* 2012/11/18
2789 In fishscale patterns we draw arc by arc, not a sequence
2790 of arcs. So we do not need to care about line join
2791 of arcs.
2792 */
2793 switch(obj->fi) {
2794 case 56: case 57: {
2795 f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_BEVEL);
2796 } break;
2797 default: {
2798 f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
2799 } break;
2800 }
2801 #endif
2802
2803 }
2804
2805
2806
2807 /** Set line width.
2808 @param job Job structure.
2809 @param drw Drawing structure.
2810 @param obj Current object to process.
2811 */
2812 static
2813 void
f2lud_set_line_width(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)2814 f2lud_set_line_width(
2815 f2l_job_t *job,
2816 dk3_fig_drawing_t *drw,
2817 dk3_fig_obj_t *obj
2818 )
2819 {
2820 double lw; /* Line width in Fig space. */
2821 int ec = 0; /* Error code variable. */
2822
2823 lw = dk3fig_tool_get_lw(drw, obj, &ec);
2824 lw = dk3ct_2d_r(&(job->ct2d), lw, &ec);
2825 if(0 == ec) {
2826 f2lud_internal_set_line_width(job, drw, obj, lw);
2827 }
2828 }
2829
2830
2831
2832 /** Set line dash (line style and dash/gap length).
2833 @param job Job structure.
2834 @param drw Drawing structure.
2835 @param obj Fig object.
2836 */
2837 static
2838 void
f2lud_set_line_dash(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)2839 f2lud_set_line_dash(
2840 f2l_job_t *job,
2841 dk3_fig_drawing_t *drw,
2842 dk3_fig_obj_t *obj
2843 )
2844 {
2845
2846 f2lud_internal_set_line_dash(job, drw, obj, obj->ls, (0.9 * obj->sv));
2847
2848 }
2849
2850
2851
2852 /** Draw operations for object: stroke.
2853 @param job Job structure.
2854 @param drw Drawing structure.
2855 @param obj Current object to process.
2856 @param ec Pointe to error code variable, may be NULL.
2857 @param primary Flag: primary (1=primary object, 0=arrowhead).
2858 */
2859 static
2860 void
f2lud_path_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)2861 f2lud_path_stroke(
2862 f2l_job_t *job,
2863 dk3_fig_drawing_t *drw,
2864 dk3_fig_obj_t *obj,
2865 int primary,
2866 int *ec
2867 )
2868 {
2869
2870 f2lud_set_color_1(job, drw, obj->pc, 20);
2871 f2lud_set_line_width(job, drw, obj);
2872 f2lud_set_line_dash(job, drw, obj);
2873 f2lud_set_line_end(job, drw, obj, obj->cs);
2874 f2lud_set_line_join(job, drw, obj, obj->js);
2875 f2lud_newpath(job, drw, obj);
2876 f2lud_create_path(job, drw, obj, primary, ec);
2877 if(obj->cl) {
2878 f2lud_closepath(job, drw, obj);
2879 }
2880 f2lud_stroke(job, drw, obj);
2881
2882 }
2883
2884
2885
2886 /** Draw operations for object: fill.
2887 @param job Job structure.
2888 @param drw Drawing structure.
2889 @param obj Current object to process.
2890 @param ec Pointe to error code variable, may be NULL.
2891 @param primary Flag: primary (1=primary object, 0=arrowhead).
2892 */
2893 static
2894 void
f2lud_path_fill(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)2895 f2lud_path_fill(
2896 f2l_job_t *job,
2897 dk3_fig_drawing_t *drw,
2898 dk3_fig_obj_t *obj,
2899 int primary,
2900 int *ec
2901 )
2902 {
2903
2904 switch(job->dr) {
2905 case FIG2LAT_DRIVER_PGF:
2906 case FIG2LAT_DRIVER_TEX_FULL_PGF:
2907 case FIG2LAT_DRIVER_TEX_FULL_PDF:
2908 case FIG2LAT_DRIVER_PDF_WITH_TEX:
2909 {
2910 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
2911 } break;
2912 default: {
2913 f2lud_set_color_1(job, drw, obj->fc, obj->fi);
2914 } break;
2915 }
2916 f2lud_newpath(job, drw, obj);
2917 f2lud_create_path(job, drw, obj, primary, ec);
2918 f2lud_closepath(job, drw, obj);
2919 f2lud_fill(job, drw, obj);
2920
2921 }
2922
2923
2924
2925 /** Draw operations for object: fill and stroke.
2926 @param job Job structure.
2927 @param drw Drawing structure.
2928 @param obj Current object to process.
2929 @param ec Pointe to error code variable, may be NULL.
2930 @param primary Flag: primary (1=primary object, 0=arrowhead).
2931 */
2932 static
2933 void
f2lud_path_fill_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)2934 f2lud_path_fill_stroke(
2935 f2l_job_t *job,
2936 dk3_fig_drawing_t *drw,
2937 dk3_fig_obj_t *obj,
2938 int primary,
2939 int *ec
2940 )
2941 {
2942
2943 switch(job->dr) {
2944 case FIG2LAT_DRIVER_PGF:
2945 case FIG2LAT_DRIVER_TEX_FULL_PGF:
2946 {
2947 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
2948 f2lud_set_color_1(job, drw, obj->pc, 20);
2949 f2lud_set_line_width(job, drw, obj);
2950 f2lud_set_line_dash(job, drw, obj);
2951 f2lud_set_line_end(job, drw, obj, obj->cs);
2952 f2lud_set_line_join(job, drw, obj, obj->js);
2953 f2lud_newpath(job, drw, obj);
2954 f2lud_create_path(job, drw, obj, primary, ec);
2955 f2lud_closepath(job, drw, obj);
2956 f2lud_fill_stroke(job, drw, obj);
2957 } break;
2958 case FIG2LAT_DRIVER_TEX_FULL_PDF:
2959 case FIG2LAT_DRIVER_PDF_WITH_TEX:
2960 {
2961 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
2962 f2lud_set_color_1(job, drw, obj->pc, 20);
2963 f2lud_set_line_width(job, drw, obj);
2964 f2lud_set_line_dash(job, drw, obj);
2965 f2lud_set_line_end(job, drw, obj, obj->cs);
2966 f2lud_set_line_join(job, drw, obj, obj->js);
2967 f2lud_newpath(job, drw, obj);
2968 f2lud_create_path(job, drw, obj, primary, ec);
2969 f2lud_closepath(job, drw, obj);
2970 f2lud_fill(job, drw, obj);
2971 f2lud_newpath(job, drw, obj);
2972 f2lud_create_path(job, drw, obj, primary, ec);
2973 f2lud_closepath(job, drw, obj);
2974 f2lud_stroke(job, drw, obj);
2975 } break;
2976 default: {
2977 f2lud_set_line_width(job, drw, obj);
2978 f2lud_set_line_dash(job, drw, obj);
2979 f2lud_set_line_end(job, drw, obj, obj->cs);
2980 f2lud_set_line_join(job, drw, obj, obj->js);
2981 f2lud_set_color_1(job, drw, obj->fc, obj->fi);
2982 f2lud_newpath(job, drw, obj);
2983 f2lud_create_path(job, drw, obj, primary, ec);
2984 f2lud_closepath(job, drw, obj);
2985 f2lud_fill(job, drw, obj);
2986 f2lud_set_color_1(job, drw, obj->pc, obj->fi);
2987 f2lud_newpath(job, drw, obj);
2988 f2lud_create_path(job, drw, obj, primary, ec);
2989 f2lud_closepath(job, drw, obj);
2990 f2lud_stroke(job, drw, obj);
2991 } break;
2992 }
2993 }
2994
2995
2996
2997 /** Draw operations for object: pattern.
2998 @param job Job structure.
2999 @param drw Drawing structure.
3000 @param obj Current object to process.
3001 @param ec Pointe to error code variable, may be NULL.
3002 @param primary Flag: primary (1=primary object, 0=arrowhead).
3003 */
3004 static
3005 void
f2lud_path_pattern(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)3006 f2lud_path_pattern(
3007 f2l_job_t *job,
3008 dk3_fig_drawing_t *drw,
3009 dk3_fig_obj_t *obj,
3010 int primary,
3011 int *ec
3012 )
3013 {
3014
3015 f2lud_set_pattern_line_style(job, drw, obj);
3016 f2lud_set_color_1(job, drw, obj->pc, 20);
3017 f2lud_gsave(job, drw, obj);
3018 f2lud_newpath(job, drw, obj);
3019 f2lud_create_path(job, drw, obj, primary, ec);
3020 f2lud_closepath(job, drw, obj);
3021 f2lud_clip(job, drw, obj);
3022 f2lud_pattern(job, drw, obj, ec);
3023 f2lud_grestore(job, drw, obj);
3024
3025 }
3026
3027
3028
3029 /** Draw operations for object: pattern and stroke.
3030 @param job Job structure.
3031 @param drw Drawing structure.
3032 @param obj Current object to process.
3033 @param ec Pointe to error code variable, may be NULL.
3034 @param primary Flag: primary (1=primary object, 0=arrowhead).
3035 */
3036 static
3037 void
f2lud_path_pattern_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)3038 f2lud_path_pattern_stroke(
3039 f2l_job_t *job,
3040 dk3_fig_drawing_t *drw,
3041 dk3_fig_obj_t *obj,
3042 int primary,
3043 int *ec
3044 )
3045 {
3046
3047 f2lud_set_color_1(job, drw, obj->pc, 20);
3048 f2lud_set_pattern_line_style(job, drw, obj);
3049 f2lud_gsave(job, drw, obj);
3050 f2lud_newpath(job, drw, obj);
3051 f2lud_create_path(job, drw, obj, primary, ec);
3052 f2lud_closepath(job, drw, obj);
3053 f2lud_clip(job, drw, obj);
3054 f2lud_pattern(job, drw, obj, ec);
3055 f2lud_grestore(job, drw, obj);
3056 f2lud_set_line_width(job, drw, obj);
3057 f2lud_set_line_dash(job, drw, obj);
3058 f2lud_set_line_end(job, drw, obj, obj->cs);
3059 f2lud_set_line_join(job, drw, obj, obj->js);
3060 f2lud_newpath(job, drw, obj);
3061 f2lud_create_path(job, drw, obj, primary, ec);
3062 f2lud_closepath(job, drw, obj);
3063 f2lud_stroke(job, drw, obj);
3064
3065 }
3066
3067
3068
3069 /** Draw operations for object: fill and pattern.
3070 @param job Job structure.
3071 @param drw Drawing structure.
3072 @param obj Current object to process.
3073 @param ec Pointe to error code variable, may be NULL.
3074 @param primary Flag: primary (1=primary object, 0=arrowhead).
3075 */
3076 static
3077 void
f2lud_path_fill_pattern(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)3078 f2lud_path_fill_pattern(
3079 f2l_job_t *job,
3080 dk3_fig_drawing_t *drw,
3081 dk3_fig_obj_t *obj,
3082 int primary,
3083 int *ec
3084 )
3085 {
3086
3087 switch(job->dr) {
3088 case FIG2LAT_DRIVER_PGF:
3089 case FIG2LAT_DRIVER_TEX_FULL_PGF:
3090 {
3091 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
3092 f2lud_set_color_1(job, drw, obj->pc, 20);
3093 f2lud_set_pattern_line_style(job, drw, obj);
3094 f2lud_gsave(job, drw, obj);
3095 f2lud_newpath(job, drw, obj);
3096 f2lud_create_path(job, drw, obj, primary, ec);
3097 f2lud_closepath(job, drw, obj);
3098 f2lud_fill_clip(job, drw, obj);
3099 f2lud_pattern(job, drw, obj, ec);
3100 f2lud_grestore(job, drw, obj);
3101 } break;
3102 default: {
3103 switch(job->dr) {
3104 case FIG2LAT_DRIVER_TEX_FULL_PDF:
3105 case FIG2LAT_DRIVER_PDF_WITH_TEX:
3106 {
3107 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
3108 f2lud_set_color_1(job, drw, obj->pc, 20);
3109 f2lud_set_pattern_line_style(job, drw, obj);
3110 f2lud_newpath(job, drw, obj);
3111 f2lud_create_path(job, drw, obj, primary, ec);
3112 f2lud_closepath(job, drw, obj);
3113 f2lud_fill(job, drw, obj);
3114 f2lud_gsave(job, drw, obj);
3115 f2lud_newpath(job, drw, obj);
3116 f2lud_create_path(job, drw, obj, primary, ec);
3117 f2lud_closepath(job, drw, obj);
3118 f2lud_clip(job, drw, obj);
3119 f2lud_pattern(job, drw, obj, ec);
3120 f2lud_grestore(job, drw, obj);
3121 } break;
3122 default: {
3123 f2lud_set_color_1(job, drw, obj->fc, obj->fi);
3124 f2lud_set_pattern_line_style(job, drw, obj);
3125 f2lud_newpath(job, drw, obj);
3126 f2lud_create_path(job, drw, obj, primary, ec);
3127 f2lud_closepath(job, drw, obj);
3128 f2lud_fill(job, drw, obj);
3129 f2lud_set_color_1(job, drw, obj->pc, 20);
3130 f2lud_gsave(job, drw, obj);
3131 f2lud_newpath(job, drw, obj);
3132 f2lud_create_path(job, drw, obj, primary, ec);
3133 f2lud_closepath(job, drw, obj);
3134 f2lud_clip(job, drw, obj);
3135 f2lud_pattern(job, drw, obj, ec);
3136 f2lud_grestore(job, drw, obj);
3137 } break;
3138 }
3139 } break;
3140 }
3141 }
3142
3143
3144
3145 /** Check whether on object line style and line width
3146 matches style and width configured in a dk3_graphics_state_t.
3147 @param gs dk3_graphics_state_t to test.
3148 @param ct2d Coordinates transformation data.
3149 @param drw Drawing containing the Fig object.
3150 @param obj Fig object.
3151 @return 1 for equal line width and style, 0 otherwise.
3152 */
3153 static
3154 int
f2lud_style_equal(dk3_graphics_state_t * gs,dk3_ct_2d_t * ct2d,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)3155 f2lud_style_equal(
3156 dk3_graphics_state_t *gs,
3157 dk3_ct_2d_t *ct2d,
3158 dk3_fig_drawing_t *drw,
3159 dk3_fig_obj_t *obj
3160 )
3161 {
3162 double lw; /* Line width in Fig space. */
3163 int back = 0;
3164 int ec = 0; /* Error code variable. */
3165 #if 0
3166 if((gs->hlw) && (gs->hls) && (gs->hlc) && (gs->hlj)) {
3167 if((gs->ls = obj->ls) && (gs->lc == obj->cs) && (gs->lj == obj->js)) {
3168 lw = dk3fig_tool_get_lw(drw, obj, &ec);
3169 if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
3170 if(0 == ec) {
3171 if(DK3_FIG_LS_SOLID == obj->ls) {
3172 back = 1;
3173 } else {
3174 sv = 0.9 * obj->sv;
3175 if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->sv, sv, &ec))) {
3176 if(0 == ec) {
3177 back = 1;
3178 }
3179 }
3180 }
3181 }
3182 }
3183 }
3184 }
3185 #else
3186 /* 2012/11/15 As this operation is applied to closed path objects
3187 only, there is no need to check line ends.
3188 As fill patterns are drawn as solid lines, we only have
3189 to check the object line style, whether it is solid.
3190 For solid lines the style value is ignored.
3191 */
3192 if((gs->hlw) && (gs->hls) && (gs->hlj)) {
3193 if(DK3_FIG_LS_SOLID == obj->ls) {
3194 if(gs->lj == obj->js) {
3195 lw = dk3fig_tool_get_lw(drw, obj, &ec);
3196 lw = dk3ct_2d_r(ct2d, lw, &ec);
3197 if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
3198 if(0 == ec) {
3199 back = 1;
3200 }
3201 }
3202 }
3203 }
3204 }
3205 #endif
3206 return back;
3207 }
3208
3209
3210
3211 /** Draw operations for object: fill, pattern and stroke.
3212 @param job Job structure.
3213 @param drw Drawing structure.
3214 @param obj Current object to process.
3215 @param ec Pointe to error code variable, may be NULL.
3216 @param primary Flag: primary (1=primary object, 0=arrowhead).
3217 */
3218 static
3219 void
f2lud_path_fill_pattern_stroke(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary,int * ec)3220 f2lud_path_fill_pattern_stroke(
3221 f2l_job_t *job,
3222 dk3_fig_drawing_t *drw,
3223 dk3_fig_obj_t *obj,
3224 int primary,
3225 int *ec
3226 )
3227 {
3228
3229 switch(job->dr) {
3230 case FIG2LAT_DRIVER_PGF:
3231 case FIG2LAT_DRIVER_TEX_FULL_PGF:
3232 {
3233 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
3234 f2lud_set_color_1(job, drw, obj->pc, 20);
3235 f2lud_set_pattern_line_style(job, drw, obj);
3236 if(f2lud_style_equal(&(job->gs), &(job->ct2d), drw, obj)) {
3237 f2lud_gsave(job, drw, obj);
3238 f2lud_newpath(job, drw, obj);
3239 f2lud_create_path(job, drw, obj, primary, ec);
3240 f2lud_closepath(job, drw, obj);
3241 f2lud_fill_stroke_clip(job, drw, obj);
3242 f2lud_pattern(job, drw, obj, ec);
3243 f2lud_grestore(job, drw, obj);
3244 } else {
3245 f2lud_gsave(job, drw, obj);
3246 f2lud_newpath(job, drw, obj);
3247 f2lud_create_path(job, drw, obj, primary, ec);
3248 f2lud_closepath(job, drw, obj);
3249 f2lud_fill_clip(job, drw, obj);
3250 f2lud_pattern(job, drw, obj, ec);
3251 f2lud_grestore(job, drw, obj);
3252 f2lud_set_line_width(job, drw, obj);
3253 f2lud_set_line_dash(job, drw, obj);
3254 f2lud_set_line_end(job, drw, obj, obj->cs);
3255 f2lud_set_line_join(job, drw, obj, obj->js);
3256 f2lud_newpath(job, drw, obj);
3257 f2lud_create_path(job, drw, obj, primary, ec);
3258 f2lud_closepath(job, drw, obj);
3259 f2lud_stroke(job, drw, obj);
3260 }
3261 } break;
3262 case FIG2LAT_DRIVER_TEX_FULL_PDF:
3263 case FIG2LAT_DRIVER_PDF_WITH_TEX:
3264 {
3265 f2lud_set_color_2(job, drw, obj->fc, obj->fi);
3266 f2lud_set_color_1(job, drw, obj->pc, 20);
3267 f2lud_set_pattern_line_style(job, drw, obj);
3268 f2lud_newpath(job, drw, obj);
3269 f2lud_create_path(job, drw, obj, primary, ec);
3270 f2lud_closepath(job, drw, obj);
3271 f2lud_fill(job, drw, obj);
3272 f2lud_gsave(job, drw, obj);
3273 f2lud_newpath(job, drw, obj);
3274 f2lud_create_path(job, drw, obj, primary, ec);
3275 f2lud_closepath(job, drw, obj);
3276 f2lud_clip(job, drw, obj);
3277 f2lud_pattern(job, drw, obj, ec);
3278 f2lud_grestore(job, drw, obj);
3279 f2lud_set_line_width(job, drw, obj);
3280 f2lud_set_line_dash(job, drw, obj);
3281 f2lud_set_line_end(job, drw, obj, obj->cs);
3282 f2lud_set_line_join(job, drw, obj, obj->js);
3283 f2lud_newpath(job, drw, obj);
3284 f2lud_create_path(job, drw, obj, primary, ec);
3285 f2lud_closepath(job, drw, obj);
3286 f2lud_stroke(job, drw, obj);
3287 } break;
3288 default: {
3289 f2lud_set_color_1(job, drw, obj->fc, obj->fi);
3290 f2lud_set_pattern_line_style(job, drw, obj);
3291 f2lud_newpath(job, drw, obj);
3292 f2lud_create_path(job, drw, obj, primary, ec);
3293 f2lud_closepath(job, drw, obj);
3294 f2lud_fill(job, drw, obj);
3295 f2lud_set_color_1(job, drw, obj->pc, 20);
3296 f2lud_gsave(job, drw, obj);
3297 f2lud_newpath(job, drw, obj);
3298 f2lud_create_path(job, drw, obj, primary, ec);
3299 f2lud_closepath(job, drw, obj);
3300 f2lud_clip(job, drw, obj);
3301 f2lud_pattern(job, drw, obj, ec);
3302 f2lud_grestore(job, drw, obj);
3303 f2lud_set_line_width(job, drw, obj);
3304 f2lud_set_line_dash(job, drw, obj);
3305 f2lud_set_line_end(job, drw, obj, obj->cs);
3306 f2lud_set_line_join(job, drw, obj, obj->js);
3307 f2lud_newpath(job, drw, obj);
3308 f2lud_create_path(job, drw, obj, primary, ec);
3309 f2lud_closepath(job, drw, obj);
3310 f2lud_stroke(job, drw, obj);
3311 } break;
3312 }
3313 }
3314
3315
3316
3317 /** Process path object.
3318 @param job Job structure.
3319 @param drw Drawing structure.
3320 @param obj Current object to process.
3321 @param primary Flag: primary (1=primary object, 0=arrowhead).
3322 */
3323 static
3324 void
f2lud_path_object(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary)3325 f2lud_path_object(
3326 f2l_job_t *job,
3327 dk3_fig_drawing_t *drw,
3328 dk3_fig_obj_t *obj,
3329 int primary
3330 )
3331 {
3332 int drawop; /* Operations to perform. */
3333 int ec = 0; /* Error code variable. */
3334
3335 drawop = dk3fig_tool_get_operation(drw, obj);
3336 if(obj->cl) {
3337 switch(drawop) {
3338 case DK3_FIG_OP_STROKE: {
3339 f2lud_path_stroke(job, drw, obj, primary, &ec);
3340 } break;
3341 case DK3_FIG_OP_FILL: {
3342 f2lud_path_fill(job, drw, obj, primary, &ec);
3343 } break;
3344 case (DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
3345 f2lud_path_fill_stroke(job, drw, obj, primary, &ec);
3346 } break;
3347 case DK3_FIG_OP_PATTERN: {
3348 f2lud_path_pattern(job, drw, obj, primary, &ec);
3349 } break;
3350 case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_STROKE): {
3351 f2lud_path_pattern_stroke(job, drw, obj, primary, &ec);
3352 } break;
3353 case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL): {
3354 f2lud_path_fill_pattern(job, drw, obj, primary, &ec);
3355 } break;
3356 case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
3357 f2lud_path_fill_pattern_stroke(job, drw, obj, primary, &ec);
3358 } break;
3359 }
3360 } else {
3361 if(DK3_FIG_OP_STROKE & drawop) {
3362 f2lud_path_stroke(job, drw, obj, primary, &ec);
3363 }
3364 }
3365 if(ec) {
3366 /* ERROR: Math error in object! */
3367 dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
3368 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
3369 }
3370 }
3371
3372
3373
3374 /** Process one object.
3375 @param job Job structure.
3376 @param drw Drawing structure.
3377 @param obj Current object to process.
3378 @param primary Flag: primary (1=primary object, 0=arrowhead).
3379 */
3380 static
3381 void
f2lud_process_one(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,int primary)3382 f2lud_process_one(
3383 f2l_job_t *job,
3384 dk3_fig_drawing_t *drw,
3385 dk3_fig_obj_t *obj,
3386 int primary
3387 )
3388 {
3389 char debbuf[256]; /* Buffer for debug messages. */
3390
3391 if(job->debug) {
3392 sprintf(debbuf, f2lud_c8_kw[6], obj->ot, obj->st);
3393 f2lud_debug(job, debbuf);
3394 }
3395 switch(obj->ot) {
3396 case DK3_FIG_OBJ_TEXT: {
3397 f2lud_text_object(job, drw, obj);
3398 } break;
3399 case DK3_FIG_OBJ_ELLIPSE:
3400 case DK3_FIG_OBJ_SPLINE:
3401 case DK3_FIG_OBJ_ARC:
3402 case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE:
3403 case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE:
3404 {
3405 f2lud_path_object(job, drw, obj, primary);
3406 } break;
3407 case DK3_FIG_OBJ_POLYLINE: {
3408 switch(obj->st) {
3409 case 5: {
3410 f2lud_image_object(job, drw, obj);
3411 } break;
3412 default: {
3413 f2lud_path_object(job, drw, obj, primary);
3414 } break;
3415 }
3416 } break;
3417 }
3418 if(job->debug) {
3419 f2lud_debug(job, f2lud_c8_kw[7]);
3420 }
3421 }
3422
3423
3424
3425 int
f2lud_is_interpolated_spline(dk3_fig_obj_t * obj)3426 f2lud_is_interpolated_spline(dk3_fig_obj_t *obj)
3427 {
3428 dk3_fig_spline_point_t *po; /* Points to test */
3429 size_t np; /* Number of points */
3430 size_t i; /* Traverse all points */
3431 int back = 1;
3432
3433 po = (obj->dt).spl.po;
3434 np = (obj->dt).spl.np;
3435 for (i = 0; ((i < np) && (1 == back)); i++) {
3436
3437 if (fabs(po->s) > 1.0e-6) {
3438 if (fabs(1.0 + po->s) > 1.0e-6) {
3439 back = 0;
3440 }
3441 }
3442 po++;
3443 }
3444 return back;
3445 }
3446
3447
3448
3449 /** Process one arrowhead object.
3450 @param job Job structure.
3451 @param drw Drawing structure.
3452 @param obj Current object to process.
3453 */
3454 static
3455 void
f2lud_process_ah_one(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj)3456 f2lud_process_ah_one(
3457 f2l_job_t *job,
3458 dk3_fig_drawing_t *drw,
3459 dk3_fig_obj_t *obj
3460 )
3461 {
3462 switch (obj->ot) {
3463 case DK3_FIG_OBJ_SPLINE: {
3464 if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
3465 obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
3466 f2lud_process_one(job, drw, obj, 0);
3467 obj->ot = DK3_FIG_OBJ_SPLINE;
3468 } else {
3469 f2lud_process_one(job, drw, obj, 0);
3470 }
3471 } break;
3472 default: {
3473 f2lud_process_one(job, drw, obj, 0);
3474 } break;
3475 }
3476 }
3477
3478
3479
3480 /** Process object and arrowheads.
3481 @param job Job structure.
3482 @param drw Drawing structure.
3483 @param obj Current object to process.
3484 @param objno Number of current object.
3485 */
3486 static
3487 void
f2lud_process_object(f2l_job_t * job,dk3_fig_drawing_t * drw,dk3_fig_obj_t * obj,unsigned long objno)3488 f2lud_process_object(
3489 f2l_job_t *job,
3490 dk3_fig_drawing_t *drw,
3491 dk3_fig_obj_t *obj,
3492 unsigned long objno
3493 )
3494 {
3495 char debbuf[256]; /* Buffer for debug messages. */
3496
3497 /*
3498 Process object itself.
3499 */
3500
3501 if(job->debug) {
3502 sprintf(debbuf, f2lud_c8_kw[0], objno, obj->li, obj->ot, obj->st, obj->la);
3503 f2lud_debug(job, debbuf);
3504 }
3505 f2lud_process_one(job, drw, obj, 1);
3506
3507 /*
3508 For primary objects process the arrowheads.
3509 */
3510 if(obj->af) {
3511
3512 if(job->debug) {
3513 sprintf(
3514 debbuf, f2lud_c8_kw[2],
3515 (obj->af)->as,
3516 (obj->af)->af,
3517 (obj->af)->he,
3518 (obj->af)->wi
3519 );
3520 f2lud_debug(job, debbuf);
3521 }
3522 if((obj->af)->o1) {
3523 #if VERSION_BEFORE_20140329
3524 f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o1),0);
3525 #else
3526 f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o1));
3527 #endif
3528 }
3529 if((obj->af)->o2) {
3530 #if VERSION_BEFORE_20140329
3531 f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o2),0);
3532 #else
3533 f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o2));
3534 #endif
3535 }
3536 if(job->debug) {
3537 f2lud_debug(job, f2lud_c8_kw[3]);
3538 }
3539
3540 }
3541 if(obj->ab) {
3542
3543 if(job->debug) {
3544 sprintf(
3545 debbuf, f2lud_c8_kw[4],
3546 (obj->ab)->as,
3547 (obj->ab)->af,
3548 (obj->ab)->he,
3549 (obj->ab)->wi
3550 );
3551 f2lud_debug(job, debbuf);
3552 }
3553 if((obj->ab)->o1) {
3554 #if VERSION_BEFORE_20140329
3555 f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o1),0);
3556 #else
3557 f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o1));
3558 #endif
3559 }
3560 if((obj->ab)->o2) {
3561 #if VERSION_BEFORE_20140329
3562 f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o2),0);
3563 #else
3564 f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o2));
3565 #endif
3566 }
3567 if(job->debug) {
3568 f2lud_debug(job, f2lud_c8_kw[5]);
3569 }
3570
3571 }
3572 if(job->debug) {
3573 sprintf(debbuf, f2lud_c8_kw[1], objno);
3574 f2lud_debug(job, debbuf);
3575 }
3576
3577 }
3578
3579
3580
3581 void
f2lud_output(f2l_job_t * job)3582 f2lud_output(f2l_job_t *job)
3583 {
3584 dk3_fig_obj_t *obj; /* Current object to process. */
3585 dk3_fig_drawing_t *drw; /* Drawing to process. */
3586 unsigned long objno; /* Current object number. */
3587
3588 drw = job->drw;
3589 objno = 0UL;
3590 if(f2lud_driver_initialize(job, drw)) {
3591 if(f2lud_open_output_files(job)) {
3592 if(f2lud_start_processing(job, drw)) {
3593 dk3sto_it_reset(drw->iobj);
3594 while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
3595 if(!dk3fig_tool_is_bgrect(obj, objno)) {
3596 f2lud_process_object(job, drw, obj, objno);
3597 }
3598 objno++;
3599 }
3600 } else {
3601 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
3602 }
3603 f2lud_end_processing(job, drw);
3604 } else {
3605 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
3606 }
3607 f2lud_close_output_files(job);
3608 } else {
3609 f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
3610 }
3611 f2lud_driver_end(job, drw);
3612 }
3613
3614