1 /****************************************************************************
2 *
3 *    Copyright 2020 NXP
4 *    All Rights Reserved.
5 *
6 *    Permission is hereby granted, free of charge, to any person obtaining
7 *    a copy of this software and associated documentation files (the
8 *    'Software'), to deal in the Software without restriction, including
9 *    without limitation the rights to use, copy, modify, merge, publish,
10 *    distribute, sub license, and/or sell copies of the Software, and to
11 *    permit persons to whom the Software is furnished to do so, subject
12 *    to the following conditions:
13 *
14 *    The above copyright notice and this permission notice (including the
15 *    next paragraph) shall be included in all copies or substantial
16 *    portions of the Software.
17 *
18 *    THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
19 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 *    IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
22 *    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 *    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *****************************************************************************/
27 
28 /*
29   ElmDrawText API
30  */
31 /** Include Files */
32 #include <stdio.h> // for snprintf
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "vg_lite.h"
37 #include "Elm.h"
38 #include "velm.h"
39 #include "vg_lite_text.h"
40 #include "elm_headers.h"
41 #include "elm_text.h"
42 #include "elm_precom.h"
43 #include "vft_draw.h"
44 
45 /** Macros */
46 #ifndef VECTOR_DEFAULT_FONT
47 #define VECTOR_DEFAULT_FONT 1
48 #endif
49 
50 #if VECTOR_DEFAULT_FONT /* Use vector font as default font */
51 #define DEFAULT_FONT_NAME    "SVGFreeSansASCII"
52 #define DEFAULT_FONT_WEIGHT  eFontWeightRegular
53 #define DEFAULT_FONT_STRETCH eFontStretchNormal
54 #define DEFAULT_FONT_STYLE   eFontStyleNormal
55 #define DEFAULT_FONT_HEIGHT  35
56 #define DEFAULT_TEXT_FG_COLOR   0xff000000
57 #define DEFAULT_TEXT_ALIGN  (eTextAlignLeft)
58 
59 #else /* Use raster font as default font */
60 #define DEFAULT_FONT_NAME    "DejaVuSans_Oblique"
61 #define DEFAULT_FONT_WEIGHT  eFontWeightRegular
62 #define DEFAULT_FONT_STRETCH eFontStretchNormal
63 #define DEFAULT_FONT_STYLE   eFontStyleItalic
64 #define DEFAULT_FONT_HEIGHT  35
65 #define DEFAULT_TEXT_FG_COLOR   0xff000000
66 #define DEFAULT_TEXT_ALIGN  (eTextAlignLeft)
67 
68 #endif
69 
70 /* Maximum font properties from EVO file */
71 #define MAX_FONT_ATTRIB_COMBINATIONS (32)
72 
73 #define TRANSPARENT_VGLITE_COLOUR(a, r, g, b) \
74     ((uint32_t)(a) << 24) | ((uint32_t)(b) << 16) | ((uint32_t)(g) << 8) | \
75     (uint32_t)r
76 
77 #define OPAQUE_VGLITE_COLOUR(r, g, b)   TRANSPARENT_VGLITE_COLOUR(0xff, r, g, b)
78 
79 /** Data structures */
80 
81 /** Internal or external API prototypes */
82 int vg_lite_is_font_valid(vg_lite_font_t font);
83 char *vg_lite_get_font_name(vg_lite_font_t font);
84 vg_lite_error_t vg_lite_free_font_memory(vg_lite_font_t font);
85 int         ref_object      (el_Object     *object);
86 
87 /** Globals */
88 int g_total_system_font = 0;
89 static font_field_info_t g_default_font_properties[eMaxFontProperties];
90 static font_field_info_t g_font_properties[MAX_FONT_ATTRIB_COMBINATIONS][eMaxFontProperties];
91 
92 /** Externs if any */
93 extern vg_lite_font_attributes_t g_font_attribs;
94 extern vg_lite_font_t g_last_font;
95 extern int g_last_font_attrib_idx;
96 
initialize_elm_text(void)97 void initialize_elm_text(void)
98 {
99     font_field_info_t *font_fields = NULL;
100     /* internal parameters of mcufont library */
101     g_font_attribs.alignment = 0;
102     g_font_attribs.scale = 1;
103     g_font_attribs.width = 1200; /* Describes drawing area */
104     g_font_attribs.margin = 5; /* Left margin in drawing area */
105     g_font_attribs.bg_color = OPAQUE_VGLITE_COLOUR(0xff,0xff,0xff); // white
106     g_font_attribs.last_y = 0;
107     g_font_attribs.last_x =0;
108     g_font_attribs.last_dx = 0;
109 
110     /* Initialize default properties */
111     font_fields = &g_default_font_properties[0];
112 
113     char *font_name = (char *)elm_alloc(1, strlen(DEFAULT_FONT_NAME)+1);
114     strcpy(font_name, DEFAULT_FONT_NAME);
115     font_fields[eFontNameProperty].value.data = font_name;
116     font_fields[eFontWeightProperty].value.i_value = DEFAULT_FONT_WEIGHT;
117     font_fields[eFontStretchProperty].value.i_value = DEFAULT_FONT_STRETCH;
118     font_fields[eFontStyleProperty].value.i_value = DEFAULT_FONT_STYLE;
119     font_fields[eFontHeightProperty].value.i_value = DEFAULT_FONT_HEIGHT;
120     font_fields[eTextColorProperty].value.i_value = DEFAULT_TEXT_FG_COLOR;
121     font_fields[eTextAlignProperty].value.i_value = DEFAULT_TEXT_ALIGN;
122 }
123 
get_property(font_field_info_t * dst_font_fields,font_fields_t * src_font_fields,int num_fields)124 static int get_property(font_field_info_t *dst_font_fields, font_fields_t *src_font_fields, int num_fields)
125 {
126     int i=0;
127     int len;
128 
129     /* Initialize default values */
130     dst_font_fields[eFontWeightProperty].value.i_value = DEFAULT_FONT_WEIGHT;
131     dst_font_fields[eFontStretchProperty].value.i_value = DEFAULT_FONT_STRETCH;
132     dst_font_fields[eFontStyleProperty].value.i_value = eFontStyleNormal;
133     dst_font_fields[eTextAlignProperty].value.i_value = DEFAULT_TEXT_ALIGN;
134 
135     dst_font_fields[eFontNameProperty].value.data = NULL;
136     dst_font_fields[eFontHeightProperty].value.i_value = DEFAULT_FONT_HEIGHT;
137     dst_font_fields[eTextColorProperty].value.i_value = DEFAULT_TEXT_FG_COLOR;
138 
139     for(i=0; i<num_fields; i++)
140     {
141         if(src_font_fields[i].info.eName == FONT_FAMILY ||
142            src_font_fields[i].info.eName == FONT_WEIGHT ||
143            src_font_fields[i].info.eName == FONT_STRETCH ||
144            src_font_fields[i].info.eName == FONT_STYLE ||
145            src_font_fields[i].info.eName == TEXT_ANCHOR )
146         {
147             switch(src_font_fields[i].info.eName)
148             {
149                 case FONT_FAMILY:
150                     len = strlen((char *)src_font_fields[i].data);
151                     dst_font_fields[eFontNameProperty].eName = FONT_FAMILY;
152                     dst_font_fields[eFontNameProperty].value.data =
153                         (char *)elm_alloc(1, len+1);
154                     strcpy(dst_font_fields[eFontNameProperty].value.data,
155                          (char *)src_font_fields[i].data);
156                     dst_font_fields[eFontNameProperty].value.data[len] = '\0';
157                     break;
158                 case FONT_WEIGHT:
159                     dst_font_fields[eFontWeightProperty].eName = FONT_WEIGHT;
160                     dst_font_fields[eFontWeightProperty].value.i_value =
161                         (eFontWeight_t)src_font_fields[i].info.value.i_value;
162                     break;
163                 case FONT_STRETCH:
164                     dst_font_fields[eFontStretchProperty].eName = FONT_STRETCH;
165                     dst_font_fields[eFontStretchProperty].value.i_value =
166                       (eFontStretch_t)src_font_fields[i].info.value.i_value;
167                     break;
168                 case FONT_STYLE:
169                     dst_font_fields[eFontStyleProperty].eName = FONT_STYLE;
170                     dst_font_fields[eFontStyleProperty].value.i_value =
171                         (eFontStyle_t)src_font_fields[i].info.value.i_value;
172                     break;
173                 case TEXT_ANCHOR:
174                     dst_font_fields[eTextAlignProperty].eName = TEXT_ANCHOR;
175                     dst_font_fields[eTextAlignProperty].value.i_value =
176                         (eTextAlign_t)src_font_fields[i].info.value.i_value;
177                     break;
178                 default:
179                     break;
180             }
181         }
182     }
183     return 0;
184 }
185 
draw_text(el_Obj_Buffer * buff,el_Obj_EVO * evo,vg_lite_matrix_t * mat)186 vg_lite_error_t draw_text(el_Obj_Buffer *buff,
187                                  el_Obj_EVO *evo, vg_lite_matrix_t *mat)
188 {
189     vg_lite_error_t error = VG_LITE_INVALID_ARGUMENT;
190     el_Obj_TEXT *text = (el_Obj_TEXT *)evo;
191     vg_lite_blend_t blend = (vg_lite_blend_t)text->attribute.blend;
192     vg_lite_font_t curr_font = VG_LITE_INVALID_FONT;
193     int curr_font_attrib_idx = INVALID_FONT_PROPERTY_IDX;
194 
195     vg_lite_font_attributes_t *font_attribs = &g_font_attribs;
196     font_field_info_t *font_fields = NULL;
197 
198     curr_font_attrib_idx = text->font_id;
199 
200     /* Single font caching can be done here (No caching for now)
201        Release last font object if it is different
202      */
203     if ( vg_lite_is_font_valid(g_last_font) == 1 ) {
204       /* recycle font objects */
205       vg_lite_free_font_memory(g_last_font);
206       g_last_font = VG_LITE_INVALID_FONT;
207     }
208 
209     if(curr_font_attrib_idx != INVALID_FONT_PROPERTY_IDX)
210     {
211         font_fields = &g_font_properties[curr_font_attrib_idx][0];
212         font_fields[eFontHeightProperty].value.i_value = text->font_size;
213 
214         curr_font = vg_lite_find_font(
215             font_fields[eFontNameProperty].value.data,
216             (eFontWeight_t)font_fields[eFontWeightProperty].value.i_value,
217             (eFontStretch_t)font_fields[eFontStretchProperty].value.i_value,
218             (eFontStyle_t)font_fields[eFontStyleProperty].value.i_value,
219             font_fields[eFontHeightProperty].value.i_value
220             );
221     }
222 
223     if (curr_font == VG_LITE_INVALID_FONT) {
224         //printf("ERROR: Font not found. Rendering with default configuration\n");
225         font_fields = &g_default_font_properties[0];
226             curr_font = vg_lite_find_font(
227                 font_fields[eFontNameProperty].value.data,
228                 (eFontWeight_t)font_fields[eFontWeightProperty].value.i_value,
229                 (eFontStretch_t)font_fields[eFontStretchProperty].value.i_value,
230                 (eFontStyle_t)font_fields[eFontStyleProperty].value.i_value,
231                 font_fields[eFontHeightProperty].value.i_value);
232     }
233     if (curr_font == VG_LITE_INVALID_FONT) {
234         printf("Font[%s] not found\n", font_fields[eFontNameProperty].value.data);
235         return VG_LITE_INVALID_ARGUMENT;
236     }
237     font_attribs->is_vector_font = vg_lite_is_vector_font(curr_font);
238     /* Properties that changes over time */
239     font_attribs->text_color = text->attribute.paint.color;
240     font_attribs->alignment = (eTextAlign_t)text->text_anchor;
241     font_attribs->font_height = font_fields[eFontHeightProperty].value.i_value;
242     font_attribs->tspan_has_dx_dy = text->tspan_has_dx_dy;
243 
244     error = vg_lite_draw_text(&buff->buffer,
245                (char *)text->msg,
246                curr_font,
247                text->x_pos, text->y_pos,
248                &text->attribute.transform.matrix,
249                blend,
250                font_attribs);
251 
252     g_last_font = curr_font;
253     g_last_font_attrib_idx = curr_font_attrib_idx;
254     return error;
255 }
256 
257 /* process font-field data */
_process_font_field_data(uint8_t * data_start,uint8_t * data,int num_fields,font_fields_t * fields)258 static int _process_font_field_data( uint8_t *data_start, uint8_t *data, int num_fields, font_fields_t* fields)
259 {
260     eFontFields_t eName;
261 
262     if (g_total_system_font >= MAX_FONT_ATTRIB_COMBINATIONS) {
263       printf("WARNING: Font property buffer overflowing...\n"
264              "Increase MAX_FONT_ATTRIB_COMBINATIONS\n");
265       return -1;
266     }
267 
268     for(int i=0; i<num_fields; i++)
269     {
270         fields[i].info.eName = (eFontFields_t)*(uint32_t *)(data + (0 + 3*i) * 4);
271         fields[i].offset = *(uint32_t *)(data + (1 + 3*i)* 4);
272         fields[i].data = NULL;
273         eName = fields[i].info.eName;
274         if(eName == FONT_SIZE ||
275            eName == HORIZ_ORIGIN_X ||
276            eName == HORIZ_ADV_X ||
277            eName == ASCENT ||
278            eName == ALPHABETIC ||
279            eName == CAP_HEIGHT ||
280            eName == DESCENT ||
281            eName == SLOPE ||
282            eName == UNITS_PER_EM ||
283            eName == X_HEIGHT
284             )
285         {
286             fields[i].info.value.f_value = *(float *)(data + (2 + 3*i)* 4);
287         }
288         else
289         {
290             fields[i].info.value.i_value = *(uint32_t *)(data + (2 + 3*i)* 4);
291         }
292 
293         if(fields[i].offset != 0)
294         {
295             fields[i].size = *(uint16_t *)(data_start + fields[i].offset);
296             fields[i].data = (uint8_t *)elm_alloc(1, fields[i].size+1);
297             memset(fields[i].data,0, fields[i].size+1);
298             memcpy(fields[i].data, (void *)(data_start + fields[i].offset + 2), fields[i].size);
299         }
300     }
301 
302     memset(&g_font_properties[g_total_system_font][0], 0,
303            sizeof(font_fields_t)*eMaxFontProperties);
304     get_property(g_font_properties[g_total_system_font], fields, num_fields);
305     g_total_system_font++;
306 
307     return 0;
308 }
309 
310 /* process ttf-type font data */
_process_ttf_font_data(uint8_t * data_start,uint8_t * void_data,font_block_t * fontblockobj,int id)311 static int _process_ttf_font_data(uint8_t *data_start, uint8_t *void_data, font_block_t *fontblockobj, int id)
312 {
313     unsigned int num_fields;
314     uint8_t * data = (uint8_t *) void_data;
315 
316     fontblockobj->ttf_fonts[id].id = *(uint32_t *)(data);
317     fontblockobj->ttf_fonts[id].type = (eElemType_t)*(uint32_t *)(data + 1 * 4);
318     num_fields = *(uint32_t *)(data + 2 * 4);
319     fontblockobj->ttf_fonts[id].num_fields = num_fields;
320     fontblockobj->ttf_fonts[id].fields = (font_fields_t *)elm_alloc(1, num_fields * sizeof(font_fields_t));
321 
322     _process_font_field_data(data_start, (uint8_t*)(data + 3 * 4), num_fields, fontblockobj->ttf_fonts[id].fields);
323     return 0;
324 }
325 
326 /* process vector-type font data */
_process_vector_font_data(uint8_t * data_start,uint8_t * data,font_block_t * fontblockobj,int id)327 static int _process_vector_font_data(uint8_t *data_start, uint8_t *data, font_block_t *fontblockobj, int id)
328 {
329     unsigned int num_fields = 0;
330 
331     fontblockobj->vector_fonts[id].id = *(uint32_t *)(data);
332     fontblockobj->vector_fonts[id].type = (eElemType_t)*(uint32_t *)(data + 1 * 4);
333     num_fields = *(uint32_t *)(data + 2 * 4);
334     fontblockobj->vector_fonts[id].num_fields = num_fields;
335     fontblockobj->vector_fonts[id].fields = (font_fields_t *)elm_alloc(1, num_fields * sizeof(font_fields_t));
336 
337     _process_font_field_data(data_start, (uint8_t*)(data + 3 * 4), num_fields, fontblockobj->vector_fonts[id].fields);
338 
339     return 0;
340 }
341 
_process_text_font_data(uint8_t * data_start,uint8_t * void_data,font_block_t * fontblockobj,int id)342 static int _process_text_font_data(uint8_t *data_start, uint8_t *void_data, font_block_t *fontblockobj, int id)
343 {
344     unsigned int num_fields;
345     uint8_t * data = (uint8_t *) void_data;
346 
347     fontblockobj->text_fonts[id].id = *(uint32_t *)(data);
348     fontblockobj->text_fonts[id].type = (eElemType_t)*(uint32_t *)(data + 1 * 4);
349     num_fields = *(uint32_t *)(data + 2 * 4);
350     fontblockobj->text_fonts[id].num_fields = num_fields;
351     fontblockobj->text_fonts[id].fields = (font_fields_t *)elm_alloc(1, num_fields * sizeof(font_fields_t));
352 
353     _process_font_field_data(data_start, (uint8_t*)(data + 3 * 4), num_fields, fontblockobj->text_fonts[id].fields);
354     return 0;
355 }
356 
alloc_mem(uint32_t size)357 static uint32_t *alloc_mem(uint32_t size)
358 {
359     uint32_t *data = NULL;
360     data = (uint32_t *)elm_alloc(1, size);
361     JUMP_IF_NULL(data, error_exit);
362 #ifdef ENABLE_STRICT_DEBUG_MEMSET
363     memset(data, 0, size);
364 #endif
365     return data;
366 error_exit:
367     return NULL;
368 }
369 
370 font_block_t *fontblockobj = NULL;
371 
372 /* load font-data */
_load_font_data(uint8_t * data)373 int _load_font_data(uint8_t *data)
374 {
375     el_Font_Header *font_header = (el_Font_Header *)data;
376 
377     if ( fontblockobj != NULL )
378     {
379         return -1;
380     }
381 
382     fontblockobj = (font_block_t *)elm_alloc(1, sizeof(font_block_t));
383     memset(fontblockobj, 0, sizeof(font_block_t));
384 
385     fontblockobj->size                          = font_header->size_font_block;
386     fontblockobj->type                          = eElemTypeFont;
387     fontblockobj->num_ttf_fonts                 = font_header->num_ttf_fonts;
388     fontblockobj->num_vector_fonts              = font_header->num_vector_fonts;
389     fontblockobj->num_text_fonts                = font_header->num_text_fonts;
390     fontblockobj->ttf_fonts_block_offset        = font_header->ttf_fonts_block_offset;
391     fontblockobj->ttf_fonts_block_length        = font_header->ttf_fonts_block_length;
392     fontblockobj->vector_fonts_block_offset     = font_header->vector_fonts_block_offset;
393     fontblockobj->vector_fonts_block_length     = font_header->vector_fonts_block_length;
394     fontblockobj->text_fonts_block_offset       = font_header->text_fonts_block_offset;
395     fontblockobj->text_fonts_block_length       = font_header->text_fonts_block_length;
396     fontblockobj->property_block_offset         = font_header->property_block_offset;
397     fontblockobj->property_block_length         = font_header->property_block_length;
398 #ifdef ENABLE_DEBUG_TRACE
399     printf("size: %d(%0x)\n", fontblockobj->size, fontblockobj->size);
400     printf("type: %d\n", fontblockobj->type);
401     printf("num_ttf_fonts: %d\n", fontblockobj->num_ttf_fonts);
402     printf("num_vector_fonts: %d\n", fontblockobj->num_vector_fonts);
403     printf("num_text_fonts: %d\n", fontblockobj->num_text_fonts);
404     printf("ttf_fonts_block_offset: %d(%0x)\n", fontblockobj->ttf_fonts_block_offset,
405         fontblockobj->ttf_fonts_block_offset);
406     printf("ttf_fonts_block_length: %d(%0x)\n", fontblockobj->ttf_fonts_block_length,
407         fontblockobj->ttf_fonts_block_length);
408     printf("vector_fonts_block_offset: %d(%0x)\n", fontblockobj->vector_fonts_block_offset,
409         fontblockobj->vector_fonts_block_offset);
410     printf("vector_fonts_block_length: %d(%0x)\n", fontblockobj->vector_fonts_block_length,
411         fontblockobj->vector_fonts_block_length);
412     printf("text_fonts_block_offset: %d(%0x)\n", fontblockobj->text_fonts_block_offset,
413         fontblockobj->text_fonts_block_offset);
414     printf("text_fonts_block_length: %d(%0x)\n", fontblockobj->text_fonts_block_length,
415         fontblockobj->text_fonts_block_length);
416     printf("property_block_offset: %d(%0x)\n", fontblockobj->property_block_offset,
417         fontblockobj->property_block_offset);
418     printf("property_block_length: %d(%0x)\n", fontblockobj->property_block_length,
419         fontblockobj->property_block_length);
420 #endif
421 
422     g_total_system_font = 0;
423 
424     if ( fontblockobj->num_ttf_fonts > 0 ) {
425         fontblockobj->sizes_of_ttf_data =
426             (unsigned int *)alloc_mem(4 * fontblockobj->num_ttf_fonts);
427         fontblockobj->offsets_of_ttf_data =
428             (unsigned int *)alloc_mem(4 * fontblockobj->num_ttf_fonts);
429         fontblockobj->ttf_fonts = NULL;
430         fontblockobj->ttf_fonts = (ttf_font_t *)elm_alloc(1, fontblockobj->num_ttf_fonts * sizeof(ttf_font_t));
431         JUMP_IF_NULL(fontblockobj->sizes_of_ttf_data, error_exit);
432         JUMP_IF_NULL(fontblockobj->offsets_of_ttf_data, error_exit);
433         JUMP_IF_NULL(fontblockobj->ttf_fonts, error_exit);
434 
435         memset(fontblockobj->ttf_fonts, 0, fontblockobj->num_ttf_fonts * sizeof(ttf_font_t));
436         for(int i=0; i<fontblockobj->num_ttf_fonts; i++)
437         {
438             fontblockobj->sizes_of_ttf_data[i] = *(uint32_t *)(data + (i) * 4 + fontblockobj->ttf_fonts_block_offset);
439             printf("ttf-DataSize: %d(%0x)\n", fontblockobj->sizes_of_ttf_data[i],
440                 fontblockobj->sizes_of_ttf_data[i]);
441             fontblockobj->offsets_of_ttf_data[i] = *(uint32_t *)(data + (i + fontblockobj->num_ttf_fonts) * 4 + fontblockobj->ttf_fonts_block_offset);
442             printf("ttf-offset: %d(%0x)\n", fontblockobj->offsets_of_ttf_data[i],
443                 fontblockobj->offsets_of_ttf_data[i]);
444 
445             if (fontblockobj->sizes_of_ttf_data[i] == 0)
446             {
447                 continue;
448             }
449 
450             _process_ttf_font_data(data, (uint8_t *)(data + fontblockobj->offsets_of_ttf_data[i]), fontblockobj, i);
451         }
452     }
453 
454     if ( fontblockobj->num_vector_fonts > 0 ) {
455         fontblockobj->sizes_of_vector_data =
456             (unsigned int *)alloc_mem(4 * fontblockobj->num_vector_fonts);
457         fontblockobj->offsets_of_vector_data =
458             (unsigned int *)alloc_mem(4 * fontblockobj->num_vector_fonts);
459         fontblockobj->vector_fonts = NULL;
460         fontblockobj->vector_fonts = (vector_font_t *)elm_alloc(1, fontblockobj->num_vector_fonts * sizeof(vector_font_t));
461         JUMP_IF_NULL(fontblockobj->sizes_of_vector_data, error_exit);
462         JUMP_IF_NULL(fontblockobj->offsets_of_vector_data, error_exit);
463         JUMP_IF_NULL(fontblockobj->vector_fonts, error_exit);
464 
465         memset(fontblockobj->vector_fonts, 0, fontblockobj->num_vector_fonts * sizeof(vector_font_t));
466         for(int i=0; i<fontblockobj->num_vector_fonts; i++)
467         {
468             fontblockobj->sizes_of_vector_data[i] = *(uint32_t *)(data + (i) * 4 + fontblockobj->vector_fonts_block_offset);
469 #ifdef ENABLE_DEBUG_TRACE
470             printf("vector-DataSize: %d(%0x)\n", fontblockobj->sizes_of_vector_data[i],
471                 fontblockobj->sizes_of_vector_data[i]);
472 #endif
473             fontblockobj->offsets_of_vector_data[i] = *(uint32_t *)(data + (i + fontblockobj->num_vector_fonts) * 4 + fontblockobj->vector_fonts_block_offset);
474 #ifdef ENABLE_DEBUG_TRACE
475             printf("vector-offset: %d(%0x)\n", fontblockobj->offsets_of_vector_data[i],
476                 fontblockobj->offsets_of_vector_data[i]);
477 #endif
478 
479             if (fontblockobj->sizes_of_vector_data[i] == 0)
480             {
481                 continue;
482             }
483 
484             _process_vector_font_data(data, (uint8_t *)(data + fontblockobj->offsets_of_vector_data[i]), fontblockobj, i);
485         }
486     }
487 
488     if ( fontblockobj->num_text_fonts > 0 ) {
489         fontblockobj->sizes_of_text_font_data =
490           (unsigned int *)alloc_mem(4 * fontblockobj->num_text_fonts);
491         fontblockobj->offsets_of_text_font_data =
492           (unsigned int *)alloc_mem(4 * fontblockobj->num_text_fonts);
493         fontblockobj->text_fonts = NULL;
494         fontblockobj->text_fonts = (ttf_font_t *)elm_alloc(1, fontblockobj->num_text_fonts * sizeof(ttf_font_t));
495         JUMP_IF_NULL(fontblockobj->sizes_of_text_font_data, error_exit);
496         JUMP_IF_NULL(fontblockobj->offsets_of_text_font_data, error_exit);
497         JUMP_IF_NULL(fontblockobj->text_fonts, error_exit);
498         memset(fontblockobj->text_fonts, 0, fontblockobj->num_text_fonts * sizeof(ttf_font_t));
499         for(int i=0; i<fontblockobj->num_text_fonts; i++)
500         {
501             fontblockobj->sizes_of_text_font_data[i] = *(uint32_t *)(data + (i) * 4 + fontblockobj->text_fonts_block_offset);
502 #ifdef ENABLE_DEBUG_TRACE
503             printf("textfont-DataSize: %d(%0x)\n", fontblockobj->sizes_of_text_font_data[i],
504                 fontblockobj->sizes_of_text_font_data[i]);
505 #endif
506             fontblockobj->offsets_of_text_font_data[i] = *(uint32_t *)(data + (i + fontblockobj->num_text_fonts) * 4 + fontblockobj->text_fonts_block_offset);
507 #ifdef ENABLE_DEBUG_TRACE
508             printf("textfont-offset: %d(%0x)\n", fontblockobj->offsets_of_text_font_data[i],
509                 fontblockobj->offsets_of_text_font_data[i]);
510 #endif
511 
512             if (fontblockobj->sizes_of_text_font_data[i] == 0)
513             {
514                 continue;
515             }
516 
517             _process_text_font_data(data, (uint8_t *)(data + fontblockobj->offsets_of_text_font_data[i]), fontblockobj, i);
518         }
519     }
520 
521     return 0;
522 
523 error_exit:
524     destroy_font_data();
525 
526     return -1;
527 }
528 
529 #if (defined(__ICCARM__))
530 /*
531  * Disable the unaligned structure attribute warning. Due to the packed data
532  * structures used to interpret ELM objects data the IAR compiler issues a
533  * number of warnings that certain attributes of the headers might be unaligned.
534  * This is not true, however, as all atributes are manually aligned to 4 bytes.
535  */
536 #pragma diag_suppress = Pa039
537 #endif
538 
539 #define TEXT_CONTENT_OFFSET_WITHOUT_TRANSFORM   9 * 4
540 #define TRANSFORM_MATRIX_LENGTH                 9 * 4
_load_text_data(uint8_t * data,el_Obj_EVO * evo)541 ElmHandle _load_text_data(uint8_t *data, el_Obj_EVO *evo)
542 {
543     el_Obj_TEXT *evo_text = NULL;
544     uint8_t *text_data = NULL;
545     el_Text_Header *text_header = (el_Text_Header *)data;
546 
547     if (evo == NULL) {
548 #if (RTOS && DDRLESS) || BAREMETAL
549         evo = alloc_evo(1);
550 #else
551         evo = (el_Obj_EVO *)elm_alloc(1, sizeof(el_Obj_TEXT));
552 #endif
553     }
554     JUMP_IF_NULL(evo, error_exit);
555 #ifdef ENABLE_STRICT_DEBUG_MEMSET
556     memset(evo, 0, sizeof(el_Obj_EVO));
557 #endif
558     evo_text = (el_Obj_TEXT *)evo;
559 
560     /*
561      Default transform matrix is,
562        identity matrix
563        no-scaling
564        zero-translate
565     */
566     _init_transform(&evo_text->defaultAttrib.transform);
567     memcpy(&evo_text->defaultAttrib.transform.matrix, &text_header->matrix,
568         sizeof(vg_lite_matrix_t));
569 
570     text_data = (uint8_t *)elm_alloc(1, text_header->data_length);
571 
572     memcpy(text_data, (void *)(data + sizeof(el_Text_Header)), text_header->data_length);
573 
574     evo_text->tspan_has_dx_dy   = text_header->tspan_has_dx_dy;
575     evo_text->x_pos             = (int)text_header->x_pos;
576     evo_text->y_pos             = (int)text_header->y_pos;
577     evo_text->text_anchor       = text_header->text_flags.text_anchor;
578     evo_text->font_id           = (int)text_header->font_id;
579     evo_text->font_size         = (int)text_header->font_size;
580     evo_text->msg               = text_data;
581 
582     evo_text->defaultAttrib.quality = (ELM_QUALITY)VG_LITE_HIGH;
583     evo_text->defaultAttrib.fill_rule = ELM_EVO_FILL_NZ;
584     evo_text->defaultAttrib.blend = ELM_BLEND_SRC_OVER;
585     evo_text->defaultAttrib.paint.type = ELM_PAINT_TEXT;
586     evo_text->defaultAttrib.paint.color = text_header->color;
587 
588     evo_text->object.type = ELM_OBJECT_TYPE_EVO;
589     evo_text->object.reference = 0;
590     evo_text->attribute = evo_text->defaultAttrib;
591 
592     ref_object(&evo_text->object);
593     JUMP_IF_NON_ZERO_VALUE(add_object(&evo_text->object), error_exit);
594 
595     return evo_text->object.handle;
596 
597 error_exit:
598     if ( (evo_text) && (evo_text->msg != NULL) ) {
599         elm_free(evo_text->msg);
600         evo_text->msg = NULL;
601     }
602     if ( evo != NULL ) {
603         elm_free(evo);
604     }
605 
606     return ELM_NULL_HANDLE;
607 }
608 
609 #if (defined(__ICCARM__))
610 /* Restore the unaligned data structure attribute warning */
611 #pragma diag_default = Pa039
612 #endif
613 
_unload_text(el_Obj_EVO * evo)614 void _unload_text(el_Obj_EVO *evo)
615 {
616     el_Obj_TEXT *evo_text = (el_Obj_TEXT *)evo;
617     if(evo_text->msg != NULL)
618     {
619         elm_free(evo_text->msg);
620         evo_text->msg = NULL;
621     }
622 }
destroy_font_data()623 void destroy_font_data()
624 {
625     int i=0, j = 0;
626     if(fontblockobj != NULL) {
627         if(fontblockobj->sizes_of_ttf_data != NULL){
628             elm_free(fontblockobj->sizes_of_ttf_data);
629             fontblockobj->sizes_of_ttf_data = NULL;
630         }
631         if(fontblockobj->offsets_of_ttf_data != NULL){
632             elm_free(fontblockobj->offsets_of_ttf_data);
633             fontblockobj->offsets_of_ttf_data = NULL;
634         }
635         if(fontblockobj->sizes_of_vector_data != NULL){
636             elm_free(fontblockobj->sizes_of_vector_data);
637             fontblockobj->sizes_of_vector_data = NULL;
638         }
639         if(fontblockobj->offsets_of_vector_data != NULL){
640             elm_free(fontblockobj->offsets_of_vector_data);
641             fontblockobj->offsets_of_vector_data = NULL;
642         }
643         if(fontblockobj->sizes_of_text_font_data != NULL){
644             elm_free(fontblockobj->sizes_of_text_font_data);
645             fontblockobj->sizes_of_text_font_data = NULL;
646         }
647         if(fontblockobj->offsets_of_text_font_data != NULL){
648             elm_free(fontblockobj->offsets_of_text_font_data);
649             fontblockobj->offsets_of_text_font_data = NULL;
650         }
651         for(i=0; i<fontblockobj->num_ttf_fonts; i++)
652         {
653             if(fontblockobj->ttf_fonts[i].fields != NULL){
654                 for(j=0; j<fontblockobj->ttf_fonts[i].num_fields; j++)
655                 {
656                     if(fontblockobj->ttf_fonts[i].fields[j].data != NULL) {
657                         elm_free(fontblockobj->ttf_fonts[i].fields[j].data);
658                         fontblockobj->ttf_fonts[i].fields[j].data = NULL;
659                     }
660                 }
661                 elm_free(fontblockobj->ttf_fonts[i].fields);
662                 fontblockobj->ttf_fonts[i].fields = NULL;
663             }
664         }
665         if(fontblockobj->ttf_fonts != NULL){
666             elm_free(fontblockobj->ttf_fonts);
667             fontblockobj->ttf_fonts = NULL;
668         }
669         for(i=0; i<fontblockobj->num_vector_fonts; i++)
670         {
671             if(fontblockobj->vector_fonts[i].fields != NULL){
672                 for(j=0; j<fontblockobj->vector_fonts[i].num_fields; j++)
673                 {
674                     if(fontblockobj->vector_fonts[i].fields[j].data != NULL) {
675                         elm_free(fontblockobj->vector_fonts[i].fields[j].data);
676                         fontblockobj->vector_fonts[i].fields[j].data = NULL;
677                     }
678                 }
679                 elm_free(fontblockobj->vector_fonts[i].fields);
680                 fontblockobj->vector_fonts[i].fields = NULL;
681             }
682         }
683         if(fontblockobj->vector_fonts != NULL){
684             elm_free(fontblockobj->vector_fonts);
685             fontblockobj->vector_fonts = NULL;
686         }
687         for(i=0; i<fontblockobj->num_text_fonts; i++)
688         {
689             if(fontblockobj->text_fonts[i].fields != NULL){
690                 for(j=0; j<fontblockobj->text_fonts[i].num_fields; j++)
691                 {
692                     if(fontblockobj->text_fonts[i].fields[j].data != NULL) {
693                         elm_free(fontblockobj->text_fonts[i].fields[j].data);
694                         fontblockobj->text_fonts[i].fields[j].data = NULL;
695                     }
696                 }
697                 elm_free(fontblockobj->text_fonts[i].fields);
698                 fontblockobj->text_fonts[i].fields = NULL;
699             }
700         }
701         if(fontblockobj->text_fonts != NULL){
702             elm_free(fontblockobj->text_fonts);
703             fontblockobj->text_fonts = NULL;
704         }
705 
706         elm_free(fontblockobj);
707         fontblockobj = NULL;
708     }
709 
710     vg_lite_unload_font_data();
711 
712     for(int i=0; i<g_total_system_font; i++)
713     {
714         if(g_font_properties[i][eFontNameProperty].value.data != NULL)
715         {
716             elm_free(g_font_properties[i][eFontNameProperty].value.data);
717             g_font_properties[i][eFontNameProperty].value.data = NULL;
718         }
719     }
720 
721     return;
722 }
723 
_release_default_text_parameters(void)724 void _release_default_text_parameters(void)
725 {
726     if(g_default_font_properties[eFontNameProperty].value.data != NULL)
727     {
728         elm_free(g_default_font_properties[eFontNameProperty].value.data);
729         g_default_font_properties[eFontNameProperty].value.data = NULL;
730     }
731     return;
732 }
733