home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / libtex / font_subr.c < prev    next >
C/C++ Source or Header  |  1990-07-10  |  5KB  |  252 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/font_subr.c,v 2.8 89/10/30 04:08:52 chris Exp $";
  10. #endif
  11.  
  12. /*
  13.  * Subroutines common to all fonts.
  14.  */
  15.  
  16. #include "types.h"
  17. #include "error.h"
  18. #include "font.h"
  19.  
  20. static struct glyph *freeglyphs;
  21.  
  22. char    *malloc();
  23. extern    errno;
  24.  
  25. /*
  26.  * Set up the font structures to note that a font has glyphs in
  27.  * the half-open interval [low, high).
  28.  *
  29.  * SHOULD I ALLOW ADDITIONS TO THE RANGE VIA SUBSEQUENT CALLS TO
  30.  * FontHasGlyphs?
  31.  */
  32. FontHasGlyphs(f, low, high)
  33.     register struct font *f;
  34.     register int low, high;
  35. {
  36.     register struct glyph **gp;
  37.  
  38.     /* record bounds */
  39.     f->f_lowch = low;
  40.     f->f_highch = high;
  41.  
  42.     /*
  43.      * Allocate space for all the glyph pointers, and set
  44.      * them all to NULL.
  45.      */
  46.     if (low >= high)    /* no glyphs */
  47.         gp = NULL;
  48.     else {
  49.         gp = (struct glyph **) malloc((unsigned) (high - low) *
  50.             sizeof (*gp));
  51.         if (gp == NULL)
  52.             return (-1);
  53.     }
  54.     f->f_glybase = gp;
  55.     f->f_gly = gp - low;
  56.     while (++low <= high)
  57.         *gp++ = NULL;
  58.     return (0);
  59. }
  60.  
  61. /*
  62.  * AllocGlyph allocates a new glyph.  ReleaseGlyph puts one onto the free
  63.  * list.  We maintain a local list of free glyphs.
  64.  */
  65. #define ReleaseGlyph(g)    \
  66.     ((g)->g_un.g_next = freeglyphs, freeglyphs = (g))
  67.  
  68. static struct glyph *
  69. AllocGlyph(n)
  70.     int n;
  71. {
  72.     register struct glyph *g;
  73.     register int i;
  74.  
  75.     if ((g = freeglyphs) == NULL) {
  76.         g = (struct glyph *) malloc((unsigned) (128 * sizeof (*g)));
  77.         if (g == NULL)
  78.             error(1, errno, "out of glyph memory");
  79.         g += (i = 128);
  80.         while (--i >= 0) {
  81.             g--;
  82.             ReleaseGlyph(g);
  83.         }
  84.     }
  85.     freeglyphs = g->g_un.g_next;
  86.     g->g_flags = 0;
  87.     g->g_raster = NULL;
  88.     g->g_index = n;
  89.     g->g_xescapement = NO_ESCAPEMENT;/* default, if not set by font */
  90.     g->g_yescapement = NO_ESCAPEMENT;
  91.     return (g);
  92. }
  93.  
  94. /*
  95.  * Free one glyph.
  96.  */
  97. void
  98. FreeGlyph(f, g)
  99.     struct font *f;
  100.     register struct glyph *g;
  101. {
  102.     int n = g->g_index;
  103.  
  104. #ifdef notdef
  105.     (*f->f_ops->fo_freegly)(f, n, n);
  106. #endif
  107.     if (g->g_raster != NULL)
  108.         free(g->g_raster);
  109.     ReleaseGlyph(g);
  110.     f->f_gly[n] = NULL;
  111. }
  112.  
  113. /*
  114.  * Free a font.
  115.  */
  116. void
  117. FreeFont(f)
  118.     register struct font *f;
  119. {
  120.     register struct glyph *g;
  121.     register int i;
  122.  
  123. #ifdef notdef
  124.     (*f->f_ops->fo_freegly)(f, f->f_lowch, f->f_highch);
  125. #endif
  126.     for (i = f->f_lowch; i < f->f_highch; i++) {
  127.         if ((g = f->f_gly[i]) == NULL)
  128.             continue;
  129.         if (g->g_raster != NULL)
  130.             free(g->g_raster);
  131.         ReleaseGlyph(g);
  132.     }
  133.     if (f->f_glybase != NULL)
  134.         free((char *)f->f_glybase);
  135.     (*f->f_ops->fo_freefont)(f);
  136.     free(f->f_path);
  137.     free(f->f_font);
  138.     free((char *)f);
  139. }
  140.  
  141. /*
  142.  * Get glyph `c' in font `f'.  We pull in a few adjacent glyphs here
  143.  * under the (perhaps naive) assumption that things will go faster
  144.  * that way.
  145.  *
  146.  * TODO:
  147.  *    try different adjacency values
  148.  *    make adjacency a font attribute? (or an op)
  149.  */
  150. #define    ADJ    4        /* must be a power of 2 */
  151. #define    GET_ADJ(c, l, h) ((h) = ADJ + ((l) = (c) & ~(ADJ - 1)))
  152.  
  153. struct glyph *
  154. GetGlyph(f, c)
  155.     register struct font *f;
  156.     int c;
  157. {
  158.     register int i, h, l;
  159.  
  160.     GET_ADJ(c, l, h);
  161.     if (l < f->f_lowch)
  162.         l = f->f_lowch;
  163.     if (h > f->f_highch)
  164.         h = f->f_highch;
  165.     if (l >= h)
  166.         return (NULL);
  167.     for (i = l; i < h; i++)
  168.         if (f->f_gly[i] == NULL)
  169.             f->f_gly[i] = AllocGlyph(i);
  170.  
  171.     if ((*f->f_ops->fo_getgly)(f, l, h)) {
  172.         /*
  173.          * I do not know what to do about this just yet, so:
  174.          */
  175.         panic("getgly fails and I am confused ... help!");
  176.     }
  177.  
  178.     /*
  179.      * Apply the appropriate scale factor to the TFM widths.
  180.      * This makes them come out in scaled points, instead of FIXes.
  181.      */
  182.     ScaleGlyphs(f, l, h);    /* ??? */
  183.  
  184.     return (f->f_gly[c]);
  185. }
  186.  
  187. /*
  188.  * Get the raster for glyph g in font f at rotation r.
  189.  */
  190. char *
  191. GetRaster(g, f, r)
  192.     register struct glyph *g;
  193.     register struct font *f;
  194.     int r;
  195. {
  196.     int l, h;
  197.  
  198.     /* abort if caller did not ask for rasters in advance */
  199.     if ((f->f_flags & FF_RASTERS) == 0)
  200.         panic("GetRaster(%s)", f->f_path);
  201.  
  202.     /*
  203.      * If there is no raster, get one.  Blank characters,
  204.      * however, never have rasters.
  205.      */
  206.     if (g->g_raster == NULL) {
  207.         if (!HASRASTER(g))
  208.             return (NULL);
  209.         /*
  210.          * THE FOLLOWING DEPENDS ON THE ADJACENCY MATCHING THAT IN
  211.          * GetGlyph() ABOVE.
  212.          */
  213.         GET_ADJ(g->g_index, l, h);
  214.         if (l < f->f_lowch)
  215.             l = f->f_lowch;
  216.         if (h > f->f_highch)
  217.             h = f->f_highch;
  218.         if ((*f->f_ops->fo_rasterise)(f, l, h))
  219.             error(1, 0, "rasterise fails (out of memory?)");
  220.     }
  221.     if (g->g_rotation != r)
  222.         SetRotation(g, r);
  223.     return (g->g_raster);
  224. }
  225.  
  226. void
  227. FreeRaster(g)
  228.     struct glyph *g;
  229. {
  230.  
  231.     if (g->g_raster) {
  232.         free((g)->g_raster);
  233.         g->g_raster = NULL;
  234.     }
  235. }
  236.  
  237. /*
  238.  * Return a TeX-style font name, including scale factor.
  239.  * SHOULD I BOTHER WITH \magstep STYLE NAMES?
  240.  */
  241. char *
  242. Font_TeXName(f)
  243.     register struct font *f;
  244. {
  245.     static char result[200];
  246.  
  247.     if (f->f_scaled == 1000)
  248.         return (f->f_font);
  249.     (void) sprintf(result, "%s scaled %d", f->f_font, f->f_scaled);
  250.     return (result);
  251. }
  252.