/* 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 */ "\n", /* 3 */ "\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 */ "", /* 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. */ /* */ 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); /* */ 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); /* */ 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); }