Mercurial > repos > blastem
view nuklear_ui/font_win.c @ 1925:039553703c20
Don't apply address and cd register changes to the 'live' registers until pending flag is cleared, but do preserve the upper address bits in the latch. Fixes regression in Overdrive 2 while preserving fix to Mona in 344 bytes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 13 Apr 2020 20:43:25 -0700 |
parents | 137dbd05ceab |
children |
line wrap: on
line source
#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; } 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); 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(pref_prefix); free(fonts); free_dir_list(entries, num_entries); if (selected) { return sfnt_flatten(selected, size_out); } return NULL; }