1 /**
2  * @file lv_draw_vglite_label.c
3  *
4  */
5 
6 /**
7  * Copyright 2023-2024 NXP
8  *
9  * SPDX-License-Identifier: MIT
10  */
11 
12 /*********************
13  *      INCLUDES
14  *********************/
15 
16 #include "lv_draw_vglite.h"
17 
18 #if LV_USE_DRAW_VGLITE
19 #include "lv_vglite_buf.h"
20 #include "lv_vglite_matrix.h"
21 #include "lv_vglite_utils.h"
22 
23 #include "../../lv_draw_label_private.h"
24 #include "../../../stdlib/lv_string.h"
25 
26 /*********************
27  *      DEFINES
28  *********************/
29 
30 /**********************
31  *      TYPEDEFS
32  **********************/
33 
34 /**********************
35  *  STATIC PROTOTYPES
36  **********************/
37 
38 static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
39                                 lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
40 
41 /**
42  * Draw letter (character bitmap blend) with optional color and opacity
43  *
44  * @param[in] mask_area Mask area with relative coordinates of source buffer
45  * @param[in] color Color
46  * @param[in] opa Opacity
47  *
48  */
49 static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa);
50 
51 /**********************
52  *  STATIC VARIABLES
53  **********************/
54 
55 /**********************
56  *  GLOBAL VARIABLES
57  **********************/
58 
59 /**********************
60  *      MACROS
61  **********************/
62 
63 /**********************
64  *   GLOBAL FUNCTIONS
65  **********************/
66 
lv_draw_vglite_label(lv_draw_unit_t * draw_unit,const lv_draw_label_dsc_t * dsc,const lv_area_t * coords)67 void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
68                           const lv_area_t * coords)
69 {
70     if(dsc->opa <= LV_OPA_MIN) return;
71 
72     lv_draw_label_iterate_characters(draw_unit, dsc, coords, _draw_vglite_letter);
73 }
74 
75 /**********************
76  *   STATIC FUNCTIONS
77  **********************/
78 
_draw_vglite_letter(lv_draw_unit_t * draw_unit,lv_draw_glyph_dsc_t * glyph_draw_dsc,lv_draw_fill_dsc_t * fill_draw_dsc,const lv_area_t * fill_area)79 static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
80                                 lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
81 {
82     if(glyph_draw_dsc) {
83 
84         switch(glyph_draw_dsc->format) {
85 
86             case LV_FONT_GLYPH_FORMAT_NONE: {
87 #if LV_USE_FONT_PLACEHOLDER
88                     /* Draw a placeholder rectangle*/
89                     lv_draw_border_dsc_t border_draw_dsc;
90                     lv_draw_border_dsc_init(&border_draw_dsc);
91                     border_draw_dsc.opa = glyph_draw_dsc->opa;
92                     border_draw_dsc.color = glyph_draw_dsc->color;
93                     border_draw_dsc.width = 1;
94                     lv_draw_vglite_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords);
95 #endif
96                 }
97                 break;
98             case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8_ALIGNED: {
99                     /*Do not draw transparent things*/
100                     if(glyph_draw_dsc->opa <= LV_OPA_MIN)
101                         return;
102 
103                     lv_layer_t * layer = draw_unit->target_layer;
104 
105                     lv_area_t blend_area;
106                     if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area))
107                         return;
108                     lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1);
109 
110                     const lv_draw_buf_t * draw_buf = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
111                     const void * mask_buf = draw_buf->data;
112 
113                     uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords);
114                     uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords);
115                     uint32_t mask_stride = draw_buf->header.stride;
116 
117                     lv_area_t mask_area;
118                     mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1);
119                     mask_area.y1 = blend_area.y1 - (glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1);
120                     mask_area.x2 = mask_width - 1;
121                     mask_area.y2 = mask_height - 1;
122 
123                     /* Set src_vgbuf structure. */
124                     vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8);
125 
126                     /* Set vgmatrix. */
127                     vglite_set_translation_matrix(&blend_area);
128 
129                     lv_draw_buf_invalidate_cache(draw_buf, &mask_area);
130 
131                     _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa);
132                 }
133                 break;
134             case LV_FONT_GLYPH_FORMAT_IMAGE: {
135 #if LV_USE_IMGFONT
136                     glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
137                     lv_draw_image_dsc_t img_dsc;
138                     lv_draw_image_dsc_init(&img_dsc);
139                     img_dsc.opa = glyph_draw_dsc->opa;
140                     img_dsc.src = glyph_draw_dsc->glyph_data;
141                     lv_draw_vglite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords);
142 #endif
143                 }
144                 break;
145             default:
146                 break;
147         }
148     }
149 
150     if(fill_draw_dsc && fill_area) {
151         lv_draw_vglite_fill(draw_unit, fill_draw_dsc, fill_area);
152     }
153 }
154 
_vglite_draw_letter(const lv_area_t * mask_area,lv_color_t color,lv_opa_t opa)155 static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa)
156 {
157     vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf();
158     vg_lite_buffer_t * mask_vgbuf = vglite_get_src_buf();
159 
160     mask_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
161     mask_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
162 
163     vg_lite_rectangle_t rect = {
164         .x = (vg_lite_int32_t)mask_area->x1,
165         .y = (vg_lite_int32_t)mask_area->y1,
166         .width = (vg_lite_int32_t)lv_area_get_width(mask_area),
167         .height = (vg_lite_int32_t)lv_area_get_height(mask_area)
168     };
169 
170     lv_color32_t col32 = lv_color_to_32(color, opa);
171     vg_lite_color_t vgcol = vglite_get_color(col32, false);
172 
173     vg_lite_matrix_t * vgmatrix = vglite_get_matrix();
174 
175     /*Blit with font color as paint color*/
176     VGLITE_CHECK_ERROR(vg_lite_blit_rect(dst_vgbuf, mask_vgbuf, &rect, vgmatrix, VG_LITE_BLEND_SRC_OVER, vgcol,
177                                          VG_LITE_FILTER_POINT));
178 
179     vglite_run();
180 }
181 
182 #endif /*LV_USE_DRAW_VGLITE*/
183