GNU Unifont  15.1.01
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 */
68 int
69 main () {
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