/* File: svgdraw.c * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit * simulation. * Copyright (C) 1998-2021 Stefan Frederik Schippers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "xschem.h" #define X_TO_SVG(x) ( (x+xctx->xorigin)* xctx->mooz ) #define Y_TO_SVG(y) ( (y+xctx->yorigin)* xctx->mooz ) static FILE *fd; typedef struct { int red; int green; int blue; } Svg_color; static Svg_color *svg_colors; static char svg_font_weight[80] = "normal"; /* normal, bold, bolder, lighter */ static char svg_font_family[80] = "Sans-Serif"; /* Serif, Monospace, Helvetica, Arial */ static char svg_font_style[80] = "normal"; /* normal, italic, oblique */ static double svg_linew; /* current width of lines / rectangles */ static void svg_restore_lw(void) { svg_linew = xctx->lw*1.2; } static void svg_xdrawline(int layer, int bus, double x1, double y1, double x2, double y2, int dash) { fprintf(fd,"zoom, 1.4*dash/xctx->zoom); if(bus) fprintf(fd, "style=\"stroke-width:%g;\" ", BUS_WIDTH * svg_linew); fprintf(fd,"d=\"M%g %gL%g %g\"/>\n", x1, y1, x2, y2); } static void svg_xdrawpoint(int layer, double x1, double y1) { fprintf(fd,"\n", x1, y1, x1+1.0, y1, x1+1.0, y1+1.0, x1, y1+1.0, x1, y1); } static void svg_xfillrectangle(int layer, double x1, double y1, double x2, double y2, int dash) { fprintf(fd,"zoom, 1.4*dash/xctx->zoom); fprintf(fd,"d=\"M%g %gL%g %gL%g %gL%g %gL%g %gz\"/>\n", x1, y1, x2, y1, x2, y2, x1, y2, x1, y1); } static void svg_drawpolygon(int c, int what, double *x, double *y, int points, int fill, int dash) { double x1,y1,x2,y2; double xx, yy; int i; polygon_bbox(x, y, points, &x1,&y1,&x2,&y2); x1=X_TO_SVG(x1); y1=Y_TO_SVG(y1); x2=X_TO_SVG(x2); y2=Y_TO_SVG(y2); if( !rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) { return; } fprintf(fd, "zoom, 1.4*dash/xctx->zoom); if(!fill) { fprintf(fd,"style=\"fill:none;\" "); } fprintf(fd, "d=\""); for(i=0;i\n"); */ fprintf(fd, "\"/>\n"); } static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash) { double x1,y1,x2,y2; x1=X_TO_SVG(rectx1); y1=Y_TO_SVG(recty1); x2=X_TO_SVG(rectx2); y2=Y_TO_SVG(recty2); if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) { svg_xfillrectangle(gc, x1,y1,x2,y2, dash); } } static void svg_drawcircle(int gc, int fillarc, double x,double y,double r,double a, double b) { double xx,yy,rr; double x1, y1, x2, y2; xx=X_TO_SVG(x); yy=Y_TO_SVG(y); rr=r*xctx->mooz; arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); x1=X_TO_SVG(x1); y1=Y_TO_SVG(y1); x2=X_TO_SVG(x2); y2=Y_TO_SVG(y2); if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) { fprintf(fd, "\n", gc, xx, yy, rr); } } static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a, double b, int dash) { double xx,yy,rr; double x1, y1, x2, y2; double xx1, yy1, xx2, yy2; int fs, fa; xx=X_TO_SVG(x); yy=Y_TO_SVG(y); rr=r*xctx->mooz; arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2); x1=X_TO_SVG(x1); y1=Y_TO_SVG(y1); x2=X_TO_SVG(x2); y2=Y_TO_SVG(y2); if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) ) { if(b == 360.) { fprintf(fd, "zoom, 1.4*dash/xctx->zoom); if(!fillarc) fprintf(fd, "style=\"fill:none;\""); fprintf(fd, "/>\n"); } else { xx1 = rr * cos(a * XSCH_PI / 180.) + xx; yy1 = -rr * sin(a * XSCH_PI / 180.) + yy; xx2 = rr * cos((a + b) * XSCH_PI / 180.) + xx; yy2 = -rr * sin((a + b) * XSCH_PI / 180.) + yy; fa = b > 180 ? 1 : 0; fs = b > 0 ? 0 : 1; fprintf(fd,"zoom, 1.4*dash/xctx->zoom); if(!fillarc) { fprintf(fd,"style=\"fill:none;\" "); fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2); } else { fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2, xx, yy); } } } } static void svg_drawline(int gc, int bus, double linex1,double liney1,double linex2,double liney2, int dash) { double x1,y1,x2,y2; x1=X_TO_SVG(linex1); y1=Y_TO_SVG(liney1); x2=X_TO_SVG(linex2); y2=Y_TO_SVG(liney2); if( clip(&x1,&y1,&x2,&y2) ) { svg_xdrawline(gc, bus, x1, y1, x2, y2, dash); } } static void svg_draw_string_line(int layer, char *s, double x, double y, double size, short rot, short flip, int lineno, double fontheight, double fontascent, double fontdescent, int llength, int no_of_lines, int longest_line) { double ix, iy; short rot1; int line_delta; double lines; char col[20]; if(color_ps) my_snprintf(col, S(col), "#%02x%02x%02x", svg_colors[layer].red, svg_colors[layer].green, svg_colors[layer].blue); else if(tclgetboolvar("dark_colorscheme")) my_snprintf(col, S(col), "#%02x%02x%02x", 255, 255, 255); else my_snprintf(col, S(col), "#%02x%02x%02x", 0, 0, 0); if(s==NULL) return; if(llength==0) return; line_delta = lineno*fontheight; lines = (no_of_lines-1)*fontheight; ix=X_TO_SVG(x); iy=Y_TO_SVG(y); if(rot&1) { rot1=3; } else rot1=0; if( rot==0 && flip==0) {iy+=line_delta+fontascent;} else if(rot==1 && flip==0) {iy+=longest_line;ix=ix-fontheight+fontascent-lines+line_delta;} else if(rot==2 && flip==0) {iy=iy-fontheight-lines+line_delta+fontascent; ix=ix-longest_line;} else if(rot==3 && flip==0) {ix+=line_delta+fontascent;} else if(rot==0 && flip==1) {ix=ix-longest_line;iy+=line_delta+fontascent;} else if(rot==1 && flip==1) {ix=ix-fontheight+line_delta-lines+fontascent;} else if(rot==2 && flip==1) {iy=iy-fontheight-lines+line_delta+fontascent;} else if(rot==3 && flip==1) {iy=iy+longest_line;ix+=line_delta+fontascent;} fprintf(fd,"mooz); if(strcmp(svg_font_weight, "normal")) fprintf(fd, "font-weight=\"%s\" ", svg_font_weight); if(strcmp(svg_font_style, "normal")) fprintf(fd, "font-style=\"%s\" ", svg_font_style); if(strcmp(svg_font_family, tclgetvar("svg_font_name"))) fprintf(fd, "style=\"font-family:%s;\" ", svg_font_family); if(rot1) fprintf(fd, "transform=\"translate(%g, %g) rotate(%d)\" ", ix, iy, rot1*90); else fprintf(fd, "transform=\"translate(%g, %g)\" ", ix, iy); fprintf(fd, ">"); while(*s) { switch(*s) { case '<': fputs("<", fd); break; case '>': fputs(">", fd); break; case '&': fputs("&", fd); break; default: fputc(*s, fd); } s++; } fprintf(fd, "\n"); } static void svg_draw_string(int layer, const char *str, short rot, short flip, int hcenter, int vcenter, double x,double y, double xscale, double yscale) { char *tt, *ss, *sss=NULL; double textx1,textx2,texty1,texty2; char c; int lineno=0; double size, height, ascent, descent; int llength=0, no_of_lines, longest_line; if(str==NULL) return; size = xscale*52.; height = size*xctx->mooz * 1.147; ascent = size*xctx->mooz * 0.908; descent = size*xctx->mooz * 0.219; text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y, &textx1,&texty1,&textx2,&texty2, &no_of_lines, &longest_line); if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,textx1,texty1,textx2,texty2)) { return; } if(hcenter) { if(rot == 0 && flip == 0 ) { x=textx1;} if(rot == 1 && flip == 0 ) { y=texty1;} if(rot == 2 && flip == 0 ) { x=textx2;} if(rot == 3 && flip == 0 ) { y=texty2;} if(rot == 0 && flip == 1 ) { x=textx2;} if(rot == 1 && flip == 1 ) { y=texty2;} if(rot == 2 && flip == 1 ) { x=textx1;} if(rot == 3 && flip == 1 ) { y=texty1;} } if(vcenter) { if(rot == 0 && flip == 0 ) { y=texty1;} if(rot == 1 && flip == 0 ) { x=textx2;} if(rot == 2 && flip == 0 ) { y=texty2;} if(rot == 3 && flip == 0 ) { x=textx1;} if(rot == 0 && flip == 1 ) { y=texty1;} if(rot == 1 && flip == 1 ) { x=textx2;} if(rot == 2 && flip == 1 ) { y=texty2;} if(rot == 3 && flip == 1 ) { x=textx1;} } llength=0; my_strdup2(465, &sss, str); tt=ss=sss; for(;;) { c=*ss; if(c=='\n' || c==0) { *ss='\0'; svg_draw_string_line(layer, tt, x, y, size, rot, flip, lineno, height, ascent, descent, llength, no_of_lines, longest_line); lineno++; if(c==0) break; *ss='\n'; tt=ss+1; llength=0; } else { llength++; } ss++; } my_free(1154, &sss); } static void old_svg_draw_string(int layer, const char *str, short rot, short flip, int hcenter, int vcenter, double x,double y, double xscale, double yscale) { double a,yy,curr_x1,curr_y1,curr_x2,curr_y2,rx1,rx2,ry1,ry2; int pos=0,cc,pos2=0; int i, no_of_lines, longest_line; if(str==NULL) return; #if HAS_CAIRO==1 text_bbox_nocairo(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y, &rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line); #else text_bbox(str, xscale, yscale, rot, flip, hcenter, vcenter, x,y, &rx1,&ry1,&rx2,&ry2, &no_of_lines, &longest_line); #endif xscale*=tclgetdoublevar("nocairo_font_xscale"); yscale*=tclgetdoublevar("nocairo_font_yscale"); if(!textclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,rx1,ry1,rx2,ry2)) return; x=rx1;y=ry1; if(rot&1) {y=ry2;rot=3;} else rot=0; flip = 0; yy=y; while(str[pos2]) { cc = (unsigned char)str[pos2++]; if(cc>127) cc= '?'; if(cc=='\n') { yy+=(FONTHEIGHT+FONTDESCENT+FONTWHITESPACE)* yscale; pos=0; continue; } a = pos*(FONTWIDTH+FONTWHITESPACE); for(i=0;imooz; while(deltaxorigin* xctx->mooz;y = xctx->yorigin* xctx->mooz; if(y>xctx->areay1 && yareay2) { svg_xdrawline(GRIDLAYER, 0, xctx->areax1+1,(int)y, xctx->areax2-1, (int)y, 0); } if(x>xctx->areax1 && xareax2) { svg_xdrawline(GRIDLAYER, 0, (int)x,xctx->areay1+1, (int)x, xctx->areay2-1, 0); } tmp = floor((xctx->areay1+1)/delta)*delta-fmod(-xctx->yorigin* xctx->mooz,delta); for(x=floor((xctx->areax1+1)/delta)*delta-fmod(-xctx->xorigin* xctx->mooz,delta);xareax2;x+=delta) { for(y=tmp;yareay2;y+=delta) { svg_xdrawpoint(GRIDLAYER, (int)(x), (int)(y)); } } } static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot, double xoffset, double yoffset) /* draws current layer only, should be called within */ { /* a "for(i=0;iinst[n].ptr == -1) return; if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) return; if(layer==0) { x1=X_TO_SVG(xctx->inst[n].x1); x2=X_TO_SVG(xctx->inst[n].x2); y1=Y_TO_SVG(xctx->inst[n].y1); y2=Y_TO_SVG(xctx->inst[n].y2); if(OUTSIDE(x1,y1,x2,y2,xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2)) { xctx->inst[n].flags|=1; return; } else xctx->inst[n].flags&=~1; } else if(xctx->inst[n].flags&1) { dbg(1, "draw_symbol(): skipping inst %d\n", n); return; } flip = xctx->inst[n].flip; if(tmp_flip) flip = !flip; rot = (xctx->inst[n].rot + rot ) & 0x3; x0=xctx->inst[n].x0 + xoffset; y0=xctx->inst[n].y0 + yoffset; symptr = (xctx->inst[n].ptr+ xctx->sym); for(j=0;j< symptr->lines[layer];j++) { line = (symptr->line[layer])[j]; ROTATION(rot, flip, 0.0,0.0,line.x1,line.y1,x1,y1); ROTATION(rot, flip, 0.0,0.0,line.x2,line.y2,x2,y2); ORDER(x1,y1,x2,y2); svg_drawline(c, line.bus, x0+x1, y0+y1, x0+x2, y0+y2, line.dash); } for(j=0;j< symptr->polygons[layer];j++) { polygon = (symptr->poly[layer])[j]; { /* scope block so we declare some auxiliary arrays for coord transforms. 20171115 */ int k; double *x = my_malloc(417, sizeof(double) * polygon.points); double *y = my_malloc(418, sizeof(double) * polygon.points); for(k=0;karcs[layer];j++) { double angle; arc = (symptr->arc[layer])[j]; if(flip) { angle = 270.*rot+180.-arc.b-arc.a; } else { angle = arc.a+rot*270.; } angle = fmod(angle, 360.); if(angle<0.) angle+=360.; ROTATION(rot, flip, 0.0,0.0,arc.x,arc.y,x1,y1); svg_drawarc(c, arc.fill, x0+x1, y0+y1, arc.r, angle, arc.b, arc.dash); } if( xctx->enable_layer[layer] ) for(j=0;j< symptr->rects[layer];j++) { rect = (symptr->rect[layer])[j]; ROTATION(rot, flip, 0.0,0.0,rect.x1,rect.y1,x1,y1); ROTATION(rot, flip, 0.0,0.0,rect.x2,rect.y2,x2,y2); RECTORDER(x1,y1,x2,y2); svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, rect.dash); } if( (layer==TEXTWIRELAYER && !(xctx->inst[n].flags&2) ) || (xctx->sym_txt && (layer==TEXTLAYER) && (xctx->inst[n].flags&2) ) ) { const char *txtptr; for(j=0;j< symptr->texts;j++) { text = symptr->text[j]; /* if(text.xscale*FONTWIDTH* xctx->mooz<1) continue; */ txtptr= translate(n, text.txt_ptr); ROTATION(rot, flip, 0.0,0.0,text.x0,text.y0,x1,y1); textlayer = c; /* do not allow custom text color on PINLAYER hilighted instances */ if( !(xctx->inst[n].color == PINLAYER)) { textlayer = symptr->text[j].layer; if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; } /* display PINLAYER colored instance texts even if PINLAYER disabled */ if(xctx->inst[n].color == PINLAYER || xctx->enable_layer[textlayer]) { my_snprintf(svg_font_family, S(svg_font_family), tclgetvar("svg_font_name")); my_snprintf(svg_font_style, S(svg_font_style), "normal"); my_snprintf(svg_font_weight, S(svg_font_weight), "normal"); textfont = symptr->text[j].font; if( (textfont && textfont[0])) { my_snprintf(svg_font_family, S(svg_font_family), textfont); } if( symptr->text[j].flags & TEXT_BOLD) my_snprintf(svg_font_weight, S(svg_font_weight), "bold"); if( symptr->text[j].flags & TEXT_ITALIC) my_snprintf(svg_font_style, S(svg_font_style), "italic"); if( symptr->text[j].flags & TEXT_OBLIQUE) my_snprintf(svg_font_style, S(svg_font_style), "oblique"); if(text_svg) svg_draw_string(textlayer, txtptr, (text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3, flip^text.flip, text.hcenter, text.vcenter, x0+x1, y0+y1, text.xscale, text.yscale); else old_svg_draw_string(textlayer, txtptr, (text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3, flip^text.flip, text.hcenter, text.vcenter, x0+x1, y0+y1, text.xscale, text.yscale); } } } } static void fill_svg_colors() { char s[200]; /* overflow safe 20161122 */ unsigned int i,c; /* if(debug_var>=1) { * tcleval( "puts $svg_colors"); * } */ for(i=0;i> 16; svg_colors[i].green = (c & 0x00ff00) >> 8; svg_colors[i].blue = (c & 0x0000ff); } else if(tclgetboolvar("dark_colorscheme")) { svg_colors[i].red = 255; svg_colors[i].green = 255; svg_colors[i].blue = 255; } else { svg_colors[i].red = 0; svg_colors[i].green = 0; svg_colors[i].blue = 0; } if(debug_var>=1) { fprintf(errfp, "svg_colors: %d %d %d\n", svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue); } } } void svg_draw(void) { double dx, dy; int c,i, textlayer; int old_grid; static char lastdir[PATH_MAX] = ""; const char *r, *textfont; int *unused_layer; int color; Hilight_hashentry *entry; if(!lastdir[0]) my_strncpy(lastdir, pwd_dir, S(lastdir)); if(has_x && !xctx->plotfile[0]) { tclvareval("tk_getSaveFile -title {Select destination file} -initialfile {", get_cell(xctx->sch[xctx->currsch], 0) , ".svg} -initialdir {", lastdir, "}", NULL); r = tclresult(); if(r[0]) { my_strncpy(xctx->plotfile, r, S(xctx->plotfile)); tclvareval("file dirname {", xctx->plotfile, "}", NULL); my_strncpy(lastdir, tclresult(), S(lastdir)); } else return; } svg_restore_lw(); svg_colors=my_calloc(419, cadlayers, sizeof(Svg_color)); if(svg_colors==NULL){ fprintf(errfp, "svg_draw(): calloc error\n"); return; } fill_svg_colors(); old_grid=tclgetboolvar("draw_grid"); tclsetvar("draw_grid", "0"); dx=xctx->xrect[0].width; dy=xctx->xrect[0].height; dbg(1, "svg_draw(): dx=%g dy=%g\n", dx, dy); if(xctx->plotfile[0]) { fd=fopen(xctx->plotfile, "w"); if(!fd) { dbg(0, "can not open file: %s\n", xctx->plotfile); return; } } else { fd=fopen("plot.svg", "w"); if(!fd) { dbg(0, "can not open file: %s\n", "plot.svg"); return; } } my_strncpy(xctx->plotfile,"", S(xctx->plotfile)); unused_layer = my_calloc(873, cadlayers, sizeof(int)); #if 0 * /* Determine used layers. Disabled since we want hilight colors */ * for(c=0;ctexts;i++) * { * textlayer = xctx->text[i].layer; * if(textlayer < 0 || textlayer >= cadlayers) textlayer = TEXTLAYER; * unused_layer[textlayer] = 0; * } * for(c=0;cinst[i].ptr + xctx->sym); * if(xctx->lines[c] || xctx->rects[c] || xctx->arcs[c] || xctx->polygons[c]) unused_layer[c] = 0; * if(xctx->wires) unused_layer[WIRELAYER] = 0; * for(i=0;iinstances;i++) { * if( (c == PINLAYER || xctx->enable_layer[c]) && symptr->lines[c] ) unused_layer[c] = 0; * if( (c == PINLAYER || xctx->enable_layer[c]) && symptr->polygons[c] ) unused_layer[c] = 0; * if( (c == PINLAYER || xctx->enable_layer[c]) && symptr->arcs[c] ) unused_layer[c] = 0; * if( (c != PINLAYER || xctx->enable_layer[c]) && symptr->rects[c] ) unused_layer[c] = 0; * if( (c==TEXTWIRELAYER && !(xctx->inst[i].flags&2) ) || * (xctx->sym_txt && (c==TEXTLAYER) && (xctx->inst[i].flags&2) ) ) * { * int j; * for(j=0;j< symptr->texts;j++) * { * textlayer = c; * if( !(xctx->inst[i].color == PINLAYER)) { * textlayer = symptr->text[j].layer; * if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; * } * /* display PINLAYER colored instance texts even if PINLAYER disabled */ * if(xctx->inst[i].color == PINLAYER || xctx->enable_layer[textlayer]) { * used_layer[textlayer] = 0; * } * } * } * } * dbg(1, "used_layer[%d] = %d\n", c, used_layer[c]); * } * /* End determine used layer */ #endif fprintf(fd, "\n", dx, dy); fprintf(fd, "\n"); /* background */ fprintf(fd, "\n", 0.0, 0.0, dx, dy); svg_drawgrid(); for(i=0;itexts;i++) { textlayer = xctx->text[i].layer; if(textlayer < 0 || textlayer >= cadlayers) textlayer = TEXTLAYER; my_snprintf(svg_font_family, S(svg_font_family), tclgetvar("svg_font_name")); my_snprintf(svg_font_style, S(svg_font_style), "normal"); my_snprintf(svg_font_weight, S(svg_font_weight), "normal"); textfont = xctx->text[i].font; if( (textfont && textfont[0])) { my_snprintf(svg_font_family, S(svg_font_family), textfont); } if( xctx->text[i].flags & TEXT_BOLD) my_snprintf(svg_font_weight, S(svg_font_weight), "bold"); if( xctx->text[i].flags & TEXT_ITALIC) my_snprintf(svg_font_style, S(svg_font_style), "italic"); if( xctx->text[i].flags & TEXT_OBLIQUE) my_snprintf(svg_font_style, S(svg_font_style), "oblique"); if(text_svg) svg_draw_string(textlayer, xctx->text[i].txt_ptr, xctx->text[i].rot, xctx->text[i].flip, xctx->text[i].hcenter, xctx->text[i].vcenter, xctx->text[i].x0,xctx->text[i].y0, xctx->text[i].xscale, xctx->text[i].yscale); else old_svg_draw_string(textlayer, xctx->text[i].txt_ptr, xctx->text[i].rot, xctx->text[i].flip, xctx->text[i].hcenter, xctx->text[i].vcenter, xctx->text[i].x0,xctx->text[i].y0, xctx->text[i].xscale, xctx->text[i].yscale); } for(c=0;clines[c];i++) svg_drawline(c, xctx->line[c][i].bus, xctx->line[c][i].x1, xctx->line[c][i].y1, xctx->line[c][i].x2, xctx->line[c][i].y2, xctx->line[c][i].dash); for(i=0;irects[c];i++) { if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) { svg_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2, xctx->rect[c][i].dash); } } for(i=0;iarcs[c];i++) { svg_drawarc(c, xctx->arc[c][i].fill, xctx->arc[c][i].x, xctx->arc[c][i].y, xctx->arc[c][i].r, xctx->arc[c][i].a, xctx->arc[c][i].b, xctx->arc[c][i].dash); } for(i=0;ipolygons[c];i++) { svg_drawpolygon(c, NOW, xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, xctx->poly[c][i].fill, xctx->poly[c][i].dash); } for(i=0;iinstances;i++) { color = c; if(xctx->inst[i].color != -10000) color = get_color(xctx->inst[i].color); svg_draw_symbol(color,i,c,0,0,0.0,0.0); } } prepare_netlist_structs(0); /* NEEDED: data was cleared by trim_wires() */ for(i=0;iwires;i++) { color = WIRELAYER; if(xctx->hilight_nets && (entry=bus_hilight_hash_lookup( xctx->wire[i].node, 0, XLOOKUP))) { color = get_color(entry->value); } svg_drawline(color, xctx->wire[i].bus, xctx->wire[i].x1, xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, 0); } { double x1, y1, x2, y2; Wireentry *wireptr; int i; Iterator_ctx ctx; update_conn_cues(0, 0); /* draw connecting dots */ x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); x2 = X_TO_XSCHEM(xctx->areax2); y2 = Y_TO_XSCHEM(xctx->areay2); for(init_wire_iterator(&ctx, x1, y1, x2, y2); ( wireptr = wire_iterator_next(&ctx) ) ;) { i = wireptr->n; color = WIRELAYER; if(xctx->hilight_nets && (entry=bus_hilight_hash_lookup( xctx->wire[i].node, 0, XLOOKUP))) { color = get_color(entry->value); } if( xctx->wire[i].end1 >1 ) { svg_drawcircle(color, 1, xctx->wire[i].x1, xctx->wire[i].y1, cadhalfdotsize, 0, 360); } if( xctx->wire[i].end2 >1 ) { svg_drawcircle(color, 1, xctx->wire[i].x2, xctx->wire[i].y2, cadhalfdotsize, 0, 360); } } } dbg(1, "svg_draw(): INT_WIDTH(lw)=%d\n",INT_WIDTH(xctx->lw)); fprintf(fd, "\n"); fclose(fd); tclsetboolvar("draw_grid", old_grid); my_free(964, &svg_colors); my_free(1217, &unused_layer); Tcl_SetResult(interp,"",TCL_STATIC); }