1 /**
2 * @file lv_draw_sw_letter.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "blend/lv_draw_sw_blend_private.h"
10 #include "../lv_draw_label_private.h"
11 #include "lv_draw_sw.h"
12 #if LV_USE_DRAW_SW
13
14 #include "../../display/lv_display.h"
15 #include "../../misc/lv_math.h"
16 #include "../../misc/lv_assert.h"
17 #include "../../misc/lv_area.h"
18 #include "../../misc/lv_style.h"
19 #include "../../font/lv_font.h"
20 #include "../../core/lv_refr_private.h"
21 #include "../../stdlib/lv_string.h"
22
23 /*********************
24 * DEFINES
25 *********************/
26
27 /**********************
28 * TYPEDEFS
29 **********************/
30
31 /**********************
32 * STATIC PROTOTYPES
33 **********************/
34
35 static void /* LV_ATTRIBUTE_FAST_MEM */ draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
36 lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
37
38 /**********************
39 * STATIC VARIABLES
40 **********************/
41
42 /**********************
43 * GLOBAL VARIABLES
44 **********************/
45
46 /**********************
47 * MACROS
48 **********************/
49
50 /**********************
51 * GLOBAL FUNCTIONS
52 **********************/
53
lv_draw_sw_letter(lv_draw_unit_t * draw_unit,const lv_draw_letter_dsc_t * dsc,const lv_area_t * coords)54 void lv_draw_sw_letter(lv_draw_unit_t * draw_unit, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords)
55 {
56 if(dsc->opa <= LV_OPA_MIN)
57 return;
58
59 lv_draw_glyph_dsc_t glyph_dsc;
60 lv_draw_glyph_dsc_init(&glyph_dsc);
61 glyph_dsc.opa = dsc->opa;
62 glyph_dsc.bg_coords = NULL;
63 glyph_dsc.color = dsc->color;
64 glyph_dsc.rotation = dsc->rotation;
65 glyph_dsc.pivot = dsc->pivot;
66
67 LV_PROFILER_BEGIN;
68 lv_draw_unit_draw_letter(draw_unit, &glyph_dsc, &(lv_point_t) {
69 .x = coords->x1, .y = coords->y1
70 },
71 dsc->font, dsc->unicode, draw_letter_cb);
72 LV_PROFILER_END;
73
74 if(glyph_dsc._draw_buf) {
75 lv_draw_buf_destroy(glyph_dsc._draw_buf);
76 glyph_dsc._draw_buf = NULL;
77 }
78 }
79
lv_draw_sw_label(lv_draw_unit_t * draw_unit,const lv_draw_label_dsc_t * dsc,const lv_area_t * coords)80 void lv_draw_sw_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords)
81 {
82 if(dsc->opa <= LV_OPA_MIN) return;
83
84 LV_PROFILER_DRAW_BEGIN;
85 lv_draw_label_iterate_characters(draw_unit, dsc, coords, draw_letter_cb);
86 LV_PROFILER_DRAW_END;
87 }
88
89 /**********************
90 * STATIC FUNCTIONS
91 **********************/
92
draw_letter_cb(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)93 static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
94 lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
95 {
96 if(glyph_draw_dsc) {
97 switch(glyph_draw_dsc->format) {
98 case LV_FONT_GLYPH_FORMAT_NONE: {
99 #if LV_USE_FONT_PLACEHOLDER
100 /* Draw a placeholder rectangle*/
101 lv_draw_border_dsc_t border_draw_dsc;
102 lv_draw_border_dsc_init(&border_draw_dsc);
103 border_draw_dsc.opa = glyph_draw_dsc->opa;
104 border_draw_dsc.color = glyph_draw_dsc->color;
105 border_draw_dsc.width = 1;
106 lv_draw_sw_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords);
107 #endif
108 }
109 break;
110 case LV_FONT_GLYPH_FORMAT_A1:
111 case LV_FONT_GLYPH_FORMAT_A2:
112 case LV_FONT_GLYPH_FORMAT_A3:
113 case LV_FONT_GLYPH_FORMAT_A4:
114 case LV_FONT_GLYPH_FORMAT_A8:
115 case LV_FONT_GLYPH_FORMAT_A1_ALIGNED:
116 case LV_FONT_GLYPH_FORMAT_A2_ALIGNED:
117 case LV_FONT_GLYPH_FORMAT_A4_ALIGNED:
118 case LV_FONT_GLYPH_FORMAT_A8_ALIGNED:
119 case LV_FONT_GLYPH_FORMAT_IMAGE: {
120 if(glyph_draw_dsc->rotation % 3600 == 0 && glyph_draw_dsc->format != LV_FONT_GLYPH_FORMAT_IMAGE) {
121 glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
122 lv_area_t mask_area = *glyph_draw_dsc->letter_coords;
123 mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1;
124 lv_draw_sw_blend_dsc_t blend_dsc;
125 lv_memzero(&blend_dsc, sizeof(blend_dsc));
126 blend_dsc.color = glyph_draw_dsc->color;
127 blend_dsc.opa = glyph_draw_dsc->opa;
128 const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data;
129 blend_dsc.mask_buf = draw_buf->data;
130 blend_dsc.mask_area = &mask_area;
131 blend_dsc.mask_stride = draw_buf->header.stride;
132 blend_dsc.blend_area = glyph_draw_dsc->letter_coords;
133 blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
134 lv_draw_sw_blend(draw_unit, &blend_dsc);
135 }
136 else {
137 glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf);
138 lv_draw_image_dsc_t img_dsc;
139 lv_draw_image_dsc_init(&img_dsc);
140 img_dsc.rotation = glyph_draw_dsc->rotation;
141 img_dsc.scale_x = LV_SCALE_NONE;
142 img_dsc.scale_y = LV_SCALE_NONE;
143 img_dsc.opa = glyph_draw_dsc->opa;
144 img_dsc.src = glyph_draw_dsc->glyph_data;
145 img_dsc.recolor = glyph_draw_dsc->color;
146 img_dsc.pivot = (lv_point_t) {
147 .x = glyph_draw_dsc->pivot.x,
148 .y = glyph_draw_dsc->g->box_h + glyph_draw_dsc->g->ofs_y
149 };
150 lv_draw_sw_image(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords);
151 }
152 break;
153 }
154 default:
155 break;
156 }
157 }
158
159 if(fill_draw_dsc && fill_area) {
160 lv_draw_sw_fill(draw_unit, fill_draw_dsc, fill_area);
161 }
162 }
163
164 #endif /*LV_USE_DRAW_SW*/
165