allow arbitrary widths (with ex. bus=3.5 attr) for arcs / circles

This commit is contained in:
stefan schippers 2025-11-28 13:31:45 +01:00
parent 7216c54f57
commit 8da982999a
10 changed files with 95 additions and 37 deletions

View File

@ -3336,7 +3336,7 @@ void new_arc(int what, double sweep, double mousex_snap, double mousey_snap)
if(xctx->nl_sweep_angle==360.) xctx->nl_b=360.;
if(xctx->nl_r>0.) {
xctx->push_undo();
drawarc(xctx->rectcolor, NOW, xctx->nl_x, xctx->nl_y, xctx->nl_r, xctx->nl_a, xctx->nl_b, 0, 0);
drawarc(xctx->rectcolor, NOW, xctx->nl_x, xctx->nl_y, xctx->nl_r, xctx->nl_a, xctx->nl_b, 0, 0.0, 0);
store_arc(-1, xctx->nl_x, xctx->nl_y, xctx->nl_r, xctx->nl_a, xctx->nl_b, xctx->rectcolor, 0, NULL);
set_modify(1);
}

View File

@ -770,7 +770,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot,
angle = fmod(angle, 360.);
if(angle<0.) angle+=360.;
ROTATION(rot, flip, 0.0, 0.0,arc->x,arc->y,x1,y1);
drawarc(c,what, x0+x1, y0+y1, arc->r, angle, arc->b, arc->fill, dash);
drawarc(c,what, x0+x1, y0+y1, arc->r, angle, arc->b, arc->fill, arc->bus, dash);
}
} /* if(!hide) */
@ -1714,13 +1714,24 @@ void filledarc(int c, int what, double x, double y, double r, double a, double b
}
}
void drawarc(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash)
void drawarc(int c, int what, double x, double y, double r, double a, double b, int arc_fill, double bus, int dash)
{
static int i=0;
static XArc xarc[CADDRAWBUFFERSIZE];
double x1, y1, x2, y2; /* arc bbox */
double xx1, yy1, xx2, yy2; /* complete circle bbox in screen coords */
GC gc;
int width;
if(bus == -1.0) {
what = NOW;
width = INT_BUS_WIDTH(xctx->lw);
} else if(bus > 0.0) {
what = NOW;
width = (int) (bus * xctx->mooz);
} else {
width = XLINEWIDTH(xctx->lw);
}
if(arc_fill || dash) what = NOW;
@ -1769,12 +1780,19 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
y2=Y_TO_SCREEN(y2);
if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
{
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);
}
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 if(bus == -1.0) {
XSetLineAttributes (display, xctx->gc[c], width, LineSolid, LINECAP, LINEJOIN);
}
if(xctx->draw_window) {
XDrawArc(display, xctx->window, xctx->gc[c], (int)xx1, (int)yy1,
@ -1798,9 +1816,10 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
}
}
if(dash) {
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
if(dash || bus > 0.0) {
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
}
}
}
else if((what & END) && i)
@ -2100,7 +2119,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
XSetLineAttributes (display, xctx->gc[c], width, xDashType, xCap, xJoin);
} else if(bus > 0.0) {
XSetLineAttributes (display, xctx->gc[c], width, LineSolid, CapProjecting, JoinMiter);
} else {
} else if(bus == -1.0) {
XSetLineAttributes (display, xctx->gc[c], width, LineSolid, LINECAP, LINEJOIN);
}
@ -5174,7 +5193,7 @@ void draw(void)
if(draw_layer && xctx->enable_layer[c]) for(i=0;i<xctx->arcs[c]; ++i) {
xArc **arc = xctx->arc;
drawarc(cc, ADD, arc[c][i].x, arc[c][i].y, arc[c][i].r, arc[c][i].a, arc[c][i].b,
arc[c][i].fill, arc[c][i].dash);
arc[c][i].fill, arc[c][i].bus, arc[c][i].dash);
}
if(draw_layer && xctx->enable_layer[c]) for(i=0;i<xctx->polygons[c]; ++i) {
int bezier;
@ -5213,7 +5232,7 @@ void draw(void)
}
}
filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* fill parameter must be 2! */
drawarc(cc, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
drawarc(cc, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0);
drawrect(cc, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
drawline(cc, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
}

View File

@ -1224,6 +1224,8 @@ static int edit_arc_property(void)
char *oldprop = NULL;
const char *dash, *fill_ptr;
int preserve, modified = 0;
double bus = 0.0, oldbus = 0.0;
double width;
my_strdup(_ALLOC_ID_, &oldprop, xctx->arc[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr);
if(oldprop && oldprop[0]) {
@ -1243,7 +1245,7 @@ static int edit_arc_property(void)
i = xctx->sel_array[ii].n;
c = xctx->sel_array[ii].col;
oldbus = xctx->arc[c][i].bus;
if(oldprop && preserve == 1) {
set_different_token(&xctx->arc[c][i].prop_ptr, (char *) tclgetvar("tctx::retval"), oldprop);
@ -1266,14 +1268,18 @@ static int edit_arc_property(void)
} else
xctx->arc[c][i].dash = 0;
bus = xctx->arc[c][i].bus = get_attr_val(get_tok_value(xctx->arc[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;
if(old_fill != xctx->arc[c][i].fill || old_dash != xctx->arc[c][i].dash) {
if(oldbus != bus || old_fill != xctx->arc[c][i].fill || old_dash != xctx->arc[c][i].dash) {
if(!drw) {
bbox(START,0.0,0.0,0.0,0.0);
drw = 1;
}
arc_bbox(xctx->arc[c][i].x, xctx->arc[c][i].y, xctx->arc[c][i].r, 0, 360, &x1,&y1,&x2,&y2);
bbox(ADD, x1, y1, x2, y2);
bbox(ADD, x1 - width, y1 - width, x2 + width, y2 + width);
}
}
if(drw) {

View File

@ -2268,7 +2268,7 @@ void draw_hilight_net(int on_window)
if(c == cadlayers - 1) draw_symbol(ADD, col, i, c + 1, 0, 0, 0.0, 0.0); /* draw texts */
}
filledrect(col, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* last parameter must be 2! */
drawarc(col, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
drawarc(col, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0);
drawrect(col, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
drawline(col, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
}

View File

@ -171,6 +171,7 @@ static void merge_arc(FILE *fd)
} else {
ptr[i].dash = 0;
}
ptr[i].bus = get_attr_val(get_tok_value(ptr[i].prop_ptr,"bus",0));
select_arc(c,i, SELECTED, 1, 1);
xctx->arcs[c]++;

View File

@ -612,11 +612,16 @@ static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,doub
}
}
static void ps_drawarc(int gc, int fillarc, double x,double y,double r,double a, double b, int dash)
static void ps_drawarc(int gc, int fillarc, double x,double y,double r,double a, double b, double bus, int dash)
{
double xx,yy,rr;
double x1, y1, x2, y2;
double psdash;
double width;
if(bus == -1.0) width = BUS_WIDTH * xctx->lw;
else if(bus > 0.0) width = bus * xctx->mooz;
else width = -1.0;
if(b < 0.0) {
a = a + b;
@ -635,13 +640,21 @@ static void ps_drawarc(int gc, int fillarc, double x,double y,double r,double a,
if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
{
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(width >= 0.0) set_lw(1.2 * width);
ps_xdrawarc(gc, fillarc, xx, yy, rr, a, b);
if(dash) {
fprintf(fd, "[] 0 setdash\n");
}
if(width >= 0.0) set_lw(xctx->lw);
if(bus > 0.0) {
fprintf(fd, "1 setlinejoin 1 setlinecap\n");
}
}
}
@ -1077,7 +1090,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
angle = fmod(angle, 360.);
if(angle<0.) angle+=360.;
ROTATION(rot, flip, 0.0,0.0,arc->x,arc->y,x1,y1);
ps_drawarc(c, arc->fill, x0+x1, y0+y1, arc->r, angle, arc->b, dash);
ps_drawarc(c, arc->fill, x0+x1, y0+y1, arc->r, angle, arc->b, arc->bus, dash);
}
} /* if(!hide) */
@ -1487,7 +1500,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
for(i=0;i<xctx->arcs[c]; ++i)
{
ps_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);
xctx->arc[c][i].r, xctx->arc[c][i].a, xctx->arc[c][i].b, xctx->arc[c][i].bus, xctx->arc[c][i].dash);
}
for(i=0;i<xctx->polygons[c]; ++i) {
int bezier = !strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "bezier", 0), "true");
@ -1537,10 +1550,10 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
}
i = wireptr->n;
if( xctx->wire[i].end1 >1 ) {
ps_drawarc(WIRELAYER, 1, xctx->wire[i].x1, xctx->wire[i].y1, xctx->cadhalfdotsize, 0, 360, 0);
ps_drawarc(WIRELAYER, 1, xctx->wire[i].x1, xctx->wire[i].y1, xctx->cadhalfdotsize, 0, 360, 0.0, 0);
}
if( xctx->wire[i].end2 >1 ) {
ps_drawarc(WIRELAYER, 1, xctx->wire[i].x2, xctx->wire[i].y2, xctx->cadhalfdotsize, 0, 360, 0);
ps_drawarc(WIRELAYER, 1, xctx->wire[i].x2, xctx->wire[i].y2, xctx->cadhalfdotsize, 0, 360, 0.0, 0);
}
}
}

View File

@ -2968,6 +2968,7 @@ static void load_arc(FILE *fd)
} else {
ptr[i].dash = 0;
}
ptr[i].bus = get_attr_val(get_tok_value(ptr[i].prop_ptr, "bus", 0));
xctx->arcs[c]++;
}
@ -4584,6 +4585,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
aa[c][i].dash = (short)(d >= 0 ? d : 0);
} else
aa[c][i].dash = 0;
aa[c][i].bus = get_attr_val(get_tok_value(aa[c][i].prop_ptr,"bus", 0));
aa[c][i].sel = 0;
dbg(2, "l_s_d(): loaded arc: ptr=%lx\n", (unsigned long)aa[c]);
lasta[c]++;

View File

@ -167,7 +167,7 @@ void store_arc(int pos, double x, double y, double r, double a, double b,
xctx->arc[rectc][n].dash = (char) (d >= 0 ? d : 0);
} else
xctx->arc[rectc][n].dash = 0;
xctx->arc[rectc][n].bus = get_attr_val(get_tok_value(xctx->arc[rectc][n].prop_ptr,"bus",0));
xctx->arcs[rectc]++;
}

View File

@ -240,12 +240,17 @@ static void svg_drawcircle(int gc, int fillarc, double x,double y,double r,doubl
}
}
static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a, double b, int dash)
static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a, double b, double bus, int dash)
{
double xx,yy,rr;
double x1, y1, x2, y2;
double xx1, yy1, xx2, yy2;
int fs, fa;
double width;
if(bus == -1.0) width = BUS_WIDTH * svg_linew;
else if(bus > 0.0) width = bus * xctx->mooz;
else width = -1.0;
if(b < 0.0) {
a = a + b;
@ -278,16 +283,26 @@ 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\" ", 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);
} else if(fillarc == 2) {
fprintf(fd, "style=\"fill-opacity:1.0;\" ");
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);
} 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);
}
if(width >= 0.0 || fillarc == 0 || fillarc == 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(fillarc == 0) {
fprintf(fd,"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 if(fillarc == 2) {
fprintf(fd, "fill-opacity:1.0;\" ");
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);
} 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);
}
}
}
}
}
@ -754,7 +769,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
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, dash);
svg_drawarc(c, arc.fill, x0+x1, y0+y1, arc.r, angle, arc.b, arc.bus, dash);
}
} /* if(!hide) */
@ -1080,7 +1095,7 @@ void svg_draw(void)
for(i=0;i<xctx->arcs[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);
xctx->arc[c][i].a, xctx->arc[c][i].b, xctx->arc[c][i].bus, xctx->arc[c][i].dash);
}
for(i=0;i<xctx->polygons[c]; ++i) {
int bezier = !strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "bezier", 0), "true");

View File

@ -533,6 +533,7 @@ typedef struct
char *prop_ptr;
short fill;
short dash;
double bus;
} xArc;
typedef struct
@ -1459,7 +1460,8 @@ extern void fix_restore_rect(double x1, double y1, double x2, double y2);
extern void drawtemprect(GC gc, int what, double rectx1,double recty1,
double rectx2,double recty2);
extern void drawtemparc(GC gc, int what, double x, double y, double r, double a, double b);
extern void drawarc(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash);
extern void drawarc(int c, int what, double x, double y, double r, double a, double b,
int arc_fill, double bus, int dash);
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);