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