home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / groff / devices / devps / afmtodit < prev    next >
Encoding:
Text File  |  1991-04-30  |  7.7 KB  |  311 lines

  1. #! /usr/bin/perl -P- # -*- Perl -*-
  2. #Copyright (C) 1989, 1990 Free Software Foundation, Inc.
  3. #     Written by James Clark (jjc@jclark.uucp)
  4. #
  5. #This file is part of groff.
  6. #
  7. #groff is free software; you can redistribute it and/or modify it under
  8. #the terms of the GNU General Public License as published by the Free
  9. #Software Foundation; either version 1, or (at your option) any later
  10. #version.
  11. #
  12. #groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. #WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. #FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. #for more details.
  16. #
  17. #You should have received a copy of the GNU General Public License along
  18. #with groff; see the file LICENSE.  If not, write to the Free Software
  19. #Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. $prog = $0;
  22.  
  23. do 'getopts.pl';
  24. do Getopts('e:sd:i:a:');
  25.  
  26. if ($#ARGV != 2) {
  27.     die "Usage: $prog [-s] [-e encoding] [-i n] [-a angle] afmfile mapfile font\n";
  28. }
  29.  
  30. $afm = $ARGV[0];
  31. $map = $ARGV[1];
  32. $font = $ARGV[2];
  33.  
  34. # read the afm file
  35.  
  36. open(AFM, $afm) || die "Can't open " . $ARGV[0];
  37.  
  38. while (<AFM>) {
  39.     chop;
  40.     @field = split(' ');
  41.     if ($field[0] eq "FontName") {
  42.     $psname = $field[1];
  43.     }
  44.     elsif($field[0] eq "ItalicAngle") {
  45.     $italic_angle = -$field[1];
  46.     }
  47.     elsif ($field[0] eq "KPX") {
  48.     if ($#field == 3) {
  49.         push(kern1, $field[1]);
  50.         push(kern2, $field[2]);
  51.         push(kernx, $field[3]);
  52.     }
  53.     }
  54.     elsif ($field[0] eq "italicCorrection") {
  55.     $italic_correction{$field[1]} = $field[2];
  56.     }
  57.     elsif ($field[0] eq "leftItalicCorrection") {
  58.     $left_italic_correction{$field[1]} = $field[2];
  59.     }
  60.     elsif ($field[0] eq "subscriptCorrection") {
  61.     $subscript_correction{$field[1]} = $field[2];
  62.     }
  63.     elsif ($field[0] eq "StartCharMetrics") {
  64.     while (<AFM>) {
  65.         @field = split(' ');
  66.         last if ($field[0] eq "EndCharMetrics");
  67.         if ($field[0] eq "C") {
  68.         $c = -1;
  69.         $wx = 0;
  70.         $n = "";
  71.         $lly = 0;
  72.         $ury = 0;
  73.         $llx = 0;
  74.         $urx = 0;
  75.         $c = $field[1];
  76.         $i = 2;
  77.         while ($i <= $#field) {
  78.             if ($field[$i] eq "WX") {
  79.             $w = $field[$i + 1];
  80.             $i += 2;
  81.             }
  82.             elsif ($field[$i] eq "N") {
  83.             $n = $field[$i + 1];
  84.             $i += 2;
  85.             }
  86.             elsif ($field[$i] eq "B") {
  87.             $llx = $field[$i + 1];
  88.             $lly = $field[$i + 2];
  89.             $urx = $field[$i + 3];
  90.             $ury = $field[$i + 4];
  91.             $i += 5;
  92.             }
  93.             elsif ($field[$i] eq "L") {
  94.             push(ligatures, $field[$i + 2]);
  95.             $i += 3;
  96.             }
  97.             else {
  98.             while ($i <= $#field && $field[$i] ne ";") {
  99.                 $i++;
  100.             }
  101.             $i++;
  102.             }
  103.         }
  104.         if (!$opt_e && $c != -1) {
  105.             $encoding[$c] = $n;
  106.             $in_encoding{$n} = 1;
  107.         }
  108.         $width{$n} = $w;
  109.         $height{$n} = $ury;
  110.         $depth{$n} = -$lly;
  111.         $left_side_bearing{$n} = -$llx;
  112.         $right_side_bearing{$n} = $urx - $w;
  113.         }
  114.     }
  115.     }
  116. }
  117. close(AFM);
  118.  
  119. # read the DESC file
  120.  
  121. $sizescale = 1;
  122.  
  123. open(DESC, "DESC") || die "Can't open DESC";
  124. while (<DESC>) {
  125.     next if /^#/;
  126.     chop;
  127.     @field = split(' ');
  128.     last if $field[0] eq "charset";
  129.     if ($field[0] eq "res") { $resolution = $field[1]; }
  130.     if ($field[0] eq "unitwidth") { $unitwidth = $field[1]; }
  131.     if ($field[0] eq "sizescale") { $sizescale = $field[1]; }
  132. }
  133. close(DESC);
  134.  
  135. if ($opt_e) {
  136.     # read the encoding file
  137.     
  138.     open(ENCODING, $opt_e) || die "Can't open $opt_e";
  139.     while (<ENCODING>) {
  140.     chop;
  141.     @field = split(' ');
  142.     if ($#field == 1) {
  143.         if ($field[1] >= 0 && defined $width{$field[0]}) {
  144.         $encoding[$field[1]] = $field[0];
  145.         $in_encoding{$field[0]} = 1;
  146.         }
  147.     }
  148.     }
  149.     close(ENCODING);
  150. }
  151.  
  152. # read the map file
  153.  
  154. open(MAP, $map) || die "Can't open $map";
  155. while (<MAP>) {
  156.     next if /^#/;
  157.     chop;
  158.     @field = split(' ');
  159.     if ($#field == 1 && $in_encoding{$field[0]}) {
  160.     if (defined $mapped{$field[1]}) {
  161.         warn "Both $mapped{$field[1]} and $field[0] map to $field[1]";
  162.     }
  163.     elsif ($field[1] eq "space") {
  164.         # the PostScript character `space' is automatically mapped
  165.         # to the groff character `space'; this is for grops
  166.         warn "you are not allowed to map to the groff character `space'";
  167.     }
  168.     elsif ($field[0] eq "space") {
  169.         warn "you are not allowed to map the PostScript character `space'";
  170.     }
  171.     else {
  172.         $nmap{$field[0]} += 0;
  173.         $map{$field[0],$nmap{$field[0]}} = $field[1];
  174.         $nmap{$field[0]} += 1;
  175.         $mapped{$field[1]} = $field[0];
  176.     }
  177.     }
  178. }
  179. close(MAP);
  180.  
  181. $italic_angle = $opt_a if $opt_a;
  182.  
  183. # print it all out
  184.  
  185. open(FONT, ">$font") || die "Can't open $font for output";
  186. select(FONT);
  187.  
  188. print("name $font\n");
  189. print("internalname $psname\n") if $psname;
  190. print("special\n") if $opt_s;
  191. printf("slant %g\n", $italic_angle) if $italic_angle != 0;
  192. printf("spacewidth %d\n", do conv($width{"space"})) if defined $width{"space"};
  193. print("encoding $opt_e\n") if $opt_e;
  194.  
  195. if ($#ligatures >= 0) {
  196.     print("ligatures");
  197.     foreach $lig (@ligatures) {
  198.     print(" $lig");
  199.     }
  200.     print(" 0\n");
  201. }
  202.  
  203. if ($#kern1 >= 0) {
  204.     print("kernpairs\n");
  205.     
  206.     for ($i = 0; $i <= $#kern1; $i++) {
  207.     $c1 = $kern1[$i];
  208.     $c2 = $kern2[$i];
  209.     if ($in_encoding{$c1} == 1 && $nmap{$c1} != 0
  210.         && $in_encoding{$c2} == 1 && $nmap{$c2} != 0) {
  211.         for ($j = 0; $j < $nmap{$c1}; $j++) {
  212.         for ($k = 0; $k < $nmap{$c2}; $k++) {
  213.             printf("%s %s %d\n",
  214.                $map{$c1,$j},
  215.                $map{$c2,$k},
  216.                do conv($kernx[$i]));
  217.         }
  218.         }
  219.     }
  220.     }
  221. }
  222.  
  223. # characters taller than asc_boundary are considered to have ascenders
  224. $asc_boundary = $height{"a"} + 50;
  225.  
  226. # likewise for descenders
  227. $desc_boundary = $depth{"a"} + 50;
  228. if (defined $height{"x"}) {
  229.     $xheight = $height{"x"};
  230. }
  231. elsif (defined $height{"alpha"}) {
  232.     $xheight = $height{"alpha"};
  233. }
  234. else {
  235.     $xheight = 450;
  236. }
  237.  
  238. $italic_angle = $italic_angle*3.14159265358979323846/180.0;
  239. $slant = sin($italic_angle)/cos($italic_angle);
  240. $slant = 0 if $slant < 0;
  241.  
  242. print("charset\n");
  243. for ($i = 0; $i < 256; $i++) {
  244.     $ch = $encoding[$i];
  245.     if ($ch ne "" && $ch ne "space") {
  246.     $map{$ch,"0"} = "---" if $nmap{$ch} == 0;
  247.     $type = 0;
  248.     $h = $height{$ch};
  249.     $h = 0 if $h < 0;
  250.     $d = $depth{$ch};
  251.     $d = 0 if $d < 0;
  252.     $type = 1 if $d > $desc_boundary;
  253.     $type += 2 if $h > $asc_boundary;
  254.     printf("%s\t%d", $map{$ch,"0"}, do conv($width{$ch}));
  255.     $italic_correction = 0;
  256.     $left_math_fit = 0;
  257.     $subscript_correction = 0;
  258.     if (defined $opt_i) {
  259.         $italic_correction = $right_side_bearing{$ch} + $opt_i;
  260.         $italic_correction = 0 if $italic_correction < 0;
  261.         $subscript_correction = $slant * $xheight * .8;
  262.         $subscript_correction = $italic_correction if
  263.         $subscript_correction > $italic_correction;
  264.         $left_math_fit = $left_side_bearing{$ch} + $opt_i;
  265.     }
  266.     if (defined $italic_correction{$ch}) {
  267.         $italic_correction = $italic_correction{$ch};
  268.     }
  269.     if (defined $left_italic_correction{$ch}) {
  270.         $left_math_fit = $left_italic_correction{$ch};
  271.     }
  272.     if (defined $subscript_correction{$ch}) {
  273.         $subscript_correction = $subscript_correction{$ch};
  274.     }
  275.     if ($subscript_correction != 0) {
  276.         printf(",%d,%d", do conv($h), do conv($d));
  277.         printf(",%d,%d,%d", do conv($italic_correction),
  278.            do conv($left_math_fit),
  279.            do conv($subscript_correction));
  280.     }
  281.     elsif ($left_math_fit != 0) {
  282.         printf(",%d,%d", do conv($h), do conv($d));
  283.         printf(",%d,%d", do conv($italic_correction),
  284.            do conv($left_math_fit));
  285.     }
  286.     elsif ($italic_correction != 0) {
  287.         printf(",%d,%d", do conv($h), do conv($d));
  288.         printf(",%d", do conv($italic_correction));
  289.     }
  290.     elsif ($d != 0) {
  291.         printf(",%d,%d", do conv($h), do conv($d));
  292.     }
  293.     else {
  294.         # always put the height in to stop groff guessing
  295.         printf(",%d", do conv($h));
  296.     }
  297.     printf("\t%d", $type);
  298.     printf("\t0%03o\t%s\n", $i, $ch);
  299.     for ($j = 1; $j < $nmap{$ch}; $j++) {
  300.         printf("%s\t\"\n", $map{$ch,$j});
  301.     }
  302.     }
  303.     if ($ch eq "space" && defined $width{"space"}) {
  304.     printf("space\t%d\t0\t0%03o\n", do conv($width{"space"}), $i);
  305.     }
  306. }
  307.  
  308. sub conv {
  309.     $_[0]*$unitwidth*$resolution/(72*1000*$sizescale) + ($_[0] < 0 ? -.5 : .5);
  310. }
  311.