plan9port

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

print.c (5269B)


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