allow arbitrary widths of polygons (with attr bus=5.0)

This commit is contained in:
stefan schippers 2025-11-27 22:03:10 +01:00
parent b67ee6a6b8
commit 7216c54f57
7 changed files with 68 additions and 42 deletions

View File

@ -3545,7 +3545,7 @@ void new_polygon(int what, double mousex_snap, double mousey_snap)
/* fprintf(errfp, "new_poly: finish: nl_points=%d\n", xctx->nl_points); */
drawtemppolygon(xctx->gc[xctx->rectcolor], NOW, xctx->nl_polyx, xctx->nl_polyy, xctx->nl_points, 0);
xctx->ui_state &= ~STARTPOLYGON;
drawpolygon(xctx->rectcolor, NOW, xctx->nl_polyx, xctx->nl_polyy, xctx->nl_points, 0, 0, 0);
drawpolygon(xctx->rectcolor, NOW, xctx->nl_polyx, xctx->nl_polyy, xctx->nl_points, 0, 0, 0.0, 0);
my_free(_ALLOC_ID_, &xctx->nl_polyx);
my_free(_ALLOC_ID_, &xctx->nl_polyy);
xctx->nl_maxpoints = xctx->nl_points = 0;

View File

@ -742,9 +742,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot,
{
int dash;
int bezier;
int bus;
polygon = &(symptr->poly[layer])[j];
bus = (polygon->bus == -1.0) ? THICK : NOW;
bezier = !strboolcmp(get_tok_value(polygon->prop_ptr, "bezier", 0), "true");
dash = (disabled == 1) ? 3 : polygon->dash;
x = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points);
@ -754,7 +752,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot,
x[k]+= x0;
y[k] += y0;
}
drawpolygon(c, bus, x, y, polygon->points, polygon->fill, dash, bezier); /* added fill */
drawpolygon(c, NOW, x, y, polygon->points, polygon->fill, dash, polygon->bus, bezier); /* added fill */
my_free(_ALLOC_ID_, &x);
my_free(_ALLOC_ID_, &y);
}
@ -2053,15 +2051,21 @@ void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int
/* Unused 'what' parameter used in spice data draw_graph()
* to avoid unnecessary clipping (what = 0) */
void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill, int dash, int flags)
void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill, int dash, double bus, int flags)
{
double x1,y1,x2,y2;
int fill, bezier;
XPoint *p;
int i;
int width = 0;
short sx, sy;
GC gc;
if(!has_x) return;
if(bus == -1.0) what = THICK;
if(what == THICK) width = INT_BUS_WIDTH(xctx->lw);
else if(bus > 0.0) width = (int) (bus * xctx->mooz);
else width = XLINEWIDTH(xctx->lw);
polygon_bbox(x, y, points, &x1,&y1,&x2,&y2);
x1=X_TO_SCREEN(x1);
x2=X_TO_SCREEN(x2);
@ -2087,22 +2091,17 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
(x[0] == x[points-1]) && (y[0] == y[points-1]);
bezier = (flags & 1) && (points > 2);
if(what == NOW) {
if(dash) {
char dash_arr[2];
dash_arr[0] = dash_arr[1] = (char)dash;
XSetDashes(display, xctx->gc[c], 0, dash_arr, 1);
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin);
}
} else if(what == THICK) {
if(dash) {
char dash_arr[2];
dash_arr[0] = dash_arr[1] = (char) dash;
XSetDashes(display, xctx->gc[c], 0, dash_arr, 1);
XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), xDashType, xCap, xJoin);
} else {
XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
}
if(dash) {
char dash_arr[2];
dash_arr[0] = dash_arr[1] = (char)dash;
XSetDashes(display, xctx->gc[c], 0, dash_arr, 1);
}
if(dash) {
XSetLineAttributes (display, xctx->gc[c], width, xDashType, xCap, xJoin);
} else if(bus > 0.0) {
XSetLineAttributes (display, xctx->gc[c], width, LineSolid, CapProjecting, JoinMiter);
} else {
XSetLineAttributes (display, xctx->gc[c], width, LineSolid, LINECAP, LINEJOIN);
}
if(xctx->draw_window) {
@ -2127,8 +2126,8 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
if(xctx->draw_pixmap)
XFillPolygon(display, xctx->save_pixmap, gc, p, points, Polygontype, CoordModeOrigin);
}
if(dash || what == THICK) {
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
if(dash || what == THICK || bus > 0.0) {
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
}
my_free(_ALLOC_ID_, &p);
}
@ -5180,9 +5179,8 @@ void draw(void)
if(draw_layer && xctx->enable_layer[c]) for(i=0;i<xctx->polygons[c]; ++i) {
int bezier;
xPoly *p = &xctx->poly[c][i];
int what = (p->bus == -1.0) ? THICK : NOW;
bezier = 2 + !strboolcmp(get_tok_value(p->prop_ptr, "bezier", 0), "true");
drawpolygon(cc, what, p->x, p->y, p->points, p->fill, p->dash, bezier);
drawpolygon(cc, NOW, p->x, p->y, p->points, p->fill, p->dash, p->bus, bezier);
}
if(use_hash) init_inst_iterator(&ctx, x1, y1, x2, y2);
else i = -1;

View File

@ -1298,6 +1298,7 @@ static int edit_polygon_property(void)
char *oldprop = NULL;
const char *dash;
int preserve, modified = 0;
double width;
dbg(1, "edit_property(): input property:\n");
my_strdup(_ALLOC_ID_, &oldprop, xctx->poly[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr);
@ -1331,6 +1332,10 @@ static int edit_polygon_property(void)
bezier = !strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr,"bezier",0),"true") ;
xctx->poly[c][i].bus = bus = get_attr_val(get_tok_value(xctx->poly[c][i].prop_ptr,"bus",0));
if(bus > 0.0) width = bus / 2.0;
else width = xctx->cadhalfdotsize;
if(oldbus / 2.0 > width) width = oldbus / 2.0;
fill_ptr = get_tok_value(xctx->poly[c][i].prop_ptr,"fill",0);
if( !strcmp(fill_ptr,"full") )
xctx->poly[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
@ -1356,8 +1361,7 @@ static int edit_polygon_property(void)
if(k==0 || xctx->poly[c][i].x[k] > x2) x2 = xctx->poly[c][i].x[k];
if(k==0 || xctx->poly[c][i].y[k] > y2) y2 = xctx->poly[c][i].y[k];
}
bbox(ADD, x1-xctx->cadhalfdotsize, y1-xctx->cadhalfdotsize,
x2+xctx->cadhalfdotsize, y2+xctx->cadhalfdotsize);
bbox(ADD, x1-width, y1-width, x2+width, y2+width);
}
}
if(drw) {

View File

@ -527,6 +527,12 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points,
double xx, yy;
double psdash;
int i, bezier;
double width;
if(bus == -1.0) width = BUS_WIDTH * xctx->lw;
else if(bus > 0.0) width = bus * xctx->mooz;
else width = -1.0;
polygon_bbox(x, y, points, &x1,&y1,&x2,&y2);
x1=X_TO_PS(x1);
y1=Y_TO_PS(y1);
@ -536,10 +542,13 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points,
return;
}
psdash = dash / xctx->zoom;
if(bus > 0.0) {
fprintf(fd, "0 setlinejoin 2 setlinecap\n");
}
if(dash) {
fprintf(fd, "[%g %g] 0 setdash\n", psdash, psdash);
}
if(bus == -1.0) set_lw(BUS_WIDTH * xctx->lw);
if(width >= 0.0) set_lw(1.2 * width);
bezier = flags && (points > 2);
if(bezier) {
ps_drawbezier(x, y, points);
@ -559,7 +568,10 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points,
if(dash) {
fprintf(fd, "[] 0 setdash\n");
}
if(bus == -1.0) set_lw(xctx->lw);
if(width >= 0.0) set_lw(xctx->lw);
if(bus > 0.0) {
fprintf(fd, "1 setlinejoin 1 setlinecap\n");
}
}

View File

@ -215,9 +215,10 @@ void store_poly(int pos, double *x, double *y, int points, unsigned int rectc,
if( strcmp(dash, "") ) {
int d = atoi(dash);
xctx->poly[rectc][n].dash = (char) (d >= 0 ? d : 0);
} else
} else {
xctx->poly[rectc][n].dash = 0;
}
xctx->poly[rectc][n].bus = get_attr_val(get_tok_value(xctx->poly[rectc][n].prop_ptr,"bus",0));
xctx->polygons[rectc]++;
}

View File

@ -45,7 +45,7 @@ static void svg_restore_lw(void)
static void svg_xdrawline(int layer, double bus, double x1, double y1, double x2, double y2, int dash)
{
fprintf(fd,"<path class=\"l%d\" ", layer);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(bus == -1.0) fprintf(fd, "style=\"stroke-width:%g;\" ", BUS_WIDTH * svg_linew);
fprintf(fd,"d=\"M%g %gL%g %g\"/>\n", x1, y1, x2, y2);
}
@ -59,7 +59,7 @@ static void svg_xdrawpoint(int layer, double x1, double y1)
static void svg_xfillrectangle(int layer, double x1, double y1, double x2, double y2, int dash, int fill)
{
fprintf(fd,"<path class=\"l%d\" ", layer);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(fill == 0) {
fprintf(fd,"style=\"fill:none;\" ");
} else if(fill == 2) {
@ -124,6 +124,12 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points,
double x1,y1,x2,y2;
double xx, yy;
int bezier, i;
double width;
if(bus == -1.0) width = BUS_WIDTH * svg_linew;
else if(bus > 0.0) width = bus * xctx->mooz;
else width = -1.0;
polygon_bbox(x, y, points, &x1,&y1,&x2,&y2);
x1=X_TO_SCREEN(x1);
y1=Y_TO_SCREEN(y1);
@ -133,10 +139,14 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points,
return;
}
fprintf(fd, "<path class=\"l%d\" ", c);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(bus == -1.0 || fill == 0 || fill == 2) {
if(bus == -1.0) fprintf(fd, "style=\"stroke-width:%g; ", BUS_WIDTH * svg_linew);
else fprintf(fd, "style=\"");
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(width >= 0.0 || fill == 0 || fill == 2) {
if(width > 0) fprintf(fd, "style=\"stroke-width:%g; ", width);
else fprintf(fd, "style=\"");
if(bus > 0.0) {
fprintf(fd, " stroke-linecap:square;\n");
fprintf(fd, " stroke-linejoin:miter;\n");
}
if(fill == 0) {
fprintf(fd,"fill:none;\" ");
} else if(fill == 2) {
@ -180,7 +190,7 @@ static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,dou
if(e_b == 360.) {
fprintf(fd, "<ellipse class=\"l%d\" cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" ", gc, cx, cy, rx, ry);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(fill == 0) fprintf(fd, "style=\"fill:none;\" ");
else if(fill == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
fprintf(fd, "/>\n");
@ -193,7 +203,7 @@ static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,dou
int fs = e_b > 0 ? 0 : 1;
fprintf(fd,"<path class=\"l%d\" ", gc);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(fill == 0) {
fprintf(fd,"style=\"fill:none;\" ");
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2);
@ -254,7 +264,7 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
{
if(b == 360.) {
fprintf(fd, "<circle class=\"l%d\" cx=\"%g\" cy=\"%g\" r=\"%g\" ", gc, xx, yy, rr);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(fillarc == 0) fprintf(fd, "style=\"fill:none;\" ");
else if(fillarc == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
@ -268,7 +278,7 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
fs = b > 0 ? 0 : 1;
fprintf(fd,"<path class=\"l%d\" ", gc);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 0.8*dash/xctx->zoom, 0.8*dash/xctx->zoom);
if(fillarc == 0) {
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);

View File

@ -1463,7 +1463,8 @@ extern void drawarc(int c, int what, double x, double y, double r, double a, dou
extern void filledarc(int c, int what, double x, double y, double r, double a, double b);
extern void drawtemppolygon(GC gc, int what, double *x, double *y, int points, int flags);
extern void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill);
extern void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill, int dash, int flags);
extern void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill,
int dash, double bus, int flags);
extern void draw_temp_symbol(int what, GC gc, int n,int layer,
short tmp_flip, short tmp_rot, double xoffset, double yoffset);
extern void draw_temp_string(GC gc,int what, const char *str, short rot, short flip, int hcenter, int vcenter,