From 635dd21d1bb5839c721bef33e93a1a34c413e81f Mon Sep 17 00:00:00 2001 From: oetiker Date: Mon, 19 Jan 2004 23:41:34 +0000 Subject: [PATCH] initial git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@238 a5681a0c-68f1-0310-ab6d-d61299d08faa --- program/src/VeraMono.ttf | Bin 0 -> 49204 bytes program/src/compile_afm.pl | 479 +++++++++++++++++++++++++++++++++++++ 2 files changed, 479 insertions(+) create mode 100644 program/src/VeraMono.ttf create mode 100644 program/src/compile_afm.pl diff --git a/program/src/VeraMono.ttf b/program/src/VeraMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..236056c49e937c730a27f0aae898d56b657e8d6e GIT binary patch literal 49204 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 z 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 literal 0 HcmV?d00001 diff --git a/program/src/compile_afm.pl b/program/src/compile_afm.pl new file mode 100644 index 00000000..3101b31e --- /dev/null +++ b/program/src/compile_afm.pl @@ -0,0 +1,479 @@ +#!/usr/local/bin/perl -w + +require 5.005; +use strict; + +# The glyps list can be downloaded from +# http://partners.adobe.com/asn/developer/type/glyphlist.txt +# This URL is from this page: +# http://partners.adobe.com/asn/developer/type/unicodegn.html +# which is refered from +# http://partners.adobe.com/asn/developer/technotes/fonts.html + +my $onlyHelvetica = 0; + +my %globalName2Unicode; +my %font_code = (); + +my $indent0 = ""; +my $indent1 = " "; +my $indent2 = $indent1 x 3; + +my $q = 0; +my $qU = 0; + +sub read_glyphlist +{ + my $fn ="glyphlist.txt"; + open(FH, $fn) + || die "Can't read $fn\n"; + my %seen = (); + while () { + next if /^\s*#/; + next unless /^([0-9A-F]{4});(\w+);/; + my $unicode = 0 + hex($1); + my $name = $2; + next if ($globalName2Unicode{$name}); + $globalName2Unicode{$name} = $unicode; + } + close(FH); +} + +sub process_all_fonts +{ + my $dir = "."; + my $wc = "*.afm"; + $wc = "Helvetica.afm" if $onlyHelvetica; + $wc = "ZapfDin.afm" if 0; + $wc = "Helve*.afm" if 0; + $wc = "Times-BoldItalic.afm" if 0; + foreach my $fn (glob("$dir/$wc")) { + process_font($fn); + } +} + +sub process_font +{ + my ($fn) = @_; + print STDERR "Compiling afm file: $fn\n"; + my %fi = (); # font info + my $c = ""; + $fi{C} = \$c; + $fi{ligaturesR} = {}; + $fi{FontSpecificUnicodeNameToChar} = {}; + $fi{filename} = $fn; + $fi{filename} =~ s/.*\///; + open(FH, $fn) || die "Can't open $fn\n"; + print STDERR "Reads global font info\n" if $q; + while () { + chomp; + next if /^\s*$/ || /^\s*#/; + last if /^StartCharMetrics/; + next unless (/^(\S+)\s+(\S(.*\S)?)/); + my $id = $1; + my $value = $2; + $value =~ s/\s+/ /g; + $fi{"Afm$id"} = $value; + } + my $fontName = $fi{AfmFontName}; + $c .= "\n\n/* ". ("-" x 66) . "*/\n"; + $c .= "/* FontName: $fontName */\n"; + $c .= "/* FullName: $fi{AfmFullName} */\n"; + $c .= "/* FamilyName: $fi{AfmFamilyName} */\n"; + $fi{cName} = $fontName; + $fi{cName} =~ s/\W/_/g; + my %charMetrics = (); + my %kerning = (); + read_charmetrics(\%fi, \%charMetrics); + while () { + read_kerning(\%fi, \%kerning) if /^StartKernPairs/; + } + if (0) { + my @names = keys %charMetrics; + print STDERR "Did read ", ($#names + 1), " font metrics\n"; + } + write_font(\%fi, \%charMetrics, \%kerning); +} + +sub read_charmetrics +{ + my ($fiR, $charMetricsR) = @_; + print STDERR "Reads char metric info\n" if $q; + my $isZapfDingbats = $$fiR{AfmFontName} eq "ZapfDingbats"; + my $ligaturesR = $$fiR{ligaturesR}; + my %ligatures = (); + my %seenUnicodes = (); + while () { + chomp; + next if /^\s*$/ || /^\s*#/; + last if /^EndCharMetrics/; +#next unless /N S / || /N comma /; +#next unless /N ([sfil]|fi) /; +#print "$_\n"; + my $line = $_; +# C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; + my ($width, $unicode, $name, @charLigatures); + foreach (split/\s*;\s*/, $line) { + if (/^C\s+(-?\d+)/) { + $unicode = 0 + $1; + } elsif (/^N\s+(\w+)/) { + $name = $1; + } elsif (/^WX?\s+(-?\d+)/) { + $width = normalize_width($1, 0); + } elsif (/^L\s+(\w+)\s+(\w+)/) { + push(@charLigatures, $1, $2); + } + } + if ($unicode < 0) { + unless (defined $name) { + print STDERR "Glyph missing name and code: $_\n"; + next; + } + $unicode = name2uni($fiR, $name); + print STDERR "name2uni: $name -> $unicode\n" if $qU && 0; + } elsif (defined $name) { + my $std = $globalName2Unicode{$name}; + if (!defined $std) { + print STDERR "Adds unicode mapping: ", + "$name -> $unicode\n" if $qU; + ${$$fiR{FontSpecificUnicodeNameToChar}}{$name} = $unicode; + } else { + $unicode = $std; + } + } + if (!defined($unicode) || $unicode <= 0) { + next if $isZapfDingbats && $name =~ /^a(\d+)$/; + next if $$fiR{AfmFontName} eq "Symbol" && $name eq "apple"; + print STDERR "Glyph '$name' has unknown unicode: $_\n"; + next; + } + unless (defined $width) { + print STDERR "Glyph '$name' missing width: $_\n"; + next; + } + if ($seenUnicodes{$unicode}) { + print STDERR "Duplicate character: unicode = $unicode, ", + "$name and ", $seenUnicodes{$unicode}, + " (might be due to Adobe charset remapping)\n"; + next; + } + $seenUnicodes{$unicode} = $name; + my %c = (); + $c{name} = $name; + $c{unicode} = $unicode; + $c{width} = $width; + $$charMetricsR{$unicode} = \%c; + $ligatures{$unicode} = \@charLigatures if $#charLigatures >= 0; + } + foreach my $unicode (keys %ligatures) { + my $aR = $ligatures{$unicode}; + my $unicode2 = name2uni($fiR, $$aR[0]); + my $unicode3 = name2uni($fiR, $$aR[1]); + unless ($unicode2) { + print STDERR "Missing ligature char 1: $$aR[0]\n"; + next; + } + unless ($unicode3) { + print STDERR "Missing ligature char 2: $$aR[1]\n"; + next; + } + my $key = sprintf("%04d;%04d", $unicode, $unicode2); + $$ligaturesR{$key} = $unicode3; + } +} + +sub name2uni +{ + my ($fiR, $name) = @_; + my $fontMapR = $$fiR{FontSpecificUnicodeNameToChar}; + return $globalName2Unicode{$name} || $$fontMapR{$name}; +} + +sub read_kerning +{ + my ($fiR, $kerningR) = @_; + print STDERR "Reads kerning info\n" if $q; + while () { + chomp; + next if /^\s*$/ || /^\s*#/; + last if /^EndKernPairs/; + unless (/^KPX\s+(\w+)\s+(\w+)\s+(-?\d+)\s*$/) { + print STDERR "Can't parse kern spec: $_\n"; + next; + } + my $name1 = $1; + my $name2 = $2; + my $delta = normalize_width($3, 1); + next unless $delta; + my $unicode1 = name2uni($fiR, $name1); + my $unicode2 = name2uni($fiR, $name2); + unless ($unicode1 && $unicode2) { + print "Unknown kern pair: $name1 and $name2\n"; + next; + } + my $charR = $$kerningR{$unicode1}; + unless (defined $charR) { + my %c = (); + $charR = \%c; + $$kerningR{$unicode1} = $charR; + } + $$charR{$unicode2} = $delta; + } +} + +sub write_font +{ + my ($fiR, $charMetricsR, $kerningR) = @_; + print STDERR "Writes font\n" if $q; + my $cR = $$fiR{C}; + $$fiR{widthsA} = make_array(); + $$fiR{kerning_indexA} = make_array(); + $$fiR{kerning_dataA} = make_array(); + $$fiR{highchars_indexA} = make_array(); + $$fiR{ligaturesA} = make_array(); + write_font_metrics($fiR, $charMetricsR, $kerningR); + write_ligatures($fiR); + my $widths_count = array_size($$fiR{widthsA}); + my $kerning_index_count = array_size($$fiR{kerning_indexA}); + my $kerning_data_count = array_size($$fiR{kerning_dataA}); + my $highchars_count = array_size($$fiR{highchars_indexA}); + my $ligatures_count = array_size($$fiR{ligaturesA}) / 3; + my $info_code = ""; + my $i2 = $indent2; + my $packedSize = $widths_count + 2 * $kerning_index_count + + $kerning_data_count + 2 * $highchars_count + + 3 * 2 * $ligatures_count; + $info_code .= $indent1 . "{ /* $$fiR{filename} $packedSize bytes */\n"; + $info_code .= $i2 . "\"$$fiR{AfmFontName}\","; + $info_code .= " \"$$fiR{AfmFullName}\",\n"; + $info_code .= $i2 . $$fiR{widthsACName} . ",\n"; + $info_code .= $i2 . $$fiR{kerning_indexACName} . ",\n"; + $info_code .= $i2 . $$fiR{kerning_dataACName} . ",\n"; + $info_code .= $i2 . $$fiR{highchars_indexACName} . ", "; + $info_code .= $highchars_count . ",\n"; + $info_code .= $i2 . $$fiR{ligaturesACName} . ", "; + $info_code .= $ligatures_count; + $info_code .= "},\n"; + $font_code{$$fiR{AfmFullName}} = { TABLES => $$cR, INFO => $info_code}; +} + +sub write_font_metrics +{ + my ($fiR, $charMetricsR, $kerningR) = @_; + print STDERR "Writes font metrics\n" if $q; + my $lastUnicode = 31; + my $cR = $$fiR{C}; + my $widthsA = $$fiR{widthsA}; + my $kerning_indexA = $$fiR{kerning_indexA}; + my $kerning_dataA = $$fiR{kerning_dataA}; + my $highchars_indexA = $$fiR{highchars_indexA}; + my @uniArray = sort { $a <=> $b } keys %$charMetricsR; + my $highchars_count = 0; + my $had_kerning = 0; + while (1) { + my $fill = 0; + if ($#uniArray < 0) { + last if $lastUnicode > 126; + $fill = 1; + } elsif ($lastUnicode < 126 && $uniArray[0] > $lastUnicode + 1) { + $fill = 1; + } + if ($fill) { + $lastUnicode++; +#print STDERR "fill for $lastUnicode, $#uniArray, $uniArray[0]\n"; + append_to_array($widthsA, 0); + append_to_array($kerning_indexA, 0); + next; + } + my $unicode = shift @uniArray; + next if $unicode < 32; + $lastUnicode = $unicode; + my $metricsR = $$charMetricsR{$unicode}; + if ($unicode > 126) { + append_to_array($highchars_indexA, $unicode); + $highchars_count++; + } + my $m = $$metricsR{width}; + $m = "/* ".array_size($widthsA)."=$unicode */". $m if 0; + append_to_array($widthsA, $m); + my $kerningInfoR = $$kerningR{$unicode}; + my $kerning_index = 0; + if (defined $kerningInfoR) { + my @kerns = (); + foreach my $unicode2 (sort { $a <=> $b } keys %$kerningInfoR) { + my $delta = $$kerningInfoR{$unicode2}; + append_escaped_16bit_int(\@kerns, $unicode2); + push(@kerns, $delta); + $had_kerning = 1; + } + $kerning_index = append_8bit_subarray($kerning_dataA, 2, @kerns); + } + append_to_array($kerning_indexA, $kerning_index); + } + $$fiR{kerning_indexA} = make_array() if !$had_kerning; + write_array($fiR, "widths", "afm_cuint8"); + write_array($fiR, "kerning_index", "afm_sint16"); + write_array($fiR, "kerning_data", "afm_cuint8"); + write_array($fiR, "highchars_index", "afm_cuint16"); +} + +sub write_ligatures +{ + my ($fiR) = @_; + print STDERR "Writes font ligatures\n" if $q; + my $ligaturesA = $$fiR{ligaturesA}; + my $ligaturesR = $$fiR{ligaturesR}; + foreach (sort keys %$ligaturesR) { + unless (/^(\w{4});(\w{4})$/) { + die "Invalid ligature key: $_"; + } + append_to_array($ligaturesA, $1 + 0, $2 + 0, $$ligaturesR{$_}); + } + write_array($fiR, "ligatures", "afm_cunicode"); +} + +sub indent +{ + my ($num) = @_; + return " " x $num; +} + +sub make_array +{ + my @a = (); + return \@a; +} + +sub append_to_array +{ + my ($aR, @newElements) = @_; + my $z1 = array_size($aR); + push(@$aR, @newElements); + my $z2 = array_size($aR); + my $zz = $#newElements +1; +} + +sub append_8bit_subarray +{ + my ($aR, $elementsPerItem, @newElements) = @_; + push(@$aR, 42) if !array_size($aR); # initial dummy value + my $idx = $#{$aR} + 1; +#print "append_8bit_subarray ", ($#newElements+1), " = (", join(", ", @newElements), ") -> $idx\n"; + append_escaped_16bit_int($aR, ($#newElements + 1) / $elementsPerItem); + push(@$aR, @newElements); + die "Can't handle that big sub array, sorry...\n" if $idx > 50000; + return $idx; +} + +sub append_escaped_16bit_int +{ + my ($aR, $count) = @_; + die "Invalid count = 0\n" unless $count; + if ($count >= 510) { + push(@$aR, 1, int($count / 256), int($count % 256)); + print STDERR "full: $count\n" if 0; + } elsif ($count >= 254) { + push(@$aR, 0, $count - 254); + print STDERR "semi: $count\n" if 0; + } else { + push(@$aR, $count + 1); + } +} + +sub array_size +{ + my ($aR) = @_; + return $#{$aR} + 1; +} + +sub write_array +{ + my ($fiR, $name, $type) = @_; + my $aR = $$fiR{$name."A"}; + my $cName = $$fiR{cName}; + my $num = $#{$aR} + 1; + my $array_name_key = $name."ACName"; + if ($num == 0) { + $$fiR{$array_name_key} = "NULL"; + return; + } + my $cR = $$fiR{C}; + my $array_name = "afm_" . $cName . "_" . $name; + $$fiR{$array_name_key} = $array_name; + $$cR .= "static $type $array_name" . "[] = { /* $num */\n"; + my $line = $indent1; + for (my $i = 0; $i < $num; $i++) { + $line .= "," if $i > 0; + if (length($line) > 65) { + $line .= "\n"; + $$cR .= $line; + $line = $indent1; + } + $line .= $$aR[$i]; + } + $line .= "\n"; + $$cR .= $line; + $$cR .= "};\n"; +} + +sub normalize_width +{ + my ($w, $signed) = @_; + my $n = int(($w + 3) / 6); + if ($signed) { + $n = -128 if $n < -128; + $n = 127 if $n > 127; + $n = 256 + $n if $n < 0; # make unsigned. + } else { + $n = 0 if $n < 0; + $n = 255 if $n > 255; + } + return $n; +} + +sub main +{ + my $cfn = "../../src/rrd_afm_data.c"; + read_glyphlist(); + process_all_fonts(); + my @fonts = sort keys %font_code; + unless ($#fonts >= 0) { + die "You must have at least 1 font.\n"; + } + open(CFILE, ">$cfn") || die "Can't create $cfn\n"; + print CFILE header($cfn); + print CFILE ${$font_code{$_}}{TABLES} foreach @fonts; + print CFILE "const afm_fontinfo afm_fontinfolist[] = {\n"; + print CFILE ${$font_code{$_}}{INFO} foreach @fonts; + print CFILE $indent1 . "{ 0, 0, 0 }\n"; + print CFILE $indent0 . "};\n"; + print CFILE $indent0 . "const int afm_fontinfo_count = ", + ($#fonts + 1), ";\n"; + close(CFILE); + print STDERR "Compiled ", ($#fonts+1), " fonts.\n"; +} + +sub header +{ + my ($fn) = @_; + $fn =~ s/.*\///; + my $h = $fn; + $h =~ s/\.c$/.h/; + return <<"END"; +/**************************************************************************** + * RRDtool 1.1.x Copyright Tobias Oetiker, 1997 - 2002 + **************************************************************************** + * $fn Encoded afm (Adobe Font Metrics) for selected fonts. + **************************************************************************** + * + * THIS FILE IS AUTOGENERATED BY PERL. DO NOT EDIT. + * + ****************************************************************************/ + +#include "$h" +#include + +END +} + +main(); -- 2.30.2