Mercurial > repos > blastem
annotate nuklear_ui/font.c @ 2688:b42f00a3a937 default tip
Fix default target. Ensure m68k.h and z80.h are built before anything else when no dep info is available
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 31 Mar 2025 21:06:18 -0700 |
parents | 48ab1e3e5df5 |
children |
rev | line source |
---|---|
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 #include <stdio.h> |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 #include <stdlib.h> |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
3 #include <stdint.h> |
1934
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
4 #include <string.h> |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
5 #include "../util.h" |
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
6 #include "sfnt.h" |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
8 char **preferred_font_paths(uint32_t *num_out) |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 { |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
10 char ** ret; |
1934
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
11 #ifdef FONT_PATH |
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
12 FILE *f = fopen(FONT_PATH, "rb"); |
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
13 if (f) { |
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
14 fclose(f); |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
15 ret = calloc(1, sizeof(char*)); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
16 ret[0] = strdup(FONT_PATH); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
17 *num_out = 1; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
18 return ret; |
1934
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
19 } |
253c62b7144e
Allow specifying a default font path at build time
Michael Pavone <pavone@retrodev.com>
parents:
1593
diff
changeset
|
20 #endif |
1976
3dd9c68472fb
Specify desired language when invoking fc-match to find an appropriate font on Linux
Michael Pavone <pavone@retrodev.com>
parents:
1934
diff
changeset
|
21 //TODO: specify language dynamically once BlastEm is localized |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
22 FILE *fc_pipe = popen("fc-match -s -f '%{file}\n' :lang=en", "r"); |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 if (!fc_pipe) { |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 return NULL; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 } |
2483
48ab1e3e5df5
Fix Linux font selection regression
Michael Pavone <pavone@retrodev.com>
parents:
2480
diff
changeset
|
26 size_t buf_size = 2048; |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 char *buffer = NULL; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 size_t total = 0, read = 0; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 do { |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 total += read; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 buf_size *= 2; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 buffer = realloc(buffer, buf_size); |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 if (!buffer) { |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 return NULL; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 } |
2483
48ab1e3e5df5
Fix Linux font selection regression
Michael Pavone <pavone@retrodev.com>
parents:
2480
diff
changeset
|
36 read = fread(buffer + total, 1, buf_size - total, fc_pipe); |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 } while (read == (buf_size - total)); |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 total += read; |
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 buffer[total] = 0; |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
40 *num_out = 0; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
41 for (size_t i = 0; i < total; i++) |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
42 { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
43 if (buffer[i] == '\n') { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
44 buffer[i] = 0; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
45 if (i + 1 != total) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
46 (*num_out)++; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
47 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
48 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
49 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
50 ret = calloc(*num_out, sizeof(char*)); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
51 size_t entry = 0; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
52 ret[entry++] = buffer; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
53 for (size_t i = 0; i < total - 1 && entry < *num_out; i++) |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
54 { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
55 if (!buffer[i]) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
56 ret[entry++] = buffer + i + 1; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
57 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
58 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
59 return ret; |
1474
c5c022c7aa54
Initial work on Nuklear-based UI
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 } |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
61 |
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
62 uint8_t *default_font(uint32_t *size_out) |
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
63 { |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
64 uint8_t *ret = NULL; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
65 uint32_t num_fonts; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
66 char **paths = preferred_font_paths(&num_fonts); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
67 if (!paths) { |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
68 goto error; |
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
69 } |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
70 for (uint32_t i = 0; i < num_fonts && !ret; i++) |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
71 { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
72 FILE *f = fopen(paths[i], "rb"); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
73 if (!f) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
74 fprintf(stderr, "Failed to open font file %s\n", paths[i]); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
75 continue; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
76 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
77 long size = file_size(f); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
78 uint8_t *buffer = malloc(size); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
79 if (size != fread(buffer, 1, size, f)) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
80 fprintf(stderr, "Failed to read font file %s\n", paths[i]); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
81 fclose(f); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
82 continue; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
83 } |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
84 fclose(f); |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
85 sfnt_container *sfnt = load_sfnt(buffer, size); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
86 if (!sfnt) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
87 fprintf(stderr, "File %s does not contain SFNT resources\n", paths[i]); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
88 free(buffer); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
89 continue; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
90 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
91 for (uint8_t j = 0; j < sfnt->num_fonts; j++) |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
92 { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
93 if (sfnt_has_truetype_glyphs(sfnt->tables + j)) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
94 ret = sfnt_flatten(sfnt->tables + j, size_out); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
95 sfnt = NULL; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
96 break; |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
97 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
98 fprintf(stderr, "Font %s in file %s doesn't have TrueType glyphs\n", sfnt_name(sfnt->tables + j, SFNT_POSTSCRIPT), paths[i]); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
99 } |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
100 if (sfnt) { |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
101 sfnt_free(sfnt); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
102 } |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
103 } |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
104 free(paths[0]); |
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
105 free(paths); |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
106 error: |
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
107 //TODO: try to find a suitable font in /usr/share/fonts as a fallback |
2480
369a52e302e2
Try multiple results from fc-match on Linux rather than assuming the first choice font will be suitable
Michael Pavone <pavone@retrodev.com>
parents:
1976
diff
changeset
|
108 return ret; |
1527
4f6e8acd7b6a
Added support for TTC and dfont format true type fonts. More robust font selection on Windows
Michael Pavone <pavone@retrodev.com>
parents:
1474
diff
changeset
|
109 } |