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