GNU Unifont 16.0.02
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
unifont1per.c
Go to the documentation of this file.
1/**
2 @file unifont1per.c
3
4 @brief unifont1per - Read a Unifont .hex file from standard input and
5 produce one glyph per ".bmp" bitmap file as output
6
7 @author Paul Hardy, unifoundry <at> unifoundry.com, December 2016
8
9 @copyright Copyright (C) 2016, 2017 Paul Hardy
10
11 Each glyph is 16 pixels tall, and can be 8, 16, 24,
12 or 32 pixels wide. The width of each output graphic
13 file is determined automatically by the width of each
14 Unifont hex representation.
15
16 This program creates files of the form "U+<codepoint>.bmp", 1 per glyph.
17
18 Synopsis: unifont1per < unifont.hex
19*/
20/*
21 LICENSE:
22
23 This program is free software: you can redistribute it and/or modify
24 it under the terms of the GNU General Public License as published by
25 the Free Software Foundation, either version 2 of the License, or
26 (at your option) any later version.
27
28 This program is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
32
33 You should have received a copy of the GNU General Public License
34 along with this program. If not, see <http://www.gnu.org/licenses/>.
35
36 Example:
37
38 mkdir my-bmp
39 cd my-bmp
40 unifont1per < ../glyphs.hex
41
42*/
43
44/*
45 11 May 2019 [Paul Hardy]:
46 - Changed sprintf function call to snprintf for writing
47 "filename" character string.
48 - Defined MAXFILENAME to hold size of "filename" array
49 for snprintf function call.
50*/
51
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55
56/** Maximum size of an input line in a Unifont .hex file - 1. */
57#define MAXSTRING 266
58
59/** Maximum size of a filename of the form "U+%06X.bmp". */
60#define MAXFILENAME 20
61
62
63/**
64 @brief The main function.
65
66 @return This program exits with status EXIT_SUCCESS.
67*/
68int
69main () {
70
71 int i; /* loop variable */
72
73 /*
74 Define bitmap header bytes
75 */
76 unsigned char header [62] = {
77 /*
78 Bitmap File Header -- 14 bytes
79 */
80 'B', 'M', /* Signature */
81 0x7E, 0, 0, 0, /* File Size */
82 0, 0, 0, 0, /* Reserved */
83 0x3E, 0, 0, 0, /* Pixel Array Offset */
84
85 /*
86 Device Independent Bitmap Header -- 40 bytes
87
88 Image Width and Image Height are assigned final values
89 based on the dimensions of each glyph.
90 */
91 0x28, 0, 0, 0, /* DIB Header Size */
92 0x10, 0, 0, 0, /* Image Width = 16 pixels */
93 0xF0, 0xFF, 0xFF, 0xFF, /* Image Height = -16 pixels */
94 0x01, 0, /* Planes */
95 0x01, 0, /* Bits Per Pixel */
96 0, 0, 0, 0, /* Compression */
97 0x40, 0, 0, 0, /* Image Size */
98 0x14, 0x0B, 0, 0, /* X Pixels Per Meter = 72 dpi */
99 0x14, 0x0B, 0, 0, /* Y Pixels Per Meter = 72 dpi */
100 0x02, 0, 0, 0, /* Colors In Color Table */
101 0, 0, 0, 0, /* Important Colors */
102
103 /*
104 Color Palette -- 8 bytes
105 */
106 0xFF, 0xFF, 0xFF, 0, /* White */
107 0, 0, 0, 0 /* Black */
108 };
109
110 char instring[MAXSTRING]; /* input string */
111 int code_point; /* current Unicode code point */
112 char glyph[MAXSTRING]; /* bitmap string for this glyph */
113 int glyph_height=16; /* for now, fixed at 16 pixels high */
114 int glyph_width; /* 8, 16, 24, or 32 pixels wide */
115 char filename[MAXFILENAME];/* name of current output file */
116 FILE *outfp; /* file pointer to current output file */
117
118 int string_index; /* pointer into hexadecimal glyph string */
119 int nextbyte; /* next set of 8 bits to print out */
120
121 /* Repeat for each line in the input stream */
122 while (fgets (instring, MAXSTRING - 1, stdin) != NULL) {
123 /* Read next Unifont ASCII hexadecimal format glyph description */
124 sscanf (instring, "%X:%s", &code_point, glyph);
125 /* Calculate width of a glyph in pixels; 4 bits per ASCII hex digit */
126 glyph_width = strlen (glyph) / (glyph_height / 4);
127 snprintf (filename, MAXFILENAME, "U+%06X.bmp", code_point);
128 header [18] = glyph_width; /* bitmap width */
129 header [22] = -glyph_height; /* negative height --> draw top to bottom */
130 if ((outfp = fopen (filename, "w")) != NULL) {
131 for (i = 0; i < 62; i++) fputc (header[i], outfp);
132 /*
133 Bitmap, with each row padded with zeroes if necessary
134 so each row is four bytes wide. (Each row must end
135 on a four-byte boundary, and four bytes is the maximum
136 possible row length for up to 32 pixels in a row.)
137 */
138 string_index = 0;
139 for (i = 0; i < glyph_height; i++) {
140 /* Read 2 ASCII hexadecimal digits (1 byte of output pixels) */
141 sscanf (&glyph[string_index], "%2X", &nextbyte);
142 string_index += 2;
143 fputc (nextbyte, outfp); /* write out the 8 pixels */
144 if (glyph_width <= 8) { /* pad row with 3 zero bytes */
145 fputc (0x00, outfp); fputc (0x00, outfp); fputc (0x00, outfp);
146 }
147 else { /* get 8 more pixels */
148 sscanf (&glyph[string_index], "%2X", &nextbyte);
149 string_index += 2;
150 fputc (nextbyte, outfp); /* write out the 8 pixels */
151 if (glyph_width <= 16) { /* pad row with 2 zero bytes */
152 fputc (0x00, outfp); fputc (0x00, outfp);
153 }
154 else { /* get 8 more pixels */
155 sscanf (&glyph[string_index], "%2X", &nextbyte);
156 string_index += 2;
157 fputc (nextbyte, outfp); /* write out the 8 pixels */
158 if (glyph_width <= 24) { /* pad row with 1 zero byte */
159 fputc (0x00, outfp);
160 }
161 else { /* get 8 more pixels */
162 sscanf (&glyph[string_index], "%2X", &nextbyte);
163 string_index += 2;
164 fputc (nextbyte, outfp); /* write out the 8 pixels */
165 } /* glyph is 32 pixels wide */
166 } /* glyph is 24 pixels wide */
167 } /* glyph is 16 pixels wide */
168 } /* glyph is 8 pixels wide */
169
170 fclose (outfp);
171 }
172 }
173
174 exit (EXIT_SUCCESS);
175}
#define MAXFILENAME
Definition: unifont1per.c:60
#define MAXSTRING
Definition: unifont1per.c:57
int main()
The main function.
Definition: unifont1per.c:69