1 /**
2  * @file lv_draw_sw_gradient.h
3  *
4  */
5 
6 #ifndef LV_DRAW_SW_GRADIENT_H
7 #define LV_DRAW_SW_GRADIENT_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../../misc/lv_color.h"
17 #include "../../misc/lv_style.h"
18 #include "lv_draw_sw_dither.h"
19 
20 /*********************
21  *      DEFINES
22  *********************/
23 #if LV_GRADIENT_MAX_STOPS < 2
24 #error LVGL needs at least 2 stops for gradients. Please increase the LV_GRADIENT_MAX_STOPS
25 #endif
26 
27 
28 /**********************
29  *      TYPEDEFS
30  **********************/
31 #if _DITHER_GRADIENT
32 typedef lv_color32_t lv_grad_color_t;
33 #else
34 typedef lv_color_t lv_grad_color_t;
35 #endif
36 
37 /** To avoid recomputing gradient for each draw operation,
38  *  it's possible to cache the computation in this structure instance.
39  *  Whenever possible, this structure is reused instead of recomputing the gradient map */
40 typedef struct _lv_gradient_cache_t {
41     uint32_t        key;          /**< A discriminating key that's built from the drawing operation.
42                                    * If the key does not match, the cache item is not used */
43     uint32_t        life : 30;    /**< A life counter that's incremented on usage. Higher counter is
44                                    * less likely to be evicted from the cache */
45     uint32_t        filled : 1;   /**< Used to skip dithering in it if already done */
46     uint32_t        not_cached: 1; /**< The cache was too small so this item is not managed by the cache*/
47     lv_color_t   *  map;          /**< The computed gradient low bitdepth color map, points into the
48                                    * cache's buffer, no free needed */
49     lv_coord_t      alloc_size;   /**< The map allocated size in colors */
50     lv_coord_t      size;         /**< The computed gradient color map size, in colors */
51 #if _DITHER_GRADIENT
52     lv_color32_t  * hmap;         /**< If dithering, we need to store the current, high bitdepth gradient
53                                    * map too, points to the cache's buffer, no free needed */
54 #if LV_DITHER_ERROR_DIFFUSION == 1
55     lv_scolor24_t * error_acc;    /**< Error diffusion dithering algorithm requires storing the last error
56                                    * drawn, points to the cache's buffer, no free needed  */
57     lv_coord_t      w;            /**< The error array width in pixels */
58 #endif
59 #endif
60 } lv_grad_t;
61 
62 
63 /**********************
64  *      PROTOTYPES
65  **********************/
66 /** Compute the color in the given gradient and fraction
67  *  Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range
68  * @param dsc       The gradient descriptor to use
69  * @param range     The range to use in computation.
70  * @param frac      The current part used in the range. frac is in [0; range]
71  */
72 LV_ATTRIBUTE_FAST_MEM lv_grad_color_t lv_gradient_calculate(const lv_grad_dsc_t * dsc, lv_coord_t range,
73                                                             lv_coord_t frac);
74 
75 /**
76  * Set the gradient cache size
77  * @param max_bytes Max cahce size
78  */
79 void lv_gradient_set_cache_size(size_t max_bytes);
80 
81 /** Free the gradient cache */
82 void lv_gradient_free_cache(void);
83 
84 /** Get a gradient cache from the given parameters */
85 lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, lv_coord_t w, lv_coord_t h);
86 
87 /**
88  * Clean up the gradient item after it was get with `lv_grad_get_from_cache`.
89  * @param grad      pointer to a gradient
90  */
91 void lv_gradient_cleanup(lv_grad_t * grad);
92 
93 #ifdef __cplusplus
94 } /*extern "C"*/
95 #endif
96 
97 #endif /*LV_DRAW_GRADIENT_H*/
98