ftp.nice.ch/pub/next/text/tex/apps/TeXview-kp0.25.s.tar.gz#/TeXview/dopage.c

This is dopage.c in view mode; [Download] [Up]

/*
 *   dopage.c of dviamiga software package.
 *
 *   Main page drawing procedure.  Interprets the page commands.  A simple
 *   (if lengthy) case statement interpreter.  
 */
#include "structures.h"
/*
 *   The external routines we use:
 */
extern void error() ;
extern void TPSbop(), TPSeop(), TPSselfont() ;
extern void drawrule() ;
extern void strflush(), texflush() ;
extern shalfword dvibyte() ;
extern halfword twobytes() ;
extern integer threebytes() ;
extern integer signedquad() ;
extern shalfword signedbyte() ;
extern shalfword signedpair() ;
extern integer signedtrio() ;
extern void dospecial() ;
extern void loadfont() ;
extern void setstatus(), qstatus() ;
extern void fontdef() ;
extern void fpageinit(), fdrawchar(), fdrawrule(), abortpage() ;
extern void dviseek() ;
extern void gottapage() ;
extern int checkformessage() ;
extern long scalewidth() ;
extern void bopcolor() ;
/*
 *   Now the external variables.
 */
extern fontdesctype *curfnt ;
extern fontdesctype *baseFonts[] ;
extern fontmaptype *ffont ;
extern quarterword *virpos, *virlim ;
extern frametype frames[] ;
extern integer curpos ;
extern halfword fnt ;
extern shalfword hh, vv ;
extern TeXfontdesctype *TeXfonts[] ;
extern real conv ;
extern integer iconv ;
extern real vconv ;
extern integer viconv ;
extern Boolean pageinterrupted ;
extern Boolean pagedrawn ;
extern integer messagebit ;
extern FILE *dvifile ;
extern integer rthispage ;
extern char lastfile[] ;
extern real screendpi ;
#ifdef DEBUG
extern int debugon ;
#endif
int curpsfont = -1 ;
void
abortdvi() {
   error("! bad command in dvi file") ;
}
/*
 *   Now we have the dopage procedure.
 */
static struct dvistack {
   shalfword hh, vv ;
   integer h, v, w, x, y, z ;
} dvistack[STACKSIZE] ;
void dopage() {
   register shalfword cmd ;
   register integer p ;
   register chardesctype *cd ;
   register FILE *df ;
   register struct dvistack *sp ;
   integer h, v, w, x, y, z ;
   register integer thinspace ;
   register frametype *frp = frames ;
   integer *wds = 0 ;
   TeXfontdesctype *tfnt ;
   register fontmaptype *cfnt ;
   int charmove ;
   integer vertsmallspace = (integer)(0.025*100/vconv) ; /* 0.025 inches */

   qstatus("Drawing") ;
   curpsfont = -1 ;
#ifdef DEBUG
        if (debugon > 7) {
           printf("\nAt the top of dopage\n") ;
           fflush(stdout) ;
        }
#endif
   TPSbop() ;
   df = dvifile ;
   if (df == NULL || pagedrawn)
      return ;
   gottapage() ;
   sp = dvistack ;
   pageinterrupted = 0 ;
   thinspace = 111000 ;
   hh = vv = h = v = w = x = y = z = fnt = 0 ;
   curfnt = NULL ;
   tfnt = 0 ;
   virpos = 0 ;
   dviseek(rthispage) ;
   bopcolor(1) ;
   while (1) {
beginloop:
      cmd = dvibyte() ;
      if (cmd < 129 || cmd == 133) {
         if (cmd >= 128) {
            charmove = (cmd < 129) ;
            cmd = dvibyte() ;
         } else
            charmove = 1 ;
        cd = curfnt->chardesc+cmd ;
#ifdef DEBUG
        if (debugon > 8) {
           if (cmd < 127 && cmd >= 32)
              printf("`%c'", cmd) ;
           else
              printf("`\\%02x'", (unsigned int)cmd) ;
           fflush(stdout) ;
        }
#endif
        if (curfnt->virtual) {
           if (charmove) {
              sp->hh = hh + cd->pixelwidth ;
              sp->h = h + wds[cmd] ;
           } else {
              sp->h = h ;
              sp->hh = hh ;
           }
           sp->vv = vv ;
           sp-> v = v ;
           sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
           if (++sp >= &dvistack[STACKSIZE]) error("! Out of stack space") ;
           w = x = y = z = 0 ; /* will be in relative units at new stack level */
           frp->curp = virpos ;
           frp->curl = virlim ;
           frp->ff = ffont ;
           frp->curf = curfnt ;
           frp->tfnt = tfnt ;
           if (++frp == &frames[MAXFRAME] )
              error("! virtual recursion stack overflow") ;
           cd = curfnt->chardesc + cmd ;
           virpos = cd->packptr + 2 ;
           virlim = virpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
           ffont = curfnt->localfonts ;
           if (ffont) {
              tfnt = ffont->tdesc ;
              if (tfnt->loaded==NULL) {
                 texflush() ;
                 loadfont(tfnt) ;
              }
              curfnt = tfnt->loaded ;
              thinspace = tfnt->thinspace ;
              wds = tfnt->scaledwidth ;
              if (curfnt->virtual == 0 &&
                  curfnt->id != curpsfont) {
                  strflush() ;
                  TPSselfont(curfnt->id) ;
                  curpsfont = curfnt->id ;
               }
           } else {
              curfnt = NULL ;
              thinspace = vertsmallspace ;
           }
           goto beginloop ;
        } else {
            if (curfnt->virtual == 0 &&
                curfnt->id != curpsfont) {
               strflush() ;
               TPSselfont(curfnt->id) ;
               curpsfont = curfnt->id ;
           }
           fdrawchar(cmd, cd->pixelwidth) ;
           if (charmove) {
              h += wds[cmd] ;
              hh += cd->pixelwidth ;
           }
           goto setmotion ;
        }
      } else if (cmd < 171) {
#ifdef DEBUG
         if (debugon > 8) {
            printf("%02x", (unsigned)cmd) ;
            fflush(stdout) ;
         }
#endif
        switch (cmd) {
/* illegal options */
case 129: case 130: case 131: case 134: case 135: case 136: case 139:
   abortdvi() ;
case 140:
   if (virpos == NULL) goto donewloop ;
   --frp ;
   curfnt = frp->curf ;
   tfnt = frp->tfnt ;
   thinspace = (curfnt) ? tfnt->thinspace : vertsmallspace ;
   wds = tfnt->scaledwidth ;
   ffont = frp->ff ;
   virlim = frp->curl ;
   virpos = frp->curp ;
   if (hh < (sp-1)->hh+2 && hh > (sp-1)->hh-2)
      (sp-1)->hh = hh; /* retain `intelligence' of pixel width, if close */ 
   else
      if (debugon > 5) printf("*") ;
/* pop */
case 142:
   if (--sp < dvistack) abortpage() ;
   hh = sp->hh ; vv = sp->vv ;
   h = sp->h ; v = sp->v ;
   w = sp->w ; x = sp->x ;
   y = sp->y ; z = sp->z ;
   break ;
/* rules */
case 132: case 137:
 { integer ry, rx ;
   shalfword rxx, ryy ;
   ry = signedquad() ; rx = signedquad() ;
   if (virpos) {
      rx = scalewidth(rx, (frp-1)->tfnt->scaledsize) ;
      ry = scalewidth(ry, (frp-1)->tfnt->scaledsize) ;
   }
   if (rx > 0 && ry > 0) {
      rxx = (rx + iconv - 1) / iconv ;
      ryy = (ry + viconv - 1) / viconv ;
      fdrawrule(rxx, ryy) ;
   } else
      rxx = (rx + iconv - 1) / iconv ;
   if (cmd == 132) {
      h += rx ; hh += rxx ;
      goto setmotion ;
   }
 }
   break ;
/* nop, eop */
case 138:
   break ;
/* push */
case 141:
   if (sp >= dvistack+(STACKSIZE-1)) error("! Out of stack space") ;
   sp->hh = hh ; sp->vv = vv ;
   sp->h = h ; sp->v = v ;
   sp->w = w ; sp->x = x ;
   sp->y = y ; sp->z = z ;
   sp++ ; break ;
/* right */
case 143:
   p = signedbyte() ; goto horizontalmotion ;
case 144:
   p = signedpair() ; goto horizontalmotion ;
case 145:
   p = signedtrio() ; goto horizontalmotion ;
case 146:
   p = signedquad() ; goto horizontalmotion ;
/* w moves */
case 147:
   p = w ; goto horizontalmotion ;
case 148:
   p = w = signedbyte() ; goto horizontalmotion ;
case 149:
   p = w = signedpair() ; goto horizontalmotion ;
case 150:
   p = w = signedtrio() ; goto horizontalmotion ;
case 151:
   p = w = signedquad() ; goto horizontalmotion ;
/* x moves */
case 152:
   p = x ; goto horizontalmotion ;
case 153:
   p = x = signedbyte() ; goto horizontalmotion ;
case 154:
   p = x = signedpair() ; goto horizontalmotion ;
case 155:
   p = x = signedtrio() ; goto horizontalmotion ;
case 156:
   p = x = signedquad() ; goto horizontalmotion ;
/* down moves */
case 157:
   p = signedbyte() ; goto verticalmotion ;
case 158:
   p = signedpair() ; goto verticalmotion ;
case 159:
   p = signedtrio() ; goto verticalmotion ;
case 160:
   p = signedquad() ; goto verticalmotion ;
/* y moves */
case 161:
   p = y ; goto verticalmotion ;
case 162:
   p = y = signedbyte() ; goto verticalmotion ;
case 163:
   p = y = signedpair() ; goto verticalmotion ;
case 164:
   p = y = signedtrio() ; goto verticalmotion ;
case 165:
   p = y = signedquad() ; goto verticalmotion ;
/* z moves */
case 166:
   p = z ; goto verticalmotion ;
case 167:
   p = z = signedbyte() ; goto verticalmotion ;
case 168:
   p = z = signedpair() ; goto verticalmotion ;
case 169:
   p = z = signedtrio() ; goto verticalmotion ;
case 170:
   p = z = signedquad() ; goto verticalmotion ;
         }
         goto endofloop ;
      } else if (cmd < 236) {   /* font selection command */
         if (cmd < 235) fnt = cmd - 171 ;
         else fnt = dvibyte() ;
         if (virpos) {
            for (cfnt=ffont; cfnt; cfnt = cfnt->next)
               if (cfnt->fontnum == fnt) break ;
            tfnt = cfnt->tdesc ;
         } else
            tfnt = TeXfonts[fnt] ;
         if (tfnt->loaded==NULL) {
            texflush() ;
            loadfont(tfnt) ;
         }
         curfnt = tfnt->loaded ;
#ifdef DEBUG
         if (debugon > 7) {
            printf("<%d:%s>", fnt, curfnt->name+1) ;
            fflush(stdout) ;
         }
#endif
         if (curfnt->virtual == 0 &&
             curfnt->id != curpsfont) {
            strflush() ;
            TPSselfont(curfnt->id) ;
            curpsfont = curfnt->id ;
         }
         thinspace = tfnt->thinspace ;
         wds = tfnt->scaledwidth ;
      } else {
      switch (cmd) {
/* illegal options */
case 236: case 237: case 238: case 244: case 245: case 246: case 247: 
case 248: case 249: case 250: case 251: case 252: case 253: case 254: 
case 255:
   abortdvi() ;
/* font definition */
case 243:
   fontdef() ;
   break ;
/* specials */   /* this should eventually call a do special routine. */
case 239: p = dvibyte() ; dospecial(p) ; break ;
case 240: p = twobytes() ; dospecial(p) ; break ;
case 241: p = threebytes() ; dospecial(p) ; break ;
case 242: p = signedquad() ; dospecial(p) ; break ;
}
      }
      goto endofloop ;
/*
 *   The calculations here are crucial to the appearance of the document.
 *   If the motion is less than a thinspace, we round the motion; otherwise,
 *   we update the position and round the new position.  Then we check to
 *   insure that the rounded position didn't accumulate an error that was
 *   greater than MAXDRIFT.
 */
verticalmotion:
/* vertical motion cases */
      if (checkformessage())
         return ;
      if (virpos)
         p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
      v += p ;
      if (p >= vertsmallspace) vv = v / viconv ;
      else if (p <= -vertsmallspace) vv = v / viconv ;
      else 
      { vv += p / viconv ;
        cmd = v / viconv - vv ;
        if (cmd > MAXDRIFT) vv += cmd - MAXDRIFT ;
        else if (cmd < -MAXDRIFT) vv += cmd + MAXDRIFT ;
      }
      goto endofloop ;
/*
 *   The horizontal kerning is done exactly analogously to the vertical
 *   motion, only characters are handled automatically; there kern is
 *   not dependent directly on their width in the dvi units.  Thus, we
 *   do the hh and h motion in the drawchar part, and only check the
 *   rounding here.
 */
horizontalmotion:
/* horizontal motion cases */
      if (virpos)
         p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
      h += p ;
      if (p >= thinspace || p <= - (thinspace << 2)) {
         hh = h / iconv ;
         goto endofloop ;
      } else hh += p / iconv ;
setmotion:
      cmd = h / iconv - hh ;
      if (cmd > MAXDRIFT)
         hh += cmd - MAXDRIFT ;
      else if (cmd < -MAXDRIFT)
         hh += cmd + MAXDRIFT ;
endofloop: ;
   }
donewloop:
   pagedrawn = 1 ;
   texflush() ;
   TPSeop() ;
   qstatus("") ;
#ifdef DEBUG
        if (debugon > 7) {
           printf("\nAt the end of dopage\n") ;
           fflush(stdout) ;
        }
#endif
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.