summaryrefslogtreecommitdiff
path: root/support/dktools/f2lsvg.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/f2lsvg.c
Initial commit
Diffstat (limited to 'support/dktools/f2lsvg.c')
-rw-r--r--support/dktools/f2lsvg.c3590
1 files changed, 3590 insertions, 0 deletions
diff --git a/support/dktools/f2lsvg.c b/support/dktools/f2lsvg.c
new file mode 100644
index 0000000000..f8d8442269
--- /dev/null
+++ b/support/dktools/f2lsvg.c
@@ -0,0 +1,3590 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lsvg.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lsvg.c The f2lsvg module.
+*/
+
+
+#line 28 "f2lsvg.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "dk3font.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lsvgst.h"
+#include "f2lpara.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3xsp.h"
+#include "dk3font.h"
+#include "dk3bif.h"
+
+
+
+
+
+#line 49 "f2lsvg.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lsvg_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n",
+
+/* 3 */
+"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n",
+
+/* 4 */
+"\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"\n",
+
+/* 5 */
+">\n",
+
+/* 6 */
+"<",
+
+/* 7 */
+"svg:",
+
+/* 8 */
+"/",
+
+/* 9 */
+">",
+
+/* 10 */
+"svg",
+
+/* 11 */
+"width=\"%lgin\" height=\"%lgin\" viewBox=\"0 0 %ld %ld\"",
+
+/* 12 */
+"xmlns=\"http://www.w3.org/2000/svg\"\n",
+
+/* 13 */
+"xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n",
+
+/* 14 */
+"title",
+
+/* 15 */
+"desc",
+
+/* 16 */
+"Fig file converted by fig2lat",
+
+/* 17 */
+"http://dktools.sourceforge.net/fig2lat.html",
+
+/* 18 */
+"defs",
+
+/* 19 */
+"style",
+
+/* 20 */
+"type=\"text/css\"",
+
+/* 21 */
+"<![CDATA[",
+
+/* 22 */
+"]]>",
+
+/* 23 */
+"@font-face {\n",
+
+/* 24 */
+"}\n",
+
+/* 25 */
+"font-family: \"",
+
+/* 26 */
+"\";\n",
+
+/* 27 */
+"font-style: oblique;\n",
+
+/* 28 */
+"font-style: italic;\n",
+
+/* 29 */
+"font-style: normal;\n",
+
+/* 30 */
+"font-weight: %d;\n",
+
+/* 31 */
+"src: url(\"",
+
+/* 32 */
+".ttf",
+
+/* 33 */
+"\");\n",
+
+/* 34 */
+"file://",
+
+/* 35 */
+"g",
+
+/* 36 */
+"/>\n",
+
+/* 37 */
+"rect",
+
+/* 38 */
+"x=\"%lg\" y=\"%lg\" width=\"%lg\" height=\"%lg\"",
+
+/* 39 */
+" rx=\"%lg\" ry=\"%lg\"",
+
+/* 40 */
+"polygon",
+
+/* 41 */
+"points=\"",
+
+/* 42 */
+"\"\n",
+
+/* 43 */
+"%lg,%lg",
+
+/* 44 */
+"polyline",
+
+/* 45 */
+"circle",
+
+/* 46 */
+"ellipse",
+
+/* 47 */
+"\ncx=\"%lg\" cy=\"%lg\" r=\"%lg\"\n",
+
+/* 48 */
+"\ntransform=\"translate(%lg %lg) rotate(%lg)\" rx=\"%lg\" ry=\"%lg\"\n",
+
+/* 49 */
+"\ncx=\"%lg\" cy=\"%lg\" rx=\"%lg\" ry=\"%lg\"\n",
+
+/* 50 */
+"text",
+
+/* 51 */
+">",
+
+/* 52 */
+"\nx=\"%lg\" y=\"%lg\" ",
+
+/* 53 */
+"\ntransform=\"translate(%lg %lg) rotate(%lg)\" x=\"0\" y=\"0\"\n",
+
+/* 54 */
+"path",
+
+/* 55 */
+"\nd=\"",
+
+/* 56 */
+"M%lg,%lg\n",
+
+/* 57 */
+"C%lg,%lg %lg,%lg %lg,%lg",
+
+/* 58 */
+"L%lg,%lg\n",
+
+/* 59 */
+"Z",
+
+/* 60 */
+"\ntransform=\"translate(%lg %lg)",
+
+/* 61 */
+" rotate(%d)",
+
+/* 62 */
+" scale(",
+
+/* 63 */
+"1",
+
+/* 64 */
+"-1",
+
+/* 65 */
+")",
+
+/* 66 */
+"image",
+
+/* 67 */
+"\nx=\"0\" y=\"0\" width=\"%lg\" height=\"%lg\"\nxlink:href=\"",
+
+NULL
+
+
+#line 239 "f2lsvg.ctr"
+};
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const f2lsvg_html_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "\"",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Tool functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 508 "f2lsvg.ctr"
+
+
+
+/** Write one text line, use special HTML notation for characters
+ if necessary.
+ @param str String to write.
+ @param of Output file.
+*/
+static
+void
+f2lsvg_fputs_translate(char const *str, FILE *of)
+{
+ char const *ptr;
+ char const *opt;
+ char c;
+ unsigned char uc;
+ unsigned u;
+ ptr = str;
+ while(*ptr) {
+ c = *(ptr++);
+ uc = (unsigned char)c;
+ u = (unsigned)uc;
+ while(255 < u) {
+ u -= 256;
+ }
+ opt = f2lsvg_html_translation_table[u];
+ if(opt) {
+ fputs(opt, of);
+ } else {
+ fputc(c, of);
+ }
+ }
+}
+
+
+
+/** Write SVG tag name.
+ For full SVG write the tag name directly, when producing an SVG
+ fragment we prepend svg:.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_name(f2l_job_t *job, size_t ind)
+{
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+}
+
+
+
+/** Start opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open_start(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+}
+
+
+
+/** End a tag.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_tag_end(f2l_job_t *job)
+{
+ fputs(f2lsvg_c8_kw[9], job->of1);
+}
+
+
+
+/** Opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ f2lsvg_tag_end(job);
+}
+
+
+
+
+/** Write a closing tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_close(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[9], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+}
+
+
+
+/** Calculate factors for coordinates transformations.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ int back = 1;
+ int mec = 0;
+
+
+#line 647 "f2lsvg.ctr"
+ (job->ct2d).mx = (job->ct2d).my = dk3ma_d_div_ok(72.0, drw->res, &mec);
+ xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
+ xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
+ ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
+ ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
+ /* Align to 1/8 inch grid.
+ */
+ xmin = xmin / 9.0; xmin = floor(xmin);
+ xmin = dk3ma_d_mul_ok(9.0, xmin, &mec);
+ xmax = xmax / 9.0; xmax = ceil(xmax);
+ xmax = dk3ma_d_mul_ok(9.0, xmax, &mec);
+ ymin = ymin / 9.0; ymin = floor(ymin);
+ ymin = dk3ma_d_mul_ok(9.0, ymin, &mec);
+ ymax = ymax / 9.0; ymax = ceil(ymax);
+ ymax = dk3ma_d_mul_ok(9.0, ymax, &mec);
+ (job->ct2d).nx = -1.0 * xmin;
+ (job->ct2d).ny = -1.0 * ymin;
+ job->width = dk3ma_d_sub_ok(xmax, xmin, &mec);
+ job->height = dk3ma_d_sub_ok(ymax, ymin, &mec);
+ job->lwidth = dk3ma_d_to_l_ok(job->width, &mec);
+ job->lheight = dk3ma_d_to_l_ok(job->height, &mec);
+
+
+#line 669 "f2lsvg.ctr"
+
+
+#line 670 "f2lsvg.ctr"
+ if(mec) {
+ back = 0;
+ /* ERROR: Math problem */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 675 "f2lsvg.ctr"
+ }
+
+#line 676 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for a text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_text_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ dk3_fig_color_t fc; /* Fill color. */
+ int back = 1;
+
+
+#line 702 "f2lsvg.ctr"
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((pobj->dt).txt.ff))) {
+ f2lsvgst_style_initialize(&sty);
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ /* Text font.
+ */
+ f2lsvgst_style_set_text(
+ psvg, &sty,
+ ((((pobj->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) ? 1 : 0),
+ (pobj->dt).txt.fo,
+ (pobj->dt).txt.fs
+ );
+ /* Text alignment.
+ */
+ f2lsvgst_style_set_text_align(&sty, pobj->st);
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 723 "f2lsvg.ctr"
+ }
+ }
+
+
+#line 726 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for a non-text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_path_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ f2l_svg_fill_pattern_t pat; /* Pattern. */
+ dk3_fig_color_t fc; /* Fill color. */
+ dk3_fig_color_t sc; /* Stroke color. */
+ double lw; /* Line width in SVG units. */
+ double lsv; /* Line style value in SVG units. */
+ int res; /* Operation result. */
+ int mec = 0; /* Mathematical error code. */
+ int any = 0; /* Flag: Any settings applied to style. */
+ int op = 0; /* Draw operation. */
+ int back = 1 ;
+
+
+#line 760 "f2lsvg.ctr"
+ op = dk3fig_tool_get_operation(drw, pobj);
+ f2lsvgst_style_initialize(&sty);
+ if(op & DK3_FIG_OP_PATTERN) {
+ /* Fill pattern.
+ */
+ any = 1;
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, 20);
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ pat.pn = 0UL;
+ pat.fn = pobj->fi;
+ pat.sr = sc.r; pat.sg = sc.g; pat.sb = sc.b;
+ pat.fr = fc.r; pat.fg = fc.g; pat.fb = fc.b;
+ res = f2lsvgst_style_set_pattern(psvg, &sty, &pat);
+ if(!(res)) {
+ back = 0;
+ switch(psvg->ec) {
+ case DK3_ERROR_MEMORY: {
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 9);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 779 "f2lsvg.ctr"
+ } break;
+ default: {
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 784 "f2lsvg.ctr"
+ } break;
+ }
+ }
+ } else {
+ if(op & DK3_FIG_OP_FILL) {
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, pobj->fi);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ any = 1;
+ }
+ }
+ if(op & DK3_FIG_OP_STROKE) {
+ any = 1;
+ /* Line width.
+ */
+ lw = dk3fig_tool_get_lw(drw, pobj, &mec);
+ lw = dk3ct_2d_r(&(job->ct2d), lw, &mec);
+ f2lsvgst_style_set_line_width(&sty, lw);
+ if(mec) {
+ back = 0;
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ mec = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 809 "f2lsvg.ctr"
+ }
+ /* Line style.
+ */
+ /* lsv = dk3ct_2d_r(&(job->ct2d), pobj->sv, &mec); */
+ lsv = 0.9 * pobj->sv;
+ f2lsvgst_style_set_line_style(&sty, pobj->ls, lsv);
+ /* Stroke color.
+ */
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_line_color(&sty, sc.r, sc.g, sc.b);
+ if(!(pobj->cl)) {
+ /* Line cap.
+ */
+ f2lsvgst_style_set_text_line_cap(&sty, pobj->cs);
+ }
+ }
+ if(op) {
+ if(DK3_FIG_OBJ_ELLIPSE != pobj->ot) {
+ if(!((DK3_FIG_OBJ_ARC == pobj->ot) && (1 == pobj->st))) {
+ /* Line join.
+ */
+ any = 1;
+ f2lsvgst_style_set_text_line_join(&sty, pobj->js);
+ }
+ }
+ }
+ if(any) {
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 840 "f2lsvg.ctr"
+ }
+ }
+
+
+#line 843 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for one object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pobj Current object.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_object_style_collection(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ int back = 1;
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(5 != pobj->st) {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ if(!f2lsvg_text_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ }
+ if(!(back)) {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 889 "f2lsvg.ctr"
+ }
+ return back;
+}
+
+
+
+/** Collect style information for all objects in drawing,
+ add styles to style collection.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_collect_styles(f2l_job_t *job, dk3_fig_drawing_t *drw, f2l_svg_t *psvg)
+{
+ dk3_fig_obj_t *pobj;
+ unsigned long objno = 0UL;
+ unsigned long oldsourceline;
+ int res;
+ int back = 1;
+
+
+#line 912 "f2lsvg.ctr"
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ if(!dk3fig_tool_is_bgrect(pobj, objno)) {
+ dk3app_set_source_line(job->app, pobj->li);
+ if(!f2lsvg_object_style_collection(job, drw, psvg, pobj)) {
+ back = 0;
+ }
+ if(pobj->af) {
+ if((pobj->af)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->af)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ if(pobj->ab) {
+ if((pobj->ab)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->ab)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ }
+ objno++;
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 953 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Check whether or not we must append a slash to the font base
+ directory.
+ @param bn Font base directory name.
+ @return 1 to add a slash, 0 for no slash needed.
+*/
+static
+int
+f2lsvg_must_add_slash_to_font_base(char const *bn)
+{
+ char const *ptr;
+ int back = 1;
+ ptr = bn;
+ while(*ptr) {
+ if('/' == *ptr) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ ptr++;
+ }
+ return back;
+}
+
+
+
+/** Write font face definitions.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+static
+void
+f2lsvg_write_font_faces(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ dkChar dkb[DK3_MAX_PATH]; /* Font base (dkChars). */
+ char chb[DK3_MAX_PATH]; /* Font base (8-bit chars). */
+ size_t i; /* Walk through the 35 fonts. */
+ int fs; /* Font style. */
+ int res = 0;
+
+
+#line 1002 "f2lsvg.ctr"
+ if(0 < job->svgfontbase) {
+
+#line 1003 "f2lsvg.ctr"
+ switch(job->svgfontbase) {
+ case 2: {
+ res = dk3font_gs_base_web(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ default: {
+ res = dk3font_gs_base_local(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ }
+ if(res) {
+
+#line 1012 "f2lsvg.ctr"
+ res = dk3str_to_c8p_app(
+ chb, sizeof(chb), dkb, dk3app_get_encoding(job->app), job->app
+ );
+
+#line 1015 "f2lsvg.ctr"
+ }
+ for(i = 0; i < 35; i++) {
+
+#line 1017 "f2lsvg.ctr"
+ if((psvg->psFontsUsed)[i]) {
+ fputs(f2lsvg_c8_kw[23], job->of1);
+ /* Font family.
+ */
+ fputs(f2lsvg_c8_kw[25], job->of1);
+ fputs(dk3font_get_svg_family((int)i), job->of1);
+ fputs(f2lsvg_c8_kw[26], job->of1);
+
+#line 1024 "f2lsvg.ctr"
+ /* Font style
+ */
+ fs = dk3font_get_svg_features((int)i);
+ if(fs & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvg_c8_kw[27], job->of1);
+ } else {
+ if(fs & DK3_FONT_ITALIC) {
+ fputs(f2lsvg_c8_kw[28], job->of1);
+ } else {
+ fputs(f2lsvg_c8_kw[29], job->of1);
+ }
+ }
+
+#line 1036 "f2lsvg.ctr"
+ /* Font weight
+ */
+ fprintf(job->of1,f2lsvg_c8_kw[30],dk3font_get_svg_font_weight((int)i));
+
+
+#line 1040 "f2lsvg.ctr"
+ /* Source
+ */
+ fputs(f2lsvg_c8_kw[31], job->of1);
+ if(res) {
+#if 0
+ /* 2013-01-30 No file:// prefix
+ */
+ if(1 == job->svgfontbase) {
+ fputs(f2lsvg_c8_kw[34], job->of1);
+ }
+#endif
+ fputs(chb, job->of1);
+ if(f2lsvg_must_add_slash_to_font_base(chb)) {
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ }
+ }
+
+#line 1056 "f2lsvg.ctr"
+ fputs(dk3font_get_gs_old_file((int)i), job->of1);
+
+#line 1057 "f2lsvg.ctr"
+ fputs(f2lsvg_c8_kw[32], job->of1);
+#if 0
+ /* 2013-01-30 No font id for TTF fonts
+ */
+ fputs(dk3font_get_svg_fontid((int)i), job->of1);
+
+#line 1062 "f2lsvg.ctr"
+#endif
+ fputs(f2lsvg_c8_kw[33], job->of1);
+
+#line 1064 "f2lsvg.ctr"
+ fputs(f2lsvg_c8_kw[24], job->of1);
+
+#line 1065 "f2lsvg.ctr"
+ }
+
+#line 1066 "f2lsvg.ctr"
+ }
+
+#line 1067 "f2lsvg.ctr"
+ }
+
+#line 1068 "f2lsvg.ctr"
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Driver functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1075 "f2lsvg.ctr"
+
+
+/** Driver-specific initialization.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 0;
+
+
+#line 1089 "f2lsvg.ctr"
+ if(f2lsvg_coordinates_transformation(job, drw)) {
+ psvg = f2lsvgst_new_app(job->app);
+ if(psvg) {
+ drw->dsd = (void *)psvg;
+ back = f2lsvg_collect_styles(job, drw, psvg);
+ }
+ }
+
+#line 1096 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Release resources allocated by f2lud_driver_initialize().
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1110 "f2lsvg.ctr"
+ if(drw->dsd) {
+ f2lsvgst_delete((f2l_svg_t *)(drw->dsd));
+ } drw->dsd = NULL;
+
+
+#line 1114 "f2lsvg.ctr"
+}
+
+
+
+/** Open output file.
+ @param job Jobs structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1132 "f2lsvg.ctr"
+ }
+ return back;
+}
+
+
+
+/** Close output file.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_close_output_files(f2l_job_t *job)
+{
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+}
+
+
+
+/** Check whether we must write a style tag for font faces or style
+ definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a style tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_style(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back = 0;
+ if(job->css) {
+ if(psvg->nStyles) {
+ back = 1;
+ }
+ }
+ if(0 < job->svgfontbase) {
+ if(f2lsvgst_any_ps_font_used(psvg)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether we must write a defs tag for fill patterns,
+ font faces, or style definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a defs tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_defs(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back;
+ back = f2lsvg_must_write_style(job, psvg);
+ if(0 == back) {
+ if(psvg->nPatterns) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write start of output file.
+ @param job Job strucure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 1;
+
+
+#line 1212 "f2lsvg.ctr"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ /* XML header and doctype.
+ */
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[2], job->of1);
+ fputs(f2lsvg_c8_kw[3], job->of1);
+ fputs(f2lsvg_c8_kw[4], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ /* Opening svg tag.
+ */
+ f2lsvg_tag_open_start(job, 10);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[11],
+ (job->width / 72.0), (job->height / 72.0), job->lwidth, job->lheight
+ );
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[12], job->of1);
+ fputs(f2lsvg_c8_kw[13], job->of1);
+ }
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Title.
+ */
+ f2lsvg_tag_open(job, 14);
+ fputs(f2lsvg_c8_kw[16], job->of1);
+ f2lsvg_tag_close(job, 14);
+ /* Description.
+ */
+ f2lsvg_tag_open(job, 15);
+ fputs(f2lsvg_c8_kw[17], job->of1);
+ f2lsvg_tag_close(job, 15);
+ /* Definitions and style.
+ */
+ if(f2lsvg_must_write_defs(job, psvg)) {
+ f2lsvg_tag_open(job, 18);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Pattern definitions.
+ */
+ f2lsvgst_write_patterns(job, drw, psvg);
+ if(f2lsvg_must_write_style(job, psvg)) {
+ f2lsvg_tag_open_start(job, 19);
+ fputs(f2lsvg_c8_kw[20], job->of1);
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[21], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Font face definitions if any.
+ */
+ f2lsvg_write_font_faces(job, drw, psvg);
+ /* Style definitions.
+ */
+ if(job->css) {
+ f2lsvgst_write_styles(job, drw, psvg);
+ }
+ fputs(f2lsvg_c8_kw[22], job->of1);
+ f2lsvg_tag_close(job, 19);
+ }
+ f2lsvg_tag_close(job, 18);
+ }
+
+#line 1272 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Write end of output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lsvg_tag_close(job, 10);
+}
+
+
+
+/** Process ellipse object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ellipse(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot; /* Rotation as integer. */
+ double x; /* Center X. */
+ double y; /* Center Y. */
+ double rx; /* Radius X. */
+ double ry; /* Radius Y. */
+ int isEllipse = 0; /* Flag: Is ellipse. */
+ int isRotated = 0; /* Flag: Is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ switch(obj->st) {
+ case 1: case 2: {
+ if(fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,&mec)) > 1.0e-6)
+ {
+ isEllipse = 1;
+ if(fabs((obj->dt).ell.an) > 1.0e-6) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, ((obj->dt).ell.an / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rotation, irot, &mec))) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ }
+ } break;
+ }
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).ell.cx, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).ell.cy, &mec);
+ rx = ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.rx, &mec);
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(isEllipse) {
+ ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.ry, &mec);
+ f2lsvg_tag_name(job, 46);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[48], x, y, rotation, rx, ry);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[49], x, y, rx, ry);
+ }
+ } else {
+ f2lsvg_tag_name(job, 45);
+ fprintf(job->of1, f2lsvg_c8_kw[47], x, y, rx);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param arcbox Flag: Rounded corners.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_box(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int arcbox,
+ int *ec
+)
+{
+ dk3_bb_t outbb;
+ dk3_fig_poly_point_t *po;
+ double x;
+ double y;
+ double w;
+ double h;
+ double r;
+ size_t i;
+ int mec = 0;
+
+
+#line 1386 "f2lsvg.ctr"
+ po = (obj->dt).pol.po;
+ if(po) {
+ dk3bb_reset(&outbb);
+ for(i = 0; i < (obj->dt).pol.np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, &mec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, &mec));
+ po++;
+ }
+ x = outbb.xmin;
+ y = outbb.ymin;
+ w = fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, &mec));
+ h = fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, &mec));
+ r = -1.0;
+ if(arcbox) {
+
+#line 1400 "f2lsvg.ctr"
+ r = fabs(0.9 * (obj->dt).pol.ra);
+
+#line 1401 "f2lsvg.ctr"
+ if(r > (0.5 * w)) { r = 0.5 * w; }
+ if(r > (0.5 * h)) { r = 0.5 * h; }
+
+#line 1403 "f2lsvg.ctr"
+ }
+ if(0 == mec) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 37);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[38], x, y, w, h);
+ if(arcbox) {
+ fprintf(job->of1, f2lsvg_c8_kw[39], r, r);
+ }
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ }
+ }
+ dk3bb_reset(&outbb);
+ if(mec) { *ec = mec; }
+
+
+#line 1420 "f2lsvg.ctr"
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polygon(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 40);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ if(primary) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].x, po[np - 1].x, &mec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].y, po[np - 1].y, &mec))) {
+ np--;
+ }
+ }
+ }
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 44);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_image(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t outbb; /* Output range. */
+ dk3_bif_t *bif; /* Image to process. */
+ dk3_fig_poly_point_t *po; /* Coordinates points. */
+ double tx; /* X translation. */
+ double ty; /* Y translation. */
+ double xres; /* Image resolution in x direction. */
+ double yres; /* Image resolution in y direction. */
+ double w; /* Image width (resolution used). */
+ double h; /* Image height (resolution used). */
+ double qx; /* Usable stretch factor for x. */
+ double qy; /* Usable stretch factor for y. */
+ double ow = 0.0; /* Output width. */
+ double oh = 0.0; /* Output height. */
+ double x1; /* Smallest x value. */
+ double x2; /* Largest x value. */
+ double y1; /* Smallest y value. */
+ double y2; /* Largest y value. */
+ dk3_bif_coord_t imw; /* Image width (number of pixels). */
+ dk3_bif_coord_t imh; /* Image height (number of pixels). */
+ size_t np; /* Number of coordinates points. */
+ size_t i; /* Traverse coordinates points. */
+ int drawdir; /* Drawing direction. */
+ int rotation = 0; /* Rotation in degree. */
+ int doScaleX = 0; /* Flag: Scale x=-1. */
+ int doScaleY = 0; /* Flag: Sclae y=-1. */
+
+ if((obj->dt).pol.fn) {
+ bif = dk3bif_open_c8_filename_app(
+ (obj->dt).pol.fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ /* Find image dimensions.
+ */
+ imw = dk3bif_get_width(bif);
+ imh = dk3bif_get_height(bif);
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ dk3bif_close(bif);
+ /* Find output area.
+ */
+ dk3bb_reset(&outbb);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
+ po++;
+ }
+ x1 = outbb.xmin; x2 = outbb.xmax;
+ y1 = outbb.ymin; y2 = outbb.ymax;
+ /* Find drawing direction.
+ */
+ drawdir = f2lto_find_draw_direction(job, drw, obj, ec);
+ /* Find real image width and height.
+ */
+ if((xres > 0.0) && (yres > 0.0)) {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = dk3ma_d_div_ok((double)imh, yres, ec);
+ h = dk3ma_d_div_ok((double)imw, xres, ec);
+ } break;
+ default: {
+ w = dk3ma_d_div_ok((double)imw, xres, ec);
+ h = dk3ma_d_div_ok((double)imh, yres, ec);
+ } break;
+ }
+ } else {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = (double)imh;
+ h = (double)imw;
+ } break;
+ default: {
+ w = (double)imw;
+ h = (double)imh;
+ } break;
+ }
+ }
+ /* Find the stretch factors and used regions.
+ */
+ qx = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), w, ec);
+ qy = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), h, ec);
+ qx = fabs(qx);
+ qy = fabs(qy);
+#if VERSION_BEFORE_20150821
+ ow = oh = 0.0;
+#endif
+ if(qy >= qx) { /* Image too wide, can not use all height. */
+ ow = dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec);
+ oh = dk3ma_d_mul_ok(qx, h, ec);
+ y1 = dk3ma_d_add_ok(
+ outbb.ymin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), oh, ec)
+ ),
+ ec
+ );
+ y2 = dk3ma_d_add_ok(y1, oh, ec);
+ } else { /* Image too high, can not use all width. */
+ oh = dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec);
+ ow = dk3ma_d_mul_ok(qy, w, ec);
+ x1 = dk3ma_d_add_ok(
+ outbb.xmin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), ow, ec)
+ ),
+ ec
+ );
+ x2 = dk3ma_d_add_ok(x1, ow, ec);
+ }
+ /* Find coordinates transformations.
+ */
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ tx = x2; ty = y2; rotation = -90; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED: {
+ tx = x2; ty = y1; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED: {
+ tx = x1; ty = y2; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED: {
+ tx = x1; ty = y1; rotation = -90; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM: {
+ tx = x2; ty = y2; rotation = 180;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP: {
+ tx = x2; ty = y1; rotation = 90;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM: {
+ tx = x1; ty = y2; rotation = -90;
+ } break;
+ default: {
+ tx = x1; ty = y1;
+ } break;
+ }
+ /* Write output.
+ */
+ /* <g transform="..."> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fprintf(job->of1, f2lsvg_c8_kw[60], tx, ty);
+ if(0 != rotation) {
+ fprintf(job->of1, f2lsvg_c8_kw[61], rotation);
+ }
+ if((doScaleX) || (doScaleY)) {
+ fputs(f2lsvg_c8_kw[62], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleX) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleY) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[65], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ /* <image ... /> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 66);
+ fprintf(job->of1, f2lsvg_c8_kw[67], ow, oh);
+ fputs((obj->dt).pol.fn, job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ /* </g> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1722 "f2lsvg.ctr"
+ }
+ }
+}
+
+
+
+/** Process polyline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 5: { /* imported image */
+ f2lsvg_process_image(job, drw, psvg, obj, ec);
+ } break;
+ case 4: { /* arc box */
+ f2lsvg_process_box(job, drw, psvg, obj, 1, ec);
+ } break;
+ case 3: { /* polygon */
+ f2lsvg_process_pl_polygon(job, drw, psvg, obj, primary, ec);
+ } break;
+ case 2: { /* box */
+ f2lsvg_process_box(job, drw, psvg, obj, 0, ec);
+ } break;
+ default: { /* polyline */
+ f2lsvg_process_pl_polyline(job, drw, psvg, obj, ec);
+ } break;
+ }
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param sp Spline points.
+ @param np Total number of points
+ @param cp Current point/segment.
+ @param isfirst Flag: Moveto needed.
+ @param iscl Flag: Closed (1) or open (0) spline.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_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 cp,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ dk3_fig_spline_point_t *pa = NULL;
+ dk3_fig_spline_point_t *pb = NULL;
+ dk3_fig_spline_point_t *pc = NULL;
+ dk3_fig_spline_point_t *pd = NULL;
+ double factor;
+ double t;
+ double x;
+ double y;
+ double dxdt;
+ double dydt;
+ double lastx = 0.0;
+ double lasty = 0.0;
+ double lastdxdt = 0.0;
+ double lastdydt = 0.0;
+ size_t xsss;
+ size_t iseg;
+ size_t ic;
+ size_t id;
+ int res;
+ int mec = 0;
+
+
+#line 1817 "f2lsvg.ctr"
+ if(cp < ((iscl) ? (np) : (np - 1))) {
+ pb = &(sp[cp]);
+
+#line 1819 "f2lsvg.ctr"
+ ic = cp + 1;
+ while(ic >= np) { ic = ic - np; }
+
+#line 1821 "f2lsvg.ctr"
+ pc = &(sp[ic]);
+ if(cp > 0) {
+
+#line 1823 "f2lsvg.ctr"
+ pa = &(sp[cp - 1]);
+ } else {
+ if(iscl) {
+
+#line 1826 "f2lsvg.ctr"
+ pa = &(sp[np - 1]);
+ }
+ }
+ if(cp < (np - 2)) {
+
+#line 1830 "f2lsvg.ctr"
+ pd = &(sp[cp + 2]);
+ } else {
+ if(iscl) {
+ id = cp + 2;
+ while(id >= np) { id = id - np; }
+
+#line 1835 "f2lsvg.ctr"
+ pd = &(sp[id]);
+ }
+ }
+ xsss = dk3fig_tool_xssbs(drw, primary);
+
+#line 1839 "f2lsvg.ctr"
+ factor = 1.0 / (double)xsss;
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+
+#line 1843 "f2lsvg.ctr"
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+
+#line 1844 "f2lsvg.ctr"
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+
+#line 1851 "f2lsvg.ctr"
+ /* MOVETO lastx lasty */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, &mec),
+ dk3ct_2d_y(&(job->ct2d), lasty, &mec)
+ );
+ }
+ for(iseg = 0; iseg < xsss; iseg++) {
+
+#line 1859 "f2lsvg.ctr"
+ if(iseg < (xsss - 1)) {
+ t = (double)(iseg + 1) / (double)xsss;
+ } else {
+ t = 1.0;
+ }
+
+#line 1864 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, t, 1);
+
+#line 1865 "f2lsvg.ctr"
+ if(!(res)) { mec = DK3_ERROR_MATH_OVERFLOW; }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+
+#line 1872 "f2lsvg.ctr"
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), x, &mec),
+ dk3ct_2d_y(&(job->ct2d), y, &mec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (xsss - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(cp < (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(iscl) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ }
+
+#line 1893 "f2lsvg.ctr"
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ if(mec) { *ec = mec; }
+
+
+#line 1900 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the first partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_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 iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 1954 "f2lsvg.ctr"
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+
+#line 1955 "f2lsvg.ctr"
+ dnumsegs = (1.0 - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 1957 "f2lsvg.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 1958 "f2lsvg.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (1.0 - myts) / (double)nsegs;
+
+#line 1967 "f2lsvg.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ /* If necessary move to the start point.
+ */
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (1.0 - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, 1.0, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2022 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2034 "f2lsvg.ctr"
+ }
+
+
+#line 2036 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the last partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_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 iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 2090 "f2lsvg.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+
+#line 2091 "f2lsvg.ctr"
+ dnumsegs = myte * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 2093 "f2lsvg.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 2094 "f2lsvg.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = myte / (double)nsegs;
+
+#line 2103 "f2lsvg.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ /* Move to start point.
+ */
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ /* Further curve only if te > 1.0e-6.
+ For smaller te draw straight line.
+ */
+ if(1.0e-6 < myte) {
+
+#line 2126 "f2lsvg.ctr"
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+
+#line 2128 "f2lsvg.ctr"
+ t = (double)(iseg + 1) / (double)nsegs;
+ t = t * myte;
+ } else {
+
+#line 2131 "f2lsvg.ctr"
+ t = myte;
+ }
+
+#line 2133 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else {
+
+#line 2158 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2164 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2176 "f2lsvg.ctr"
+ }
+
+
+#line 2178 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the single partial X-spline segment cutted on both ends
+ from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_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 iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 2236 "f2lsvg.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+ dnumsegs = (myte - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (myte - myts) / ((double)nsegs);
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (myte - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = myte;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2305 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2319 "f2lsvg.ctr"
+ }
+
+
+#line 2321 "f2lsvg.ctr"
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+ size_t min;
+ size_t max;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if(job->coah) {
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ } else {
+ if(obj->ab) {
+
+#line 2363 "f2lsvg.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the start segment.
+ */
+ min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
+ if(obj->af) {
+
+#line 2369 "f2lsvg.ctr"
+ if((obj->dt).spl.te >= (obj->dt).spl.ts) {
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max > min) {
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_single_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
+ 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Arrowheads in summary too long for spline */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX);
+
+#line 2397 "f2lsvg.ctr"
+ }
+ } else {
+
+#line 2399 "f2lsvg.ctr"
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ }
+ } else {
+
+#line 2409 "f2lsvg.ctr"
+ if(obj->af) {
+
+#line 2410 "f2lsvg.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max < (np - 1)) {
+ if(max > 0) {
+ for(i = 0; i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Illegal max value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 2434 "f2lsvg.ctr"
+ }
+ } else {
+
+#line 2436 "f2lsvg.ctr"
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ }
+ }
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ib;
+ size_t ic;
+
+
+#line 2477 "f2lsvg.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (1 < np) {
+ for (ib = 0; ib < (np - 1); ib++) {
+ ic = ib + 1;
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ }
+ }
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ } else {
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* Too few points in X-spline */
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+
+
+#line 2556 "f2lsvg.ctr"
+}
+
+
+
+/** Process closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ for(i = 0; i < np; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
+ );
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ia;
+ size_t ib;
+ size_t ic;
+ size_t id;
+
+
+
+#line 2630 "f2lsvg.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (2 < np) {
+ for (ib = 0; ib < np; ib++) {
+ ic = ib + 1;
+ id = ib + 2;
+ if (ic >= np) { ic = ic - np; }
+ if (id >= np) { id = id - np; }
+ if (0 < ib) {
+ ia = ib - 1;
+ } else {
+ ia = np - 1;
+ }
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
+ }
+ }
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
+ } else {
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* ERROR: Too few points */
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+
+
+#line 2718 "f2lsvg.ctr"
+}
+
+
+
+/** Process spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 1: case 3: case 5: { /* closed spline */
+ f2lsvg_process_closed_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ default: { /* open spline */
+ f2lsvg_process_open_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ }
+}
+
+
+
+/** Process text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_text(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot = 0.0; /* Rotation as integer. */
+ double x; /* Text x position. */
+ double y; /* Text y position. */
+ int isRotated = 0; /* Flag: Text is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
+ rotation = (obj->dt).txt.an;
+ if(1.0e-6 < fabs(rotation)) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, (rotation / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(fabs(dk3ma_d_sub_ok(rotation, irot, &mec)) < 1.0e-3) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 50);
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &mec);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[53], x, y, rotation);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[52], x, y);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[51], job->of1);
+ if((obj->dt).txt.st) {
+#if VERSION_BEFORE_2013_11_10
+ fputs((obj->dt).txt.st, job->of1);
+#else
+ f2lsvg_fputs_translate((obj->dt).txt.st, job->of1);
+#endif
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 50);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ if(mec) { *ec = mec; }
+ if(DK3_FIG_FONT_FLAG_SPECIAL & ((obj->dt).txt.ff)) {
+ /* WARNING: Special text was found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 44);
+ }
+ }
+}
+
+
+
+/** Process arc object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_arc(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double sx; /* Start x. */
+ double sy; /* Start y. */
+ double cx; /* Center x. */
+ double cy; /* Center y. */
+ double r; /* Radius. */
+ double as; /* Arc start angle in radians. */
+ double ae; /* Arc end angle in radians. */
+ double lastx; /* Segment start x. */
+ double lasty; /* Segment start y. */
+ double lastkdxdt; /* X difference to first control. */
+ double lastkdydt; /* Y difference to first control. */
+ double x; /* Segment end x. */
+ double y; /* Segment end y. */
+ double kdxdt; /* X difference to last control. */
+ double kdydt; /* Y difference to last control. */
+ double dnumsegs; /* Number of segments. */
+ double alpha; /* Arc angle in radians. */
+ double alphaseg; /* Segment angle in radians. */
+ double kappa; /* Factor for derivative. */
+ double alphaend; /* Segment end angle in radians. */
+ size_t nsegs; /* Number of segments. */
+ size_t i; /* Index of current segment. */
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+
+ cx = (obj->dt).arc.xc;
+ cy = (obj->dt).arc.yc;
+ r = (obj->dt).arc.ra;
+ if((obj->dt).arc.as < (obj->dt).arc.ae) {
+ as = (obj->dt).arc.as;
+ ae = (obj->dt).arc.ae;
+ } else {
+ as = (obj->dt).arc.ae;
+ ae = (obj->dt).arc.as;
+ }
+ alpha = dk3ma_d_sub_ok(ae, as, ec);
+ dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ alphaseg = alpha / ((double)nsegs);
+ kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
+ sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
+ sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ lastkdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
+ ec
+ );
+ lastkdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
+ ec
+ );
+ for(i = 0; i < nsegs; i++) {
+ if(i < (nsegs - 1)) {
+ alphaend = dk3ma_d_add_ok(
+ as,
+ dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
+ ec
+ );
+ } else {
+ alphaend = ae;
+ }
+ x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
+ y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
+ kdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
+ ec
+ );
+ kdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
+ ec
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastkdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastkdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, kdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, kdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
+ }
+ /* For closed arc draw the lines.
+ */
+ if(1 != obj->st) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), cx, ec),
+ dk3ct_2d_y(&(job->ct2d), cy, ec)
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), sx, ec),
+ dk3ct_2d_y(&(job->ct2d), sy, ec)
+ );
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process half-circle object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_half_circle(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[7];
+ size_t i; /* Traverse po. */
+ int mec = 0; /* Mathematical error code. */
+
+
+#line 2973 "f2lsvg.ctr"
+ po[0].x = 0.0;
+ po[0].y = (obj->dt).hci.ra;
+ po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[1].y = (obj->dt).hci.ra;
+ po[2].x = -1.0 * (obj->dt).hci.ra;
+ po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[3].x = -1.0 * (obj->dt).hci.ra;
+ po[3].y = 0.0;
+ po[4].x = -1.0 * (obj->dt).hci.ra;
+ po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].y = -1.0 * (obj->dt).hci.ra;
+ po[6].x = 0.0;
+ po[6].y = -1.0 * (obj->dt).hci.ra;
+ if(1.0e-6 < fabs((obj->dt).hci.an)) {
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, &mec);
+ }
+ }
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, &mec);
+ }
+ for(i = 0; i < 7; i++) {
+ po[i].x = dk3ct_2d_x(&(job->ct2d), po[i].x, &mec);
+ po[i].y = dk3ct_2d_y(&(job->ct2d), po[i].y, &mec);
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[56], po[0].x, po[0].y);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y
+ );
+ if(obj->st) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[58], po[0].x, po[0].y);
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+
+
+#line 3022 "f2lsvg.ctr"
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ int op;
+
+
+#line 3047 "f2lsvg.ctr"
+ op = dk3fig_tool_get_operation(drw, obj);
+
+#line 3048 "f2lsvg.ctr"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(op) { f2lsvg_process_ellipse(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(op) {f2lsvg_process_polyline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(op) {f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ f2lsvg_process_text(job, drw, psvg, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(op) {f2lsvg_process_arc(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+
+#line 3065 "f2lsvg.ctr"
+ if(op) {f2lsvg_process_half_circle(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
+ if(op) {
+ /* f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); */
+ switch(obj->st) {
+ case 1: case 3: case 5: {
+ f2lsvg_process_fast_closed_spline(job, drw, psvg, obj, ec);
+ } break;
+ default: {
+ f2lsvg_process_fast_open_spline(job, drw, psvg, obj, ec);
+ } break;
+ }
+ }
+ } break;
+ }
+
+
+#line 3082 "f2lsvg.ctr"
+}
+
+
+
+/** Check whether we must use a g instruction to group
+ the object with its arrowheads.
+ @param job Job structure.
+ @param obj Current object to process.
+ @return 1 to group, 0 for no group.
+*/
+static
+int
+f2lsvg_check_must_group(f2l_job_t *job, dk3_fig_obj_t *obj)
+{
+ int back = 0;
+
+
+#line 3098 "f2lsvg.ctr"
+ if(job->group) {
+
+#line 3099 "f2lsvg.ctr"
+ if(obj->af) {
+
+#line 3100 "f2lsvg.ctr"
+ if((obj->af)->o1) {
+
+#line 3101 "f2lsvg.ctr"
+ back = 1;
+ }
+ if((obj->af)->o2) {
+
+#line 3104 "f2lsvg.ctr"
+ back = 1;
+ }
+ }
+ if(obj->ab) {
+
+#line 3108 "f2lsvg.ctr"
+ if((obj->ab)->o1) {
+
+#line 3109 "f2lsvg.ctr"
+ back = 1;
+ }
+ if((obj->ab)->o2) {
+
+#line 3112 "f2lsvg.ctr"
+ back = 1;
+ }
+ }
+ }
+
+#line 3116 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Process arrowhead object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ah_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ switch (obj->ot) {
+ case DK3_FIG_OBJ_SPLINE: {
+ if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
+ obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ obj->ot = DK3_FIG_OBJ_SPLINE;
+ } else {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ }
+ } break;
+ default: {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ } break;
+ }
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lsvg_process_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_svg_t *psvg; /* SVG style collection. */
+ int mg; /* Flag: Must group */
+ int mec = 0; /* Mathematical error code. */
+
+
+
+#line 3174 "f2lsvg.ctr"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ mg = f2lsvg_check_must_group(job, obj);
+ /*
+ Process object itself.
+ */
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+
+
+#line 3185 "f2lsvg.ctr"
+ f2lsvg_process_one(job, drw, psvg, obj, 1, &mec);
+ /*
+ Process arrowheads.
+ */
+ if(obj->af) {
+
+#line 3190 "f2lsvg.ctr"
+ if((obj->af)->o1) {
+
+#line 3191 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),&mec);
+#endif
+ }
+ if((obj->af)->o2) {
+
+#line 3198 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),&mec);
+#endif
+ }
+
+#line 3204 "f2lsvg.ctr"
+ }
+ if(obj->ab) {
+
+#line 3206 "f2lsvg.ctr"
+ if((obj->ab)->o1) {
+
+#line 3207 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),&mec);
+#endif
+ }
+ if((obj->ab)->o2) {
+
+#line 3214 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),&mec);
+#endif
+ }
+
+#line 3220 "f2lsvg.ctr"
+ }
+
+
+#line 3222 "f2lsvg.ctr"
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ if(mec) {
+ /* ERROR: Mathematical error occured. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ job->exval = FIG2LAT_EXIT_ERROR_MATH;
+
+#line 3232 "f2lsvg.ctr"
+ }
+
+
+#line 3234 "f2lsvg.ctr"
+}
+
+
+
+void
+f2lsvg_output(f2l_job_t *job)
+{
+ dk3_fig_drawing_t *drw;
+ dk3_fig_obj_t *obj;
+ unsigned long objno = 0UL;
+ unsigned long oldsrcline = 0UL;
+
+
+#line 3246 "f2lsvg.ctr"
+ oldsrcline = dk3app_get_source_line(job->app);
+ dk3app_set_source_line(job->app, 0UL);
+ drw = job->drw; objno = 0UL;
+ if(f2lsvg_driver_initialize(job, drw)) {
+ if(f2lsvg_open_output_files(job)) {
+ if(f2lsvg_start_processing(job, drw)) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(job->app, obj->li);
+ if(!dk3fig_tool_is_bgrect(obj, objno)) {
+ f2lsvg_process_object(job, drw, obj);
+ }
+ objno++;
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3262 "f2lsvg.ctr"
+ }
+ f2lsvg_end_processing(job, drw);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3266 "f2lsvg.ctr"
+ }
+ f2lsvg_close_output_files(job);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3270 "f2lsvg.ctr"
+ }
+ dk3app_set_source_line(job->app, oldsrcline);
+
+
+#line 3273 "f2lsvg.ctr"
+ f2lsvg_driver_end(job, drw);
+}
+