comparison nuklear_ui/font_win.c @ 1541:f8ef74e7c800

Merged nuklear_ui into default
author Michael Pavone <pavone@retrodev.com>
date Sun, 25 Mar 2018 12:01:49 -0700
parents 982c5327dfcc
children cb12667aa83e
comparison
equal deleted inserted replaced
1533:78b7fc03c7c6 1541:f8ef74e7c800
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 printf("Preferred family: %s, weight: %d\n", pref_name, weight);
44 pref_sub_families = weight_to_subfamilies[weight];
45 }
46 if (pref_name) {
47 uint32_t prefix_len = 0;
48 while (pref_name[prefix_len] && pref_name[prefix_len] != ' ')
49 {
50 prefix_len++;
51 }
52 pref_prefix = malloc(prefix_len + 1);
53 memcpy(pref_prefix, pref_name, prefix_len);
54 pref_prefix[prefix_len] = 0;
55 }
56 sfnt_table *selected = NULL;
57 char windows[MAX_PATH];
58 SHGetFolderPathA(NULL, CSIDL_WINDOWS, NULL, 0, windows);
59 char *fonts = path_append(windows, "Fonts");
60 size_t num_entries;
61 char *tahoma = NULL, *arial = NULL;
62 dir_entry *entries = get_dir_list(fonts, &num_entries);
63 char *path = NULL;
64 for (size_t i = 0; i < num_entries; i++)
65 {
66 if (entries[i].is_dir) {
67 continue;
68 }
69 char *ext = path_extension(entries[i].name);
70 if (!ext || (strcasecmp(ext, "ttf") && strcasecmp(ext, "ttc") && strcasecmp(ext, "dfont"))) {
71 //not a truetype font, ignore
72 free(ext);
73 continue;
74 }
75 free(ext);
76 char *base = basename_no_extension(entries[i].name);
77 printf("basename: %s\n", base);
78 if (pref_prefix && !strncasecmp(base, pref_prefix, 6)) {
79 path = path_append(fonts, entries[i].name);
80 FILE *f = fopen(path, "rb");
81 if (f)
82 {
83 long font_size = file_size(f);
84 uint8_t *blob = malloc(font_size);
85 if (font_size == fread(blob, 1, font_size, f))
86 {
87 sfnt_container *sfnt = load_sfnt(blob, font_size);
88 if (sfnt) {
89 selected = sfnt_subfamily_by_names(sfnt, pref_sub_families);
90 if (!selected) {
91 sfnt_free(sfnt);
92 }
93 } else {
94 free(blob);
95 }
96 } else {
97 free(blob);
98 }
99 fclose(f);
100 }
101 free(path);
102 free(base);
103 if (selected) {
104 printf("Found preferred font in %s\n", entries[i].name);
105 break;
106 }
107 } else if (!strcasecmp(base, "tahoma")) {
108 tahoma = entries[i].name;
109 } else if (!strcasecmp(base, "arial")) {
110 arial = entries[i].name;
111 }
112 free(base);
113 }
114 if (!selected) {
115 path = NULL;
116 if (tahoma) {
117 path = path_append(fonts, tahoma);
118 } else if (arial) {
119 path = path_append(fonts, arial);
120 }
121 if (path) {
122 FILE *f = fopen(path, "rb");
123 if (f)
124 {
125 long font_size = file_size(f);
126 uint8_t *blob = malloc(font_size);
127 if (font_size == fread(blob, 1, font_size, f))
128 {
129 sfnt_container *sfnt = load_sfnt(blob, font_size);
130 if (sfnt) {
131 selected = sfnt->tables;
132 } else {
133 free(blob);
134 }
135 }
136 fclose(f);
137 }
138 free(path);
139 }
140 }
141 free(fonts);
142 free_dir_list(entries, num_entries);
143 if (selected) {
144 return sfnt_flatten(selected, size_out);
145 }
146 return NULL;
147 }