3 # unihex2png - program to turn a GNU Unifont hex glyph page of 256 code
4 # points into a PNG file
6 # Synopsis: unihex2png [-i in_file.hex] [-o out_file.png]
9 # Author: Paul Hardy, unifoundry <at> unifoundry.com, December 2007
11 # Perl conversion: Andrew Miller, August 2013
14 # Copyright (C) 2007-2008 Paul Hardy
16 # This program is free software: you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation, either version 2 of the License, or
19 # (at your option) any later version.
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program. If not, see <http://www.gnu.org/licenses/>.
32 $result = GetOptions (
34 "input|i=s" => \$input,
35 "output|o=s" => \$output,
37 "rows|r=i" => \$charheight
41 print << "END" or die ("Cannot print to stdout.\n");
43 Turn a GNU Unifont hex glyph page of 256 code points into a PNG file
47 unihex2png -i <Input_File> [-o <Output_File>] [-p <Page>] [-r <Rows>]
49 -i, --input the input hex file (read from STDIN if not specified)
50 -o, --output the output PNG file
51 -p, --page the Unicode page to convert - valid values are
52 0 to 10FF (default is 0)
53 -r, --rows the height of the output glyphs in pixel rows -
54 valid values are 16, 24 and 32 (default is 16)
55 -?, --help display this help and exit
60 unihex2png -i unifont.hex -o u83.png -p 83
67 # die ("No input file specified\n")
71 die ("No output file specified\n")
78 $pagenum = hex ($page);
80 if ($pagenum > 0x10FF) {
81 die ("Invalid page\n");
88 if (not $charheight) {
92 if ($charheight == 16) {
98 } elsif ($charheight == 24) {
104 } elsif ($charheight == 32) {
111 die ("Invalid height\n");
114 # Create box and set as tile pattern
116 $box = new GD::Image ($boxsize, $boxsize);
118 $black = $box->colorAllocate (0, 0, 0);
119 $white = $box->colorAllocate (255, 255, 255);
121 $box->filledRectangle (1, 1, $boxsize - 1, $boxsize - 1, $white);
123 # Draw dots at 8 pixel boundaries
124 for ($count = 0; $count <= $xmax; $count++) {
125 $box->setPixel (($count * 8) + $charxoffset + 1, 0, $white);
126 $box->setPixel (($count * 8) + $charxoffset + 8, 0, $white);
129 for ($count = 0; $count <= $ymax; $count++) {
130 $box->setPixel (0, ($count * 8) + $charyoffset + 1, $white);
131 $box->setPixel (0, ($count * 8) + $charyoffset + 8, $white);
136 $im = new GD::Image ($boxsize * 16 + $gridxoffset, $boxsize * 16 + $gridyoffset);
138 $black = $im->colorAllocate (0, 0, 0);
139 $white = $im->colorAllocate (255, 255, 255);
141 $im->fill (0, 0, $white);
143 for ($xcount = 0; $xcount <= 16; $xcount++) {
144 for ($ycount = 0; $ycount <= 16; $ycount++) {
145 $im->copy ($box, $xcount * $boxsize + $gridxoffset - 1, $ycount * $boxsize + $gridyoffset - 1, 0, 0, $boxsize, $boxsize);
150 $im->string (gdLargeFont, 8, 9, sprintf ('U+%02X', $pagenum >> 8), $black);
153 for ($count = 0; $count <= 15; $count++) {
154 $im->string (gdLargeFont, 32, ($count * $boxsize) + (($boxsize - 16) / 2) + $gridyoffset, sprintf ('%X', $count), $black);
157 # Print column headers
158 for ($count = 0; $count <= 15; $count++) {
159 $im->string (gdLargeFont, ($count * $boxsize) + (($boxsize - 24) / 2) + $gridxoffset, 9, sprintf ('%03X', (($pagenum & 0xFF) << 4) + $count), $black);
163 open (HEXFILE, "$input") or die ('Cannot open hex file for input.\n');
170 @data = split (':', $_);
171 $codepoint = hex ($data[0]);
173 # Calculate if codepoint is within page
174 if ($codepoint >> 8 == $pagenum) {
177 # Calculate character width, column and row
178 $charwidth = length ($char) / $charheight;
180 if ($charwidth <= $charmaxwidth) {
181 $col = ($codepoint >> 4) & 0xF;
182 $row = $codepoint & 0xF;
184 for ($j = 0; $j < $charheight; $j++) {
186 $r = hex (substr ($char, $j * $charwidth, $charwidth));
189 for ($i = 0; $i < $charwidth * 4; $i++) {
191 $im->setPixel (($col * $boxsize) + ($charwidth * 4 - $i) + $charxoffset + $gridxoffset - 1, ($row * $boxsize) + $j + $charyoffset + $gridyoffset, $black);
198 # Only close input file handler if it isn't STDIN.
200 close HEXFILE or die ("Cannot properly close input file.\n");
204 open (PICTURE, ">$output") or die ("Cannot save image.\n");
206 print PICTURE $im->png or die ("Cannot write to picture file.\n");
207 close PICTURE or die ("Cannot properly close output file.\n");