home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2095 / opt.c
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.2 KB  |  285 lines

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