diff options
author | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
---|---|---|
committer | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
commit | 7d0663b7c023cd7dd2764cb232798f8bc1309c20 (patch) | |
tree | e5b8eca2f1b0e825f115fb1b73c3ccb0103b9f39 /src/cmd/svgpic/blockgen.c | |
parent | 5e176c5794de5124b67d3ac4ea7afe2f210b6d84 (diff) | |
parent | 711336c348ac9b98cd22464496e6b7e9a109c3a9 (diff) | |
download | plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.gz plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.bz2 plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.zip |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/cmd/svgpic/blockgen.c')
-rw-r--r-- | src/cmd/svgpic/blockgen.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/cmd/svgpic/blockgen.c b/src/cmd/svgpic/blockgen.c new file mode 100644 index 00000000..9015d56d --- /dev/null +++ b/src/cmd/svgpic/blockgen.c @@ -0,0 +1,226 @@ +#include <stdio.h> +#include <stdlib.h> +#include "pic.h" +#include "y.tab.h" + +#define NBRACK 20 /* depth of [...] */ +#define NBRACE 20 /* depth of {...} */ + +struct pushstack stack[NBRACK]; +int nstack = 0; +struct pushstack bracestack[NBRACE]; +int nbstack = 0; + +void blockadj(obj *); + +obj *leftthing(int c) /* called for {... or [... */ + /* really ought to be separate functions */ +{ + obj *p; + + if (c == '[') { + if (nstack >= NBRACK) + ERROR "[...] nested too deep" FATAL; + stack[nstack].p_x = curx; + stack[nstack].p_y = cury; + stack[nstack].p_hvmode = hvmode; + curx = cury = 0; + stack[nstack].p_xmin = xmin; + stack[nstack].p_xmax = xmax; + stack[nstack].p_ymin = ymin; + stack[nstack].p_ymax = ymax; + nstack++; + xmin = ymin = 30000; + xmax = ymax = -30000; + p = makenode(BLOCK, 7); + p->o_val[4] = nobj; /* 1st item within [...] */ + if (p->o_nobj != nobj-1) + fprintf(stderr, "nobjs wrong%d %d\n", p->o_nobj, nobj); + } else { + if (nbstack >= NBRACK) + ERROR "{...} nested too deep" FATAL; + bracestack[nbstack].p_x = curx; + bracestack[nbstack].p_y = cury; + bracestack[nbstack].p_hvmode = hvmode; + nbstack++; + p = NULL; + } + return(p); +} + +obj *rightthing(obj *p, int c) /* called for ... ] or ... } */ +{ + obj *q; + + if (c == '}') { + nbstack--; + curx = bracestack[nbstack].p_x; + cury = bracestack[nbstack].p_y; + hvmode = bracestack[nbstack].p_hvmode; + q = makenode(MOVE, 0); + dprintf("M %g %g\n", curx, cury); + } else { + nstack--; + curx = stack[nstack].p_x; + cury = stack[nstack].p_y; + hvmode = stack[nstack].p_hvmode; + q = makenode(BLOCKEND, 7); + q->o_val[4] = p->o_nobj + 1; /* back pointer */ + p->o_val[5] = q->o_nobj - 1; /* forward pointer */ + if (xmin > xmax) /* nothing happened */ + xmin = xmax; + if (ymin > ymax) + ymin = ymax; + p->o_val[0] = xmin; p->o_val[1] = ymin; + p->o_val[2] = xmax; p->o_val[3] = ymax; + p->o_symtab = q->o_symtab = stack[nstack+1].p_symtab; + xmin = stack[nstack].p_xmin; + ymin = stack[nstack].p_ymin; + xmax = stack[nstack].p_xmax; + ymax = stack[nstack].p_ymax; + } + return(q); +} + +obj *blockgen(obj *p, obj *q) /* handles [...] */ +{ + int i, invis, at, with; + double ddval, h, w, xwith, ywith; + double x0, y0, x1, y1, cx, cy; + obj *ppos; + Attr *ap; + + invis = at = 0; + with = xwith = ywith = 0; + ddval = 0; + w = p->o_val[2] - p->o_val[0]; + h = p->o_val[3] - p->o_val[1]; + cx = (p->o_val[2] + p->o_val[0]) / 2; /* geom ctr of [] wrt local orogin */ + cy = (p->o_val[3] + p->o_val[1]) / 2; + dprintf("cx,cy=%g,%g\n", cx, cy); + for (i = 0; i < nattr; i++) { + ap = &attr[i]; + switch (ap->a_type) { + case HEIGHT: + h = ap->a_val.f; + break; + case WIDTH: + w = ap->a_val.f; + break; + case WITH: + with = ap->a_val.i; /* corner */ + break; + case PLACE: /* actually with position ... */ + ppos = ap->a_val.o; + xwith = cx - ppos->o_x; + ywith = cy - ppos->o_y; + with = PLACE; + break; + case AT: + case FROM: + ppos = ap->a_val.o; + curx = ppos->o_x; + cury = ppos->o_y; + at++; + break; + case INVIS: + invis = INVIS; + break; + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); + break; + } + } + if (with) { + switch (with) { + case NORTH: ywith = -h / 2; break; + case SOUTH: ywith = h / 2; break; + case EAST: xwith = -w / 2; break; + case WEST: xwith = w / 2; break; + case NE: xwith = -w / 2; ywith = -h / 2; break; + case SE: xwith = -w / 2; ywith = h / 2; break; + case NW: xwith = w / 2; ywith = -h / 2; break; + case SW: xwith = w / 2; ywith = h / 2; break; + } + curx += xwith; + cury += ywith; + } + if (!at) { + if (isright(hvmode)) + curx += w / 2; + else if (isleft(hvmode)) + curx -= w / 2; + else if (isup(hvmode)) + cury += h / 2; + else + cury -= h / 2; + } + x0 = curx - w / 2; + y0 = cury - h / 2; + x1 = curx + w / 2; + y1 = cury + h / 2; + extreme(x0, y0); + extreme(x1, y1); + p->o_x = curx; + p->o_y = cury; + p->o_nt1 = ntext1; + p->o_nt2 = ntext; + ntext1 = ntext; + p->o_val[0] = w; + p->o_val[1] = h; + p->o_val[2] = cx; + p->o_val[3] = cy; + p->o_val[5] = q->o_nobj - 1; /* last item in [...] */ + p->o_ddval = ddval; + p->o_attr = invis; + dprintf("[] %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w); + if (isright(hvmode)) + curx = x1; + else if (isleft(hvmode)) + curx = x0; + else if (isup(hvmode)) + cury = y1; + else + cury = y0; + for (i = 0; i <= 5; i++) + q->o_val[i] = p->o_val[i]; + stack[nstack+1].p_symtab = NULL; /* so won't be found again */ + blockadj(p); /* fix up coords for enclosed blocks */ + return(p); +} + +void blockadj(obj *p) /* adjust coords in block starting at p */ +{ + double dx, dy; + int n, lev; + + dx = p->o_x - p->o_val[2]; + dy = p->o_y - p->o_val[3]; + n = p->o_nobj + 1; + dprintf("into blockadj: dx,dy=%g,%g\n", dx, dy); + for (lev = 1; lev > 0; n++) { + p = objlist[n]; + if (p->o_type == BLOCK) + lev++; + else if (p->o_type == BLOCKEND) + lev--; + dprintf("blockadj: type=%d o_x,y=%g,%g;", p->o_type, p->o_x, p->o_y); + p->o_x += dx; + p->o_y += dy; + dprintf(" becomes %g,%g\n", p->o_x, p->o_y); + switch (p->o_type) { /* other absolute coords */ + case LINE: + case ARROW: + case SPLINE: + p->o_val[0] += dx; + p->o_val[1] += dy; + break; + case ARC: + p->o_val[0] += dx; + p->o_val[1] += dy; + p->o_val[2] += dx; + p->o_val[3] += dy; + break; + } + } +} |