1 /****************************************************************************
2 *
3 * The MIT License (MIT)
4 *
5 * Copyright 2020 NXP
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * 'Software'), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject
14 * to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial
18 * portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
24 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 *****************************************************************************/
29
30 /** Include Files */
31 #include <mcufont.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 #include "vg_lite.h"
37 #include "buf_reader.h"
38 #include "vg_lite_text.h"
39 #include "vft_draw.h"
40 #include "vft_debug.h"
41
42 /** Macros */
43 #define __COUNTOF(x) (sizeof(x)/sizeof(x[0]))
44 #define MAX_SYSTEM_FONTS (8)
45
46 #define RCD_ALLOC(x) _mem_allocate(x)
47 #define RCD_FREE(x) _mem_free(x)
48
49 #ifdef ENABLE_DEBUG_TRACE
50 static int g_id;
51
52 #define DBG_ID() (g_id)
53 #define DBG_INC_ID() (g_id++)
54 #define DBG_SET_ID(x) g_id = x
55 #else
56
57 #define DBG_ID() (0)
58 #define DBG_INC_ID() (0)
59 #define DBG_SET_ID(x)
60 #endif
61
62 #if APP_ENABLE_SDCARD
63 #define sprintf_s snprintf
64 #endif
65
66 /** Data structures */
67 typedef struct font_height_list {
68 const char font_height;
69 const char ref_font_height;
70 const char ref_font_scale;
71 } font_height_list_t;
72
73 typedef struct font_info_internal {
74 /* Variable shared between user and driver */
75 vg_lite_font_params_t font_params;
76 /* any additional variables internal to driver */
77 int valid;
78 /* Internal loaded raster font */
79 struct mf_font_s *_raster_font;
80 /* Internal loaded vector font */
81 font_face_desc_t *_vector_font;
82 }font_info_internal_t;
83
84 /** Internal or external API prototypes */
85
86 /** Globals */
87 static font_info_internal_t s_device_fonts[MAX_SYSTEM_FONTS];
88
89 /** Local function prototypes */
90 int read_rle_font_header(bufferred_reader_t *f, struct mf_font_s* font);
91 int read_rle_font_from_buffer(char *buf, int size, struct mf_font_s* font);
92 int load_raster_font(char *data, int data_len, struct mf_font_s** font);
93
94 int read_8b(bufferred_reader_t *f, uint8_t* pdata);
95 int read_16b(bufferred_reader_t *f, uint16_t* pword);
96 int read_32b(bufferred_reader_t *f, uint32_t* pword);
97 int read_16b_blob(bufferred_reader_t *f, uint16_t** ary, uint32_t* ary_len);
98 int read_8b_blob(bufferred_reader_t *f, uint8_t** ary, uint32_t* ary_len);
99 int free_rle_font_memory(struct mf_font_s** font);
100 vg_lite_error_t vg_lite_free_font_memory(vg_lite_font_t font);
101 vg_lite_error_t vg_lite_load_font_data(vg_lite_font_t font, int font_height);
102
103 /** Externs if any */
104
105 /** Code section */
106 vg_lite_font_t vg_lite_find_font(
107 char *font_name,
108 eFontWeight_t font_weight,
109 eFontStretch_t font_stretch,
110 eFontStyle_t font_style,
111 int font_height);
112
vg_lite_register_font(vg_lite_font_t * font,vg_lite_font_params_t * params)113 vg_lite_error_t vg_lite_register_font(vg_lite_font_t *font,
114 vg_lite_font_params_t *params)
115 {
116 int i;
117 int free_entry = VG_LITE_INVALID_FONT;
118
119 if (font != NULL)
120 *font = VG_LITE_INVALID_FONT;
121
122 /* Check if font is already registered */
123 for (i=0; i<MAX_SYSTEM_FONTS; i++) {
124 /* Is entry is valid ? */
125 if ( s_device_fonts[i].valid == 0 ) {
126 /* Grab free entry in list for new font */
127 if (free_entry == -1 ) {
128 free_entry = i;
129 }
130 } else if (s_device_fonts[i].valid == 1 ) {
131 /* Does font.name matches */
132 if ( strncmp(s_device_fonts[i].font_params.name,
133 params->name,
134 strlen(s_device_fonts[i].font_params.name)) == 0)
135 {
136 return VG_LITE_ALREADY_EXISTS;
137 }
138 } else {
139 printf("Corrupt font table\n");
140 return VG_LITE_INVALID_ARGUMENT;
141 }
142 }
143
144 /* Check if list is completely full or not */
145 if ( i == MAX_SYSTEM_FONTS && free_entry == VG_LITE_INVALID_FONT) {
146 /* Font List descriptor exhausted */
147 return VG_LITE_OUT_OF_RESOURCES;
148 } else {
149 /* Add new font in global table */
150 memcpy(&s_device_fonts[free_entry].font_params, params, sizeof(vg_lite_font_params_t));
151 s_device_fonts[free_entry].valid = 1;
152 /*
153 Loading font here leads to low run-time memory, we may need to characterize memory usage
154 e.g. pure path test don't require font, eventhrough application registers them
155 */
156 #if 0
157 error = vg_lite_load_font_data(free_entry, params->font_height);
158 if ( error != 0 ) {
159 s_device_fonts[free_entry].valid = 0;
160 return error;
161 }
162 #endif
163 }
164
165 if (font != NULL)
166 *font = free_entry;
167
168 return VG_LITE_SUCCESS;
169 }
170
vg_lite_is_font_valid(vg_lite_font_t font)171 int vg_lite_is_font_valid(vg_lite_font_t font)
172 {
173 if (font < MAX_SYSTEM_FONTS) {
174 if (s_device_fonts[font].valid == 1)
175 return 0;
176 }
177 return VG_LITE_INVALID_ARGUMENT;
178 }
179
vg_lite_is_vector_font(vg_lite_font_t font)180 int vg_lite_is_vector_font(vg_lite_font_t font)
181 {
182 if (font < MAX_SYSTEM_FONTS) {
183 if (s_device_fonts[font].valid == 1)
184 return (s_device_fonts[font].font_params.font_type ==
185 eFontTypeVector);
186 else
187 return 0;
188 }
189 return VG_LITE_INVALID_ARGUMENT;;
190 }
191
vg_lite_unregister_font(vg_lite_font_t font)192 vg_lite_error_t vg_lite_unregister_font(vg_lite_font_t font)
193 {
194 if (vg_lite_is_font_valid(font) != 0 ) {
195 /* Font not found */
196 return VG_LITE_INVALID_ARGUMENT;;
197 }
198
199 vg_lite_free_font_memory(font);
200 s_device_fonts[font].valid = 0;
201 return VG_LITE_SUCCESS;
202 }
203
vg_lite_get_font_name(vg_lite_font_t font)204 char *vg_lite_get_font_name(vg_lite_font_t font)
205 {
206 if ( vg_lite_is_font_valid(font) != 0 ) {
207 return NULL;
208 }
209
210 return (char *)s_device_fonts[font].font_params.name;
211 }
212
vg_lite_free_font_memory(vg_lite_font_t font)213 vg_lite_error_t vg_lite_free_font_memory(vg_lite_font_t font)
214 {
215 if ( vg_lite_is_font_valid(font) != 0 ) {
216 /* Font not found */
217 return VG_LITE_INVALID_ARGUMENT;
218 }
219 switch (s_device_fonts[font].font_params.font_type) {
220 case eFontTypeVector:
221 if ( s_device_fonts[font]._vector_font != NULL ) {
222 vft_unload(s_device_fonts[font]._vector_font);
223 s_device_fonts[font]._vector_font = NULL;
224 }
225 break;
226 case eFontTypeRaster:
227 if ( s_device_fonts[font]._raster_font != NULL ) {
228 free_rle_font_memory(&s_device_fonts[font]._raster_font);
229 s_device_fonts[font]._raster_font = NULL;
230 }
231 break;
232 }
233
234 return VG_LITE_SUCCESS;
235 }
236
_vg_lite_get_vector_font(vg_lite_font_t font)237 font_face_desc_t *_vg_lite_get_vector_font(vg_lite_font_t font)
238 {
239 if ( vg_lite_is_font_valid(font) != 0 ) {
240 return NULL;
241 }
242
243 return s_device_fonts[font]._vector_font;
244 }
245
_vg_lite_get_raster_font(vg_lite_font_t font)246 struct mf_font_s *_vg_lite_get_raster_font(vg_lite_font_t font)
247 {
248 if ( vg_lite_is_font_valid(font) != 0 ) {
249 return NULL;
250 }
251
252 return s_device_fonts[font]._raster_font;
253 }
254
vg_lite_load_font_data(vg_lite_font_t font,int font_height)255 vg_lite_error_t vg_lite_load_font_data(vg_lite_font_t font, int font_height)
256 {
257 if ( vg_lite_is_font_valid(font) != 0 ) {
258 /* Font not found */
259 return VG_LITE_INVALID_ARGUMENT;
260 }
261
262 switch (s_device_fonts[font].font_params.font_type) {
263 case eFontTypeVector:
264 if (s_device_fonts[font]._vector_font == NULL ) {
265 //printf("Loading vector font : [%s]\n",
266 // s_device_fonts[font].font_params.name);
267 s_device_fonts[font]._vector_font =
268 vft_load_from_buffer(
269 s_device_fonts[font].font_params.data,
270 s_device_fonts[font].font_params.data_len);
271 if ( s_device_fonts[font]._vector_font == NULL ) {
272 return VG_LITE_INVALID_ARGUMENT;
273 }
274 }
275 return VG_LITE_SUCCESS;
276 case eFontTypeRaster:
277 if (s_device_fonts[font]._raster_font == NULL ) {
278 //printf("Loading raster font : [%s]\n",
279 // s_device_fonts[font].font_params.name);
280 /* Raster fonts height should match */
281 if ( font_height == s_device_fonts[font].font_params.font_height &&
282 load_raster_font(
283 s_device_fonts[font].font_params.data,
284 s_device_fonts[font].font_params.data_len,
285 &s_device_fonts[font]._raster_font) != 0)
286 {
287 return VG_LITE_INVALID_ARGUMENT;
288 }
289 }
290 return VG_LITE_SUCCESS;
291 }
292 return VG_LITE_INVALID_ARGUMENT;
293 }
294
295
vg_lite_find_font(char * font_name_list,eFontWeight_t font_weight,eFontStretch_t font_stretch,eFontStyle_t font_style,int font_height)296 vg_lite_font_t vg_lite_find_font(
297 char *font_name_list,
298 eFontWeight_t font_weight,
299 eFontStretch_t font_stretch,
300 eFontStyle_t font_style,
301 int font_height)
302 {
303 int i;
304 char tmp_data;
305 int font_found = 0;
306 int end_pos = 0; /* End position of font name */
307 char *font_name;
308 /*
309 printf("Font params: [%s],%d, %d, %d, %d\n",
310 font_name_list,
311 font_weight,
312 font_stretch,
313 font_style,
314 font_height);
315 */
316
317 /* While probing font, if required font is found, then
318 only keep that name in supplied font list */
319
320 /* Split and extract font name one-by-one */
321 font_name = font_name_list;
322 while (font_found == 0 &&
323 font_name[end_pos] != '\0')
324 {
325 tmp_data = '\0';
326 /* Scan for seperator */
327 while (font_name[end_pos] != '\0') {
328 if (font_name[end_pos] == ',' || font_name[end_pos] == ' ' ||
329 font_name[end_pos] == '\t')
330 {
331 tmp_data = font_name[end_pos];
332 font_name[end_pos] = '\0';
333 break;
334 }
335 end_pos++;
336 }
337
338 /* Search for exact font-name match */
339 for (i=0; i<__COUNTOF(s_device_fonts); i++) {
340 if (s_device_fonts[i].valid == 0)
341 continue;
342
343 /* For vector font only compare name */
344 if (s_device_fonts[i].font_params.font_type == eFontTypeVector ) {
345 if ( strlen(font_name) > 0 &&
346 strcmp(font_name,
347 s_device_fonts[i].font_params.name) == 0)
348 {
349 font_name[end_pos] = tmp_data; /* Restor delimeter */
350 return i;
351 }
352 } else {
353 /* For raster font compare all properties */
354 if (s_device_fonts[i].font_params.font_weight == font_weight &&
355 s_device_fonts[i].font_params.font_stretch == font_stretch &&
356 s_device_fonts[i].font_params.font_style == font_style )
357 {
358 if ( strlen(font_name) > 0 &&
359 strcmp(font_name,
360 s_device_fonts[i].font_params.name) == 0)
361 {
362 font_name[end_pos] = tmp_data; /* Restor delimeter */
363
364 if (s_device_fonts[i].font_params.font_height == font_height)
365 {
366 return i;
367 }
368 /* Update font_name_list to improve future searches */
369 strncpy(font_name_list, font_name, strlen(font_name)+1);
370 }
371 }
372 }
373 }
374 /* Continue searching for other font entries */
375 font_name[end_pos] = tmp_data;
376 font_name += (end_pos + 1);
377 end_pos = 0;
378 }
379 printf("WARNING: [%s] Font not found\r\n",font_name_list);
380
381 return VG_LITE_INVALID_FONT;
382 }
383
vg_lite_text_init(void)384 void vg_lite_text_init(void)
385 {
386 static int font_table_ready = 0;
387
388 if (font_table_ready)
389 return;
390
391 /* Initialize font table */
392 memset(s_device_fonts, 0, MAX_SYSTEM_FONTS * sizeof(font_info_internal_t));
393 font_table_ready = 1;
394 }
395
396 /* Read-Write 8-bit unsigned int data */
read_8b(bufferred_reader_t * f,uint8_t * pdata)397 int read_8b(bufferred_reader_t * f, uint8_t* pdata)
398 {
399 bufferred_fread(pdata, 1, 1, f);
400 TRACE_DBG(("%d) 8b: fp=%08x %d %d\r\n", DBG_INC_ID(),
401 bufferred_ftell(f) - 1, 1, *pdata));
402 return 1;
403 }
404
405 /* Read-Write 16-bit unsigned int data */
read_16b(bufferred_reader_t * f,uint16_t * pword)406 int read_16b(bufferred_reader_t * f, uint16_t* pword)
407 {
408 uint8_t buf[4];
409 uint16_t word;
410
411 bufferred_fread(buf, 2, 1, f);
412 word = 0; word += buf[1];
413 word <<= 8; word += buf[0];
414
415 TRACE_DBG(("%d) 16b: fp=%08x %d %d\r\n", DBG_INC_ID(),
416 bufferred_ftell(f)-2, 2, word));
417 *pword = word;
418 return 2;
419 }
420
421 /* Read-write 32-bit unsigned int data */
read_32b(bufferred_reader_t * f,uint32_t * pword)422 int read_32b(bufferred_reader_t * f, uint32_t* pword)
423 {
424 uint8_t buf[4];
425 uint32_t word;
426
427 bufferred_fread(buf, 4, 1, f);
428 word = 0; word += buf[3];
429 word <<= 8; word += buf[2];
430 word <<= 8; word += buf[1];
431 word <<= 8; word += buf[0];
432
433 *pword = word;
434 TRACE_DBG(("%d) 32b: fp=%08x %d %d\r\n", DBG_INC_ID(),
435 bufferred_ftell(f) - 4, 4,
436 word));
437 return 4;
438 }
439
read_16b_blob(bufferred_reader_t * f,uint16_t ** ary,uint32_t * ary_len)440 int read_16b_blob(bufferred_reader_t * f, uint16_t** ary, uint32_t* ary_len)
441 {
442 uint16_t blob_len = 0;
443
444 *ary_len = 0;
445 bufferred_fread(&blob_len, 1, sizeof(uint16_t), f);
446 *ary = (uint16_t *)RCD_ALLOC(blob_len * sizeof(uint16_t)); /* Malloc must be aligned on 2 byte boundary */
447 if (*ary == NULL) {
448 TRACE_ERR(("ERROR: malloc failed\n"));;
449 return VG_LITE_OUT_OF_MEMORY;
450 }
451 if ((((unsigned long)*ary) & 0x1) != 0) {
452 TRACE_ERR(("ERROR: malloc pointer not 2 byte aligned\n"));;
453 return VG_LITE_NOT_ALIGNED;
454 }
455 TRACE_DBG(("%d ) 16b_blob: fp=%08x %d\r\n", DBG_INC_ID(), bufferred_ftell(f)-2,
456 (int)blob_len));
457 bufferred_fread(*ary, 2, blob_len, f);
458 *ary_len = blob_len * 2;
459
460 return blob_len + 2; /* Actual bytes read from file */
461 }
462
read_8b_blob(bufferred_reader_t * f,uint8_t ** ary,uint32_t * ary_len)463 int read_8b_blob(bufferred_reader_t * f, uint8_t** ary, uint32_t *ary_len)
464 {
465 uint16_t blob_len = 0;
466 uint8_t* p_tmp = (uint8_t *)NULL;
467 bufferred_fread(&blob_len, 1, sizeof(uint16_t), f);
468 //TRACE_DBG(("%d) 8b_blob: %d\r\n", DBG_INC_ID(), blob_len));
469 p_tmp = (uint8_t *)RCD_ALLOC(blob_len+1);
470 if (p_tmp == NULL) {
471 TRACE_ERR(("ERROR: malloc failed\n"));;
472 return VG_LITE_OUT_OF_MEMORY;
473 }
474 TRACE_DBG(("%d ) 8b_blob: fp=%08x %d\r\n", DBG_INC_ID(), bufferred_ftell(f)-2,
475 (int)blob_len));
476 bufferred_fread(p_tmp, 1, blob_len, f);
477 p_tmp[blob_len] = 0;
478 *ary = p_tmp;
479
480 return blob_len + 2; /* Actual bytes read from file */
481 }
482
483 #define EXIT_IF_NEGATIVE(param) if ((ret = param) < 0) return ret;
484
read_rle_font_header(bufferred_reader_t * f,struct mf_font_s * font)485 int read_rle_font_header(bufferred_reader_t * f, struct mf_font_s* font)
486 {
487 int raw_header_offset = 0;
488 struct mf_rlefont_s* mfont = (struct mf_rlefont_s*)font;
489 uint32_t size = 0;
490 int ret = 0;
491
492 TRACE_DBG(("** %s\r\n", __FUNCTION__));
493 DBG_SET_ID(0);
494
495 EXIT_IF_NEGATIVE(read_8b_blob(f, (uint8_t **)&font->full_name, &size));
496 raw_header_offset += ret; /* font.full_name */
497
498 EXIT_IF_NEGATIVE(read_8b_blob(f, (uint8_t **)&font->short_name, &size));
499 raw_header_offset += ret; /* font.short_name */
500
501 EXIT_IF_NEGATIVE(read_8b(f, &font->width));
502 raw_header_offset += 1; /* font.width */
503
504 EXIT_IF_NEGATIVE(read_8b(f, &font->height));
505 raw_header_offset += 1; /* font.height */
506
507 EXIT_IF_NEGATIVE(read_8b(f, &font->min_x_advance));
508 raw_header_offset += 1; /* font.min_x_advance */
509
510 EXIT_IF_NEGATIVE(read_8b(f, &font->max_x_advance));
511 raw_header_offset += 1; /* font.max_x_advance */
512
513 EXIT_IF_NEGATIVE(read_8b(f, (uint8_t *)&font->baseline_x));
514 raw_header_offset += 1; /* font.baseline_x */
515
516 EXIT_IF_NEGATIVE(read_8b(f, &font->baseline_y));
517 raw_header_offset += 1; /* font.baseline_y */
518
519 EXIT_IF_NEGATIVE(read_8b(f, &font->line_height));
520 raw_header_offset += 1; /* font.line_height */
521
522 EXIT_IF_NEGATIVE(read_8b(f, &font->flags));
523 raw_header_offset += 1; /* font.flags */
524
525 EXIT_IF_NEGATIVE(read_16b(f, &font->fallback_character));
526 raw_header_offset += 2; /* font.fallback_character */
527
528 EXIT_IF_NEGATIVE(read_8b(f, &(mfont->version)));
529 raw_header_offset += 1; /* mf_rlefont_s.version */
530
531 /* Other mf_rlefont_s variables */
532 uint16_t value = 0;
533 EXIT_IF_NEGATIVE(read_16b(f, &value)); //&mfont->dictionary_data_size));
534 mfont->dictionary_data_size = value;
535 raw_header_offset += 2; /* mf_rlefont_s.dictionary_data_size */
536
537 EXIT_IF_NEGATIVE(read_32b(f, &mfont->dictionary_data_fp_offset));
538 raw_header_offset += 4; /* mf_rlefont_s.dictionary_data_fp_offset */
539
540 value = 0;
541 EXIT_IF_NEGATIVE(read_16b(f, &value)); //mfont->dictionary_offsets_size));
542 mfont->dictionary_offsets_size = value;
543 raw_header_offset += 2; /* mf_rlefont_s.dictionary_data_size */
544
545 EXIT_IF_NEGATIVE(read_32b(f, &mfont->dictionary_offsets_fp_offset));
546 raw_header_offset += 4; /* mf_rlefont_s.dictionary_data_fp_offset */
547
548 EXIT_IF_NEGATIVE(read_8b(f, &mfont->rle_entry_count));
549 raw_header_offset += 1; /* mf_rlefont_s.rle_entry_count */
550
551 EXIT_IF_NEGATIVE(read_8b(f, &mfont->dict_entry_count));
552 raw_header_offset += 1; /* mf_rlefont_s.dict_entry_count */
553
554 EXIT_IF_NEGATIVE(read_8b(f, &mfont->char_range_count));
555 raw_header_offset += 1; /* mf_rlefont_s.char_range_count */
556
557 mfont->char_ranges = (struct mf_rlefont_char_range_s *)RCD_ALLOC(sizeof(struct mf_rlefont_char_range_s)* mfont->char_range_count);
558 memset(mfont->char_ranges, 0, sizeof(struct mf_rlefont_char_range_s) * mfont->char_range_count);
559
560 /* Skip size of ranges */
561 for (int r = 0; r < mfont->char_range_count; r++) {
562 EXIT_IF_NEGATIVE(read_16b(f, &mfont->char_ranges[r].first_char));
563 raw_header_offset += 2; /* mf_rlefont_s.char_ranges[r].first_char */
564
565 EXIT_IF_NEGATIVE(read_16b(f, &mfont->char_ranges[r].char_count));
566 raw_header_offset += 2; /* mf_rlefont_s.char_ranges[r].char_count */
567
568 EXIT_IF_NEGATIVE(read_32b(f, &mfont->char_ranges[r].glyph_offsets_fp_offset));
569 raw_header_offset += 4; /* mf_rlefont_s.char_ranges[r].glyph_offsets_fp_offset */
570
571 EXIT_IF_NEGATIVE(read_32b(f, &mfont->char_ranges[r].glyph_offsets_size));
572 raw_header_offset += 4; /* mf_rlefont_s.char_ranges[r].glyph_offsets_size */
573
574 EXIT_IF_NEGATIVE(read_32b(f, &mfont->char_ranges[r].glyph_data_fp_offset));
575 raw_header_offset += 4; /* mf_rlefont_s.char_ranges[r].glyph_offsets_fp_offset */
576
577 EXIT_IF_NEGATIVE(read_32b(f, &mfont->char_ranges[r].glyph_data_size));
578 raw_header_offset += 4; /* mf_rlefont_s.char_ranges[r].glyph_offsets_size */
579 }
580 return raw_header_offset;
581 }
582
583 /* Writes a BMP file. The data is assumed to be 8-bit grayscale. */
read_rle_font_from_buffer(char * buff,int size,struct mf_font_s * font)584 int read_rle_font_from_buffer(char *buff, int size, struct mf_font_s* font)
585 {
586 struct mf_rlefont_s* mfont = (struct mf_rlefont_s*)font;
587 bufferred_reader_t f_obj;
588 bufferred_reader_t * f = &f_obj;
589 int raw_header_offset = 0;
590 int fp_offset;
591 int ret;
592
593 DBG_SET_ID(0);
594
595 /* No need to dynamically allocate small descriptor */
596 if ( bufferred_fopen(f, buff, size) < 0 ) {
597 /* Font file open failed */
598 return VG_LITE_INVALID_ARGUMENT;
599 }
600
601 raw_header_offset = read_rle_font_header(f, font);
602 if (mfont->dictionary_data_fp_offset != raw_header_offset) {
603 TRACE_ERR(("ERROR: dictonary offset is different"));
604 }
605 TRACE_DBG(("** %s\r\n", __FUNCTION__));
606 DBG_SET_ID(0);
607
608 /* Skip header portion */
609 bufferred_fseek(f, raw_header_offset, SEEK_SET);
610 /* Write dictionary entries */
611 fp_offset = raw_header_offset;
612 TRACE_DBG(("dictionary_data_fp_offset=%08x %08x\r\n",
613 mfont->dictionary_data_fp_offset, bufferred_ftell(f)));
614 //mfont->dictionary_data_fp_offset = fp_offset;
615 EXIT_IF_NEGATIVE(read_8b_blob(f, &mfont->dictionary_data,
616 &mfont->dictionary_data_size));
617 fp_offset += mfont->dictionary_data_size + 2;
618
619 //mfont->dictionary_offsets_fp_offset = fp_offset;
620 TRACE_DBG(("dictionary_offsets_fp_offset=%08x %08x\r\n",
621 mfont->dictionary_offsets_fp_offset, bufferred_ftell(f)));
622 EXIT_IF_NEGATIVE(read_16b_blob(f, &mfont->dictionary_offsets,
623 &mfont->dictionary_offsets_size));
624 fp_offset += mfont->dictionary_offsets_size + 2;
625
626 /* Write range entries */
627 for (int r = 0; r < mfont->char_range_count; r++) {
628 //mfont->char_ranges[r].glyph_offsets_fp_offset = fp_offset;
629 TRACE_DBG(("mfont->char_ranges[%d].glyph_offsets=%08x %08x\r\n", r,
630 mfont->char_ranges[r].glyph_offsets_fp_offset, bufferred_ftell(f)));
631 EXIT_IF_NEGATIVE(read_16b_blob(f, &mfont->char_ranges[r].glyph_offsets,
632 &mfont->char_ranges[r].glyph_offsets_size));
633 fp_offset += mfont->char_ranges[r].glyph_offsets_size + 2;
634
635 //mfont->char_ranges[r].glyph_data_fp_offset = fp_offset;
636 TRACE_DBG(("mfont->char_ranges[%d].glyph_data_fp_offset=%08x %08x\r\n",
637 r,
638 mfont->char_ranges[r].glyph_data_fp_offset, bufferred_ftell(f)));
639 EXIT_IF_NEGATIVE(read_8b_blob(f, &mfont->char_ranges[r].glyph_data,\
640 &mfont->char_ranges[r].glyph_data_size));
641 fp_offset += mfont->char_ranges[r].glyph_data_size + 2;
642 }
643
644 bufferred_fclose(f);
645 return 0;
646 }
647
load_raster_font(char * data,int data_len,struct mf_font_s ** font)648 int load_raster_font(char *data, int data_len, struct mf_font_s** font)
649 {
650 int ret;
651
652 /* Allocate font memory */
653 *font = (struct mf_font_s*)RCD_ALLOC(sizeof(struct mf_rlefont_s));
654 if (*font == NULL) {
655 return VG_LITE_OUT_OF_MEMORY;
656 }
657 memset(*font, 0, sizeof(struct mf_rlefont_s));
658
659 /* Load font from file */
660 ret = read_rle_font_from_buffer(data,
661 data_len, *font);
662 if (ret < 0) {
663 return ret;
664 }
665
666 /* Update generic char width pointers of mculib */
667 uint8_t mf_rlefont_character_width(const struct mf_font_s* font,
668 uint16_t character);
669 uint8_t mf_rlefont_render_character(const struct mf_font_s* font,
670 int16_t x0, int16_t y0,
671 uint16_t character,
672 mf_pixel_callback_t callback,
673 void* state);
674
675 (*font)->character_width = &mf_rlefont_character_width;
676 (*font)->render_character = &mf_rlefont_render_character;
677
678
679 return 0;
680 }
681
free_rle_font_memory(struct mf_font_s ** font)682 int free_rle_font_memory(struct mf_font_s** font)
683 {
684 struct mf_rlefont_s* mfont = (struct mf_rlefont_s*)(*font);
685
686 RCD_FREE(mfont->font.full_name);
687 RCD_FREE(mfont->font.short_name);
688 RCD_FREE(mfont->dictionary_data);
689 RCD_FREE(mfont->dictionary_offsets);
690 for (int r = 0; r < mfont->char_range_count; r++) {
691 RCD_FREE(mfont->char_ranges[r].glyph_offsets);
692 RCD_FREE(mfont->char_ranges[r].glyph_data);
693 }
694 #ifdef DEBUG_RESET_DATASTRUCTURE_ON_FREE
695 memset(mfont->char_ranges);
696 #endif
697 RCD_FREE(mfont->char_ranges);
698
699 #ifdef DEBUG_RESET_DATASTRUCTURE_ON_FREE
700 memset(mfont);
701 #endif
702 RCD_FREE(mfont);
703
704 *font = NULL;
705 return 0;
706 }
707
vg_lite_unload_font_data(void)708 void vg_lite_unload_font_data(void)
709 {
710 for(int i=0; i<MAX_SYSTEM_FONTS; i++)
711 {
712 vg_lite_free_font_memory(i);
713 }
714
715 return;
716 }
717