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

  1. /*
  2.  *   Calculates the bounding box for a one-page .dvi file.
  3.  *   Based on a lot of other dvips stuff.  Requires a total re-scan
  4.  *   of the page.
  5.  *
  6.  *   If you request an EPSF file and specify -a, you may end up
  7.  *   processing a single page four times!
  8.  */
  9. #include "dvips.h"
  10. #include <math.h>
  11. #ifdef AMIGA
  12. #ifdef _IEEE
  13. #include <mieeedoub.h>
  14. #else
  15. #ifdef _M68881
  16. #include <m68881.h>
  17. #endif
  18. #endif
  19. #include "bbox_protos.h"
  20. #include "dvips_protos.h"
  21. #include "scalewidth_protos.h"
  22. #include "tfmload_protos.h"
  23. #include "dviinput_protos.h"
  24. #else
  25. extern char *mymalloc() ;
  26. extern integer scalewidth() ;
  27. extern void tfmopen(), skipover(), error() ;
  28. extern shalfword tfmbyte(), dvibyte(), signedbyte(), signedpair() ;
  29. extern halfword tfm16(), twobytes() ;
  30. extern integer tfm32(), threebytes(), signedtrio(), signedquad() ;
  31. #endif
  32.  
  33. extern char *nextstring, errbuf[] ;
  34. extern FILE *tfmfile, *dvifile ;
  35. extern fontdesctype *baseFonts[] ;
  36. extern integer firstboploc, num, den, mag ;
  37. extern integer hoff, voff ;
  38.  
  39. typedef struct {
  40.    integer llx, lly, urx, ury ;
  41. } bbchardesctype ;
  42. typedef struct {
  43.    bbchardesctype bbchardesc[256] ;
  44. } bbfontdesctype ;
  45.  
  46. static bbfontdesctype *bbaseFonts[256] ;
  47.  
  48. integer nscalewidth(a, b)
  49. register integer a, b ;
  50. {
  51.    if (a < 0)
  52.       return - nscalewidth(-a, b) ;
  53.    else if (b < 0)
  54.       return - scalewidth(a, -b) ;
  55.    else
  56.       return scalewidth(a, b) ;
  57. }
  58.  
  59. void bbtfmload(n)
  60. int n ;
  61. {
  62.    register shalfword i ;
  63.    register integer li ;
  64.    integer scaledsize ;
  65.    shalfword nw, nh, nd, ns, hd ;
  66.    shalfword bc, ec ;
  67.    integer scaled[300] ;
  68.    integer chardat[256] ;
  69.    integer slant = 0 ;
  70.    bbchardesctype *cc ;
  71.    register fontdesctype *curfnt = baseFonts[n] ;
  72.    register bbfontdesctype *bbcurfnt =
  73.       (bbfontdesctype *)mymalloc(sizeof(bbfontdesctype)) ;
  74.  
  75.    bbaseFonts[n] = bbcurfnt ;
  76.    tfmopen(curfnt) ;
  77. /*
  78.  *   Next, we read the font data from the tfm file, and store it in
  79.  *   our own arrays.
  80.  */
  81.    li = tfm16() ; hd = tfm16() ;
  82.    bc = tfm16() ; ec = tfm16() ;
  83.    nw = tfm16() ; nh = tfm16() ; nd = tfm16() ;
  84.    ns = tfm16() ;
  85.    ns += tfm16() ;
  86.    ns += tfm16() ;
  87.    ns += tfm16() ;
  88.    li = tfm16() ;
  89.    li = tfm32() ;
  90.    if (li && curfnt->checksum)
  91.       if (li!=curfnt->checksum) {
  92.          (void)sprintf(errbuf,"Checksum mismatch in %s", curfnt->name) ;
  93.          error(errbuf) ;
  94.        }
  95.    li = tfm32() ;
  96.    for (i=2; i<hd; i++)
  97.       li = tfm32() ;
  98.    for (i=0; i<256; i++)
  99.       chardat[i] = -1 ;
  100.    for (i=bc; i<=ec; i++) {
  101.       chardat[i] = tfm16() ;
  102.       li = tfm16() ;
  103.    }
  104.    scaledsize = curfnt->scaledsize ;
  105.    for (i=0; i<nw + nh + nd; i++)
  106.       scaled[i] = scalewidth(tfm32(), scaledsize) ;
  107.    for (i=0; i<ns; i++)
  108.       tfm32() ;
  109.    slant = tfm32() ;
  110.    (void)fclose(tfmfile) ;
  111.    for (i=0; i<256; i++) {
  112.       cc = &(bbcurfnt->bbchardesc[i]) ;
  113.       if (chardat[i] != -1) {
  114.          cc->ury = scaled[((chardat[i] >> 4) & 15) + nw] ;
  115.          cc->lly = - scaled[(chardat[i] & 15) + nw + nh] ;
  116.          cc->llx = 0 ;
  117.          cc->urx = curfnt->chardesc[i].TFMwidth ;
  118.       } else {
  119.          cc->llx = cc->lly = cc->urx = cc->ury = 0 ;
  120.       }
  121.    }
  122.    if (slant) {
  123.       for (i=0; i<256; i++) {
  124.          cc = &(bbcurfnt->bbchardesc[i]) ;
  125.          cc->llx += nscalewidth(cc->lly, slant) ;
  126.          cc->urx += nscalewidth(cc->ury, slant) ;
  127.       }
  128.    }
  129. }
  130. extern struct dvistack {
  131.   integer hh, vv ;
  132.   integer h, v, w, x, y, z ;
  133. } stack[] ;
  134. static integer llx, lly, urx, ury ;
  135. void bbdopage()
  136. {
  137.    register shalfword cmd ;
  138.    register bbchardesctype *bcd ;
  139.    register chardesctype *cd ;
  140.    register integer h ;
  141.    integer fnt ;
  142.    int charmove ;
  143.    struct dvistack *sp = stack ;
  144.    integer v, w, x, y, z ;
  145.    register fontdesctype *curfnt = 0 ;
  146.    register bbfontdesctype *bbcurfnt = 0 ;
  147.  
  148.    w = x = y = z = 0 ;
  149.    h = 0 ; v = 0 ;
  150.    llx = lly = 1000000000 ;
  151.    urx = ury = -1000000000 ;
  152.    charmove = 0 ;
  153.    while (1) {
  154.       switch (cmd=dvibyte()) {
  155. case 138: break ;
  156. case 133: /* put1 */
  157.          cmd = dvibyte() ;
  158.          charmove = 0 ;
  159.          goto dochar ;
  160. case 128: cmd = dvibyte() ; /* set1 command drops through to setchar */
  161. default: /* these are commands 0 (setchar0) thru 127 (setchar127) */
  162.          charmove = 1 ;
  163. dochar:
  164.          cd = &(curfnt->chardesc[cmd]) ;
  165.          bcd = &(bbcurfnt->bbchardesc[cmd]) ;
  166.          if (h + bcd->llx < llx) llx = h + bcd->llx ;
  167.          if (h + bcd->urx > urx) urx = h + bcd->urx ;
  168.          if (v - bcd->ury < lly) lly = v - bcd->ury ;
  169.          if (v - bcd->lly > ury) ury = v - bcd->lly ;
  170.          if (charmove)
  171.             h += cd->TFMwidth ;
  172.          break ;
  173. case 129: case 130: case 131: case 134: case 135: case 136: case 139: 
  174. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  175. case 254: case 255: /* unimplemented or illegal commands */
  176.          error("! synch") ;
  177. case 132: case 137: /* rules */
  178.          {  integer ry, rx ;
  179.             ry = signedquad() ; rx = signedquad() ;
  180.             if (rx>0 && ry>0) {
  181.                if (h < llx) llx = h ;
  182.                if (v - ry < lly) lly = v - ry ;
  183.                if (h + rx > urx) urx = h + rx ;
  184.                if (v > ury) ury = v ;
  185.             } else
  186.                rx = 0 ;
  187.             if (cmd != 137)
  188.                h += rx ;
  189.             break ;
  190.          }
  191. case 141: /* push */
  192.          sp->h = h ; sp->v = v ;
  193.          sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  194.          if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  195.          break ;
  196. case 140: /* eop or end of virtual character */
  197.          return ;
  198. case 142: /* pop */
  199.          if (--sp < stack) error("! More pops than pushes") ;
  200.          h = sp->h ; v = sp->v ;
  201.          w = sp->w ; x = sp->x ; y = sp->y ; z = sp->z ;
  202.          break ;
  203. case 143: h += signedbyte() ; break ;
  204. case 144: h += signedpair() ; break ;
  205. case 145: h += signedtrio() ; break ;
  206. case 146: h += signedquad() ; break ;
  207. case 147: h += w ; break ;
  208. case 148: h += (w = signedbyte()) ; break ;
  209. case 149: h += (w = signedpair()) ; break ;
  210. case 150: h += (w = signedtrio()) ; break ;
  211. case 151: h += (w = signedquad()) ; break ;
  212. case 152: h += x ; break ;
  213. case 153: h += (x = signedbyte()) ; break ;
  214. case 154: h += (x = signedpair()) ; break ;
  215. case 155: h += (x = signedtrio()) ; break ;
  216. case 156: h += (x = signedquad()) ; break ;
  217. case 157: v += signedbyte() ; break ;
  218. case 158: v += signedpair() ; break ;
  219. case 159: v += signedtrio() ; break ;
  220. case 160: v += signedquad() ; break ;
  221. case 161: v += y ; break ;
  222. case 162: v += (y = signedbyte()) ; break ;
  223. case 163: v += (y = signedpair()) ; break ;
  224. case 164: v += (y = signedtrio()) ; break ;
  225. case 165: v += (y = signedquad()) ; break ;
  226. case 166: v += z ; break ;
  227. case 167: v += (z = signedbyte()) ; break ;
  228. case 168: v += (z = signedpair()) ; break ;
  229. case 169: v += (z = signedtrio()) ; break ;
  230. case 170: v += (z = signedquad()) ; break ;
  231. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  232. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  233. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  234. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  235. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  236. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  237. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  238. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  239. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  240. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  241.          if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  242.          else {
  243.             fnt = dvibyte() ;
  244.             while (cmd-- > 235)
  245.                fnt = (fnt << 8) + dvibyte() ;
  246.          }
  247.          curfnt = baseFonts[fnt] ;
  248.          bbcurfnt = bbaseFonts[fnt] ;
  249.          if (bbcurfnt == 0) {
  250.             bbtfmload(fnt) ;
  251.             bbcurfnt = bbaseFonts[fnt] ;
  252.          }
  253.          break ;
  254. case 243: case 244: case 245: case 246: /*fntdef1 */
  255.          skipover(cmd - 230) ;
  256.          skipover(dvibyte() + dvibyte()) ;
  257.          break ;
  258. case 239: skipover((int)dvibyte()) ; break ;
  259. case 240: skipover((int)twobytes()) ; break ;
  260. case 241: skipover((int)threebytes()) ; break ;
  261. case 242: skipover((int)signedquad()) ; break ;
  262.       }
  263.    }
  264. }
  265. void findbb() {
  266.    integer curpos = ftell(dvifile) ;
  267.    real conv = 72.0 * (real)num / (real)den * (real)mag / 254000000.0 ;
  268.    real off = 72.0 / conv ;
  269.    real margin = 1.0 / conv ;
  270.    real vsize = 792.0 / conv ;
  271.    real hadj = -72.0 * hoff / 4736286.72 ;
  272.    real vadj = 72.0 * voff / 4736286.72 ;
  273.  
  274.    fseek(dvifile, firstboploc, 0) ;
  275.    bbdopage() ;
  276.    fseek(dvifile, curpos, 0) ;
  277.    lly = vsize - 2 * off - lly ;
  278.    ury = vsize - 2 * off - ury ;
  279.    llx = (int)floor((llx + off - margin) * conv - hadj + 0.5) ;
  280.    lly = (int)floor((lly + off + margin) * conv - vadj + 0.5) ;
  281.    urx = (int)floor((urx + off + margin) * conv - hadj + 0.5) ;
  282.    ury = (int)floor((ury + off - margin) * conv - vadj + 0.5) ;
  283. /* no marks on the page? */
  284.    if (llx >= urx || lly <= ury)
  285.       llx = lly = urx = ury = 72 ;
  286. #ifdef SHORTINT
  287.    sprintf(nextstring, "%ld %ld %ld %ld", llx, ury, urx, lly) ;
  288. #else
  289.    sprintf(nextstring, "%d %d %d %d", llx, ury, urx, lly) ;
  290. #endif
  291. }
  292.