summaryrefslogtreecommitdiff
path: root/nuklear_ui/font_win.c
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2018-03-25 12:01:49 -0700
committerMichael Pavone <pavone@retrodev.com>2018-03-25 12:01:49 -0700
commita5d5c017589945008024f111c06894f5724d6c3b (patch)
treea06db423e81d53aee66cfa0b0ca366bd57d71dc8 /nuklear_ui/font_win.c
parent15af9462392967b6adf7ba6ff4f7ff778cf10eb3 (diff)
parentb6feecb6c12566e9ea826cb67701008f9e423eea (diff)
Merged nuklear_ui into default
Diffstat (limited to 'nuklear_ui/font_win.c')
-rw-r--r--nuklear_ui/font_win.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/nuklear_ui/font_win.c b/nuklear_ui/font_win.c
new file mode 100644
index 0000000..1235d9e
--- /dev/null
+++ b/nuklear_ui/font_win.c
@@ -0,0 +1,147 @@
+#include <windows.h>
+#include <shlobj.h>
+#include <string.h>
+#include "../paths.h"
+#include "../util.h"
+#include "sfnt.h"
+
+uint8_t *default_font(uint32_t *size_out)
+{
+ static const char *thin[] = {"Thin", NULL};
+ static const char *extra_light[] = {"ExtraLight", "UltraLight", NULL};
+ static const char *light[] = {"Light", NULL};
+ static const char *regular[] = {"Regular", "Normal", "Book", NULL};
+ static const char *medium[] = {"Medium", NULL};
+ static const char *semi_bold[] = {"SemiBold", "DemiBold", NULL};
+ static const char *bold[] = {"Bold", NULL};
+ static const char *extra_bold[] = {"ExtraBold", "UltraBold", NULL};
+ static const char *heavy[] = {"Heavy", "Black", NULL};
+ static const char **weight_to_subfamilies[] = {
+ NULL,
+ thin,
+ extra_light,
+ light,
+ regular,
+ medium,
+ semi_bold,
+ bold,
+ extra_bold,
+ heavy
+ };
+
+ NONCLIENTMETRICSA metrics = {
+ .cbSize = sizeof(metrics)
+ };
+ char *pref_name = NULL, *pref_prefix = NULL;
+ const char **pref_sub_families;
+ if (SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0)) {
+ pref_name = metrics.lfMenuFont.lfFaceName;
+ int32_t weight = metrics.lfMenuFont.lfWeight / 100;
+ if (weight < 1 || weight > 9) {
+ weight = 4;
+ }
+ printf("Preferred family: %s, weight: %d\n", pref_name, weight);
+ pref_sub_families = weight_to_subfamilies[weight];
+ }
+ if (pref_name) {
+ uint32_t prefix_len = 0;
+ while (pref_name[prefix_len] && pref_name[prefix_len] != ' ')
+ {
+ prefix_len++;
+ }
+ pref_prefix = malloc(prefix_len + 1);
+ memcpy(pref_prefix, pref_name, prefix_len);
+ pref_prefix[prefix_len] = 0;
+ }
+ sfnt_table *selected = NULL;
+ char windows[MAX_PATH];
+ SHGetFolderPathA(NULL, CSIDL_WINDOWS, NULL, 0, windows);
+ char *fonts = path_append(windows, "Fonts");
+ size_t num_entries;
+ char *tahoma = NULL, *arial = NULL;
+ dir_entry *entries = get_dir_list(fonts, &num_entries);
+ char *path = NULL;
+ for (size_t i = 0; i < num_entries; i++)
+ {
+ if (entries[i].is_dir) {
+ continue;
+ }
+ char *ext = path_extension(entries[i].name);
+ if (!ext || (strcasecmp(ext, "ttf") && strcasecmp(ext, "ttc") && strcasecmp(ext, "dfont"))) {
+ //not a truetype font, ignore
+ free(ext);
+ continue;
+ }
+ free(ext);
+ char *base = basename_no_extension(entries[i].name);
+ printf("basename: %s\n", base);
+ if (pref_prefix && !strncasecmp(base, pref_prefix, 6)) {
+ path = path_append(fonts, entries[i].name);
+ FILE *f = fopen(path, "rb");
+ if (f)
+ {
+ long font_size = file_size(f);
+ uint8_t *blob = malloc(font_size);
+ if (font_size == fread(blob, 1, font_size, f))
+ {
+ sfnt_container *sfnt = load_sfnt(blob, font_size);
+ if (sfnt) {
+ selected = sfnt_subfamily_by_names(sfnt, pref_sub_families);
+ if (!selected) {
+ sfnt_free(sfnt);
+ }
+ } else {
+ free(blob);
+ }
+ } else {
+ free(blob);
+ }
+ fclose(f);
+ }
+ free(path);
+ free(base);
+ if (selected) {
+ printf("Found preferred font in %s\n", entries[i].name);
+ break;
+ }
+ } else if (!strcasecmp(base, "tahoma")) {
+ tahoma = entries[i].name;
+ } else if (!strcasecmp(base, "arial")) {
+ arial = entries[i].name;
+ }
+ free(base);
+ }
+ if (!selected) {
+ path = NULL;
+ if (tahoma) {
+ path = path_append(fonts, tahoma);
+ } else if (arial) {
+ path = path_append(fonts, arial);
+ }
+ if (path) {
+ FILE *f = fopen(path, "rb");
+ if (f)
+ {
+ long font_size = file_size(f);
+ uint8_t *blob = malloc(font_size);
+ if (font_size == fread(blob, 1, font_size, f))
+ {
+ sfnt_container *sfnt = load_sfnt(blob, font_size);
+ if (sfnt) {
+ selected = sfnt->tables;
+ } else {
+ free(blob);
+ }
+ }
+ fclose(f);
+ }
+ free(path);
+ }
+ }
+ free(fonts);
+ free_dir_list(entries, num_entries);
+ if (selected) {
+ return sfnt_flatten(selected, size_out);
+ }
+ return NULL;
+}