home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1837 < prev    next >
Internet Message Format  |  1990-12-28  |  42KB

  1. From: clewis@ecicrl.UUCP (Chris Lewis)
  2. Newsgroups: comp.text.desktop,comp.fonts,alt.sources
  3. Subject: TeX PK to HP SFP format font conversion (1 of 2)
  4. Message-ID: <851@ecicrl.UUCP>
  5. Date: 17 Sep 90 16:17:28 GMT
  6.  
  7. Since this keeps coming up, and psroff hasn't apparently made it to
  8. comp.sources.unix, here's the utility to convert PK fonts to HP
  9. SFP's that Liam mentions:
  10.  
  11. Shell archive - cut here -
  12. #!/bin/sh
  13. sed -e 's/^X//' > README <<\!BLOTTO
  14. XThis distribution is that of pk2sfp, which is a subset of
  15. Xthe full psroff 2.0 distribution.  Psroff is a complete package
  16. Xto allow you to use CAT (aka "old") troff with HP Laserjet
  17. Xcompatible printers, Postscript and ditroff output drivers.
  18. XPsroff has a complete set of utilities for handling PK and SFP
  19. Xformat fonts.  Pk2sfp converts PK and SFP fonts into SFP format,
  20. Xwhich can be useful outside of psroff.  Psroff 2.0 is currently
  21. Xsitting in the queue for comp.sources.unix, but since people keep
  22. Xasking for pk2sfp, I've decided to release this subset separately.
  23. XIt also includes pktype, a program for printing the characteristics
  24. Xof PK and SFP fonts.  This distribution corresponds to Proff 2.0,
  25. Xpatchlevel 3, though, patches 1 thru 2 did not touch any of this code,
  26. Xand patch 3 was exclusively to make standalone pk2sfp possible.
  27. XPatch 3 to psroff has not been distributed yet.
  28. X
  29. XTo build: modify defs.h as appropriate and type "make".
  30. X
  31. XThe man page for pk2sfp is uneditted from the psroff distribution
  32. Xand refers to some things that aren't in this release:
  33. X
  34. X    1) pk2ditwid        (creates ditroff-like width tables)
  35. X    2) pk2ps            (converts SFP's and PK's to Postscript fonts)
  36. X    3) "partial" pk2sfp downloading stuff (-p).
  37. X
  38. XIn the interests of saving space, they have been omitted.  If
  39. Xyou need them, pick up the full Psroff release (they need tables
  40. Xbuilt by other major parts of psroff).  Further, you'll see some
  41. Xstrange things that look like ``%%LJF%%''.  If you had the full
  42. Xpsroff release, they'd expand into configuration dependent directory
  43. Xnames, but they're not builtin to any of *this* code.
  44. X
  45. XIf you intend to do any substantial work with PK and SFP fonts,
  46. XI suggest that you get the whole psroff package.
  47. X
  48. XThis distribution is unsupported.  However, psroff 2.0 *is*, and patches
  49. Xto psroff may be applicable to this distribution.
  50. X
  51. XPsroff availability (while it's languishing in comp.sources.unix's queue):
  52. X
  53. X    - gatekeeper.dec.com (16.1.0.2) as anonymous,
  54. X      file /pub/misc/psroff-2.0.tar.Z,
  55. X      courtesy Paul Vixie (vixie@wrl.dec.com)
  56. X    - cs.toronto.edu as anonymous,
  57. X      file pub/psroff.tar.Z,
  58. X      pub/psroff.patch[1-2].Z,
  59. X      courtesy Mark Moraes (moraes@cs.toronto.edu)
  60. X
  61. XHave fun!
  62. X
  63. XChris Lewis,
  64. X
  65. Xpsroff-request@eci386 or ...!uunet!utai!lsuc!eci386!psroff-request
  66. !BLOTTO
  67. sed -e 's/^X//' > Makefile <<\!BLOTTO
  68. XCFLAGS = -DALONE
  69. X
  70. Xall:    pk2sfp pktype
  71. X
  72. Xpk2sfp:    pk.o pk2sfp.o debug.o
  73. X    $(CC) -o pk2sfp debug.o pk.o pk2sfp.o
  74. X
  75. Xpktype: pk.o pktype.o debug.o
  76. X    $(CC) -o pktype debug.o pk.o pktype.o
  77. X
  78. Xpk.o pk2sfp.o debug.o:    pk.h defs.h
  79. X
  80. Xclean:
  81. X    rm -f *.o pktype pk2sfp
  82. !BLOTTO
  83. sed -e 's/^X//' > defs.h <<\!BLOTTO
  84. X/*    Copyright 1988, 1989 11:12:33 Chris Lewis
  85. X        All Rights Reserved
  86. X
  87. X    Permission to copy and further distribute is freely given provided
  88. X    this copyright notice remains intact and that this software is not
  89. X    sold for profit.
  90. X
  91. X    Project:    Generic Troff drivers
  92. X    Module:        defs.h 2.5 90/09/17 11:12:33
  93. X    Author:     Chris Lewis
  94. X    Specs:        Main header file - contains some customization
  95. X */
  96. X
  97. X/*    Official Release and Patch level:    */
  98. X#define    T2VERSION    "@(#)PSROFF Copyright 90/09/17 Chris Lewis - R2 P3"
  99. X
  100. X#ifndef    LIBDIR
  101. X/*    Don't touch this */
  102. X#define    LIBDIR    "/usr/lib/troff2"
  103. X#endif
  104. X
  105. X/*    Configuration parameters:
  106. X */
  107. X
  108. X#undef    BSD        /* Define if you are a V7 or BSD machine */
  109. X            /* strchr vs. index etc.... */
  110. X
  111. X#define    ATT        /* Define if you are some sort of SIII or SV system */
  112. X
  113. X#undef    BCOPY        /* Define if you don't have memcpy and friends - eg:
  114. X               oldish BSD systems */
  115. X
  116. X#undef    UNSIGNEDCHAR    /* Define if chars are unsigned on your machine */
  117. X
  118. X/*    The name of a routine that can be called thusly:
  119. X    VFPRINTF(stream, format, ap)
  120. X    FILE *stream;
  121. X    char *format;
  122. X    va_list ap;
  123. X    (eg: you have varargs.h and you have a routine functionally compatible
  124. X    with System V vfprintf.  I think BSD has one too)
  125. X
  126. X    undef if you don't got, and maybe my fakeout will work.
  127. X */
  128. X
  129. X#define VFPRINTF    vfprintf
  130. X
  131. X/* If you have the stand-alone pk2sfp distribution, do not touch
  132. X   anything from here on */
  133. X
  134. X/*    Font width file configuration:
  135. X
  136. X    - If HEADERSIZE defined, use that many bytes as a prefix to the
  137. X      compiled font width table.  HEADERSIZE 0 is the correct definition
  138. X      for Xenix and most System V Troffs.  HEADERSIZE=32 works for Ultrix.
  139. X      HEADERSIZE=0 works properly for Suns (I think).
  140. X    - If COFF is defined instead, use a COFF header on the beginning of
  141. X      the file.  I personally know of no machine that supports these.
  142. X    - If neither are defined, use a BSD/V7 style a.out.h header, this
  143. X      is appropriate for V7 and BSD troffs
  144. X
  145. X    The headers I write out do not have anything in them, so some
  146. X    troff's may blow.  Please let me know if they work for you...
  147. X    If you do need the headers, and these doesn't work for you, enable
  148. X    the COMPILE option in gfnttab.  I know of no troff that *needs*
  149. X    COMPILE on.
  150. X
  151. X */
  152. X
  153. X#define    HEADERSIZE 0    /* size of header in bytes */
  154. X#undef    COFF        /* systems using COFF headers */
  155. X
  156. X/* What do your CAT codes look like?
  157. X
  158. X   If BSDHACK defined, the code to magnify the next lead by 64 replaces the
  159. X   codes to set the tilt (tilt used only on 8-font CATs, which most CAT troff
  160. X   programs don't support).
  161. X
  162. X   Both FONT8 and BSDHACK code are *untested*.  FONT8 probably does *not*
  163. X   work.
  164. X */
  165. X
  166. X#undef    BSDHACK        /* Has magnify lead opcode - untested */
  167. X#undef    FONT8        /* 8 Font device - untested */
  168. X#define FONT4        /* Normal 4 font device */
  169. X
  170. X            /* define a command for decompressing an argument
  171. X               file to stdout - allows you to compress SFP's.
  172. X               undef if you don't got.  The -d option may be
  173. X               undocumented, but means decompress.  "-dc"
  174. X               is equivalent to zcat.  -dc appears to be
  175. X               in most versions of compress (eg: v3 & v4) */
  176. X#define    COMPRESS    "/usr/lbin/compress -dc"
  177. X
  178. X/*    Some postscript printers don't accept control-D as job termination
  179. X    (DEC scriptwriters for instance).  In that case, define this
  180. X    macro.  Alternately, if you have a proper printer manager that
  181. X    does this sort of stuff, define it too.
  182. X */
  183. X#undef    NOCONTROLD
  184. X
  185. X/*    define if you don't want your Postscript printer talking to you */
  186. X#undef    NOCHATTER
  187. X
  188. X/*    The only advantage to commenting-out one of these is to make the
  189. X    binary executable of troff2?? smaller.
  190. X */
  191. X
  192. X/*    Basic drivers: */
  193. X#define    PS    /* Postscript */
  194. X#define    LJ    /* Laserjet - psroff will not build with this undef'd */
  195. X#define    DT    /* ditroff */
  196. X
  197. X/*    Laserjet driver config: */
  198. X#define    PK    /* enable PK font downloading (needs LJ) */
  199. X
  200. X#define    SFP    /* enable SFP incremental font downloading (needs PK).
  201. X           You can still use SFP's without this turned on, but
  202. X           you won't get incremental downloading */
  203. X
  204. X#define    PARTIAL    /* partial (not incremental) font downloading */
  205. X
  206. X#define    INCR    /* enable incremental font downloading (needs PARTIAL) */
  207. X
  208. X#define    MDLF    16    /* Max # downloaded fonts permitted by your laserjet
  209. X               per *page*.  16 is correct for HPLJ+ and most II's.
  210. X               IIP's are 32 I think.  Some newer ones have higher
  211. X               restrictions (don't put this too high even if
  212. X               your printer supports it, you may run out of
  213. X               memory) */
  214. X
  215. X#define    PRELOAD    0    /* set to number of LJ fonts permanently
  216. X               downloaded to printer.  The backend will
  217. X               make sure that you don't go over the number
  218. X               of fonts permitted by the printer */
  219. X
  220. X#define    DEBUG        /* Do you want the debugger in?  If you encounter
  221. X               problems and you want help from me, you'll have
  222. X               to have this turned on */
  223. X
  224. X#define    OPT        /* Experimental code */
  225. X
  226. X#define    DEFPL  11    /* Default page length (11 inches).
  227. X               DO NOT change unless you absolutely HAVE to.
  228. X               You should only need to change this if you
  229. X               desire your printer to use something different
  230. X               as default.  If so, you'll HAVE to change
  231. X               your macro package to agree on the default - RT
  232. X               owners take note! (the man macros are wrong) */
  233. X
  234. X#define    DEFOFF 0.5    /* Default page offset.  DO NOT change unless you
  235. X               absolutely HAVE to.  You should only need this
  236. X               if: your vendor has buggered your macros to
  237. X               have a different default .po offset (Xenix),
  238. X               and you aren't using the macro adapter
  239. X               libraries that come with psroff (eg: you're
  240. X               using troff2ps directly).  See README/TROUBLE/
  241. X               psroff(1) (-O vs. -rO options) */
  242. X
  243. X#define    DEFYOFF   0    /* Default page vertical offset.  See README/TROUBLE/
  244. X               psroff(1) -Y options too */
  245. X
  246. X/*    Edit no more .... */
  247. X
  248. X#define    MAXDLFONTS (MDLF - PRELOAD)    /* # fonts troff2ps can download */
  249. X
  250. X/*    configuration verification */
  251. X
  252. X#if    defined(BSDHACK) && defined(FONT8)
  253. X#include    "BSDHACK and FONT8 cannot be defined at the same time"
  254. X#endif
  255. X#if    defined(FONT4) && defined(FONT8)
  256. X#include    "FONT4 and FONT8 cannot be defined at the same time"
  257. X#endif
  258. X
  259. X#if    !defined(LJ) && defined(PK)
  260. X#include    "Pointless to define PK without LJ"
  261. X#endif
  262. X
  263. X#if    !defined(PK) && (defined(INCR) || defined(PARTIAL))
  264. X#include    "Pointless to define INCR or PARTIAL without PK"
  265. X#endif
  266. X
  267. X#if    defined(INCR) && !defined(PARTIAL)
  268. X#include    "Don't support INCR without PARTIAL"
  269. X#endif
  270. X
  271. X#if    defined(SFP) && !defined(PK)
  272. X#include    "Can't define SFP without PK"
  273. X#endif
  274. X
  275. X#include <stdio.h>
  276. X#include <ctype.h>
  277. X
  278. X#ifdef BSD
  279. X#include <strings.h>
  280. X#define    strchr    index
  281. X#define    strrchr    rindex
  282. X#else
  283. X#include <string.h>
  284. X#endif
  285. X
  286. X#ifdef    BCOPY
  287. X#define    memcpy(to, from, len)    bcopy(from, to, len)
  288. X#define    clrarray(array, len)    bzero(array, len)
  289. X#else
  290. X#define    clrarray(array, len)    memset(array, '\0', len)
  291. X#endif
  292. X
  293. X#ifdef    UNSIGNEDCHAR
  294. X/* Ah heck, and this is probably not ANSI C either... */
  295. X#define    SIGNED(x) (((x)&0x80) ? ((x) - 256) : (x))
  296. X#endif
  297. X
  298. X#define    ESC    0x80
  299. X#define    FLASH    0x00
  300. X#define    CONTROL    0x40
  301. X#define    LEAD    0x60
  302. X#define    SIZE    0x50
  303. X
  304. X#define    DOWN    0
  305. X#define    UP    1
  306. X#define    LOWER    2
  307. X#define    UPPER    3
  308. X#define    FORWARD    4
  309. X#define    BACKWARD 5
  310. X
  311. X#define    TROFFRESOLUTION    432
  312. X
  313. X#define    SPECIAL        /* define if you want to supports special directives */
  314. X#define    FORM        /* define if you want the forms facility */
  315. X
  316. XFILE    *diagFile;
  317. X
  318. X#ifdef DEBUG
  319. X#define    DBP(x)    if (diagFile) dprintf x
  320. Xextern dprintf();
  321. X#else
  322. X#define    DBP(x)
  323. X#endif
  324. X
  325. Xtypedef int(*FUNC)();
  326. X
  327. X#define    FNULL    (FUNC) NULL
  328. X
  329. Xstruct    troff2befont {
  330. X    short    t2b_font;    /* font (troff nomenclature) S=don't change */
  331. X    short    t2b_xc;        /* X-shift */
  332. X    short    t2b_yc;        /* Y-shift */
  333. X    short    t2b_scale;    /* point size scale adjust */
  334. X    char     *t2b_charseq;    /* character sequence - may include PS */
  335. X};
  336. X
  337. Xstruct cattab {
  338. X    char *ch_name;
  339. X    char ch_set;
  340. X    unsigned char ch_catidx;
  341. X    unsigned char ch_wididx;
  342. X    unsigned char ch_info;    /* used by some auxiliary programs */
  343. X    char *ch_desc;
  344. X};
  345. X
  346. Xstruct backend {
  347. X    char    *bename;
  348. X    FUNC    beprolog,
  349. X        beepilog,
  350. X        beputchar,
  351. X        bepage,
  352. X        befontsel,    /* special function F */
  353. X        beoverlay,    /* special function O */
  354. X        bepassthru,    /* special function P */
  355. X        bexlat,        /* Xlate function */
  356. X        bedraw;        /* Ditroff draw emulation routine */
  357. X    struct troff2befont
  358. X        *bestdfont,    /* standard font translate table */
  359. X        *besymfont;    /* symbol font translate table */
  360. X};
  361. X
  362. X#define    MAXFONTS    50
  363. X
  364. Xstruct fonttable {
  365. X    char *tab[4];
  366. X    long flags;
  367. X#ifdef    INCR
  368. X    struct downmaps *map;
  369. X#endif
  370. X#ifdef    OPT
  371. X    char *widthtable;
  372. X#endif
  373. X};
  374. X
  375. X/*    Symbolic names for tab entries in fonttable    */
  376. X#define    troffName    tab[0]    /* troff name */
  377. X#define    fontName    tab[1]    /* back-end name (if used) */
  378. X#define    fontSeq        tab[2]    /* sequence to emit to shift to it
  379. X                   lj builtin's mostly */
  380. X
  381. X/*    fontFlags is 16 characters that reflect the state of the font
  382. X    at a particular pointsize - mainly for lj */
  383. X
  384. X/*    Use of flags:
  385. X    s:    unloaded SFP
  386. X    S:    loaded SFP
  387. X    p:    unloaded PK
  388. X    P:    loaded PK
  389. X    n:    non-existant
  390. X    b:    builtin.
  391. X */
  392. X#define    fontFlags    tab[3]
  393. X
  394. X
  395. X
  396. Xextern struct fonttable fonttable[MAXFONTS+1];
  397. Xextern struct fonttable *xlatetable[8];
  398. X
  399. Xstruct backend *be;
  400. X#define    BNULL    (struct backend *) NULL
  401. X
  402. Xextern char *skipblanks();
  403. X
  404. X/*    Common Back-end definitions */
  405. X
  406. X#define    N    (unsigned char) (0xff)    /* Use standard font */
  407. X#define    S    (unsigned char) (0xfe)    /* Use symbol font */
  408. X#define    D    (unsigned char) (0xfd)    /* Draw macro exists - use string directly */
  409. X#define    NTC    (unsigned char) (0xfc)    /* No font/Special flag */
  410. X
  411. X#define    NOC    NULL
  412. X
  413. Xextern int currentPage;
  414. Xextern int pageoffset;
  415. Xextern int pageyoffset;
  416. Xextern int pagelength;
  417. Xextern int pagePending;
  418. X
  419. X#ifdef    OPT
  420. Xextern char *widthtables;
  421. Xextern char *widthptr;
  422. Xextern int optimize;
  423. X#endif
  424. X
  425. Xextern int lastFont, lastPoints;
  426. Xextern int lastYPos, lastXPos, specXPos, specYPos;
  427. Xextern char *progname, *printer, *device;
  428. Xextern char **prologs;
  429. X
  430. Xint metrics;
  431. X
  432. XFILE *libopen();
  433. X
  434. X/*    Encoding format for generating width tables from font files */
  435. X/*    Used by pk2ditwid and friends */
  436. Xstruct enctab {
  437. X    char *e_name;
  438. X    char *e_seq;
  439. X    char e_wid;
  440. X};
  441. X
  442. X/*    Points in an inch */
  443. X#define    POINT    72.27
  444. X
  445. X#define    min(a,b)    ((a) < (b) ? (a) : (b))
  446. X#define    max(a,b)    ((a) > (b) ? (a) : (b))
  447. X
  448. X/* debug flags */
  449. X#define    D_CAT    1
  450. X#define    D_SPEC    2
  451. X#define    D_CHAR    4
  452. X#define    D_FONT    8
  453. X#define    D_BEND    0x10
  454. X#define    D_PK    0x20
  455. X#define    D_VERB    0x40
  456. X
  457. Xextern int debug;
  458. X
  459. Xextern char username[];
  460. X
  461. Xextern char *mustmalloc();
  462. X
  463. Xextern char *version, *shortversion;
  464. X
  465. X#ifdef    ALONE
  466. X#undef    PARTIAL
  467. X#undef    INCR
  468. X#endif
  469. !BLOTTO
  470. sed -e 's/^X//' > pk.h <<\!BLOTTO
  471. X/*    Copyright 1985, 1986, 1987, 1988 16:47:03 Chris Lewis
  472. X        All Rights Reserved
  473. X
  474. X    Permission to copy and further distribute is freely given provided
  475. X    this copyright notice remains intact and that this software is not
  476. X    sold for profit.
  477. X
  478. X    Project:    Generic Troff drivers
  479. X    Module:        pk.h
  480. X    Author:     Chris Lewis
  481. X    Specs:        PK format font file description
  482. X */
  483. X
  484. X#ifdef    PK
  485. X
  486. X#define    int8    unsigned char
  487. X#define    PK_ID    89
  488. X#define    PK_xxx1    240
  489. X#define    PK_xxx2    241
  490. X#define    PK_xxx3    242
  491. X#define    PK_xxx4    243
  492. X#define    PK_yyy    244
  493. X#define    PK_post    245
  494. X#define    PK_no_op    246
  495. X#define    PK_pre    247
  496. X
  497. X/*    PK header data */
  498. Xstruct pkp {
  499. X#define    PK_PK    01
  500. X#define    PK_SFP    02
  501. X    long pkp_ds;    /* design size */
  502. X    long pkp_npts;    /* pointsize normalized to 300 dpi */
  503. X    long pkp_res;    /* resolution of this font */
  504. X    long pkp_cs;    /* checksum */
  505. X    long pkp_hppp;    /* Horizontal pixel ratio */
  506. X    long pkp_vppp;    /* Vertical pixel ratio */
  507. X    long pkp_bmax;    /* baseline max */
  508. X    long pkp_dmax;    /* descender max */
  509. X    long pkp_wmax;    /* width max */
  510. X    long pkp_xomax;    /* left offset max */
  511. X    long pkp_kh;    /* kern high */
  512. X    long pkp_kl;    /* kern low */
  513. X    struct pkc *pkp_chars;    /* pointer to character descriptors */
  514. X    struct pkc *pkp_last;    /* pointer to last character descriptor */
  515. X    struct pkc **pkp_list;    /* pointer to sorted list of descriptors */
  516. X    long pkp_num;    /* number of characters */
  517. X    int pkp_symset;    /* symbol set */
  518. X    char pkp_flags;    /* font format */
  519. X    char pkp_style;    /* style */
  520. X    char pkp_sw;    /* stroke weight */
  521. X    char pkp_typeface;    /* typeface */
  522. X};
  523. X
  524. Xstruct pkp *pk_read();
  525. X
  526. Xstruct pkc {
  527. X    long pkc_flag;    /* flag byte */
  528. X    long pkc_dyn_f;    /* dynamic packing byte */
  529. X    long pkc_pl;    /* packet length */
  530. X    long pkc_char;    /* character code */
  531. X    long pkc_tfm;    /* TeX font metrics */
  532. X    long pkc_dx;    /* Horizontal escapement */
  533. X    long pkc_dy;    /* Vertical escapement */
  534. X    long pkc_width;    /* character width of BB */
  535. X    long pkc_height;    /* character height of BB */
  536. X    long pkc_x_off;    /* horizontal offset from upper left pixel to ref. */
  537. X    long pkc_y_off;    /* vertical offset from upper left pixel to ref. */
  538. X    long turnon;    /* used for unravelling bits */
  539. X    long pkc_rlen;    /* actual raster length */
  540. X    int8 *pkc_pkr;    /* actual PK raster */
  541. X    struct ras *pkc_sfpr;    /* SFP raster */
  542. X    struct pkc *pkc_next;    /* next character */
  543. X};
  544. X
  545. Xstruct ras {
  546. X    long ras_width;
  547. X    long ras_height;
  548. X    long ras_bline;
  549. X    long ras_bytes;
  550. X    long ras_xcur;
  551. X    long ras_ycur;
  552. X    int8 *ras_raster;
  553. X};
  554. X
  555. X#define    pow2(x)    (1L << (x))
  556. X
  557. X#define    OUTRES    300
  558. X#endif
  559. !BLOTTO
  560. sed -e 's/^X//' > pk.c <<\!BLOTTO
  561. X/*    Copyright 1990 Chris Lewis
  562. X */
  563. X
  564. X
  565. X#include "defs.h"
  566. X
  567. X#ifdef    PK
  568. X
  569. X#ifndef lint
  570. Xstatic char SCCSid[] = "@(#)pk.c 2.1 Copyright 90/07/18 16:51:38 Chris Lewis";
  571. X#endif
  572. X
  573. X#define    DRAW
  574. X#define    OUTRES    300
  575. X
  576. X#include "pk.h"
  577. X
  578. X#if    defined(PARTIAL)
  579. X#include "pkc.h"
  580. Xstruct needmaps *needmaps = (struct needmaps *) NULL;
  581. X#endif
  582. X
  583. Xextern char *progname;
  584. X
  585. Xstatic FILE *fin;
  586. Xstatic char *filename;    /* name of *current* font being read */
  587. Xextern char *malloc();
  588. X
  589. Xstatic long flag_byte;
  590. Xstatic repeatcount;
  591. Xstatic dyn_f;
  592. X
  593. Xstatic readraster();
  594. X
  595. Xstatic long
  596. Xget1int() { return(getc(fin)); }
  597. X
  598. Xstatic long
  599. Xget2int() {
  600. X    register long c;
  601. X    c = get1int();
  602. X    c = (c<<8) | (0xff & get1int());
  603. X    return(c);
  604. X}
  605. X
  606. Xstatic long
  607. Xget4int() {
  608. X    register long c;
  609. X    c = get2int();
  610. X    c = (c << 16) | (0xffff & get2int());
  611. X    return(c);
  612. X}
  613. X
  614. Xstatic long
  615. Xget3int() {
  616. X    register long c;
  617. X    c = get2int();
  618. X    c = (c << 8) | (0xff & get1int());
  619. X    return(c);
  620. X}
  621. X
  622. X#ifdef VFPRINTF
  623. X#include <varargs.h>
  624. X/* VARARGS */
  625. Xpkmsg(va_alist)
  626. Xva_dcl
  627. X{
  628. X    va_list args;
  629. X    char *fmt;
  630. X
  631. X    va_start(args);
  632. X    fmt = (char *) va_arg(args, char *);
  633. X    VFPRINTF(stderr, fmt, args);
  634. X    va_end(args);
  635. X}
  636. X#else
  637. X/* VARARGS1 ARGSUSED */
  638. Xpkmsg(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
  639. Xchar    *fmt;
  640. Xint    a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
  641. X    char buf[BUFSIZ];
  642. X    sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  643. X    fprintf(stderr, buf);
  644. X}
  645. X#endif
  646. X
  647. Xstatic
  648. Xskipspecials() {
  649. X    register int i,c;
  650. X    do {
  651. X    flag_byte = getc(fin);
  652. X    if (flag_byte >= 240) {
  653. X        i = 0;
  654. X        switch(flag_byte) {
  655. X        case PK_xxx4:
  656. X            i = (i << 8) + getc(fin);
  657. X        case PK_xxx3:
  658. X            i = (i << 8) + getc(fin);
  659. X        case PK_xxx2:
  660. X            i = (i << 8) + getc(fin);
  661. X        case PK_xxx1:
  662. X            i = (i << 8) + getc(fin);
  663. X            DBP((D_PK, "PK_xxx%d: ", flag_byte - PK_xxx1 + 1));
  664. X            while(i--) {
  665. X            c = getc(fin);
  666. X            DBP((D_PK, "%c", c));
  667. X            }
  668. X            DBP((D_PK, "\n"));
  669. X            break;
  670. X        case PK_yyy:
  671. X            i = get4int();
  672. X            DBP((D_PK, "Num special: %d\n", i));
  673. X            break;
  674. X        case PK_post:
  675. X            DBP((D_PK, "Postamble\n"));
  676. X            break;
  677. X        case PK_no_op:
  678. X            DBP((D_PK, "No-op\n"));
  679. X            break;
  680. X        default:
  681. X            pkmsg("PK file %s: Unexpected %ld\n", filename,
  682. X            flag_byte);
  683. X            exit(1);
  684. X        }
  685. X    }
  686. X    } while (flag_byte >= 240 && flag_byte != PK_post);
  687. X}
  688. X
  689. Xstatic
  690. Xreadschar(p)
  691. Xstruct pkc *p; {
  692. X    p->pkc_pl = get1int() + ((p->pkc_flag&0x3) << 8);
  693. X    p->pkc_char = get1int();
  694. X    p->pkc_tfm = get3int();
  695. X    p->pkc_dx = get1int() * pow2(16);
  696. X    p->pkc_dy = 0;
  697. X    p->pkc_width = get1int();
  698. X    p->pkc_height = get1int();
  699. X    p->pkc_x_off = get1int();
  700. X    p->pkc_y_off = get1int();
  701. X    if (p->pkc_x_off > 127)
  702. X    p->pkc_x_off -= 256;
  703. X    if (p->pkc_y_off > 127)
  704. X    p->pkc_y_off -= 256;
  705. X    p->pkc_rlen = p->pkc_pl - 8;
  706. X    readraster(p);
  707. X}
  708. X
  709. Xstatic
  710. Xreadeschar(p)
  711. Xstruct pkc *p; {
  712. X    p->pkc_pl = get2int() + ((p->pkc_flag&0x3) << 16);
  713. X    p->pkc_char = get1int();
  714. X    p->pkc_tfm = get3int();
  715. X    p->pkc_dx = get2int() * pow2(16);
  716. X    p->pkc_dy = 0;
  717. X    p->pkc_width = get2int();
  718. X    p->pkc_height = get2int();
  719. X    p->pkc_x_off = get2int();
  720. X    p->pkc_y_off = get2int();
  721. X    if (p->pkc_x_off > 32767)
  722. X    p->pkc_x_off -= 65536;
  723. X    if (p->pkc_y_off > 32767)
  724. X    p->pkc_y_off -= 65536;
  725. X    p->pkc_rlen = p->pkc_pl - 13;
  726. X    readraster(p);
  727. X}
  728. X
  729. Xstatic
  730. Xreadlchar(p)
  731. Xstruct pkc *p; {
  732. X    p->pkc_pl = get4int();
  733. X    p->pkc_char = get4int();
  734. X    p->pkc_tfm = get4int();
  735. X    p->pkc_dx = get4int();
  736. X    p->pkc_dy = get4int();
  737. X    p->pkc_width = get4int();
  738. X    p->pkc_height = get4int();
  739. X    p->pkc_x_off = get4int();
  740. X    p->pkc_y_off = get4int();
  741. X    p->pkc_rlen = p->pkc_pl - 28;
  742. X    readraster(p);
  743. X}
  744. X
  745. Xstatic
  746. Xreadraster(p)
  747. Xstruct pkc *p; {
  748. X    p->pkc_pkr = (int8 *) mustmalloc((int) p->pkc_rlen, filename);
  749. X    fread((char *) p->pkc_pkr, 1, (int) p->pkc_rlen, fin);
  750. X}
  751. X
  752. X/*    Read a character sequence from a PK file */
  753. Xstatic struct pkc *
  754. Xrpkc() {
  755. X    register struct pkc *p = (struct pkc *) mustmalloc(sizeof(struct pkc),
  756. X    filename);
  757. X
  758. X    p->pkc_pkr = NULL;
  759. X    p->pkc_sfpr = NULL;
  760. X    p->pkc_flag = flag_byte;
  761. X    p->pkc_dyn_f = p->pkc_flag >> 4;
  762. X    flag_byte &= 0x7;
  763. X
  764. X    if (flag_byte == 7)
  765. X    readlchar(p);
  766. X    else if (flag_byte > 3)
  767. X    readeschar(p);
  768. X    else
  769. X    readschar(p);
  770. X    return(p);
  771. X}
  772. X
  773. X#ifdef    SFP
  774. X/*    Read a character sequence from an SFP */
  775. Xstatic struct pkc *
  776. Xrsfpc() {
  777. X    register struct pkc *p;
  778. X    int len;
  779. X
  780. X    if ((len = getc(fin)) == EOF || len != '\033') {
  781. X    /* HP fonts when loaded often have trailing nulls due to DOS
  782. X       file padding.  Screech on non-null */
  783. X    if (len && len != EOF)
  784. X        fprintf(stderr,
  785. X        "%s: WARNING: trailing garbage in %s, offset %ld, char 0x%02x\n",
  786. X        progname, filename, ftell(fin), len);
  787. X    flag_byte = PK_post;
  788. X    return((struct pkc *) NULL);
  789. X    }
  790. X
  791. X    p = (struct pkc *) mustmalloc(sizeof(struct pkc), filename);
  792. X    p->pkc_pkr = NULL;
  793. X    p->pkc_sfpr = NULL;
  794. X    p->pkc_flag = 0;
  795. X    p->pkc_dyn_f = 0;
  796. X
  797. X    if (fscanf(fin, "*c%ldE", &(p->pkc_char)) != 1) {
  798. X    pkmsg("SFP file: %s, bad/missing SET CHAR CODE, offset: %ld\n",
  799. X        filename, ftell(fin));
  800. X    exit(1);
  801. X    }
  802. X
  803. X    if (fscanf(fin, "\033(s%dW", &len) != 1 || len < 16) {
  804. X    pkmsg("SFP file: %s, bad/missing/tooshort CHAR DOWNLOAD sequence\n",
  805. X        filename);
  806. X    exit(1);
  807. X    }
  808. X
  809. X    get4int();    /* skip some garbage */
  810. X    get2int();    /* skip more garbage (actually, orientation & dummy */
  811. X
  812. X    p->pkc_x_off = get2int();
  813. X    if (p->pkc_x_off > 32767)
  814. X    p->pkc_x_off -= 65536;
  815. X    p->pkc_x_off = -p->pkc_x_off;
  816. X    p->pkc_y_off = get2int();
  817. X    if (p->pkc_y_off > 32767)
  818. X    p->pkc_y_off -= 65536;
  819. X    p->pkc_width = get2int();
  820. X    p->pkc_height = get2int();
  821. X    p->pkc_dx = get2int() * pow2(16) / 4;
  822. X
  823. X    p->pkc_sfpr = (struct ras *) mustmalloc(sizeof(struct ras), filename);
  824. X
  825. X    p->pkc_sfpr->ras_height = p->pkc_height;
  826. X    p->pkc_sfpr->ras_width = p->pkc_width;
  827. X    p->pkc_sfpr->ras_bline = (p->pkc_width + 7) / 8;
  828. X    p->pkc_sfpr->ras_bytes = p->pkc_sfpr->ras_height * p->pkc_sfpr->ras_bline;
  829. X    if (p->pkc_sfpr->ras_bytes) {
  830. X    p->pkc_sfpr->ras_raster = (int8 *) mustmalloc((int)
  831. X        p->pkc_sfpr->ras_bytes, filename);
  832. X
  833. X    fread((char *) p->pkc_sfpr->ras_raster, (int) p->pkc_sfpr->ras_bytes,
  834. X        1, fin);
  835. X    } else {
  836. X    free((char *) p->pkc_sfpr);
  837. X    p->pkc_sfpr = NULL;
  838. X    }
  839. X
  840. X    return(p);
  841. X}
  842. X#endif
  843. X
  844. Xstatic struct pkc *
  845. Xreadchar(p)
  846. Xstruct pkp *p; {
  847. X    if (p->pkp_flags&PK_PK)
  848. X    return(rpkc());
  849. X#ifdef    SFP
  850. X    else if (p->pkp_flags&PK_SFP)
  851. X    return(rsfpc());
  852. X#endif
  853. X    else
  854. X    return((struct pkc *) NULL);
  855. X}
  856. X
  857. Xstatic int
  858. Xpkccomp(a, b)
  859. Xstruct pkc **a, **b; {
  860. X    if ((*a)->pkc_char < (*b)->pkc_char)
  861. X    return(-1);
  862. X    else
  863. X    return(1);
  864. X    /* can't be equal! */
  865. X}
  866. X
  867. Xstatic
  868. Xrastbit(x,y,r)
  869. Xregister int x, y;
  870. Xregister struct ras *r; {
  871. X    register int bi = y * r->ras_bline + (x >> 3);
  872. X
  873. X    /* You don't really want to uncomment this.... ;-) */
  874. X    /*    printf("x,y,bi: %d,%d,%d\n", x, y, bi);*/
  875. X    return(r->ras_raster[bi] & (0x80 >> (x&7)));
  876. X}
  877. X
  878. Xstatic int8 *rptr;
  879. Xstatic long bitweight;
  880. X
  881. Xgetnyb() {
  882. X    register int8 b;
  883. X    if (!bitweight) {
  884. X    bitweight = 8;
  885. X    rptr++;
  886. X    }
  887. X    b = *rptr;
  888. X    bitweight -= 4;
  889. X#ifdef    VDEBUG
  890. X    DBP((D_PK, "getnyb byte: %x\n", b));
  891. X    DBP((D_PK, "getnyb: %x\n", (b >> bitweight) & 0xf));
  892. X#endif
  893. X    return((b >> bitweight)&0xf);
  894. X}
  895. X
  896. X#ifdef    NEVER
  897. Xgetbit() {
  898. X    register int8 b;
  899. X    if (!bitweight) {
  900. X    bitweight = 8;
  901. X    rptr++;
  902. X    }
  903. X    b = *rptr;
  904. X    bitweight--;
  905. X    return((b>>bitweight)&1);
  906. X}
  907. X#endif
  908. X
  909. X/*    Dumps an ASCII version of the SFP raster r, to line n.
  910. X    Normally only for debugging, but is also used from pktype
  911. X */
  912. X
  913. Xdumpr(r, n)
  914. Xstruct ras *r;
  915. Xint n; {
  916. X    int x, y;
  917. X    if (!diagFile)
  918. X    return;
  919. X    fprintf(diagFile, "\n");
  920. X    for (y = 0; y < n; y++) {
  921. X    fprintf(diagFile, "%3d  ", y);
  922. X    for (x = 0; x < r->ras_width; x++) {
  923. X        if (rastbit(x, y, r))
  924. X        putc('*', diagFile);
  925. X        else
  926. X        putc(' ', diagFile);
  927. X    }
  928. X    putc('\n', diagFile);
  929. X    }
  930. X}
  931. X
  932. Xstatic long
  933. Xpkpack(pc,r)
  934. Xregister struct pkc *pc;
  935. Xregister struct ras *r; {
  936. X    long i, j;
  937. X    long pkpackret;
  938. X    i = getnyb();
  939. X    if (i == 0) {
  940. X    do {
  941. X        j = getnyb();
  942. X        i++;
  943. X    } while(!j);
  944. X    while(i--)
  945. X        j = (j << 4) + getnyb();
  946. X    pkpackret = (j - 15 + (13 - dyn_f) * 16 + dyn_f);
  947. X    } else if (i <= dyn_f)
  948. X    pkpackret = (i);
  949. X    else if (i < 14)
  950. X    pkpackret = ((i - dyn_f - 1)*16 + getnyb() + dyn_f + 1);
  951. X    else {
  952. X    if (repeatcount) {
  953. X        pkmsg("Second repeat count for this row!\n");
  954. X        exit(1);
  955. X    }
  956. X    if (i == 14)
  957. X        repeatcount = pkpack(pc,r);
  958. X    else
  959. X        repeatcount = 1;
  960. X    /*sendout(1, repeatcount, pc, r);*/
  961. X    pkpackret = (pkpack(pc,r));
  962. X    }
  963. X    if (pkpackret < 1) {
  964. X    pkmsg("pkpack returned < 1! (%s)", filename);
  965. X    exit(1);
  966. X    }
  967. X    return(pkpackret);
  968. X}
  969. X
  970. Xstatic
  971. Xgetpbits(pc, r)
  972. Xregister struct pkc *pc;
  973. Xregister struct ras *r; {
  974. X    register int h_bit        = pc->pkc_width,
  975. X         count,
  976. X         turnon;
  977. X    turnon = pc->pkc_flag&0x8;
  978. X    dyn_f = pc->pkc_dyn_f;
  979. X    repeatcount = 0;
  980. X    r->ras_xcur = r->ras_ycur = 0;
  981. X    while(r->ras_ycur < pc->pkc_height) {
  982. X    count = pkpack(pc,r);
  983. X    while(count > 0) {
  984. X        if (count >= h_bit) {
  985. X        count -= h_bit;
  986. X        while(h_bit--) {
  987. X            if (turnon)
  988. X            r->ras_raster[r->ras_ycur*r->ras_bline + (r->ras_xcur>>3)]
  989. X                |= (0x80 >> (r->ras_xcur&7));
  990. X            r->ras_xcur++;
  991. X        }
  992. X        r->ras_ycur++;
  993. X        r->ras_xcur = 0;
  994. X        while(repeatcount --) {
  995. X#ifdef    VDEBUG
  996. X            DBP((D_PK, "Copy line %d to %d\n", r->ras_ycur,
  997. X            r->ras_ycur-1));
  998. X#endif
  999. X            memcpy((char*)&(r->ras_raster[r->ras_ycur * r->ras_bline]),
  1000. X               (char*)&(r->ras_raster[(r->ras_ycur - 1) *
  1001. X                   r->ras_bline]),
  1002. X               (int) r->ras_bline);
  1003. X            r->ras_ycur++;
  1004. X        }
  1005. X        repeatcount = 0;
  1006. X        h_bit = pc->pkc_width;
  1007. X        } else {
  1008. X        h_bit -= count;
  1009. X        while(count--) {
  1010. X            if (turnon)
  1011. X            r->ras_raster[r->ras_ycur*r->ras_bline +
  1012. X                (r->ras_xcur>>3)] |= (0x80 >> (r->ras_xcur&7));
  1013. X            r->ras_xcur++;
  1014. X        }
  1015. X        count = 0;
  1016. X        }
  1017. X    }
  1018. X    turnon = !turnon;
  1019. X    }
  1020. X    if (r->ras_ycur != pc->pkc_height ||
  1021. X    h_bit != pc->pkc_width)
  1022. X    pkmsg("Bad bit somehow (%s)\n", filename);
  1023. X}
  1024. X
  1025. Xstatic
  1026. Xgetrbits(pc, r)
  1027. Xregister struct pkc *pc;
  1028. Xregister struct ras *r; {
  1029. X    register int x, y;
  1030. X    register int bit = 0;
  1031. X    for (y = 0; y < pc->pkc_height; y++) {
  1032. X    for (x = 0; x < pc->pkc_width; x++) {
  1033. X        if (pc->pkc_pkr[bit >> 3] & (0x80 >> (bit&7)))
  1034. X        r->ras_raster[y*r->ras_bline + (x>>3)] |= (0x80 >> (x&7));
  1035. X        bit++;
  1036. X    }
  1037. X    }
  1038. X}
  1039. X
  1040. X/*    Convert a PK raster to an unpacked SFP version.
  1041. X    (If there's already an SFP version, it's returned instead)
  1042. X */
  1043. Xstruct ras *
  1044. Xpkrast(pc)
  1045. Xstruct pkc *pc; {
  1046. X    register struct ras *r;
  1047. X    if (pc->pkc_sfpr)
  1048. X    return(pc->pkc_sfpr);
  1049. X    if (!pc->pkc_rlen)
  1050. X    return(NULL);
  1051. X
  1052. X    pc->pkc_sfpr = r = (struct ras *) mustmalloc(sizeof(struct ras),
  1053. X    filename);
  1054. X
  1055. X    r->ras_height = pc->pkc_height;
  1056. X    r->ras_width = pc->pkc_width;
  1057. X    r->ras_bline = (pc->pkc_width + 7) / 8;
  1058. X    r->ras_bytes = r->ras_height * r->ras_bline;
  1059. X    r->ras_raster = (int8 *) mustmalloc((int) r->ras_bytes, filename);
  1060. X
  1061. X    /* initialize bit unpackers */
  1062. X    rptr = pc->pkc_pkr;
  1063. X    bitweight = 8;
  1064. X
  1065. X    /* calculate bits here...*/
  1066. X    if (pc->pkc_dyn_f == 14)
  1067. X    getrbits(pc, r);
  1068. X    else
  1069. X    getpbits(pc, r);
  1070. X    return(r);
  1071. X}
  1072. X
  1073. X/*    Read a PK font file header */
  1074. Xstatic struct pkp *
  1075. Xpk_rpk(p)
  1076. Xregister struct pkp *p; {
  1077. X    register int i,c;
  1078. X
  1079. X    if (getc(fin) != 89) {
  1080. X    pkmsg("PK file %s: Wrong version of packed file!\n", filename);
  1081. X    exit(1);
  1082. X    }
  1083. X    i = getc(fin);
  1084. X    if (i > 0) {
  1085. X    DBP((D_PK, "PKVersion: "));
  1086. X    while (i--) {
  1087. X        c = getc(fin);
  1088. X        DBP((D_PK, "%c", c));
  1089. X    }
  1090. X    DBP((D_PK, "\n"));
  1091. X    }
  1092. X    p->pkp_bmax = 0;
  1093. X    p->pkp_dmax = 0;
  1094. X    p->pkp_wmax = 0;
  1095. X    p->pkp_xomax = 0;
  1096. X    p->pkp_ds = get4int();
  1097. X    p->pkp_cs = get4int();
  1098. X    p->pkp_hppp = get4int();
  1099. X    p->pkp_vppp = get4int();
  1100. X
  1101. X    if (p->pkp_hppp != p->pkp_vppp)
  1102. X    pkmsg("PK file %s: Warning aspect ratio not 1:1\n", filename);
  1103. X    p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
  1104. X    p->pkp_npts = ((double) p->pkp_ds / pow2(20)) *
  1105. X    ((double) p->pkp_res / OUTRES) + .5;
  1106. X    p->pkp_chars = (struct pkc *) NULL;
  1107. X    p->pkp_last = (struct pkc *) NULL;
  1108. X    p->pkp_num = 0;
  1109. X    p->pkp_list = (struct pkc **) NULL;
  1110. X
  1111. X    /*    Try to guess symset, style, stroke weight and typeface
  1112. X    These aren't particularly important, but it assists the LJ
  1113. X    if it's trying to select one of these via characteristic.
  1114. X    This will only work if the file name reflects the Troff name,
  1115. X    according to the following conventions:
  1116. X
  1117. X    filename: {<path>/}troffname.pointsize.[pk|sfp]
  1118. X
  1119. X    All ROMAN8 encodings unless MATH8.
  1120. X    All 0 strokeweight, unless Bold.
  1121. X    All upright, unless Italic
  1122. X    All Roman typeface, unless otherwise specified
  1123. X
  1124. X        R    : Normal Roman
  1125. X        I    : Italic
  1126. X        B    : Bold
  1127. X        S    : MATH8 Symbol
  1128. X        X    : Bold italic
  1129. X        .X    : <typeface> Bold italic
  1130. X        .I    : <typeface> Italic
  1131. X        .B    : <typeface> Bold
  1132. X        .R    : <typeface> Normal
  1133. X        H or H.    : Helvetica typeface
  1134. X        C or C.    : Courier typeface
  1135. X              typefaces should be extended.
  1136. X     */
  1137. X
  1138. X    {
  1139. X    register char *fp;
  1140. X    register int char1, char2, italic, bold, bolditalic, onechar;
  1141. X
  1142. X    fp = strrchr(filename, '/');
  1143. X    if (!fp)
  1144. X        fp = filename;
  1145. X    else
  1146. X        fp++;
  1147. X
  1148. X    /* Default settings */
  1149. X    p->pkp_symset = (8 << 5) - 64 + 'U';    /* ROMAN 8 */
  1150. X    p->pkp_style = 0;    /* upright */
  1151. X    p->pkp_sw = 0;        /* stroke 0 */
  1152. X    p->pkp_typeface = 5;    /* typeface Roman */
  1153. X
  1154. X    char1 = *fp++;
  1155. X    onechar = (*fp == '.');
  1156. X
  1157. X    if (char1 == 'S' && onechar)
  1158. X        p->pkp_symset = (8 << 5) - 64 + 'M';    /* MATH 8 */
  1159. X    else {
  1160. X
  1161. X        char2 = *fp;
  1162. X
  1163. X        italic = ((onechar && char1 == 'I') || char2 == 'I');
  1164. X        bold = ((onechar && char1 == 'B') || char2 == 'B');
  1165. X        bolditalic = ((onechar && char1 == 'X') || char2 == 'X');
  1166. X
  1167. X        if (bold || bolditalic)
  1168. X        p->pkp_sw = 3;
  1169. X
  1170. X        if (italic || bolditalic)
  1171. X        p->pkp_style = 1;
  1172. X
  1173. X        /* This should be extended, but I don't have a good feeling
  1174. X           for troff typeface -> HPLJ nomenclature */
  1175. X        switch(char1) {
  1176. X        case 'H':
  1177. X            p->pkp_typeface = 4;    /* Helvetica */
  1178. X            break;
  1179. X        case 'C':
  1180. X            p->pkp_typeface = 3;    /* Courier */
  1181. X            break;
  1182. X        /* more? */
  1183. X        }
  1184. X    }
  1185. X    }
  1186. X
  1187. X    return(p);
  1188. X}
  1189. X
  1190. X#ifdef    SFP
  1191. X
  1192. X/*    Read an SFP header and convert it into the PK internal structure.
  1193. X */
  1194. Xstatic struct pkp *
  1195. Xpk_rsfp(p)
  1196. Xregister struct pkp *p; {
  1197. X    register int c;
  1198. X    int len;
  1199. X
  1200. X    if (fscanf(fin, ")s%dW", &len) != 1) {
  1201. X    pkmsg("SFP file %s: Bad CREATE FONT sequence\n", filename);
  1202. X    exit(1);
  1203. X    }
  1204. X
  1205. X    if (len < 26) {
  1206. X    pkmsg("SFP file %s: CREATE FONT sequence too short (%d)\n",
  1207. X        filename, len);
  1208. X    exit(1);
  1209. X    }
  1210. X
  1211. X    get2int();    /* 26 */
  1212. X    get1int();    /* 0 */
  1213. X    get1int();    /* 0 or 1 - forced 1 anyways */
  1214. X    get2int();    /* dummy */
  1215. X
  1216. X    p->pkp_bmax = get2int();    /* baseline */
  1217. X    p->pkp_wmax = get2int();    /* cell width */
  1218. X    p->pkp_dmax = get2int() - p->pkp_bmax;    /* cell height */
  1219. X
  1220. X    get1int();    /* 0 port, 1 land - forced 0 */
  1221. X    get1int();    /* fixed/proportional - forced proportional */
  1222. X
  1223. X    p->pkp_symset = get2int();
  1224. X
  1225. X    get2int();        /* pitch - we calculate this from height */
  1226. X    c = get2int();    /* retrieved *height* */
  1227. X    p->pkp_npts = c * POINT / (OUTRES*4) + .5;
  1228. X
  1229. X    get2int();    /* dummy */
  1230. X    get1int();    /* dummy */
  1231. X
  1232. X    p->pkp_style = get1int();
  1233. X    p->pkp_sw = get1int();
  1234. X    p->pkp_typeface = get1int();
  1235. X
  1236. X    p->pkp_xomax = 0;
  1237. X
  1238. X    /* These are simulated so that the PK handlers can figure the font out */
  1239. X    p->pkp_ds = p->pkp_npts * pow2(20);
  1240. X    p->pkp_cs = 0;
  1241. X    p->pkp_hppp = OUTRES * pow2(16) / POINT;
  1242. X    p->pkp_vppp = OUTRES * pow2(16) / POINT;
  1243. X    p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
  1244. X
  1245. X    p->pkp_chars = (struct pkc *) NULL;
  1246. X    p->pkp_last = (struct pkc *) NULL;
  1247. X    p->pkp_num = 0;
  1248. X    p->pkp_list = (struct pkc **) NULL;
  1249. X
  1250. X
  1251. X    len -= 26;
  1252. X    while(len--)
  1253. X    getc(fin);
  1254. X    return(p);
  1255. X}
  1256. X#endif
  1257. X
  1258. Xstatic struct pkp *
  1259. Xreadhead() {
  1260. X    register struct pkp *p = (struct pkp *) mustmalloc(sizeof(struct pkp),
  1261. X    filename);
  1262. X    switch(getc(fin)) {
  1263. X    case PK_pre:
  1264. X        p->pkp_flags |= PK_PK;
  1265. X        return(pk_rpk(p));
  1266. X#ifdef    SFP
  1267. X    case 0x1b:
  1268. X        p->pkp_flags |= PK_SFP;
  1269. X        flag_byte = 0;
  1270. X        return(pk_rsfp(p));
  1271. X#endif
  1272. X    default:
  1273. X        fprintf(stderr, "PK file: %s don't know what it is!\n",
  1274. X        filename);
  1275. X        exit(1);
  1276. X    }
  1277. X    /*NOTREACHED*/
  1278. X}
  1279. X
  1280. Xpk_destroy(p)
  1281. Xregister struct pkp *p; {
  1282. X    register struct pkc *pc, *opc;
  1283. X    for (pc = p->pkp_chars; pc;) {
  1284. X    if (pc->pkc_pkr)
  1285. X        free((char *) pc->pkc_pkr);
  1286. X
  1287. X    if (pc->pkc_sfpr) {
  1288. X        free((char *) pc->pkc_sfpr->ras_raster);
  1289. X        free((char *) pc->pkc_sfpr);
  1290. X    }
  1291. X
  1292. X    opc = pc;
  1293. X    pc = opc->pkc_next;
  1294. X    free((char *) opc);
  1295. X    }
  1296. X    if (p->pkp_list)
  1297. X    free((char *) p->pkp_list);
  1298. X    free((char *) p);
  1299. X}
  1300. X
  1301. Xstruct pkp *
  1302. Xpk_read(file, fontcode)
  1303. Xchar *file; int fontcode; {
  1304. X    register struct pkp *p;
  1305. X    register struct pkc *pc, **pcp;
  1306. X#ifdef    COMPRESS
  1307. X    int compressed = 0;
  1308. X#endif
  1309. X    fin = (FILE *) NULL;
  1310. X    if (access(filename = file, 4) == 0)
  1311. X    fin = fopen(filename, "r");
  1312. X#ifdef    COMPRESS
  1313. X    else {
  1314. X    char buf[1024];
  1315. X    strcpy(buf, file);
  1316. X    strcat(buf, ".Z");
  1317. X    if (access(buf, 4) == 0) {
  1318. X        sprintf(buf, "%s %s.Z", COMPRESS, file);
  1319. X        fin = popen(buf, "r");
  1320. X        compressed = 1;
  1321. X    }
  1322. X    }
  1323. X#endif
  1324. X    if (!fin) {
  1325. X    pkmsg("Cannot open PK/SFP file %s\n", file);
  1326. X    exit(1);
  1327. X    }
  1328. X    p = readhead();
  1329. X    if (p->pkp_flags&PK_PK)
  1330. X    skipspecials();
  1331. X
  1332. X    while ((flag_byte != PK_post) && (pc = readchar(p))) {
  1333. X    DBP((D_VERB, "type: %s: %d\n", p->pkp_flags&PK_PK? "PK": "SFP",
  1334. X        pc->pkc_char));
  1335. X#ifdef    PARTIAL
  1336. X    if (!needchar(fontcode, pc->pkc_char)) {
  1337. X        DBP((D_FONT|D_PK, "Dropping char %02x from load\n", pc->pkc_char));
  1338. X
  1339. X        if (pc->pkc_pkr) {
  1340. X        free((char *) pc->pkc_pkr);
  1341. X        pc->pkc_pkr = (int8 *) NULL;
  1342. X        }
  1343. X
  1344. X        if (pc->pkc_sfpr) {
  1345. X        free((char *) pc->pkc_sfpr->ras_raster);
  1346. X        free((char *) pc->pkc_sfpr);
  1347. X        pc->pkc_sfpr = (struct ras *) NULL;
  1348. X        }
  1349. X
  1350. X        free((char *) pc);
  1351. X        if (p->pkp_flags&PK_PK)
  1352. X        skipspecials();
  1353. X        continue;
  1354. X    }
  1355. X#endif
  1356. X    DBP((D_FONT|D_PK, "Loading char %02x\n", pc->pkc_char));
  1357. X    p->pkp_num++;
  1358. X    pc->pkc_next = (struct pkc *) NULL;
  1359. X    if (!p->pkp_chars)
  1360. X        p->pkp_chars = pc;
  1361. X    if (p->pkp_last)
  1362. X        p->pkp_last->pkc_next = pc;
  1363. X    p->pkp_last = pc;
  1364. X    if (p->pkp_flags&PK_PK) {
  1365. X        p->pkp_bmax = max(p->pkp_bmax, pc->pkc_y_off);
  1366. X        p->pkp_dmax = max(p->pkp_dmax, pc->pkc_height - pc->pkc_y_off);
  1367. X        p->pkp_wmax = max(p->pkp_wmax, pc->pkc_width - pc->pkc_x_off);
  1368. X    }
  1369. X    p->pkp_xomax = min(p->pkp_xomax, pc->pkc_x_off);
  1370. X    if (pc->pkc_char == 'a') {
  1371. X        p->pkp_kh = pc->pkc_y_off;
  1372. X        p->pkp_kl = pc->pkc_y_off - pc->pkc_height;
  1373. X    }
  1374. X    if (p->pkp_flags&PK_PK)
  1375. X        skipspecials();
  1376. X    }
  1377. X    DBP((D_FONT|D_PK, "End of font\n"));
  1378. X#ifdef    COMPRESS
  1379. X    if (compressed) {
  1380. X    if (pclose(fin)) {
  1381. X        pkmsg("Decompression of %s failed\n", file);
  1382. X        exit(1);
  1383. X    }
  1384. X    } else
  1385. X#endif
  1386. X    fclose(fin);
  1387. X    pcp = p->pkp_list = (struct pkc **)
  1388. X    mustmalloc((int) (p->pkp_num * sizeof(struct pkc *)), filename);
  1389. X    for (pc = p->pkp_chars; pc; pc = pc->pkc_next)
  1390. X    *pcp++ = pc;
  1391. X    qsort(p->pkp_list, (unsigned) p->pkp_num, sizeof(struct pkc *), pkccomp);
  1392. X    return(p);
  1393. X}
  1394. X
  1395. X/*    Emit routines */
  1396. X
  1397. X/*    Emit a font descriptor in SFP format */
  1398. Xepk_desc(p, sfp)
  1399. Xregister struct pkp *p;
  1400. XFILE *sfp; {
  1401. X
  1402. X    fprintf(sfp, "\033)s26W");
  1403. X    fputshort(26, sfp);
  1404. X    fputc(0, sfp);
  1405. X    fputc(1, sfp);    /* font type 1 (33-127 && 160-255 printable) */
  1406. X    fputshort(0, sfp);
  1407. X    fputshort(p->pkp_bmax, sfp);    /* baseline position */
  1408. X    fputshort(p->pkp_wmax, sfp);    /* cell width */
  1409. X    fputshort(p->pkp_bmax + p->pkp_dmax, sfp);    /* cell height */
  1410. X    fputc(0, sfp);    /* portrait */
  1411. X    fputc(1, sfp);    /* proportional */
  1412. X
  1413. X    fputshort((long) p->pkp_symset, sfp);
  1414. X
  1415. X    fputshort((long) (OUTRES * p->pkp_npts * 4) / 120, sfp);
  1416. X    fputshort((long) (p->pkp_npts * (OUTRES / POINT) * 4), sfp);
  1417. X    fputshort(0, sfp);
  1418. X    fputc(0, sfp);
  1419. X    fputc(p->pkp_style, sfp);
  1420. X    fputc(p->pkp_sw, sfp);
  1421. X    fputc(p->pkp_typeface, sfp);
  1422. X
  1423. X}
  1424. X
  1425. Xfputshort(val, f)
  1426. XFILE *f;
  1427. Xlong val; {
  1428. X    fputc(((int) val >> 8) & 0xff, f);
  1429. X    fputc((int) val & 0xff, f);
  1430. X}
  1431. X
  1432. X
  1433. X/*    Emit a character descriptor in SFP format.
  1434. X    Notes: if this is a PK font, the PK raster is converted
  1435. X    to SFP format and dumpped.  If the font was originally
  1436. X    SFP format, it's dumpped directly.  In either event, epkc_desc
  1437. X    deletes the SFP raster *and* the PK raster (if the character
  1438. X    has one), meaning that once this routine has emitted a character,
  1439. X    you can't emit it again!  Which is why pkc's pkflush completely
  1440. X    destroys the font.  Why?  Well, SFP's can get rather large, and
  1441. X    it seems reasonable to get rid of them as quickly as possible.
  1442. X
  1443. X    Returns number of bytes emitted.
  1444. X */
  1445. Xepkc_desc(pc, sfp)
  1446. Xregister struct pkc *pc;
  1447. Xregister FILE *sfp; {
  1448. X    register struct ras *r;
  1449. X
  1450. X    if (!pc->pkc_pkr && !pc->pkc_sfpr) {
  1451. X    fprintf(stderr, "%s: already downloaded %02x\n", pc->pkc_char);
  1452. X    return(0);
  1453. X    }
  1454. X
  1455. X    /* Emit SET CHARACTER sequence */
  1456. X    fprintf(sfp, "\033*c%dE", pc->pkc_char);
  1457. X
  1458. X    /* Emit DOWNLOAD CHARACTER sequence */
  1459. X    fprintf(sfp, "\033(s%dW", 16 + ((pc->pkc_width + 7) / 8) *
  1460. X    pc->pkc_height);
  1461. X    fputc(4, sfp);
  1462. X    fputc(0, sfp);
  1463. X    fputc(14, sfp);
  1464. X    fputc(1, sfp);
  1465. X    fputc(0, sfp);        /* portrait */
  1466. X    fputc(0, sfp);
  1467. X    fputshort(-pc->pkc_x_off, sfp);
  1468. X    fputshort(pc->pkc_y_off, sfp);
  1469. X    fputshort(pc->pkc_width, sfp);
  1470. X    fputshort(pc->pkc_height, sfp);
  1471. X    fputshort(pc->pkc_dx * 4 / pow2(16), sfp);
  1472. X    r = pkrast(pc);
  1473. X
  1474. X    if (pc->pkc_pkr)
  1475. X    free((char *) pc->pkc_pkr);
  1476. X    pc->pkc_pkr = (int8 *) NULL;
  1477. X
  1478. X    if (r) {
  1479. X#ifdef    VDEBUG
  1480. X    dumpr(r, r->ras_ycur);
  1481. X#endif
  1482. X    fwrite((char *) r->ras_raster, 1, (int) ((pc->pkc_width + 7) / 8) *
  1483. X        (int) pc->pkc_height, sfp);
  1484. X    free((char *) r->ras_raster);
  1485. X    free((char *) r);
  1486. X    }
  1487. X    pc->pkc_sfpr = (struct ras *) NULL;
  1488. X    return(((pc->pkc_width + 7) / 8) * pc->pkc_height);
  1489. X}
  1490. X#endif
  1491. !BLOTTO
  1492. sed -e 's/^X//' > debug.c <<\!BLOTTO
  1493. X#include "defs.h"
  1494. X
  1495. X#ifndef    lint
  1496. Xstatic char SCCSid[] =
  1497. X    "@(#)debug.c: 2.2 Copyright 90/08/08 13:14:09 Chris Lewis";
  1498. X#endif
  1499. X
  1500. X#ifdef    DEBUG
  1501. X
  1502. Xint debug = 0;
  1503. X
  1504. X#define    D_CAT    1
  1505. X#define    D_SPEC    2
  1506. X#define    D_CHAR    4
  1507. X#define    D_FONT    8
  1508. X#define    D_BEND    0x10
  1509. X#define    D_PK    0x20
  1510. X#define    D_VERB    0x40
  1511. X#define    D_FLSH    0x80
  1512. X
  1513. Xstruct dbm {
  1514. X    char req;
  1515. X    int bit;
  1516. X} dbm[] = {
  1517. X    {'c', D_CAT},
  1518. X    {'s', D_SPEC},
  1519. X    {'C', D_CHAR},
  1520. X    {'f', D_FONT},
  1521. X    {'F', D_FLSH},
  1522. X    {'b', D_BEND},
  1523. X    {'p', D_PK},
  1524. X    {'v', D_VERB},
  1525. X    {'A', ~0},
  1526. X    {0, 0}
  1527. X};
  1528. X
  1529. Xsetdebug(str, df)
  1530. Xchar *str, *df; {
  1531. X    register struct dbm *d;
  1532. X    for(;*str; str++) {
  1533. X    for(d = dbm; d->req; d++)
  1534. X        if (d->req == *str) {
  1535. X        debug |= d->bit;
  1536. X        break;
  1537. X        }
  1538. X    if (!d->req) {
  1539. X        fprintf(stderr, "%s: don't understand %c debug flag\n",
  1540. X        progname, *str);
  1541. X        exit(1);
  1542. X    }
  1543. X    }
  1544. X
  1545. X    if (debug) {
  1546. X    if (!(diagFile = fopen(df, "w"))) {
  1547. X        fprintf(stderr, "%s: Cannot open diagnostics file (%s)\n",
  1548. X        progname, df);
  1549. X        exit(1);
  1550. X    }
  1551. X    fprintf(diagFile, "Debug flags: %x\n", debug);
  1552. X    }
  1553. X}
  1554. X
  1555. X#ifdef VFPRINTF
  1556. X#include <varargs.h>
  1557. X/* VARARGS */
  1558. Xdprintf(level, va_alist)
  1559. Xint level;
  1560. Xva_dcl
  1561. X{
  1562. X    va_list args;
  1563. X    char *fmt;
  1564. X
  1565. X    if (!(debug&level))
  1566. X        return;
  1567. X
  1568. X    va_start(args);
  1569. X    fmt = va_arg(args, char *);
  1570. X    VFPRINTF(diagFile, fmt, args);
  1571. X    va_end(args);
  1572. X    if (debug&D_FLSH)
  1573. X        fflush(diagFile);
  1574. X}
  1575. X#else
  1576. X/* VARARGS1 ARGSUSED */
  1577. Xdprintf(level, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
  1578. Xint level;
  1579. Xchar    *fmt;
  1580. Xint    a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
  1581. X    char buf[BUFSIZ];
  1582. X
  1583. X    if (!(debug&level))
  1584. X        return;
  1585. X
  1586. X    sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  1587. X    fprintf(diagFile, buf);
  1588. X    if (debug&D_FLSH)
  1589. X        fflush(diagFile);
  1590. X}
  1591. X#endif
  1592. X#endif
  1593. X
  1594. Xchar *
  1595. Xmustmalloc(n, msg)
  1596. Xint n;
  1597. Xchar *msg; {
  1598. X    extern char *malloc();
  1599. X    register char *p = malloc((unsigned) n);
  1600. X    if (!p) {
  1601. X    fprintf(stderr, "%s: Out of space! (requesting %d bytes, key: %s)\n",
  1602. X        progname, n, msg);
  1603. X    exit(1);
  1604. X    }
  1605. X    clrarray(p, n);
  1606. X    return(p);
  1607. X}
  1608. X
  1609. X#ifdef    BCOPY
  1610. X/*    "slowish" routines when you don't have memcpy and friends
  1611. X */
  1612. Xbcopy(from, to, len)
  1613. Xregister char *from, *to;
  1614. Xregister int n; {
  1615. X    while(n--)
  1616. X    *to++ = *from++;
  1617. X}
  1618. Xbzero(array, len)
  1619. Xregister char *array;
  1620. Xregister int len; {
  1621. X    while(n--)
  1622. X    *array++ = '\0';
  1623. X}
  1624. X#endif
  1625. !BLOTTO
  1626. -- 
  1627. Chris Lewis, Phone: (416)-294-9253
  1628. UUCP: uunet!utai!lsuc!ecicrl!clewis
  1629. Moderator of the Ferret Mailing List (ferret-request@eci386)
  1630. Psroff mailing list (psroff-request@eci386)
  1631.