Mercurial > repos > blastem
comparison nuklear_ui/font_win.c @ 1692:5dacaef602a7 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 05 Jan 2019 00:58:08 -0800 |
parents | 137dbd05ceab |
children |
comparison
equal
deleted
inserted
replaced
1504:95b3a1a8b26c | 1692:5dacaef602a7 |
---|---|
1 #include <windows.h> | |
2 #include <shlobj.h> | |
3 #include <string.h> | |
4 #include "../paths.h" | |
5 #include "../util.h" | |
6 #include "sfnt.h" | |
7 | |
8 uint8_t *default_font(uint32_t *size_out) | |
9 { | |
10 static const char *thin[] = {"Thin", NULL}; | |
11 static const char *extra_light[] = {"ExtraLight", "UltraLight", NULL}; | |
12 static const char *light[] = {"Light", NULL}; | |
13 static const char *regular[] = {"Regular", "Normal", "Book", NULL}; | |
14 static const char *medium[] = {"Medium", NULL}; | |
15 static const char *semi_bold[] = {"SemiBold", "DemiBold", NULL}; | |
16 static const char *bold[] = {"Bold", NULL}; | |
17 static const char *extra_bold[] = {"ExtraBold", "UltraBold", NULL}; | |
18 static const char *heavy[] = {"Heavy", "Black", NULL}; | |
19 static const char **weight_to_subfamilies[] = { | |
20 NULL, | |
21 thin, | |
22 extra_light, | |
23 light, | |
24 regular, | |
25 medium, | |
26 semi_bold, | |
27 bold, | |
28 extra_bold, | |
29 heavy | |
30 }; | |
31 | |
32 NONCLIENTMETRICSA metrics = { | |
33 .cbSize = sizeof(metrics) | |
34 }; | |
35 char *pref_name = NULL, *pref_prefix = NULL; | |
36 const char **pref_sub_families; | |
37 if (SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0)) { | |
38 pref_name = metrics.lfMenuFont.lfFaceName; | |
39 int32_t weight = metrics.lfMenuFont.lfWeight / 100; | |
40 if (weight < 1 || weight > 9) { | |
41 weight = 4; | |
42 } | |
43 pref_sub_families = weight_to_subfamilies[weight]; | |
44 } | |
45 if (pref_name) { | |
46 uint32_t prefix_len = 0; | |
47 while (pref_name[prefix_len] && pref_name[prefix_len] != ' ') | |
48 { | |
49 prefix_len++; | |
50 } | |
51 pref_prefix = malloc(prefix_len + 1); | |
52 memcpy(pref_prefix, pref_name, prefix_len); | |
53 pref_prefix[prefix_len] = 0; | |
54 } | |
55 sfnt_table *selected = NULL; | |
56 char windows[MAX_PATH]; | |
57 SHGetFolderPathA(NULL, CSIDL_WINDOWS, NULL, 0, windows); | |
58 char *fonts = path_append(windows, "Fonts"); | |
59 size_t num_entries; | |
60 char *tahoma = NULL, *arial = NULL; | |
61 dir_entry *entries = get_dir_list(fonts, &num_entries); | |
62 char *path = NULL; | |
63 for (size_t i = 0; i < num_entries; i++) | |
64 { | |
65 if (entries[i].is_dir) { | |
66 continue; | |
67 } | |
68 char *ext = path_extension(entries[i].name); | |
69 if (!ext || (strcasecmp(ext, "ttf") && strcasecmp(ext, "ttc") && strcasecmp(ext, "dfont"))) { | |
70 //not a truetype font, ignore | |
71 free(ext); | |
72 continue; | |
73 } | |
74 free(ext); | |
75 char *base = basename_no_extension(entries[i].name); | |
76 if (pref_prefix && !strncasecmp(base, pref_prefix, 6)) { | |
77 path = path_append(fonts, entries[i].name); | |
78 FILE *f = fopen(path, "rb"); | |
79 if (f) | |
80 { | |
81 long font_size = file_size(f); | |
82 uint8_t *blob = malloc(font_size); | |
83 if (font_size == fread(blob, 1, font_size, f)) | |
84 { | |
85 sfnt_container *sfnt = load_sfnt(blob, font_size); | |
86 if (sfnt) { | |
87 selected = sfnt_subfamily_by_names(sfnt, pref_sub_families); | |
88 if (!selected) { | |
89 sfnt_free(sfnt); | |
90 } | |
91 } else { | |
92 free(blob); | |
93 } | |
94 } else { | |
95 free(blob); | |
96 } | |
97 fclose(f); | |
98 } | |
99 free(path); | |
100 free(base); | |
101 if (selected) { | |
102 printf("Found preferred font in %s\n", entries[i].name); | |
103 break; | |
104 } | |
105 } else if (!strcasecmp(base, "tahoma")) { | |
106 tahoma = entries[i].name; | |
107 } else if (!strcasecmp(base, "arial")) { | |
108 arial = entries[i].name; | |
109 } | |
110 free(base); | |
111 } | |
112 if (!selected) { | |
113 path = NULL; | |
114 if (tahoma) { | |
115 path = path_append(fonts, tahoma); | |
116 } else if (arial) { | |
117 path = path_append(fonts, arial); | |
118 } | |
119 if (path) { | |
120 FILE *f = fopen(path, "rb"); | |
121 if (f) | |
122 { | |
123 long font_size = file_size(f); | |
124 uint8_t *blob = malloc(font_size); | |
125 if (font_size == fread(blob, 1, font_size, f)) | |
126 { | |
127 sfnt_container *sfnt = load_sfnt(blob, font_size); | |
128 if (sfnt) { | |
129 selected = sfnt->tables; | |
130 } else { | |
131 free(blob); | |
132 } | |
133 } | |
134 fclose(f); | |
135 } | |
136 free(path); | |
137 } | |
138 } | |
139 free(pref_prefix); | |
140 free(fonts); | |
141 free_dir_list(entries, num_entries); | |
142 if (selected) { | |
143 return sfnt_flatten(selected, size_out); | |
144 } | |
145 return NULL; | |
146 } |