plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

symbol.c (3310B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <stdio.h>
      4 #include "map.h"
      5 #include "iplot.h"
      6 
      7 #define NSYMBOL 20
      8 
      9 enum flag { POINT,ENDSEG,ENDSYM };
     10 struct symb {
     11 	double x, y;
     12 	char name[10+1];
     13 	enum flag flag;
     14 } *symbol[NSYMBOL];
     15 
     16 static int nsymbol;
     17 static double halfrange = 1;
     18 extern int halfwidth;
     19 extern int vflag;
     20 
     21 static int	getrange(FILE *);
     22 static int	getsymbol(FILE *, int);
     23 static void	setrot(struct place *, double, int);
     24 static void	dorot(struct symb *, double *, double *);
     25 
     26 
     27 void
     28 getsyms(char *file)
     29 {
     30 	FILE *sf = fopen(file,"r");
     31 	if(sf==0)
     32 		filerror("cannot open", file);
     33 	while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
     34 		nsymbol++;
     35 	fclose(sf);
     36 }
     37 
     38 static int
     39 getsymbol(FILE *sf, int n)
     40 {
     41 	double x,y;
     42 	char s[2];
     43 	int i;
     44 	struct symb *sp;
     45 	for(;;) {
     46 		if(fscanf(sf,"%1s",s)==EOF)
     47 			return 0;
     48 		switch(s[0]) {
     49 		case ':':
     50 			break;
     51 		case 'o':
     52 		case 'c':	/* cl */
     53 			fscanf(sf,"%*[^\n]");
     54 			continue;
     55 		case 'r':
     56 			if(getrange(sf))
     57 				continue;
     58 		default:
     59 			error("-y file syntax error");
     60 		}
     61 		break;
     62 	}
     63 	sp = (struct symb*)malloc(sizeof(struct symb));
     64 	symbol[n] = sp;
     65 	if(fscanf(sf,"%10s",sp->name)!=1)
     66 		return 0;
     67 	i = 0;
     68 	while(fscanf(sf,"%1s",s)!=EOF) {
     69 		switch(s[0]) {
     70 		case 'r':
     71 			if(!getrange(sf))
     72 				break;
     73 			continue;
     74 		case 'm':
     75 			if(i>0)
     76 				symbol[n][i-1].flag = ENDSEG;
     77 			continue;
     78 		case ':':
     79 			ungetc(s[0],sf);
     80 			break;
     81 		default:
     82 			ungetc(s[0],sf);
     83 		case 'v':
     84 			if(fscanf(sf,"%lf %lf",&x,&y)!=2)
     85 				break;
     86 			sp[i].x = x*halfwidth/halfrange;
     87 			sp[i].y = y*halfwidth/halfrange;
     88 			sp[i].flag = POINT;
     89 			i++;
     90 			sp = symbol[n] = (struct symb*)realloc(symbol[n],
     91 					(i+1)*sizeof(struct symb));
     92 			continue;
     93 		}
     94 		break;
     95 	}
     96 	if(i>0)
     97 		symbol[n][i-1].flag = ENDSYM;
     98 	else
     99 		symbol[n] = 0;
    100 	return 1;
    101 }
    102 
    103 static int
    104 getrange(FILE *sf)
    105 {
    106 	double x,y,xmin,ymin;
    107 	if(fscanf(sf,"%*s %lf %lf %lf %lf",
    108 		&xmin,&ymin,&x,&y)!=4)
    109 		return 0;
    110 	x -= xmin;
    111 	y -= ymin;
    112 	halfrange = (x>y? x: y)/2;
    113 	if(halfrange<=0)
    114 		error("bad ra command in -y file");
    115 	return 1;
    116 }
    117 
    118 /* r=0 upright;=1 normal;=-1 reverse*/
    119 int
    120 putsym(struct place *p, char *name, double s, int r)
    121 {
    122 	int x,y,n;
    123 	struct symb *sp;
    124 	double dx,dy;
    125 	int conn = 0;
    126 	for(n=0; symbol[n]; n++)
    127 		if(strcmp(name,symbol[n]->name)==0)
    128 			break;
    129 	sp = symbol[n];
    130 	if(sp==0)
    131 		return 0;
    132 	if(doproj(p,&x,&y)*vflag <= 0)
    133 		return 1;
    134 	setrot(p,s,r);
    135 	for(;;) {
    136 		dorot(sp,&dx,&dy);
    137 		conn = cpoint(x+(int)dx,y+(int)dy,conn);
    138 		switch(sp->flag) {
    139 		case ENDSEG:
    140 			conn = 0;
    141 		case POINT:
    142 			sp++;
    143 			continue;
    144 		case ENDSYM:
    145 			break;
    146 		}
    147 		break;
    148 	}
    149 	return 1;
    150 }
    151 
    152 static double rot[2][2];
    153 
    154 static void
    155 setrot(struct place *p, double s, int r)
    156 {
    157 	double x0,y0,x1,y1;
    158 	struct place up;
    159 	up = *p;
    160 	up.nlat.l += .5*RAD;
    161 	sincos(&up.nlat);
    162 	if(r&&(*projection)(p,&x0,&y0)) {
    163 		if((*projection)(&up,&x1,&y1)<=0) {
    164 			up.nlat.l -= RAD;
    165 			sincos(&up.nlat);
    166 			if((*projection)(&up,&x1,&y1)<=0)
    167 				goto unit;
    168 			x1 = x0 - x1;
    169 			y1 = y0 - y1;
    170 		} else {
    171 			x1 -= x0;
    172 			y1 -= y0;
    173 		}
    174 		x1 = r*x1;
    175 		s /= hypot(x1,y1);
    176 		rot[0][0] = y1*s;
    177 		rot[0][1] = x1*s;
    178 		rot[1][0] = -x1*s;
    179 		rot[1][1] = y1*s;
    180 	} else {
    181 unit:
    182 		rot[0][0] = rot[1][1] = s;
    183 		rot[0][1] = rot[1][0] = 0;
    184 	}
    185 }
    186 
    187 static void
    188 dorot(struct symb *sp, double *px, double *py)
    189 {
    190 	*px = rot[0][0]*sp->x + rot[0][1]*sp->y;
    191 	*py = rot[1][0]*sp->x + rot[1][1]*sp->y;
    192 }