home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume24 / psroff3.0 / part03 / pk.c next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  21.1 KB  |  938 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: PK and SFP font reading and emission functions
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. #ifdef    PK
  14.  
  15. #ifndef lint
  16. static char SCCSid[] = "@(#)pk.c 2.3 Copyright 91/02/20 09:02:17 Chris Lewis";
  17. #endif
  18.  
  19. #define    DRAW
  20. #define    OUTRES    300
  21.  
  22. #include "pk.h"
  23.  
  24. #if    defined(PARTIAL)
  25. #include "pkc.h"
  26. struct needmaps *needmaps = (struct needmaps *) NULL;
  27. #endif
  28.  
  29. extern char *progname;
  30.  
  31. static FILE *fin;
  32. static char *filename;    /* name of *current* font being read */
  33. extern char *malloc();
  34.  
  35. static long flag_byte;
  36. static repeatcount;
  37. static dyn_f;
  38.  
  39. static readraster();
  40.  
  41. static long
  42. get1int() { return(getc(fin)); }
  43.  
  44. static long
  45. get2int() {
  46.     register long c;
  47.     c = get1int();
  48.     c = (c<<8) | (0xff & get1int());
  49.     return(c);
  50. }
  51.  
  52. static long
  53. get4int() {
  54.     register long c;
  55.     c = get2int();
  56.     c = (c << 16) | (0xffff & get2int());
  57.     return(c);
  58. }
  59.  
  60. static long
  61. get3int() {
  62.     register long c;
  63.     c = get2int();
  64.     c = (c << 8) | (0xff & get1int());
  65.     return(c);
  66. }
  67.  
  68. #ifdef VFPRINTF
  69. #include <varargs.h>
  70. /* VARARGS */
  71. pkmsg(va_alist)
  72. va_dcl
  73. {
  74.     va_list args;
  75.     char *fmt;
  76.  
  77.     va_start(args);
  78.     fmt = (char *) va_arg(args, char *);
  79.     VFPRINTF(stderr, fmt, args);
  80.     va_end(args);
  81. }
  82. #else
  83. /* VARARGS1 ARGSUSED */
  84. pkmsg(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
  85. char    *fmt;
  86. int    a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
  87.     char buf[BUFSIZ];
  88.     sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  89.     fprintf(stderr, buf);
  90. }
  91. #endif
  92.  
  93. static
  94. skipspecials() {
  95.     register int i,c;
  96.     do {
  97.     flag_byte = getc(fin);
  98.     if (flag_byte >= 240) {
  99.         i = 0;
  100.         switch(flag_byte) {
  101.         case PK_xxx4:
  102.             i = (i << 8) + getc(fin);
  103.         case PK_xxx3:
  104.             i = (i << 8) + getc(fin);
  105.         case PK_xxx2:
  106.             i = (i << 8) + getc(fin);
  107.         case PK_xxx1:
  108.             i = (i << 8) + getc(fin);
  109.             DBP((D_PK, "PK_xxx%d: ", flag_byte - PK_xxx1 + 1));
  110.             while(i--) {
  111.             c = getc(fin);
  112.             DBP((D_PK, "%c", c));
  113.             }
  114.             DBP((D_PK, "\n"));
  115.             break;
  116.         case PK_yyy:
  117.             i = get4int();
  118.             DBP((D_PK, "Num special: %d\n", i));
  119.             break;
  120.         case PK_post:
  121.             DBP((D_PK, "Postamble\n"));
  122.             break;
  123.         case PK_no_op:
  124.             DBP((D_PK, "No-op\n"));
  125.             break;
  126.         default:
  127.             pkmsg("PK file %s: Unexpected %ld\n", filename,
  128.             flag_byte);
  129.             exit(1);
  130.         }
  131.     }
  132.     } while (flag_byte >= 240 && flag_byte != PK_post);
  133. }
  134.  
  135. static
  136. readschar(p)
  137. struct pkc *p; {
  138.     p->pkc_pl = get1int() + ((p->pkc_flag&0x3) << 8);
  139.     p->pkc_char = get1int();
  140.     p->pkc_tfm = get3int();
  141.     p->pkc_dx = get1int() * pow2(16);
  142.     p->pkc_dy = 0;
  143.     p->pkc_width = get1int();
  144.     p->pkc_height = get1int();
  145.     p->pkc_x_off = get1int();
  146.     p->pkc_y_off = get1int();
  147.     if (p->pkc_x_off > 127)
  148.     p->pkc_x_off -= 256;
  149.     if (p->pkc_y_off > 127)
  150.     p->pkc_y_off -= 256;
  151.     p->pkc_rlen = p->pkc_pl - 8;
  152.     readraster(p);
  153. }
  154.  
  155. static
  156. readeschar(p)
  157. struct pkc *p; {
  158.     p->pkc_pl = get2int() + ((p->pkc_flag&0x3) << 16);
  159.     p->pkc_char = get1int();
  160.     p->pkc_tfm = get3int();
  161.     p->pkc_dx = get2int() * pow2(16);
  162.     p->pkc_dy = 0;
  163.     p->pkc_width = get2int();
  164.     p->pkc_height = get2int();
  165.     p->pkc_x_off = get2int();
  166.     p->pkc_y_off = get2int();
  167.     if (p->pkc_x_off > 32767)
  168.     p->pkc_x_off -= 65536;
  169.     if (p->pkc_y_off > 32767)
  170.     p->pkc_y_off -= 65536;
  171.     p->pkc_rlen = p->pkc_pl - 13;
  172.     readraster(p);
  173. }
  174.  
  175. static
  176. readlchar(p)
  177. struct pkc *p; {
  178.     p->pkc_pl = get4int();
  179.     p->pkc_char = get4int();
  180.     p->pkc_tfm = get4int();
  181.     p->pkc_dx = get4int();
  182.     p->pkc_dy = get4int();
  183.     p->pkc_width = get4int();
  184.     p->pkc_height = get4int();
  185.     p->pkc_x_off = get4int();
  186.     p->pkc_y_off = get4int();
  187.     p->pkc_rlen = p->pkc_pl - 28;
  188.     readraster(p);
  189. }
  190.  
  191. static
  192. readraster(p)
  193. struct pkc *p; {
  194.     p->pkc_pkr = (int8 *) mustmalloc((int) p->pkc_rlen, filename);
  195.     fread((char *) p->pkc_pkr, 1, (int) p->pkc_rlen, fin);
  196. }
  197.  
  198. /*    Read a character sequence from a PK file */
  199. static struct pkc *
  200. rpkc() {
  201.     register struct pkc *p = (struct pkc *) mustmalloc(sizeof(struct pkc),
  202.     filename);
  203.  
  204.     p->pkc_pkr = NULL;
  205.     p->pkc_sfpr = NULL;
  206.     p->pkc_flag = flag_byte;
  207.     p->pkc_dyn_f = p->pkc_flag >> 4;
  208.     flag_byte &= 0x7;
  209.  
  210.     if (flag_byte == 7)
  211.     readlchar(p);
  212.     else if (flag_byte > 3)
  213.     readeschar(p);
  214.     else
  215.     readschar(p);
  216.     return(p);
  217. }
  218.  
  219. #ifdef    SFP
  220. /*    Read a character sequence from an SFP */
  221. static struct pkc *
  222. rsfpc() {
  223.     register struct pkc *p;
  224.     int len;
  225.  
  226.     if ((len = getc(fin)) == EOF || len != '\033') {
  227.     /* HP fonts when loaded often have trailing nulls due to DOS
  228.        file padding.  Screech on non-null */
  229.     if (len && len != EOF)
  230.         fprintf(stderr,
  231.         "%s: WARNING: trailing garbage in %s, offset %ld, char 0x%02x\n",
  232.         progname, filename, ftell(fin), len);
  233.     flag_byte = PK_post;
  234.     return((struct pkc *) NULL);
  235.     }
  236.  
  237.     p = (struct pkc *) mustmalloc(sizeof(struct pkc), filename);
  238.     p->pkc_pkr = NULL;
  239.     p->pkc_sfpr = NULL;
  240.     p->pkc_flag = 0;
  241.     p->pkc_dyn_f = 0;
  242.  
  243.     if (fscanf(fin, "*c%ldE", &(p->pkc_char)) != 1) {
  244.     pkmsg("SFP file: %s, bad/missing SET CHAR CODE, offset: %ld\n",
  245.         filename, ftell(fin));
  246.     exit(1);
  247.     }
  248.  
  249.     if (fscanf(fin, "\033(s%dW", &len) != 1 || len < 16) {
  250.     pkmsg("SFP file: %s, bad/missing/tooshort CHAR DOWNLOAD sequence\n",
  251.         filename);
  252.     exit(1);
  253.     }
  254.  
  255.     get4int();    /* skip some garbage */
  256.     get2int();    /* skip more garbage (actually, orientation & dummy */
  257.  
  258.     p->pkc_x_off = get2int();
  259.     if (p->pkc_x_off > 32767)
  260.     p->pkc_x_off -= 65536;
  261.     p->pkc_x_off = -p->pkc_x_off;
  262.     p->pkc_y_off = get2int();
  263.     if (p->pkc_y_off > 32767)
  264.     p->pkc_y_off -= 65536;
  265.     p->pkc_width = get2int();
  266.     p->pkc_height = get2int();
  267.     p->pkc_dx = get2int() * pow2(16) / 4;
  268.  
  269.     p->pkc_sfpr = (struct ras *) mustmalloc(sizeof(struct ras), filename);
  270.  
  271.     p->pkc_sfpr->ras_height = p->pkc_height;
  272.     p->pkc_sfpr->ras_width = p->pkc_width;
  273.     p->pkc_sfpr->ras_bline = (p->pkc_width + 7) / 8;
  274.     p->pkc_sfpr->ras_bytes = p->pkc_sfpr->ras_height * p->pkc_sfpr->ras_bline;
  275.     if (p->pkc_sfpr->ras_bytes) {
  276.     p->pkc_sfpr->ras_raster = (int8 *) mustmalloc((int)
  277.         p->pkc_sfpr->ras_bytes, filename);
  278.  
  279.     fread((char *) p->pkc_sfpr->ras_raster, (int) p->pkc_sfpr->ras_bytes,
  280.         1, fin);
  281.     } else {
  282.     free((char *) p->pkc_sfpr);
  283.     p->pkc_sfpr = NULL;
  284.     }
  285.  
  286.     return(p);
  287. }
  288. #endif
  289.  
  290. static struct pkc *
  291. readchar(p)
  292. struct pkp *p; {
  293.     if (p->pkp_flags&PK_PK)
  294.     return(rpkc());
  295. #ifdef    SFP
  296.     else if (p->pkp_flags&PK_SFP)
  297.     return(rsfpc());
  298. #endif
  299.     else
  300.     return((struct pkc *) NULL);
  301. }
  302.  
  303. static int
  304. pkccomp(a, b)
  305. struct pkc **a, **b; {
  306.     if ((*a)->pkc_char < (*b)->pkc_char)
  307.     return(-1);
  308.     else
  309.     return(1);
  310.     /* can't be equal! */
  311. }
  312.  
  313. static
  314. rastbit(x,y,r)
  315. register int x, y;
  316. register struct ras *r; {
  317.     register int bi = y * r->ras_bline + (x >> 3);
  318.  
  319.     /* You don't really want to uncomment this.... ;-) */
  320.     /*    printf("x,y,bi: %d,%d,%d\n", x, y, bi);*/
  321.     return(r->ras_raster[bi] & (0x80 >> (x&7)));
  322. }
  323.  
  324. static int8 *rptr;
  325. static long bitweight;
  326.  
  327. getnyb() {
  328.     register int8 b;
  329.     if (!bitweight) {
  330.     bitweight = 8;
  331.     rptr++;
  332.     }
  333.     b = *rptr;
  334.     bitweight -= 4;
  335. #ifdef    VDEBUG
  336.     DBP((D_PK, "getnyb byte: %x\n", b));
  337.     DBP((D_PK, "getnyb: %x\n", (b >> bitweight) & 0xf));
  338. #endif
  339.     return((b >> bitweight)&0xf);
  340. }
  341.  
  342. #ifdef    NEVER
  343. getbit() {
  344.     register int8 b;
  345.     if (!bitweight) {
  346.     bitweight = 8;
  347.     rptr++;
  348.     }
  349.     b = *rptr;
  350.     bitweight--;
  351.     return((b>>bitweight)&1);
  352. }
  353. #endif
  354.  
  355. /*    Dumps an ASCII version of the SFP raster r, to line n.
  356.     Normally only for debugging, but is also used from pktype
  357.  */
  358.  
  359. dumpr(r, n)
  360. struct ras *r;
  361. int n; {
  362.     int x, y;
  363.     if (!diagFile)
  364.     return;
  365.     fprintf(diagFile, "\n");
  366.     for (y = 0; y < n; y++) {
  367.     fprintf(diagFile, "%3d  ", y);
  368.     for (x = 0; x < r->ras_width; x++) {
  369.         if (rastbit(x, y, r))
  370.         putc('*', diagFile);
  371.         else
  372.         putc(' ', diagFile);
  373.     }
  374.     putc('\n', diagFile);
  375.     }
  376. }
  377.  
  378. static long
  379. pkpack(pc,r)
  380. register struct pkc *pc;
  381. register struct ras *r; {
  382.     long i, j;
  383.     long pkpackret;
  384.     i = getnyb();
  385.     if (i == 0) {
  386.     do {
  387.         j = getnyb();
  388.         i++;
  389.     } while(!j);
  390.     while(i--)
  391.         j = (j << 4) + getnyb();
  392.     pkpackret = (j - 15 + (13 - dyn_f) * 16 + dyn_f);
  393.     } else if (i <= dyn_f)
  394.     pkpackret = (i);
  395.     else if (i < 14)
  396.     pkpackret = ((i - dyn_f - 1)*16 + getnyb() + dyn_f + 1);
  397.     else {
  398.     if (repeatcount) {
  399.         pkmsg("Second repeat count for this row!\n");
  400.         exit(1);
  401.     }
  402.     if (i == 14)
  403.         repeatcount = pkpack(pc,r);
  404.     else
  405.         repeatcount = 1;
  406.     /*sendout(1, repeatcount, pc, r);*/
  407.     pkpackret = (pkpack(pc,r));
  408.     }
  409.     if (pkpackret < 1) {
  410.     pkmsg("pkpack returned < 1! (%s)", filename);
  411.     exit(1);
  412.     }
  413.     return(pkpackret);
  414. }
  415.  
  416. static
  417. getpbits(pc, r)
  418. register struct pkc *pc;
  419. register struct ras *r; {
  420.     register int h_bit        = pc->pkc_width,
  421.          count,
  422.          turnon;
  423.     turnon = pc->pkc_flag&0x8;
  424.     dyn_f = pc->pkc_dyn_f;
  425.     repeatcount = 0;
  426.     r->ras_xcur = r->ras_ycur = 0;
  427.     while(r->ras_ycur < pc->pkc_height) {
  428.     count = pkpack(pc,r);
  429.     while(count > 0) {
  430.         if (count >= h_bit) {
  431.         count -= h_bit;
  432.         while(h_bit--) {
  433.             if (turnon)
  434.             r->ras_raster[r->ras_ycur*r->ras_bline + (r->ras_xcur>>3)]
  435.                 |= (0x80 >> (r->ras_xcur&7));
  436.             r->ras_xcur++;
  437.         }
  438.         r->ras_ycur++;
  439.         r->ras_xcur = 0;
  440.         while(repeatcount --) {
  441. #ifdef    VDEBUG
  442.             DBP((D_PK, "Copy line %d to %d\n", r->ras_ycur,
  443.             r->ras_ycur-1));
  444. #endif
  445.             memcpy((char*)&(r->ras_raster[r->ras_ycur * r->ras_bline]),
  446.                (char*)&(r->ras_raster[(r->ras_ycur - 1) *
  447.                    r->ras_bline]),
  448.                (int) r->ras_bline);
  449.             r->ras_ycur++;
  450.         }
  451.         repeatcount = 0;
  452.         h_bit = pc->pkc_width;
  453.         } else {
  454.         h_bit -= count;
  455.         while(count--) {
  456.             if (turnon)
  457.             r->ras_raster[r->ras_ycur*r->ras_bline +
  458.                 (r->ras_xcur>>3)] |= (0x80 >> (r->ras_xcur&7));
  459.             r->ras_xcur++;
  460.         }
  461.         count = 0;
  462.         }
  463.     }
  464.     turnon = !turnon;
  465.     }
  466.     if (r->ras_ycur != pc->pkc_height ||
  467.     h_bit != pc->pkc_width)
  468.     pkmsg("Bad bit somehow (%s)\n", filename);
  469. }
  470.  
  471. static
  472. getrbits(pc, r)
  473. register struct pkc *pc;
  474. register struct ras *r; {
  475.     register int x, y;
  476.     register int bit = 0;
  477.     for (y = 0; y < pc->pkc_height; y++) {
  478.     for (x = 0; x < pc->pkc_width; x++) {
  479.         if (pc->pkc_pkr[bit >> 3] & (0x80 >> (bit&7)))
  480.         r->ras_raster[y*r->ras_bline + (x>>3)] |= (0x80 >> (x&7));
  481.         bit++;
  482.     }
  483.     }
  484. }
  485.  
  486. /*    Convert a PK raster to an unpacked SFP version.
  487.     (If there's already an SFP version, it's returned instead)
  488.  */
  489. struct ras *
  490. pkrast(pc)
  491. struct pkc *pc; {
  492.     register struct ras *r;
  493.     if (pc->pkc_sfpr)
  494.     return(pc->pkc_sfpr);
  495.     if (!pc->pkc_rlen)
  496.     return(NULL);
  497.  
  498.     pc->pkc_sfpr = r = (struct ras *) mustmalloc(sizeof(struct ras),
  499.     filename);
  500.  
  501.     r->ras_height = pc->pkc_height;
  502.     r->ras_width = pc->pkc_width;
  503.     r->ras_bline = (pc->pkc_width + 7) / 8;
  504.     r->ras_bytes = r->ras_height * r->ras_bline;
  505.     r->ras_raster = (int8 *) mustmalloc((int) r->ras_bytes, filename);
  506.  
  507.     /* initialize bit unpackers */
  508.     rptr = pc->pkc_pkr;
  509.     bitweight = 8;
  510.  
  511.     /* calculate bits here...*/
  512.     if (pc->pkc_dyn_f == 14)
  513.     getrbits(pc, r);
  514.     else
  515.     getpbits(pc, r);
  516.     return(r);
  517. }
  518.  
  519. /*    Read a PK font file header */
  520. static struct pkp *
  521. pk_rpk(p)
  522. register struct pkp *p; {
  523.     register int i,c;
  524.  
  525.     if (getc(fin) != 89) {
  526.     pkmsg("PK file %s: Wrong version of packed file!\n", filename);
  527.     exit(1);
  528.     }
  529.     i = getc(fin);
  530.     if (i > 0) {
  531.     DBP((D_PK, "PKVersion: "));
  532.     while (i--) {
  533.         c = getc(fin);
  534.         DBP((D_PK, "%c", c));
  535.     }
  536.     DBP((D_PK, "\n"));
  537.     }
  538.     p->pkp_bmax = 0;
  539.     p->pkp_dmax = 0;
  540.     p->pkp_wmax = 0;
  541.     p->pkp_xomax = 0;
  542.     p->pkp_ds = get4int();
  543.     p->pkp_cs = get4int();
  544.     p->pkp_hppp = get4int();
  545.     p->pkp_vppp = get4int();
  546.  
  547.     if (p->pkp_hppp != p->pkp_vppp)
  548.     pkmsg("PK file %s: Warning aspect ratio not 1:1\n", filename);
  549.     p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
  550.     p->pkp_npts = ((double) p->pkp_ds / pow2(20)) *
  551.     ((double) p->pkp_res / OUTRES) + .5;
  552.     p->pkp_chars = (struct pkc *) NULL;
  553.     p->pkp_last = (struct pkc *) NULL;
  554.     p->pkp_num = 0;
  555.     p->pkp_list = (struct pkc **) NULL;
  556.  
  557.     /*    Try to guess symset, style, stroke weight and typeface
  558.     These aren't particularly important, but it assists the LJ
  559.     if it's trying to select one of these via characteristic.
  560.     This will only work if the file name reflects the Troff name,
  561.     according to the following conventions:
  562.  
  563.     filename: {<path>/}troffname.pointsize.[pk|sfp]
  564.  
  565.     All ROMAN8 encodings unless MATH8.
  566.     All 0 strokeweight, unless Bold.
  567.     All upright, unless Italic
  568.     All Roman typeface, unless otherwise specified
  569.  
  570.         R    : Normal Roman
  571.         I    : Italic
  572.         B    : Bold
  573.         S    : MATH8 Symbol
  574.         X    : Bold italic
  575.         .X    : <typeface> Bold italic
  576.         .I    : <typeface> Italic
  577.         .B    : <typeface> Bold
  578.         .R    : <typeface> Normal
  579.         H or H.    : Helvetica typeface
  580.         C or C.    : Courier typeface
  581.               typefaces should be extended.
  582.      */
  583.  
  584.     {
  585.     register char *fp;
  586.     register int char1, char2, italic, bold, bolditalic, onechar;
  587.  
  588.     fp = strrchr(filename, '/');
  589.     if (!fp)
  590.         fp = filename;
  591.     else
  592.         fp++;
  593.  
  594.     /* Default settings */
  595.     p->pkp_symset = (8 << 5) - 64 + 'U';    /* ROMAN 8 */
  596.     p->pkp_style = 0;    /* upright */
  597.     p->pkp_sw = 0;        /* stroke 0 */
  598.     p->pkp_typeface = 5;    /* typeface Roman */
  599.  
  600.     char1 = *fp++;
  601.     onechar = (*fp == '.');
  602.  
  603.     if (char1 == 'S' && onechar)
  604.         p->pkp_symset = (8 << 5) - 64 + 'M';    /* MATH 8 */
  605.     else {
  606.  
  607.         char2 = *fp;
  608.  
  609.         italic = ((onechar && char1 == 'I') || char2 == 'I');
  610.         bold = ((onechar && char1 == 'B') || char2 == 'B');
  611.         bolditalic = ((onechar && char1 == 'X') || char2 == 'X');
  612.  
  613.         if (bold || bolditalic)
  614.         p->pkp_sw = 3;
  615.  
  616.         if (italic || bolditalic)
  617.         p->pkp_style = 1;
  618.  
  619.         /* This should be extended, but I don't have a good feeling
  620.            for troff typeface -> HPLJ nomenclature */
  621.         switch(char1) {
  622.         case 'H':
  623.             p->pkp_typeface = 4;    /* Helvetica */
  624.             break;
  625.         case 'C':
  626.             p->pkp_typeface = 3;    /* Courier */
  627.             break;
  628.         /* more? */
  629.         }
  630.     }
  631.     }
  632.  
  633.     return(p);
  634. }
  635.  
  636. #ifdef    SFP
  637.  
  638. /*    Read an SFP header and convert it into the PK internal structure.
  639.  */
  640. static struct pkp *
  641. pk_rsfp(p)
  642. register struct pkp *p; {
  643.     register int c;
  644.     int len;
  645.  
  646.     if (fscanf(fin, ")s%dW", &len) != 1) {
  647.     pkmsg("SFP file %s: Bad CREATE FONT sequence\n", filename);
  648.     exit(1);
  649.     }
  650.  
  651.     if (len < 26) {
  652.     pkmsg("SFP file %s: CREATE FONT sequence too short (%d)\n",
  653.         filename, len);
  654.     exit(1);
  655.     }
  656.  
  657.     get2int();    /* 26 */
  658.     get1int();    /* 0 */
  659.     get1int();    /* 0 or 1 - forced 1 anyways */
  660.     get2int();    /* dummy */
  661.  
  662.     p->pkp_bmax = get2int();    /* baseline */
  663.     p->pkp_wmax = get2int();    /* cell width */
  664.     p->pkp_dmax = get2int() - p->pkp_bmax;    /* cell height */
  665.  
  666.     get1int();    /* 0 port, 1 land - forced 0 */
  667.     get1int();    /* fixed/proportional - forced proportional */
  668.  
  669.     p->pkp_symset = get2int();
  670.  
  671.     get2int();        /* pitch - we calculate this from height */
  672.     c = get2int();    /* retrieved *height* */
  673.     p->pkp_npts = c * POINT / (OUTRES*4) + .5;
  674.  
  675.     get2int();    /* dummy */
  676.     get1int();    /* dummy */
  677.  
  678.     p->pkp_style = get1int();
  679.     p->pkp_sw = get1int();
  680.     p->pkp_typeface = get1int();
  681.  
  682.     p->pkp_xomax = 0;
  683.  
  684.     /* These are simulated so that the PK handlers can figure the font out */
  685.     p->pkp_ds = p->pkp_npts * pow2(20);
  686.     p->pkp_cs = 0;
  687.     p->pkp_hppp = OUTRES * pow2(16) / POINT;
  688.     p->pkp_vppp = OUTRES * pow2(16) / POINT;
  689.     p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
  690.  
  691.     p->pkp_chars = (struct pkc *) NULL;
  692.     p->pkp_last = (struct pkc *) NULL;
  693.     p->pkp_num = 0;
  694.     p->pkp_list = (struct pkc **) NULL;
  695.  
  696.  
  697.     len -= 26;
  698.     while(len--)
  699.     getc(fin);
  700.     return(p);
  701. }
  702. #endif
  703.  
  704. static struct pkp *
  705. readhead() {
  706.     register struct pkp *p = (struct pkp *) mustmalloc(sizeof(struct pkp),
  707.     filename);
  708.     switch(getc(fin)) {
  709.     case PK_pre:
  710.         p->pkp_flags |= PK_PK;
  711.         return(pk_rpk(p));
  712. #ifdef    SFP
  713.     case 0x1b:
  714.         p->pkp_flags |= PK_SFP;
  715.         flag_byte = 0;
  716.         return(pk_rsfp(p));
  717. #endif
  718.     default:
  719.         fprintf(stderr, "PK file: %s don't know what it is!\n",
  720.         filename);
  721.         exit(1);
  722.     }
  723.     /*NOTREACHED*/
  724. }
  725.  
  726. pk_destroy(p)
  727. register struct pkp *p; {
  728.     register struct pkc *pc, *opc;
  729.     for (pc = p->pkp_chars; pc;) {
  730.     if (pc->pkc_pkr)
  731.         free((char *) pc->pkc_pkr);
  732.  
  733.     if (pc->pkc_sfpr) {
  734.         free((char *) pc->pkc_sfpr->ras_raster);
  735.         free((char *) pc->pkc_sfpr);
  736.     }
  737.  
  738.     opc = pc;
  739.     pc = opc->pkc_next;
  740.     free((char *) opc);
  741.     }
  742.     if (p->pkp_list)
  743.     free((char *) p->pkp_list);
  744.     free((char *) p);
  745. }
  746.  
  747. struct pkp *
  748. pk_read(file, fontcode)
  749. char *file; int fontcode; {
  750.     register struct pkp *p;
  751.     extern FILE *popen();
  752.     register struct pkc *pc, **pcp;
  753. #ifdef    COMPRESS
  754.     int compressed = 0;
  755. #endif
  756.     fin = (FILE *) NULL;
  757.     if (access(filename = file, 4) == 0)
  758.     fin = fopen(filename, "r");
  759. #ifdef    COMPRESS
  760.     else {
  761.     char buf[1024];
  762.     strcpy(buf, file);
  763.     strcat(buf, ".Z");
  764.     if (access(buf, 4) == 0) {
  765.         sprintf(buf, "%s %s.Z", COMPRESS, file);
  766.         fin = popen(buf, "r");
  767.         compressed = 1;
  768.     }
  769.     }
  770. #endif
  771.     if (!fin) {
  772.     pkmsg("Cannot open PK/SFP file %s\n", file);
  773.     exit(1);
  774.     }
  775.     p = readhead();
  776.     if (p->pkp_flags&PK_PK)
  777.     skipspecials();
  778.  
  779.     while ((flag_byte != PK_post) && (pc = readchar(p))) {
  780.     DBP((D_VERB, "type: %s: %d\n", p->pkp_flags&PK_PK? "PK": "SFP",
  781.         pc->pkc_char));
  782. #ifdef    PARTIAL
  783.     if (!needchar(fontcode, pc->pkc_char)) {
  784.         DBP((D_FONT|D_PK, "Dropping char %02x from load\n", pc->pkc_char));
  785.  
  786.         if (pc->pkc_pkr) {
  787.         free((char *) pc->pkc_pkr);
  788.         pc->pkc_pkr = (int8 *) NULL;
  789.         }
  790.  
  791.         if (pc->pkc_sfpr) {
  792.         free((char *) pc->pkc_sfpr->ras_raster);
  793.         free((char *) pc->pkc_sfpr);
  794.         pc->pkc_sfpr = (struct ras *) NULL;
  795.         }
  796.  
  797.         free((char *) pc);
  798.         if (p->pkp_flags&PK_PK)
  799.         skipspecials();
  800.         continue;
  801.     }
  802. #endif
  803.     DBP((D_FONT|D_PK, "Loading char %02x\n", pc->pkc_char));
  804.     p->pkp_num++;
  805.     pc->pkc_next = (struct pkc *) NULL;
  806.     if (!p->pkp_chars)
  807.         p->pkp_chars = pc;
  808.     if (p->pkp_last)
  809.         p->pkp_last->pkc_next = pc;
  810.     p->pkp_last = pc;
  811.     if (p->pkp_flags&PK_PK) {
  812.         p->pkp_bmax = max(p->pkp_bmax, pc->pkc_y_off);
  813.         p->pkp_dmax = max(p->pkp_dmax, pc->pkc_height - pc->pkc_y_off);
  814.         p->pkp_wmax = max(p->pkp_wmax, pc->pkc_width - pc->pkc_x_off);
  815.     }
  816.     p->pkp_xomax = min(p->pkp_xomax, pc->pkc_x_off);
  817.     if (pc->pkc_char == 'a') {
  818.         p->pkp_kh = pc->pkc_y_off;
  819.         p->pkp_kl = pc->pkc_y_off - pc->pkc_height;
  820.     }
  821.     if (p->pkp_flags&PK_PK)
  822.         skipspecials();
  823.     }
  824.     DBP((D_FONT|D_PK, "End of font\n"));
  825. #ifdef    COMPRESS
  826.     if (compressed) {
  827.     if (pclose(fin)) {
  828.         pkmsg("Decompression of %s failed\n", file);
  829.         exit(1);
  830.     }
  831.     } else
  832. #endif
  833.     fclose(fin);
  834.     pcp = p->pkp_list = (struct pkc **)
  835.     mustmalloc((int) (p->pkp_num * sizeof(struct pkc *)), filename);
  836.     for (pc = p->pkp_chars; pc; pc = pc->pkc_next)
  837.     *pcp++ = pc;
  838.     qsort(p->pkp_list, (unsigned) p->pkp_num, sizeof(struct pkc *), pkccomp);
  839.     return(p);
  840. }
  841.  
  842. /*    Emit routines */
  843.  
  844. /*    Emit a font descriptor in SFP format */
  845. epk_desc(p, sfp)
  846. register struct pkp *p;
  847. FILE *sfp; {
  848.  
  849.     fprintf(sfp, "\033)s26W");
  850.     fputshort(26, sfp);
  851.     fputc(0, sfp);
  852.     fputc(1, sfp);    /* font type 1 (33-127 && 160-255 printable) */
  853.     fputshort(0, sfp);
  854.     fputshort(p->pkp_bmax, sfp);    /* baseline position */
  855.     fputshort(p->pkp_wmax, sfp);    /* cell width */
  856.     fputshort(p->pkp_bmax + p->pkp_dmax, sfp);    /* cell height */
  857.     fputc(0, sfp);    /* portrait */
  858.     fputc(1, sfp);    /* proportional */
  859.  
  860.     fputshort((long) p->pkp_symset, sfp);
  861.  
  862.     fputshort((long) (OUTRES * p->pkp_npts * 4) / 120, sfp);
  863.     fputshort((long) (p->pkp_npts * (OUTRES / POINT) * 4), sfp);
  864.     fputshort(0, sfp);
  865.     fputc(0, sfp);
  866.     fputc(p->pkp_style, sfp);
  867.     fputc(p->pkp_sw, sfp);
  868.     fputc(p->pkp_typeface, sfp);
  869.  
  870. }
  871.  
  872. fputshort(val, f)
  873. FILE *f;
  874. long val; {
  875.     fputc(((int) val >> 8) & 0xff, f);
  876.     fputc((int) val & 0xff, f);
  877. }
  878.  
  879.  
  880. /*    Emit a character descriptor in SFP format.
  881.     Notes: if this is a PK font, the PK raster is converted
  882.     to SFP format and dumpped.  If the font was originally
  883.     SFP format, it's dumpped directly.  In either event, epkc_desc
  884.     deletes the SFP raster *and* the PK raster (if the character
  885.     has one), meaning that once this routine has emitted a character,
  886.     you can't emit it again!  Which is why pkc's pkflush completely
  887.     destroys the font.  Why?  Well, SFP's can get rather large, and
  888.     it seems reasonable to get rid of them as quickly as possible.
  889.  
  890.     Returns number of bytes emitted.
  891.  */
  892. epkc_desc(pc, sfp)
  893. register struct pkc *pc;
  894. register FILE *sfp; {
  895.     register struct ras *r;
  896.  
  897.     if (!pc->pkc_pkr && !pc->pkc_sfpr) {
  898.     fprintf(stderr, "%s: already downloaded %02x\n", pc->pkc_char);
  899.     return(0);
  900.     }
  901.  
  902.     /* Emit SET CHARACTER sequence */
  903.     fprintf(sfp, "\033*c%dE", pc->pkc_char);
  904.  
  905.     /* Emit DOWNLOAD CHARACTER sequence */
  906.     fprintf(sfp, "\033(s%dW", 16 + ((pc->pkc_width + 7) / 8) *
  907.     pc->pkc_height);
  908.     fputc(4, sfp);
  909.     fputc(0, sfp);
  910.     fputc(14, sfp);
  911.     fputc(1, sfp);
  912.     fputc(0, sfp);        /* portrait */
  913.     fputc(0, sfp);
  914.     fputshort(-pc->pkc_x_off, sfp);
  915.     fputshort(pc->pkc_y_off, sfp);
  916.     fputshort(pc->pkc_width, sfp);
  917.     fputshort(pc->pkc_height, sfp);
  918.     fputshort(pc->pkc_dx * 4 / pow2(16), sfp);
  919.     r = pkrast(pc);
  920.  
  921.     if (pc->pkc_pkr)
  922.     free((char *) pc->pkc_pkr);
  923.     pc->pkc_pkr = (int8 *) NULL;
  924.  
  925.     if (r) {
  926. #ifdef    VDEBUG
  927.     dumpr(r, r->ras_ycur);
  928. #endif
  929.     fwrite((char *) r->ras_raster, 1, (int) ((pc->pkc_width + 7) / 8) *
  930.         (int) pc->pkc_height, sfp);
  931.     free((char *) r->ras_raster);
  932.     free((char *) r);
  933.     }
  934.     pc->pkc_sfpr = (struct ras *) NULL;
  935.     return(((pc->pkc_width + 7) / 8) * pc->pkc_height);
  936. }
  937. #endif
  938.