home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / Xtex / x11fonts.c < prev    next >
C/C++ Source or Header  |  1992-04-25  |  7KB  |  294 lines

  1. /*
  2.  * Copyright 1989 Dirk Grunwald
  3.  * 
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of Dirk Grunwald or M.I.T.
  9.  * not be used in advertising or publicity pertaining to distribution of
  10.  * the software without specific, written prior permission.  Dirk
  11.  * Grunwald and M.I.T. makes no representations about the suitability of
  12.  * this software for any purpose.  It is provided "as is" without express
  13.  * or implied warranty.
  14.  * 
  15.  * DIRK GRUNWALD AND M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL M.I.T.  BE LIABLE FOR ANY SPECIAL, INDIRECT
  18.  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  19.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  20.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  21.  * OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * Author:
  24.  *     Dr. Dirk Grunwald
  25.  *     Dept. of Computer Science
  26.  *     Campus Box 430
  27.  *     Univ. of Colorado, Boulder
  28.  *     Boulder, CO 80309
  29.  * 
  30.  *     grunwald@colorado.edu
  31.  *     
  32.  */ 
  33. #include "xtex.h"
  34. #include "dvi-simple.h"
  35. #include "x11fonts.h"
  36. #include "libtex/conv.h"
  37. #include <assert.h>
  38. #include <ctype.h>
  39.  
  40. extern Widget TopLevelWidget;
  41.  
  42. /* font handlers */
  43.  
  44. int MagAtShrink[] =
  45. {-1,
  46.    2489, 2074, 1728, 1440, 1200, 1098, 1000, 500,
  47.    333, 250, 200, 166, 142, 125, 111, 0, -1};
  48.  
  49. #define MAX_SHRINK sizeof(MagAtShrink)/sizeof(int)
  50.  
  51. XFontStruct **FontsAtMag[ MAX_SHRINK + 2 ];
  52.  
  53. int FontRefCnt[ MAX_SHRINK + 2 ];
  54.  
  55.  
  56. XFontStruct **
  57.   TeXFontRef(usermag)
  58. int usermag;
  59. {
  60.   int magSlot;
  61.   
  62.   for ( magSlot = MIN_SHRINK; magSlot <= MAX_SHRINK; magSlot++ ) {
  63.     if ( usermag >= MagAtShrink[ magSlot ] )
  64.       break;
  65.   }
  66.   
  67.   assert( magSlot >= MIN_SHRINK && magSlot <= (MAX_SHRINK+1) );
  68.   
  69.   if ( FontsAtMag[ magSlot ] == 0 ) {
  70.     
  71.     int nameSize;
  72.     char *name;
  73.     char *args[128];
  74.     int argCnt;
  75.     char tmpStr[128];
  76.     int lth;
  77.     int missing;
  78.     
  79.     int font;
  80.     
  81.     XFontStruct **thisMag = (XFontStruct **)
  82.       XtMalloc( sizeof( XFontStruct *) * (RegisteredFonts + 1) );
  83.     
  84.     for ( font = 0; font <= RegisteredFonts; font++ ) {
  85.       thisMag[ font ] = 0;
  86.     }
  87.     
  88.     /* try to load the fonts */
  89.     
  90.     missing = 0;
  91.     
  92.     for (font = 0; font < RegisteredFonts; font++ ) {
  93.       
  94.       /* get the canonical font name */
  95.       
  96.       char tmpStr[128];
  97.       double dvimag = TheFontInfo[font].paf.paf_DVIMag;
  98.       double dvidsz = TheFontInfo[font].paf.paf_DVIDesignSize;
  99.       
  100.       int mag = usermag;
  101.       
  102.       double dscaled
  103.     = (dvimag * (double) ThePostAmbleInfo.pai_DVIMag) / dvidsz;
  104.       int scaled = ROUND(dscaled);
  105.       
  106.       double dsuff
  107.     = ((double) DviDpi * scaled * mag) / ((double) 1000.0 * 1000.0) ;
  108.       int suff = ROUND(dsuff);
  109.       
  110.       int slop;
  111.       int slopCount;
  112.       
  113.       for (slopCount = 0; slopCount < 3; slopCount++ ) {
  114.     int len;
  115.     char *p;
  116.     
  117.     slop = (slopCount > 1) ? -1 : slopCount;
  118.     
  119.     sprintf(tmpStr,"%s.%d",
  120.         TheFontInfo[font].paf.paf_name, (int) suff + slop);
  121.     
  122.     /* convert to lower-case for X */
  123.     
  124.     len = strlen(tmpStr);
  125.     for (p = tmpStr; len > 0; len--, p++) {
  126.       if ( isupper(*p) ) {
  127.         *p = tolower(*p);
  128.       }
  129.     }
  130.  
  131.     /* It seems that, despite the XLoadQueryFont documentation,
  132.        some X implementations will re-load a font even if it is
  133.        already loaded. The NCD X terminal, under xremote, is an
  134.        example.  To avoid delays, specially visible at 9600 bauds,
  135.        we first explicitly check if the font information exists in
  136.        the server, which is an indication that the font is loaded.
  137.  
  138.        Thanks to Martin Beaudoin for discovering this.
  139.      */
  140.  
  141.     thisMag[ font ]
  142.       = XQueryFont( XtDisplay ( TopLevelWidget ), (XID) tmpStr );
  143.     if(thisMag[font]) break;
  144.  
  145.         thisMag[ font ]
  146.             = XLoadQueryFont( XtDisplay ( TopLevelWidget ), tmpStr );
  147.     if (thisMag[font]) break;
  148.     
  149.       }
  150.       
  151.       /*
  152.        * The following added by mjk on 1-14-91 (until next comment),
  153.        * but hacked a lot by dirk -- so don't blame either of us.
  154.        *
  155.        * This code will (optionally) fork a child to create a new font
  156.        */
  157.  
  158.       if ( (thisMag[ font ]  == 0) && (*(xtexResources.makeFont)) ) {
  159.      char buf[1024];
  160.      char *p, *q;
  161.     char *pc;
  162.     
  163.      for (p=xtexResources.makeFont, q=buf; *p; p++)
  164.        if (*p != '%')
  165.          *q++ = *p ;
  166.        else {
  167.          switch (*++p) {
  168.          case 'n' : case 'N' :
  169.            (void)strcpy(q, TheFontInfo[font].paf.paf_name) ;
  170.            break ;
  171.          case 'd' : case 'D' :
  172.            (void)sprintf(q, "%d", suff) ;
  173.            break ;
  174.          case 'b' : case 'B' :
  175.            (void)sprintf(q, "%d", DviDpi) ;
  176.            break ;
  177.          case 'm' : case 'M' :
  178.            (void)sprintf(q, "%d", scaled * mag / 1000) ;
  179.            break;
  180.          case 0 :    *q = 0 ;
  181.            break ;
  182.          default:    *q++ = *p ;
  183.            *q = 0 ;
  184.            break ;
  185.          }
  186.          q += strlen(q) ;
  187.        }
  188.     
  189.      *q = 0 ;
  190.      (void)strcat(buf, " 2>&1") ;
  191.      
  192.      /*    (void)system(buf) ; */
  193.  
  194.     /* Added the automakeFont resource to make all fonts without
  195.        requiring conformation. (MBoyer) */
  196.  
  197.     if (xtexResources.automakeFont)
  198.       pc = buf;
  199.     else
  200.       pc = TeXConfirmString(TopLevelWidget,
  201.                 "Generate Font Using Command:", buf);
  202.  
  203.     if ( pc ) { 
  204.  
  205.       TeXSystemCall(pc);
  206.  
  207.       sprintf(tmpStr,"%s.%d",
  208.           TheFontInfo[font].paf.paf_name, (int) suff);
  209.     
  210.       /* convert to lower-case for X */
  211.       
  212.       { int len;
  213.         char *p;
  214.         
  215.         len = strlen(tmpStr);
  216.         for (p = tmpStr; len > 0; len--, p++) {
  217.           if ( isupper(*p) ) {
  218.         *p = tolower(*p);
  219.           }
  220.         }
  221.        }
  222.      }
  223.      
  224.      thisMag[ font ]
  225.        = XLoadQueryFont( XtDisplay ( TopLevelWidget ), tmpStr );
  226.       }
  227.       /* End of additions */
  228.       
  229.       
  230.       
  231.       if ( thisMag[ font ]  == 0 ) {
  232.     missing++;
  233.     
  234.     /* correct the name of the missing font so it's not off by one */
  235.     
  236.     sprintf(tmpStr,"%s.%d",
  237.         TheFontInfo[font].paf.paf_name, (int) suff);
  238.     
  239.     error(0,0,"Missing %s ( -mag %d -scaled %d %s )",
  240.           tmpStr, mag, scaled, TheFontInfo[font].paf.paf_name);
  241.       }
  242.     }
  243.     
  244.     FontsAtMag[ magSlot ] = thisMag;
  245.   }
  246.   
  247.   FontRefCnt[ magSlot ] ++;
  248.   
  249.   return( FontsAtMag[ magSlot ] );
  250. }
  251.  
  252. XFontStruct **
  253.   TeXFontUnref(usermag)
  254. int usermag;
  255. {
  256.   int magSlot;
  257.   
  258.   for ( magSlot = MIN_SHRINK; magSlot <= MAX_SHRINK; magSlot++ ) {
  259.     if ( usermag >= MagAtShrink[ magSlot ] )
  260.       break;
  261.   }
  262.   
  263.   assert( magSlot >= MIN_SHRINK && magSlot <= MAX_SHRINK );
  264.   
  265.   if ( FontsAtMag [ magSlot]  ) {
  266.     
  267.     FontRefCnt[ magSlot ] --;
  268.     
  269.     if (FontRefCnt[ magSlot ] <= 0 ) {
  270.       int font;
  271.       XFontStruct **fonts = FontsAtMag[magSlot];
  272.       
  273.       /* fonts list is null terminated */
  274.       
  275.       for (font = 0; fonts[ font ] ; font++ ) {
  276.     XFreeFont(XtDisplay( TopLevelWidget ), fonts[font] );
  277.     fonts[ font ] = 0;
  278.       }
  279.       XtFree( (char *)FontsAtMag[ magSlot ] );
  280.       FontsAtMag[ magSlot ] = 0;
  281.       FontRefCnt[ magSlot ] = 0;
  282.     }
  283.   }
  284. }
  285.  
  286. void
  287.   TeXFontNewFile()
  288. {
  289.   int mag;
  290.   for ( mag = 1; mag < MAX_SHRINK ; mag++ ) {
  291.     TeXFontUnref( MagAtShrink[ mag ] );
  292.   }
  293. }
  294.