home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / unix / unix_dra.hqx / textimp.c < prev    next >
C/C++ Source or Header  |  1987-02-14  |  8KB  |  357 lines

  1. /* #define DEBUG */
  2. /* #define DEBUG2 */
  3.  
  4. #include "types.h"
  5. #include "pxl.h"
  6. #include <stdio.h>
  7. #include "drawimp.h"
  8.  
  9. #define NFONTS        128    /* max number of fonts */
  10.  
  11. extern int   errno;
  12.  
  13. /* Globals */
  14.  
  15. struct fontinfo {
  16.     struct pxltail *px;        /* pxl file info */
  17.     int     family;        /* Imagen family number (we pick one) */
  18.     int     cwidth[128];    /* width (in DEVs) of each char */
  19.     char    cload[128];        /* flag for ``char loaded into Imagen'' */
  20. };
  21.  
  22. struct fontinfo FontInfo[NFONTS];/* the fonts themselves */
  23. struct fontinfo *CurrentFont;    /* the current font (if any) */
  24. int     NextFamilyNumber = FONT_FAMILY_TOP;
  25.                 /* next available Imagen glyph-family index */
  26. int    numfonts;        /* number of fonts read in so far */
  27.  
  28. char   *TeXfonts;        /* getenv("TEXFONTS") */
  29.  
  30. int     hh;            /* current horizontal position, in DEVs */
  31. int     vv;            /* current vertical position, in DEVs */
  32.  
  33. int    ImHH;            /* Imagen horizontal position */
  34. int    ImVV;            /* Imagen vertical position */
  35. int    ImFamily;        /* Imagen current-font number */
  36.  
  37. double    UserMag;        /* user specified magnification */
  38. double    GlobalMag;        /* overall magnification (UserMag*DVIMag) */
  39. int    IntGlobalMag;        /* ROUND (GlobalMag * 1000.0) */
  40. double    conv;            /* conversion factor for magnified DVI units */
  41.  
  42. double    OneHalf = 0.5;        /* .5, so compiler can generate constant only
  43.                    once */
  44.  
  45. char *getenv (), *malloc ();
  46.  
  47. /* Round a floating point number to integer */
  48. #define ROUND(f) ((int) ((f) + OneHalf))
  49.  
  50. /* Convert a value in sp's to dev's, and vice versa */
  51. #define SPtoDEV(sp)  (ROUND ((sp)  * conv))
  52. #define DEVtoSP(dev) (ROUND ((dev) / conv))
  53.  
  54. static int text_init, sp_size_set, il_size_set;
  55. extern int resolution;
  56. extern int sp_size, tab_size, il_size;
  57. extern FILE *fontfp, *impout();
  58.  
  59. /***********************************************************************/
  60.  
  61. textimp(s,startv,starth,setpos)
  62. char *s;
  63. int startv,starth,setpos;
  64. {
  65.     char ch;
  66.     if (text_init == 0)
  67.         initialize();
  68.     if (setpos) {    /* setpos != 0 to set h,v position and mark BOL */
  69.         hh = starth;
  70.         vv = startv;
  71.         imP_set_bol(hh);
  72.     }
  73.     while ((ch = *s++) != '\0') {
  74.         if (ch & 0x80) {    /* something special */
  75.             ch &= 0x7f;
  76.             if (ch == '\r') {
  77.                 if (il_size != il_size_set)
  78.                     imP_set_il(il_size_set = il_size);
  79.                 imP_crlf();
  80.                 ImVV += il_size;
  81.                 vv += il_size;
  82.             }
  83.             else if (ch == ' ') {
  84.                 if (sp_size != sp_size_set)
  85.                     imP_set_sp(sp_size_set = sp_size);
  86.                 imP_sp();
  87.                 ImHH += sp_size;
  88.                 hh += sp_size;
  89.             }
  90.             else if (ch == '\t') {
  91.                 if (tab_size != sp_size_set)
  92.                     imP_set_sp(sp_size_set = tab_size);
  93.                 imP_sp();
  94.                 ImHH += sp_size;
  95.                 hh += sp_size;
  96.             }
  97.         }
  98.         else {
  99.             DoChar(ch, 1);
  100.         }
  101.     }
  102. }
  103.  
  104. static initialize()
  105. {
  106.     reset_text();
  107.     TeXfonts = getenv ("TEXFONTS");
  108.     if (TeXfonts == 0)
  109.         TeXfonts = "";
  110.     UserMag = ((double) resolution) / 200;
  111.     GlobalMag = UserMag;
  112.     IntGlobalMag = ROUND (GlobalMag * 1000.0);
  113.     conv = (100.0) * (200.0 / 473628672) * GlobalMag;
  114. #ifdef DEBUG
  115.     fprintf(stderr,"TeXfonts=%s\n",TeXfonts);
  116.     fprintf(stderr,"UserMag=%g, GlobalMag=%g, IntGlobalMag=%d\n",
  117.         UserMag, GlobalMag, IntGlobalMag);
  118.     fprintf(stderr,"conv=%g\n",conv);
  119. #endif
  120.     text_init = 1;
  121. }
  122.  
  123. /* This should be called after each output file is complete to make sure
  124. things get set right for the next file.
  125. */
  126. reset_text()
  127. {
  128.     sp_size_set = 0;
  129.     il_size_set = 0;
  130.     ImHH = ImVV = ImFamily = -1;
  131. }
  132.  
  133. /* Resets all fonts to show as not downloaded yet. */
  134. reset_fonts()
  135. {
  136.     int i, j;
  137.     char *cl;
  138.     for (i = 0; i < numfonts; i++) {
  139.         cl = FontInfo[i].cload;
  140.         for (j = 128; j > 0; j--)
  141.             *cl++ = 0;
  142.     }
  143. }
  144.  
  145. /* Given a font file name, find the font table entry for it.  If 'define'
  146.    is nonzero, make an entry for it. */
  147. selectfont(name,at_size,design_size)
  148. char *name;
  149. int at_size, design_size;
  150. {
  151.     char *font;
  152.     struct finder {
  153.         char *name;        /* the font file name */
  154.         struct fontinfo *f;    /* the font info defined for it */
  155.     };
  156.     register struct finder *f, *f1, *f2;
  157.     static struct finder    finder[NFONTS];
  158.  
  159.     if (text_init == 0)
  160.         initialize();
  161.     font = GenPXLFileName(name, at_size, design_size, IntGlobalMag,
  162.         TeXfonts);
  163. #ifdef DEBUG
  164.     fprintf(stderr,"\nLooking for font \"%s\", numfonts=%d\n",
  165.         font,numfonts);
  166. #endif
  167.      /* If there are fonts defined, look around for the given font */
  168.     if (numfonts) {
  169.         register int h, l, m, x;
  170.         h = numfonts - 1;
  171.         l = 0;
  172. #ifdef DEBUG
  173.         for (x = 0; x < numfonts; x++) {
  174.             fprintf(stderr,"%d: id=%d, \"%s\"\n",x,
  175.                 (finder[x].f)->family, finder[x].name);
  176.         }
  177. #endif        
  178.         while (l <= h) {
  179.             f = &finder[m = (l + h) >> 1];
  180.             if ((x = strcmp(f->name, font)) > 0)
  181.                 h = m - 1;
  182.             else if (x < 0)
  183.                 l = m + 1;
  184.             else {
  185.                 CurrentFont = f->f;
  186. #ifdef  DEBUG
  187.                 fprintf(stderr,"Found it, id=%d\n",
  188.                     CurrentFont->family);
  189. #endif
  190.                 return(CurrentFont->family);
  191.             }
  192.         }
  193.         if (l == numfonts)
  194.             f = &finder[numfonts];
  195.     }
  196.     else
  197.         f = finder;
  198.  
  199.  /* f is now where the font should have been found, if anywhere */
  200.  
  201.     f1 = &finder[numfonts];
  202.     if (numfonts > NFONTS)
  203.         error (1, 0, "too many fonts used (%d)", numfonts);
  204.     while (f1 > f) {
  205.         *f1 = *(f2 = f1 - 1);
  206.         f1 = f2;
  207.     }
  208.     f->name = malloc(strlen(font) + 1);
  209.     strcpy(f->name, font);
  210.     CurrentFont = f->f = &FontInfo[numfonts];
  211.     if ((CurrentFont->px = ReadPXLFile(font, 1)) == 0)
  212.         error(1, errno, "can't find font \"%s\"",font);
  213.     ScaleTFMWidths(CurrentFont->px, at_size);
  214.     ComputeCWidths(CurrentFont);
  215.     CurrentFont->family = NextFamilyNumber--;
  216.     numfonts++;
  217. #ifdef DEBUG
  218.     fprintf(stderr,"Font file now loaded, id=%d\n",CurrentFont->family);
  219. #endif
  220. #ifdef DEBUG2
  221.     printwidths(CurrentFont,stderr);
  222. #endif
  223.     return(CurrentFont->family);
  224. }
  225.  
  226. /* Compute the DEV widths of the characters in the given font */
  227. static ComputeCWidths (fi)
  228. struct fontinfo *fi;
  229. {
  230.     register int    i;
  231.     register struct chinfo *ch;
  232.     register int   *cw;
  233.  
  234.     ch = fi -> px -> px_info;
  235.     cw = fi -> cwidth;
  236.     i = 128;
  237.     while (--i >= 0) {
  238.         *cw++ = SPtoDEV (ch -> ch_TFMwidth);
  239.         ch++;
  240.     }
  241. }
  242.  
  243. static DoChar(c, advance)
  244. char c;
  245. int advance;
  246. {
  247.     register struct chinfo *ch;
  248.     register struct fontinfo *cf;
  249.  
  250.     cf = CurrentFont;
  251.     ch = &cf -> px -> px_info[c];
  252.     if (ch -> ch_width != 0) {
  253.         if (!cf -> cload[c])
  254.             DownLoadGlyph (c, ch, cf);
  255.         ImSetPosition(hh, vv);
  256.         if (ImFamily != cf->family) {
  257.             ImFamily = cf->family;
  258.             imP_set_family(ImFamily);
  259.         }
  260.         imP_member(c);
  261.         ImHH += cf -> cwidth[c];  /* where the Imagen thinks we are */
  262.     }
  263.  
  264.     if (advance) {
  265.         hh += cf -> cwidth[c];    /* where we want to be */
  266.     }
  267. }
  268.  
  269. #define RoundUp(n,r) (((n) + ((r) - 1)) & ~((r) - 1))
  270.  
  271. /* Download the character c/ch/cf (also, do rotation if needed) */
  272. static DownLoadGlyph (c, ch, cf)
  273. int c;                /* ordinal value */
  274. register struct chinfo *ch;    /* chinfo for c */
  275. register struct fontinfo *cf;    /* advance amount */
  276. {
  277.     register char  *p;
  278.     register int    i,
  279.                     j,
  280.                     o,
  281.                     w;
  282.     FILE *fp;
  283. /*
  284.     if (!LFlag)
  285.     w = 0;
  286.     else {
  287.     PerformRotation (ch, -90);
  288.     w = 1;
  289.     } */
  290.     w = 0;
  291.  
  292.     fp = impout(fontfp);    /* switch to font file */
  293.  /* Define the character */
  294.     imP_bgly(w,  cf->family, c, cf->cwidth[c],
  295.     ch->ch_width, ch->ch_xoffset,
  296.     ch->ch_height, ch->ch_yoffset, NULL);
  297.  
  298.  /* Now put out the bitmap.  We have to drop any extra ``all blank'' bytes
  299.     that are implied by the definition of the PXL fonts, since the Imagen
  300.     doesn't need (nor want) them. */
  301.     w = (RoundUp (ch -> ch_width, 8) >> 3);
  302.     o = (RoundUp (ch -> ch_width, 32) >> 3) - w;
  303.     p = ch -> ch_raster;
  304.     for (i = ch -> ch_height; --i >= 0;) {
  305.     for (j = w; --j >= 0;)
  306.         imP_member(*p++);
  307.     p += o;
  308.     }
  309.     cf -> cload[c] = 1;        /* it's now loaded */
  310.     impout(fp);
  311. }
  312.  
  313. /* Set the Imagen's h & v positions.  (It's currently at ImHH, ImVV.) */
  314. static ImSetPosition (h, v)
  315. register int h, v;
  316. {
  317.     if (ImHH != h) {
  318.         if (ImHH == h - 1)
  319.             imP_mplus();
  320.         else if (ImHH == h + 1)
  321.             imP_mminus();
  322.         else
  323.             imP_set_abs_h(h);
  324.         ImHH = h;
  325.     }
  326.     if (ImVV != v) {
  327.         imP_set_abs_v(v);
  328.         ImVV = v;
  329.     }
  330. }
  331.  
  332. #ifdef DEBUG2
  333. /* Print out the DEV widths of the characters in the given font */
  334. static printwidths (fi, fp)
  335. struct fontinfo *fi;
  336. FILE *fp;
  337. {
  338.     register int    i, j, k;
  339.     register struct chinfo *ch;
  340.     register int   *cw;
  341.  
  342.     ch = fi -> px -> px_info;
  343.     cw = fi -> cwidth;
  344.     i = 0;
  345.     k = 32;
  346.     while (--k >= 0) {
  347.         j = 4;
  348.         while (--j >= 0) {
  349.             fprintf(fp,"%d: %d %d   ",i++,ch->ch_TFMwidth,*cw);
  350.             cw++;
  351.             ch++;
  352.         }
  353.         fprintf(fp,"\n");
  354.     }
  355. }
  356. #endif
  357.