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