rule generation machinery
[xfonts-traditional] / utility
CommitLineData
18d2cc90
IJ
1#!/usr/bin/perl -w
2use strict;
3use POSIX;
4use IO::File;
a2d36db5 5use Getopt::Long;
18d2cc90 6
a2d36db5
IJ
7our $package='xfonts-traditional';
8our $sharedir="/usr/share/$package";
9our @rulespath;
10our $mode;
148a1d85
IJ
11our %foundrymap;
12our $verbose=0;
13our $reportfh;
14
15sub reportloaded {
16 return unless $verbose;
17 print $reportfh @_,"\n" or die $!;
18}
18d2cc90 19
4ee8efe0
IJ
20sub loadrules ($) {
21 my ($key) = @_;
18d2cc90 22 our %cache;
18d2cc90
IJ
23 my $fc=$cache{$key};
24 return $fc if $fc;
25 foreach my $path (@rulespath) {
26 my $script="$path/$key.rules";
27 $!=0; $@=''; my $f = do $script;
28 if (defined $f) {
148a1d85 29 reportloaded("rules: loaded ",$script);
18d2cc90
IJ
30 $cache{$key}=$f;
31 return $f;
32 }
33 die "$! $? $script" unless $! == &ENOENT;
34 }
35 return $cache{$key}=undef;
36}
37
148a1d85
IJ
38sub processbdf ($$$) {
39 my ($inbdf,$outbdf,$what) = @_;
4ee8efe0 40 my $state='idle';
148a1d85 41 my ($foundry,$font);
4ee8efe0 42 my ($w,$h,$xo,$yo,$y,$bitmap,$glyph);
148a1d85 43 my $modified=0;
18d2cc90
IJ
44 while (<$inbdf>) {
45 if ($state eq 'bitmap' && $y==$h) {
148a1d85
IJ
46 $glyph = uc $glyph;
47 $glyph =~ s/\;$//;
48 local ($_) = $glyph;
49 my $key= sprintf "%s,%d,%d,%d,%d", $foundry,$w,$h,$xo,$yo;
4ee8efe0 50 my $rules= loadrules($key);
148a1d85 51 return (0,'no rules') if !$rules;
18d2cc90 52 $rules->();
148a1d85 53 $modified += ($_ ne $glyph);
18d2cc90 54 print $outbdf $_,"\n" or die $!
4ee8efe0 55 foreach split /\;/, $_; # /;
18d2cc90
IJ
56 $state='idle';
57 }
58 if ($state eq 'bitmap') {
59 m/^([0-9a-fA-F]+)\s+$/ or die $y;
60 length($1) == (($w+7 >> 3) << 1) or die "$1 $w";
61 $glyph .= "$1;";
4ee8efe0
IJ
62 $y++;
63 next;
18d2cc90 64 }
4ee8efe0 65 if ($state eq 'idle' && m/^FOUNDRY\s+/) {
148a1d85
IJ
66 die if defined $foundry;
67 return (0,'foundry syntax') unless m/^FOUNDRY\s+\"(\w+)\"\s+/;
68 $foundry = $foundrymap{lc $1};
69 return (0,'no foundry') unless defined $foundry;
70 $_ = "FOUNDRY \"$foundry\"\n";
4ee8efe0
IJ
71 }
72 if ($state eq 'idle' && m/^FONT\s+/) {
148a1d85
IJ
73 die if defined $font;
74 return 0 unless m/^(FONT\s+)\-(\w+)\-/;
75 $font = $foundrymap{lc $2};
76 return (0,'no foundry') unless defined $font;
77 $_ = "FONT -$font-$'";
18d2cc90
IJ
78 }
79 if ($state eq 'idle' && m/^STARTCHAR\s/) {
148a1d85
IJ
80 die unless defined $foundry;
81 die unless defined $font;
82 return (0,'foundry != font') unless $foundry eq $font;
18d2cc90
IJ
83 $state='startchar';
84 $w=undef;
85 }
86 if ($state eq 'startchar') {
87 if (m/^BBX\s+(\+?\d+)\s+(\+?\d+)\s+([-+]?\d+)\s+([-+]?\d+)\s+$/) {
88 ($w,$h,$xo,$yo) = ($1,$2,$3,$4);
89 }
90 if (m/^BITMAP\s+$/) {
91 die unless defined $w;
92 $y=0;
93 $glyph='';
94 $state='bitmap';
95 }
96 }
4ee8efe0 97 print $outbdf $_ or die $!;
18d2cc90
IJ
98 }
99 die $! if $inbdf->error;
4ee8efe0 100 die $! if $outbdf->error or !$outbdf->flush;
18d2cc90 101 die unless $state eq 'idle';
148a1d85
IJ
102 if ($modified) {
103 printf $reportfh "%s: %d glyphs changed\n", $what, $modified
104 or die $!;
105 } else {
106 printf $reportfh "%s: unchanged - no rules matched\n", $what
107 or die $!;
108 }
109 return $modified;
18d2cc90
IJ
110}
111
a2d36db5
IJ
112our (@options)=(
113 'R|rules-include=s@' => \@rulespath,
114 'share-dir=s' => \$sharedir,
148a1d85 115 'verbose|v+' => \$verbose,
a2d36db5 116 );
4ee8efe0 117
a2d36db5
IJ
118sub define_mode ($$) {
119 my ($optname,$f) = @_;
120 push @options, $optname, sub {
121 die "only one mode may be specified\n" if defined $mode;
122 $mode=$f;
123 };
124}
125
148a1d85
IJ
126sub loadfoundries () {
127 foreach my $path (@rulespath) {
128 my $p = "$path/foundries";
129 my $f = new IO::File $p;
130 if (!$f) {
131 die "$p $!" unless $!==&ENOENT;
132 print $reportfh "foundries: none in $p\n" or die $! if $verbose;
133 next;
134 }
135 while (<$f>) {
136 s/^\s*//; s/\s+$//;
137 next if m/^\#/;
138 m/^(\w+)\s+(\w+)$/ or die;
139 my $k = lc $1;
140 next if exists $foundrymap{$k};
141 $foundrymap{$k}=$2;
142 }
143 $f->error and die $!;
144 reportloaded('foundries: loaded ',$p);
145 }
146 die "no foundry maps\n" unless %foundrymap;
147}
a2d36db5 148
148a1d85
IJ
149our $stdin = new IO::File '<&STDIN' or die $!;
150our $stdout = new IO::File '>&STDOUT' or die $!;
151our $stderr = new IO::File '>&STDERR' or die $!;
152$reportfh = $stdout;
153
154define_mode('bdf-filter', sub {
155 die "no arguments allowed with --bdf-filter\n" if @ARGV;
156 $reportfh = $stderr;
157 loadfoundries();
158 my $r = processbdf($stdin,$stdout,'stdin');
159 if ($r !~ m/^\d/) {
160 print STDERR "stdin not processed: $r\n";
161 exit 2;
162 }
a2d36db5
IJ
163});
164
165Getopt::Long::Configure(qw(bundling));
166GetOptions(@options) or exit 127;
167
db16069b 168push @rulespath, "$sharedir/rules";
a2d36db5
IJ
169
170die "need a mode\n" unless $mode;
171
172$mode->();
5f15b814
IJ
173
174# 70 zcat /usr/share/fonts/X11/misc/6x13.pcf.gz |pcf2bdf >in.bdf
175# 71 ./utility <in.bdf >out.bdf
176# 83 bdftopcf out.bdf >out.pcf
177# 84 gzip out.pcf
178# 85 cp out.pcf.gz /usr/share/fonts/X11/misc/
179# really mkfontdir /usr/share/fonts/X11/misc/
180# xset fp rehash
181# xfontsel