home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / unix / unix_mw2.sha / fonts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-04-26  |  7.9 KB  |  483 lines

  1. #include    <stdio.h>
  2. #include    <ctype.h>
  3.  
  4. #include    "site.h"
  5. #include    "gen.h"
  6. #include    "option.h"
  7. #include    "md.h"
  8. #include    "dvi.h"
  9. #include    "fonts.h"
  10.  
  11. LOCAL    char    * get_tok();
  12. LOCAL    char    * mac_font();
  13.  
  14. /*
  15.  *    translate apple font numbers into something more reasonable
  16.  */
  17. fontno( lptr )
  18. Char    * lptr;
  19.     {
  20.     REG    int    i;
  21.     REG    int    j;
  22.     REG    FONT    * fnt;
  23.  
  24.     char    buf[200];
  25.     char    obuf[200];
  26.     FILE    * fd;
  27.     int    bc, ec;
  28.     int    hlength;
  29.     int    wlength;
  30.     int    dlength;
  31.     int    extra_length;
  32.     int    hdlength;
  33.  
  34.     int    at_size;
  35.     double    ratio;
  36.  
  37.  
  38.     for( i=0; i<MAX_FONTS; i++ )
  39.         {
  40.         if( fonts[i].f_number == -1 )
  41.             break;
  42.         else
  43.         if( fonts[i].f_number == lptr->c_font
  44.         &&  fonts[i].f_size == lptr->c_size
  45.         &&  ( (fonts[i].f_style & ~(ST_UL|ST_SHADOW)) == 
  46.               (lptr->c_style & ~(ST_UL|ST_SHADOW)) )  )
  47.             return( i );
  48.         }
  49.     
  50.     if( i == MAX_FONTS )
  51.         fatal( "too many fonts" );
  52.  
  53.     fnt = &fonts[i];
  54.     
  55.  
  56.     /*
  57.      *    no such font - load one up
  58.      */
  59.  
  60.     at_size = lptr->c_size;
  61.  
  62.     /*    default font is a scaled 10pt font    */
  63.     sprintf( buf, "cm%s10", Style(lptr->c_style) );
  64.     substitute_font( buf, lptr, &at_size );
  65.  
  66.     if( verbose )
  67.         fprintf( stderr, "using font %s at %dpt for MAC font %s\n", 
  68.             buf, at_size, mac_font(lptr) );
  69.  
  70.     strcat( buf, ".tfm" );
  71.  
  72.     fnt->f_number = lptr->c_font;
  73.     fnt->f_size = lptr->c_size;
  74.     fnt->f_style = lptr->c_style;
  75.  
  76.     sprintf( obuf, "%s/%s", TFM_PATH, buf );
  77.  
  78.     buf[strlen(buf)-4] = '\0';
  79.     fnt->f_name = (char *)(strcpy( (char *)malloc(strlen(buf)+1),buf));
  80.  
  81.  
  82.     /*
  83.      *    read in the tfm file
  84.      */
  85.     if( (fd = fopen(obuf, "r")) == NULL )
  86.         fatal( "couldn't open font tfm file %s", obuf );
  87.     
  88.     get_int(fd);            /* lf */
  89.     hdlength = get_int(fd);        /* header data */
  90.     bc = get_int(fd);        /* first character */
  91.     ec = get_int(fd);        /* last character */
  92.     wlength = get_int(fd);        /* lengths of sections */
  93.     hlength = get_int(fd);
  94.     dlength = get_int(fd);
  95.  
  96.     extra_length = get_int(fd) + get_int(fd) +
  97.         get_int(fd) + get_int(fd);    /* length of the rest */
  98.  
  99.     fnt->f_info = (CH_INFO *)malloc( (ec-bc+1) * sizeof(CH_INFO) );
  100.     fnt->f_width = (long *)malloc( wlength * 4 );
  101.     fnt->f_height = (long *)malloc( hlength * 4 );
  102.     fnt->f_depth = (long *)malloc( dlength * 4 );
  103.  
  104.     set( fd, 6 * sizeof(long) );
  105.  
  106.     fnt->f_csum = get_long(fd);
  107.     fnt->f_dsize = fix_to_sp(get_long(fd));
  108.     fnt->f_at_size = pt_to_sp(at_size);
  109.  
  110.     set( fd, (6 + hdlength) * 4 );
  111.  
  112.     for( j=0; j<(ec-bc+1); j++ )
  113.         {
  114.         fnt->f_info[j].ch_windex = get_byte(fd);
  115.         fnt->f_info[j].ch_hindex = get_byte(fd);
  116.         fnt->f_info[j].ch_itindex = get_byte(fd);
  117.         fnt->f_info[j].ch_remainder = get_byte(fd);
  118.         }
  119.     
  120.     for( j=0; j<wlength; j++ )
  121.         fnt->f_width[j] = fix_to_sp(get_long(fd) * at_size);
  122.  
  123.     for( j=0; j<hlength; j++ )
  124.         fnt->f_height[j] = fix_to_sp(get_long(fd) * at_size);
  125.  
  126.     for( j=0; j<dlength; j++ )
  127.         fnt->f_depth[j] = fix_to_sp(get_long(fd) * at_size);
  128.     
  129.     /*
  130.      *    (fix this right) - grab a big character to set the pace
  131.      */
  132.     fnt->f_maxheight = 
  133.         fnt->f_height[(fnt->f_info['['].ch_hindex>>4) & 0xf];
  134.  
  135.     skip( fd, extra_length * 4 );
  136.  
  137.     /*    parameter words    */
  138.     (void)get_long(fd);                    /* slant */
  139.     fnt->f_ws = fix_to_sp(get_long(fd) * at_size);        /* space */
  140.     fnt->f_stretch = fix_to_sp(get_long(fd) * at_size);    /* stretch */
  141.     fnt->f_shrink = fix_to_sp(get_long(fd) * at_size);    /* shrink */
  142.     fnt->f_accent = fix_to_sp(get_long(fd) * at_size);    /* accent */
  143.     (void)get_long(fd);                    /* quad */
  144.     fnt->f_ss = fnt->f_ws + fix_to_sp(get_long(fd) * at_size); /*sentence*/
  145.     
  146.     fclose(fd);
  147.  
  148.     return( i );
  149.  
  150.     }
  151.  
  152. /*
  153.  *    perform font substitutions from a file with the format:
  154.  *
  155.  *    font pointsize style  -> newfont atsize
  156.  */
  157.  
  158. LOCAL    char    *
  159. get_tok( ptr )
  160. REG    char    * * ptr;
  161.     {
  162.  
  163.     char    * pstart = *ptr;
  164.  
  165.     while( **ptr && !isspace( **ptr ) )
  166.         (*ptr)++;
  167.     
  168.     if( **ptr )
  169.         *((*ptr)++) = '\0';
  170.     
  171.     return( pstart );
  172.  
  173.     }
  174.  
  175.  
  176. LOCAL
  177. skip_blank( ptr )
  178. REG    char    * * ptr;
  179.     {
  180.  
  181.     while( **ptr && isspace( **ptr ) )
  182.         (*ptr)++;
  183.     
  184.     return( **ptr != '\0' );
  185.  
  186.     }
  187.  
  188.  
  189.  
  190. substitute_font( buf, cptr, at_size )
  191. char    * buf;
  192. Char    * cptr;
  193. int    * at_size;
  194.     {
  195.     FILE    * fd;
  196.     char    tbuf[200];
  197.     char    * font;
  198.     char    * ptr;
  199.     REG    char    * tok;
  200.     char    *    rc;
  201.     int    fno;
  202.     int    style;
  203.     int    pt;
  204.     int    st;
  205.     int    line_no;
  206.  
  207.     if( !font_sub_file )
  208.         return;
  209.  
  210.     if( (fd = fopen( font_sub_file, "r" )) == NULL )
  211.         {
  212.         warning( "couldn't open substitution file %s", font_sub_file );
  213.         return;
  214.         }
  215.     
  216.     /*    substitute only the rational fonts    */
  217.     style = cptr->c_style & (ST_PLAIN|ST_BOLD|ST_ITALIC);
  218.     
  219.     for( line_no=1; (rc = fgets( tbuf, 200, fd )) != NULL; line_no++ )
  220.         {
  221.  
  222.         if( *tbuf == '#' )
  223.             continue;
  224.  
  225.         st = pt = -1;
  226.         ptr = tbuf;
  227.  
  228.  
  229.         /*
  230.          *    font name or number
  231.          */
  232.         if( !skip_blank( &ptr ) )
  233.             break;
  234.         
  235.         font = get_tok( &ptr );
  236.         if( isdigit( *font ) )
  237.             fno = atoi( font );
  238.         else
  239.             {
  240.             if( (fno = f_ord( font )) < 0 )
  241.                 break;
  242.             }
  243.  
  244.         /*
  245.          *    style or pt size or ->
  246.          */
  247.         if( !skip_blank( &ptr ) )
  248.             break;
  249.  
  250.         tok =  get_tok( &ptr );
  251.  
  252.         /*    could have default style, pt, or both at this point */
  253.         if( strcmp( "->", tok ) != 0 && !isdigit( *tok ) )
  254.             {
  255.             if( (st = st_ord( tok )) < 0 )
  256.                 break;
  257.             
  258.  
  259.             if( !skip_blank( &ptr ) )
  260.                 break;
  261.             
  262.             tok =  get_tok( &ptr );
  263.             }
  264.         
  265.         if( isdigit( *tok ) )
  266.             {
  267.             pt = atoi( tok );
  268.  
  269.  
  270.             if( !skip_blank( &ptr ) )
  271.                 break;
  272.  
  273.             tok = get_tok( &ptr );
  274.             }
  275.  
  276.         /*    gots to have that arrow    */
  277.         if( strcmp( "->", tok ) != 0 )
  278.             break;
  279.         
  280.  
  281.         if( fno == cptr->c_font
  282.         &&  (st == -1 || st == style)
  283.         &&  (pt == -1 || pt == cptr->c_size) )
  284.             {
  285.             /*    match!        */
  286.  
  287.             if( !skip_blank( &ptr ) )
  288.                 break;
  289.             
  290.             strcpy( buf, get_tok( &ptr ) );
  291.  
  292.             if( skip_blank( &ptr ) )
  293.                 *at_size = atoi( get_tok( &ptr ) );
  294.  
  295.             return;
  296.  
  297.             }
  298.         
  299.  
  300.         }
  301.     
  302.     if( rc != NULL )
  303.         warning( "syntax error in font substitution file at line %d",
  304.             line_no );
  305.     
  306.     fclose( fd );
  307.  
  308.     }
  309.  
  310. /*    macintosh predefined fonts */
  311. LOCAL    
  312. char    * macfonts[] =
  313.     {
  314.     "system",
  315.     "application",
  316.     "new_york",
  317.     "geneva",
  318.     "monaco",
  319.     "venice",
  320.     "london",
  321.     "athens",
  322.     "san_fran",
  323.     "toronto",
  324.     };
  325.  
  326. f_ord( font )
  327. char    * font;
  328.     {
  329.  
  330.     char    * * fptr;
  331.  
  332.     for( 
  333.          fptr = macfonts;
  334.          fptr < &macfonts[sizeof(macfonts)/sizeof(char *)];
  335.          fptr++
  336.        )
  337.         if( strcmp( font, *fptr ) == 0 )
  338.             return( fptr - macfonts );
  339.     
  340.     return( -1 );
  341.     
  342.     }
  343.  
  344. st_ord( style )
  345. char    * style;
  346.     {
  347.  
  348.     if( strcmp( "plain", style ) == 0 )
  349.         return( ST_PLAIN );
  350.     
  351.     else
  352.     if( strcmp( "bold", style ) == 0 )
  353.         return( ST_BOLD );
  354.     else
  355.     if( strcmp( "italics", style ) == 0 )
  356.         return( ST_ITALIC );
  357.     else
  358.     if( strcmp( "bold_italics", style ) == 0 )
  359.         return( ST_BOLD | ST_ITALIC );
  360.     
  361.     return( -1 );
  362.  
  363.     }
  364.  
  365.  
  366. /*    print out the name of the macintosh font indicated    */
  367. LOCAL    char *
  368. mac_font( cptr )
  369. Char    * cptr;
  370.     {
  371.     LOCAL    char    buf[40];
  372.  
  373.     if( cptr->c_font >= 0 
  374.     &&  cptr->c_font < (sizeof(macfonts)/sizeof(char *)) )
  375.         strcpy( buf, macfonts[ cptr->c_font ] );
  376.     else
  377.         sprintf( buf, "#%d", cptr->c_font );
  378.     
  379.     if( cptr->c_style & ST_BOLD )
  380.         strcat( buf, " bold" );
  381.     
  382.     if( cptr->c_style & ST_ITALIC )
  383.         strcat( buf, " italic" );
  384.     
  385.     return( buf );
  386.     
  387.     }
  388.  
  389.  
  390.         
  391.  
  392. /*
  393.  *    put a definition of the indicated font into the dvi file
  394.  */
  395.     
  396. def_font( fno )
  397. int    fno;
  398.     {
  399.     REG    int    i;
  400.  
  401.     if( fno < 0 || fno > MAX_FONTS ||
  402.         fonts[fno].f_number < 0 )
  403.         fatal( "unknown font: %d\n", fno );
  404.  
  405.  
  406.     outcmd( DFONT1 );
  407.     out1( fno );
  408.     out4( fonts[fno].f_csum );        /* checksum */
  409.     out4( fonts[fno].f_at_size  );        /* num */
  410.     out4( fonts[fno].f_dsize );        /* denom */
  411.     out1( 0 );                /* use the system fonts */
  412.     out1( strlen( fonts[fno].f_name ) );
  413.     for( i=0; i<strlen(fonts[fno].f_name ); i++ )
  414.         out1( fonts[fno].f_name[i] );
  415.  
  416.     fonts[fno].f_active = TRUE;
  417.     
  418.     }
  419.  
  420.  
  421. SP
  422. font_height( fontno )
  423. int    fontno;
  424.     {
  425.  
  426.     return( fonts[fontno].f_maxheight );
  427.  
  428.     }
  429.  
  430. SP
  431. font_ws( fontno )
  432. int    fontno;
  433.     {
  434.  
  435.     return( fonts[fontno].f_ws );
  436.  
  437.     }
  438.  
  439. SP
  440. font_ss( fontno )
  441.     {
  442.  
  443.     return( fonts[fontno].f_ss );
  444.  
  445.     }
  446.  
  447.  
  448. SP
  449. ch_wid( cptr )
  450. Char    * cptr;
  451.     {
  452.     REG    FONT    * fno;
  453.  
  454.     fno = &fonts[fontno(cptr)];
  455.  
  456.     return(fno->f_width [ (fno->f_info[cptr->c_char]).ch_windex ]);
  457.  
  458.     }
  459.  
  460. SP
  461. ch_height( cptr )
  462. Char    * cptr;
  463.     {
  464.     REG    FONT    * fno;
  465.  
  466.     fno = &fonts[fontno(cptr)];
  467.  
  468.     return( fno->f_height[(fno->f_info[cptr->c_char].ch_hindex>>4) & 0xf] );
  469.  
  470.     }
  471.  
  472. SP
  473. ch_depth( cptr )
  474. Char    * cptr;
  475.     {
  476.     REG    FONT    * fno;
  477.  
  478.     fno = &fonts[fontno(cptr)];
  479.  
  480.     return( fno->f_depth[fno->f_info[cptr->c_char].ch_hindex & 0xf] );
  481.  
  482.     }
  483.