home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / cat2deskjet / part02 / rf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-30  |  11.1 KB  |  473 lines

  1. #ifndef lint
  2. static char ScrId[] = "@(#) rf.c:1.3";
  3. #endif
  4.  
  5. /*****************************************************************
  6.  
  7.     Copyright 1985. All Rights Reserved Chris Lewis
  8.  
  9.     Module          : rf.c 1.3
  10.     Date submitted  : 86/01/30 09:19:57
  11.     Author          : Chris Lewis
  12.     Origin          : Permission to copy and further distribute is 
  13.               freely given provided this copyright notice remains 
  14.               intact and that this software is not sold for profit.
  15.     Description     : Description of the file
  16.     Modifications:
  17.  
  18. vp@cui.unige.ch 19.2.90:
  19.     modified to work with downloadble (soft) fonts.  The program
  20.     keeps a record of which fonts have been dent down so that only
  21.     new fonts are downloaded.
  22.  
  23.     the size of the cache shoud be adjusted according to the
  24.     memory available on the printer and the size of the fonts
  25.     used.
  26.  
  27.     BUGS:
  28.           - may work with MSDOS/TURBOC but then again it may not
  29.           - the names of the downloaded fonts should be kept in
  30.         a file so that subsequent programs know about them.
  31.     
  32.  
  33. ******************************************************************/
  34.  
  35. #include <assert.h>
  36. #include <stdio.h>
  37. #include <fcntl.h>
  38. #ifdef UNIX
  39. #include <ctype.h>
  40. #include <vfont.h>
  41. #include <sys/file.h>
  42. #else
  43. #include <alloc.h>
  44. #include <mem.h>
  45. #include <vp/vfont.h>
  46. #endif
  47. #include "lcat.h"
  48.  
  49. extern FILE    *diagFile;
  50. extern FILE    *outFile;
  51. #define    DEBUGPRINTF    if (diagFile) fprintf
  52. #define REGISTER    /**/
  53. static char    *fontFamily;
  54. static char    *djfontFamily;
  55. #define FONTS    "RIBS"
  56. char    fpos[] = FONTS;
  57.  
  58. extern char* ft_getname();
  59.  
  60. #define STD_DPI 300
  61. static int    dpi = STD_DPI;
  62. static int    gl_dpi = STD_DPI;
  63.  
  64. #define MAX_FONT    16
  65. #define SPEC_FONT    3
  66. #define IMG_SIZE    (unsigned int)(50000)
  67.  
  68. /*
  69.  * Construction of font identifier (fid):
  70.  *    Since the fid is 15 bits wide, we can use it to encode information
  71.  *    about the font that will be loaded in that position.
  72.  *        +-+--------+------+-----------+
  73.  *        |X| Family | type | pointsize |
  74.  *        +-+--------+------+-----------+
  75.  *    bits    |1|   6    |   3  |     6     |
  76.  *        +-+--------+------+-----------+
  77.  *    X:    is the sign bit and cannot be used.
  78.  *    Family: is the font family and we use the same numbers as HP
  79.  *        uses for the typeface field in the font control block
  80.  *        (see page 5-10 of developers guide).
  81.  *    Type:    0=normal, 1=italic, 2=bold, 3=special
  82.  *    Pointsize:
  83.  */
  84. #define FID_TIMES    5
  85. #define FID_HELVETICA    4
  86. #define FID_PRESTIGE    8
  87. #define FID_FAMO    9
  88. #define FID_FAMM    0x3f
  89. #define FID_TYPO    6
  90. #define FID_TYPM    0x7
  91. #define FID_PNTO    0
  92. #define FID_PNTM    0x3f
  93.  
  94. static long xpos = -1;
  95. static long ypos = -1;
  96.  
  97. struct ftbl {
  98.     int fnum;    /* number of downloaded font (R=0, I=1, B=2, S=3) */
  99.     int psize;    /* pointsize of font */
  100.     int count;    /* usage counter for LRU caching */
  101.     int used;    /* true if font appears on current page */
  102.     int fid;    /* only used by the MSDOS font cache */
  103.     int lpad_tbl_valid;        /* is left pad table valid? */
  104.     int lpad_tbl[NUM_DISPATCH];    /* left pad table */
  105. } fonttbl[MAX_FONT];
  106.  
  107. /*
  108.  * following vars hold data for selected font
  109.  */
  110. int cfnum, cpsize;
  111. int *clpad_tbl;
  112. struct dispatch *cdsp;
  113. u_char huge* imageTable;
  114. int use_count=1;
  115.  
  116.  
  117. #define TRUE 1
  118. #define FALSE 0
  119. static int new_page = TRUE;
  120. static long y_base;    /* vertical position of baseline for current line */
  121. static long max_up;    /* max height above baseline of glyphs on current line */
  122. static long max_down;    /* max depth below baseline of glyphs on cur line */
  123. static long min_x;    /* left horizontal offset of cur. line */
  124. static long max_x;    /* rightmost position on current line */
  125.  
  126. vf_init(quality, ff, dj)
  127. int quality;
  128. char* ff;
  129. char* dj;
  130. {
  131.     int i, j;
  132.     u_char *vp;
  133.  
  134.     fontFamily = ff;
  135. #ifndef UNIX
  136.     djfontFamily = dj;
  137. #endif
  138.     new_page = TRUE;
  139. /* don't need that any more ...
  140.     if (quality == 2)
  141.         fprintf(outFile, "\033*r1Q");
  142.     else
  143.         fprintf(outFile, "\033*r0Q");
  144. */
  145.     cfnum = -1;
  146.     for (i=0; i < MAX_FONT; i++)
  147.     {
  148.         int fid;
  149.  
  150.         fonttbl[i].fnum = -1;
  151.         fonttbl[i].count = -1;
  152.         fonttbl[i].used = 0;
  153.         fonttbl[i].fid = -1;
  154.         fonttbl[i].lpad_tbl_valid = 0;
  155.  
  156.         if ((fid = ft_getnextent()) > 0)
  157.             if (((fid >> FID_FAMO) & FID_FAMM) == FID_TIMES)
  158.             {
  159.                 fonttbl[i].fnum = ((fid >> FID_TYPO) & FID_TYPM);
  160.                 fonttbl[i].psize = ((fid >> FID_PNTO) & FID_PNTM);
  161.                 fonttbl[i].fid = fid;
  162.                 fonttbl[i].count = 0;
  163.                 fonttbl[i].used = 0;
  164.             }
  165.     }
  166. }
  167.  
  168. /*
  169.  *    loadfont -- load vfont
  170.  *
  171.  */
  172. loadfont(fnum, psize)
  173. int fnum, psize;
  174. {
  175.     int i, c, sel;
  176.  
  177.     if (cfnum == fnum && cpsize == psize)
  178.         return;
  179.     for (i=0; i < MAX_FONT; i++)
  180.     {
  181.         if (fonttbl[i].fnum == fnum && fonttbl[i].psize == psize)
  182.         {
  183.             cfnum = fnum;
  184.             cpsize = psize;
  185.             clpad_tbl = fonttbl[i].lpad_tbl;
  186.             if (!fonttbl[i].lpad_tbl_valid)
  187.             if (!fonttbl[i].lpad_tbl_valid)
  188.             {
  189.                 get_lpad_tbl(fnum, psize, clpad_tbl);
  190.                 fonttbl[i].lpad_tbl_valid = 1;
  191.             }
  192.             fonttbl[i].used = 1;
  193.             fonttbl[i].count = use_count++;
  194.             /* select it */
  195. #ifdef VERBOSE
  196.             printf("Using font %s (%d)\n",
  197.                 ft_getname(fonttbl[i].fid), fonttbl[i].fid);
  198. #endif
  199.             fprintf(outFile, "\033(%dX", fonttbl[i].fid);
  200.             return;
  201.         }
  202.     }
  203.     /* not in downloaded set => load in place of LRU font */
  204.     c = use_count;
  205.     sel = -1;
  206.     for (i=0; i < MAX_FONT; i++)
  207.     {
  208.         if (fonttbl[i].used)
  209.             continue;
  210.         if (fonttbl[i].count < c)
  211.         {
  212.             c = fonttbl[i].count;
  213.             sel = i;
  214.         }
  215.     }
  216.     assert(sel != -1);
  217.  
  218.     /* delete font from printer */
  219.     if (fonttbl[sel].fid != -1)
  220.     {
  221.         fprintf(outFile, "\033*c%D\033*c2D", fonttbl[sel].fid);
  222.         /* delete font from cache table, doesn't matter if its not there */
  223.         printf("deleting font %d\n", fonttbl[sel].fid);
  224.         ft_delent(fonttbl[sel].fid);
  225.     }
  226.     getfont(fnum, psize, sel);
  227.     /* recursively call loadfont to properly select the
  228.      * font we've just loaded.  i.e. retry loadfont operation
  229.      */
  230.     loadfont(fnum, psize);
  231. }
  232.  
  233. /*
  234.  * getfont -- 
  235.  */
  236. getfont(fnum, psize, position)
  237. int fnum, psize, position;
  238. {
  239.     static char fontBuf[BUFSIZ];
  240. #ifdef UNIX
  241.     static char sbuf[BUFSIZ];
  242. #endif
  243.     int fd;        /* file handle for vfont file */
  244.     int i;
  245.     int xx, c;
  246.     FILE* font_fd;
  247.     int fid;
  248.  
  249.     assert(fnum <= (strlen(FONTS)-1));
  250.     fid = (FID_TIMES & FID_FAMM) << FID_FAMO;
  251.     fid |= ((fnum & FID_TYPM) << FID_TYPO);
  252.     fid |= ((psize & FID_PNTM) << FID_PNTO);
  253. #ifdef UNIX
  254.     sprintf(fontBuf, "%s%c.%d", fontFamily, tolower(fpos[fnum]), psize);
  255.     if (access(fontBuf, R_OK) < 0)
  256.     {
  257.         sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
  258.         if (access(fontBuf, R_OK) < 0)
  259.         {
  260.             fprintf(stderr,
  261.                 "lcat: Could not load font %s\n", fontBuf);
  262.             exit(1);
  263.         }
  264.     }
  265.     sprintf(sbuf, "./railmag -s %d0%c -i %d %s",
  266.         psize, fpos[fnum], fid, fontBuf);
  267.     /* fprintf(stderr, "calling %s\n", sbuf); */
  268.     if ((xx = system(sbuf)) != 0)
  269.     {
  270.         fprintf(stderr, "lcat: railmag reported an error (%x)\n", xx);
  271.         exit(1);
  272.     }
  273. #else
  274.     /* Unfortunately MSDOS systems cannot accomodate both
  275.      * programs; instead we have to prepare the DeskJet files in
  276.      * advance, so that here we only need to copy the data
  277.      * to the printer.
  278.      */
  279.     sprintf(fontBuf, "%s%c.%d", djfontFamily, fpos[fnum], psize);
  280.     if ((font_fd = fopen(fontBuf, "rb")) == NULL)
  281.     {
  282.         fprintf(stderr, "lcat: Could not load font %s\n", fontBuf);
  283.         exit(1);
  284.     }
  285.     /* specify font number */
  286.     fprintf(stderr, "Downloading font %s, fid %d\n", fontBuf, fid);
  287.     fprintf(outFile,"\033*c%dD", fid);
  288.     while ((c = getc(font_fd)) != EOF)
  289.         putc(c, outFile);
  290.     fclose(font_fd);
  291.     /* select font and make it permanent */
  292.     fprintf(outFile,"\033*c5F\033(%dX", fid);
  293. #endif
  294.  
  295.     fonttbl[position].fnum = fnum;
  296.     fonttbl[position].psize = psize;
  297.     /* update font table */
  298.     fonttbl[position].fid = fid;
  299.     ft_addent(fid, fontBuf);
  300.     return;
  301. }
  302.  
  303. /*
  304.  *     get_lpad_tbl -- get the left pad bytes for given font
  305.  */
  306.  
  307. get_lpad_tbl(fnum, psize, tbl)
  308. int fnum, psize;
  309. int *tbl;
  310. {
  311.     static char fontBuf[BUFSIZ];
  312.     static struct dispatch dsptbl[NUM_DISPATCH];
  313.     static struct header vf_header;
  314.     int fd;        /* file handle for vfont file */
  315.     int i;
  316.     unsigned int len;
  317.  
  318. #ifdef UNIX
  319.     sprintf(fontBuf, "%s%c.%d", fontFamily, tolower(fpos[fnum]), psize);
  320.     if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
  321.     {
  322.         sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
  323.         if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
  324.         {
  325.             fprintf(stderr,
  326.                 "lcat: Could not load font %s\n", fontBuf);
  327.             exit(1);
  328.         }
  329.     }
  330. #else
  331.     sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
  332.  
  333.     if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
  334.     {
  335.         fprintf(stderr, "lcat: Could not load font %s\n", fontBuf);
  336.         exit(1);
  337.     }
  338. #endif
  339.     fprintf(stderr, "\tLoaded description for %s\n", fontBuf);
  340.     len = sizeof(struct header);
  341.     if (read(fd, &vf_header, len) != len)
  342.     {
  343.         fprintf(stderr, "lcat: Bad font file header\n");
  344.         exit(1);
  345.     }
  346.     if (vf_header.magic != VFONT_MAGIC)
  347.     {
  348.         fprintf(stderr, "lcat: Bad font magic number\n");
  349.         exit(1);
  350.     }
  351.     len = NUM_DISPATCH*sizeof(struct dispatch);
  352.     if (read(fd, dsptbl, len) != len)
  353.     {
  354.         fprintf(stderr, "lcat: Could not load font dispatch table\n");
  355.         exit(1);
  356.     }
  357.     close(fd);
  358.  
  359.     /* tranfer left pads to left pad table */
  360.     for (i=0; i < NUM_DISPATCH; i++)
  361.         tbl[i] = dsptbl[i].left;
  362.     return;
  363. }
  364.  
  365. #define VF_FI    '\01'
  366. #define VF_FL    '\02'
  367. #define VF_FF    '\03'
  368. #define VF_FFL    '\012'
  369. #define VF_FFI    '\011'
  370.  
  371. flashrast(ch, ps, ftype)
  372. int    ch, ps, ftype;
  373. {
  374.     int up, down, left, right;
  375.     char idx;
  376.     register int i,j,H,V;
  377.     u_char huge *bp;
  378.     u_char huge *vp;
  379.     int points;
  380.     long axpos;    /* adjusted xpos (by lpad) */
  381.     long x;
  382.  
  383.     points = (gl_dpi == 150) ? ps>>1: ps;
  384.     if (ftype != cfnum || points != cpsize)
  385.         loadfont(ftype, points);
  386.     idx = (char)((ftype==SPEC_FONT) ? spectab[ch] : asctab[ch]);
  387.     if (clpad_tbl[idx] > 0)
  388.         axpos = xpos - (clpad_tbl[idx] * 2);
  389.     else
  390.         axpos = xpos;
  391. #ifdef USELIGATURES
  392.     /* Unfortunately the code for ligatures doesn't work!
  393.      * Since we have to adjust the spacing of the characters
  394.      * we cannot just send a string (e.g. ffi) to the printer,
  395.      * the spacing will be all wrong.  Also if a font doesn't have
  396.      * ligatures, then the clpad[idx] will be zero, we would have
  397.      * to use the lpad of 'f'.  What I am trying to say that its too
  398.      * much of a bother to implement when you can just ask troff
  399.      * not to generate ligatures (.lg 0).
  400.      */
  401.     /*
  402.      * composite glyphs ff, fi, fl, ffi, ffl get special treatment
  403.      * since they are not available on all fonts.
  404.      */
  405. /*
  406. fprintf(stderr, "ftype %d, ch %o\n", ftype, idx);
  407. */
  408.     if (ftype != SPEC_FONT)
  409.         switch (idx) {
  410.         case VF_FFI:
  411.             fprintf(outFile, "\033&a%ldh%ldVffi", axpos, ypos);
  412.             return;
  413.         case VF_FI:
  414.             fprintf(outFile, "\033&a%ldh%ldVfi", axpos, ypos);
  415.             return;
  416.         case VF_FFL:
  417.             fprintf(outFile, "\033&a%ldh%ldVffl", axpos, ypos);
  418.             return;
  419.         case VF_FL:
  420.             fprintf(outFile, "\033&a%ldh%ldVfl", axpos, ypos);
  421.             return;
  422.         case VF_FF:
  423.             fprintf(outFile, "\033&a%ldh%ldVff", axpos, ypos);
  424.             return;
  425.         }
  426. #endif
  427.     /* if the character is in the unprintable region, escape it */
  428.     if (((idx & 0x7f) < 32) || ((idx & 0x7f) == 0x7f))
  429.         fprintf(outFile, "\033&a%ldh%ldV\033&p1X%c", axpos, ypos, idx);
  430.     else
  431.         fprintf(outFile, "\033&a%ldh%ldV%c", axpos, ypos, idx);
  432. }
  433.  
  434. vf_move(x, y)
  435. long x, y;
  436. {
  437.     xpos = x;
  438.     ypos = y;
  439.     if (new_page)
  440.         new_page = FALSE;
  441. }
  442.  
  443. vf_newpage()
  444. {
  445.     int i;
  446.  
  447.     new_page = TRUE;
  448.     /* mark all fonts as unused */
  449.     for (i=0; i < MAX_FONT; i++)
  450.     {
  451.         fonttbl[i].used = 0;
  452.     }
  453.     /* eject page */
  454.     putc('\f', outFile);
  455. }
  456.  
  457. prt(s, vp, nb, nl)
  458. char *s;
  459. u_char huge* vp;
  460. int nb, nl;
  461. {
  462.     int i;
  463.  
  464.     DEBUGPRINTF(diagFile, "%s= ", s);
  465.     for(i=0; i< nb; i++)
  466.         DEBUGPRINTF(diagFile, "%2x, ", *vp++);
  467.     if (nl)
  468.         DEBUGPRINTF(diagFile, "%2x\n", *vp);
  469.     else
  470.         DEBUGPRINTF(diagFile, "%2x\t", *vp);
  471. }
  472.  
  473.