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 / pkfont.c < prev    next >
C/C++ Source or Header  |  1990-07-10  |  17KB  |  730 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/pkfont.c,v 2.10 89/08/22 21:54:49 chris Exp $";
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include "types.h"
  16. #include "error.h"
  17. #include "font.h"
  18. #include "num.h"
  19.  
  20. /*
  21.  * PK font operations.
  22.  *
  23.  * The spelling `nybble' is a concession to the authors of the PK format.
  24.  */
  25. static int pk_read(), pk_getgly(), pk_rasterise();
  26. static void pk_freefont();
  27.  
  28. struct    fontops pkops =
  29.     { "pk", 0, 1.0, pk_read, pk_getgly, pk_rasterise, pk_freefont };
  30.  
  31. /*
  32.  * Local info.
  33.  */
  34.  
  35. /*
  36.  * Commands.
  37.  */
  38. #define    PK_XXX1        240    /* 1 byte special */
  39. #define    PK_XXX2        241    /* 2 byte special */
  40. #define    PK_XXX3        242    /* 3 byte special */
  41. #define    PK_XXX4        243    /* 4 byte special */
  42. #define    PK_YYY        244    /* METAFONT numspecial */
  43. #define    PK_POST        245    /* marks postamble */
  44. #define    PK_NO_OP    246    /* do nothing */
  45. #define    PK_PRE        247    /* marks preamble */
  46.                 /* 248..255 undefined */
  47. #define PK_IsUndef(c)    ((c) > PK_PRE)
  48.  
  49. #define    PK_ID        89    /* marks this brand of PK file */
  50.  
  51. /*
  52.  * Information about a character packet.
  53.  */
  54. struct cp {
  55.     char    *cp_packet;    /* the beginning of the packet */
  56.     int    cp_type;    /* decoded pre type, see below */
  57. };
  58.  
  59. #define    CP_SHORT    0    /* short preamble */
  60. #define    CP_EXT_SHORT    1    /* extended short preamble */
  61. #define    CP_LONG        2    /* long preamble */
  62.  
  63. /*
  64.  * The PK details include:
  65.  *  ->    a pointer to the next byte to fetch;
  66.  *  ->    the most recent byte fetched (when we are using nextnyb());
  67.  *  ->    a flag indicating that we have used nybble 0 (bits 4..7) and
  68.  *    should use nybble 1 next;
  69.  *  ->    the base address of the memory allocated for the PK file;
  70.  *  ->    the value of dyn_f (during character translation);
  71.  *  ->    the repeat count (during rasterisation);
  72.  *  ->    the lowest glyph number that is legal;
  73.  *  ->    the highest glyph number that is legal;
  74.  *  ->    glyph instructions for the standard glyphs;
  75.  *  ->    glyph instructions for more (nonstandard) glyphs;
  76.  * and    the number of glyphs left unrasterised.
  77.  */
  78. struct pk_details {
  79.     char    *pk_ptr;    /* next byte to fetch */
  80.     int    pk_c;        /* most recent byte fetched, if nybbling */
  81.     int    pk_1nyb;    /* true => nybble 1 is next (bits 0..3) */
  82.     char    *pk_base;    /* base of allocated memory */
  83.     int    pk_dyn_f;    /* the dyn_f value */
  84.     int    pk_repeat;    /* the repeat count */
  85.     int    pk_minc;    /* minimum character value */
  86.     int    pk_maxc;    /* maximum character value */
  87. #define MAXSTD    256        /* maximum `standard' character value */
  88.     int    pk_gleft;    /* number of valid glyphs left uninterpreted */
  89.     struct    cp pk_cpack[MAXSTD];    /* for characters in [0..MAXSTD) */
  90.     struct    cp *pk_morec;        /* for characters in [MAXSTD..maxc] */
  91. };
  92.  
  93. /*
  94.  * Fetch the next byte from the PK file.
  95.  */
  96. #define    nextbyte(pk) pgetbyte((pk)->pk_ptr)
  97.  
  98. /*
  99.  * PK packed number encoding.  Nybbles in [1..dyn_f] represent themselves.
  100.  * Values in (dyn_f..13] are two-nybble values, and represent values
  101.  * dyn_f+1 through (13-dyn_f+1)*16+15.  Zero marks a long number; 14 and
  102.  * 15 specify repeat counts instead (which are another packed number).
  103.  * Note that we cannot represent the number zero as a packed number.
  104.  */
  105. #define    PK_LONGNUM    0    /* a `long number' */
  106. #define    PK_REPEAT    14    /* set repeat count */
  107. #define    PK_REPEAT1    15    /* set repeat to 1 */
  108.  
  109. /*
  110.  * Get the next nybble.  This is an expression rendition of
  111.  *    if (--pk->pk_1nyb < 0) {
  112.  *        pk->pk_1nyb = 1;
  113.  *        pk->pk_c = nextbyte(pk);
  114.  *        return (pk->pk_c >> 4);
  115.  *    } else
  116.  *        return (pk->pk_c & 0xf);
  117.  */
  118. #define    nextnyb(pk) \
  119.     (--(pk)->pk_1nyb < 0 ? \
  120.      ((pk)->pk_1nyb = 1, ((pk)->pk_c = nextbyte(pk)) >> 4) : \
  121.      (pk)->pk_c & 0xf)
  122.  
  123. /*
  124.  * Get the pk_details from font f.
  125.  */
  126. #define    ftopk(f) ((struct pk_details *)(f)->f_details)
  127.  
  128. static int scan_characters();
  129.  
  130. extern    int errno;
  131. char    *malloc();
  132.  
  133. /*
  134.  * PK subroutines.
  135.  */
  136.  
  137. /*
  138.  * Unpack a packed number.
  139.  */
  140. static int
  141. pk_unpack(pk)
  142.     register struct pk_details *pk;
  143. {
  144.     register int i, j;
  145.  
  146. top:
  147.     if ((i = nextnyb(pk)) == PK_LONGNUM) {
  148. #if PK_LONGNUM != 0        /* this may be silly, but . . . */
  149.         i = 0;
  150. #endif
  151.         /*
  152.          * Expand a long number.  There are one fewer leading
  153.          * zeros than there are nonzero digits to obtain, so
  154.          * count up the leading zeros, add one, and get that
  155.          * many digits.  (The `digits' are hexadecimal values.)
  156.          */
  157.         do {
  158.             i++;
  159.         } while ((j = nextnyb(pk)) == 0);
  160.         while (--i >= 0) {
  161.             j <<= 4;
  162.             j += nextnyb(pk);
  163.         }
  164.         return (j - 15 + (13 - pk->pk_dyn_f) * 16 + pk->pk_dyn_f);
  165.     }
  166.     if (i <= pk->pk_dyn_f)
  167.         return (i);
  168.     if (i < PK_REPEAT)
  169.         return ((i - pk->pk_dyn_f - 1) * 16 + nextnyb(pk) +
  170.             pk->pk_dyn_f + 1);
  171.  
  172.     /*
  173.      * There is a repeat count, either one or a packed number.
  174.      * Get it first, then start over.  (tail recursion)
  175.      */
  176.     if (i == PK_REPEAT)
  177.         pk->pk_repeat = pk_unpack(pk);
  178.     else
  179.         pk->pk_repeat = 1;
  180.     goto top;
  181. }
  182.  
  183. /*
  184.  * Skip over special commands (PK_XXX?, PK_YYY).
  185.  */
  186. static void
  187. skip_specials(f)
  188.     struct font *f;
  189. {
  190.     struct pk_details *pk = ftopk(f);
  191.     register char *p = pk->pk_ptr;
  192.     register i32 i;
  193.  
  194.     for (;;) {
  195.         switch (UnSign8(*p++)) {
  196.  
  197.         case PK_XXX1:
  198.             i = UnSign8(*p++);
  199.             p += i;
  200.             break;
  201.  
  202.         case PK_XXX2:
  203.             pGetWord(p, i);
  204.             p += i;
  205.             break;
  206.  
  207.         case PK_XXX3:
  208.             pGet3Byte(p, i);
  209.             p += i;
  210.             break;
  211.  
  212.         case PK_XXX4:
  213.             pGetLong(p, i);
  214.             p += i;
  215.             break;
  216.  
  217.         case PK_YYY:
  218.             p += 4;
  219.             break;
  220.  
  221.         case PK_NO_OP:
  222.             break;
  223.  
  224.         case PK_PRE:
  225.             error(1, 0, "unexpected PK_PRE in \"%s\"", f->f_path);
  226.             break;
  227.  
  228.         default:
  229.             p--;
  230.             if (PK_IsUndef(UnSign8(*p)))
  231.                 error(1, 0, "invalid opcode %d in \"%s\"",
  232.                     f->f_path);
  233.             pk->pk_ptr = p;
  234.             return;
  235.         }
  236.     }
  237. }
  238.  
  239. /*
  240.  * Read a PK file.
  241.  */
  242. static int
  243. pk_read(f, fd)
  244.     register struct font *f;
  245.     int fd;
  246. {
  247.     register struct pk_details *pk;
  248.     register char *p;
  249.     int i, minc;
  250.     struct stat st;
  251.     char *reason;
  252.  
  253.     pk = NULL;        /* prepare for failure */
  254.     reason = NULL;
  255.     (void) fstat(fd, &st);
  256.     if (st.st_size < 4) {    /* ??? */
  257.         reason = "file is too small";
  258.         goto fail;
  259.     }
  260.     if ((pk = (struct pk_details *)malloc(sizeof (*pk))) == NULL)
  261.         goto fail;
  262.     pk->pk_morec = NULL;
  263.     if ((pk->pk_base = malloc(st.st_size)) == NULL)
  264.         goto fail;
  265.     if (read(fd, pk->pk_base, st.st_size) != st.st_size)
  266.         goto fail;
  267.     pk->pk_ptr = pk->pk_base;
  268.     if (nextbyte(pk) != PK_PRE) {
  269.         reason = "file does not begin with PK_PRE";
  270.         goto fail;
  271.     }
  272.     if (nextbyte(pk) != PK_ID) {
  273.         reason = "bad PK_ID";
  274.         goto fail;
  275.     }
  276.     i = nextbyte(pk);
  277.     p = pk->pk_ptr + i;    /* skip comment */
  278.     pGetLong(p, f->f_design_size);
  279.     pGetLong(p, f->f_checksum);
  280.     pGetLong(p, f->f_hppp);
  281.     pGetLong(p, f->f_vppp);
  282.     pk->pk_ptr = p;
  283.  
  284.     f->f_details = (char *)pk;
  285.  
  286.     /* scan the characters, fail if necessary */
  287.     if (scan_characters(f, &reason))
  288.         goto fail;
  289.  
  290.     /* ignore the postamble */
  291.  
  292.     /* COMPRESS pk->pk_base DATA? */
  293.  
  294.     if (FontHasGlyphs(f, pk->pk_minc, pk->pk_maxc + 1))
  295.         goto fail;
  296.     (void) close(fd);
  297.     return (0);
  298.  
  299. fail:
  300.     if (reason) {
  301.         error(0, 0, "%s", reason);
  302.         error(0, 0, "(are you sure %s is a PK file?)", f->f_path);
  303.         errno = 0;
  304.     }
  305.     if (pk != NULL) {
  306.         if (pk->pk_base != NULL)
  307.             free(pk->pk_base);
  308.         if (pk->pk_morec != NULL)
  309.             free((char *)pk->pk_morec);
  310.         free((char *)pk);
  311.     }
  312.     (void) close(fd);
  313.     return (-1);
  314. }
  315.  
  316. /*
  317.  * Scan through the characters in the PK file, and set the offsets
  318.  * and preamble types for each of the character packets.
  319.  */
  320. static int
  321. scan_characters(f, reason)
  322.     struct font *f;
  323.     char **reason;
  324. {
  325.     register struct pk_details *pk = ftopk(f);
  326.     register i32 c, pl;
  327.     register char *p;
  328.     register struct cp *cp;
  329.     int type;
  330.  
  331. #ifdef lint
  332.     /* reason will be used someday ... I think */
  333.     reason = reason;
  334. #endif
  335.  
  336.     /* set up the minimisers and the glyph count */
  337.     pk->pk_minc = 1;
  338.     pk->pk_maxc = 0;
  339.     pk->pk_gleft = 0;
  340.  
  341.     /* mark all character packets as untouched */
  342.     for (cp = pk->pk_cpack, c = MAXSTD; --c >= 0; cp++)
  343.         cp->cp_packet = NULL;
  344.  
  345.     /*
  346.      * Loop through the packets until we reach a POST, skipping
  347.      * the glyph instructions themselves after each definition,
  348.      * and specials (if any) before each.
  349.      */
  350.     for (;; pk->pk_ptr = p + pl) {
  351.         skip_specials(f);
  352.         p = pk->pk_ptr;
  353.         if ((c = pgetbyte(p)) == PK_POST)
  354.             break;    /* whoops, done after all */
  355.  
  356.         /*
  357.          * Look at the low three bits to decide preamble size.
  358.          * A value of 7 is a `long preamble'; 4, 5, and 6 are
  359.          * `extended short preambles'; and 0, 1, 2, and 3 are
  360.          * `short preambles'.
  361.          *
  362.          * We ignore most of the preamble, reading only the
  363.          * `packet length' and the character code at this time.
  364.          */
  365.         switch (c & 7) {
  366.  
  367.         case 7:        /* long */
  368.             type = CP_LONG;
  369.             pGetLong(p, pl);
  370.             pGetLong(p, c);
  371.             break;
  372.  
  373.         case 6:
  374.         case 5:
  375.         case 4:        /* extended short */
  376.             type = CP_EXT_SHORT;
  377.             pGetWord(p, pl);
  378.             pl += (c & 3) << 16;
  379.             c = pgetbyte(p);
  380.             break;
  381.  
  382.         default:    /* short */
  383.             type = CP_SHORT;
  384.             pl = ((c & 3) << 8) + pgetbyte(p);
  385.             c = pgetbyte(p);
  386.             break;
  387.         }
  388.  
  389.         if (c >= MAXSTD) {
  390.             /*
  391.              * BEGIN XXX - should alloc pk_morec, but is hard
  392.              * and not now useful
  393.              */
  394.             error(0, 0, "ignoring character %d in \"%s\"",
  395.                 f->f_path);
  396.             error(0, 0, "because some darn programmer was lazy!");
  397.             continue;
  398.             /* END XXX */
  399.         } else
  400.             cp = &pk->pk_cpack[c];
  401.  
  402.         cp->cp_packet = pk->pk_ptr;
  403.         cp->cp_type = type;
  404.  
  405.         /* adjust range */
  406.         if (c < pk->pk_minc)
  407.             pk->pk_minc = c;
  408.         if (c > pk->pk_maxc)
  409.             pk->pk_maxc = c;
  410.  
  411.         pk->pk_gleft++;    /* and count the glyph */
  412.     }
  413.     return (0);        /* no problems */
  414. }
  415.  
  416. /*
  417.  * Obtain the specified range of glyphs.
  418.  */
  419. static int
  420. pk_getgly(f, l, h)
  421.     register struct font *f;
  422.     int l, h;
  423. {
  424.     register struct pk_details *pk = ftopk(f);
  425.     register char *p;
  426.     register struct glyph *g;
  427.     register int i;
  428.     register struct cp *cp;
  429.  
  430.     if (pk == NULL)
  431.         panic("pk_getgly(%s)", f->f_path);
  432.     for (i = l; i < h; i++) {
  433.         if (i < MAXSTD)
  434.             cp = &pk->pk_cpack[i];
  435.         else {
  436.             if (i > pk->pk_maxc)
  437.                 panic("pk_getgly(%s, %d)", f->f_path, i);
  438.             cp = &pk->pk_morec[i - MAXSTD];
  439.         }
  440.         p = cp->cp_packet;
  441.         if (p == NULL)    /* glyph is not valid */
  442.             continue;
  443.         g = f->f_gly[i];
  444.         p++;        /* skip flag */
  445.         switch (cp->cp_type) {
  446.  
  447.         case CP_LONG:
  448.             p += 8;    /* skip packet len, character code */
  449.             pGetLong(p, g->g_rawtfmwidth);
  450.             pGetLong(p, g->g_xescapement);
  451.             pGetLong(p, g->g_yescapement);
  452.             pGetLong(p, g->g_width);
  453.             pGetLong(p, g->g_height);
  454.             pGetLong(p, g->g_xorigin);
  455.             pGetLong(p, g->g_yorigin);
  456.             break;
  457.  
  458.         case CP_EXT_SHORT: {
  459.             i32 dm;
  460.  
  461.             p += 3;    /* skip packet len, character code */
  462.             pGet3Byte(p, g->g_rawtfmwidth);
  463.             pGetWord(p, dm);
  464.             g->g_xescapement = dm << 16;
  465.             g->g_yescapement = 0;
  466.             pGetWord(p, g->g_width);
  467.             pGetWord(p, g->g_height);
  468.             pGetWord(p, g->g_xorigin);
  469.             g->g_xorigin = Sign16(g->g_xorigin);
  470.             pGetWord(p, g->g_yorigin);
  471.             g->g_yorigin = Sign16(g->g_yorigin);
  472.             break;
  473.         }
  474.  
  475.         case CP_SHORT:
  476.             p += 2;    /* skip packet len, character code */
  477.             pGet3Byte(p, g->g_rawtfmwidth);
  478.             g->g_xescapement = pgetbyte(p) << 16;
  479.             g->g_yescapement = 0;
  480.             g->g_width = pgetbyte(p);
  481.             g->g_height = pgetbyte(p);
  482.             g->g_xorigin = pgetbyte(p);
  483.             g->g_xorigin = Sign8(g->g_xorigin);
  484.             g->g_yorigin = pgetbyte(p);
  485.             g->g_yorigin = Sign8(g->g_yorigin);
  486.             break;
  487.         }
  488.         g->g_flags = GF_VALID;
  489.         g->g_un.g_details = p;
  490.     }
  491.     return (0);
  492. }
  493.  
  494. /*
  495.  * Bit masks for pk_rasterise().
  496.  */
  497. static char bmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
  498. static char rbits[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  499.  
  500. /*
  501.  * Obtain rasters for the specified glyphs.
  502.  */
  503. static int
  504. pk_rasterise(f, l, h)
  505.     struct font *f;
  506.     int l, h;
  507. {
  508.     struct pk_details *pk0;
  509.     struct glyph *g0;
  510.     char *p0, *rp0;
  511.     int flag, ii;
  512.  
  513.     if ((pk0 = ftopk(f)) == NULL)
  514.         panic("pk_rasterise(%s)", f->f_path);
  515.     for (ii = l; ii < h; ii++) {
  516.         {
  517.             register struct glyph *g;
  518.             register char *p;
  519.             register int i;
  520.  
  521.             g = f->f_gly[i = ii];
  522.             if ((g->g_flags & GF_VALID) == 0)
  523.                 continue;    /* no glyph */
  524.             if (!HASRASTER(g))    /* empty raster */
  525.                 goto done;
  526.  
  527.             /*
  528.              * Allocate a raster.
  529.              */
  530.             rp0 = malloc(((g->g_width + 7) >> 3) * g->g_height);
  531.             if ((g->g_raster = rp0) == NULL)
  532.                 return (-1);/* ??? */
  533.             g->g_rotation = ROT_NORM;
  534.  
  535.             /*
  536.              * Pick up the flag byte, then start at the real
  537.              * packet, which we saved in g_details.
  538.              */
  539.             if (i < MAXSTD)
  540.                 p = pk0->pk_cpack[i].cp_packet;
  541.             else
  542.                 p = pk0->pk_morec[i - MAXSTD].cp_packet;
  543.             flag = UnSign8(*p);
  544.             p0 = g->g_un.g_details;
  545.             g0 = g;
  546.         }
  547.         if ((pk0->pk_dyn_f = flag >> 4) == 14) {
  548.             register char *p = p0, *rp = rp0;
  549.             register int j, ls, rs, i, w;
  550.  
  551.             /*
  552.              * Expand a bit-packed representation.
  553.              * If we get lucky, it is byte packed and
  554.              * we can just copy it over.
  555.              */
  556.             i = g0->g_height;
  557.             j = g0->g_width;
  558.             if ((j & 7) == 0) {
  559.                 bcopy(p, rp, i * (j >> 3));
  560.                 goto done;
  561.             }
  562.  
  563.             /*
  564.              * No such luck.
  565.              */
  566.             w = j;
  567.             ls = 0;
  568.             while (--i >= 0) {
  569.                 rs = 8 - ls;
  570.                 /* know j always != 8 */
  571.                 for (j = w; j > 8; j -= 8) {
  572.                     *rp = *p++ << ls;
  573.                     *rp++ |= UnSign8(*p) >> rs;
  574.                 }
  575.  
  576.                 /*
  577.                  * We need j more bits; there are rs
  578.                  * bits available at *p.  Ask for j,
  579.                  * which gets min(j, rs).
  580.                  */
  581.                 *rp++ = (*p << ls) & bmask[j];
  582.                 /* account for j bits */
  583.                 ls += j; ls &= 7;
  584.                 /* then adjust j based on rs */
  585.                 j -= rs;
  586.                 /* still need j more bits */
  587.                 if (j < 0)    /* got them all */
  588.                     continue;
  589.                 p++;
  590.                 if (j == 0)    /* there were just enough */
  591.                     continue;
  592.                 /* take j more bits */
  593.                 rp[-1] |= UnSign8(*p & bmask[j]) >> rs;
  594.             }
  595.         } else {
  596.             register struct pk_details *pk = pk0;
  597.             register int on = flag & 8 ? 0xff : 0;
  598.             register char *rowp;    /* pointer into this row */
  599.             register int j;        /* trimmed run count */
  600.             register int k;        /* misc */
  601.             register int b;        /* bit index in current col */
  602.             register int i;        /* run count */
  603.             register int colsleft;    /* columns left this row */
  604.             register int rowsleft;    /* rows left */
  605.             static char *row;    /* a one-row buffer */
  606.             static int rowsize;    /* and its size in bytes */
  607.             int wb;            /* row width in bytes */
  608.  
  609.             wb = (g0->g_width + 7) >> 3;
  610.             if (rowsize < wb) {    /* get more row space */
  611.                 if (row)
  612.                     free(row);
  613.                 /* keep a slop byte */
  614.                 row = malloc((unsigned) (wb + 1));
  615.                 if (row == NULL)
  616.                     return (-1);    /* ??? */
  617.                 rowsize = wb;
  618.             }
  619.             bzero(row, wb);
  620.             rowsleft = g0->g_height;
  621.             colsleft = g0->g_width;
  622.             pk->pk_repeat = 0;
  623.             pk->pk_ptr = p0;
  624.             pk->pk_1nyb = 0;    /* start on nybble 0 */
  625.             rowp = row;
  626.             b = 0;
  627.             while (rowsleft > 0) {    /* do all rows */
  628.                 /* EXPAND IN LINE? */
  629.                 i = pk_unpack(pk);
  630.                 /*
  631.                  * Work until the run count is exhausted
  632.                  * (or at least pretty tired).
  633.                  *
  634.                  * (Okay, so the joke is stolen!)
  635.                  */
  636.                 while ((j = i) > 0) {
  637.                     /*
  638.                      * If the count is more than the
  639.                      * rest of this row, trim it down.
  640.                      */
  641.                     if (j > colsleft)
  642.                         j = colsleft;
  643.                     i -= j;    /* call them done */
  644.                     /*
  645.                      * We need k=8-b bits to finish
  646.                      * up the current byte.  If we
  647.                      * can finish it, do so; the proper
  648.                      * bits to set are in rbits[k].
  649.                      */
  650.                     if (j >= (k = 8 - b)) {
  651.                         j -= k;
  652.                         colsleft -= k;
  653.                         *rowp++ |= on & rbits[k];
  654.                         b = 0;
  655.                     }
  656.                     /*
  657.                      * Set any full bytes.
  658.                      */
  659.                     while (j >= 8) {
  660.                         *rowp++ = on;
  661.                         j -= 8;
  662.                         colsleft -= 8;
  663.                     }
  664.                     /*
  665.                      * Finally, begin a new byte, or
  666.                      * add to the current byte, with
  667.                      * j more bits.  We know j <= 8-b.
  668.                      * (If j==0, we may be writing on
  669.                      * our slop byte, which is why we
  670.                      * keep one around....)
  671.                      */
  672. if (j > 8-b) panic("pk_rasterise j>8-b");
  673.                     *rowp |= (on & bmask[j]) >> b;
  674.                     colsleft -= j;
  675.                     b += j; b &= 7;
  676.                     if (colsleft == 0) {
  677.                         pk->pk_repeat++;
  678.                         rowsleft -= pk->pk_repeat;
  679.                         while (--pk->pk_repeat >= 0) {
  680.                             bcopy(row, rp0, wb);
  681.                             rp0 += wb;
  682.                         }
  683. if (rowsleft == 0 && i) panic("pk_rasterise leftover bits");
  684.                         pk->pk_repeat = 0;
  685.                         rowp = row;
  686.                         colsleft = g0->g_width;
  687.                         bzero(row, wb);
  688.                         b = 0;
  689.                     }
  690.                 }
  691.                 on = 0xff - on;
  692.             }
  693.         }
  694.  
  695. done:
  696.         /*
  697.          * Successfully converted another glyph.
  698.          */
  699.         pk0->pk_gleft--;
  700.     }
  701.  
  702. if (pk0->pk_gleft < 0)
  703. panic("%s: gleft==%d", f->f_path, pk0->pk_gleft);
  704.     if (pk0->pk_gleft == 0) {
  705.         free(pk0->pk_base);
  706.         if (pk0->pk_morec != NULL)
  707.             free((char *) pk0->pk_morec);
  708.         free((char *) pk0);
  709.         f->f_details = NULL;
  710.     }
  711.     return (0);
  712. }
  713.  
  714. /*
  715.  * Discard the font details.
  716.  */
  717. static void
  718. pk_freefont(f)
  719.     struct font *f;
  720. {
  721.     register struct pk_details *pk = ftopk(f);
  722.  
  723.     if (pk != NULL) {
  724.         free(pk->pk_base);
  725.         if (pk->pk_morec != NULL)
  726.             free((char *) pk->pk_morec);
  727.         free((char *) pk);
  728.     }
  729. }
  730.