plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

print.c (4495B)


      1 #include <stdio.h>
      2 #include <math.h>
      3 #include "pic.h"
      4 #include "y.tab.h"
      5 
      6 void dotext(obj *);
      7 void ellipse(double, double, double, double);
      8 void circle(double, double, double);
      9 void arc(double, double, double, double, double, double, double);
     10 void arrow(double, double, double, double, double, double, double, int);
     11 void line(double, double, double, double, int, double);
     12 void box(double, double, double, double, int, double);
     13 void spline(double x, double y, double n, ofloat *p, int dashed, double ddval);
     14 void move(double, double);
     15 void troff(char *);
     16 void dot(void);
     17 void fillstart(double, int, int), fillend(void);
     18 
     19 void print(void)
     20 {
     21 	obj *p;
     22 	int i, j, k, m;
     23 	int fill, vis, invis;
     24 	double x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy;
     25 
     26 	x1 = y1 = 0.0; /* Botch? (gcc) */
     27 
     28 	for (i = 0; i < nobj; i++) {
     29 		p = objlist[i];
     30 		ox = p->o_x;
     31 		oy = p->o_y;
     32 		if (p->o_count >= 1)
     33 			x1 = p->o_val[0];
     34 		if (p->o_count >= 2)
     35 			y1 = p->o_val[1];
     36 		m = p->o_mode;
     37 		fill = p->o_attr & FILLBIT;
     38 		invis = p->o_attr & INVIS;
     39 		vis = !invis;
     40 		switch (p->o_type) {
     41 		case TROFF:
     42 			troff(text[p->o_nt1].t_val);
     43 			break;
     44 		case BOX:
     45 		case BLOCK:
     46 			x0 = ox - x1 / 2;
     47 			y0 = oy - y1 / 2;
     48 			x1 = ox + x1 / 2;
     49 			y1 = oy + y1 / 2;
     50 			if (fill) {
     51 				move(x0, y0);
     52 				fillstart(p->o_fillval, vis, fill);
     53 			}
     54 			if (p->o_type == BLOCK)
     55 				;	/* nothing at all */
     56 			else if (invis && !fill)
     57 				;	/* nothing at all */
     58 			else
     59 				box(x0, y0, x1, y1, p->o_attr & (DOTBIT|DASHBIT), p->o_ddval);
     60 			if (fill)
     61 				fillend();
     62 			move(ox, oy);
     63 			dotext(p);	/* if there are any text strings */
     64 			if (ishor(m))
     65 				move(isright(m) ? x1 : x0, oy);	/* right side */
     66 			else
     67 				move(ox, isdown(m) ? y0 : y1);	/* bottom */
     68 			break;
     69 		case BLOCKEND:
     70 			break;
     71 		case CIRCLE:
     72 			if (fill)
     73 				fillstart(p->o_fillval, vis, fill);
     74 			if (vis || fill)
     75 				circle(ox, oy, x1);
     76 			if (fill)
     77 				fillend();
     78 			move(ox, oy);
     79 			dotext(p);
     80 			if (ishor(m))
     81 				move(ox + isright(m) ? x1 : -x1, oy);
     82 			else
     83 				move(ox, oy + isup(m) ? x1 : -x1);
     84 			break;
     85 		case ELLIPSE:
     86 			if (fill)
     87 				fillstart(p->o_fillval, vis, fill);
     88 			if (vis || fill)
     89 				ellipse(ox, oy, x1, y1);
     90 			if (fill)
     91 				fillend();
     92 			move(ox, oy);
     93 			dotext(p);
     94 			if (ishor(m))
     95 				move(ox + isright(m) ? x1 : -x1, oy);
     96 			else
     97 				move(ox, oy - isdown(m) ? y1 : -y1);
     98 			break;
     99 		case ARC:
    100 			if (fill) {
    101 				move(ox, oy);
    102 				fillstart(p->o_fillval, vis, fill);
    103 			}
    104 			if (p->o_attr & HEAD1)
    105 				arrow(x1 - (y1 - oy), y1 + (x1 - ox),
    106 				      x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead);
    107 			if (invis && !fill)
    108 				/* probably wrong when it's cw */
    109 				move(x1, y1);
    110 			else
    111 				arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3], p->o_val[6]);
    112 			if (p->o_attr & HEAD2)
    113 				arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox),
    114 				      p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead);
    115 			if (fill)
    116 				fillend();
    117 			if (p->o_attr & CW_ARC)
    118 				move(x1, y1);	/* because drawn backwards */
    119 			move(ox, oy);
    120 			dotext(p);
    121 			break;
    122 		case LINE:
    123 		case ARROW:
    124 		case SPLINE:
    125 			if (fill) {
    126 				move(ox, oy);
    127 				fillstart(p->o_fillval, vis, fill);
    128 			}
    129 			if (vis && p->o_attr & HEAD1)
    130 				arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
    131 			if (invis && !fill)
    132 				move(x1, y1);
    133 			else if (p->o_type == SPLINE)
    134 				spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval);
    135 			else {
    136 				dx = ox;
    137 				dy = oy;
    138 				for (k=0, j=5; k < p->o_val[4]; k++, j += 2) {
    139 					ndx = dx + p->o_val[j];
    140 					ndy = dy + p->o_val[j+1];
    141 					line(dx, dy, ndx, ndy, p->o_attr & (DOTBIT|DASHBIT), p->o_ddval);
    142 					dx = ndx;
    143 					dy = ndy;
    144 				}
    145 			}
    146 			if (vis && p->o_attr & HEAD2) {
    147 				dx = ox;
    148 				dy = oy;
    149 				for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) {
    150 					dx += p->o_val[j];
    151 					dy += p->o_val[j+1];
    152 				}
    153 				arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
    154 			}
    155 			if (fill)
    156 				fillend();
    157 			move((ox + x1)/2, (oy + y1)/2);	/* center */
    158 			dotext(p);
    159 			break;
    160 		case MOVE:
    161 			move(ox, oy);
    162 			break;
    163 		case TEXT:
    164 			move(ox, oy);
    165                         if (vis)
    166 				dotext(p);
    167 			break;
    168 		}
    169 	}
    170 }
    171 
    172 void dotext(obj *p)	/* print text strings of p in proper vertical spacing */
    173 {
    174 	int i, nhalf;
    175 	void label(char *, int, int);
    176 
    177 	nhalf = p->o_nt2 - p->o_nt1 - 1;
    178 	for (i = p->o_nt1; i < p->o_nt2; i++) {
    179 		label(text[i].t_val, text[i].t_type, nhalf);
    180 		nhalf -= 2;
    181 	}
    182 }