Viewing file: composeglyphs (13.67 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!no
# Create a composite font program.
# By J. Chroboczek
#
# Copyright (c) 1996-1999 by J. Chroboczek
# This code may be distributed under the terms of the
# GNU Public License, either version 2 of the license, or (at your
# option) any later version.
# Time-stamp: <99/05/14 02:37:45 jec>
$PROGNAME='composeglyphs';
$VERSION='v. 0.7.10 by J. Chroboczek';
sub usage {
local($oldfh)=select(STDERR);
print <<"ALAMAKOTA";
$PROGNAME $VERSION
$PROGNAME -e -E
$PROGNAME -i -o -c -n
-e -t -a
-C
ALAMAKOTA
select($oldfh);
}
sub min {
local($x1,$x2) = @_;
if($x1<=$x2) {
return $x1;
} else {
return $x2;
}
}
sub max {
local($x1,$x2) = @_;
if($x1>=$x2) {
return $x1;
} else {
return $x2;
}
}
# A finite state automaton for parsing AFMs
sub readAFM {
$fontName=('UnknownFont');
local($afmname,$dochars,$doencoding,$docomposites)=@_;
open(AFM,$afmname);
$_=;
if (! (/^StartFontMetrics.*/))
{ die "$afmname is not an Adobe Font Metrics file" ; }
header: while () {
if (/^FontName *(.*)$/) { $fontName=$1 ; }
elsif (/^EncodingScheme *(.*)$/ && $doencoding) {
if ($doencoding eq 'target') {
$encodingName=$1 ;
} else {
$baseEncodingName=$1;
}
} elsif (/^FontBBox *(-?[0-9]*) *(-?[0-9]*) *(-?[0-9]*) *(-?[0-9]*)/) {
@fontBBox=($1,$2,$3,$4);
}
elsif (/^Start/) { reset ; last header ; }
}
afmloop: while (TRUE) {
garbage: while (TRUE) {
if(/^Start([a-zA-Z0-9]*).*/) {
$where=$1;
last garbage;
}
elsif(/^EndFontMetrics.*/) { last afmloop; }
$_=;
}
if ($where eq 'CharMetrics') {
while() {
if (/^EndCharMetrics.*/) { next afmloop ; }
$characterName='Unknown'; $characterCode=-1 ;
@_=split(/ *; */);
@bbox=();
while($_ = $_[0]) {
shift @_ ;
if(/^C *(-?[0-9]*)/) { $characterCode=$1 ; }
elsif(/^CH *([0-9a-fA-F]*)/) { $characterCode=hex($1) ; }
elsif(/^N *([a-zA-Z0-9\.]*)/) { $characterName=$1 ; }
elsif(/^WX *(-?[0-9\.]*)/) { $width=$1; }
elsif(/^B *(-?[0-9]*) *(-?[0-9]*) *(-?[0-9]*) *(-?[0-9]*)/) {
@bbox=($1,$2,$3,$4);
}
}
if($dochars && !defined($characters{$characterName})) {
$characters{$characterName}=$characterName;
$characterIndex[$#characterIndex+1]=$characterName;
$widths{$characterName}=$width;
if($#bbox eq 3) {
$BBox{$characterName}=$characterName;
$BBox{$characterName,0}=$bbox[0];
$BBox{$characterName,1}=$bbox[1];
$BBox{$characterName,2}=$bbox[2];
$BBox{$characterName,3}=$bbox[3];
}
}
if($doencoding && ($characterCode>=0) && ($characterCode<=255)) {
if($doencoding eq 'base') {
$decoding{$characterName}=$characterCode;
$baseEncoding[$characterCode]=$characterName;
} elsif($doencoding eq 'target') {
$encoding[$characterCode]=$characterName;
}
}
}
}
if ($where eq 'KernData') {
while() {
if (/^EndKernData/) { next afmloop ; }
}
}
if ($where eq 'Composites') {
compositeloop: while() {
if (/^EndComposites/) { next afmloop ; }
if (!$docomposites) { next; }
$characterName='Unknown'; $components=0; $currentComponent=0 ;
@_=split(/\s*;\s*/);
while($#_ >= 0) {
$_=$_[0];
shift @_;
if(/^CC *([a-zA-Z0-9\.]*) *([0-9]*)/) {
$characterName=$1;
if(defined($composites{$characterName})) {
next compositeloop;
}
$components=$2;
$compositeIndex[$#compositeIndex+1]=$characterName;
$composites{$characterName}=$components;
}
elsif(/^PCC *([a-zA-Z0-9.]*) *(-?[0-9]*) *(-?[0-9]*)/) {
$composites{$characterName,$currentComponent}=$1;
$composites{$characterName,$currentComponent,'dx'}=$2;
$composites{$characterName,$currentComponent,'dy'}=$3;
$currentComponent=$currentComponent+1;
}
}
if($components!=$currentComponent) {
die "Composite information inconsistent for character $characterName font $fontName";
}
}
}
}
}
# sub readSidebearings {
# local($filename)=$_;
# open(SB,$filename);
# while() {
# if (/^%/) { next ; }
# elsif (/ */) { next ; }
# elsif (/^ *([-_$a-zA-Z0-9]*) *([-_$a-zA-Z0-9]*)* ([0-9]*) *$/) {
# $sidebearings{$1,$2}=$3;
# } else {
# die "Error reading sidebearings data";
# }
# }
# }
sub printEncoding {
print "%!\n";
print "% Automatically generated by the Ogonkify package\n";
print "% Do not modify\n";
print "% -- code follows this line --\n";
print "%%BeginResource: encoding $baseEncodingName\n";
print "/$baseEncodingName [\n";
for($i=0; $i<256; $i++) {
if($i!=0 && $i%64==0) {
printf "%% %o\n", $i;
}
print "/$baseEncoding[$i]";
if($i%8==7) {
print "\n";
} else {
print " ";
}
}
print "] def\n";
print "%%EndResource\n";
}
sub printCAFM {
$shortFontName=$shortnames{$fontName};
if(!$shortFontName) {
$shortFontName=$fontName;
}
$shortEncodingName=$shortnames{$baseEncodingName};
if(!$shortEncodingName) {
$shortEncodingName=$baseEncodingName;
}
print "/* Automatically generated by the Ogonkify package */\n";
print "/* Do not modify */\n";
print "/* -- code follows this line -- */\n";
printf "unsigned int %s_%s_WX [256] = {\n ",
$shortEncodingName,$shortFontName;
for($i=0; $i<256; $i++) {
if(defined($w=$widths{$baseEncoding[$i]})) {
printf "%d",$w;
} else {
print "0";
}
if($i<255) {
if($i%8==7) {
print ",\n ";
} else {
print ", ";
}
}
}
print "\n};\n\n";
}
sub printAFM {
print <<"ALAMAKOTA";
StartFontMetrics 3.0
Comment Automatically generated by the Ogonkify package
Comment Do not modify
FontName $newName
EncodingScheme $encodingName
FullName $newName Composite font
FontBBox $newFontBBox[0] $newFontBBox[1] $newFontBBox[2] $newFontBBox[3]
ALAMAKOTA
$numChars=0;
for($i=0; $i<=$#characterIndex; $i++) {
$charname=$characterIndex[$i];
if($characters{$charname} &&
($decoding{$charname} bool(false)
|