home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume24 / psroff3.0 / part14 / opt.c next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  6.1 KB  |  282 lines

  1. /*
  2.     Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 Chris Lewis
  3.         All Rights Reserved
  4.  
  5.     See the LICENSE file for a full description of restrictions under which
  6.     this software is provided.
  7.  
  8.     Function:        Optimizer module
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. int specXPos, specYPos;
  14. extern struct cattab tabN[], tabS[];
  15.  
  16. #ifdef    OPT
  17. #ifndef    lint
  18. static char SCCSid[] =
  19.     "@(#)opt.c: 2.4 Copyright 91/02/20 09:02:37 Chris Lewis";
  20. #endif
  21.  
  22. struct insbuf {
  23.     char font, points, nc;
  24.     short xpos, ypos;
  25. };
  26.  
  27. #define    INSBUFSIZ    200
  28. #define    OPTSIZ    100
  29. struct insbuf insbuf[INSBUFSIZ];
  30. static struct insbuf *insptr = insbuf;
  31. static int insypos = -1;
  32.  
  33. canoninsert(xpos, ypos, font, points, nc)
  34. register int xpos, ypos;
  35. register int font, points, nc; {
  36.     DBP((D_CAT, "canoninsert: %d %d %d %d %d\n", xpos, ypos, font, points,
  37.     nc));
  38.  
  39.     if (insypos != ypos || (insptr - insbuf >= INSBUFSIZ - 2)) {
  40.     canonflush();
  41.     insypos = ypos;
  42.     }
  43.     insptr->font = font;
  44.     insptr->points = points;
  45.     insptr->nc = nc;
  46.     insptr->xpos = xpos;
  47.     insptr++;
  48. }
  49.  
  50. #ifdef    SORT
  51. int xsortorder;
  52.  
  53. xsort(a, b)
  54. register struct insbuf *a, *b; {
  55.     int ret;
  56.     if (a->xpos < b->xpos)
  57.     ret = -1;
  58.     else if (a->xpos > b->xpos)
  59.     ret = 1;
  60.     else
  61.     ret = 0;
  62.     return(xsortorder * ret);
  63. }
  64. #endif
  65.  
  66. canonflush() {
  67.     register struct insbuf *ip;
  68.     insptr--;
  69.     DBP((D_CAT, "canonflush: start: %d chars\n", insptr - insbuf + 1));
  70.  
  71.     if (insptr < insbuf) {
  72.     insptr = insbuf;
  73.     return;
  74.     }
  75.  
  76.     if (insptr->xpos < insbuf[0].xpos) {
  77.     DBP((D_CAT, "canonflush: BACK (%d chars)\n", insptr - insbuf + 1));
  78. #ifdef    SORT
  79.     xsortorder = -1;
  80.     insdump(insbuf, insptr);
  81.     qsort(insbuf, insptr - insbuf + 1, sizeof(struct insbuf), xsort);
  82.     insdump(insbuf, insptr);
  83. #endif
  84.     for(ip = insptr;ip >= insbuf; ip--)
  85.         canonchar(ip->xpos, insypos, ip->font, ip->points, ip->nc);
  86.     } else {
  87.     DBP((D_CAT, "canonflush: FORW (%d chars)\n", insptr - insbuf + 1));
  88. #ifdef    SORT
  89.     xsortorder = 1;
  90. insdump(insbuf, insptr);
  91.     qsort(insbuf, insptr - insbuf + 1, sizeof(struct insbuf), xsort);
  92. insdump(insbuf, insptr);
  93. #endif
  94.     for(ip = insbuf;ip <= insptr; ip++)
  95.         canonchar(ip->xpos, insypos, ip->font, ip->points, ip->nc);
  96.     }
  97.     insptr = insbuf;
  98.     optflush();
  99. }
  100.  
  101. canonchar(xpos, ypos, font, points, nc)
  102. register int xpos, ypos;
  103. register int font, points, nc; {
  104.     static struct insbuf lastchar;
  105.     static short lastypos;
  106.     static sstate = 0;
  107.     static char sbuf[512];
  108.     register char *p;
  109. #ifdef    INSPECIAL
  110.     /* Inline special directives, not supported yet */
  111.     switch(sstate) {
  112.     case 0:
  113.         if (font == symidx && nc == 34) {
  114.         sstate = 1;
  115.         lastchar.xpos = specXPos = xpos;
  116.         lastchar.font = font;
  117.         lastchar.points = points;
  118.         lastchar.nc = nc;
  119.         lastypos = specYPos = ypos;
  120.         optflush();
  121.         return;
  122.         }
  123.         break;
  124.     case 1:
  125.         if (font == symidx && nc == 34) {
  126.         if (xpos == lastchar.xpos && ypos == lastypos) {
  127.             sstate++;
  128.             sbuf[0] = '\0';
  129.             return;
  130.         } else {
  131.             lastchar.xpos = xpos;
  132.             lastypos = ypos;
  133.             /* stay in this state */
  134.         }
  135.         } else
  136.         sstate = 0;
  137.  
  138.         if (be->beputchar)
  139.         (*be->beputchar)(lastchar.xpos, lastypos, lastchar.font,
  140.             lastchar.points, lastchar.nc, (char *) NULL);
  141.         break;
  142.     case 2:
  143.         if (nc == 34 && font == symidx) {
  144.         DBP((D_CAT, "Special inline sequence: %s\n", sbuf));
  145.         dospecial(sbuf);
  146.         sstate = 0;
  147.         return;
  148.         }
  149.         if (strlen(sbuf) > sizeof(sbuf) - 1) {
  150.         fprintf(stderr,
  151.             "%s: unterminated/too long \\(bs\\(bstr\\(bs\n",
  152.             progname);
  153.         sstate = 0;
  154.         return;
  155.         }
  156.         if (font == symidx)
  157.         p = tabS[nc].ch_name;
  158.         else
  159.         p = tabN[nc].ch_name;
  160.         if (strlen(p) >= 2) {
  161.         if (strcmp(p, "hy") == 0 ||
  162.             strcmp(p, "mi") == 0 ||
  163.             strcmp(p, "\\-") == 0)
  164.             p = "-";
  165.         else if (strcmp(p, "ff") == 0 ||
  166.              strcmp(p, "fi") == 0 ||
  167.              strcmp(p, "fl") == 0)
  168.             ;
  169.         else if (strcmp(p, "Fi") == 0)
  170.             p = "ffi";
  171.         else if (strcmp(p, "Fl") == 0)
  172.             p = "ffl";
  173.         else
  174.             p = " ";
  175.         }
  176.         strcat(sbuf, p);
  177.         return;
  178.     }
  179. #endif
  180.     optinsert(xpos, ypos, font, points, nc);
  181. }
  182.  
  183. int optxpos, optypos;
  184. int optfont, optpoints, optnc, origxpos;
  185. char optbuffer[OPTSIZ];
  186. char *optp = optbuffer;
  187.  
  188. optflush() {
  189.  
  190.     if (!optimize)
  191.     return;
  192.  
  193.     if (optbuffer[0] && be->beputchar)
  194.     (*be->beputchar)(origxpos, optypos, optfont, optpoints, optnc,
  195.         optbuffer);
  196.     optbuffer[0] = '\0';
  197.     optp = optbuffer;
  198. }
  199.  
  200. optinsert(xpos, ypos, font, points, nc)
  201. int font, points, nc;
  202. int xpos, ypos; {
  203.     struct troff2befont *bp;
  204.     static char *wp;
  205.     extern struct cattab tabN[], tabS[];
  206.     struct cattab *ct;
  207.     register char *from;
  208.     int cantcache;
  209.  
  210.     if (!optimize) {
  211.     if (be->beputchar)
  212.         (*be->beputchar)(xpos, ypos, font, points, nc, (char *) NULL);
  213.     return;
  214.     }
  215.  
  216.     DBP((D_CHAR, "OLD: x,y,f,p,c = %d,%d,%d,%d,%d\n",
  217.     optxpos, optypos, optfont, optpoints, optnc));
  218.     DBP((D_CHAR, "NEW: x,y,f,p,c = %d,%d,%d,%d,%d\n",
  219.     xpos, ypos, font, points, nc));
  220.  
  221.     /* the 10 is to ensure that there's enough room for moderately
  222.        long multiple-character sequences */
  223.  
  224.     if (ypos != optypos || optfont != font || optpoints != points ||
  225.     wp != xlatetable[font]->widthtable ||
  226.     optp > optbuffer + OPTSIZ - 10)
  227.     optflush();
  228.  
  229.     wp = xlatetable[font]->widthtable;
  230.  
  231.     if (font == symidx) {
  232.     bp = &be->besymfont[nc];
  233.     ct = &tabS[nc];
  234.     } else {
  235.     bp = &be->bestdfont[nc];
  236.     ct = &tabN[nc];
  237.     }
  238.  
  239.     cantcache = !wp || (int) wp == 1 || (font == symidx ? bp->t2b_font != S:
  240.                  bp->t2b_font != N);
  241.  
  242.     if (bp->t2b_xc || bp->t2b_yc || bp->t2b_scale || cantcache)
  243.     optflush();
  244.  
  245.     if (optxpos != xpos)    /* handle spaces one day... */
  246.     optflush();
  247.  
  248.     if (!optbuffer[0]) {
  249.     optypos = ypos;
  250.     optxpos = xpos;
  251.     origxpos = xpos;
  252.     optfont = font;
  253.     optnc = nc;
  254.     optpoints = points;
  255.     }
  256.  
  257.     if (cantcache) {
  258.     if (be->beputchar)
  259.         (*be->beputchar)(xpos, ypos, font, points, nc, (char *) NULL);
  260.     return;
  261.     }
  262.  
  263.     optxpos += ((wp[ct->ch_wididx]) * points + 3) / 6;
  264.     DBP((D_CAT, "optxpos: %d\n", optxpos));
  265.  
  266.     for (from = bp->t2b_charseq; *from;)
  267.     *optp++ = *from++;
  268.     *optp = '\0';
  269. }
  270. #endif
  271.  
  272. #ifdef    SORT
  273. insdump(b, p)
  274. register struct insbuf *b, *p; {
  275.     if (!(debug&D_VERB))
  276.     return;
  277.     DBP((D_VERB, "insdump:\n"));
  278.     for(; b <= p; b++)
  279.     DBP((D_VERB, "%d %d\n", b->xpos, b->nc));
  280. }
  281. #endif
  282.