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
19static 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
26static 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
35FT_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

source code of poppler/goo/ft_utils.cc