unifont-7.0.06.tar.gz
[unifont.git] / src / hex2sfd
1 #!/usr/bin/perl
2 #
3 # Copyright (C) 2005 Luis Alejandro Gonzalez Miranda
4 #
5 # hex2sfd created in 2005 by Luis Alejandro Gonzalez Miranda, http://www.lgm.cl
6 #
7 # LICENSE:
8 #
9 #    This program is free software: you can redistribute it and/or modify
10 #    it under the terms of the GNU General Public License as published by
11 #    the Free Software Foundation, either version 2 of the License, or
12 #    (at your option) any later version.
13 #  
14 #    This program is distributed in the hope that it will be useful,
15 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
17 #    GNU General Public License for more details.
18 #  
19 #    You should have received a copy of the GNU General Public License
20 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22 #
23 # June 2008: modifications by Paul Hardy for the Unifont 5.1 build.
24 #
25 # July 2014: modifications by Paul Hardy as follows:
26 #
27 #   - Updated comments to use Luis' full name and add a link to
28 #     the Unifont page on savannah.gnu.org.
29 #   - Store combining character code points for the entire Unicode
30 #     range, not just for the Basic Multilingual Plane.
31 #   - Change "Encoding: UnicodeBmp" by detecting whether the highest
32 #     glyph is in the Basic Multilingual Plane or above that; if above,
33 #     use "Encoding: Unicode" instead.
34 #   - Add explicit definitions for three TrueType code points:
35 #     ".notdef", ".null", and "nonmarkingreturn".  These override
36 #     the defaults that Fontforge creates.  The ".notdef" and
37 #     "nonmarkingreturn" glyphs now have widths of 8 pixels
38 #     (512 units in the SFD output file).
39 #   - Calculate exact number of glyphs in the font for "BeginChars" entry.
40 #   - Convert the pixel outline drawing portion of this script
41 #     to a subroutine.
42 #   - Add "uni" prefix to StartChar description of Unicode code points.
43 #
44 #
45 # Read the list of combining characters, which will have zero width.
46 #
47 @combining = ();
48 for ($i = 0; $i < 0x110000; $i++) {
49    push (@combining, 0);
50 }
51 if ($#ARGV < 0) {
52    open (A, "<", "combining.txt") or die ("Cannot open combining.txt.\n");
53 }
54 else {
55    open (A, "<", $ARGV[0]) or die ("Cannot open specified combining file for input.\n");
56 }
57 $maxcombining = 0;
58 while (<A>) {
59    chomp;
60    $codepoint = hex ($_);
61    $combining[ $codepoint ] = 1;
62    if ($codepoint > $maxcombining) {
63       $maxcombining = $codepoint;
64    }
65 }
66 close (A) or die ("Cannot properly close combining input file.\n");
67
68 $nglyphs    = 0;   # number of glyphs in font (none defined yet)
69 @codepoints = ();  # code points of hex bitmaps
70 @bitmaps    = ();  # the corresponding hex bitmaps
71
72 #
73 # Add three special characters for TrueType; use these instead of
74 # the Fontforge defaults for these three characters.
75 #
76 push (@codepoints, ".notdef");
77 push (@bitmaps,    "0000007E665A5A7A76767E76767E0000");
78 $nglyphs++;
79
80 push (@codepoints, ".null");
81 push (@bitmaps,    "");
82 $nglyphs++;
83
84 push (@codepoints, "nonmarkingreturn");
85 push (@bitmaps,    "00000000000000000000000000000000");
86 $nglyphs++;
87
88 while(<STDIN>) {
89         chomp;
90         ($c,$d) = split (/:/);
91         push (@codepoints, $c);
92         push (@bitmaps,    $d);
93         $nglyphs++;
94 }
95 $max_code_point=$codepoints[ $nglyphs - 1 ];
96
97 # Encoding tag: Is highest glyph above Plane 0?
98 if ($max_code_point > 0xFFFF) {
99    $encoding = "Unicode";
100 }
101 else {
102    $encoding = "UnicodeBmp";
103 }
104
105 #
106 # Modified by Paul Hardy, July 2008.
107 #
108 # Make pixel 64 units for greatest scale; floating point numbers in
109 # TrueType have 6 fractional bits, so this works out well (2^6 = 64).
110 # Also, make size of font a power of 2 (16 * 64) for efficient scaling
111 # to any point size in TrueType.  Made bitmask a variable for easy
112 # experimenting.
113 #
114 $pixel   = 64;
115 $descent = 2 * $pixel;
116 $ascent  = 16 * $pixel - $descent;
117 $bitmask = 25;  # round in x (doesn't really work), corner point selected
118
119 print << "END" or die ("Cannot print to stdout.\n");
120 SplineFontDB: 1.0
121 FontName: unifont
122 FullName: GNU Unifont
123 FamilyName: unifont
124 Weight: Medium
125 Comments: Created from GNU Unifont
126 Comments: with Luis Alejandro Gonzalez Miranda's Perl and FontForge scripts.
127 Comments: See http://www.lgm.cl/trabajos/unifont/index.en.html for
128 Comments: information on Luis' scripts.  See
129 Comments: http://savannah.gnu.org/projects/unifont,
130 Comments: http://czyborra.com/unifont, and
131 Comments: http://unifoundry.com/unifont.html for information on GNU Unifont.
132 Comments: See http://fontforge.sf.net for information on FontForge.
133 Version: 1.00
134 ItalicAngle: 0
135 UnderlinePosition: -100
136 UnderlineWidth: 40
137 Ascent: $ascent
138 Descent: $descent
139 NeedsXUIDChange: 1
140 XUID: [1021 140 1293607838 5610107]
141 FSType: 0
142 PfmFamily: 33
143 TTFWeight: 500
144 TTFWidth: 5
145 Panose: 2 0 6 4 0 0 0 0 0 0
146 LineGap: 72
147 VLineGap: 0
148 OS2WinAscent: 0
149 OS2WinAOffset: 1
150 OS2WinDescent: 0
151 OS2WinDOffset: 1
152 HheadAscent: 0
153 HheadAOffset: 1
154 HheadDescent: 0
155 HheadDOffset: 1
156 ScriptLang: 1
157  1 latn 1 dflt 
158 Encoding: $encoding
159 UnicodeInterp: none
160 DisplaySize: -24
161 AntiAlias: 1
162 FitToEm: 1
163 WinInfo: 0 50 22
164 TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
165 BeginChars: 65536 $nglyphs
166 END
167
168 #
169 # Print outlines for all glyphs using Fontforge's
170 # Spline Font Database (.sfd) format.
171 #
172 # $count=0;  # number of glyphs created so far.
173
174 for ($count = 0; $count < $nglyphs; $count++) {
175         $c = $codepoints[ $count ];
176         $d = $bitmaps[    $count ];
177         outline ($count, $c, $d);
178 }
179
180 # while (<STDIN>) {
181 #       chomp;
182 #       ($c,$d)=split(/:/);
183 #       outline ($count, $c, $d);
184 #       $count++;
185 # }
186
187 print << "END" or die ("Cannot print to stdout.\n");
188 EndChars
189 EndSplineFont
190 END
191
192 exit;
193
194 #
195 # Print the outlines of a glyph's pixels.
196 #
197 # Parameters:
198 #    - Position in font
199 #    - Glyph non-Unicode name or Unicode hexadecimal code point
200 #    - Unifont hexadecimal string to render glyph.
201 #
202 sub outline {
203         my $count = $_[0];
204         my $c     = $_[1];
205         my $d     = $_[2];
206         $width=length($d)/4;
207         $ptwidth=$pixel * $width;
208         if ( $c =~ m/^[0-9A-Fa-f]+$/ ) {
209                 $charname = "uni$c";
210                 if ($combining[ hex($c) ]) {
211                         $ptwidth = 0;
212                 }
213                 $cn = hex ($c);
214         }
215         else {
216                 $charname = $c;
217                 $cn = -1;
218         }
219         # Changed "Flags: H" to "Flags: HW" to fix spaces - Paul Hardy, 2008
220         print << "END" or die ("Cannot print to stdout.\n");
221 StartChar: $charname
222 Encoding: $cn $cn $count
223 Width: $ptwidth
224 Flags: HW
225 TeX: 0 0 0 0
226 Fore
227 END
228
229         for($i=0;$i<16;$i++) {
230                 $l=substr($d, $i*$width/4, $width/4);
231                 $num=hex($l);
232                 $prev=0;
233                 for($j=0; $j<$width; $j++) {
234                         $x=$width - 1 - $j;
235                         $y=15 - $i;
236                         if($num%2) {
237                                 # point at i, width-1-j
238                                 if(!$prev) {
239                                         $x1=$x * $pixel + $pixel;
240                                         $y1=$y * $pixel - $descent;
241                                         $x2=$x1 + $pixel;
242                                         $y2=$y1 + $pixel;
243                                 }
244                                 $prev=1;
245                         } else {
246                                 if($prev) {
247                                         $x2=$x * $pixel + $pixel;
248                                         print << "END" or die ("Cannot print to stdout.\n");
249 $x1 $y1 m $bitmask
250  $x1 $y2 l $bitmask
251  $x2 $y2 l $bitmask
252  $x2 $y1 l $bitmask
253  $x1 $y1 l $bitmask
254 END
255                                 }
256                                 $prev=0;
257                         }
258                         $num=int($num/2);
259                 }
260                 if($prev) {
261                         $x2=0;
262                         print << "END" or die ("Cannot print to stdout.\n");
263 $x1 $y1 m $bitmask
264  $x1 $y2 l $bitmask
265  $x2 $y2 l $bitmask
266  $x2 $y1 l $bitmask
267  $x1 $y1 l $bitmask
268 END
269                 }
270         }
271         print << "END" or die ("Cannot print to stdout.\n");
272 EndSplineSet
273 EndChar
274 END
275
276 }