From 5cabc68ccb42cdd0976f522c83ba3c9c5b347031 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Mon, 14 Nov 2022 21:59:32 +0800 Subject: [PATCH 1/3] fix utfconv.h duplicate functions --- src/utfconv.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/utfconv.h b/src/utfconv.h index 059b3071..59f98e4a 100644 --- a/src/utfconv.h +++ b/src/utfconv.h @@ -1,6 +1,12 @@ #ifndef MBSEC_H #define MBSEC_H +#ifdef __GNUC__ +#define UNUSED __attribute__((__unused__)) +#else +#define UNUSED +#endif + #ifdef _WIN32 #include @@ -8,7 +14,7 @@ #define UTFCONV_ERROR_INVALID_CONVERSION "Input contains invalid byte sequences." -LPWSTR utfconv_utf8towc(const char *str) { +static UNUSED LPWSTR utfconv_utf8towc(const char *str) { LPWSTR output; int len; @@ -30,7 +36,7 @@ LPWSTR utfconv_utf8towc(const char *str) { return output; } -char *utfconv_wctoutf8(LPCWSTR str) { +static UNUSED char *utfconv_wctoutf8(LPCWSTR str) { char *output; int len; From 4457f26502f9ba004122d478b05280cbd0f42309 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Mon, 14 Nov 2022 22:00:40 +0800 Subject: [PATCH 2/3] use flexible structure member from C99 --- src/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index 89bcdd50..c854771e 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -51,7 +51,7 @@ typedef struct RenFont { ERenFontHinting hinting; unsigned char style; unsigned short underline_thickness; - char path[1]; + char path[]; } RenFont; static const char* utf8_to_codepoint(const char *p, unsigned *dst) { From 69938c619c25b35ef36ff3b7ced29062266b7226 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Mon, 14 Nov 2022 22:01:24 +0800 Subject: [PATCH 3/3] add support for loading fonts with UTF-8 filenames --- src/renderer.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index c854771e..e34c8504 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -8,6 +8,10 @@ #include #include FT_FREETYPE_H +#ifdef _WIN32 +#include "utfconv.h" +#endif + #include "renderer.h" #include "renwindow.h" @@ -51,6 +55,7 @@ typedef struct RenFont { ERenFontHinting hinting; unsigned char style; unsigned short underline_thickness; + unsigned char *file; char path[]; } RenFont; @@ -206,9 +211,48 @@ static void font_clear_glyph_cache(RenFont* font) { } RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) { - FT_Face face; - if (FT_New_Face( library, path, 0, &face)) + FT_Face face = NULL; + +#ifdef _WIN32 + + HANDLE file = INVALID_HANDLE_VALUE; + DWORD read; + int font_file_len = 0; + unsigned char *font_file = NULL; + wchar_t *wpath = NULL; + + if ((wpath = utfconv_utf8towc(path)) == NULL) return NULL; + + if ((file = CreateFileW(wpath, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) + goto failure; + + if ((font_file_len = GetFileSize(file, NULL)) == INVALID_FILE_SIZE) + goto failure; + + font_file = check_alloc(malloc(font_file_len * sizeof(unsigned char))); + if (!ReadFile(file, font_file, font_file_len, &read, NULL) || read != font_file_len) + goto failure; + + CloseHandle(file); + free(wpath); + + if (FT_New_Memory_Face(library, font_file, read, 0, &face)) + goto failure; + +#else + + if (FT_New_Face(library, path, 0, &face)) + return NULL; + +#endif + const int surface_scale = renwin_surface_scale(&window_renderer); if (FT_Set_Pixel_Sizes(face, 0, (int)(size*surface_scale))) goto failure; @@ -223,6 +267,11 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial font->hinting = hinting; font->style = style; +#ifdef _WIN32 + // we need to keep this for freetype + font->file = font_file; +#endif + if(FT_IS_SCALABLE(face)) font->underline_thickness = (unsigned short)((face->underline_thickness / (float)face->units_per_EM) * font->size); if(!font->underline_thickness) font->underline_thickness = ceil((double) font->height / 14.0); @@ -232,8 +281,15 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial font->space_advance = face->glyph->advance.x / 64.0f; font->tab_advance = font->space_advance * 2; return font; - failure: - FT_Done_Face(face); + +failure: +#ifdef _WIN32 + free(wpath); + free(font_file); + if (file != INVALID_HANDLE_VALUE) CloseHandle(file); +#endif + if (face != NULL) + FT_Done_Face(face); return NULL; } @@ -252,6 +308,9 @@ const char* ren_font_get_path(RenFont *font) { void ren_font_free(RenFont* font) { font_clear_glyph_cache(font); FT_Done_Face(font->face); +#ifdef _WIN32 + free(font->file); +#endif free(font); }