1 /**
2  * @file lv_ftsystem.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "../../../lvgl.h"
11 #if LV_USE_FREETYPE && LV_FREETYPE_USE_LVGL_PORT
12 
13 #include <ft2build.h>
14 #include FT_CONFIG_CONFIG_H
15 #include <freetype/internal/ftdebug.h>
16 #include <freetype/internal/ftstream.h>
17 #include <freetype/ftsystem.h>
18 #include <freetype/fterrors.h>
19 #include <freetype/fttypes.h>
20 
21 /*********************
22  *      DEFINES
23  *********************/
24 
25 /* The macro FT_COMPONENT is used in trace mode.  It is an implicit
26  * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
27  * messages during execution.
28  */
29 #undef  FT_COMPONENT
30 #define FT_COMPONENT  io
31 
32 /* We use the macro STREAM_FILE for convenience to extract the       */
33 /* system-specific stream handle from a given FreeType stream object */
34 #define STREAM_FILE( stream )  ( (lv_fs_file_t*)stream->descriptor.pointer )
35 
36 /**********************
37  *      TYPEDEFS
38  **********************/
39 
40 /**********************
41  *  STATIC PROTOTYPES
42  **********************/
43 
44 FT_CALLBACK_DEF(unsigned long)
45 ft_lv_fs_stream_io(FT_Stream       stream,
46                    unsigned long   offset,
47                    unsigned char * buffer,
48                    unsigned long   count);
49 FT_CALLBACK_DEF(void)
50 ft_lv_fs_stream_close(FT_Stream  stream);
51 FT_CALLBACK_DEF(void *)
52 ft_alloc(FT_Memory  memory,
53          long       size);
54 FT_CALLBACK_DEF(void *)
55 ft_realloc(FT_Memory  memory,
56            long       cur_size,
57            long       new_size,
58            void   *   block);
59 FT_CALLBACK_DEF(void)
60 ft_free(FT_Memory  memory,
61         void   *   block);
62 
63 /**********************
64  *  STATIC VARIABLES
65  **********************/
66 
67 /**********************
68  *      MACROS
69  **********************/
70 
71 #ifdef FT_DEBUG_MEMORY
72 
73     extern FT_Int
74     ft_mem_debug_init(FT_Memory  memory);
75 
76     extern void
77     ft_mem_debug_done(FT_Memory  memory);
78 
79 #endif
80 
81 /**********************
82  *   GLOBAL FUNCTIONS
83  **********************/
84 
85 #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
86 
87 /* documentation is in ftstream.h */
88 
89 FT_BASE_DEF(FT_Error)
FT_Stream_Open(FT_Stream stream,const char * filepathname)90 FT_Stream_Open(FT_Stream    stream,
91                const char * filepathname)
92 {
93     lv_fs_file_t  file;
94 
95     if(!stream)
96         return FT_THROW(Invalid_Stream_Handle);
97 
98     stream->descriptor.pointer = NULL;
99     stream->pathname.pointer   = (char *)filepathname;
100     stream->base               = NULL;
101     stream->pos                = 0;
102     stream->read               = NULL;
103     stream->close              = NULL;
104 
105     lv_fs_res_t res = lv_fs_open(&file, filepathname, LV_FS_MODE_RD);
106 
107     if(res != LV_FS_RES_OK) {
108         FT_ERROR(("FT_Stream_Open:"
109                   " could not open `%s'\n", filepathname));
110 
111         return FT_THROW(Cannot_Open_Resource);
112     }
113 
114     lv_fs_seek(&file, 0, LV_FS_SEEK_END);
115 
116     uint32_t pos;
117     res = lv_fs_tell(&file, &pos);
118     if(res != LV_FS_RES_OK) {
119         FT_ERROR(("FT_Stream_Open:"));
120         FT_ERROR((" opened `%s' but zero-sized\n", filepathname));
121         lv_fs_close(&file);
122         return FT_THROW(Cannot_Open_Stream);
123     }
124     stream->size = pos;
125     lv_fs_seek(&file, 0, LV_FS_SEEK_SET);
126 
127     lv_fs_file_t * file_p = lv_malloc(sizeof(lv_fs_file_t));
128     LV_ASSERT_MALLOC(file_p);
129 
130     if(!file_p) {
131         FT_ERROR(("FT_Stream_Open: malloc failed for file_p"));
132         lv_fs_close(&file);
133         return FT_THROW(Cannot_Open_Stream);
134     }
135 
136     *file_p = file;
137 
138     stream->descriptor.pointer = file_p;
139     stream->read  = ft_lv_fs_stream_io;
140     stream->close = ft_lv_fs_stream_close;
141 
142     FT_TRACE1(("FT_Stream_Open:"));
143     FT_TRACE1((" opened `%s' (%ld bytes) successfully\n",
144                filepathname, stream->size));
145 
146     return FT_Err_Ok;
147 }
148 
149 #endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
150 
151 /* documentation is in ftobjs.h */
152 
153 FT_BASE_DEF(FT_Memory)
FT_New_Memory(void)154 FT_New_Memory(void)
155 {
156     FT_Memory  memory;
157 
158     memory = (FT_Memory)lv_malloc(sizeof(*memory));
159     if(memory) {
160         memory->user    = NULL;
161         memory->alloc   = ft_alloc;
162         memory->realloc = ft_realloc;
163         memory->free    = ft_free;
164 #ifdef FT_DEBUG_MEMORY
165         ft_mem_debug_init(memory);
166 #endif
167     }
168 
169     return memory;
170 }
171 
172 /* documentation is in ftobjs.h */
173 
174 FT_BASE_DEF(void)
FT_Done_Memory(FT_Memory memory)175 FT_Done_Memory(FT_Memory  memory)
176 {
177 #ifdef FT_DEBUG_MEMORY
178     ft_mem_debug_done(memory);
179 #endif
180     lv_free(memory);
181 }
182 
183 /**********************
184  *   STATIC FUNCTIONS
185  **********************/
186 
187 /**
188  * The memory allocation function.
189  * @param memory A pointer to the memory object.
190  * @param size The requested size in bytes.
191  * @return The address of newly allocated block.
192  */
193 FT_CALLBACK_DEF(void *)
ft_alloc(FT_Memory memory,long size)194 ft_alloc(FT_Memory  memory,
195          long       size)
196 {
197     FT_UNUSED(memory);
198 
199     return lv_malloc((size_t)size);
200 }
201 
202 /**
203  * The memory reallocation function.
204  * @param memory A pointer to the memory object.
205  * @param cur_size The current size of the allocated memory block.
206  * @param new_size The newly requested size in bytes.
207  * @param block The current address of the block in memory.
208  * @return The address of the reallocated memory block.
209  */
210 FT_CALLBACK_DEF(void *)
ft_realloc(FT_Memory memory,long cur_size,long new_size,void * block)211 ft_realloc(FT_Memory  memory,
212            long       cur_size,
213            long       new_size,
214            void   *   block)
215 {
216     FT_UNUSED(memory);
217     FT_UNUSED(cur_size);
218 
219     return lv_realloc(block, (size_t)new_size);
220 }
221 
222 /**
223  * The memory release function.
224  * @param memory A pointer to the memory object.
225  * @param block The address of block in memory to be freed.
226  */
227 FT_CALLBACK_DEF(void)
ft_free(FT_Memory memory,void * block)228 ft_free(FT_Memory  memory,
229         void   *   block)
230 {
231     FT_UNUSED(memory);
232 
233     lv_free(block);
234 }
235 
236 #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
237 
238 /**
239  * The function to close a stream.
240  * @param stream A pointer to the stream object.
241  */
242 FT_CALLBACK_DEF(void)
ft_lv_fs_stream_close(FT_Stream stream)243 ft_lv_fs_stream_close(FT_Stream  stream)
244 {
245     lv_fs_file_t * file_p = STREAM_FILE(stream);
246     lv_fs_close(file_p);
247     lv_free(file_p);
248 
249     stream->descriptor.pointer = NULL;
250     stream->size               = 0;
251     stream->base               = NULL;
252 }
253 
254 /**
255  * The function to open a stream.
256  * @param stream A pointer to the stream object.
257  * @param offset The position in the data stream to start reading.
258  * @param buffer The address of buffer to store the read data.
259  * @param count The number of bytes to read from the stream.
260  * @return The number of bytes actually read.  If `count' is zero (this is,
261  *         the function is used for seeking), a non-zero return value
262  *         indicates an error.
263  */
264 FT_CALLBACK_DEF(unsigned long)
ft_lv_fs_stream_io(FT_Stream stream,unsigned long offset,unsigned char * buffer,unsigned long count)265 ft_lv_fs_stream_io(FT_Stream       stream,
266                    unsigned long   offset,
267                    unsigned char * buffer,
268                    unsigned long   count)
269 {
270     lv_fs_file_t * file_p;
271 
272     if(!count && offset > stream->size)
273         return 1;
274 
275     file_p = STREAM_FILE(stream);
276 
277     if(stream->pos != offset)
278         lv_fs_seek(file_p, (long)offset, LV_FS_SEEK_SET);
279 
280     if(count == 0)
281         return 0;
282 
283     uint32_t br;
284     lv_fs_res_t res = lv_fs_read(file_p, buffer, count, &br);
285 
286     return res == LV_FS_RES_OK ? br : 0;
287 }
288 
289 #endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
290 
291 #endif/*LV_FREETYPE_USE_LV_FTSYSTEM*/
292