5 # SFD normalizer (discards GUI information from SFD files)
6 # (c)2004,2005 Stepan Roh (PUBLIC DOMAIN)
7 # usage: ./sfdnormalize.pl sfd_file(s)
8 # will create files with suffix .norm
14 # Flags - discarded O (open), H (changed since last hinting - useless for TTF), M (manual hinting - useless for TTF)
15 # Refer - changed S (selected) to N (not selected)
16 # Fore, Back, SplineSet, Grid
17 # - all points have 4 masked out from flags (selected)
18 # and 256 (do not interpolate)
20 # - discarded (those are Type1 stems = PS hints)
21 # recalculate number of characters and positional encoding
23 # - discarded (temporary)
24 # ModificationTime - discarded
25 # CreationTime - discarded
26 # VWidth - discarded (for now)
29 # Validated - discarded
30 # UndoRedoHistory - discarded
31 # changes making it incompatible with FF older than (approx.) 20050728:
32 # Ref - renamed to Refer
34 # - renamed to KernsSLIFO
36 # !!! Always review changes done by this utility !!!
38 sub process_sfd_file
($);
40 sub process_sfd_file
($) {
43 my $out = $sfd_file . '.norm';
45 open (SFD
, $sfd_file) || die "Unable to open $sfd_file : $!\n";
46 open (OUT
, '>'.$out) || die "Unable to open $out : $!\n";
50 my $in_spline_set = 0;
52 my %pos_glyphs_map = ();
56 next if (/^(WinInfo|DisplaySize|HStem|VStem|ModificationTime|CreationTime|VWidth|TeX|TeXData|Validated|AltUni2):/);
58 s
,^(NameList
:).*$,$1 AGL without afii
,;
60 s
,^KernsSLIF
:,KernsSLIFO
:,;
61 s
,^(Flags
:.*?
)O
(.*)$,$1$2,;
62 s
,^(Flags
:.*?
)H
(.*)$,$1$2,;
63 s
,^(Flags
:.*?
)M
(.*)$,$1$2,;
64 # remove empty Flags line
65 next if (/^Flags:\s*$/);
66 s
,^(Refer
:.*?
)S
(.*)$,$1N$2,;
67 if (/^(Fore|Back|SplineSet|Grid)\s*$/) {
69 } elsif (/^EndSplineSet\s*$/) {
71 } elsif ($in_spline_set) {
72 s/(\s+)(\S+?)(,\S+\s*)$/$1.($2 & ~4 & ~256).$3/e;
73 s/([\s^])-0(\s)/$1."0".$2/eg
75 #remove UndoRedoHistory block
76 if (/^UndoRedoHistory/) {
77 $in_undo_redo = 1; next
78 } elsif (/^EndUndoRedoHistory/) {
79 $in_undo_redo = 0; next
81 next if ($in_undo_redo);
84 } elsif (/^EndChars\s*$/) {
86 # adding of 1 to max_dec_enc is strange, but works
87 # second parameter is set to 0 to avoid merging conflicts (fontforge ignores anyway)
88 print OUT
"BeginChars: ", $max_dec_enc + 1, " 0\n";
89 foreach $glyph (sort { $glyphs{$a}{'dec_enc'} <=> $glyphs{$b}{'dec_enc'} } keys %glyphs) {
90 print OUT
"StartChar: ", $glyphs{$glyph}{'name'}, "\n";
91 my $dec_enc = $glyphs{$glyph}{'dec_enc'};
92 my $mapped_enc = $glyphs{$glyph}{'mapped_enc'};
93 print OUT
"Encoding: ", $dec_enc, " ", $mapped_enc, " ", $dec_enc, "\n";
94 # recalculate references and kerning pairs
95 foreach $l (@
{$glyphs{$glyph}{'lines'}}) {
96 $l =~ s/^(Refer:\s*)(\S+)/$1.(exists $pos_glyphs_map{$2} ? $pos_glyphs_map{$2} : (warn "Glyph $glyph ($dec_enc) has reference to unknown glyph position $2\n", $2))/e;
97 if ($l =~ /^KernsSLIFO:\s*(.*)$/) {
98 my @nums = split(/\s+/, $1);
99 if ((scalar (@nums) % 4) != 0) {
100 warn "Kerning definition in glyph $curchar ($dec_enc) is malformed and won't be remapped\n";
102 for (my $i = 0; $i < scalar (@nums); $i += 4) {
104 if (exists $pos_glyphs_map{$pos}) {
105 $nums[$i] = $pos_glyphs_map{$pos};
107 warn "Glyph $glyph ($dec_enc) has kerning reference to unknown glyph position $pos\n";
111 $l = "KernsSLIFO: " . join(' ', @nums) . "\n";
115 print OUT
"EndChar\n";
118 print OUT
"EndChars\n";
119 } elsif (/^StartChar:\s*(\S+)\s*$/) {
122 while (exists $glyphs{$curchar}) {
125 $glyphs{$curchar}{'name'} = $name;
126 } elsif (/^Encoding:\s*(\d+)\s*((?:-|\d)+)\s*(\d+)\s*$/) {
128 $max_dec_enc = $dec_enc if ($dec_enc > $max_dec_enc);
131 $glyphs{$curchar}{'dec_enc'} = $dec_enc;
132 $glyphs{$curchar}{'mapped_enc'} = $mapped_enc;
133 $glyphs{$curchar}{'pos'} = $pos;
134 if (exists $pos_glyphs_map{$pos}) {
135 warn "Glyph $curchar ($dec_enc) has duplicate glyph position $pos - won't be remapped - possible output corruption!\n";
137 $pos_glyphs_map{$pos} = $dec_enc;
139 } elsif (/^EndChar\s*$/) {
144 } elsif ($curchar eq '') {
145 warn "Malformed input file $sfd_file?";
147 push (@
{$glyphs{$curchar}{'lines'}}, $_);
157 print STDERR
"usage: sfd_files+\n";
163 foreach $sfd_file (@sfd_files) {
164 process_sfd_file
($sfd_file);