diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/f2lsvg.c |
Initial commit
Diffstat (limited to 'support/dktools/f2lsvg.c')
-rw-r--r-- | support/dktools/f2lsvg.c | 3590 |
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 */ "&", +/* 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 */ "<", +/* 61 3d */ "=", +/* 62 3e */ ">", +/* 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 */ " ", +/* 161 a1 */ "¡", +/* 162 a2 */ "¢", +/* 163 a3 */ "£", +/* 164 a4 */ "¤", +/* 165 a5 */ "¥", +/* 166 a6 */ "¦", +/* 167 a7 */ "§", +/* 168 a8 */ "¨", +/* 169 a9 */ "©", +/* 170 aa */ "ª", +/* 171 ab */ "«", +/* 172 ac */ "¬", +/* 173 ad */ "­", +/* 174 ae */ "®", +/* 175 af */ "¯", +/* 176 b0 */ "°", +/* 177 b1 */ "±", +/* 178 b2 */ "²", +/* 179 b3 */ "³", +/* 180 b4 */ "´", +/* 181 b5 */ "µ", +/* 182 b6 */ "¶", +/* 183 b7 */ "·", +/* 184 b8 */ "¸", +/* 185 b9 */ "¹", +/* 186 ba */ "º", +/* 187 bb */ "»", +/* 188 bc */ "¼", +/* 189 bd */ "½", +/* 190 be */ "¾", +/* 191 bf */ "¿", +/* 192 c0 */ "À", +/* 193 c1 */ "Á", +/* 194 c2 */ "Â", +/* 195 c3 */ "Ã", +/* 196 c4 */ "Ä", +/* 197 c5 */ "Å", +/* 198 c6 */ "Æ", +/* 199 c7 */ "Ç", +/* 200 c8 */ "È", +/* 201 c9 */ "É", +/* 202 ca */ "Ê", +/* 203 cb */ "Ë", +/* 204 cc */ "/Igrave;", +/* 205 cd */ "Í", +/* 206 ce */ "Î", +/* 207 cf */ "Ï", +/* 208 d0 */ "Ð", +/* 209 d1 */ "Ñ", +/* 210 d2 */ "Ò", +/* 211 d3 */ "Ó", +/* 212 d4 */ "Ô", +/* 213 d5 */ "Õ", +/* 214 d6 */ "Ö", +/* 215 d7 */ "×", +/* 216 d8 */ "Ø", +/* 217 d9 */ "Ù", +/* 218 da */ "Ú", +/* 219 db */ "Û", +/* 220 dc */ "Ü", +/* 221 dd */ "Ý", +/* 222 de */ "Þ", +/* 223 df */ "ß", +/* 224 e0 */ "à", +/* 225 e1 */ "á", +/* 226 e2 */ "â", +/* 227 e3 */ "ã", +/* 228 e4 */ "ä", +/* 229 e5 */ "å", +/* 230 e6 */ "æ", +/* 231 e7 */ "ç", +/* 232 e8 */ "è", +/* 233 e9 */ "é", +/* 234 ea */ "ê", +/* 235 eb */ "ë", +/* 236 ec */ "ì", +/* 237 ed */ "í", +/* 238 ee */ "î", +/* 239 ef */ "ï", +/* 240 f0 */ "ð", +/* 241 f1 */ "ñ", +/* 242 f2 */ "ò", +/* 243 f3 */ "ó", +/* 244 f4 */ "ô", +/* 245 f5 */ "õ", +/* 246 f6 */ "ö", +/* 247 f7 */ "÷", +/* 248 f8 */ "ø", +/* 249 f9 */ "ù", +/* 250 fa */ "ú", +/* 251 fb */ "û", +/* 252 fc */ "ü", +/* 253 fd */ "ý", +/* 254 fe */ "þ", +/* 255 ff */ "ÿ" +}; + + +/* ************************************************************************ */ +/* * * */ +/* * 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); +} + |