home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3.4.17 [SPARC, PA-RISC] / nextstep33_risc.iso / NextLibrary / TeX / tex / src / texview / dopage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-20  |  11.3 KB  |  412 lines

  1. /*
  2.  *   dopage.c of dviamiga software package.
  3.  *
  4.  *   Main page drawing procedure.  Interprets the page commands.  A simple
  5.  *   (if lengthy) case statement interpreter.  
  6.  */
  7. #include "structures.h"
  8. /*
  9.  *   The external routines we use:
  10.  */
  11. extern void error() ;
  12. extern void TPSbop(), TPSeop(), TPSselfont() ;
  13. extern void drawrule() ;
  14. extern void strflush(), texflush() ;
  15. extern shalfword dvibyte() ;
  16. extern halfword twobytes() ;
  17. extern integer threebytes() ;
  18. extern integer signedquad() ;
  19. extern shalfword signedbyte() ;
  20. extern shalfword signedpair() ;
  21. extern integer signedtrio() ;
  22. extern void dospecial() ;
  23. extern void loadfont() ;
  24. extern void setstatus(), qstatus() ;
  25. extern void fontdef() ;
  26. extern void fpageinit(), fdrawchar(), fdrawrule(), abortpage() ;
  27. extern void dviseek() ;
  28. extern void gottapage() ;
  29. extern int checkformessage() ;
  30. extern long scalewidth() ;
  31. extern void bopcolor() ;
  32. /*
  33.  *   Now the external variables.
  34.  */
  35. extern fontdesctype *curfnt ;
  36. extern fontdesctype *baseFonts[] ;
  37. extern fontmaptype *ffont ;
  38. extern quarterword *virpos, *virlim ;
  39. extern frametype frames[] ;
  40. extern integer curpos ;
  41. extern halfword fnt ;
  42. extern shalfword hh, vv ;
  43. extern TeXfontdesctype *TeXfonts[] ;
  44. extern real conv ;
  45. extern integer iconv ;
  46. extern real vconv ;
  47. extern integer viconv ;
  48. extern Boolean pageinterrupted ;
  49. extern Boolean pagedrawn ;
  50. extern integer messagebit ;
  51. extern FILE *dvifile ;
  52. extern integer rthispage ;
  53. extern char lastfile[] ;
  54. extern real screendpi ;
  55. #ifdef DEBUG
  56. extern int debugon ;
  57. #endif
  58. void
  59. abortdvi() {
  60.    error("! bad command in dvi file") ;
  61. }
  62. /*
  63.  *   Now we have the dopage procedure.
  64.  */
  65. static struct dvistack {
  66.    shalfword hh, vv ;
  67.    integer h, v, w, x, y, z ;
  68. } dvistack[STACKSIZE] ;
  69. void dopage() {
  70.    register shalfword cmd ;
  71.    register integer p ;
  72.    register chardesctype *cd ;
  73.    register FILE *df ;
  74.    register struct dvistack *sp ;
  75.    integer h, v, w, x, y, z ;
  76.    register integer thinspace ;
  77.    register frametype *frp = frames ;
  78.    integer *wds = 0 ;
  79.    TeXfontdesctype *tfnt ;
  80.    register fontmaptype *cfnt ;
  81.    int curpsfont = -1 ;
  82.    int charmove ;
  83.    integer vertsmallspace = (integer)(0.025*100/vconv) ; /* 0.025 inches */
  84.  
  85.    qstatus("Drawing") ;
  86. #ifdef DEBUG
  87.         if (debugon > 7) {
  88.            printf("\nAt the top of dopage\n") ;
  89.            fflush(stdout) ;
  90.         }
  91. #endif
  92.    TPSbop() ;
  93.    df = dvifile ;
  94.    if (df == NULL || pagedrawn)
  95.       return ;
  96.    gottapage() ;
  97.    sp = dvistack ;
  98.    pageinterrupted = 0 ;
  99.    thinspace = 111000 ;
  100.    hh = vv = h = v = w = x = y = z = fnt = 0 ;
  101.    curfnt = NULL ;
  102.    tfnt = 0 ;
  103.    virpos = 0 ;
  104.    dviseek(rthispage) ;
  105.    bopcolor(1) ;
  106.    while (1) {
  107. beginloop:
  108.       cmd = dvibyte() ;
  109.       if (cmd < 129 || cmd == 133) {
  110.          if (cmd >= 128) {
  111.             charmove = (cmd < 129) ;
  112.             cmd = dvibyte() ;
  113.          } else
  114.             charmove = 1 ;
  115.         cd = curfnt->chardesc+cmd ;
  116. #ifdef DEBUG
  117.         if (debugon > 8) {
  118.            if (cmd < 127 && cmd >= 32)
  119.               printf("`%c'", cmd) ;
  120.            else
  121.               printf("`\\%02x'", (unsigned int)cmd) ;
  122.            fflush(stdout) ;
  123.         }
  124. #endif
  125.         if (curfnt->virtual) {
  126.            if (charmove) {
  127.               sp->hh = hh + cd->pixelwidth ;
  128.               sp->h = h + wds[cmd] ;
  129.            } else {
  130.               sp->h = h ;
  131.               sp->hh = hh ;
  132.            }
  133.            sp->vv = vv ;
  134.            sp-> v = v ;
  135.            sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  136.            if (++sp >= &dvistack[STACKSIZE]) error("! Out of stack space") ;
  137.            w = x = y = z = 0 ; /* will be in relative units at new stack level */
  138.            frp->curp = virpos ;
  139.            frp->curl = virlim ;
  140.            frp->ff = ffont ;
  141.            frp->curf = curfnt ;
  142.            frp->tfnt = tfnt ;
  143.            if (++frp == &frames[MAXFRAME] )
  144.               error("! virtual recursion stack overflow") ;
  145.            cd = curfnt->chardesc + cmd ;
  146.            virpos = cd->packptr + 2 ;
  147.            virlim = virpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  148.            ffont = curfnt->localfonts ;
  149.            if (ffont) {
  150.               tfnt = ffont->tdesc ;
  151.               if (tfnt->loaded==NULL) {
  152.                  texflush() ;
  153.                  loadfont(tfnt) ;
  154.               }
  155.               curfnt = tfnt->loaded ;
  156.               thinspace = tfnt->thinspace ;
  157.               wds = tfnt->scaledwidth ;
  158.               if (curfnt->virtual == 0 &&
  159.                   curfnt->id != curpsfont) {
  160.                   strflush() ;
  161.                   TPSselfont(curfnt->id) ;
  162.                   curpsfont = curfnt->id ;
  163.                }
  164.            } else {
  165.               curfnt = NULL ;
  166.               thinspace = vertsmallspace ;
  167.            }
  168.            goto beginloop ;
  169.         } else {
  170.            fdrawchar(cmd, cd->pixelwidth) ;
  171.            if (charmove) {
  172.               h += wds[cmd] ;
  173.               hh += cd->pixelwidth ;
  174.            }
  175.            goto setmotion ;
  176.         }
  177.       } else if (cmd < 171) {
  178. #ifdef DEBUG
  179.          if (debugon > 8) {
  180.             printf("%02x", (unsigned)cmd) ;
  181.             fflush(stdout) ;
  182.          }
  183. #endif
  184.         switch (cmd) {
  185. /* illegal options */
  186. case 129: case 130: case 131: case 134: case 135: case 136: case 139:
  187.    abortdvi() ;
  188. case 140:
  189.    if (virpos == NULL) goto donewloop ;
  190.    --frp ;
  191.    curfnt = frp->curf ;
  192.    tfnt = frp->tfnt ;
  193.    thinspace = (curfnt) ? tfnt->thinspace : vertsmallspace ;
  194.    wds = tfnt->scaledwidth ;
  195.    ffont = frp->ff ;
  196.    virlim = frp->curl ;
  197.    virpos = frp->curp ;
  198.    if (hh < (sp-1)->hh+2 && hh > (sp-1)->hh-2)
  199.       (sp-1)->hh = hh; /* retain `intelligence' of pixel width, if close */ 
  200.    else
  201.       if (debugon > 5) printf("*") ;
  202. /* pop */
  203. case 142:
  204.    if (--sp < dvistack) abortpage() ;
  205.    hh = sp->hh ; vv = sp->vv ;
  206.    h = sp->h ; v = sp->v ;
  207.    w = sp->w ; x = sp->x ;
  208.    y = sp->y ; z = sp->z ;
  209.    break ;
  210. /* rules */
  211. case 132: case 137:
  212.  { integer ry, rx ;
  213.    shalfword rxx, ryy ;
  214.    ry = signedquad() ; rx = signedquad() ;
  215.    if (virpos) {
  216.       rx = scalewidth(rx, (frp-1)->tfnt->scaledsize) ;
  217.       ry = scalewidth(ry, (frp-1)->tfnt->scaledsize) ;
  218.    }
  219.    if (rx > 0 && ry > 0) {
  220.       rxx = (rx + iconv - 1) / iconv ;
  221.       ryy = (ry + viconv - 1) / viconv ;
  222.       fdrawrule(rxx, ryy) ;
  223.    } else
  224.       rxx = (rx + iconv - 1) / iconv ;
  225.    if (cmd == 132) {
  226.       h += rx ; hh += rxx ;
  227.       goto setmotion ;
  228.    }
  229.  }
  230.    break ;
  231. /* nop, eop */
  232. case 138:
  233.    break ;
  234. /* push */
  235. case 141:
  236.    if (sp >= dvistack+(STACKSIZE-1)) error("! Out of stack space") ;
  237.    sp->hh = hh ; sp->vv = vv ;
  238.    sp->h = h ; sp->v = v ;
  239.    sp->w = w ; sp->x = x ;
  240.    sp->y = y ; sp->z = z ;
  241.    sp++ ; break ;
  242. /* right */
  243. case 143:
  244.    p = signedbyte() ; goto horizontalmotion ;
  245. case 144:
  246.    p = signedpair() ; goto horizontalmotion ;
  247. case 145:
  248.    p = signedtrio() ; goto horizontalmotion ;
  249. case 146:
  250.    p = signedquad() ; goto horizontalmotion ;
  251. /* w moves */
  252. case 147:
  253.    p = w ; goto horizontalmotion ;
  254. case 148:
  255.    p = w = signedbyte() ; goto horizontalmotion ;
  256. case 149:
  257.    p = w = signedpair() ; goto horizontalmotion ;
  258. case 150:
  259.    p = w = signedtrio() ; goto horizontalmotion ;
  260. case 151:
  261.    p = w = signedquad() ; goto horizontalmotion ;
  262. /* x moves */
  263. case 152:
  264.    p = x ; goto horizontalmotion ;
  265. case 153:
  266.    p = x = signedbyte() ; goto horizontalmotion ;
  267. case 154:
  268.    p = x = signedpair() ; goto horizontalmotion ;
  269. case 155:
  270.    p = x = signedtrio() ; goto horizontalmotion ;
  271. case 156:
  272.    p = x = signedquad() ; goto horizontalmotion ;
  273. /* down moves */
  274. case 157:
  275.    p = signedbyte() ; goto verticalmotion ;
  276. case 158:
  277.    p = signedpair() ; goto verticalmotion ;
  278. case 159:
  279.    p = signedtrio() ; goto verticalmotion ;
  280. case 160:
  281.    p = signedquad() ; goto verticalmotion ;
  282. /* y moves */
  283. case 161:
  284.    p = y ; goto verticalmotion ;
  285. case 162:
  286.    p = y = signedbyte() ; goto verticalmotion ;
  287. case 163:
  288.    p = y = signedpair() ; goto verticalmotion ;
  289. case 164:
  290.    p = y = signedtrio() ; goto verticalmotion ;
  291. case 165:
  292.    p = y = signedquad() ; goto verticalmotion ;
  293. /* z moves */
  294. case 166:
  295.    p = z ; goto verticalmotion ;
  296. case 167:
  297.    p = z = signedbyte() ; goto verticalmotion ;
  298. case 168:
  299.    p = z = signedpair() ; goto verticalmotion ;
  300. case 169:
  301.    p = z = signedtrio() ; goto verticalmotion ;
  302. case 170:
  303.    p = z = signedquad() ; goto verticalmotion ;
  304.          }
  305.          goto endofloop ;
  306.       } else if (cmd < 236) {   /* font selection command */
  307.          if (cmd < 235) fnt = cmd - 171 ;
  308.          else fnt = dvibyte() ;
  309.          if (virpos) {
  310.             for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  311.                if (cfnt->fontnum == fnt) break ;
  312.             tfnt = cfnt->tdesc ;
  313.          } else
  314.             tfnt = TeXfonts[fnt] ;
  315.          if (tfnt->loaded==NULL) {
  316.             texflush() ;
  317.             loadfont(tfnt) ;
  318.          }
  319.          curfnt = tfnt->loaded ;
  320. #ifdef DEBUG
  321.          if (debugon > 7) {
  322.             printf("<%d:%s>", fnt, curfnt->name+1) ;
  323.             fflush(stdout) ;
  324.          }
  325. #endif
  326.          if (curfnt->virtual == 0 &&
  327.              curfnt->id != curpsfont) {
  328.             strflush() ;
  329.             TPSselfont(curfnt->id) ;
  330.             curpsfont = curfnt->id ;
  331.          }
  332.          thinspace = tfnt->thinspace ;
  333.          wds = tfnt->scaledwidth ;
  334.       } else {
  335.       switch (cmd) {
  336. /* illegal options */
  337. case 236: case 237: case 238: case 244: case 245: case 246: case 247: 
  338. case 248: case 249: case 250: case 251: case 252: case 253: case 254: 
  339. case 255:
  340.    abortdvi() ;
  341. /* font definition */
  342. case 243:
  343.    fontdef() ;
  344.    break ;
  345. /* specials */   /* this should eventually call a do special routine. */
  346. case 239: p = dvibyte() ; dospecial(p) ; break ;
  347. case 240: p = twobytes() ; dospecial(p) ; break ;
  348. case 241: p = threebytes() ; dospecial(p) ; break ;
  349. case 242: p = signedquad() ; dospecial(p) ; break ;
  350. }
  351.       }
  352.       goto endofloop ;
  353. /*
  354.  *   The calculations here are crucial to the appearance of the document.
  355.  *   If the motion is less than a thinspace, we round the motion; otherwise,
  356.  *   we update the position and round the new position.  Then we check to
  357.  *   insure that the rounded position didn't accumulate an error that was
  358.  *   greater than MAXDRIFT.
  359.  */
  360. verticalmotion:
  361. /* vertical motion cases */
  362.       if (checkformessage())
  363.          return ;
  364.       if (virpos)
  365.          p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
  366.       v += p ;
  367.       if (p >= vertsmallspace) vv = v / viconv ;
  368.       else if (p <= -vertsmallspace) vv = v / viconv ;
  369.       else 
  370.       { vv += p / viconv ;
  371.         cmd = v / viconv - vv ;
  372.         if (cmd > MAXDRIFT) vv += cmd - MAXDRIFT ;
  373.         else if (cmd < -MAXDRIFT) vv += cmd + MAXDRIFT ;
  374.       }
  375.       goto endofloop ;
  376. /*
  377.  *   The horizontal kerning is done exactly analogously to the vertical
  378.  *   motion, only characters are handled automatically; there kern is
  379.  *   not dependent directly on their width in the dvi units.  Thus, we
  380.  *   do the hh and h motion in the drawchar part, and only check the
  381.  *   rounding here.
  382.  */
  383. horizontalmotion:
  384. /* horizontal motion cases */
  385.       if (virpos)
  386.          p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
  387.       h += p ;
  388.       if (p >= thinspace || p <= - (thinspace << 2)) {
  389.          hh = h / iconv ;
  390.          goto endofloop ;
  391.       } else hh += p / iconv ;
  392. setmotion:
  393.       cmd = h / iconv - hh ;
  394.       if (cmd > MAXDRIFT)
  395.          hh += cmd - MAXDRIFT ;
  396.       else if (cmd < -MAXDRIFT)
  397.          hh += cmd + MAXDRIFT ;
  398. endofloop: ;
  399.    }
  400. donewloop:
  401.    pagedrawn = 1 ;
  402.    texflush() ;
  403.    TPSeop() ;
  404.    qstatus("") ;
  405. #ifdef DEBUG
  406.         if (debugon > 7) {
  407.            printf("\nAt the end of dopage\n") ;
  408.            fflush(stdout) ;
  409.         }
  410. #endif
  411. }
  412.