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