comparison nuklear_ui/font_mac.m @ 1692:5dacaef602a7 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 05 Jan 2019 00:58:08 -0800
parents 18ffa9caa00c
children
comparison
equal deleted inserted replaced
1504:95b3a1a8b26c 1692:5dacaef602a7
1 #import <AppKit/AppKit.h>
2 #include <stddef.h>
3 #include "../paths.h"
4 #include "../util.h"
5 #include "sfnt.h"
6
7 static sfnt_table *find_font_in_dir(char *path, char *prefix, const char *ps_name)
8 {
9 size_t num_entries;
10 dir_entry *entries = get_dir_list(path, &num_entries);
11 size_t prefix_len = prefix ? strlen(prefix) : 0;
12 sfnt_table *selected = NULL;
13 for (size_t i = 0; i < num_entries && !selected; i++)
14 {
15 char *ext = path_extension(entries[i].name);
16 if (!ext || (strcasecmp(ext, "ttf") && strcasecmp(ext, "ttc") && strcasecmp(ext, "dfont"))) {
17 //not a truetype font, ignore
18 printf("Skipping %s because of its extension\n", entries[i].name);
19 free(ext);
20 continue;
21 }
22 free(ext);
23 if (!prefix || !strncasecmp(entries[i].name, prefix, prefix_len)) {
24 char *full_path = path_append(path, entries[i].name);
25 FILE *f = fopen(full_path, "rb");
26 if (f)
27 {
28 long font_size = file_size(f);
29 uint8_t *blob = malloc(font_size);
30 if (font_size == fread(blob, 1, font_size, f))
31 {
32 sfnt_container *sfnt = load_sfnt(blob, font_size);
33 if (sfnt) {
34 printf("Examining font file %s\n", entries[i].name);
35 for (uint8_t j = 0; j < sfnt->num_fonts && !selected; j++)
36 {
37 char *cur_ps = sfnt_name(sfnt->tables + j, SFNT_POSTSCRIPT);
38 printf("\t%s\n", cur_ps);
39 if (!strcmp(cur_ps, ps_name)) {
40 selected = sfnt->tables + j;
41 }
42 free(cur_ps);
43 }
44 } else {
45 printf("Failed to load %s as sfnt containern\n", entries[i].name);
46 free(blob);
47 }
48 } else {
49 free(blob);
50 }
51 fclose(f);
52 }
53 free(full_path);
54 }
55 }
56 return selected;
57 }
58
59 static sfnt_table *find_font_by_ps_name(const char*ps_name, uint8_t exhaustive)
60 {
61 const unsigned char *prefix_start = (const unsigned char *)ps_name;
62 while(*prefix_start && (
63 *prefix_start < '0' ||
64 (*prefix_start > 'z' && *prefix_start <= 0x80) ||
65 (*prefix_start > 'Z' && *prefix_start < 'a') ||
66 (*prefix_start > '9' && *prefix_start < 'A')
67 ))
68 {
69 prefix_start++;
70 }
71 if (!*prefix_start) {
72 //Didn't find a suitable starting character, just start from the beginning
73 prefix_start = (const unsigned char *)ps_name;
74 }
75 const unsigned char *prefix_end = (const unsigned char *)prefix_start + 1;
76 while (*prefix_end && *prefix_end >= 'a')
77 {
78 prefix_end++;
79 }
80 char *prefix = malloc(prefix_end - prefix_start + 1);
81 memcpy(prefix, prefix_start, prefix_end - prefix_start);
82 prefix[prefix_end-prefix_start] = 0;
83 //check /Library/Fonts first
84 sfnt_table *selected = find_font_in_dir("/Library/Fonts", (char *)prefix, ps_name);
85 if (!selected) {
86 selected = find_font_in_dir("/System/Library/Fonts", (char *)prefix, ps_name);
87 }
88 if (exhaustive) {
89 if (!selected) {
90 puts("Check using prefix failed, exhaustively checking fonts");
91 selected = find_font_in_dir("/Library/Fonts", NULL, ps_name);
92 }
93 if (!selected) {
94 selected = find_font_in_dir("/System/Library/Fonts", NULL, ps_name);
95 }
96 }
97 free(prefix);
98 return selected;
99 }
100
101 uint8_t *default_font(uint32_t *size_out)
102 {
103 NSFont *sys = [NSFont systemFontOfSize:0];
104 NSString *name = [sys fontName];
105 sfnt_table *selected = find_font_by_ps_name([name UTF8String], 1);
106 if (!selected) {
107 selected = find_font_by_ps_name(".HelveticaNeueDeskInterface-Regular", 0);
108 }
109 if (!selected) {
110 selected = find_font_by_ps_name(".LucidaGrandeUI", 0);
111 }
112
113 if (!selected) {
114 fatal_error("Failed to find system font %s\n", [name UTF8String]);
115 }
116 return sfnt_flatten(selected, size_out);
117 }
118