/* Copyright (c) 2004-2010, Dirk Krause All rights reserved. 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 Dirk Krause 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 dkfigsvg.c SVG output driver module. */ /** Inside the dkfigsvg module. */ #define DKFIGSVG_C 1 #include "dkfig.h" $(trace-include) /** Restrict number of decimal digits for double values. */ #define drd(v,o,w) dkfig_tool2_drd(v,o,w) /** Abbreviation. */ #define OI dkfig_svg_output_instruction /** Abbreviation. */ #define DRVE dk_fig_svg_drve /** Abbreviation. */ #define SVGPAT dk_fig_svg_pat /** Abbreviation. */ #define SVGSTY dk_fig_svg_style /** Abbreviation. */ #define OBJ dk_fig_object /** Abbreviation. */ #define AH dk_fig_arrow /** String pointer. */ typedef char *PCHAR; /** String array pointer. */ typedef PCHAR *PPCHAR; /** Output keywords. */ static char *kw[] = { /* 00 */ "\n", /* 01 */ " ", /* 02 */ "<", /* 03 */ ">", /* 04 */ "/", /* 05 */ "svg", /* 06 */ "", /* 07 */ "!DOCTYPE svg PUBLIC", /* 08 */ "\"-//W3C//DTD SVG 20010904//EN\"", /* 09 */ "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"", /* 10 */ "xmlns=\"http://www.w3.org/2000/svg\"", /* 11 */ "xmlns:xlink=\"http://www.w3.org/1999/xlink\"", /* 12 */ "\"-//W3C//DTD SVG 1.1//EN\"", /* 13 */ "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"", /* 14 */ "x", /* 15 */ "y", /* 16 */ "width", /* 17 */ "height", /* 18 */ "viewBox", /* 19 */ "=", /* 20 */ "\"", /* 21 */ "in", /* 22 */ "px", /* 23 */ "xmlns:svg=\"http://www.w3.org/2000/svg\"", /* 24 */ ":", /* 25 */ "title", /* 26 */ "desc", /* 27 */ "Converted by fig2vect, see http://dktools.sourceforge.net/fig2vect.html", /* 28 */ "defs", /* 29 */ "type=\"text/ecmascript\"", /* 30 */ "", /* 32 */ "script", /* 33 */ "a", /* 34 */ "g", /* 35 */ "pattern", /* 36 */ "id", /* 37 */ "p", /* 38 */ "style", /* 39 */ "type=\"text/css\"", /* 40 */ ".", /* 41 */ "{", /* 42 */ "}", /* 43 */ ";", /* 44 */ "c", /* 45 */ "#", /* 46 */ "font-family", /* 47 */ "font-style", /* 48 */ "font-weight", /* 49 */ "font-size", /* 50 */ "color", /* 51 */ "text-anchor", /* 52 */ "start", /* 53 */ "middle", /* 54 */ "end", /* 55 */ ",", /* 56 */ "serif", /* 57 */ "sans-serif", /* 58 */ "monospace", /* 59 */ "normal", /* 60 */ "italic", /* 61 */ "bold", /* 62 */ "fill", /* 63 */ "stroke", /* 64 */ "stroke-width", /* 65 */ "none", /* 66 */ "stroke-dasharray", /* 67 */ "stroke-linecap", /* 68 */ "butt", /* 69 */ "round", /* 70 */ "square", /* 71 */ "stroke-linejoin", /* 72 */ "miter", /* 73 */ "bevel", /* 74 */ "url", /* 75 */ "(", /* 76 */ ")", /* 77 */ "text", /* 78 */ "img", /* 79 */ "rect", /* 80 */ "class", /* 81 */ "pt", /* 82 */ "rx", /* 83 */ "ry", /* 84 */ "polygon", /* 85 */ "polyline", /* 86 */ "points", /* 87 */ "cx", /* 88 */ "cy", /* 89 */ "r", /* 90 */ "circle", /* 91 */ "ellipse", /* 92 */ "transform", /* 93 */ "translate", /* 94 */ "rotate", /* 95 */ "rx", /* 96 */ "ry", /* 97 */ "-", /* 98 */ "path", /* 99 */ "d", /* 100 */ "M", /* 101 */ "L", /* 102 */ "A", /* 103 */ "0", /* 104 */ "1", /* 105 */ "z", /* 106 */ "C", /* 107 */ "'", /* 108 */ "@font-face", /* 109 */ "src: ", /* 110 */ "format(svg)", /* 111 */ "patternUnits=\"userSpaceOnUse\"", /* 112 */ "image", /* 113 */ "", /* 115 */ "line ", /* 116 */ "layer ", }; /** Number of elements in the kw array. */ static size_t kw_num = sizeof(kw)/sizeof(PCHAR); /** Configuration option: js library */ static char *cmd00[] = { "js", "library", NULL }; /** Configuration option: id */ static char *cmd01[] = { "id", NULL }; /** Configuration option: onfocusin */ static char *cmd02[] = { "onfocusin", NULL }; /** Configuration option: onfocusout */ static char *cmd03[] = { "onfocusout", NULL }; /** Configuration option: onactivate */ static char *cmd04[] = { "onactivate", NULL }; /** Configuration option: onclick */ static char *cmd05[] = { "onclick", NULL }; /** Configuration option: onmousedown */ static char *cmd06[] = { "onmousedown", NULL }; /** Configuration option: onmouseup */ static char *cmd07[] = { "onmouseup", NULL }; /** Configuration option: onmouseover */ static char *cmd08[] = { "onmouseover", NULL }; /** Configuration option: onmousemove */ static char *cmd09[] = { "onmousemove", NULL }; /** Configuration option: onmouseout */ static char *cmd10[] = { "onmouseout", NULL }; /** Configuration option: onload */ static char *cmd11[] = { "onload", NULL }; /** Configuration option: onunload */ static char *cmd12[] = { "onunload", NULL }; /** Configuration option: onabort */ static char *cmd13[] = { "onabort", NULL }; /** Configuration option: onerror */ static char *cmd14[] = { "onerror", NULL }; /** Configuration option: onresize */ static char *cmd15[] = { "onresize", NULL }; /** Configuration option: onscroll */ static char *cmd16[] = { "onscroll", NULL }; /** Configuration option: onzoom */ static char *cmd17[] = { "onzoom", NULL }; /** Configuration option: onbegin */ static char *cmd18[] = { "onbegin", NULL }; /** Configuration option: onend */ static char *cmd19[] = { "onend", NULL }; /** Configuration option: onrepeat */ static char *cmd20[] = { "onrepeat", NULL }; /** Configuration option: gs svg-font directory */ static char *cmd21[] = { "gs", "svg-font", "directory", NULL }; /** Configuration options array. */ static char **cmds[] = { /* 00 */ cmd00, /* js library */ /* 01 */ cmd01, /* id */ /* 02 */ cmd02, /* onfocusin */ /* 03 */ cmd03, /* onfocusout */ /* 04 */ cmd04, /* onactivate */ /* 05 */ cmd05, /* onclick */ /* 06 */ cmd06, /* onmousedown */ /* 07 */ cmd07, /* onmouseup */ /* 08 */ cmd08, /* onmouseover */ /* 09 */ cmd09, /* onmousemove */ /* 10 */ cmd10, /* onmouseout */ /* 11 */ cmd11, /* onload */ /* 12 */ cmd12, /* onunload */ /* 13 */ cmd13, /* onabort */ /* 14 */ cmd14, /* onerror */ /* 15 */ cmd15, /* onresize */ /* 16 */ cmd16, /* onscroll */ /* 17 */ cmd17, /* onzoom */ /* 18 */ cmd18, /* onbegin */ /* 19 */ cmd19, /* onend */ /* 20 */ cmd20, /* onrepeat */ /* 21 */ cmd21, /* urw font directory */ NULL }; /** Numbeer of elements in the cmds array. */ static size_t sz_cmds = (sizeof(cmds)/sizeof(PPCHAR)) - 1; /** String exploder pattern. */ static char exploder_pattern[] = { " \t\r\n." }; /** File open mode. */ static char str_mode_open_read[] = { "r" }; /** URW font family name: Nimbus Roman No9 L */ static char urw_svg_nimbus_roman_no9_l[] = { "Nimbus Roman No9 L" }; /** URW font family name: URW Gothic L */ static char urw_svg_urw_gothic_l[] = { "URW Gothic L" }; /** URW font family name: URW Bookman L */ static char urw_svg_urw_bookman_l[] = { "URW Bookman L" }; /** URW font family name: Nimbus Mono L */ static char urw_svg_nimbus_mono_l[] = { "Nimbus Mono L" }; /** URW font family name: Nimbus Sans L */ static char urw_svg_nimbus_sans_l[] = { "Nimbus Sans L" }; /** URW font family name: Nimbus Sans L */ static char urw_svg_nimbus_sans_condensed[] = { "Nimbus Sans L Condensed" }; /** URW font family name: Century Schoolbook L */ static char urw_svg_century_schoolbook_l[] = { "Century Schoolbook L" }; /** URW font family name: URW Palladio L */ static char urw_svg_urw_palladio_l[] = { "URW Palladio L" }; /** URW font family name: Standard Symbols L */ static char urw_svg_standard_symbols_l[] = { "Standard Symbols L" }; /** URW font family name: URW Chancery L */ static char urw_svg_urw_chancery_l[] = { "URW Chancery L" }; /** URW font family name: Dingbats */ static char urw_svg_dingbats[] = { "Dingbats" }; /** Names of URW font families. */ static char *urw_svg_font_families[] = { /* 0 n021003l */ urw_svg_nimbus_roman_no9_l, /* 1 n021023l */ urw_svg_nimbus_roman_no9_l, /* 2 n021004l */ urw_svg_nimbus_roman_no9_l, /* 3 n021004l */ urw_svg_nimbus_roman_no9_l, /* 4 a021023l */ urw_svg_urw_gothic_l, /* 5 a010033l */ urw_svg_urw_gothic_l, /* 6 a010015l */ urw_svg_urw_gothic_l, /* 7 a010035l */ urw_svg_urw_gothic_l, /* 8 b018012l */ urw_svg_urw_bookman_l, /* 9 b018032l */ urw_svg_urw_bookman_l, /* 10 b018015l */ urw_svg_urw_bookman_l, /* 11 b018035l */ urw_svg_urw_bookman_l, /* 12 n022003l */ urw_svg_nimbus_mono_l, /* 13 n022023l */ urw_svg_nimbus_mono_l, /* 14 n022004l */ urw_svg_nimbus_mono_l, /* 15 n022024l */ urw_svg_nimbus_mono_l, /* 16 n019003l */ urw_svg_nimbus_sans_l, /* 17 n019023l */ urw_svg_nimbus_sans_l, /* 18 n019004l */ urw_svg_nimbus_sans_l, /* 19 n019024l */ urw_svg_nimbus_sans_l, /* 20 n019043l */ urw_svg_nimbus_sans_condensed, /* 21 n019063l */ urw_svg_nimbus_sans_condensed, /* 22 n019044l */ urw_svg_nimbus_sans_condensed, /* 23 n019064l */ urw_svg_nimbus_sans_condensed, /* 24 c059013l */ urw_svg_century_schoolbook_l, /* 25 c059033l */ urw_svg_century_schoolbook_l, /* 26 c059016l */ urw_svg_century_schoolbook_l, /* 27 c059036l */ urw_svg_century_schoolbook_l, /* 28 p052003l */ urw_svg_urw_palladio_l, /* 29 p052023l */ urw_svg_urw_palladio_l, /* 30 p052004l */ urw_svg_urw_palladio_l, /* 31 p052024l */ urw_svg_urw_palladio_l, /* 32 s050000l */ urw_svg_standard_symbols_l, /* 33 z003034l */ urw_svg_urw_chancery_l, /* 34 d050000l */ urw_svg_dingbats }; /** File name used when processing standard input. */ static char name_stdin[] = { "standard input" }; /** Link keyword: xlink:href */ static char *xlc00[] = { "xlink:href", NULL }; /** Link keyword: xlink:type */ static char *xlc01[] = { "xlink:type", NULL }; /** Link keyword: xlink:role */ static char *xlc02[] = { "xlink:role", NULL }; /** Link keyword: xlink:arcrole */ static char *xlc03[] = { "xlink:arcrole", NULL }; /** Link keyword: xlink:title */ static char *xlc04[] = { "xlink:title", NULL }; /** Link keyword: xlink:show */ static char *xlc05[] = { "xlink:show", NULL }; /** Link keyword: xlink:actuate */ static char *xlc06[] = { "xlink:actuate", NULL }; /** Array containing all link keywords. */ static char **xlcmds[] = { xlc00, xlc01, xlc02, xlc03, xlc04, xlc05, xlc06, NULL }; /** Number of elements in the xlcmds array. */ static size_t sz_xlcmds = (sizeof(xlcmds)/sizeof(PPCHAR)) - 1; /** Suffixes for compressed files. */ static char *suffix_types[] = { (char *)".gz", (char *)".bz2", NULL }; /** Hexadecimal digits. */ static char hex_digits[] = { "0123456789ABCDEF" }; /** Conversion factor from pt to bp. */ static double pt_to_bp = DKFIG_BP_PER_INCH / DKFIG_PT_PER_INCH; /** Default text for hex encoded character output. */ static char default_encoding[] = { "&#x ;" }; /** Compare two values. */ #define COMPARE(a,b) ((a > b) ? 1 : ((a < b) ? -1 : 0)) /** Restrict number of digits after decimal dot, use downward rounding. @param x Value to correct. @param dig Number of digits after decimal dot. @return Rounding result. */ static double round_down_digits DK_P2(double,x,unsigned,dig) { double back, newval; unsigned cc, didcc; int errc; $? "+ round_down_digits %lf %u", x, dig newval = back = x; cc = dig; didcc = 0; errc = 0; while (cc--) { newval = dkma_mul_double_ok(back, 10.0, &errc); if (errc) { cc = 0; } else { back = newval; didcc++; } } back = floor(back); while (didcc--) { back = back / 10.0; } $? "- round_down_digits %lf", back return back; } /** Compare two pattern information structures. @param l Left pattern information structure. @param r Right pattern information structure. @param cr Comparison criteria (ignored). @return Comparison result. */ int dkfig_svg_comp_pat DK_P3(void *,l, void *,r, int,cr) { int back = 0; SVGPAT *lp, *rp; $? "+ dkfig_svg_comp_pat %s %s %d", TR_PTR(l), TR_PTR(r), cr lp = (SVGPAT *)l; rp = (SVGPAT *)r; switch(cr) { case 1: { } break; default: { if(l) { if(r) { back = COMPARE((lp->flags),(rp->flags)) ; if(!back) { back = COMPARE((lp->pattp),(rp->pattp)) ; } /* if(!back) { back = COMPARE((lp->lw),(rp->lw)) ; } */ if(!back) { back = COMPARE((lp->patrp),(rp->patrp)) ; } if(!back) { back = COMPARE((lp->sred),(rp->sred)) ; } if(!back) { back = COMPARE((lp->sgreen),(rp->sgreen)) ; } if(!back) { back = COMPARE((lp->sblue),(rp->sblue)) ; } if((!back) && ((lp->flags) & 1UL)) { back = COMPARE((lp->fred),(rp->fred)) ; } if((!back) && ((lp->flags) & 1UL)) { back = COMPARE((lp->fgreen),(rp->fgreen)) ; } if((!back) && ((lp->flags) & 1UL)) { back = COMPARE((lp->fblue),(rp->fblue)) ; } } else { back = 1; } } else { if(r) { back = -1; } } } break; } $? "- dkfig_svg_comp_pat %d", back return back; } /** Destroy pattern information structure. @param p Pattern information structure to destroy. */ static void svg_pat_del DK_P1(SVGPAT *,p) { $? "+ svg_pat_del %s", TR_PTR(p) if(p) { $? ". patno = %lu", p->patno $? ". flags = %lu", p->flags $? ". patrp = %ld", p->patrp $? ". pattp = %d", p->pattp $? ". sred = %d", p->sred $? ". sgreen = %d", p->sgreen $? ". sblue = %d", p->sblue $? ". fred = %d", p->fred $? ". fgreen = %d", p->fgreen $? ". fblue = %d", p->fblue DK_MEMRES(p,sizeof(SVGPAT)) ; dk_delete(p); } $? "- svg_pat_del" } /** Initialize pattern information structure. @param p Pattern information structure to initialize. */ static void svg_pat_null DK_P1(SVGPAT *,p) { $? "+ svg_pat_null %s", TR_PTR(p) if(p) { DK_MEMRES(p,sizeof(SVGPAT)) ; $? ". patno = %lu", p->patno $? ". flags = %lu", p->flags $? ". patrp = %ld", p->patrp $? ". pattp = %d", p->pattp $? ". sred = %d", p->sred $? ". sgreen = %d", p->sgreen $? ". sblue = %d", p->sblue $? ". fred = %d", p->fred $? ". fgreen = %d", p->fgreen $? ". fblue = %d", p->fblue } $? "- svg_pat_null" } /** Create a tolerance value to compare two double values. @param d1 One value in comparison. @param d2 Other value in comparison. @return Comparison epsilon. */ static double create_epsilon DK_P2(double,d1, double,d2) { double back = 0.000001; double x1, x2, min; x1 = fabs(d1); x2 = fabs(d2); min = x1; if(x2 < x1) { min = x2; } back = min * 0.000001; return back; } /** Compare two style information structures. @param l Left style information structure. @param r Right style information structure. @param cr Comparison criteria (ignored). @return Comparison result. */ int dkfig_svg_comp_style DK_P3(void *,l, void *,r, int,cr) { int back = 0; SVGSTY *lp, *rp; $? "+ dkfig_svg_comp_style" lp = (SVGSTY *)l; rp = (SVGSTY *)r; switch(cr) { case 1: { $? ". cr = 1" } break; default: { if(l) { if(r) { $? ". lp->flags = %ld rp->flags = %ld", lp->flags, rp->flags if(!back) { back = COMPARE((lp->flags),(rp->flags)) ; } $? ". left stroke = %d %d %d", lp->sred, lp->sgreen, lp->sblue $? ". right stroke = %d %d %d", rp->sred, rp->sgreen, rp->sblue $? ". left fill = %d %d %d", lp->fred, lp->fgreen, lp->fblue $? ". right fill = %d %d %d", rp->fred, rp->fgreen, rp->fblue if((lp->flags) & DKFIG_SVG_FL_TEXT) { $? ". text object" if(!back) { back = COMPARE((lp->sred),(rp->sred)) ; } if(!back) { back = COMPARE((lp->sgreen),(rp->sgreen)) ; } if(!back) { back = COMPARE((lp->sblue),(rp->sblue)) ; } /* 2004/11/22 Bugfix: The following comparisons must be executed only if there is no comparison result yet! */ if(!back) { if(lp->fonth) { if(rp->fonth) { back = dkfig_fnt_comp_fonth( (void *)(lp->fonth),(void *)(rp->fonth), 0 ); $? ". dkfig_fnt_comp_fonth -> %d", back } else { back = 1; } } else { if(rp->fonth) { back = -1; } } } if(!back) { if(lp->talign > rp->talign) { back = 1; } else { if(lp->talign < rp->talign) { back = -1; } } } } else { $? ". non-text object" if((lp->flags) & DKFIG_SVG_FL_STROKE) { if(!back) { back = COMPARE((lp->lw),(rp->lw)) ; } if(!back) { back = COMPARE((lp->ls),(rp->ls)) ; } if(!back) { back = COMPARE((lp->lc),(rp->lc)) ; } if(!back) { back = COMPARE((lp->lj),(rp->lj)) ; } if(!back) { back = COMPARE((lp->sred),(rp->sred)) ; } if(!back) { back = COMPARE((lp->sgreen),(rp->sgreen)) ; } if(!back) { back = COMPARE((lp->sblue),(rp->sblue)) ; } if(!back) { double epsilon; epsilon = create_epsilon(lp->sv, rp->sv); if(lp->sv > (rp->sv + epsilon)) { back = 1; } else { if(rp->sv > (lp->sv + epsilon)) { back = -1; } } } } if((!back) && ((lp->flags) & DKFIG_SVG_FL_FILL)) { if(lp->pat) { if(rp->pat) { back = dkfig_svg_comp_pat((void *)(lp->pat),(void *)(rp->pat), 0); } else { back = 1; } } else { if(rp->pat) { back = -1; } else { back = COMPARE((lp->fred),(rp->fred)) ; if(!back) { back = COMPARE((lp->fgreen),(rp->fgreen)) ; } if(!back) { back = COMPARE((lp->fblue),(rp->fblue)) ; } } } } } } else { back = -1; } } else { if(r) { back = -1; } } } break; } $? "- dkfig_svg_comp_style %d", back return back; } /** Destroy style information structure. @param s Style information structure to destroy. */ static void svg_style_del DK_P1(SVGSTY *,s) { $? "+ svg_style_del %s", TR_PTR(s) if(s) { $? ". classno = %lu", s->classno $? ". flags = %lu", s->flags $? ". lw = %ld", s->lw $? ". sred = %d", s->sred $? ". sgreen = %d", s->sgreen $? ". sblue = %d", s->sblue $? ". fred = %d", s->fred $? ". sgreen = %d", s->sgreen $? ". sblue = %d", s->sblue $? ". pattern = %s", TR_PTR(s->pat) DK_MEMRES(s,sizeof(SVGSTY)) ; dk_delete(s); } $? "- svg_style_del" } /** Initialize a style information structure. @param s Style information structure. */ static void svg_style_null DK_P1(SVGSTY *,s) { if(s) { DK_MEMRES(s,sizeof(SVGSTY)) ; s->pat = NULL; s->fonth = NULL; s->sv = 1.0; } } /** Compare two attribute structures or compare one structure against a class id. @param l Left attribute to compare. @param r Right attribute to compare. @param cr Comparison criteria (ignored). @return Comparison result. */ int dkfig_svg_comp_attr DK_P3(void *,l, void *,r, int,cr) { int back = 0; dk_fig_svg_attr *lp, *rp; int *ip; if(l) { if(r) { lp = (dk_fig_svg_attr *)l; switch(cr) { case 1: { /* search for classid */ ip = (int *)r; if((lp->classid) > *ip) { back = 1; } else { if((lp->classid) < *ip) { back = -1; } } } break; default: { /* compare by classid */ rp = (dk_fig_svg_attr *)r; if((lp->classid) > (rp->classid)) { back = 1; } else { if((lp->classid) < (rp->classid)) { back = -1; } } } break; } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Destroy attribute structure, release memory associated with it. @param a Attribute structure to destroy. */ static void dkfig_svg_attr_del DK_P1(dk_fig_svg_attr *,a) { char *ptr; $? "+ dkfig_svg_attr_del" if(a) { if(a->value) { ptr = a->value; $? ". %d %s", a->classid, TR_STR(ptr) dk_delete(ptr); a->value = NULL; } dk_delete(a); } $? "- dkfig_svg_attr_del" } /** Create new attribute structure, initialize it. @param clid Class ID. @param v Attribute value. @return Pointer to new structure on success, NULL on error. */ static dk_fig_svg_attr * dkfig_svg_attr_new DK_P2(int,clid, char *,v) { dk_fig_svg_attr *back = NULL; $? "+ dkfig_svg_attr_new %d %s", clid, TR_STR(v) if(v) { back = dk_new(dk_fig_svg_attr,1); if(back) { back->classid = clid; back->value = dkstr_dup(v); if(!(back->value)) { dkfig_svg_attr_del(back); back = NULL; } } } $? "- dkfig_svg_attr_new %s", TR_PTR(back) return back; } /** Write one keyword from the list. @param oi OI structure. @param kn Index of keyword in \arg kw array. @return 1 on success, 0 on error. */ static int kw_out DK_P2(OI *,oi,size_t,kn) { int back = 0; if(kn < kw_num) { dkstream_puts(oi->s, kw[kn]); back = 1; } return back; } /** Put double to output. @param oi OI structure. @param x Value to write. @param w Number of digits after decimal dot. */ static void put_double DK_P3(OI *,oi, double,x, int,w) { dkstream_puts_double(oi->s, drd(x, oi->c, w)); } /** Convert double value coordinate x to SVG. @param oi OI structure. @param x Value to convert. @return Converted value. */ static double ccdx DK_P2(OI *,oi, double,x) { double back; back = dkma_add_double_ok( dkma_mul_double_ok(oi->mx, x, &(oi->me)), oi->nx, &(oi->me) ); return back; } /** Convert double value coordinate y to SVG. @param oi OI structure. @param y Value to convert. @return Converted value. */ static double ccdy DK_P2(OI *,oi, double,y) { double back; back = dkma_add_double_ok( dkma_mul_double_ok(oi->my, y, &(oi->me)), oi->ny, &(oi->me) ); return back; } /** Convert double value coordinate radius to SVG. @param oi OI structure. @param r Value to convert. @return Converted value. */ static double ccdr DK_P2(OI *,oi, double,r) { double back; back = dkma_mul_double_ok(oi->mx, r, &(oi->me)); return back; } /** Convert double value coordinate (line width) to SVG. @param oi OI structure. @param w Value to convert. @param use_enl Enlighten look (apply factor 1/2). @return Converted value. */ static double ccdl DK_P3(OI *,oi, double,w, int,use_enl) { double back; back = 0.9 * w; if(use_enl) { if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { back = 0.5 * back; } } return back; } /** Convert long value coordinate x to SVG. @param oi OI structure. @param x Value to convert. @return Converted value. */ static double cclx DK_P2(OI *,oi, long,x) { double back; back = ccdx(oi, dkma_l_to_double(x)); return back; } /** Convert long value coordinate y to SVG. @param oi OI structure. @param y Value to convert. @return Converted value. */ static double ccly DK_P2(OI *,oi, long,y) { double back; back = ccdy(oi, dkma_l_to_double(y)); return back; } /** Convert long value coordinate (radius) to SVG. @param oi OI structure. @param r Value to convert. @return Converted value. */ static double cclr DK_P2(OI *,oi, long,r) { double back; back = ccdr(oi, dkma_l_to_double(r)); return back; } /** Convert long value coordinate (line width) to SVG. @param oi OI structure. @param w Value to convert. @param use_enl Flag: Enlighten look (apply factor 1/2). @return Converted value. */ static double ccll DK_P3(OI *,oi, long,w, int,use_enl) { double back; back = ccdl(oi, dkma_l_to_double(w), use_enl); return back; } /** Initialize DRVE structure. @param p Pointer to structure. */ static void svg_drve_init DK_P1(dk_fig_svg_drve *,p) { $? "+ svg_drve_init" if(p) { p->st1 = p->st2 = p->st3 = NULL; p->attr = NULL; p->attri = NULL; p->xl = NULL; p->xli = NULL; } $? "- svg_drve_init" } /** Free memory, check pointer before freeing. */ #define MEMFREE(x) if(x) { ptr = x; dk_delete(ptr); } x = NULL; /** Destroy DRVE structure, release memory associated with it. @param p DRVE structure to destroy. */ static void svg_drve_delete DK_P1(dk_fig_svg_drve *,p) { dk_fig_svg_attr *a; $? "+ svg_drve_delete" if(p) { p->st1 = p->st2 = p->st3 = NULL; if(p->attri) { $? ". remove object properties" dksto_it_reset(p->attri); while((a = (dk_fig_svg_attr *)dksto_it_next(p->attri)) != NULL) { dkfig_svg_attr_del(a); } dksto_it_close(p->attri); } p->attri = NULL; if(p->attr) { dksto_close(p->attr); } p->attr = NULL; if(p->xli) { $? ". remove link properties" dksto_it_reset(p->xli); while((a = (dk_fig_svg_attr *)dksto_it_next(p->xli)) != NULL) { dkfig_svg_attr_del(a); } dksto_it_close(p->xli); } p->xli = NULL; if(p->xl) { dksto_close(p->xl); } p->xl = NULL; dk_delete(p); } $? "- svg_drve_delete" } /** Create new DRVE structure, initialize it. @return Pointer to new DRVE structure on success, NULL on error. */ static dk_fig_svg_drve * svg_drve_new DK_P0() { dk_fig_svg_drve *back = NULL; $? "+ svg_drve_new" back = dk_new(dk_fig_svg_drve,1); if(back) { svg_drve_init(back); } $? "- svg_drve_new %s", TR_PTR(back) return back; } /** Add a xlink:xxx="xxx" attribute to DRVE. @param oi OI structure. @param dr DRVE structure. @param clid Class ID. @param v Value for entry. @return 1 on success, 0 on error. */ static int svg_drve_add_xla DK_P4(OI *,oi, dk_fig_svg_drve *,dr, int,clid, char *,v) { int back = 0; dk_fig_svg_attr *a; char *nn; $? "+ svg_drve_add_xla" if(dr) { if(!(dr->xl)) { dr->xl = dksto_open(0); if(dr->xl) { dksto_set_comp(dr->xl, dkfig_svg_comp_attr, 0); } } if(dr->xl) { if(!(dr->xli)) { dr->xli = dksto_it_open(dr->xl); } if(dr->xli) { if(v) { a = (dk_fig_svg_attr *)dksto_it_find_like( dr->xli, (void *)(&clid), 1 ); if(a) { nn = dkstr_dup(v); if(nn) { if(a->value) { char *ptr; ptr = a->value; /* WARNING: Already defined */ dkfig_tool2_msg3(oi->c, DK_LOG_LEVEL_WARNING, 93, 92, (xlcmds[clid])[0]); dk_delete(ptr); a->value = NULL; } a->value = nn; back = 1; } } else { a = dkfig_svg_attr_new(clid, v); if(a) { $? ". attribute structure ok" if(dksto_add(dr->xl, (void *)a)) { back = 1; $? ". attribute added successfully" } else { $? "! failed to add attribute" dkfig_svg_attr_del(a); } } } } } } } $? "- svg_drve_add_xla %d", back return back; } /** Add attribute to DRVE. @param oi OI structure. @param dr DRVE structure. @param clid Class ID. @param v Value for attribute. @return 1 on success, 0 on error. */ static int svg_drve_add_attr DK_P4(OI *,oi, dk_fig_svg_drve *,dr, int,clid, char *,v) { int back = 0; dk_fig_svg_attr *a; char *nn; $? "+ svg_drve_add_attr %s %d %s", TR_PTR(dr), clid, TR_STR(v) if(dr) { if(!(dr->attr)) { $? ". must create storage" dr->attr = dksto_open(0); if(dr->attr) { $? ". storage created" dksto_set_comp(dr->attr, dkfig_svg_comp_attr, 0); } } if(dr->attr) { $? ". storage ok" if(!(dr->attri)) { $? ". must create iterator" dr->attri = dksto_it_open(dr->attr); } if(dr->attri) { $? ". iterator ok" if(v) { $? ". value ok" a = (dk_fig_svg_attr *)dksto_it_find_like( dr->attri, (void *)(&clid), 1 ); if(a) { nn = dkstr_dup(v); if(nn) { if(a->value) { char *ptr; $? "! removing old value %s", TR_STR(a->value) /* WARNING: Already defined */ dkfig_tool2_msg3(oi->c, DK_LOG_LEVEL_WARNING, 93, 92, (cmds[clid])[0]); ptr = a->value; dk_delete(ptr); a->value = NULL; } a->value = nn; back = 1; } } else { a = dkfig_svg_attr_new(clid, v); if(a) { $? ". attribute structure ok" if(dksto_add(dr->attr, (void *)a)) { back = 1; $? ". attribute added successfully" } else { $? "! failed to add attribute" dkfig_svg_attr_del(a); } } } } } } } $? "- svg_drve_add_attr %d", back return back; } /** Start a new SVG tag. @param oi OI structure. @param n Index of tag name in kw array. */ static void begin_tag DK_P2(OI *,oi, size_t,n) { $? "+ begin_tag %lu", (unsigned long)n kw_out(oi, 2); if(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED) { kw_out(oi, 5); kw_out(oi, 24); } kw_out(oi, n); $? "- begin_tag" } /** Finish an SVG tag. @param oi OI structure. */ static void finish_tag DK_P1(OI *,oi) { $? "+ finish_tag" kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); $? "- finish_tag" } /** Write a closing SVG tag. @param oi OI structure. @param n Index of tag name in kw array. */ static void end_tag DK_P2(OI *,oi, size_t,n) { $? "+ end_tag %lu", (unsigned long)n kw_out(oi, 2); kw_out(oi, 4); if(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED) { kw_out(oi, 5); kw_out(oi, 24); } kw_out(oi, n); kw_out(oi, 3); kw_out(oi, 0); $? "- end_tag" } /** Reset OI structure. @param oi OI structure. */ static void null_oi DK_P1(OI *,oi) { $? "+ null_oi" oi->c = NULL; oi->d = NULL; oi->s = NULL; oi->dro = NULL; oi->xmin = oi->xmax = oi->ymin = oi->ymax = 0L; oi->mx = oi->nx = oi->my = oi->ny = 0.0; oi->me = 0; oi->fl = NULL; oi->fli = NULL; oi->pat = NULL; oi->pati = NULL; oi->sty = NULL; oi->styi = NULL; oi->o = NULL; oi->jsl = NULL; oi->jsli = NULL; oi->njsl = 0UL; oi->spcp = 0; oi->errprinted = 0; oi->npat = oi->nsty = 0UL; oi->lpat = oi->lsty = (size_t)0; oi->urw_dir = NULL; oi->fnused = NULL; oi->prep_mods = 0; oi->spcpass = 0; oi->fontmap = NULL; $? "- null_oi" } /** Calculate coefficients for transformations. @param oi OI structure. @return 1 on success, 0 on error. */ static int establish_coord_transformation DK_P1(OI *,oi) { int back = 1; double xmin, xmax, ymin, ymax, cxmin, cxmax, cymin, cymax; $? "+ establish_coord_transformation" oi->me = 0; /* Get minima and maxima in Fig resolution. */ xmin = dkfig_tool_bb_get_xmin(&(oi->d->dbb)); xmax = dkfig_tool_bb_get_xmax(&(oi->d->dbb)); ymin = dkfig_tool_bb_get_ymin(&(oi->d->dbb)); ymax = dkfig_tool_bb_get_ymax(&(oi->d->dbb)); /* Set scale factors to switch from Fig resolution to normal resolution. */ oi->mx = dkma_div_double_ok( 72.0, (oi->d)->fres, &(oi->me)); oi->my = oi->mx; if(!dkfig_tool_invert_y(oi->d)) { oi->my = 0.0 - oi->my; } $? ". mx=%lg my=%lg", oi->mx, oi->my /* Calculate minima and maxima after resolution change. */ xmin = dkma_mul_double_ok(xmin, oi->mx, &(oi->me)); xmax = dkma_mul_double_ok(xmax, oi->mx, &(oi->me)); ymin = dkma_mul_double_ok(ymin, oi->my, &(oi->me)); ymax = dkma_mul_double_ok(ymax, oi->my, &(oi->me)); /* Maximum/minimum swap if necessary. */ if(xmax < xmin) { cxmin = xmin; xmin = xmax; xmax = cxmin; } if(ymax < ymin) { cxmin = ymin; ymin = ymax; ymax = cxmin; } /* Change to int values. */ $? ". cxmin=%lg cxmax=%lg cymin=%lg cymax=%lg", cxmin,cxmax,cymin,cymax if(((oi->c)->svgs) == DKFIG_SVG_VP_INCHES) { /* Rounding in multiples of 9 produces 1/8 inch. So width/height specification in inches is restricted to 3 digits after decimal dot. */ $? ". xmin=%lg xmax=%lg ymin=%lg ymax=%lg", xmin,xmax,ymin,ymax cxmin = dkma_mul_double_ok(9.0, floor(xmin/9.0), &(oi->me)); cymin = dkma_mul_double_ok(9.0, floor(ymin/9.0), &(oi->me)); cxmax = dkma_mul_double_ok(9.0, ceil(xmax/9.0), &(oi->me)); cymax = dkma_mul_double_ok(9.0, ceil(ymax/9.0), &(oi->me)); $? ". cxmin=%lg cxmax=%lg cymin=%lg cymax=%lg", cxmin,cxmax,cymin,cymax } else { /* Simple rounding if no inches. */ cxmin = floor(xmin); cxmax = ceil(xmax); cymin = floor(ymin); cymax = ceil(ymax); } $? ". cxmin=%lg cxmax=%lg cymin=%lg cymax=%lg", cxmin,cxmax,cymin,cymax $? ". cxmin=%lg cxmax=%lg cymin=%lg cymax=%lg", cxmin/72.0, cxmax/72.0, cymin/72.0, cymax/72.0 /* Calculate shiftings. First move xmin to 0, add half of the empty space to get figure centered in output file. */ oi->nx = dkma_add_double_ok( dkma_sub_double_ok(0.0, xmin, &(oi->me)), (0.5 * dkma_sub_double_ok( dkma_sub_double_ok(cxmax, cxmin, &(oi->me)), dkma_sub_double_ok(xmax, xmin, &(oi->me)), &(oi->me) )), &(oi->me) ); oi->ny = dkma_add_double_ok( dkma_sub_double_ok(0.0, ymin, &(oi->me)), (0.5 * dkma_sub_double_ok( dkma_sub_double_ok(cymax, cymin, &(oi->me)), dkma_sub_double_ok(ymax, ymin, &(oi->me)), &(oi->me) )), &(oi->me) ); $? ". nx=%lg ny=%lg", oi->nx, oi->ny $? ". ymin -> %lg ", dkfig_tool_bb_get_ymin(&(oi->d->dbb)) * oi->my + oi->ny $? ". ymax -> %lg ", dkfig_tool_bb_get_ymax(&(oi->d->dbb)) * oi->my + oi->ny oi->xmin = 0L; oi->ymin = 0L; oi->xmax = dkma_double_to_l(ceil(dkma_sub_double_ok(cxmax, cxmin, &(oi->me)))); oi->ymax = dkma_double_to_l(ceil(dkma_sub_double_ok(cymax, cymin, &(oi->me)))); if(oi->me) { back = 0; } $? "- establish_coord_transformation %d", back return back; } /** Decide how to process an object. 0 = "normal" object (polyline/polygon, spline, arc, ellipse) 1 = text object 2 = included image. @param o Fig object. @return Selection how to process the object. */ static int get_how DK_P1(dk_fig_object *,o) { int back = 0; if(o->objtype == DK_FIG_OBJ_TEXT) { back = 1; } if((o->objtype == DK_FIG_OBJ_POLYLINE) && (o->subtype == 5)) { back = 2; } return back; } /** Register pattern. Return a pointer to an existing pattern in the pattern collection or add a new pattern to the collection. @param oi OI structure. @param src SVG pattern (source). @return Pointer to existing or new pattern structure or NULL on error. */ static SVGPAT * svg_pat_register DK_P2(OI *,oi, SVGPAT *,src) { SVGPAT *back = NULL; $? "+ svg_pat_register %s %s", TR_PTR(oi), TR_PTR(src) $? ". patno = %lu", src->patno $? ". flags = %lu", src->flags $? ". patrp = %ld", src->patrp $? ". pattp = %d", src->pattp $? ". sred = %d", src->sred $? ". sgreen = %d", src->sgreen $? ". sblue = %d", src->sblue $? ". fred = %d", src->fred $? ". fgreen = %d", src->fgreen $? ". fblue = %d", src->fblue back = (dk_fig_svg_pat *)dksto_it_find_like(oi->pati, (void *)src, 0); if(!back) { $? ". must build new pattern" back = dk_new(SVGPAT,1); if(back) { $? ". new pattern ok" $? ". patno = %lu", src->patno $? ". flags = %lu", src->flags $? ". patrp = %ld", src->patrp $? ". pattp = %d", src->pattp $? ". sred = %d", src->sred $? ". sgreen = %d", src->sgreen $? ". sblue = %d", src->sblue $? ". fred = %d", src->fred $? ". fgreen = %d", src->fgreen $? ". fblue = %d", src->fblue DK_MEMCPY(back,src,sizeof(SVGPAT)) ; $? ". patno = %lu", back->patno $? ". flags = %lu", back->flags $? ". patrp = %ld", back->patrp $? ". pattp = %d", back->pattp $? ". sred = %d", back->sred $? ". sgreen = %d", back->sgreen $? ". sblue = %d", back->sblue $? ". fred = %d", back->fred $? ". fgreen = %d", back->fgreen $? ". fblue = %d", back->fblue if(!dksto_add(oi->pat, (void *)back)) { $? "! failed to add new pattern to list" dk_delete(back); back = NULL; } } } $? "- svg_pat_register %s", TR_PTR(back) return back; } /** Register an SVG style in the style collection. Create a new entry in the collection if necessary or return pointer to an existing entry. @param oi OI structure. @param st SVG style information structure. @return Pointer to exisiting or new style information structure or NULL on error. */ static SVGSTY * svg_style_register DK_P2(OI *,oi, SVGSTY *,st) { SVGSTY *back = NULL; $? "+ svg_style_register %s %s", TR_PTR(oi), TR_PTR(st) back = (dk_fig_svg_style *)dksto_it_find_like(oi->styi, (void *)st, 0); if(!back) { $? ". must build new style" back = dk_new(SVGSTY,1); if(back) { $? ". new style ok" DK_MEMCPY(back,st,sizeof(SVGSTY)) ; if(!dksto_add(oi->sty, (void *)back)) { $? "! failed to add new style to list" dk_delete(back); back = NULL; } } } $? ". st stroke %d %d %d", st->sred, st->sgreen, st->sblue $? ". st fill %d %d %d", st->fred, st->fgreen, st->fblue if(back) { $? ". back stroke %d %d %d", back->sred, back->sgreen, back->sblue $? ". back fill %d %d %d", back->fred, back->fgreen, back->fblue } $? "- svg_style_register %s", TR_PTR(back) return back; } /** Attach a new driver-specific extension to each drawing object. @param oi OI structure. @return 1 on success, 0 on error. */ static int attach_drve DK_P1(OI *,oi) { int back = 1; dk_fig_object *o; $? "+ attach_drve" dksto_it_reset(oi->fli); while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) { oi->o = o; $? ". next o, ls=%d", (o->fpd).ls if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, o->lineno); } o->drve = svg_drve_new(); if(!(o->drve)) { back = 0; $? "! memory" /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, 0UL); } } if(!((oi->dro)->drve)) { (oi->dro)->drve = svg_drve_new(); if(!((oi->dro)->drve)) { back = 0; /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } $? "- attach_drve %d", back return back; } /** Store the name of a file containing JavaScript code. @param oi OI structure. @param vptr File name. @return 1 on success, 0 on error. */ static int set_js_library DK_P2(OI *,oi, char *,vptr) { int back = 0; dk_fig_opt *fo; $? "+ set_js_library" if(vptr) { back = 1; if(!(oi->jsl)) { oi->jsl = dksto_open(0); if(oi->jsl) { dksto_set_comp(oi->jsl, dkfig_opt_compare, 0); } } if(oi->jsl) { if(!(oi->jsli)) { oi->jsli = dksto_it_open(oi->jsl); } if(oi->jsli) { fo = dkfig_opt_new(oi->njsl, vptr); oi->njsl += 1UL; if(fo) { if(!dksto_add(oi->jsl, (void *)fo)) { back = 0; dkfig_opt_delete(fo); fo = NULL; /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } else { back = 0; /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } else { back = 0; /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } else { back = 0; /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } $? "- set_js_library %d", back return back; } /** Save the name of the directory containing SVG fonts derived from the URW fonts. @param oi OI structure. @param vptr Directory name. @return 1 on success, 0 on error. */ static int set_urw_dir DK_P2(OI *,oi, char *,vptr) { int back = 0; char *cptr, *nn; if(vptr) { nn = dkstr_dup(vptr); if(nn) { back = 1; if(oi->urw_dir) { cptr = oi->urw_dir; dk_delete(cptr); oi->urw_dir = NULL; } oi->urw_dir = nn; } } return back; } /** Process one storage containing saved options from the configuration file to check for driver-specific options. There are separated storages for global options, for the base driver, the configuration-specific options and command line options. @param oi OI structure. @param it Iterator for storage to process. @return 1 on success, 0 on error. */ static int scan_it_options DK_P2(OI *,oi, dk_storage_iterator_t *,it) { int back = 1; dk_fig_opt *fo; char *buffer, *sptr, *vptr; size_t sz; char *parts[16]; size_t xsz; int i; $? "+ scan_it_options %s %s", TR_PTR(oi), TR_PTR(it) sz = 1 + ((oi->c)->lcfge); buffer = dk_new(char,sz); if(buffer) { dksto_it_reset(it); while((fo = (dk_fig_opt *)dksto_it_next(it)) != NULL) { if(fo->name) { $? ". fo->name=\"%s\"", TR_STR(fo->name) if((oi->c)->app) { $? ". fo->number=%lu", fo->number dkapp_set_source_lineno((oi->c)->app, fo->number); } if(strlen(fo->name) < sz) { $? ". strlen ok" strcpy(buffer, fo->name); vptr = sptr = NULL; vptr = dkstr_chr(buffer, '='); if(vptr) { $? ". vptr = \"%s\"", TR_STR(vptr) *vptr++ = '\0'; vptr = dkstr_start(vptr, NULL); if(vptr) { dkstr_chomp(vptr, NULL); } } sptr = dkstr_start(buffer, NULL); if(sptr) { $? ". sptr = \"%s\"", TR_STR(sptr) dkstr_chomp(sptr, NULL); xsz = sizeof(parts)/sizeof(PCHAR); if(dkstr_explode(parts,xsz,sptr,exploder_pattern)) { $? ". string explosion ok" i = dkstr_find_multi_part_abbr(parts, cmds, '$', 1); $? ". i=%d", i switch(i) { case 0: { /* js library */ back = set_js_library(oi, vptr); fo->used = 0x01; oi->prep_mods = 1; } break; case 21: { /* URW font directory */ back = set_urw_dir(oi, vptr); fo->used = 0x01; } break; } } } } } } dk_delete(buffer); buffer = NULL; sz = 0; } else { back = 0; if((oi->c)->app) { dkapp_err_memory((oi->c)->app, 1, sz); } } $? "- scan_it_options %d", back return back; } /** Re-read the saved options from the configuration file to process the driver-specific options. @param oi OI structure. @return 1 on success, 0 on error. */ static int scan_options DK_P1(OI *,oi) { int back = 1; char *oldsrcfile; unsigned long oldsrcno; $? "+ scan_options" if((oi->c)->app) { oldsrcfile = dkapp_get_source_filename((oi->c)->app); oldsrcno = dkapp_get_source_lineno((oi->c)->app); dkapp_set_source_filename((oi->c)->app, (oi->c)->cfgfn); dkapp_set_source_lineno((oi->c)->app, 0UL); } if(((oi->c)->optg) && ((oi->c)->optgi)) { if(!scan_it_options(oi, (oi->c)->optgi)) { back = 0; } } if(((oi->c)->optb) && ((oi->c)->optbi)) { if(!scan_it_options(oi, (oi->c)->optbi)) { back = 0; } } if(((oi->c)->optd) && ((oi->c)->optdi)) { if(!scan_it_options(oi, (oi->c)->optdi)) { back = 0; } } if((oi->c)->app) { dkapp_set_source_filename((oi->c)->app, NULL); } if(((oi->c)->opt) && ((oi->c)->opti)) { if(!scan_it_options(oi, (oi->c)->opti)) { back = 0; } } if((oi->c)->app) { dkapp_set_source_filename((oi->c)->app, oldsrcfile); dkapp_set_source_lineno((oi->c)->app, oldsrcno); } $? "- scan_options %d", back return back; } /** Handle special comments attached to an object. @param oi OI structure. @param obj Current object. @param it Iterator for special comments storage. @param docroot Flag: Processing document level comments (1). @param use_svg_spec Flag: Use SVG related special comments. @return 1 on success, 0 on error. */ static int handle_spc_for_object DK_P5(OI *,oi, dk_fig_object *,obj, dk_storage_iterator_t *,it, int,docroot, int,use_svg_spec) { int back = 1; dk_fig_opt *fo; char mybuffer[128], *parts[16], *myline, *lptr, *cptr, *vptr; size_t sz; int i; int handled; unsigned long oldsrcno = 0UL; $? "+ handle_spc_for_object docroot=%d, use_svg_spec=%d", docroot, use_svg_spec if((oi->c)->app) { oldsrcno = dkapp_get_source_lineno((oi->c)->app); } if(it) { dksto_it_reset(it); while((fo = (dk_fig_opt *)dksto_it_next(it)) != NULL) { if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, fo->number); } myline = NULL; handled = 0; if(fo->name) { sz = strlen(fo->name); if(sz < sizeof(mybuffer)) { strcpy(mybuffer, fo->name); lptr = mybuffer; } else { myline = dkstr_dup(fo->name); lptr = myline; } if(lptr) { cptr = dkfig_opt_special_comment_contents(lptr, kw[5]); if((cptr) && (use_svg_spec)) { vptr = dkstr_chr(cptr, '='); if(vptr) { *(vptr++) = '\0'; vptr = dkstr_start(vptr, NULL); if(vptr) { dkstr_chomp(vptr, NULL); } cptr = dkstr_start(cptr, NULL); if(cptr) { dkstr_chomp(cptr, NULL); sz = sizeof(parts)/sizeof(PCHAR); if(dkstr_explode(parts,sz,cptr,exploder_pattern)) { i = dkstr_find_multi_part_abbr(parts,cmds,'$',1); switch(i) { case -1: { /* not in cmds list */ int j; j = dkstr_find_multi_part_abbr(parts,xlcmds,'$',1); if(j > -1) { if(svg_drve_add_xla(oi, (DRVE *)(obj->drve), j, vptr)) { handled = 1; } else { back = 0; /* ERROR: MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } } break; case 0: { /* js library */ handled = 1; if(docroot) { $? ". adding js library %s", TR_STR(vptr) back = set_js_library(oi, vptr); oi->prep_mods = 1; } else { /* ERROR: Only in document level comments */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_WARNING, 94); } } break; case 21: { /* URW font directory */ back = set_urw_dir(oi, vptr); handled = 1; } break; default: { if(svg_drve_add_attr(oi, (DRVE *)(obj->drve), i, vptr)) { handled = 1; } else { back = 0; /* ERROR: MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } if((i >= 2) && (i <= 20)) { oi->prep_mods = 1; } } break; } } } } } } } if(myline) { dk_delete(myline); myline = NULL; } if(!handled) { i = dkfig_opt_process_special_comment(oi->c, fo->name, kw[5], docroot); if((oi->spcpass) == 0) { dkfig_tool2_report_special_comment(oi->c, fo, i); } } } } if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, oldsrcno); } $? "- handle_spc_for_object %d", back return back; } /** Process the document level special comments. @param oi OI structure. @return 1 on success, 0 on error. */ static int use_dlspc DK_P1(OI *,oi) { int back = 1; $? "+ use_dlspc" back = handle_spc_for_object(oi, oi->dro, (oi->d)->dlsci, 1, 1); $? "- use_dlscp %d", back return back; } /** Prepare each object for output. Create references to patterns and styles in the pattern and style collections, create new collection entries if necessary. @param oi OI structure. @return 1 on success, 0 on error. */ static int prepare_objects DK_P1(OI *,oi) { int back = 1; unsigned long backupopt1, backupopt2; int how, must_draw, backupia; dk_fig_object *o; SVGSTY style, *pstyle; SVGPAT pattern, *ppattern; dk_fig_dcc dcc; $? "+ prepare_objects" dksto_it_reset(oi->fli); while((oi->o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) { o = oi->o; if(back) { backupopt1 = (oi->c)->opt1; backupopt2 = (oi->c)->opt2; backupia = (oi->c)->image_align; if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, (oi->o)->lineno); } oi->me = 0; if((oi->o)->osci) { if(!handle_spc_for_object(oi, oi->o, (oi->o)->osci, 0, 1)) { back = 0; $? ". reset back" } } if(back) { how = 0; must_draw = 1; if(o->drve) { svg_style_null(&style); svg_pat_null(&pattern); how = get_how(o); switch(how) { case 1: { /* text */ dk_fig_text *t; svg_style_null(&style); style.flags = DKFIG_SVG_FL_TEXT; dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); /* 2004/11/22 style.fred = ... Fig files store the text color as pen color, SVG needs it as fill color. */ style.fred = style.sred = dcc.ired; style.fgreen = style.sgreen = dcc.igreen; style.fblue = style.sblue = dcc.iblue; $? ". colors r=%d g=%d b=%d", dcc.ired, dcc.igreen, dcc.iblue t = (dk_fig_text *)(o->data); if(t) { style.fonth = t->font_handling; } switch((style.fonth)->handling) { case 2: case 3: case 4: case 5: { if(!((oi->errprinted) & 1)) { dkfig_tool2_svg_error_message(oi, 85); if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) { oi->errprinted |= 1; } } } break; default: { style.talign = o->subtype; if((style.fonth)->fontno < 0) { (style.fonth)->fontno = 0; } if((style.fonth)->fontno > 35) { (style.fonth)->fontno = 35; } (oi->fnused)[(style.fonth)->fontno] = '+'; ((dk_fig_svg_drve *)(o->drve))->st1 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st1)) { back = 0; $? "! reset back" } else { SVGSTY *stptr; stptr = ((dk_fig_svg_drve *)(o->drve))->st1; $? ". colors r=%d g=%d b=%d", stptr->fred, stptr->fgreen, stptr->fblue } } break; } } break; case 2: { /* included image */ svg_style_null(&style); /* filling */ if(((oi->c)->opt1) & DKFIG_OPT_FILL_BITMAP_AREA) { if(dkfig_tool_must_fill((o->fpd).af, (oi->c)->opt1) || dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1)) { style.flags |= DKFIG_SVG_FL_FILL; dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).fc); dkfig_tool_correct_dcc(&dcc, (o->fpd).fc, (o->fpd).af); if(dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1) && ((o->fpd).pc != (oi->d)->transparent) && (((oi->c)->opt1) & DKFIG_OPT_FILL_PATTERNS)) { /* fill patterns */ svg_pat_null(&pattern); pattern.pattp = (o->fpd).af; /* pattern.lw = (o->fpd).lt; */ pattern.patrp = (oi->c)->patrp; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { pattern.flags |= DKFIG_SVG_FL_ENLIGHTEN; } if((o->fpd).fc != (oi->d)->transparent) { pattern.flags |= DKFIG_SVG_FL_FILL; pattern.fred = dcc.ired; pattern.fgreen = dcc.igreen; pattern.fblue = dcc.iblue; } pattern.flags |= DKFIG_SVG_FL_STROKE; dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); pattern.sred = dcc.ired; pattern.sgreen = dcc.igreen; pattern.sblue = dcc.iblue; style.pat = svg_pat_register(oi, &pattern); if(!(style.pat)) { back = 0; $? "! reset back" } } else { /* color fill */ style.fred = dcc.ired; style.fgreen = dcc.igreen; style.fblue = dcc.iblue; } ((dk_fig_svg_drve *)(o->drve))->st1 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st1)) { back = 0; $? "! reset back" } } } svg_style_null(&style); /* stroking */ must_draw = 1; if(o->objtype == DK_FIG_OBJ_POLYLINE) { if(o->subtype == 5) { if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BITMAP_BORDER) { must_draw = 0; } } } if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_THIN_BORDERS) { if((o->fpd).lt == 0L) { if((o->fpd).cl) { if(dkfig_tool_must_fill((o->fpd).af, (oi->c)->opt1)) { must_draw = 0; } if(dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1)) { must_draw = 0; } } } } if((o->fpd).pc == (oi->d)->transparent) { must_draw = 0; } if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BG_RECTANGLE) { int wbgr = 0; if(((oi->c)->opt2) & DKFIG_OPT_WHITE_BGRECT) { wbgr = 1; } if(dkfig_tool2_obj_is_bg_rect(oi->o, wbgr)) { must_draw = 0; } } $? ". must_draw=%d", must_draw if(must_draw) { dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); style.ls = (o->fpd).ls; $? ". ls=%d", style.ls style.lw = (o->fpd).lt; style.sred = dcc.ired; style.sgreen = dcc.igreen; style.sblue = dcc.iblue; style.flags |= DKFIG_SVG_FL_STROKE; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { style.flags |= DKFIG_SVG_FL_ENLIGHTEN; } style.sv = (o->fpd).sv; style.lc = (o->fpd).cs; style.lj = (o->fpd).js; ((dk_fig_svg_drve *)(o->drve))->st2 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st2)) { back = 0; $? "! reset back" } } } break; default: { /* regular path object */ svg_style_null(&style); /* filling */ if(dkfig_tool_must_fill((o->fpd).af, (oi->c)->opt1) || dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1)) { style.flags |= DKFIG_SVG_FL_FILL; dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).fc); dkfig_tool_correct_dcc(&dcc, (o->fpd).fc, (o->fpd).af); if(dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1) && ((o->fpd).pc != (oi->d)->transparent)) { /* fill patterns */ svg_pat_null(&pattern); pattern.pattp = (o->fpd).af; /* pattern.lw = (o->fpd).lt; */ pattern.patrp = (oi->c)->patrp; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { pattern.flags |= DKFIG_SVG_FL_ENLIGHTEN; } if((o->fpd).fc != (oi->d)->transparent) { pattern.flags |= DKFIG_SVG_FL_FILL; pattern.fred = dcc.ired; pattern.fgreen = dcc.igreen; pattern.fblue = dcc.iblue; } pattern.flags |= DKFIG_SVG_FL_STROKE; dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); pattern.sred = dcc.ired; pattern.sgreen = dcc.igreen; pattern.sblue = dcc.iblue; style.pat = svg_pat_register(oi, &pattern); if(!(style.pat)) { back = 0; $? "! reset back" } } else { /* color fill */ style.fred = dcc.ired; style.fgreen = dcc.igreen; style.fblue = dcc.iblue; } } /* stroking */ must_draw = 1; if(o->objtype == DK_FIG_OBJ_POLYLINE) { if(o->subtype == 5) { if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BITMAP_BORDER) { must_draw = 0; $? ". no draw" } } } if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_THIN_BORDERS) { if((o->fpd).lt == 0L) { if((o->fpd).cl) { if(dkfig_tool_must_fill((o->fpd).af, (oi->c)->opt1)) { must_draw = 0; $? ". no draw" } if(dkfig_tool_must_pattern((o->fpd).af, (oi->c)->opt1)) { must_draw = 0; $? ". no draw" } } } } if((o->fpd).pc == (oi->d)->transparent) { must_draw = 0; $? ". no draw" } if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BG_RECTANGLE) { int wbgr = 0; if(((oi->c)->opt2) & DKFIG_OPT_WHITE_BGRECT) { wbgr = 1; } if(dkfig_tool2_obj_is_bg_rect(oi->o, wbgr)) { must_draw = 0; } } $? ". must_draw=%d", must_draw if(must_draw) { $? ". must draw" dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); style.ls = (o->fpd).ls; $? ". ls=%d", (style.ls) style.lw = (o->fpd).lt; style.sred = dcc.ired; style.sgreen = dcc.igreen; style.sblue = dcc.iblue; style.flags |= DKFIG_SVG_FL_STROKE; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { style.flags |= DKFIG_SVG_FL_ENLIGHTEN; } style.sv = (o->fpd).sv; style.lc = (o->fpd).cs; style.lj = (o->fpd).js; } ((dk_fig_svg_drve *)(o->drve))->st1 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st1)) { back = 0; $? "! reset back" } if(((o->fpd).ar) & 1) { /* forward arrowhead */ svg_style_null(&style); dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); style.lw = (o->fpd).lt; style.sred = dcc.ired; style.sgreen = dcc.igreen; style.sblue = dcc.iblue; style.flags |= DKFIG_SVG_FL_STROKE; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { style.flags |= DKFIG_SVG_FL_ENLIGHTEN; } if(((o->fpd).ahf).type > 0) { style.flags |= DKFIG_SVG_FL_FILL; if(((o->fpd).ahf).style > 0) { style.fred = style.sred; style.fgreen = style.sgreen; style.fblue = style.sblue; } else { style.fred = style.fgreen = style.fblue = 255; } } style.lj = (oi->c)->ahlj; ((dk_fig_svg_drve *)(o->drve))->st2 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st2)) { back = 0; $? "! reset back" } } if(((o->fpd).ar) & 2) { /* backward arrowhead */ svg_style_null(&style); dkfig_tool_fill_dcc(oi->d, &dcc, (o->fpd).pc); style.lw = (o->fpd).lt; style.sred = dcc.ired; style.sgreen = dcc.igreen; style.sblue = dcc.iblue; style.flags |= DKFIG_SVG_FL_STROKE; if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) { style.flags |= DKFIG_SVG_FL_ENLIGHTEN; } if(((o->fpd).ahb).type > 0) { style.flags |= DKFIG_SVG_FL_FILL; if(((o->fpd).ahb).style > 0) { style.fred = style.sred; style.fgreen = style.sgreen; style.fblue = style.sblue; } else { style.fred = style.fgreen = style.fblue = 255; } } style.lj = (oi->c)->ahlj; ((dk_fig_svg_drve *)(o->drve))->st3 = svg_style_register(oi, &style); if(!(((dk_fig_svg_drve *)(o->drve))->st3)) { back = 0; $? "! reset back" } } } break; } } else { back = 0; $? "! reset back" /* MEMORY */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 11); } } if(oi->me) { /* MATH PROBLEM */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 13); } oi->me = 0; if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, 0UL); } (oi->c)->opt1 = backupopt1; (oi->c)->opt2 = backupopt2; (oi->c)->image_align = backupia; } } oi->spcpass = 1; if(back) { oi->npat = 0UL; dksto_it_reset(oi->pati); while((ppattern = (SVGPAT *)dksto_it_next(oi->pati)) != NULL) { ppattern->patno = oi->npat; oi->npat += 1UL; } oi->nsty = 0UL; dksto_it_reset(oi->styi); while((pstyle = (SVGSTY *)dksto_it_next(oi->styi)) != NULL) { pstyle->classno = oi->nsty; oi->nsty += 1UL; } oi->lpat = dkfig_dt_needed_alpha(oi->npat); $? ". lpat = %lu", (unsigned long)(oi->lpat) oi->lsty = dkfig_dt_needed_alpha(oi->nsty); $? ". lsty = %lu", (unsigned long)(oi->lsty) } $? "- prepare_objects %d", back return back; } /** Find compression type for file name. @param n File name. @return -1=not compressed, 0=gzip, 1=bzip2. */ static int compression_type DK_P1(char *,n) { int back = -1; char *suffixptr; suffixptr = dksf_get_file_type_dot(n); if(n) { back = dkstr_array_index(suffix_types, suffixptr, 0); } return back; } /** Open the font mapping file. @param oi OI structure. @param n File name of font mapping file. @return Pointer to stream structure to read file on success, NULL on error. */ static dk_stream_t * open_the_mapping_file DK_P2(OI *,oi, char *,n) { dk_stream_t *back = NULL; switch(compression_type(n)) { case 0: { #if DK_HAVE_ZLIB_H if((oi->c)->app) { back = dkapp_stream_opengz((oi->c)->app, n, str_mode_open_read); } else { back = dkstream_opengz(n, str_mode_open_read, 0, NULL); } #else dkapp_err_no_zlib_support_for((oi->c)->app, n); #endif } break; case 1: { #if DK_HAVE_BZLIB_H if((oi->c)->app) { back = dkapp_stream_openbz2((oi->c)->app, n, str_mode_open_read); } else { back = dkstream_openbz2(n, str_mode_open_read, 0, NULL); } #else dkapp_err_no_bzlib_support_for((oi->c)->app, n); #endif } break; default: { if((oi->c)->app) { back = dkapp_stream_openfile((oi->c)->app, n, str_mode_open_read); } else { back = dkstream_openfile(n, str_mode_open_read, 0, NULL); } } break; } return back; } /** Read font mapping. @param oi OI structure. @return 1 on success, 0 on error. */ static int get_fontmap DK_P1(OI *,oi) { int back = 0; dk_stream_t *st; char *fmname; size_t szfmname; $? "+ get_fontmap" szfmname = (size_t)dksf_get_maxpathlen(); fmname = dk_new(char,szfmname); if(fmname) { if((oi->c)->app) { if(dkapp_find_file((oi->c)->app, (oi->c)->fcfg, fmname, szfmname)) { $? ". font configuration file found %s", fmname oi->fontmap = dkfont_mapping_open(); if(oi->fontmap) { st = open_the_mapping_file(oi, fmname); if(st) { if(dkfont_mapping_add_stream(oi->fontmap, st)) { back = 1; $? ". everything ok" } else { char *oldsourcefilename; unsigned long oldsourcelineno; oldsourcefilename = dkapp_get_source_filename((oi->c)->app); oldsourcelineno = dkapp_get_source_lineno((oi->c)->app); dkapp_set_source_filename((oi->c)->app, fmname); dkapp_set_source_lineno((oi->c)->app, dkfont_get_error_lineno(oi->fontmap)); switch(dkfont_get_error_code(oi->fontmap)) { case DK_ERR_NOMEM: { dkfig_tool2_simple_error_message(oi->c, 11); } break; default: { dkfig_tool2_simple_error_message(oi->c, 12); } break; } dkapp_set_source_lineno((oi->c)->app, oldsourcelineno); dkapp_set_source_filename((oi->c)->app, oldsourcefilename); dkfont_mapping_close(oi->fontmap); oi->fontmap = NULL; } dkstream_close(st); } else { dkapp_err_fopenr((oi->c)->app, fmname); } } else { dkapp_err_memory((oi->c)->app, 1, 1); } back = 1; } else { dkapp_err_matchfile((oi->c)->app, (oi->c)->fcfg); } } else { oi->fontmap = dkfont_mapping_open(); if(oi->fontmap) { st = open_the_mapping_file(oi, (oi->c)->fcfg); if(st) { if(dkfont_mapping_add_stream(oi->fontmap, st)) { back = 1; } else { dkfont_mapping_close(oi->fontmap); oi->fontmap = NULL; } dkstream_close(st); } else { } } else { } } dk_delete(fmname); } else { if((oi->c)->app) { dkapp_err_memory((oi->c)->app, 1, szfmname); } } $? "- get_fontmap %d", back return back; } /** Prepare for output. @param oi OI structure. @return 1 on success, 0 on error. */ static int preparation_pass DK_P1(OI *,oi) { int back = 0; $? "+ preparation_pass" oi->fl = dkfig_flat_list(oi->c, (oi->c)->drwng); oi->pat = dksto_open(0); oi->sty = dksto_open(0); if((oi->fl) && (oi->pat) && (oi->sty)) { dksto_set_comp(oi->pat, dkfig_svg_comp_pat, 0); dksto_set_comp(oi->sty, dkfig_svg_comp_style, 0); oi->fli = dksto_it_open(oi->fl); oi->pati = dksto_it_open(oi->pat); oi->styi = dksto_it_open(oi->sty); if((oi->fli) && (oi->pati) && (oi->styi)) { if(attach_drve(oi)) { $? ". driver extensions attached" if(scan_options(oi)) { if(establish_coord_transformation(oi)) { if(use_dlspc(oi)) { $? ". dl special comments ok" dkfig_tool2_report_unused_options(oi->c); back = prepare_objects(oi); if((oi->c)->fcfg) { $? ". have fcfg" back = get_fontmap(oi); } else { $? ". no fcfg" back = 1; } } else { $? "! error while processing dl sp comments" } } else { $? "! error in coord transformation setup" } } else { $? "! option processing failed" } } else { $? "! failed to attach drve's" } } } $? "- preparation_pass %d", back return back; } /** Write the SVG document type. @param oi OI structure. */ static void svg_document_type DK_P1(OI *,oi) { $? "+ svg_document_type" switch((oi->c)->svgv) { case DKFIG_SVG_VERS_12: /* HIER NOCH SCHAUEN, WIE DEFINIERT ##### */ case DKFIG_SVG_VERS_10: { kw_out(oi, 6); kw_out(oi, 0); kw_out(oi, 2); kw_out(oi, 7); kw_out(oi, 1); kw_out(oi, 8); kw_out(oi, 0); kw_out(oi, 9); kw_out(oi, 0); kw_out(oi, 3); kw_out(oi, 0); } break; default: { kw_out(oi, 6); kw_out(oi, 0); kw_out(oi, 2); kw_out(oi, 7); kw_out(oi, 1); kw_out(oi, 12); kw_out(oi, 0); kw_out(oi, 13); kw_out(oi, 0); kw_out(oi, 3); kw_out(oi, 0); } break; } $? "- svg_document_type" } /** Print a length, maybee either in inches or pixels. @param oi OI structure. @param v Value to print. @param h Choose units (DKFIG_SVG_VP_xxx). @param w Index of "what" in kw array. */ static void print_lgt DK_P4(OI *,oi, double,v, int,h, size_t,w) { $? "+ print_lgt" kw_out(oi, w); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, v, 1); switch(h) { case DKFIG_SVG_VP_PIXELS: { kw_out(oi, 22); } break; case DKFIG_SVG_VP_INCHES: { kw_out(oi, 21); } break; } kw_out(oi, 20); $? "- print_lgt" } /** Print width of SVG either in inches or in pixels (without unit). @param oi OI structure. @param v Value to print. @param h Choose unit. */ static void print_width DK_P3(OI *,oi, double,v, int,h) { print_lgt(oi,v,h,16); $? "= print_width v=%lg h=%d", v, h } /** Print height of SVG either in inches or in pixels (without unit). @param oi OI structure. @param v Value to print. @param h Choose units. */ static void print_height DK_P3(OI *,oi, double,v, int,h) { print_lgt(oi,v,h,17); $? "= print_width v=%lg h=%d", v, h } /** Write data attached to the entire drawing. @param oi OI structure. @param o Fig object for entire drawing. @param drve Driver-specific extension data for entire drawing. @param isroot Flag: Is root object. @return 1 on success, 0 on error. */ static int svg_drve_write DK_P4(OI *,oi, dk_fig_object *,o, DRVE *,drve, int,isroot) { int back = 1; int i, is_first; dk_fig_svg_attr *a; char *ptr, **pptr; $? "+ svg_drve_write" is_first = 1; if(drve->attri) { for(i = 1; i < (int)sz_cmds; i++) { a = (dk_fig_svg_attr *)dksto_it_find_like(drve->attri, (void *)(&i), 1); if(a) { if(a->value) { if(is_first) { if(!isroot) { kw_out(oi, 0); } } pptr = cmds[i]; ptr = *pptr; dkstream_puts(oi->s, ptr); kw_out(oi, 19); kw_out(oi, 20); dkstream_puts(oi->s, a->value); kw_out(oi, 20); kw_out(oi, 0); is_first = 0; } } } } $? "- svg_drve_write %d", back return back; } /** Write opening SVG tag. @param oi OI structure. */ static void svg_start_tag DK_P1(OI *,oi) { double w, h, wp, hp; $? "+ svg_start_tag" begin_tag(oi, 5); kw_out(oi, 1); wp = dkma_sub_double_ok( dkma_l_to_double(oi->xmax), dkma_l_to_double(oi->xmin), &(oi->me) ); hp = dkma_sub_double_ok( dkma_l_to_double(oi->ymax), dkma_l_to_double(oi->ymin), &(oi->me) ); h = hp; w = wp; if(((oi->c)->svgs) == DKFIG_SVG_VP_INCHES) { h = h / 72.0; w = w / 72.0; } hp = dkma_double_restrict_digits(hp, 0); wp = dkma_double_restrict_digits(wp, 0); h = drd(h, oi->c, 1); w = drd(w, oi->c, 1); print_width(oi, w, (oi->c)->svgs); kw_out(oi, 1); print_height(oi, h, (oi->c)->svgs); kw_out(oi, 1); kw_out(oi, 18); kw_out(oi, 19); kw_out(oi, 20); dkstream_puts_ul(oi->s, 0UL); kw_out(oi, 1); dkstream_puts_ul(oi->s, 0UL); kw_out(oi, 1); dkstream_puts_long(oi->s, dkma_double_to_l(wp)); kw_out(oi, 1); dkstream_puts_long(oi->s, dkma_double_to_l(hp)); kw_out(oi, 20); if(!(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED)) { kw_out(oi, 0); switch((oi->c)->svgv) { case DKFIG_SVG_VERS_10: { if(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED) { kw_out(oi, 23); } else { kw_out(oi, 10); } kw_out(oi, 0); kw_out(oi, 11); kw_out(oi, 0); } break; case DKFIG_SVG_VERS_11: { if(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED) { kw_out(oi, 23); } else { kw_out(oi, 10); } kw_out(oi, 0); kw_out(oi, 11); kw_out(oi, 0); } break; } } svg_drve_write(oi, oi->dro, (DRVE *)((oi->dro)->drve), 1); kw_out(oi, 3); kw_out(oi, 0); $? "- svg_start_tag" } /** Finish svg output. @param oi OI structure. */ static void svg_end_tag DK_P1(OI *,oi) { end_tag(oi, 5); $? "= svg_end_tag" } /** Write a byte as two hex digits. @param oi OI structure. @param i Byte to print. */ static void hex_out DK_P2(OI *,oi, int,i) { size_t sz; char buffer[3]; sz = (i >> 4) & 15; buffer[0] = hex_digits[sz]; sz = i & 15; buffer[1] = hex_digits[sz]; buffer[2] = '\0'; dkstream_puts(oi->s, buffer); } /** Calculate grey value. @param r Red component. @param g Green component. @param b Blue component. @return Grey value. */ static unsigned ntsc DK_P3(unsigned, r, unsigned, g, unsigned, b) { unsigned long l1, l2, l3, l4; l1 = 54UL * (unsigned long)r; l2 = 183UL * (unsigned long)g; l3 = 19UL * (unsigned long)b; l4 = l1 + l2 + l3; l4 = (l4 >> 8) & 0x000000FFUL; return((unsigned)l4); } /** Write a color in hexadecimal notation, i.e. "#FF0000". @param oi OI structure @param r Red. @param g Green. @param b Blue. */ static void color_out DK_P4(OI *,oi, int,r, int,g, int,b) { int use_color = 1; int grayvalue; if(oi->c) { if(!(((oi->c)->opt2) & DKFIG_OPT_COLOR)) { use_color = 0; } } if(use_color) { kw_out(oi, 45); hex_out(oi, r); hex_out(oi, g); hex_out(oi, b); } else { grayvalue = (int)ntsc((unsigned)r, (unsigned)g, (unsigned)b); kw_out(oi, 45); hex_out(oi, grayvalue); hex_out(oi, grayvalue); hex_out(oi, grayvalue); } } /** Write style information for pattern stroke. @param oi OI structure. @param pat SVG pattern information structure. @param st */ static void pattern_style DK_P3(OI *,oi, SVGPAT *,pat, int,st) { double dlw; /* if(st) { dlw = ccll(oi, ((pat->lw) ? pat->lw : 1L), 1); } */ if(st) { dlw = ccll(oi, 1L, 1); } kw_out(oi, 38); kw_out(oi, 19); dkstream_set_double_no_exponent(oi->s, 1); kw_out(oi, 20); kw_out(oi, (st ? 62 : 63)); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, 65); kw_out(oi, 43); kw_out(oi, 1); kw_out(oi, (st ? 63 : 62)); kw_out(oi, 24); kw_out(oi, 1); color_out(oi, pat->sred, pat->sgreen, pat->sblue); kw_out(oi, 43); if(st) { kw_out(oi, 1); kw_out(oi, 64); kw_out(oi, 24); kw_out(oi, 1); put_double(oi, dlw, 1); kw_out(oi, 43); kw_out(oi, 1); kw_out(oi, 67); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, 69); kw_out(oi, 43); } kw_out(oi, 20); dkstream_set_double_no_exponent(oi->s, 0); } /** Write points="xxx" for polyline/polygon. @param oi OI structure. @param co Coordinates array. @param n Size of array (even number). @param cl Flag: Closed path. */ static void points_out DK_P4(OI *,oi, double *,co, size_t,n, int,cl) { size_t max; size_t i; max = 2 * n; kw_out(oi, 86); kw_out(oi, 19); kw_out(oi, 20); for(i = 0; i < max; i++) { if(i) { kw_out(oi, ((i % 2) ? 55 : 0)); } put_double(oi, co[i], 1); } kw_out(oi, 20); } /** Draw and fill operations for pattern strokes. @param oi OI structure. @param co Coordinates array. @param np Number of points. @param cl Flag: Closed path. @param pat SVG pattern information structure. @param lof Flag: Line (0) or fill (1). */ static void pattern_line_or_fill DK_P6(OI *,oi, double *,co, size_t,np, int,cl, SVGPAT *,pat, int,lof) { begin_tag(oi, ((lof && cl) ? 84 : 85)); kw_out(oi, 0); pattern_style(oi, pat, lof); kw_out(oi, 0); points_out(oi, co, np, cl); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); } /** Write pattern strokes as a polyline/polygon. @param oi OI structure. @param co Coordinates. @param np Number of points. @param cl Flag: Closed path. @param pat SVG pattern information structure. */ static void pattern_line DK_P5(OI *,oi, double *,co, size_t,np, int,cl, SVGPAT *,pat) { pattern_line_or_fill(oi, co, np, cl, pat, 1); } /** Write pattern strokes as a filled polygon. @param oi OI structure. @param co Coordinates. @param np Number of points. @param cl Flag: Closed path. @param pat SVG pattern information structure. */ static void pattern_area DK_P5(OI *,oi, double *,co, size_t,np, int,cl, SVGPAT *,pat) { pattern_line_or_fill(oi, co, np, cl, pat, 0); } /** Write strokes for the fish scales patterns. @param oi OI structure. @param pat Pattern information structure. @param xstep Repeat distance in x direction. @param ystep Repeat distance in y direction. @param x1 Start point x. @param y1 Start point y. @param r Radius of fishscale. */ static void do_fish_scales DK_P7(OI *,oi, SVGPAT *,pat, double,xstep, double,ystep, double,x1, double,y1, double,r) { begin_tag(oi, 98); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 100); kw_out(oi, 103); kw_out(oi, 55); kw_out(oi, 103); kw_out(oi, 102); put_double(oi, r, 2); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); put_double(oi, xstep, 1); kw_out(oi, 55); put_double(oi, 0.0, 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); begin_tag(oi, 98); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 100); kw_out(oi, 103); kw_out(oi, 55); put_double(oi, ystep, 1); kw_out(oi, 102); put_double(oi, r, 1); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); put_double(oi, x1, 1); kw_out(oi, 55); put_double(oi, y1, 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); begin_tag(oi, 98); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 100); put_double(oi, x1, 1); kw_out(oi, 55); put_double(oi, y1, 1); kw_out(oi, 102); put_double(oi, r, 1); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); put_double(oi, xstep, 1); kw_out(oi, 55); put_double(oi, ystep, 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); begin_tag(oi, 98); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 100); kw_out(oi, 103); kw_out(oi, 55); kw_out(oi, 103); kw_out(oi, 102); put_double(oi, r, 1); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); put_double(oi, x1, 1); kw_out(oi, 55); put_double(oi, (0.0 - y1), 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); begin_tag(oi, 98); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 100); put_double(oi, x1, 1); kw_out(oi, 55); put_double(oi, (0.0 - y1), 1); kw_out(oi, 102); put_double(oi, r, 1); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); put_double(oi, xstep, 1); kw_out(oi, 55); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); } /** Write one pattern. @param oi OI structure. @param pat Pattern information structure. */ static void pattern_out DK_P2(OI *,oi, SVGPAT *,pat) { double patrp, xstep, ystep, a, b, dlw; double x1, y1, x2, y2, x3, y3, x4, y4; double co[32]; $? "+ pattern_out" xstep = ystep = 10.0; a = b = 0.0; /* dlw = ccll(oi, ((pat->lw) ? pat->lw : 1L), 1); */ dlw = ccll(oi, 1L, 1); if((oi->c)->patrp) { patrp = 0.9 * dkma_l_to_double((oi->c)->patrp); } else { patrp = 3.6; } patrp = fabs(patrp); xstep = ystep = patrp; switch(pat->pattp) { case 41: case 42: case 43: { xstep = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); ystep = dkma_mul_double_ok(patrp, sqrt(4.0/3.0), &(oi->me)); } break; case 44: case 45: case 46: { /* FourtyFiveLeft */ xstep = dkma_mul_double_ok(patrp, sqrt(2.0), &(oi->me)); ystep = xstep; } break; case 47: { /* HorizontalBricks */ x1 = patrp; patrp = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); x2 = dkma_add_double_ok(x1, patrp, &(oi->me)); x3 = dkma_add_double_ok(x2, patrp, &(oi->me)); x4 = dkma_add_double_ok(x3, patrp, &(oi->me)); y1 = patrp; ystep = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); xstep = dkma_mul_double_ok(ystep, 2.0, &(oi->me)); } break; case 48: { /* VerticalBricks */ y1 = patrp; patrp = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); y2 = dkma_add_double_ok(y1, patrp, &(oi->me)); y3 = dkma_add_double_ok(y2, patrp, &(oi->me)); y4 = dkma_add_double_ok(y3, patrp, &(oi->me)); x1 = patrp; xstep = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); ystep = dkma_mul_double_ok(xstep, 2.0, &(oi->me)); } break; case 49: { /* HorizontalLines */ } break; case 50: { /* VerticalLines */ } break; case 51: { /* CrossHatch */ } break; case 52: case 53: { /* HorizShinglesRight, Left... */ ystep = dkma_mul_double_ok(patrp, 8.0, &(oi->me)); xstep = dkma_mul_double_ok(patrp, 4.0, &(oi->me)); x1 = patrp; x2 = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); x3 = dkma_mul_double_ok(patrp, 3.0, &(oi->me)); a = 0.5 * dlw; y1 = x2; y2 = xstep; y3 = dkma_mul_double_ok(patrp, 6.0, &(oi->me)); } break; case 54: case 55: { /* VertShinglesOne */ ystep = dkma_mul_double_ok(patrp, 4.0, &(oi->me)); xstep = dkma_mul_double_ok(patrp, 8.0, &(oi->me)); y1 = patrp; y2 = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); y3 = dkma_mul_double_ok(patrp, 3.0, &(oi->me)); a = 0.5 * dlw; x1 = y2; x2 = ystep; x3 = dkma_mul_double_ok(patrp, 6.0, &(oi->me)); } break; case 56: { /* FishScales */ a = dkma_mul_double_ok(patrp, 2.5, &(oi->me)); b = 1.881618; xstep = dkma_mul_double_ok( 2.0, dkma_mul_double_ok(a, sin(0.5*b), &(oi->me)), &(oi->me) ); ystep = dkma_mul_double_ok( (1.0 - cos(0.5*b)), a, &(oi->me) ); ystep = dkma_mul_double_ok(ystep, 2.0, &(oi->me)); xstep = round_down_digits(xstep, 4); ystep = round_down_digits(ystep, 4); x1 = 0.5 * xstep; y1 = 0.5 * ystep; } break; case 57: { /* SmallFishScales */ a = patrp; b = M_PI; xstep = dkma_mul_double_ok( 2.0, dkma_mul_double_ok(a, sin(0.5*b), &(oi->me)), &(oi->me) ); ystep = dkma_mul_double_ok( (1.0 - cos(0.5*b)), a, &(oi->me) ); ystep = dkma_mul_double_ok(ystep, 2.0, &(oi->me)); xstep = round_down_digits(xstep, 4); ystep = round_down_digits(ystep, 4); x1 = 0.5 * xstep; y1 = 0.5 * ystep; } break; case 58: { /* Circles */ a = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); xstep = ystep = dkma_mul_double_ok(patrp, 4.0, &(oi->me)); } break; case 59: { /* Hexagons */ xstep = dkma_mul_double_ok(patrp, 6.0, &(oi->me)); y1 = ystep = dkma_mul_double_ok(patrp, sqrt(3.0), &(oi->me)); ystep = dkma_mul_double_ok(ystep, 2.0, &(oi->me)); x1 = patrp; x2 = dkma_mul_double_ok(patrp, 3.0, &(oi->me)); x3 = dkma_mul_double_ok(patrp, 4.0, &(oi->me)); x4 = dkma_add_double_ok(xstep, patrp, &(oi->me)); } break; case 60: { /* Octagons */ patrp = dkma_mul_double_ok(patrp, 4.0, &(oi->me)); xstep = ystep = patrp; a = xstep / (2.0+sqrt(2.0)); } break; case 61: case 62: { /* HorizontalTireTreads, Vertical... */ xstep = ystep = dkma_mul_double_ok(patrp, 2.0, &(oi->me)); } break; } begin_tag(oi, 35); kw_out(oi, 1); kw_out(oi, 36); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 37); dkfig_tool_num_as_string(oi->s, pat->patno, oi->lpat); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 16); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, xstep, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 17); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, ystep, 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 111); kw_out(oi, 0); kw_out(oi, 3); kw_out(oi, 0); if((pat->flags) & DKFIG_SVG_FL_FILL) { begin_tag(oi, 79); kw_out(oi, 1); kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 16); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, xstep, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 17); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, ystep, 1); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 38); kw_out(oi, 19); dkstream_set_double_no_exponent(oi->s, 1); kw_out(oi, 20); kw_out(oi, 62); kw_out(oi, 24); kw_out(oi, 1); color_out(oi, pat->fred, pat->fgreen, pat->fblue); kw_out(oi, 43); kw_out(oi, 1); kw_out(oi, 63); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, 65); kw_out(oi, 43); kw_out(oi, 20); dkstream_set_double_no_exponent(oi->s, 0); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); } if((pat->flags) & DKFIG_SVG_FL_STROKE) { switch(pat->pattp) { case 41: { /* ThirtyLeft */ a = dlw; b = dlw / sqrt(3.0); co[0] = 0.0; co[1] = 0.0; co[2] = a; co[3] = 0.0; co[4] = xstep; co[5] = dkma_sub_double_ok(ystep, b, &(oi->me)); co[6] = xstep; co[7] = ystep; co[8] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[9] = ystep; co[10] = 0.0; co[11] = b; pattern_area(oi, co, 6, 0, pat); co[0] = 0.0; co[1] = dkma_sub_double_ok(ystep, b, &(oi->me)); co[2] = a; co[3] = ystep; co[4] = 0.0; co[5] = ystep; pattern_area(oi, co, 3, 0, pat); co[0] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[1] = 0.0; co[2] = xstep; co[3] = b; co[4] = xstep; co[5] = 0.0; pattern_area(oi, co, 3, 0, pat); } break; case 42: { /* ThirtyRight */ a = dlw; b = dlw / sqrt(3.0); co[0] = 0.0; co[1] = ystep; co[2] = a; co[3] = ystep; co[4] = xstep; co[5] = b; co[6] = xstep; co[7] = 0.0; co[8] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[9] = 0.0; co[10] = 0.0; co[11] = dkma_sub_double_ok(ystep, b, &(oi->me)); pattern_area(oi, co, 6, 0, pat); co[0] = 0.0; co[1] = b; co[2] = a; co[3] = 0.0; co[4] = 0.0; co[5] = 0.0; pattern_area(oi, co, 3, 0, pat); co[0] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[1] = ystep; co[2] = xstep; co[3] = ystep; co[4] = xstep; co[5] = dkma_sub_double_ok(ystep, b, &(oi->me)); pattern_area(oi, co, 3, 0, pat); } break; case 43: case 46: { /* ThirtyHatch, FourtyFiveHatch */ co[0] = 0.0; co[1] = 0.0; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = ystep; co[2] = xstep; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); } break; case 44: { /* FourtyFiveLeft */ a = dlw / sqrt(2.0); b = dlw / sqrt(2.0); co[0] = 0.0; co[1] = 0.0; co[2] = a; co[3] = 0.0; co[4] = xstep; co[5] = dkma_sub_double_ok(ystep, b, &(oi->me)); co[6] = xstep; co[7] = ystep; co[8] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[9] = ystep; co[10] = 0.0; co[11] = b; pattern_area(oi, co, 6, 0, pat); co[0] = 0.0; co[1] = dkma_sub_double_ok(ystep, b, &(oi->me)); co[2] = a; co[3] = ystep; co[4] = 0.0; co[5] = ystep; pattern_area(oi, co, 3, 0, pat); co[0] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[1] = 0.0; co[2] = xstep; co[3] = b; co[4] = xstep; co[5] = 0.0; pattern_area(oi, co, 3, 0, pat); } break; case 45: { /* FourtyFiveRight */ a = dlw / sqrt(2.0); b = dlw / sqrt(2.0); co[0] = 0.0; co[1] = ystep; co[2] = a; co[3] = ystep; co[4] = xstep; co[5] = b; co[6] = xstep; co[7] = 0.0; co[8] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[9] = 0.0; co[10] = 0.0; co[11] = dkma_sub_double_ok(ystep, b, &(oi->me)); pattern_area(oi, co, 6, 0, pat); co[0] = 0.0; co[1] = b; co[2] = a; co[3] = 0.0; co[4] = 0.0; co[5] = 0.0; pattern_area(oi, co, 3, 0, pat); co[0] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[1] = ystep; co[2] = xstep; co[3] = ystep; co[4] = xstep; co[5] = dkma_sub_double_ok(ystep, b, &(oi->me)); pattern_area(oi, co, 3, 0, pat); } break; case 47: { /* HorizontalBricks */ co[0] = x1; co[1] = 0.0; co[2] = x1; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = 0.0; co[2] = x3; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = y1; co[2] = x2; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x4; co[1] = y1; co[2] = x4; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = xstep; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = ystep; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y1; co[2] = xstep; co[3] = y1; pattern_line(oi, co, 2, 0, pat); } break; case 48: { /* VerticalBricks */ co[0] = 0.0; co[1] = y1; co[2] = x1; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y3; co[2] = x1; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = y2; co[2] = xstep; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = y4; co[2] = xstep; co[3] = y4; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = 0.0; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = 0.0; co[2] = x1; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = xstep; co[1] = 0.0; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 49: { /* HorizontalLines */ co[0] = 0.0; co[1] = 0.0; co[2] = xstep; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = ystep; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 50: { /* VerticalLines */ co[0] = 0.0; co[1] = 0.0; co[2] = 0.0; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = xstep; co[1] = 0.0; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 51: { /* CrossHatch */ co[0] = 0.0; co[1] = 0.0; co[2] = 0.0; co[3] = ystep; co[4] = xstep; co[5] = ystep; co[6] = xstep; co[7] = 0.0; pattern_line(oi, co, 4, 1, pat); } break; case 52: { /* HorizShinglesRight */ co[0] = a; co[1] = y1; co[2] = dkma_sub_double_ok(x1, a, &(oi->me)); co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = dkma_add_double_ok(x1, a, &(oi->me)); co[1] = y2; co[2] = dkma_sub_double_ok(x2, a, &(oi->me)); co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = dkma_add_double_ok(x2, a, &(oi->me)); co[1] = y3; co[2] = dkma_sub_double_ok(x3, a, &(oi->me)); co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = dkma_add_double_ok(x3, a, &(oi->me)); co[1] = ystep; co[2] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = xstep; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y1; co[2] = xstep; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y2; co[2] = xstep; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y3; co[2] = xstep; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = ystep; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 53: { /* HorizShinglesLeft */ co[0] = 0.0; co[1] = 0.0; co[2] = x1; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = y1; co[2] = xstep; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = y2; co[2] = x3; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = y3; co[2] = x2; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = xstep; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y1; co[2] = xstep; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y2; co[2] = xstep; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = y3; co[2] = xstep; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = ystep; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 54: { /* VertShinglesOne */ co[0] = 0.0; co[1] = y3; co[2] = x1; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = y2; co[2] = x2; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = y1; co[2] = x3; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = 0.0; co[2] = xstep; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = 0.0; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = 0.0; co[2] = x1; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = 0.0; co[2] = x2; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = 0.0; co[2] = x3; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = xstep; co[1] = 0.0; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 55: { /* VertShinglesOther */ co[0] = 0.0; co[1] = ystep; co[2] = x1; co[3] = y3; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = y1; co[2] = x2; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = y2; co[2] = x3; co[3] = y1; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = y3; co[2] = xstep; co[3] = y2; pattern_line(oi, co, 2, 0, pat); co[0] = 0.0; co[1] = 0.0; co[2] = 0.0; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x1; co[1] = 0.0; co[2] = x1; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x2; co[1] = 0.0; co[2] = x2; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = x3; co[1] = 0.0; co[2] = x3; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); co[0] = xstep; co[1] = 0.0; co[2] = xstep; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 56: { /* FishScales */ do_fish_scales(oi, pat, xstep, ystep, x1, y1, a); } break; case 57: { /* SmallFishScales */ do_fish_scales(oi, pat, xstep, ystep, x1, y1, a); } break; case 58: { /* Circles */ begin_tag(oi, 90); kw_out(oi, 1); kw_out(oi, 87); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, a, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 88); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, a, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 89); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, a, 1); kw_out(oi, 20); kw_out(oi, 0); pattern_style(oi, pat, 1); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); } break; case 59: { /* Hexagons */ co[0] = x1; co[1] = 0.0; co[2] = 0.0; co[3] = y1; co[4] = x1; co[5] = ystep; co[6] = x2; co[7] = ystep; co[8] = x3; co[9] = y1; co[10] = x2; co[11] = 0.0; pattern_line(oi, co, 6, 1, pat); co[0] = x3; co[1] = y1; co[2] = xstep; co[3] = y1; pattern_line(oi, co, 2, 0, pat); /* for the line ends at the right border */ co[0] = xstep; co[1] = y1; co[2] = x4; co[3] = 0.0; pattern_line(oi, co, 2, 0, pat); co[0] = xstep; co[1] = y1; co[2] = x4; co[3] = ystep; pattern_line(oi, co, 2, 0, pat); } break; case 60: { /* Octagons */ co[0] = 0.0; co[1] = a; co[2] = a; co[3] = 0.0; co[4] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[5] = 0.0; co[6] = xstep; co[7] = a; co[8] = xstep; co[9] = dkma_sub_double_ok(ystep, a, &(oi->me)); co[10] = dkma_sub_double_ok(xstep, a, &(oi->me)); co[11] = ystep; co[12] = a; co[13] = ystep; co[14] = 0.0; co[15] = dkma_sub_double_ok(ystep, a, &(oi->me)); pattern_line(oi, co, 8, 1, pat); } break; case 61: { /* HorizontalTireTreads */ y1 = 0.5 * patrp; y2 = dkma_mul_double_ok(patrp, 1.5, &(oi->me)); co[0] = 0.0; co[1] = y1; co[2] = patrp; co[3] = y2; co[4] = xstep; co[5] = y1; pattern_line(oi, co, 3, 0, pat); } break; case 62: { /* VerticalTireTreads */ x1 = 0.5 * patrp; x2 = dkma_mul_double_ok(patrp, 1.5, &(oi->me)); co[0] = x1; co[1] = 0.0; co[2] = x2; co[3] = patrp; co[4] = x1; co[5] = ystep; pattern_line(oi, co, 3, 0, pat); } break; } } end_tag(oi, 35); $? "- pattern_out" } /** Write a font size. @param oi OI structure. @param sty Style information structure. */ static void put_font_size DK_P2(OI *,oi, SVGSTY *,sty) { if(((oi->c)->opt2) & DKFIG_OPT_SVG_FONTSIZE_UNIT) { switch((oi->c)->svgs) { case DKFIG_SVG_VP_INCHES: { dkstream_puts_double( oi->s, drd( dkma_mul_double_ok((sty->fonth)->fontsize, (oi->c)->fsf, &(oi->me)), oi->c, 1 ) ); kw_out(oi, 81); } break; case DKFIG_SVG_VP_PIXELS: { dkstream_puts_double( oi->s, drd( (pt_to_bp * dkma_mul_double_ok((sty->fonth)->fontsize, (oi->c)->fsf, &(oi->me)) ), oi->c, 1 ) ); kw_out(oi, 22); } break; default: { dkstream_puts_double( oi->s, drd( (pt_to_bp * dkma_mul_double_ok((sty->fonth)->fontsize, (oi->c)->fsf, &(oi->me)) ), oi->c, 1 ) ); } break; } } else { dkstream_puts_double( oi->s, drd( (pt_to_bp * dkma_mul_double_ok((sty->fonth)->fontsize, (oi->c)->fsf, &(oi->me)) ), oi->c, 1 ) ); } } /** Write style information (style contents). The iscss flag indicates whether we are in a style type="text/css" section or in a style="..." string. @param oi OI structure. @param sty Style information structure. @param iscss Flag: Write CSS style definition (1) or attribute set (0). */ static void style_out DK_P3(OI *,oi, SVGSTY *,sty, int,iscss) { double dotlgt; int had_entry; dk_one_font_mapping_t *pofm; dk_font_replacement_t *pfr; char *fontfamilyname; $? "+ style_out %s %s %d", TR_PTR(oi), TR_PTR(sty), iscss dotlgt = 0.0; if(oi->prep_mods) { if(!iscss) { if((sty->flags) & DKFIG_SVG_FL_TEXT) { if(sty->fonth) { switch((sty->fonth)->handling) { case 2: case 3: case 4: case 5: { } break; default: { char *ptr; int ft; /* font-family */ if(iscss) { kw_out(oi, 0); } kw_out(oi, 46); kw_out(oi, 19); kw_out(oi, 20); ptr = dkfont_get_svg_family_name((size_t)((sty->fonth)->fontno)); $? ". font family name = \"%s\"", ptr if(oi->urw_dir) { if(((sty->fonth)->fontno) >= 0) { if(((sty->fonth)->fontno) < 35) { ptr = urw_svg_font_families[(sty->fonth)->fontno]; $? ". font family name = \"%s\"", ptr } } } ft = dkfont_get_features((size_t)((sty->fonth)->fontno)); had_entry = 0; if(oi->fontmap) { pofm = dkfont_get_one_font(oi->fontmap, (sty->fonth)->fontno); if(pofm) { dkfont_one_font_reset(pofm); while((pfr = dkfont_one_font_get(pofm)) != NULL) { if(dkfont_rep_check_driver(pfr, kw[5])) { fontfamilyname = dkfont_rep_get_family(pfr); if(fontfamilyname) { if(had_entry) { kw_out(oi, 55); } kw_out(oi, (iscss ? 20 : 107)); dkstream_puts(oi->s, fontfamilyname); kw_out(oi, (iscss ? 20 : 107)); had_entry = 1; } } } } } else { if(ptr) { $? ". font family name = \"%s\"", ptr kw_out(oi, (iscss ? 20 : 107)); dkstream_puts(oi->s, ptr); kw_out(oi, (iscss ? 20 : 107)); had_entry = 1; } } if(had_entry) { kw_out(oi, 55); } switch(ft & DK_FONT_FEATURE_FAMILY) { case DK_FONT_FEATURE_TT: { kw_out(oi, 58); } break; case DK_FONT_FEATURE_SF: { kw_out(oi, 57); } break; default: { kw_out(oi, 56); } break; } kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 47); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, ((ft & DK_FONT_FEATURE_IT) ? 60 : 59)); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 48); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, ((ft & DK_FONT_FEATURE_BD) ? 61 : 59)); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 49); kw_out(oi, 19); kw_out(oi, 20); /* font size */ put_font_size(oi, sty); /* kw_out(oi, 81); */ kw_out(oi, 20); kw_out(oi, 0); /* align */ kw_out(oi, 51); kw_out(oi, 19); kw_out(oi, 20); switch(sty->talign) { case 1: { kw_out(oi, 53); } break; case 2: { kw_out(oi, 54); } break; default: { kw_out(oi, 52); } break; } kw_out(oi, 20); kw_out(oi, 1); /* color */ /* kw_out(oi, 50); */ kw_out(oi, 62); kw_out(oi, 19); kw_out(oi, 20); color_out(oi, sty->sred, sty->sgreen, sty->sblue); kw_out(oi, 20); kw_out(oi, 0); } break; } } } else { if(iscss) { kw_out(oi, 0); } kw_out(oi, 62); kw_out(oi, 19); kw_out(oi, 20); if((sty->flags) & DKFIG_SVG_FL_FILL) { if(sty->pat) { kw_out(oi, 74); kw_out(oi, 75); kw_out(oi, 45); kw_out(oi, 37); dkfig_tool_num_as_string(oi->s, (sty->pat)->patno, oi->lpat); kw_out(oi, 76); } else { color_out(oi, sty->fred, sty->fgreen, sty->fblue); } } else { kw_out(oi, 65); } kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 63); kw_out(oi, 19); kw_out(oi, 20); if((sty->flags) & DKFIG_SVG_FL_STROKE) { double mylw; color_out(oi, sty->sred, sty->sgreen, sty->sblue); kw_out(oi, 20); kw_out(oi, 1); mylw = ccll(oi, sty->lw, 1); /* mylw = dkma_l_to_double(sty->lw); mylw = dkma_mul_double_ok(mylw, oi->mx, &(oi->me)); if((sty->flags) & DKFIG_SVG_FL_ENLIGHTEN) { mylw = mylw * 0.5; } */ kw_out(oi, 64); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, mylw, 1); kw_out(oi, 20); if(sty->lc) { kw_out(oi, 0); kw_out(oi, 67); kw_out(oi, 19); kw_out(oi, 20); switch(sty->lc) { case 2: { kw_out(oi, 70); } break; case 1: { kw_out(oi, 69); } break; default: { kw_out(oi, 68); } break; } kw_out(oi, 20); } if(sty->lj) { kw_out(oi, 0); kw_out(oi, 71); kw_out(oi, 19); kw_out(oi, 20); switch(sty->lj) { case 2: { kw_out(oi, 73); } break; case 1: { kw_out(oi, 69); } break; default: { kw_out(oi, 72); } break; } kw_out(oi, 20); } if((sty->ls) > 0) { /* double mylw; */ kw_out(oi, 0); mylw = ccdl(oi, sty->sv, 0); dotlgt = 0.0; if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) { dotlgt = ccll(oi, ((sty->lw) ? sty->lw : 1L), 1); dotlgt = drd(dotlgt, oi->c, 1); } /* mylw = dkma_l_to_double(sty->sv); mylw = dkma_mul_double_ok(mylw, oi->mx, &(oi->me)); */ mylw = drd(mylw, oi->c, 1); kw_out(oi, 66); kw_out(oi, 19); kw_out(oi, 20); switch(sty->ls) { case 1: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 2: { dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 3: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 4: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 5: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; } kw_out(oi, 20); } } else { kw_out(oi, 65); kw_out(oi, 20); } kw_out(oi, 0); } } } else { if(iscss) { kw_out(oi, 40); kw_out(oi, 44); $? ". vor num_as_string" dkfig_tool_num_as_string(oi->s, sty->classno, oi->lsty); $? ". nach num_as_string" kw_out(oi, 1); kw_out(oi, 41); } else { kw_out(oi, 38); kw_out(oi, 19); dkstream_set_double_no_exponent(oi->s, 1); kw_out(oi, 20); } if((sty->flags) & DKFIG_SVG_FL_TEXT) { if(sty->fonth) { switch((sty->fonth)->handling) { case 2: case 3: case 4: case 5: { } break; default: { char *ptr; int ft; /* font-family */ if(iscss) { kw_out(oi, 0); } kw_out(oi, 46); kw_out(oi, 24); kw_out(oi, 1); ptr = dkfont_get_svg_family_name((size_t)((sty->fonth)->fontno)); $? ". font family name = \"%s\"", ptr if(oi->urw_dir) { if(((sty->fonth)->fontno) >= 0) { if(((sty->fonth)->fontno) < 35) { ptr = urw_svg_font_families[(sty->fonth)->fontno]; $? ". font family name = \"%s\"", ptr } } } ft = dkfont_get_features((size_t)((sty->fonth)->fontno)); had_entry = 0; if(oi->fontmap) { pofm = dkfont_get_one_font(oi->fontmap, (sty->fonth)->fontno); if(pofm) { dkfont_one_font_reset(pofm); while((pfr = dkfont_one_font_get(pofm)) != NULL) { if(dkfont_rep_check_driver(pfr, kw[5])) { fontfamilyname = dkfont_rep_get_family(pfr); if(fontfamilyname) { $? ". fontfamilyname=\"%s\"", fontfamilyname if(had_entry) { kw_out(oi, 55); } kw_out(oi, (iscss ? 20 : 107)); dkstream_puts(oi->s, fontfamilyname); kw_out(oi, (iscss ? 20 : 107)); had_entry = 1; } } } } } else { if(ptr) { $? ". font family name = \"%s\"", ptr kw_out(oi, (iscss ? 20 : 107)); dkstream_puts(oi->s, ptr); kw_out(oi, (iscss ? 20 : 107)); had_entry = 1; } } if(had_entry) { kw_out(oi, 55); } switch(ft & DK_FONT_FEATURE_FAMILY) { case DK_FONT_FEATURE_TT: { kw_out(oi, 58); } break; case DK_FONT_FEATURE_SF: { kw_out(oi, 57); } break; default: { kw_out(oi, 56); } break; } kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); kw_out(oi, 47); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_IT) ? 60 : 59)); kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); kw_out(oi, 48); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_BD) ? 61 : 59)); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 49); kw_out(oi, 24); kw_out(oi, 1); /* font size */ put_font_size(oi, sty); /* kw_out(oi, 81); */ kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); /* align */ kw_out(oi, 51); kw_out(oi, 24); kw_out(oi, 1); switch(sty->talign) { case 1: { kw_out(oi, 53); } break; case 2: { kw_out(oi, 54); } break; default: { kw_out(oi, 52); } break; } kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); /* color */ /* kw_out(oi, 50); */ kw_out(oi, 62); kw_out(oi, 24); kw_out(oi, 1); color_out(oi, sty->sred, sty->sgreen, sty->sblue); kw_out(oi, 43); } break; } } } else { if(iscss) { kw_out(oi, 0); } kw_out(oi, 62); kw_out(oi, 24); kw_out(oi, 1); if((sty->flags) & DKFIG_SVG_FL_FILL) { if(sty->pat) { kw_out(oi, 74); kw_out(oi, 75); kw_out(oi, 45); kw_out(oi, 37); dkfig_tool_num_as_string(oi->s, (sty->pat)->patno, oi->lpat); kw_out(oi, 76); } else { color_out(oi, sty->fred, sty->fgreen, sty->fblue); } } else { kw_out(oi, 65); } kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); kw_out(oi, 63); kw_out(oi, 24); kw_out(oi, 1); if((sty->flags) & DKFIG_SVG_FL_STROKE) { double mylw; color_out(oi, sty->sred, sty->sgreen, sty->sblue); kw_out(oi, 43); kw_out(oi, (iscss ? 0 : 1)); mylw = ccll(oi, sty->lw, 1); /* mylw = dkma_l_to_double(sty->lw); mylw = dkma_mul_double_ok(mylw, oi->mx, &(oi->me)); if((sty->flags) & DKFIG_SVG_FL_ENLIGHTEN) { mylw = mylw * 0.5; } */ kw_out(oi, 64); kw_out(oi, 24); kw_out(oi, 1); put_double(oi, mylw, 1); kw_out(oi, 43); if(sty->lc) { kw_out(oi, (iscss ? 0 : 1)); kw_out(oi, 67); kw_out(oi, 24); kw_out(oi, 1); switch(sty->lc) { case 2: { kw_out(oi, 70); } break; case 1: { kw_out(oi, 69); } break; default: { kw_out(oi, 68); } break; } kw_out(oi, 43); } if(sty->lj) { kw_out(oi, 0); kw_out(oi, 71); kw_out(oi, 24); kw_out(oi, 1); switch(sty->lj) { case 2: { kw_out(oi, 73); } break; case 1: { kw_out(oi, 69); } break; default: { kw_out(oi, 72); } break; } kw_out(oi, 43); } if((sty->ls) > 0) { /* double mylw; */ kw_out(oi, 0); mylw = ccdl(oi, sty->sv, 0); dotlgt = 0.0; if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) { dotlgt = ccll(oi, ((sty->lw) ? sty->lw : 1L), 1); dotlgt = drd(dotlgt, oi->c, 1); } /* mylw = dkma_l_to_double(sty->sv); mylw = dkma_mul_double_ok(mylw, oi->mx, &(oi->me)); */ mylw = drd(mylw, oi->c, 1); kw_out(oi, 66); kw_out(oi, 24); kw_out(oi, 1); switch(sty->ls) { case 1: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 2: { dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 3: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 4: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; case 5: { dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); kw_out(oi, 55); dkstream_puts_double(oi->s,dotlgt); kw_out(oi, 55); dkstream_puts_double(oi->s, mylw); } break; } kw_out(oi, 43); } } else { kw_out(oi, 65); kw_out(oi, 43); } } if(iscss) { kw_out(oi, 0); kw_out(oi, 42); kw_out(oi, 0); } else { kw_out(oi, 20); dkstream_set_double_no_exponent(oi->s, 0); kw_out(oi, 0); } } $? "- style_out" } /** Check whether or not an object has a link attached. @param drve Driver-specific extension to a Fig object. @return 1=link attached, 0=no link. */ static int check_link DK_P1(DRVE *,drve) { int back = 0; if(drve) { if(drve->xli) { dksto_it_reset(drve->xli); if(dksto_it_next(drve->xli)) { back = 1; } } } return back; } /** Write the hyperlink for an object. @param oi OI structure. @param drve Driver-specific extension to Fig object. */ static void print_a_contents DK_P2(OI *,oi, DRVE *,drve) { dk_fig_svg_attr *a; if(drve->xli) { dksto_it_reset(drve->xli); while((a = (dk_fig_svg_attr *)dksto_it_next(drve->xli)) != NULL) { if((a->classid >= 0) && ((size_t)(a->classid) < sz_xlcmds) && (a->value)) { kw_out(oi, 0); dkstream_puts(oi->s, *(xlcmds[a->classid])); kw_out(oi, 19); kw_out(oi, 20); dkstream_puts(oi->s, a->value); kw_out(oi, 20); } } } } /** Check whether we need to create a group for an object. This is usefull if SVGs are imported into a drawing application. In this case we want to copy/move not only lines/splines/arcs but also the arrowheads attached to them. @param oi OI structure. @return 1=group necessary, 0=no group necessary. */ static int check_group DK_P1(OI *,oi) { int back = 0, how; how = get_how(oi->o); switch(how) { case 1: { } break; case 2: { if(((DRVE *)((oi->o)->drve))->st1) { back = 1; } if(((DRVE *)((oi->o)->drve))->st2) { back = 1; } } break; default: { if(!(((oi->o)->fpd).cl)) { if((((oi->o)->fpd).ar) & 3) { back = 1; } } } break; } return back; } /** Transfer text contents to output, encode characters if necessary. @param oi OI structure. @param s UTF-8 encoded text to print. */ static void print_utf8_encoded DK_P2(OI *,oi, char,*s) { /* char buffer[10], c, *ptr; unsigned char uc; size_t sz; int must_encode; ptr = s; while(*ptr) { c = *ptr; must_encode = 1; if((c >= 'a') && (c <= 'z')) { must_encode = 0; } else { if((c >= 'A') && (c <= 'Z')) { must_encode = 0; } else { if((c >= '0') && (c <= '9')) { must_encode = 0; } else { switch(c) { case '|': case '@': case '^': case '!': case '$': case '%': case '/': case '(': case ')': case '=': case '?': case '~': case '*': case '#': case '_': case '+': case '-': case ':': case ';': case ',': case '.': case ' ': { must_encode = 0; } break; } } } } if(must_encode) { uc = (unsigned char)c; sz = (size_t)uc; strcpy(buffer, default_encoding); buffer[3] = hex_digits[(sz >> 4) & 15]; buffer[4] = hex_digits[sz & 15]; dkstream_puts(oi->s, buffer); } else { buffer[0] = c; buffer[1] = '\0'; dkstream_puts(oi->s, buffer); } ptr++; } */ dk_udword ucb; unsigned char uc; char chr; int i; int cc, must_encode; char buffer[16]; size_t max, used, avail, step; cc = 1; max = strlen(s); avail = max; used = 0; while(cc) { cc = 0; if(avail) { step = 0; cc = dkenc_utf82uc(&ucb, (unsigned char *)(&(s[used])), avail, &step); if(cc) { used += step; if(avail > step) { avail = avail - step; } else { avail = 0; } uc = (unsigned char)ucb; chr = (char)uc; i = (int)chr; must_encode = 1; if((chr >= 'a') && (chr <= 'z')) { must_encode = 0; } else { if((chr >= 'A') && (chr <= 'Z')) { must_encode = 0; } else { if((chr >= '0') && (chr <= '9')) { must_encode = 0; } else { switch(chr) { case '|': case '@': case '^': case '!': case '$': case '%': case '/': case '(': case ')': case '=': case '?': case '~': case '*': case '#': case '_': case '+': case '-': case ':': case ';': case ',': case '.': case ' ': { must_encode = 0; } break; } } } } if(must_encode) { /* sz = size_t uc; strcpy(buffer, default_encoding); buffer[3] = hex_digits[(sz >> 4) & 15]; buffer[4] = hex_digits[sz & 15]; */ if(ucb > 0x000000FFUL) { if(ucb > 0x0000FFFFUL) { if(ucb > 0x00FFFFFFUL) { #if DK_HAVE_SNPRINTF snprintf(buffer, sizeof(buffer), "&#x%08lX;", ucb); buffer[sizeof(buffer)-1] = '\0'; #else sprintf(buffer, "&#x%08lX;", ucb); #endif } else { /* 6 */ #if DK_HAVE_SNPRINTF snprintf(buffer, sizeof(buffer), "&#x%06lX;", ucb); buffer[sizeof(buffer)-1] = '\0'; #else sprintf(buffer, "&#x%06lX;", ucb); #endif } } else { /* 4 */ #if DK_HAVE_SNPRINTF snprintf(buffer, sizeof(buffer), "&#x%04lX;", ucb); buffer[sizeof(buffer)-1] = '\0'; #else sprintf(buffer, "&#x%04lX;", ucb); #endif } } else { /* 2 */ #if DK_HAVE_SNPRINTF snprintf(buffer, sizeof(buffer), "&#x%02lX;", ucb); buffer[sizeof(buffer)-1] = '\0'; #else sprintf(buffer, "&#x%02lX;", ucb); #endif } } else { buffer[0] = chr; buffer[1] = '\0'; } dkstream_puts(oi->s, buffer); } } } } /** Transfer text contents to output, encode characters if necessary. @param oi OI structure. @param s Text to print. */ static void print_text_encoded DK_P2(OI *,oi, char,*s) { char buffer[10], c, *ptr; unsigned char uc; size_t sz; int must_encode; ptr = s; while(*ptr) { c = *ptr; must_encode = 1; if((c >= 'a') && (c <= 'z')) { must_encode = 0; } else { if((c >= 'A') && (c <= 'Z')) { must_encode = 0; } else { if((c >= '0') && (c <= '9')) { must_encode = 0; } else { switch(c) { case '|': case '@': case '^': case '!': case '$': case '%': case '/': case '(': case ')': case '=': case '?': case '~': case '*': case '#': case '_': case '+': case '-': case ':': case ';': case ',': case '.': case ' ': { must_encode = 0; } break; } } } } if(must_encode) { uc = (unsigned char)c; sz = (size_t)uc; strcpy(buffer, default_encoding); buffer[3] = hex_digits[(sz >> 4) & 15]; buffer[4] = hex_digits[sz & 15]; dkstream_puts(oi->s, buffer); } else { buffer[0] = c; buffer[1] = '\0'; dkstream_puts(oi->s, buffer); } ptr++; } } /** Write either style="xxx" parameter or class="xxx" reference. @param oi OI structure. @param s SVG style information structure. */ static void style_or_class DK_P2(OI *,oi, SVGSTY *,s) { if(oi->prep_mods) { kw_out(oi, 0); style_out(oi, s, 0); } else { if(((oi->c)->opt1) & DKFIG_OPT_USE_CSS) { kw_out(oi, 1); kw_out(oi, 80); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 44); dkfig_tool_num_as_string(oi->s, s->classno, oi->lsty); kw_out(oi, 20); kw_out(oi, 0); } else { kw_out(oi, 0); style_out(oi, s, 0); } } } /** Generate output for a text. @param oi OI structure. @param ug Flag: Use group. @return 1 on success, 0 on error. */ static int print_text DK_P2(OI *,oi, int,ug) { int back = 0; dk_fig_text *t = NULL; dk_fig_fonth_t *f = NULL; DRVE *d = NULL; SVGSTY *s = NULL; t = (dk_fig_text *)((oi->o)->data); d = (DRVE *)((oi->o)->drve); if(d) { s = d->st1; } if((t) && (s)) { if(t->text) { f = t->font_handling; switch(f->handling) { case 2: case 3: case 4: case 5: {} break; default: { back = 1; begin_tag(oi, 77); kw_out(oi, 1); if(fabs(t->angle) > DKFIG_EPSILON) { kw_out(oi, 92); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 93); kw_out(oi, 75); put_double(oi, cclx(oi, t->x), 1); kw_out(oi, 1); put_double(oi, ccly(oi, t->y), 1); kw_out(oi, 76); kw_out(oi, 1); kw_out(oi, 94); kw_out(oi, 75); kw_out(oi, 97); dkstream_puts_double(oi->s, drd( dkma_div_double_ok( dkma_mul_double_ok(180.0, t->angle, &(oi->me)), M_PI, &(oi->me) ), oi->c, 1 ) ); kw_out(oi, 76); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 103); kw_out(oi, 20); } else { kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, cclx(oi, t->x), 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, ccly(oi, t->y), 1); kw_out(oi, 20); } style_or_class(oi, s); if(!ug) { svg_drve_write(oi, oi->o, (DRVE *)((oi->o)->drve), 0); } kw_out(oi, 3); if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) { /* UTF-8 encoded */ print_utf8_encoded(oi, t->text); } else { print_text_encoded(oi, t->text); } end_tag(oi, 77); } break; } } } return back; } /** Write point specified by double coordinates in Fig space. @param oi OI structure. @param x X position. @param y Y position. @param w Number of digits after decimal dot. */ static void point_double DK_P4(OI *,oi, double,x, double,y, int,w) { put_double( oi, ccdx(oi, x), w ); kw_out(oi, 55); put_double( oi, ccdy(oi, y), w ); } /** Write point specified by long coordinates in Fig space. @param oi OI structure. @param x X position. @param y Y position. */ static void point_long DK_P3(OI *,oi, long,x, long,y) { point_double( oi, dkma_l_to_double(x), dkma_l_to_double(y), 1 ); } /** Print rectangle/arc box specified by bounding box information b. If da is non-zero, we have an arc box, radius is a. b and a are in output space. @param oi OI structure. @param b Bounding box. @param s Style information structure. @param da Flag: Arc box. @param a Radius for arc box. */ static void print_rect_arc_bb DK_P5(OI *,oi, dk_fig_bb *,b, SVGSTY *,s, int,da, double,a) { begin_tag(oi, 79); kw_out(oi, 1); kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, b->xmin, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, b->ymin, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 16); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, (b->xmax - b->xmin), 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 17); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, (b->ymax - b->ymin), 1); kw_out(oi, 20); if(da) { kw_out(oi, 0); kw_out(oi, 82); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, a, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 83); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, a, 1); kw_out(oi, 20); } style_or_class(oi, s); finish_tag(oi); } /** Draw a rectangle as specified in the bounding-box structure b (specified in output space). @param oi OI structure. @param b Bounding box. @param s SVG style information structure. */ static void print_rect_bb DK_P3(OI *,oi, dk_fig_bb *,b, SVGSTY *,s) { print_rect_arc_bb(oi,b,s,0,0.0); } /** Draw included image. @param oi OI structure. @param ug Flag: Use group. @return 1 on success, 0 on error. */ static int print_image DK_P2(OI *,oi, int,ug) { int back = 0; dk_fig_bb ibb; dk_fig_polyline *p; long *xptr, *yptr; size_t i; SVGSTY *s; double xmin, xmax, ymin, ymax; double ori_width, ori_height, xstart, ystart; double new_width, new_height; unsigned long w, h; int res; p = (dk_fig_polyline *)((oi->o)->data); if(p) { if(p->imagename) { dkfig_tool_bb_reset(&ibb); xptr = p->xvalues; yptr = p->yvalues; for(i = 0; i < p->npoints; i++) { dkfig_tool_bb_add_x(&ibb, cclx(oi, *xptr)); dkfig_tool_bb_add_y(&ibb, ccly(oi, *yptr)); xptr++; yptr++; } if(p->npoints > 0) { back = 1; if(((DRVE *)((oi->o)->drve))->st1) { s = ((DRVE *)((oi->o)->drve))->st1; print_rect_bb(oi, &ibb, s); } xmin = dkfig_tool_bb_get_xmin(&ibb); xmax = dkfig_tool_bb_get_xmax(&ibb); ymin = dkfig_tool_bb_get_ymin(&ibb); ymax = dkfig_tool_bb_get_ymax(&ibb); if(((DRVE *)((oi->o)->drve))->st2) { double lwh; lwh = 0.5 * ccll(oi, (((DRVE *)((oi->o)->drve))->st2)->lw, 1); xmin = dkma_add_double_ok(xmin, lwh, &(oi->me)); xmax = dkma_sub_double_ok(xmax, lwh, &(oi->me)); ymin = dkma_add_double_ok(ymin, lwh, &(oi->me)); ymax = dkma_sub_double_ok(ymax, lwh, &(oi->me)); } ori_width = dkma_sub_double_ok(xmax, xmin, &(oi->me)); ori_height = dkma_sub_double_ok(ymax, ymin, &(oi->me)); new_width = ori_width; new_height = ori_height; xstart = xmin; ystart = ymin; $? ". x=%lg y=%lg w=%lg h=%lg", xstart, ystart, new_width, new_height res = dkfig_tool2_get_image_size(oi->c, p->imagename, &w, &h); if(res) { if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) { double ls, rs; $? ". correction needed" ls = dkma_div_double_ok( dkma_l_to_double(h), dkma_l_to_double(w), &(oi->me) ); rs = dkma_div_double_ok(ori_height, ori_width, &(oi->me)); if(ls > rs) { new_width = dkma_mul_double_ok( new_height, dkma_div_double_ok( dkma_l_to_double(w), dkma_l_to_double(h), &(oi->me) ), &(oi->me) ); switch(((oi->c)->image_align) & 3) { case DKFIG_ALIGN_H_CENTERED: { xstart = dkma_add_double_ok( xstart, (0.5 * dkma_sub_double_ok(ori_width, new_width, &(oi->me))), &(oi->me) ); } break; case DKFIG_ALIGN_H_RIGHT: { xstart = dkma_add_double_ok( xstart, dkma_sub_double_ok(ori_width, new_width, &(oi->me)), &(oi->me) ); } break; } } else { new_height = dkma_mul_double_ok( new_width, dkma_div_double_ok( dkma_l_to_double(h), dkma_l_to_double(w), &(oi->me) ), &(oi->me) ); switch((((oi->c)->image_align) >> 2) & 3) { case DKFIG_ALIGN_V_CENTERED: { ystart = dkma_add_double_ok( ystart, (0.5 * dkma_sub_double_ok(ori_height, new_height, &(oi->me))), &(oi->me) ); } break; case DKFIG_ALIGN_V_BOTTOM: { ystart = dkma_add_double_ok( ystart, dkma_sub_double_ok(ori_height, new_height, &(oi->me)), &(oi->me) ); } break; } } } } else { dkfig_tool2_msg3(oi->c, DK_LOG_LEVEL_WARNING, 95, 92, p->imagename); } $? ". x=%lg y=%lg w=%lg h=%lg", xstart, ystart, new_width, new_height begin_tag(oi, 112); kw_out(oi, 1); kw_out(oi, 14); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, xstart, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 15); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, ystart, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 16); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, new_width, 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 17); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, new_height, 1); kw_out(oi, 20); kw_out(oi, 0); dkstream_puts(oi->s, xlc00[0]); kw_out(oi, 19); kw_out(oi, 20); dkstream_puts(oi->s, p->imagename); kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 4); kw_out(oi, 3); kw_out(oi, 0); if(((DRVE *)((oi->o)->drve))->st2) { s = ((DRVE *)((oi->o)->drve))->st2; print_rect_bb(oi, &ibb, s); } } } } return back; } /** Check the corner radius for arc boxes, correct (decrease) radius if necessary. @param rx Original corner radius. @param oi OI structure. @param mini Minimum side length. @param maxi Maximum side length. @return Corner radius. */ static double check_rx DK_P4(double,rx, OI *,oi, double,mini, double,maxi) { double back, distance; back = rx; if(back < 0.0) { back = 0.0 - back; } distance = fabs(dkma_sub_double_ok(maxi, mini, &(oi->me))); if(back > (0.5 * distance)) { back = 0.5 * distance; } return back; } /** Eraw a polyline/polygon, spline, ellipse or arc. (Everything except text or included image) @param oi OI structure. @param ug Flag: Use group. @return 1 on success, 0 on error. */ static int print_path_object DK_P2(OI *,oi, int,ug) { int back = 0; dk_fig_arc *pa; dk_fig_spline *ps; dk_fig_polyline *pp; dk_fig_ellipse *pe; DRVE *d = NULL; SVGSTY *s = NULL; d = (DRVE *)((oi->o)->drve); if(d) { s = d->st1; if(s) { switch((oi->o)->objtype) { case DK_FIG_OBJ_ARC: { pa = (dk_fig_arc *)((oi->o)->data); if(pa) { double aa, ae, p1x, p1y, p2x, p2y, r; int islong; aa = ae = p1x = p1y = p2x = p2y = 0.0; islong = 0; r = ccdr(oi, (pa->calc).ra); aa = (pa->calc).astart; if((!(((oi->o)->fpd).cl)) && ((((oi->o)->fpd).ar) & 2)) { aa = dkma_add_double_ok(aa, pa->lba, &(oi->me)); } ae = dkma_add_double_ok( (pa->calc).astart, (pa->calc).alength, &(oi->me) ); if((!(((oi->o)->fpd).cl)) && ((((oi->o)->fpd).ar) & 1)) { ae = dkma_sub_double_ok(ae, pa->rba, &(oi->me)); } p1x = dkma_add_double_ok( (pa->calc).xm, (((pa->calc).ra) * cos(aa)), &(oi->me) ); p2x = dkma_add_double_ok( (pa->calc).xm, (((pa->calc).ra) * cos(ae)), &(oi->me) ); if(dkfig_tool_invert_y(oi->d)) { p1y = dkma_sub_double_ok( (pa->calc).ym, (((pa->calc).ra) * sin(aa)), &(oi->me) ); p2y = dkma_sub_double_ok( (pa->calc).ym, (((pa->calc).ra) * sin(ae)), &(oi->me) ); } else { p1y = dkma_add_double_ok( (pa->calc).ym, (((pa->calc).ra) * sin(aa)), &(oi->me) ); p2y = dkma_add_double_ok( (pa->calc).ym, (((pa->calc).ra) * sin(ae)), &(oi->me) ); } while(ae < aa) { ae = dkma_add_double_ok(ae, (2.0 * M_PI), &(oi->me)); } if(dkma_sub_double_ok(ae, aa, &(oi->me)) >= M_PI) { islong = 1; } else { islong = 0; } back = 1; begin_tag(oi, 98); style_or_class(oi, s); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); if(((oi->o)->fpd).cl) { /* pie-wedge */ kw_out(oi, 100); point_double(oi, (pa->calc).xm, (pa->calc).ym, 1); kw_out(oi, 1); kw_out(oi, 101); point_double(oi, p1x, p1y, 1); kw_out(oi, 0); } else { /* open arc */ kw_out(oi, 100); point_double(oi, p1x, p1y, 1); } kw_out(oi, 1); kw_out(oi, 102); put_double(oi, r, 1); kw_out(oi, 1); put_double(oi, r, 1); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); kw_out(oi, (islong ? 104 : 103)); kw_out(oi, 1); kw_out(oi, 103); kw_out(oi, 1); point_double(oi, p2x, p2y, 1); if(((oi->o)->fpd).cl) { /* pie-wedge */ kw_out(oi, 0); kw_out(oi, 101); point_double(oi, (pa->calc).xm, (pa->calc).ym, 1); kw_out(oi, 105); } kw_out(oi, 20); kw_out(oi, 0); finish_tag(oi); } } break; case DK_FIG_OBJ_SPLINE: { dk_fig_bezier_point *bpptr; size_t nsegs, li, ri, maxli; ps = (dk_fig_spline *)((oi->o)->data); if(ps) { if((ps->nbpoints) >= 2) { begin_tag(oi, 98); style_or_class(oi, s); kw_out(oi, 99); kw_out(oi, 19); kw_out(oi, 20); bpptr = ps->bpoints; nsegs = ps->nbpoints - 1; if(((oi->o)->fpd).cl) { nsegs = ps->nbpoints; } if((!(((oi->o)->fpd).cl)) && ((((oi->o)->fpd).ar) & 2)) { /* moveto point pa */ kw_out(oi, 100); point_double(oi,(ps->pa).value.x,(ps->pa).value.y, 1); kw_out(oi, 0); /* bezier to point pa2 */ kw_out(oi, 106); point_double(oi, (ps->pa).rcontrol.x, (ps->pa).rcontrol.y, 1); kw_out(oi, 1); point_double(oi, (ps->pa2).lcontrol.x, (ps->pa2).lcontrol.y, 1); kw_out(oi, 1); point_double(oi, (ps->pa2).value.x, (ps->pa2).value.y, 1); li = ps->normals; } else { /* moveto point 0 */ kw_out(oi, 100); point_double(oi,bpptr[0].value.x,bpptr[0].value.y, 1); li = 0; } kw_out(oi, 0); if((ps->normale > 0)||(((oi->o)->fpd).cl)||(!((((oi->o)->fpd).ar) & 1))) { maxli = ps->nbpoints - 2; if(((oi->o)->fpd).cl) { maxli = ps->nbpoints - 1; } if((!(((oi->o)->fpd).cl)) && (((oi->o)->fpd).ar & 1)) { maxli = ps->normale - 1; } while(li <= maxli) { ri = li + 1; if(ri >= ps->nbpoints) { ri = 0; } kw_out(oi, 106); point_double(oi, bpptr[li].rcontrol.x, bpptr[li].rcontrol.y, 1); kw_out(oi, 1); point_double(oi, bpptr[ri].lcontrol.x, bpptr[ri].lcontrol.y, 1); kw_out(oi, 1); point_double(oi, bpptr[ri].value.x, bpptr[ri].value.y, 1); kw_out(oi, 0); li++; } } if(((oi->o)->fpd).cl) { kw_out(oi, 105); } else { if((((oi->o)->fpd).ar) & 1) { kw_out(oi, 106); point_double(oi, (ps->pe2).rcontrol.x, (ps->pe2).rcontrol.y, 1); kw_out(oi, 1); point_double(oi, (ps->pe).lcontrol.x, (ps->pe).lcontrol.y, 1); kw_out(oi, 1); point_double(oi, (ps->pe).value.x, (ps->pe).value.y, 1); kw_out(oi, 0); } } kw_out(oi, 20); kw_out(oi, 0); finish_tag(oi); } } } break; case DK_FIG_OBJ_POLYLINE: { pp = (dk_fig_polyline *)((oi->o)->data); if(pp) { long *xptr, *yptr; size_t i, npoints; double rx; int urx, wr_nl, wr_no; dk_fig_bb ibb; urx = 0; rx = 0.0; switch((oi->o)->subtype) { case 5: { /* image, handled somewhere else */ } break; case 2: /* box */ case 4: { /* arc-box */ dkfig_tool_bb_reset(&ibb); xptr = pp->xvalues; yptr = pp->yvalues; for(i = 0; i < pp->npoints; i++) { dkfig_tool_bb_add_x(&ibb, cclx(oi, *xptr)); dkfig_tool_bb_add_y(&ibb, ccly(oi, *yptr)); xptr++; yptr++; } if(pp->npoints > 0) { if((oi->o)->subtype == 4) { if(pp->radius > 0L) { urx = 1; rx = ccll(oi, pp->radius, 0); rx = check_rx(rx, oi, ibb.xmin, ibb.xmax); rx = check_rx(rx, oi, ibb.ymin, ibb.ymax); } } print_rect_arc_bb(oi, &ibb, s, urx, rx); back = 1; } } break; case 3: { /* polygon */ xptr = pp->xvalues; yptr = pp->yvalues; npoints = pp->npoints; if(npoints) { back = 1; if(xptr[0] == xptr[npoints-1]) { if(yptr[0] == yptr[npoints-1]) { npoints--; } } begin_tag(oi, 84); style_or_class(oi, s); kw_out(oi, 86); kw_out(oi, 19); kw_out(oi, 20); wr_nl = 0; wr_no = 0; for(i = 0; i < npoints; i++) { if(i) { /* kw_out(oi, (wr_nl ? 0 : 1)); if(wr_nl) { wr_nl = 0; } if(wr_no >= 3) { wr_no = 0; wr_nl = 1; } else { wr_no++; } */ kw_out(oi, 0); } point_long(oi, xptr[i], yptr[i]); } kw_out(oi, 20); kw_out(oi, 0); finish_tag(oi); } } break; case 1: { /* polyline */ xptr = pp->xvalues; yptr = pp->yvalues; npoints = pp->npoints; if(npoints) { back = 1; begin_tag(oi, 85); style_or_class(oi, s); kw_out(oi, 86); kw_out(oi, 19); kw_out(oi, 20); wr_nl = 0; wr_no = 0; for(i = 0; i < npoints; i++) { if(i) { /* kw_out(oi, (wr_nl ? 0 : 1)); if(wr_nl) { wr_nl = 0; } if(wr_no >= 3) { wr_no = 0; wr_nl = 1; } else { wr_no++; } */ kw_out(oi, 0); } if((i == 0) && ((((oi->o)->fpd).ar) & 2)) { point_double(oi, (pp->pa).x, (pp->pa).y, 1); } else { if((i == (npoints - 1)) && ((((oi->o)->fpd).ar) & 1)) { point_double(oi, (pp->pe).x, (pp->pe).y, 1); } else { point_long(oi, xptr[i], yptr[i]); } } } kw_out(oi, 20); kw_out(oi, 0); finish_tag(oi); } } break; } } } break; case DK_FIG_OBJ_ELLIPSE: { pe = (dk_fig_ellipse *)((oi->o)->data); if(pe) { if((pe->radiusx) == (pe->radiusy)) { begin_tag(oi, 90); kw_out(oi, 1); kw_out(oi, 87); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, cclx(oi, pe->centerx), 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 88); kw_out(oi, 19); kw_out(oi, 20); /* cy */ put_double(oi, ccly(oi, pe->centery), 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 89); kw_out(oi, 19); kw_out(oi, 20); /* r */ put_double(oi, cclr(oi, pe->radiusx), 1); kw_out(oi, 20); style_or_class(oi, s); if(!ug) { svg_drve_write(oi, oi->o, (DRVE *)((oi->o)->drve), 0); } finish_tag(oi); } else { begin_tag(oi, 91); kw_out(oi, 1); kw_out(oi, 92); kw_out(oi, 19); kw_out(oi, 20); kw_out(oi, 93); kw_out(oi, 75); put_double(oi, cclx(oi, pe->centerx), 1); kw_out(oi, 1); put_double(oi, ccly(oi, pe->centery), 1); kw_out(oi, 76); if(fabs(pe->angle) > DKFIG_EPSILON) { kw_out(oi, 1); kw_out(oi, 94); kw_out(oi, 75); kw_out(oi, 97); put_double( oi, dkma_mul_double_ok( pe->angle, dkma_div_double_ok(180.0, M_PI, &(oi->me)), &(oi->me) ), 1 ); kw_out(oi, 76); } kw_out(oi, 20); kw_out(oi, 0); kw_out(oi, 95); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, cclr(oi, pe->radiusx), 1); kw_out(oi, 20); kw_out(oi, 1); kw_out(oi, 96); kw_out(oi, 19); kw_out(oi, 20); put_double(oi, cclr(oi, pe->radiusy), 1); kw_out(oi, 20); style_or_class(oi, s); if(!ug) { svg_drve_write(oi, oi->o, (DRVE *)((oi->o)->drve), 0); } finish_tag(oi); } } } break; } } } return back; } /** Draw arrowhead, this is typically done after drawing the line. @param oi OI structure. @param o Current object. @param ah Arrowhead structure. @param d Driver-specific extension data for Fig object. @param s SVG style information structure for object. */ static void arrow_head DK_P5(OI *,oi, OBJ *,o, AH *,ah, DRVE *,d, SVGSTY *,s) { if((ah->type) > 0) { begin_tag(oi, 84); } else { begin_tag(oi, 85); } style_or_class(oi, s); kw_out(oi, 86); kw_out(oi, 19); kw_out(oi, 20); point_double(oi, (ah->p1).x, (ah->p1).y, 1); kw_out(oi, 1); point_double(oi, (ah->p2).x, (ah->p2).y, 1); kw_out(oi, 1); point_double(oi, (ah->p3).x, (ah->p3).y, 1); if((ah->numpoints) > 3) { kw_out(oi, 1); point_double(oi, (ah->p4).x, (ah->p4).y, 1); } kw_out(oi, 20); kw_out(oi, 0); finish_tag(oi); } /** Handle one graphics object. @param oi OI structure. @return 1 on success, 0 on error. */ static int output_object DK_P1(OI *,oi) { int back = 1; unsigned long backupopt1, backupopt2; int use_link, use_group, how, backupia; DRVE *d; SVGSTY *s; $? "+ output_object" backupopt1 = (oi->c)->opt1; backupopt2 = (oi->c)->opt2; backupia = (oi->c)->image_align; /* handle special comments */ if((oi->o)->osci) { (void)handle_spc_for_object(oi, oi->o, (oi->o)->osci, 0, 0); } use_link = use_group = how = 0; use_link = check_link((DRVE *)((oi->o)->drve)); use_group = check_group(oi); if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) { kw_out(oi, 113); kw_out(oi, 115); dkstream_puts_ul(oi->s, (oi->o)->lineno); kw_out(oi, 55); kw_out(oi, 1); kw_out(oi, 116); dkstream_puts_ul(oi->s, (unsigned long)((oi->o)->layer)); kw_out(oi, 114); kw_out(oi, 0); } if(use_link) { begin_tag(oi, 33); print_a_contents(oi, (DRVE *)((oi->o)->drve)); kw_out(oi, 0); kw_out(oi, 3); kw_out(oi, 0); } if(use_group) { begin_tag(oi, 34); if(how != 2) { svg_drve_write(oi, oi->o, (DRVE *)((oi->o)->drve), 0); } kw_out(oi, 3); kw_out(oi, 0); } /* print object */ how = get_how(oi->o); switch(how) { case 1: { /* text */ print_text(oi, use_group); } break; case 2: { /* included image */ print_image(oi, use_group); } break; default: { /* path object */ int must_draw = 1; if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BG_RECTANGLE) { int wbgr = 0; if(((oi->c)->opt2) & DKFIG_OPT_WHITE_BGRECT) { wbgr = 1; } if(dkfig_tool2_obj_is_bg_rect(oi->o, wbgr)) { must_draw = 0; } } if(must_draw) { print_path_object(oi, use_group); } } break; } /* forward arrow */ if((!(((oi->o)->fpd).cl)) && ((((oi->o)->fpd).ar) & 1)) { d = (DRVE *)((oi->o)->drve); if(d) { s = d->st2; if(s) { arrow_head(oi, oi->o, &(((oi->o)->fpd).ahf), d, s); } } } /* backward arrow */ if((!(((oi->o)->fpd).cl)) && ((((oi->o)->fpd).ar) & 2)) { d = (DRVE *)((oi->o)->drve); if(d) { s = d->st3; if(s) { arrow_head(oi, oi->o, &(((oi->o)->fpd).ahb), d, s); } } } if(use_group) { end_tag(oi, 34); } if(use_link) { end_tag(oi, 33); } (oi->c)->opt1 = backupopt1; (oi->c)->opt2 = backupopt2; (oi->c)->image_align = backupia; $? "- output_object %d", back return back; } /** Write title and desc sections. @param oi OI structure. @return 1 on success, 0 on error. */ static int svg_title_and_desc DK_P1(OI *,oi) { int back = 1; $? "+ svg_title_and_desc" begin_tag(oi, 25); kw_out(oi, 3); dkstream_puts(oi->s, (((oi->c)->ifn2) ? ((oi->c)->ifn2) : (name_stdin))); end_tag(oi, 25); begin_tag(oi, 26); kw_out(oi, 3); kw_out(oi, 27); end_tag(oi, 26); $? "- svg_title_and_desc" return back; } /** Write JavaScript code from the named library files into the defs section. @param oi OI structure. @return 1 on success, 0 on error. */ static int write_js_libraries DK_P1(OI *,oi) { int back = 1; int is_first; dk_fig_opt *fo; FILE *fipo; char inputline[512], *sptr; $? "+ write_js_libraries" if((oi->jsl) && (oi->jsli)) { is_first = 1; dksto_it_reset(oi->jsli); while((fo = (dk_fig_opt *)dksto_it_next(oi->jsli)) != NULL) { if(fo->name) { if((oi->c)->app) { fipo = dkapp_fopen((oi->c)->app, fo->name, str_mode_open_read); } else { fipo = dksf_fopen(fo->name, str_mode_open_read); } if(fipo) { if(is_first) { begin_tag(oi, 32); kw_out(oi, 1); kw_out(oi, 29); kw_out(oi, 3); kw_out(oi, 30); kw_out(oi, 0); is_first = 0; } while(fgets(inputline, sizeof(inputline), fipo)) { sptr = dkstr_start(inputline, NULL); if(sptr) { dkstr_chomp(sptr, NULL); dkstream_puts(oi->s, inputline); } kw_out(oi, 0); } fclose(fipo); } else { /* Warning: Failed to read file */ if((oi->c)->app) { dkapp_err_fopenr((oi->c)->app, fo->name); } } } } if(!is_first) { kw_out(oi, 31); end_tag(oi, 32); } } $? "- write_js_libraries %d", back return back; } /** Write file the defs section which consists of patterns, fonts, styles and JavaScript code. @param oi OI structure. */ static int svg_defs DK_P1(OI *,oi) { int back = 1; int is_first; size_t i, ft; SVGPAT *pat; SVGSTY *sty; dk_one_font_mapping_t *pofm; dk_font_replacement_t *pfr; char *fontfamilyname; char *fontlocation; char *fontfilename; char *fontid; char *fontformat; $? "+ svg_defs" back = write_js_libraries(oi); begin_tag(oi, 28); kw_out(oi, 3); kw_out(oi, 0); if(oi->pati) { dksto_it_reset(oi->pati); while((pat = (SVGPAT *)dksto_it_next(oi->pati)) != NULL) { pattern_out(oi, pat); } } is_first = 1; if((oi->urw_dir) || (oi->fontmap)) { $? ". urw dir or fontmap" for(i = 0; i < 35; i++) { if((oi->fnused)[i]) { if(is_first) { begin_tag(oi, 38); kw_out(oi, 1); kw_out(oi, 39); kw_out(oi, 3); kw_out(oi, 30); kw_out(oi, 0); is_first = 0; dkstream_set_double_no_exponent(oi->s, 1); } if(oi->fontmap) { $? ". have fontmap" pofm = dkfont_get_one_font(oi->fontmap, i); if(pofm) { $? ". have pofm" dkfont_one_font_reset(pofm); while((pfr = dkfont_one_font_get(pofm)) != NULL) { $? ". yet another font to visit" if(dkfont_rep_check_driver(pfr, kw[5])) { $? ". font is for svg" fontfamilyname = dkfont_rep_get_family(pfr); fontlocation = dkfont_rep_get_location(pfr); fontfilename = dkfont_rep_get_source_name(pfr); fontid = dkfont_rep_get_name(pfr); fontformat = dkfont_rep_get_font_type(pfr); if(fontfamilyname) { $? ". fontfamilyname=\"%s\"", fontfamilyname if(fontlocation) { $? ". fontlocation=\"%s\"", fontlocation if(fontfilename) { $? ". fontfilename=\"%s\"", fontfilename if(fontid) { $? ". fontid=\"%s\"", fontid if(fontformat) { $? ". fontformat=\"%s\"", fontformat kw_out(oi, 108); kw_out(oi, 1); kw_out(oi, 41); kw_out(oi, 0); kw_out(oi, 46); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, 107); dkstream_puts(oi->s, fontfamilyname); kw_out(oi, 107); kw_out(oi, 43); kw_out(oi, 0); ft = dkfont_get_features(i); kw_out(oi, 47); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_IT) ? 60 : 59)); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 48); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_BD) ? 61 : 59)); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 109); kw_out(oi, 74); kw_out(oi, 75); kw_out(oi, 20); dkstream_puts(oi->s, fontlocation); kw_out(oi, 4); dkstream_puts(oi->s, fontfilename); kw_out(oi, 45); dkstream_puts(oi->s, fontid); kw_out(oi, 20); kw_out(oi, 76); kw_out(oi, 1); kw_out(oi, 110); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 42); kw_out(oi, 0); } else { $? "! no font format" } } else { $? "! no font id" } } else { $? "! no file name" } } else { $? "! no location" } } else { $? "! no family name" } } else { $? ". not an SVG font" } } } else { $? "! no pofm" } } else { kw_out(oi, 108); kw_out(oi, 1); kw_out(oi, 41); kw_out(oi, 0); kw_out(oi, 46); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, 107); dkstream_puts(oi->s, urw_svg_font_families[i]); kw_out(oi, 107); kw_out(oi, 43); kw_out(oi, 0); ft = dkfont_get_features(i); kw_out(oi, 47); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_IT) ? 60 : 59)); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 48); kw_out(oi, 24); kw_out(oi, 1); kw_out(oi, ((ft & DK_FONT_FEATURE_BD) ? 61 : 59)); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 109); kw_out(oi, 74); kw_out(oi, 75); kw_out(oi, 20); dkstream_puts(oi->s, oi->urw_dir); kw_out(oi, 4); dkstream_puts( oi->s, dkfont_get_gs_file_name(i) ); kw_out(oi, 40); kw_out(oi, 5); kw_out(oi, 45); dkstream_puts( oi->s, dkfont_get_svg_font_id(i) ); kw_out(oi, 20); kw_out(oi, 76); kw_out(oi, 1); kw_out(oi, 110); kw_out(oi, 43); kw_out(oi, 0); kw_out(oi, 42); kw_out(oi, 0); } } } } if(!(oi->prep_mods)) { if(((oi->c)->opt1) & DKFIG_OPT_USE_CSS) { if(oi->styi) { dksto_it_reset(oi->styi); while((sty = (SVGSTY *)dksto_it_next(oi->styi)) != NULL) { if(is_first) { begin_tag(oi, 38); kw_out(oi, 1); kw_out(oi, 39); kw_out(oi, 3); kw_out(oi, 30); kw_out(oi, 0); dkstream_set_double_no_exponent(oi->s, 1); } style_out(oi, sty, 1); is_first = 0; } } } } if(!is_first) { kw_out(oi, 31); end_tag(oi, 38); dkstream_set_double_no_exponent(oi->s, 0); } end_tag(oi, 28); $? "- svg_defs" return back; } /** Write output. @param oi OI structure. */ static int output_pass DK_P1(OI *,oi) { int back = 1; $? "+ output_pass" if(!(((oi->c)->opt1) & DKFIG_OPT_SVG_EMBEDDED)) { svg_document_type(oi); } svg_start_tag(oi); svg_title_and_desc(oi); svg_defs(oi); dksto_it_reset(oi->fli); while((oi->o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) { $? ". object in line %lu", (oi->o)->lineno if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, (oi->o)->lineno); } oi->me = 0; if(!output_object(oi)) { back = 0; } if(oi->me) { /* MATH PROBLEM */ dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_ERROR, 13); } oi->me = 0; if((oi->c)->app) { dkapp_set_source_lineno((oi->c)->app, 0UL); } } svg_end_tag(oi); $? "- output_pass %d", back return back; } /** Clean up after writing output. This function releases the pattern and style information gathered in the preparation_pass(). The collection of JavaScript library file names is released too. @param oi OI structure. @return 1 on success, 0 on error. */ static int cleanup_pass DK_P1(OI *,oi) { int back = 0; char *cptr; dk_fig_opt *fo; SVGSTY *s; SVGPAT *p; $? "+ cleanup_pass" if(oi->fontmap) { dkfont_mapping_close(oi->fontmap); oi->fontmap = NULL; } if(oi->styi) { dksto_it_reset(oi->styi); while((s = (SVGSTY *)dksto_it_next(oi->styi)) != NULL) { svg_style_del(s); } dksto_it_close(oi->styi); } oi->styi = NULL; if(oi->sty) { dksto_close(oi->sty); } oi->sty = NULL; if(oi->pati) { dksto_it_reset(oi->pati); while((p = (SVGPAT *)dksto_it_next(oi->pati)) != NULL) { svg_pat_del(p); } dksto_it_close(oi->pati); } oi->pati = NULL; if(oi->pat) { dksto_close(oi->pat); } oi->pat = NULL; if(oi->fli) { dk_fig_object *o; dksto_it_reset(oi->fli); while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) { if(o->drve) { svg_drve_delete((dk_fig_svg_drve *)(o->drve)); o->drve = NULL; } } dksto_it_close(oi->fli); oi->fli = NULL; } if((oi->dro)->drve) { svg_drve_delete((DRVE *)((oi->dro)->drve)); (oi->dro)->drve = NULL; } if(oi->fl) { dksto_close(oi->fl); oi->fl = NULL; } if(oi->jsli) { dksto_it_reset(oi->jsli); while((fo = (dk_fig_opt *)dksto_it_next(oi->jsli)) != NULL) { $? ". destroying js library name %s", TR_STR(fo->name) dkfig_opt_delete(fo); } } oi->jsli = NULL; if(oi->jsl) { dksto_close(oi->jsl); } oi->jsl = NULL; if(oi->urw_dir) { cptr = oi->urw_dir; $? ". releasing URW dir \"%s\"", cptr dk_delete(cptr); } oi->urw_dir = NULL; $? "- cleanup_pass %d", back return back; } /** The preparation/output/cleanup sequence. @param oi OI structure. @return 1 on success, 0 on error. */ static int run_the_passes DK_P1(OI *,oi) { int back = 0; $? "+ run_the_passes" if(preparation_pass(oi)) { back = output_pass(oi); } cleanup_pass(oi); $? "- run_the_passes %d", back return back; } /** SVG output driver function. @param c Conversion job structure. @return 1 on success, 0 on error. */ int dkfig_output_svg DK_P1(dk_fig_conversion *,c) { int back = 0; char fnused[35]; size_t i; OI oi; $? "+ dkfig_output_svg" if(c) { null_oi(&oi); if((c->opt1) & DKFIG_OPT_PREPARE_FOR_MODS) { oi.prep_mods = 1; } for(i = 0; i < 35; i++) { fnused[i] = 0x00; }; oi.fnused = fnused; oi.c = c; oi.s = c->ostrm; if(c->ostrm) { oi.dro = c->drwng; if(c->drwng) { oi.d = (dk_fig_drawing *)((oi.dro)->data); if((oi.dro)->data) { back = run_the_passes(&oi); } } } } $? "- dkfig_output_svg %d", back return back; }