GNU Unifont: src/unifont1per.c Source File

GNU Unifont 17.0.04 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 6 September 2025 [Paul Hardy]:
52 - Changed code_point and nextbyte from "int" to "unsigned" for
53 compatibility with sscanf definition.
54*/
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59
60/** Maximum size of an input line in a Unifont .hex file - 1. */
61#define MAXSTRING 266
62
63/** Maximum size of a filename of the form "U+%06X.bmp". */
64#define MAXFILENAME 20
65
66
67/**
68 @brief The main function.
69
70 @return This program exits with status EXIT_SUCCESS.
71*/
72int
73main (void) {
74
75 int i; /* loop variable */
76
77 /*
78 Define bitmap header bytes
79 */
80 unsigned char header [62] = {
81 /*
82 Bitmap File Header -- 14 bytes
83 */
84 'B', 'M', /* Signature */
85 0x7E, 0, 0, 0, /* File Size */
86 0, 0, 0, 0, /* Reserved */
87 0x3E, 0, 0, 0, /* Pixel Array Offset */
88
89 /*
90 Device Independent Bitmap Header -- 40 bytes
91
92 Image Width and Image Height are assigned final values
93 based on the dimensions of each glyph.
94 */
95 0x28, 0, 0, 0, /* DIB Header Size */
96 0x10, 0, 0, 0, /* Image Width = 16 pixels */
97 0xF0, 0xFF, 0xFF, 0xFF, /* Image Height = -16 pixels */
98 0x01, 0, /* Planes */
99 0x01, 0, /* Bits Per Pixel */
100 0, 0, 0, 0, /* Compression */
101 0x40, 0, 0, 0, /* Image Size */
102 0x14, 0x0B, 0, 0, /* X Pixels Per Meter = 72 dpi */
103 0x14, 0x0B, 0, 0, /* Y Pixels Per Meter = 72 dpi */
104 0x02, 0, 0, 0, /* Colors In Color Table */
105 0, 0, 0, 0, /* Important Colors */
106
107 /*
108 Color Palette -- 8 bytes
109 */
110 0xFF, 0xFF, 0xFF, 0, /* White */
111 0, 0, 0, 0 /* Black */
112 };
113
114 char instring[MAXSTRING]; /* input string */
115 unsigned code_point; /* current Unicode code point */
116 char glyph[MAXSTRING]; /* bitmap string for this glyph */
117 int glyph_height=16; /* for now, fixed at 16 pixels high */
118 int glyph_width; /* 8, 16, 24, or 32 pixels wide */
119 char filename[MAXFILENAME];/* name of current output file */
120 FILE *outfp; /* file pointer to current output file */
121
122 int string_index; /* pointer into hexadecimal glyph string */
123 unsigned nextbyte; /* next set of 8 bits to print out */
124
125 /* Repeat for each line in the input stream */
126 while (fgets (instring, MAXSTRING - 1, stdin) != NULL) {
127 /* Read next Unifont ASCII hexadecimal format glyph description */
128 sscanf (instring, "%X:%s", &code_point, glyph);
129 /* Calculate width of a glyph in pixels; 4 bits per ASCII hex digit */
130 glyph_width = strlen (glyph) / (glyph_height / 4);
131 snprintf (filename, MAXFILENAME, "U+%06X.bmp", code_point);
132 header [18] = glyph_width; /* bitmap width */
133 header [22] = -glyph_height; /* negative height --> draw top to bottom */
134 if ((outfp = fopen (filename, "w")) != NULL) {
135 for (i = 0; i < 62; i++) fputc (header[i], outfp);
136 /*
137 Bitmap, with each row padded with zeroes if necessary
138 so each row is four bytes wide. (Each row must end
139 on a four-byte boundary, and four bytes is the maximum
140 possible row length for up to 32 pixels in a row.)
141 */
142 string_index = 0;
143 for (i = 0; i < glyph_height; i++) {
144 /* Read 2 ASCII hexadecimal digits (1 byte of output pixels) */
145 sscanf (&glyph[string_index], "%2X", &nextbyte);
146 string_index += 2;
147 fputc (nextbyte, outfp); /* write out the 8 pixels */
148 if (glyph_width <= 8) { /* pad row with 3 zero bytes */
149 fputc (0x00, outfp); fputc (0x00, outfp); fputc (0x00, outfp);
150 }
151 else { /* get 8 more pixels */
152 sscanf (&glyph[string_index], "%2X", &nextbyte);
153 string_index += 2;
154 fputc (nextbyte, outfp); /* write out the 8 pixels */
155 if (glyph_width <= 16) { /* pad row with 2 zero bytes */
156 fputc (0x00, outfp); fputc (0x00, outfp);
157 }
158 else { /* get 8 more pixels */
159 sscanf (&glyph[string_index], "%2X", &nextbyte);
160 string_index += 2;
161 fputc (nextbyte, outfp); /* write out the 8 pixels */
162 if (glyph_width <= 24) { /* pad row with 1 zero byte */
163 fputc (0x00, outfp);
164 }
165 else { /* get 8 more pixels */
166 sscanf (&glyph[string_index], "%2X", &nextbyte);
167 string_index += 2;
168 fputc (nextbyte, outfp); /* write out the 8 pixels */
169 } /* glyph is 32 pixels wide */
170 } /* glyph is 24 pixels wide */
171 } /* glyph is 16 pixels wide */
172 } /* glyph is 8 pixels wide */
173
174 fclose (outfp);
175 }
176 }
177
178 exit (EXIT_SUCCESS);
179}
MAXFILENAME
#define MAXFILENAME
Definition: unifont1per.c:64
MAXSTRING
#define MAXSTRING
Definition: unifont1per.c:61
main
int main(void)
The main function.
Definition: unifont1per.c:73