1 | //======================================================================== |
2 | // |
3 | // ft_util.cc |
4 | // |
5 | // FreeType helper functions. |
6 | // |
7 | // This file is licensed under the GPLv2 or later |
8 | // |
9 | // Copyright (C) 2022 Adrian Johnson <ajohnson@redneon.com> |
10 | // |
11 | //======================================================================== |
12 | |
13 | #include <cstdio> |
14 | |
15 | #include "ft_utils.h" |
16 | #include "gfile.h" |
17 | |
18 | #ifdef _WIN32 |
19 | static unsigned long ft_stream_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) |
20 | { |
21 | FILE *file = (FILE *)stream->descriptor.pointer; |
22 | fseek(file, offset, SEEK_SET); |
23 | return fread(buffer, 1, count, file); |
24 | } |
25 | |
26 | static void ft_stream_close(FT_Stream stream) |
27 | { |
28 | FILE *file = (FILE *)stream->descriptor.pointer; |
29 | fclose(file); |
30 | delete stream; |
31 | } |
32 | #endif |
33 | |
34 | // Same as FT_New_Face() but handles UTF-8 filenames on Windows |
35 | FT_Error ft_new_face_from_file(FT_Library library, const char *filename_utf8, FT_Long face_index, FT_Face *aface) |
36 | { |
37 | #ifdef _WIN32 |
38 | FILE *file; |
39 | long size; |
40 | |
41 | if (!filename_utf8) |
42 | return FT_Err_Invalid_Argument; |
43 | |
44 | file = openFile(filename_utf8, "rb" ); |
45 | if (!file) |
46 | return FT_Err_Cannot_Open_Resource; |
47 | |
48 | fseek(file, 0, SEEK_END); |
49 | size = ftell(file); |
50 | rewind(file); |
51 | |
52 | if (size <= 0) |
53 | return FT_Err_Cannot_Open_Stream; |
54 | |
55 | FT_StreamRec *stream = new FT_StreamRec; |
56 | *stream = {}; |
57 | stream->size = size; |
58 | stream->read = ft_stream_read; |
59 | stream->close = ft_stream_close; |
60 | stream->descriptor.pointer = file; |
61 | |
62 | FT_Open_Args args = {}; |
63 | args.flags = FT_OPEN_STREAM; |
64 | args.stream = stream; |
65 | |
66 | return FT_Open_Face(library, &args, face_index, aface); |
67 | #else |
68 | // On POSIX, FT_New_Face mmaps font files. If not Windows, prefer FT_New_Face over our stdio.h based FT_Open_Face. |
69 | return FT_New_Face(library, filepathname: filename_utf8, face_index, aface); |
70 | #endif |
71 | } |
72 | |