1 /** 2 * @file lv_mask.h 3 * 4 */ 5 6 #ifndef LV_MASK_H 7 #define LV_MASK_H 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 /********************* 14 * INCLUDES 15 *********************/ 16 #include <stdbool.h> 17 #include "../lv_misc/lv_area.h" 18 #include "../lv_misc/lv_color.h" 19 20 /********************* 21 * DEFINES 22 *********************/ 23 #define LV_MASK_ID_INV (-1) 24 #define _LV_MASK_MAX_NUM 16 25 26 /********************** 27 * TYPEDEFS 28 **********************/ 29 30 enum { 31 LV_DRAW_MASK_RES_TRANSP, 32 LV_DRAW_MASK_RES_FULL_COVER, 33 LV_DRAW_MASK_RES_CHANGED, 34 LV_DRAW_MASK_RES_UNKNOWN 35 }; 36 37 typedef uint8_t lv_draw_mask_res_t; 38 39 40 enum { 41 LV_DRAW_MASK_TYPE_LINE, 42 LV_DRAW_MASK_TYPE_ANGLE, 43 LV_DRAW_MASK_TYPE_RADIUS, 44 LV_DRAW_MASK_TYPE_FADE, 45 LV_DRAW_MASK_TYPE_MAP, 46 }; 47 48 typedef uint8_t lv_draw_mask_type_t; 49 50 enum { 51 LV_DRAW_MASK_LINE_SIDE_LEFT = 0, 52 LV_DRAW_MASK_LINE_SIDE_RIGHT, 53 LV_DRAW_MASK_LINE_SIDE_TOP, 54 LV_DRAW_MASK_LINE_SIDE_BOTTOM, 55 }; 56 57 /** 58 * A common callback type for every mask type. 59 * Used internally by the library. 60 */ 61 typedef lv_draw_mask_res_t (*lv_draw_mask_xcb_t)(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, 62 lv_coord_t len, 63 void * p); 64 65 typedef uint8_t lv_draw_mask_line_side_t; 66 67 typedef struct { 68 lv_draw_mask_xcb_t cb; 69 lv_draw_mask_type_t type; 70 } lv_draw_mask_common_dsc_t; 71 72 typedef struct { 73 /*The first element must be the common descriptor*/ 74 lv_draw_mask_common_dsc_t dsc; 75 76 struct { 77 /*First point */ 78 lv_point_t p1; 79 80 /*Second point*/ 81 lv_point_t p2; 82 83 /*Which side to keep?*/ 84 lv_draw_mask_line_side_t side : 2; 85 } cfg; 86 87 /*A point of the line*/ 88 lv_point_t origo; 89 90 /* X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y?*/ 91 int32_t xy_steep; 92 93 /* Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X?*/ 94 int32_t yx_steep; 95 96 /*Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines */ 97 int32_t steep; 98 99 /*Steepness in 1 px in 0..255 range. Used only by flat lines. */ 100 int32_t spx; 101 102 /*1: It's a flat line? (Near to horizontal)*/ 103 uint8_t flat : 1; 104 105 106 /* Invert the mask. The default is: Keep the left part. 107 * It is used to select left/right/top/bottom*/ 108 uint8_t inv: 1; 109 } lv_draw_mask_line_param_t; 110 111 typedef struct { 112 /*The first element must be the common descriptor*/ 113 lv_draw_mask_common_dsc_t dsc; 114 115 struct { 116 lv_point_t vertex_p; 117 lv_coord_t start_angle; 118 lv_coord_t end_angle; 119 } cfg; 120 121 lv_draw_mask_line_param_t start_line; 122 lv_draw_mask_line_param_t end_line; 123 uint16_t delta_deg; 124 } lv_draw_mask_angle_param_t; 125 126 typedef struct { 127 /*The first element must be the common descriptor*/ 128 lv_draw_mask_common_dsc_t dsc; 129 130 struct { 131 lv_area_t rect; 132 lv_coord_t radius; 133 /* Invert the mask. 0: Keep the pixels inside.*/ 134 uint8_t outer: 1; 135 } cfg; 136 int32_t y_prev; 137 lv_sqrt_res_t y_prev_x; 138 139 } lv_draw_mask_radius_param_t; 140 141 typedef struct { 142 /*The first element must be the common descriptor*/ 143 lv_draw_mask_common_dsc_t dsc; 144 145 struct { 146 lv_area_t coords; 147 lv_coord_t y_top; 148 lv_coord_t y_bottom; 149 lv_opa_t opa_top; 150 lv_opa_t opa_bottom; 151 } cfg; 152 153 } lv_draw_mask_fade_param_t; 154 155 typedef struct _lv_draw_mask_map_param_t { 156 /*The first element must be the common descriptor*/ 157 lv_draw_mask_common_dsc_t dsc; 158 159 struct { 160 lv_area_t coords; 161 const lv_opa_t * map; 162 } cfg; 163 } lv_draw_mask_map_param_t; 164 165 typedef struct { 166 void * param; 167 void * custom_id; 168 } _lv_draw_mask_saved_t; 169 170 typedef _lv_draw_mask_saved_t _lv_draw_mask_saved_arr_t[_LV_MASK_MAX_NUM]; 171 172 /********************** 173 * GLOBAL PROTOTYPES 174 **********************/ 175 176 /** 177 * Add a draw mask. Everything drawn after it (until removing the mask) will be affected by the mask. 178 * @param param an initialized mask parameter. Only the pointer is saved. 179 * @param custom_id a custom pointer to identify the mask. Used in `lv_draw_mask_remove_custom`. 180 * @return the an integer, the ID of the mask. Can be used in `lv_draw_mask_remove_id`. 181 */ 182 int16_t lv_draw_mask_add(void * param, void * custom_id); 183 184 185 //! @cond Doxygen_Suppress 186 187 /** 188 * Apply the added buffers on a line. Used internally by the library's drawing routines. 189 * @param mask_buf store the result mask here. Has to be `len` byte long. Should be initialized with `0xFF`. 190 * @param abs_x absolute X coordinate where the line to calculate start 191 * @param abs_y absolute Y coordinate where the line to calculate start 192 * @param len length of the line to calculate (in pixel count) 193 * @return One of these values: 194 * - `LV_DRAW_MASK_RES_FULL_TRANSP`: the whole line is transparent. `mask_buf` is not set to zero 195 * - `LV_DRAW_MASK_RES_FULL_COVER`: the whole line is fully visible. `mask_buf` is unchanged 196 * - `LV_DRAW_MASK_RES_CHANGED`: `mask_buf` has changed, it shows the desired opacity of each pixel in the given line 197 */ 198 LV_ATTRIBUTE_FAST_MEM lv_draw_mask_res_t lv_draw_mask_apply(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, 199 lv_coord_t len); 200 201 202 //! @endcond 203 204 /** 205 * Remove a mask with a given ID 206 * @param id the ID of the mask. Returned by `lv_draw_mask_add` 207 * @return the parameter of the removed mask. 208 * If more masks have `custom_id` ID then the last mask's parameter will be returned 209 */ 210 void * lv_draw_mask_remove_id(int16_t id); 211 212 /** 213 * Remove all mask with a given custom ID 214 * @param custom_id a pointer used in `lv_draw_mask_add` 215 * @return return the parameter of the removed mask. 216 * If more masks have `custom_id` ID then the last mask's parameter will be returned 217 */ 218 void * lv_draw_mask_remove_custom(void * custom_id); 219 220 //! @cond Doxygen_Suppress 221 222 /** 223 * Count the currently added masks 224 * @return number of active masks 225 */ 226 LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void); 227 228 229 //! @endcond 230 231 /** 232 *Initialize a line mask from two points. 233 * @param param pointer to a `lv_draw_mask_param_t` to initialize 234 * @param p1x X coordinate of the first point of the line 235 * @param p1y Y coordinate of the first point of the line 236 * @param p2x X coordinate of the second point of the line 237 * @param p2y y coordinate of the second point of the line 238 * @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep. 239 * With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept 240 * With `LV_DRAW_MASK_LINE_SIDE_TOP/BOTTOM` and vertical line all pixels are kept 241 */ 242 void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, 243 lv_coord_t p2y, lv_draw_mask_line_side_t side); 244 245 /** 246 *Initialize a line mask from a point and an angle. 247 * @param param pointer to a `lv_draw_mask_param_t` to initialize 248 * @param px X coordinate of a point of the line 249 * @param py X coordinate of a point of the line 250 * @param angle right 0 deg, bottom: 90 251 * @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep. 252 * With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept 253 * With `LV_DRAW_MASK_LINE_SIDE_TOP/BOTTOM` and vertical line all pixels are kept 254 */ 255 void lv_draw_mask_line_angle_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t py, int16_t angle, 256 lv_draw_mask_line_side_t side); 257 258 /** 259 * Initialize an angle mask. 260 * @param param pointer to a `lv_draw_mask_param_t` to initialize 261 * @param vertex_x X coordinate of the angle vertex (absolute coordinates) 262 * @param vertex_y Y coordinate of the angle vertex (absolute coordinates) 263 * @param start_angle start angle in degrees. 0 deg on the right, 90 deg, on the bottom 264 * @param end_angle end angle 265 */ 266 void lv_draw_mask_angle_init(lv_draw_mask_angle_param_t * param, lv_coord_t vertex_x, lv_coord_t vertex_y, 267 lv_coord_t start_angle, lv_coord_t end_angle); 268 269 /** 270 * Initialize a fade mask. 271 * @param param param pointer to a `lv_draw_mask_param_t` to initialize 272 * @param rect coordinates of the rectangle to affect (absolute coordinates) 273 * @param radius radius of the rectangle 274 * @param inv: true: keep the pixels inside the rectangle; keep the pixels outside of the rectangle 275 */ 276 void lv_draw_mask_radius_init(lv_draw_mask_radius_param_t * param, const lv_area_t * rect, lv_coord_t radius, bool inv); 277 278 /** 279 * Initialize a fade mask. 280 * @param param pointer to a `lv_draw_mask_param_t` to initialize 281 * @param coords coordinates of the area to affect (absolute coordinates) 282 * @param opa_top opacity on the top 283 * @param y_top at which coordinate start to change to opacity to `opa_bottom` 284 * @param opa_bottom opacity at the bottom 285 * @param y_bottom at which coordinate reach `opa_bottom`. 286 */ 287 void lv_draw_mask_fade_init(lv_draw_mask_fade_param_t * param, const lv_area_t * coords, lv_opa_t opa_top, 288 lv_coord_t y_top, 289 lv_opa_t opa_bottom, lv_coord_t y_bottom); 290 291 /** 292 * Initialize a map mask. 293 * @param param pointer to a `lv_draw_mask_param_t` to initialize 294 * @param coords coordinates of the map (absolute coordinates) 295 * @param map array of bytes with the mask values 296 */ 297 void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * coords, const lv_opa_t * map); 298 299 /********************** 300 * MACROS 301 **********************/ 302 303 #ifdef __cplusplus 304 } /* extern "C" */ 305 #endif 306 307 #endif /*LV_MASK_H*/ 308