#! /usr/bin/perl -P- # -*- Perl -*-
#Copyright (C) 1989, 1990 Free Software Foundation, Inc.
# Written by James Clark (jjc@jclark.uucp)
#This file is part of groff.
#groff is free software; you can redistribute it and/or modify it under
#the terms of the GNU General Public License as published by the Free
#Software Foundation; either version 1, or (at your option) any later
#groff is distributed in the hope that it will be useful, but WITHOUT ANY
#WARRANTY; without even the implied warranty of MERCHANTABILITY or
#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
#You should have received a copy of the GNU General Public License along
#with groff; see the file LICENSE. If not, write to the Free Software
#Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
die "Usage: $prog [-s] [-e encoding] [-i n] [-a angle] afmfile mapfile font\n";
open(AFM
, $afm) || die "Can't open " . $ARGV[0];
if ($field[0] eq "FontName") {
elsif($field[0] eq "ItalicAngle") {
$italic_angle = -$field[1];
elsif ($field[0] eq "KPX") {
elsif ($field[0] eq "italicCorrection") {
$italic_correction{$field[1]} = $field[2];
elsif ($field[0] eq "leftItalicCorrection") {
$left_italic_correction{$field[1]} = $field[2];
elsif ($field[0] eq "subscriptCorrection") {
$subscript_correction{$field[1]} = $field[2];
elsif ($field[0] eq "StartCharMetrics") {
last if ($field[0] eq "EndCharMetrics");
if ($field[$i] eq "WX") {
elsif ($field[$i] eq "N") {
elsif ($field[$i] eq "B") {
elsif ($field[$i] eq "L") {
push(ligatures
, $field[$i + 2]);
while ($i <= $#field && $field[$i] ne ";") {
if (!$opt_e && $c != -1) {
$left_side_bearing{$n} = -$llx;
$right_side_bearing{$n} = $urx - $w;
open(DESC
, "DESC") || die "Can't open DESC";
last if $field[0] eq "charset";
if ($field[0] eq "res") { $resolution = $field[1]; }
if ($field[0] eq "unitwidth") { $unitwidth = $field[1]; }
if ($field[0] eq "sizescale") { $sizescale = $field[1]; }
open(ENCODING
, $opt_e) || die "Can't open $opt_e";
if ($field[1] >= 0 && defined $width{$field[0]}) {
$encoding[$field[1]] = $field[0];
$in_encoding{$field[0]} = 1;
open(MAP
, $map) || die "Can't open $map";
if ($#field == 1 && $in_encoding{$field[0]}) {
if (defined $mapped{$field[1]}) {
warn "Both $mapped{$field[1]} and $field[0] map to $field[1]";
elsif ($field[1] eq "space") {
# the PostScript character `space' is automatically mapped
# to the groff character `space'; this is for grops
warn "you are not allowed to map to the groff character `space'";
elsif ($field[0] eq "space") {
warn "you are not allowed to map the PostScript character `space'";
$map{$field[0],$nmap{$field[0]}} = $field[1];
$mapped{$field[1]} = $field[0];
$italic_angle = $opt_a if $opt_a;
open(FONT
, ">$font") || die "Can't open $font for output";
print("internalname $psname\n") if $psname;
print("special\n") if $opt_s;
printf("slant %g\n", $italic_angle) if $italic_angle != 0;
printf("spacewidth %d\n", do conv
($width{"space"})) if defined $width{"space"};
print("encoding $opt_e\n") if $opt_e;
foreach $lig (@ligatures) {
for ($i = 0; $i <= $#kern1; $i++) {
if ($in_encoding{$c1} == 1 && $nmap{$c1} != 0
&& $in_encoding{$c2} == 1 && $nmap{$c2} != 0) {
for ($j = 0; $j < $nmap{$c1}; $j++) {
for ($k = 0; $k < $nmap{$c2}; $k++) {
# characters taller than asc_boundary are considered to have ascenders
$asc_boundary = $height{"a"} + 50;
# likewise for descenders
$desc_boundary = $depth{"a"} + 50;
if (defined $height{"x"}) {
elsif (defined $height{"alpha"}) {
$xheight = $height{"alpha"};
$italic_angle = $italic_angle*3.14159265358979323846/180.0;
$slant = sin($italic_angle)/cos($italic_angle);
$slant = 0 if $slant < 0;
for ($i = 0; $i < 256; $i++) {
if ($ch ne "" && $ch ne "space") {
$map{$ch,"0"} = "---" if $nmap{$ch} == 0;
$type = 1 if $d > $desc_boundary;
$type += 2 if $h > $asc_boundary;
printf("%s\t%d", $map{$ch,"0"}, do conv
($width{$ch}));
$subscript_correction = 0;
$italic_correction = $right_side_bearing{$ch} + $opt_i;
$italic_correction = 0 if $italic_correction < 0;
$subscript_correction = $slant * $xheight * .8;
$subscript_correction = $italic_correction if
$subscript_correction > $italic_correction;
$left_math_fit = $left_side_bearing{$ch} + $opt_i;
if (defined $italic_correction{$ch}) {
$italic_correction = $italic_correction{$ch};
if (defined $left_italic_correction{$ch}) {
$left_math_fit = $left_italic_correction{$ch};
if (defined $subscript_correction{$ch}) {
$subscript_correction = $subscript_correction{$ch};
if ($subscript_correction != 0) {
printf(",%d,%d", do conv
($h), do conv
($d));
printf(",%d,%d,%d", do conv
($italic_correction),
do conv
($subscript_correction));
elsif ($left_math_fit != 0) {
printf(",%d,%d", do conv
($h), do conv
($d));
printf(",%d,%d", do conv
($italic_correction),
do conv
($left_math_fit));
elsif ($italic_correction != 0) {
printf(",%d,%d", do conv
($h), do conv
($d));
printf(",%d", do conv
($italic_correction));
printf(",%d,%d", do conv
($h), do conv
($d));
# always put the height in to stop groff guessing
printf(",%d", do conv
($h));
printf("\t0%03o\t%s\n", $i, $ch);
for ($j = 1; $j < $nmap{$ch}; $j++) {
printf("%s\t\"\n", $map{$ch,$j});
if ($ch eq "space" && defined $width{"space"}) {
printf("space\t%d\t0\t0%03o\n", do conv
($width{"space"}), $i);
$_[0]*$unitwidth*$resolution/(72*1000*$sizescale) + ($_[0] < 0 ?
-.5 : .5);