Back to index

radiance  4R0+20100331
expand.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: expand.c,v 1.4 2003/11/15 02:13:36 schorsch Exp $";
00003 #endif
00004 /*
00005  *   Expansion routine for command implementation
00006  *   on simple drivers
00007  */
00008 
00009 #include  <string.h>
00010 
00011 #include  "meta.h"
00012 
00013                             /* vector characters file */
00014 #define  VINPUT  "vchars.mta"
00015 
00016 #define  FIRSTCHAR  ' '                   /* first vector character */
00017 
00018 #define  LASTCHAR  '~'                    /* last vector character */
00019 
00020 #define  PEPS  5                   /* minimum size for fill area */
00021 
00022 #define  fillok(p)  ((p)->xy[XMX] - (p)->xy[XMN] > PEPS && \
00023                      (p)->xy[YMX] - (p)->xy[YMN] > PEPS)
00024 
00025 
00026 
00027 static short  *xlist;                     /* pointer to expansion list */
00028 
00029 static void exfile(FILE  *fp);
00030 static void exprim(PRIMITIVE  *p);
00031 static void sendmstr(register PRIMITIVE  *p);
00032 static void sendvstr(register PRIMITIVE   *p);
00033 static void include(int  code, char  *fname);
00034 static void polyfill(PRIMITIVE  *p);
00035 static void polyedge(PRIMITIVE  *p, int  x1, int y1, int x2, int y2);
00036 
00037 
00038 void
00039 expand(              /* expand requested commands */
00040 FILE  *infp,
00041 short  *exlist
00042 )
00043 {
00044  static PRIMITIVE  pincl = {PINCL, 02, {-1, -1, -1, -1}, VINPUT, NULL};
00045  static short  vcloaded = FALSE;
00046 
00047  xlist = exlist;
00048 
00049  if (exlist[comndx(PVSTR)] == 1 && !vcloaded) {
00050     vcloaded = TRUE;
00051     exprim(&pincl);
00052     }
00053 
00054  exfile(infp);
00055 
00056  if (inseg())
00057     error(USER, "unclosed segment in expand");
00058     
00059  }
00060 
00061 
00062 
00063 
00064 static void
00065 exfile(                     /* expand the given file */
00066 register FILE  *fp
00067 )
00068 {
00069     PRIMITIVE  curp;
00070 
00071     while (readp(&curp, fp)) {
00072        exprim(&curp);
00073        fargs(&curp);
00074     }
00075 
00076 }
00077 
00078 
00079 
00080 
00081 static void
00082 exprim(                     /* expand primitive */
00083 register PRIMITIVE  *p
00084 )
00085 {
00086     int  xflag = xlist[comndx(p->com)];
00087                             /* 1==expand, 0==pass, -1==discard */
00088     if (xflag != -1) {
00089        if (xflag == 1)
00090           switch (p->com)  {
00091 
00092             case POPEN:
00093                openseg(p->args);
00094               break;
00095 
00096             case PSEG:
00097               segment(p, exprim);
00098               break;
00099 
00100             case PCLOSE:
00101               closeseg();
00102               break;
00103                
00104             case PINCL:
00105               include(p->arg0, p->args);
00106                break;
00107 
00108             case PMSTR:
00109               sendmstr(p);
00110               break;
00111                
00112             case PVSTR:
00113               sendvstr(p);
00114               break;
00115 
00116             case PPFILL:
00117                polyfill(p);
00118                break;
00119                
00120             default:
00121               sprintf(errmsg, "unsupported command '%c' in exprim", p->com);
00122               error(WARNING, errmsg);
00123                break;
00124             }
00125        else if (inseg())
00126           segprim(p);
00127        else
00128           writep(p, stdout);
00129     }
00130 }
00131 
00132 
00133 
00134 
00135 static void
00136 sendmstr(                   /* expand a matrix string */
00137 register PRIMITIVE  *p
00138 )
00139 {
00140     PRIMITIVE  pout;
00141     int  cheight, cwidth, cthick, ccol;
00142 
00143     cheight = 350;
00144     if (p->arg0 & 010)
00145        cheight *= 2;
00146     cwidth = (6 - ((p->arg0 >> 4) & 03)) * 35;
00147     if (p->arg0 & 04)
00148        cwidth *= 2;
00149     cthick = (p->arg0 & 0100) ? 1 : 0;
00150     ccol = p->arg0 & 03;
00151 
00152     pout.com = PVSTR;
00153     pout.arg0 = (cthick << 2) | ccol;
00154     pout.xy[XMN] = p->xy[XMN];
00155     pout.xy[YMN] = p->xy[YMX] - cheight/2;
00156     pout.xy[XMX] = p->xy[XMN] + strlen(p->args)*cwidth;
00157     if (pout.xy[XMX] >= XYSIZE)
00158        pout.xy[XMX] = XYSIZE-1;
00159     pout.xy[YMX] = p->xy[YMX] + cheight/2;
00160     pout.args = p->args;
00161 
00162     exprim(&pout);
00163 
00164 }
00165 
00166 
00167 
00168 static void
00169 sendvstr(                   /* expand a vector string */
00170 register PRIMITIVE   *p
00171 )
00172 {
00173     PRIMITIVE  pout;
00174     int  xadv = 0, yadv = 0;
00175     char  s[3];
00176     register char  *cp;
00177 
00178     if (p->args == NULL)
00179        error(USER, "illegal empty string in sendvstr");
00180 
00181     pout.com = PSEG;
00182     pout.arg0 = p->arg0;
00183     switch (p->arg0 & 060) {
00184        case 0:                     /* right */
00185            xadv = (p->xy[XMX] - p->xy[XMN])/strlen(p->args);
00186            pout.xy[XMN] = p->xy[XMN];
00187            pout.xy[XMX] = p->xy[XMN] + xadv;
00188            yadv = 0;
00189            pout.xy[YMN] = p->xy[YMN];
00190            pout.xy[YMX] = p->xy[YMX];
00191            break;
00192        case 020:            /* up */
00193            xadv = 0;
00194            pout.xy[XMN] = p->xy[XMN];
00195            pout.xy[XMX] = p->xy[XMX];
00196            yadv = (p->xy[YMX] - p->xy[YMN])/strlen(p->args);
00197            pout.xy[YMN] = p->xy[YMN];
00198            pout.xy[YMX] = p->xy[YMN] + yadv;
00199            break;
00200        case 040:            /* left */
00201            xadv = -(p->xy[XMX] - p->xy[XMN])/strlen(p->args);
00202            pout.xy[XMN] = p->xy[XMX] + xadv;
00203            pout.xy[XMX] = p->xy[XMX];
00204            yadv = 0;
00205            pout.xy[YMN] = p->xy[YMN];
00206            pout.xy[YMX] = p->xy[YMX];
00207            break;
00208        case 060:            /* down */
00209            xadv = 0;
00210            pout.xy[XMN] = p->xy[XMN];
00211            pout.xy[XMX] = p->xy[XMX];
00212            yadv = -(p->xy[YMX] - p->xy[YMN])/strlen(p->args);
00213            pout.xy[YMN] = p->xy[YMX] + yadv;
00214            pout.xy[YMX] = p->xy[YMX];
00215            break;
00216     }
00217 
00218     pout.args = s;
00219     s[1] = '\'';
00220     s[2] = '\0';
00221     for (cp = p->args; *cp; cp++)
00222        if (*cp < FIRSTCHAR || *cp > LASTCHAR) {
00223            sprintf(errmsg, "unknown character (%d) in sendvstr", *cp);
00224            error(WARNING, errmsg);
00225        }
00226        else {
00227            s[0] = *cp;
00228            exprim(&pout);
00229            pout.xy[XMN] += xadv;
00230            pout.xy[XMX] += xadv;
00231            pout.xy[YMN] += yadv;
00232            pout.xy[YMX] += yadv;
00233        }
00234 
00235 }
00236 
00237 
00238 
00239 static void
00240 include(                    /* load an include file */
00241 int  code,
00242 char  *fname
00243 )
00244 {
00245     register FILE  *fp = NULL;
00246 
00247     if (fname == NULL)
00248        error(USER, "missing include file name in include");
00249     
00250     if (code == 2 || (fp = fopen(fname, "r")) == NULL) {
00251        if (code != 0)
00252            fp = mfopen(fname, "r");
00253        else {
00254            sprintf(errmsg, "cannot open user include file \"%s\"", fname);
00255            error(USER, errmsg);
00256        }
00257     }
00258     
00259     exfile(fp);
00260     fclose(fp);
00261 
00262 }
00263 
00264 
00265 
00266 static void
00267 polyfill(                   /* expand polygon fill command */
00268 PRIMITIVE  *p
00269 )
00270 {
00271     char  firstx, firsty, x, y;
00272        int lastx, lasty;
00273     register char  *cp;
00274     
00275     if ((cp=nextscan(nextscan(p->args,"%d",&firstx),"%d",&firsty)) == NULL) {
00276         sprintf(errmsg, "illegal polygon spec \"%s\" in polyfill", p->args);
00277         error(WARNING, errmsg);
00278         return;
00279     }
00280     
00281     lastx = firstx;
00282     lasty = firsty;
00283     
00284     while ((cp=nextscan(nextscan(cp,"%d",&x),"%d",&y)) != NULL) {
00285     
00286         polyedge(p, lastx, lasty, x, y);
00287         lastx = x;
00288         lasty = y;
00289     }
00290     
00291     polyedge(p, lastx, lasty, firstx, firsty);
00292 }
00293 
00294 
00295 
00296 static void
00297 polyedge(            /* expand edge of polygon */
00298 PRIMITIVE  *p,
00299 int  x1, int y1, int x2, int y2
00300 )
00301 {
00302     int  reverse;
00303     PRIMITIVE  pin, pout;
00304     
00305     if (x1 < x2) {
00306         pin.xy[XMN] = x1;
00307         pin.xy[XMX] = x2;
00308         reverse = FALSE;
00309     } else {
00310         pin.xy[XMN] = x2;
00311         pin.xy[XMX] = x1;
00312         reverse = TRUE;
00313     }
00314     
00315     if (y1 < y2) {
00316         pin.xy[YMN] = y1;
00317         pin.xy[YMX] = y2;
00318     } else {
00319         pin.xy[YMN] = y2;
00320         pin.xy[YMX] = y1;
00321         reverse = y1 > y2 && !reverse;
00322     }
00323     
00324     pout.xy[XMN] = xlate(XMN, &pin, p);
00325     pout.xy[XMX] = xlate(XMX, &pin, p);
00326     pout.xy[YMN] = xlate(YMN, &pin, p);
00327     pout.xy[YMX] = xlate(YMX, &pin, p);
00328     pout.com = PTFILL;
00329     pout.arg0 = 0100 | (reverse << 4) | (p->arg0 & 017);
00330     pout.args = NULL;
00331     if (fillok(&pout))
00332        exprim(&pout);
00333     
00334     if (p->arg0 & 0100) {          /* draw border */
00335         pout.com = PLSEG;
00336         pout.arg0 = reverse << 6;
00337         exprim(&pout);
00338     }
00339     
00340     pout.com = PRFILL;
00341     pout.arg0 = 0100 | (p->arg0 & 017);
00342     pout.xy[XMN] = pout.xy[XMX];
00343     pout.xy[XMX] = p->xy[XMX];
00344     if (fillok(&pout))
00345        exprim(&pout);
00346     
00347 }