home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / dvips / dopage.c < prev    next >
C/C++ Source or Header  |  1994-09-27  |  12KB  |  388 lines

  1. /*
  2.  *   Main page drawing procedure.  Interprets the page commands.  A simple
  3.  *   (if lengthy) case statement interpreter.  
  4.  */
  5. #include "dvips.h" /* The copyright notice in that file is included too! */
  6. #include <math.h>
  7. /*
  8.  *   The external routines we use:
  9.  */
  10. #ifdef AMIGA
  11.  
  12. #ifdef _IEEE
  13. #include <mieeedoub.h>
  14. #else
  15. #ifdef _M68881
  16. #include <m68881.h>
  17. #endif
  18. #endif
  19.  
  20. #include "dopage_protos.h"
  21. #include "dospecial_protos.h"
  22. #include "dvips_protos.h"
  23. #include "output_protos.h"
  24. #include "dviinput_protos.h"
  25. #include "scalewidth_protos.h"
  26. #include "fontdef_protos.h"
  27. #include "color_protos.h"
  28.  
  29. #ifdef EMTEX
  30. #include "emspecial_protos.h"
  31. #endif
  32.  
  33. #else
  34. extern void error() ;
  35. extern void pageinit() ;
  36. extern void drawrule() ;
  37. extern shalfword dvibyte() ;
  38. extern halfword twobytes() ;
  39. extern integer threebytes() ;
  40. extern integer signedquad() ;
  41. extern shalfword signedbyte() ;
  42. extern shalfword signedpair() ;
  43. extern integer signedtrio() ;
  44. extern void dospecial() ;
  45. extern void drawchar() ;
  46. extern integer scalewidth() ;
  47. extern void skipover() ;
  48. extern void bopcolor() ; /* IBM: color */
  49. extern void fontdef() ;
  50. extern void pageend() ;
  51. #endif
  52. /*
  53.  *   Now the external variables.
  54.  */
  55. extern fontdesctype *curfnt ;
  56. extern fontdesctype *baseFonts[] ;
  57. extern fontmaptype *ffont ;
  58. extern quarterword *curpos, *curlim ;
  59. extern integer hh, vv ;
  60. extern integer hoff, voff ;
  61. /*
  62.  * CONVENTION:  conv -> horizontial converter
  63.  *        vconv -> vertical converter
  64.  */
  65. extern real conv ;
  66. extern real vconv ;
  67.  
  68. extern FILE *bitfile ;
  69. extern int actualdpi ;
  70. extern int vactualdpi ;
  71. extern frametype frames[] ;
  72. extern int maxdrift ;
  73. extern int vmaxdrift ;
  74. #ifdef EMTEX
  75. extern void emclear() ;
  76. #endif
  77.  
  78. #ifdef XENIX
  79. #define PixRound(x) ((integer)(x + (iconv >> 1)) / iconv)
  80. #define VPixRound(x) ((integer)(x + (viconv >> 1)) / viconv)
  81. #else
  82. #ifdef __THINK__
  83. #define  PixRound(x) ((integer)(x +  (iconv >> 1)) /  iconv)
  84. #define VPixRound(x) ((integer)(x + (viconv >> 1)) / viconv)
  85. #else
  86. #define PixRound(x) ((integer)(floor(((x) * conv) + 0.5)))
  87. #define VPixRound(x) ((integer)(floor(((x) * vconv) + 0.5)))
  88. #endif
  89. #endif
  90. /*
  91.  *   Now we have the dopage procedure.
  92.  *   Most error checking is suppressed because the prescan has already
  93.  *   verified that the DVI data is OK....except for stack over/underflow.
  94.  */
  95. struct dvistack {
  96.   integer hh, vv ;
  97.   integer h, v, w, x, y, z ;
  98. } stack[STACKSIZE] ;
  99. void
  100. dopage()
  101. {
  102.    register shalfword cmd ;
  103.    register integer p ;
  104.    register chardesctype *cd ;
  105.    register integer h ;
  106.    register fontmaptype *cfnt ;
  107.    register frametype *frp = frames ;
  108.    integer fnt ;
  109.    int charmove ;
  110.    struct dvistack *sp = stack ;
  111.    integer v, w, x, y, z ;
  112.    integer roundpos ;
  113.    integer thinspace ;
  114.    integer vertsmallspace ;
  115. #ifdef XENIX
  116.    integer iconv ;
  117.    integer viconv ;
  118.  
  119.    iconv = (integer)(1.0 / conv + 0.5) ;
  120.    viconv = (integer)(1.0 / vconv + 0.5) ;
  121. #else
  122. #ifdef __THINK__
  123.    integer  iconv ;
  124.    integer viconv ;
  125.  
  126.     iconv = (integer)(1.0 /  conv + 0.5) ;
  127.    viconv = (integer)(1.0 / vconv + 0.5) ;
  128. #endif
  129. #endif
  130. #ifdef EMTEX
  131.    emclear() ;
  132. #endif
  133.    pageinit() ;
  134.  
  135.    bopcolor(1) ;
  136.    thinspace =  (integer)(0.025*DPI/conv) ; /* 0.025 inches */
  137.    vertsmallspace = (integer)(0.025*VDPI/vconv) ; /* 0.025 inches */
  138.  
  139.    w = x = y = z = 0 ;
  140.    h = DPI / conv * hoff / 4736286.72 ;
  141.    v = DPI / conv * voff / 4736286.72 ;
  142.    hh = PixRound(h) ;
  143.    vv = PixRound(v) ;
  144.    curfnt = NULL ;
  145.    curpos = NULL ;
  146.    charmove = 0 ;
  147. beginloop:
  148.    switch (cmd=dvibyte()) {
  149. case 138: goto beginloop ; /* nop command does nuttin */
  150. /*
  151.  *   For put1 commands, we subtract the width of the character before
  152.  *   dropping through to the normal character setting routines.  This
  153.  */
  154. case 133: /* put1 */
  155.    cmd = dvibyte() ;
  156.    charmove = 0 ;
  157.    goto dochar ;
  158. case 128: cmd = dvibyte() ; /* set1 command drops through to setchar */
  159. default: /* these are commands 0 (setchar0) thru 127 (setchar127) */
  160.    charmove = 1 ;
  161. dochar:
  162.    cd = &(curfnt->chardesc[cmd]) ;
  163.    if (cd->flags & EXISTS) {
  164.       if (curfnt->loaded == 2) { /* virtual character being typeset */
  165.          if (charmove) {
  166.             sp->hh = hh + cd->pixelwidth ;
  167.             sp->h = h + cd->TFMwidth ;
  168.          } else {
  169.             sp->hh = hh ; sp->h = h ;
  170.          }
  171.          sp->vv = vv ; sp-> v = v ;
  172.          sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  173.          if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  174.          w = x = y = z = 0 ; /* will be in relative units at new stack level */
  175.          frp->curp = curpos ;
  176.          frp->curl = curlim ;
  177.          frp->ff = ffont ;
  178.          frp->curf = curfnt ;
  179.          if (++frp == &frames[MAXFRAME] )
  180.             error("! virtual recursion stack overflow") ;
  181.          curpos = cd->packptr + 2 ;
  182.          curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  183.          ffont = curfnt->localfonts ;
  184.          if (ffont) {
  185.             curfnt = ffont->desc ;
  186.             thinspace = curfnt->thinspace ;
  187.          } else {
  188.             curfnt = NULL ;
  189.             thinspace = vertsmallspace ;
  190.          }
  191.          goto beginloop ;
  192.       }
  193.       drawchar(cd, cmd) ;
  194.    }
  195.    if (charmove) {
  196.       h += cd->TFMwidth ;
  197.       hh += cd->pixelwidth ;
  198.    }
  199.    goto setmotion ;
  200. case 129: case 130: case 131: case 134: case 135: case 136: case 139: 
  201. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  202. case 254: case 255: /* unimplemented or illegal commands */
  203.    error("! synch") ;
  204. case 132: case 137: /* rules */
  205.  { integer ry, rx , rxx, ryy ;
  206.    ry = signedquad() ; rx = signedquad() ;
  207.    if (rx>0 && ry>0) {
  208.       if (curpos) {
  209.          rx = scalewidth(rx, (frp-1)->curf->scaledsize) ;
  210.          ry = scalewidth(ry, (frp-1)->curf->scaledsize) ;
  211.       }
  212.       rxx = (int)(conv * rx + 0.9999999) ;
  213.       ryy = (int)(vconv * ry + 0.9999999) ;
  214.       drawrule(rxx, ryy) ;
  215.    } else
  216.       rxx = 0 ;
  217.    if (cmd == 137) goto beginloop ;
  218.    h += rx ; hh += rxx ;
  219.    goto setmotion ;
  220.  }
  221. case 141: /* push */
  222.    sp->hh = hh ; sp->vv = vv ; sp->h = h ; sp->v = v ;
  223.    sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  224.    if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  225.    goto beginloop ;
  226. case 140: /* eop or end of virtual character */
  227.    if (curpos == NULL) break ; /* eop */
  228.    --frp ;
  229.    curfnt = frp->curf ;
  230.    thinspace = (curfnt) ? curfnt->thinspace : vertsmallspace ;
  231.    ffont = frp->ff ;
  232.    curlim = frp->curl ;
  233.    curpos = frp->curp ;
  234.    if (hh < (sp-1)->hh+2 && hh > (sp-1)->hh-2)
  235.       (sp-1)->hh = hh; /* retain `intelligence' of pixel width, if close */ 
  236.    /* falls through */
  237. case 142: /* pop */
  238.    if (--sp < stack) error("! More pops than pushes") ;
  239.    hh = sp->hh ; vv = sp->vv ; h = sp->h ; v = sp->v ;
  240.    w = sp->w ; x = sp->x ; y = sp->y ; z = sp->z ;
  241.    goto beginloop ;
  242. case 143: /* right1 */
  243.    p = signedbyte() ; goto horizontalmotion ;
  244. case 144: /* right2 */
  245.    p = signedpair() ; goto horizontalmotion ;
  246. case 145: /* right3 */
  247.    p = signedtrio() ; goto horizontalmotion ;
  248. case 146: /* right4 */
  249.    p = signedquad() ; goto horizontalmotion ;
  250. case 147: /* w0 */
  251.    p = w ; goto horizontalmotion ;
  252. case 148: /* w1 */
  253.    p = w = signedbyte() ; goto horizontalmotion ;
  254. case 149: /* w2 */
  255.    p = w = signedpair() ; goto horizontalmotion ;
  256. case 150: /* w3 */
  257.    p = w = signedtrio() ; goto horizontalmotion ;
  258. case 151: /* w4 */
  259.    p = w = signedquad() ; goto horizontalmotion ;
  260. case 152: /* x0 */
  261.    p = x ; goto horizontalmotion ;
  262. case 153: /* x1 */
  263.    p = x = signedbyte() ; goto horizontalmotion ;
  264. case 154: /* x2 */
  265.    p = x = signedpair() ; goto horizontalmotion ;
  266. case 155: /* x3 */
  267.    p = x = signedtrio() ; goto horizontalmotion ;
  268. case 156: /* x4 */
  269.    p = x = signedquad() ; goto horizontalmotion ;
  270. case 157: /* down1 */
  271.    p = signedbyte() ; goto verticalmotion ;
  272. case 158: /* down2 */
  273.    p = signedpair() ; goto verticalmotion ;
  274. case 159: /* down3 */
  275.    p = signedtrio() ; goto verticalmotion ;
  276. case 160: /* down4 */
  277.    p = signedquad() ; goto verticalmotion ;
  278. case 161: /* y0 */
  279.    p = y ; goto verticalmotion ;
  280. case 162: /* y1 */
  281.    p = y = signedbyte() ; goto verticalmotion ;
  282. case 163: /* y2 */
  283.    p = y = signedpair() ; goto verticalmotion ;
  284. case 164: /* y3 */
  285.    p = y = signedtrio() ; goto verticalmotion ;
  286. case 165: /* y4 */
  287.    p = y = signedquad() ; goto verticalmotion ;
  288. case 166: /* z0 */
  289.    p = z ; goto verticalmotion ;
  290. case 167: /* z1 */
  291.    p = z = signedbyte() ; goto verticalmotion ;
  292. case 168: /* z2 */
  293.    p = z = signedpair() ; goto verticalmotion ;
  294. case 169: /* z3 */
  295.    p = z = signedtrio() ; goto verticalmotion ;
  296. case 170: /* z4 */
  297.    p = z = signedquad() ; goto verticalmotion ;
  298. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  299. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  300. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  301. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  302. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  303. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  304. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  305. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  306. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  307. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  308.    if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  309.    else {
  310.       fnt = dvibyte() ;
  311.       while (cmd-- > 235)
  312.          fnt = (fnt << 8) + dvibyte() ;
  313.    }
  314.    if (curpos || fnt > 255) {
  315.       for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  316.          if (cfnt->fontnum == fnt) break ;
  317.       curfnt = cfnt->desc ;
  318.    } else
  319.       curfnt = baseFonts[fnt] ;
  320.    thinspace = curfnt->thinspace ;
  321.    goto beginloop ;
  322. case 243: case 244: case 245: case 246: /*fntdef1 */
  323.    skipover(cmd - 230) ;
  324.    skipover(dvibyte() + dvibyte()) ;
  325.    goto beginloop ;
  326. case 239: /* xxx1 */
  327.    p = dvibyte() ;
  328.    dospecial(p) ;
  329.    goto beginloop ;
  330. case 240: /* xxx2 */
  331.    p = twobytes() ;
  332.    dospecial(p) ;
  333.    goto beginloop ;
  334. case 241: /* xxx3 */
  335.    p = threebytes() ;
  336.    dospecial(p) ;
  337.    goto beginloop ;
  338. case 242: /* xxx4 */
  339.    p = signedquad() ;
  340.    dospecial(p) ;
  341.    goto beginloop ;
  342.  
  343. /*
  344.  *   The calculations here are crucial to the appearance of the document.
  345.  *   If the motion is small, we round the amount of relative motion; otherwise,
  346.  *   we update the position and round the new position.  Then we check to
  347.  *   insure that the rounded position didn't accumulate an error that was
  348.  *   greater than maxdrift.
  349.  */
  350. verticalmotion:
  351. /* vertical motion cases */
  352.       if (curpos)
  353.          p = scalewidth(p, (frp-1)->curf->scaledsize) ;
  354.       v += p ;
  355.       if (p >= vertsmallspace) vv = VPixRound(v) ;
  356.       else if (p <= -vertsmallspace) vv = VPixRound(v) ;
  357.       else 
  358.       { vv += VPixRound(p) ;
  359.         roundpos = VPixRound(v) ;
  360.         if (roundpos - vv > vmaxdrift) vv = roundpos - vmaxdrift ;
  361.         else if (vv - roundpos > vmaxdrift) vv = roundpos + vmaxdrift ;
  362.       }
  363.       goto beginloop ;
  364. /*
  365.  *   Horizontal motion is analogous. We know the exact width of each
  366.  *   character in pixels. Kerning is distinguished from space between
  367.  *   words if it's less than a thinspace and not more negative than would
  368.  *   occur when an accent is being positioned by backspacing.
  369.  */
  370. horizontalmotion:
  371. /* horizontal motion cases */
  372.       if (curpos)
  373.          p = scalewidth(p, (frp-1)->curf->scaledsize) ;
  374.       h += p ;
  375.       if (p >= thinspace || p <= -6 * thinspace) {
  376.          hh = PixRound(h) ; goto beginloop ;
  377.       }
  378.       else hh += PixRound(p) ;
  379. setmotion:
  380.       roundpos = PixRound(h) ;
  381.       if (roundpos - hh > maxdrift) { hh = roundpos - maxdrift ; }
  382.       else if (hh - roundpos > maxdrift) { hh = roundpos + maxdrift ; }
  383. goto beginloop ;
  384.  
  385.    } /* end of the big switch */
  386.    pageend() ;
  387. }
  388.