changeset 1537:b4914d92308b nuklear_ui

Added OSX implementation of default_font
author Michael Pavone <pavone@retrodev.com>
date Sun, 25 Mar 2018 10:30:40 -0700
parents 982c5327dfcc
children b581663c42ec
files Makefile nuklear_ui/font_mac.m
diffstat 2 files changed, 105 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Mar 25 10:29:40 2018 -0700
+++ b/Makefile	Sun Mar 25 10:30:40 2018 -0700
@@ -27,13 +27,14 @@
 
 MEM:=mem.o
 TERMINAL:=terminal.o
-FONT:=nuklear_ui/font.o
 EXE:=
 
 ifeq ($(OS),Darwin)
 LIBS=sdl2 glew
+FONT:=nuklear_ui/font_mac.o
 else
 LIBS=sdl2 glew gl
+FONT:=nuklear_ui/font.o
 endif #Darwin
 
 HAS_PROC:=$(shell if [ -d /proc ]; then /bin/echo -e -DHAS_PROC; fi)
@@ -48,7 +49,7 @@
 
 ifeq ($(OS),Darwin)
 CFLAGS+= -IFrameworks/SDL2.framework/Headers
-LDFLAGS+= -FFrameworks -framework SDL2 -framework OpenGL
+LDFLAGS+= -FFrameworks -framework SDL2 -framework OpenGL -framework AppKit
 FIXUP:=install_name_tool -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/Frameworks/SDL2.framework/Versions/A/SDL2
 else
 CFLAGS+= -Isdl/include
@@ -60,14 +61,18 @@
 LDFLAGS:=-lm $(shell pkg-config --libs $(LIBS))
 
 ifeq ($(OS),Darwin)
-LDFLAGS+= -framework OpenGL
+LDFLAGS+= -framework OpenGL -framework AppKit
 endif
 
 endif #PORTABLE
 endif #Windows
 
 ifdef DEBUG
+ifeq ($(OS),Darwin)
+OPT:=-g3 -O0
+else
 OPT:=-g3 -Og
+endif #Darwin
 else
 ifdef NOLTO
 OPT:=-O2
@@ -249,6 +254,10 @@
 
 %.o : %.c
 	$(CC) $(CFLAGS) -c -o $@ $<
+  
+%.o : %.m
+	$(CC) $(CFLAGS) -c -o $@ $<
+
 %.png : %.xcf
 	xcf2png $< > $@
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuklear_ui/font_mac.m	Sun Mar 25 10:30:40 2018 -0700
@@ -0,0 +1,93 @@
+#import <AppKit/AppKit.h>
+#include <stddef.h>
+#include "../paths.h"
+#include "../util.h"
+#include "sfnt.h"
+
+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 = strlen(prefix);
+	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
+			free(ext);
+			continue;
+		}
+		free(ext);
+		if (!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) {
+						for (uint8_t j = 0; j < sfnt->num_fonts && !selected; j++)
+						{
+							char *cur_ps = sfnt_name(sfnt->tables + j, SFNT_POSTSCRIPT);
+							if (!strcmp(cur_ps, ps_name)) {
+								selected = sfnt->tables + j;
+							}
+							free(cur_ps);
+						}
+					} else {
+						free(blob);
+					}
+				} else {
+					free(blob);
+				}
+				fclose(f);
+			}
+			free(full_path);
+		}
+	}
+	return selected;
+}
+
+uint8_t *default_font(uint32_t *size_out)
+{
+	NSFont *sys = [NSFont systemFontOfSize:0];
+	NSString *name = [sys fontName];
+	const char *ps_name = [name UTF8String];
+	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 (!selected) {
+		fatal_error("Failed to find system font %s using prefix %s\n", ps_name, prefix);
+	}
+	free(prefix);
+	return sfnt_flatten(selected, size_out);
+}
+