Skip to content

Commit 1176224

Browse files
committed
Add makefile and the Fonts support program
Fonts: Program to draw text diagrams of each character in the font file. Example: ./Fonts Arduino/libraries/SparkFun_Qwiic_OLED_Graphics_Library/src/res/_fnt_5x7.h Icons: Program to draw text diagrams of each icon in the icon file. Example: ./Icons Firmware/RTK_Surveyor/icons.h makefile: Build script to build the Fonts and Icons programs.
1 parent de93932 commit 1176224

File tree

3 files changed

+396
-4
lines changed

3 files changed

+396
-4
lines changed

Graphics/C/Fonts.c

Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
#include <fcntl.h>
2+
#include <malloc.h>
3+
#include <stdint.h>
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
#define DRAW_OUTLINE 1
9+
10+
typedef struct _CHARACTER_ENTRY {
11+
struct _CHARACTER_ENTRY * next;
12+
int character;
13+
uint8_t data[];
14+
} CHARACTER_ENTRY;
15+
16+
int bytes_high;
17+
CHARACTER_ENTRY * character_list;
18+
int data_bytes;
19+
char * font_text;
20+
uint8_t * font_data;
21+
int height;
22+
int map_width;
23+
int nchar;
24+
int start;
25+
int width;
26+
27+
int
28+
read_value (
29+
const char * string,
30+
const char * text_end
31+
)
32+
{
33+
const char * text;
34+
int length;
35+
int value;
36+
37+
// Find the map width
38+
text = font_text;
39+
length = strlen(string);
40+
while (text < text_end) {
41+
if (strncmp (text, string, length) == 0) {
42+
text += length;
43+
break;
44+
}
45+
text++;
46+
}
47+
48+
// Skip over the white space
49+
while (text < text_end) {
50+
if ((*text != ' ') && (*text != '\t'))
51+
break;
52+
text++;
53+
}
54+
55+
// Get the map width
56+
if (sscanf (text, "%d", &value) != 1) {
57+
fprintf (stderr, "ERROR - Invalid map width!\n");
58+
return -1;
59+
}
60+
return value;
61+
}
62+
63+
const char *
64+
find_next_character (
65+
const char * text,
66+
const char * text_end
67+
)
68+
{
69+
// Walk through the font file
70+
while (text < (text_end - 2)) {
71+
// Determine if this is an icon name
72+
if ((text[0] == '0') && ((text[1] == 'x') || (text[1] == 'X')))
73+
return text;
74+
text++;
75+
}
76+
77+
// No more data
78+
return NULL;
79+
}
80+
81+
int
82+
read_data (
83+
const char * text_end
84+
)
85+
{
86+
int character_count;
87+
const char * text;
88+
int data_offset;
89+
int index;
90+
unsigned int value;
91+
92+
// Read the data array
93+
character_count = 0;
94+
text = font_text;
95+
while (text < text_end) {
96+
for (index = 0; index < data_bytes; index++) {
97+
98+
// Find the next data value
99+
text = find_next_character (text, text_end);
100+
if ((text == NULL) && (index == 0))
101+
return character_count;
102+
else if (text == NULL) {
103+
fprintf (stderr, "ERROR - Missing data!\n");
104+
return 0;
105+
}
106+
107+
// Get the value
108+
if (sscanf (text, "0x%02x", &value) != 1) {
109+
fprintf (stderr, "ERROR - Invalid data value!\n");
110+
return 0;
111+
}
112+
text += 4;
113+
114+
// Save the data value
115+
data_offset = (data_bytes * character_count) + index;
116+
font_data[data_offset] = value;
117+
}
118+
character_count++;
119+
}
120+
return 0;
121+
}
122+
123+
void
124+
add_entry (
125+
CHARACTER_ENTRY * new_entry
126+
)
127+
{
128+
CHARACTER_ENTRY * previous_entry;
129+
130+
// Walk to the end of the list
131+
previous_entry = character_list;
132+
while (previous_entry && previous_entry->next)
133+
previous_entry = previous_entry->next;
134+
135+
// Add this entry to the list
136+
new_entry->next = NULL;
137+
if (previous_entry)
138+
previous_entry->next = new_entry;
139+
else
140+
character_list = new_entry;
141+
}
142+
143+
int
144+
process_data (
145+
int character_count
146+
)
147+
{
148+
int font_index;
149+
int index;
150+
int map_characters;
151+
int map_offset;
152+
int next_character;
153+
CHARACTER_ENTRY * new_entry;
154+
ssize_t offset;
155+
unsigned int value;
156+
int x;
157+
int y;
158+
159+
next_character = start;
160+
map_characters = map_width / width;
161+
while ((next_character - start) < character_count) {
162+
// Allocate the data structure
163+
new_entry = malloc (sizeof(*new_entry) + data_bytes);
164+
165+
if (!new_entry) {
166+
fprintf (stderr, "ERROR - Failed to allocate next_entry!\n");
167+
return -1;
168+
}
169+
new_entry->character = next_character++;
170+
map_offset = new_entry->character - start;
171+
map_offset = ((map_offset / map_characters) * map_characters * data_bytes)
172+
+ ((map_offset % map_characters) * width);
173+
for (y = 0; y < bytes_high; y++) {
174+
for (x = 0; x < width; x++) {
175+
176+
// Save the data value
177+
font_index = map_offset + (y * map_width) + x;
178+
value = font_data[font_index];
179+
index = (y * width) + x;
180+
new_entry->data[index] = value;
181+
}
182+
}
183+
184+
// Add the entry to the list
185+
add_entry (new_entry);
186+
}
187+
return 0;
188+
}
189+
190+
void
191+
display_character (
192+
CHARACTER_ENTRY * character
193+
)
194+
{
195+
int bit;
196+
const char * indent = " ";
197+
int x;
198+
int y;
199+
200+
printf ("/*\n");
201+
printf (" 0x%02x, %d [%d, %d]\n", character->character, character->character, width, height);
202+
printf ("\n");
203+
#ifdef DRAW_OUTLINE
204+
printf ("%s.", indent);
205+
for (x = 0; x < width; x++)
206+
printf ("-");
207+
printf (".\n");
208+
#endif // DRAW_OUTLINE
209+
for (y = 0; y < height; y++) {
210+
printf ("%s", indent);
211+
#ifdef DRAW_OUTLINE
212+
printf ("|");
213+
#endif // DRAW_OUTLINE
214+
for (x = 0; x < width; x++) {
215+
bit = character->data[((y >> 3) * width) + x];
216+
bit >>= y & 7;
217+
printf ("%c", (bit & 1) ? '*' : ' ');
218+
}
219+
#ifdef DRAW_OUTLINE
220+
printf ("|");
221+
#endif // DRAW_OUTLINE
222+
printf ("\n");
223+
}
224+
#ifdef DRAW_OUTLINE
225+
printf ("%s'", indent);
226+
for (x = 0; x < width; x++)
227+
printf ("-");
228+
printf ("'\n");
229+
#endif // DRAW_OUTLINE
230+
printf ("*/\n");
231+
printf ("\n");
232+
}
233+
234+
int
235+
main (
236+
int argc,
237+
char ** argv
238+
)
239+
{
240+
CHARACTER_ENTRY * character;
241+
int character_count;
242+
const char * text_end;
243+
char * filename;
244+
int font_file;
245+
off_t file_length;
246+
int status;
247+
ssize_t valid_data;
248+
249+
do {
250+
// Assume failure
251+
font_file = -1;
252+
status = -1;
253+
254+
// Verify the argument count
255+
if (argc != 2) {
256+
fprintf (stderr, "%s font_fliename\n", argv[0]);
257+
break;
258+
}
259+
260+
// Get the font file name
261+
filename = argv[1];
262+
263+
// Open the font file
264+
font_file = open (filename, O_RDONLY);
265+
if (font_file < 0) {
266+
perror("ERROR - File open failed!");
267+
break;
268+
}
269+
270+
// Determine the length of the file
271+
file_length = lseek (font_file, 0, SEEK_END);
272+
273+
// Go the the beginning of the file
274+
lseek (font_file, 0, SEEK_SET);
275+
276+
// Allocate the text buffer
277+
font_text = malloc (file_length);
278+
if (!font_text) {
279+
fprintf (stderr, "ERROR - Failed to allocate font text buffer!\n");
280+
break;
281+
}
282+
283+
// Fill the text buffer
284+
valid_data = read (font_file, font_text, file_length);
285+
if (valid_data < 0) {
286+
fprintf (stderr, "ERROR - File read failed!\n");
287+
break;
288+
}
289+
text_end = &font_text[valid_data];
290+
291+
// Find the font values
292+
width = read_value ("WIDTH", text_end);
293+
if (width < 0) {
294+
fprintf (stderr, "ERROR - Failed to read font width!\n");
295+
}
296+
height = read_value ("HEIGHT", text_end);
297+
if (height < 0) {
298+
fprintf (stderr, "ERROR - Failed to read font height!\n");
299+
break;
300+
}
301+
start = read_value ("START", text_end);
302+
if (start < 0) {
303+
fprintf (stderr, "ERROR - Failed to read font start!\n");
304+
break;
305+
}
306+
nchar = read_value ("NCHAR", text_end);
307+
if (nchar < 0) {
308+
fprintf (stderr, "ERROR - Failed to read font nchar!\n");
309+
break;
310+
}
311+
map_width = read_value ("MAP_WIDTH", text_end);
312+
if (map_width < 0) {
313+
fprintf (stderr, "ERROR - Failed to read map width!\n");
314+
break;
315+
}
316+
bytes_high = (height + 7) / 8;
317+
data_bytes = width * bytes_high;
318+
319+
// Allocate the data buffer
320+
font_data = malloc (sizeof(*font_data) * 256 * data_bytes);
321+
if (!font_data) {
322+
fprintf (stderr, "ERROR - Failed to allocate font data buffer!\n");
323+
break;
324+
}
325+
326+
// Fill the data buffer
327+
character_count = read_data (text_end);
328+
329+
// Process the data
330+
if (process_data(character_count))
331+
break;
332+
333+
// Display the characters in the font file
334+
character = character_list;
335+
while (character) {
336+
display_character (character);
337+
character = character->next;
338+
}
339+
340+
// Indicate success
341+
status = 0;
342+
} while (0);
343+
344+
// Close the file
345+
if (font_file >= 0)
346+
close(font_file);
347+
348+
return status;
349+
}

Graphics/C/Icons.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ terminate_end_of_line (
4747
text++;
4848

4949
// Skip over the end of line
50-
while ((text < text_end) && (*text == '\r') || (*text == '\n'))
50+
while ((text < text_end) && ((*text == '\r') || (*text == '\n')))
5151
*text++ = 0;
5252

5353
// Return the start of the next line
@@ -151,7 +151,7 @@ read_icon_data (
151151
ICON_ENTRY * icon_entry;
152152
int index;
153153
char * number;
154-
int value;
154+
unsigned int value;
155155
int x;
156156
int y;
157157

@@ -410,8 +410,8 @@ display_icon (
410410
}
411411
for (y = 0; y < icon->height; y++) {
412412
printf ("%s", indent);
413-
if (DRAW_OUTLINE)
414-
printf ("0x%02x|", 1 << (y & 7));
413+
if (DRAW_OUTLINE)
414+
printf ("0x%02x|", 1 << (y & 7));
415415
for (x = 0; x < icon->width; x++) {
416416
bit = icon->data[((y >> 3) * icon->bytes_wide) + x];
417417
bit >>= y & 7;

0 commit comments

Comments
 (0)