1 #ifndef EFL_DRAW_H
2 #define EFL_DRAW_H
3
4 #ifdef HAVE_CONFIG_H
5 # include <config.h>
6 #endif
7
8 #include <Eina.h>
9 #include "efl/interfaces/efl_gfx_types.eot.h"
10
11 /* FIXME: naming convention */
12 /* FIXME: mul_col & const_alpha are redondant */
13 typedef void (*RGBA_Comp_Func) (uint32_t *dest, const uint32_t *src, int length, uint32_t mul_col, uint32_t const_alpha);
14 typedef void (*RGBA_Comp_Func_Solid) (uint32_t *dest, int length, uint32_t color, uint32_t const_alpha);
15 typedef void (*RGBA_Comp_Func_Mask) (uint32_t *dest, const uint8_t *mask, int length, uint32_t color);
16 typedef void (*Draw_Func_ARGB_Mix3) (uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color);
17 typedef void (*Draw_Func_Alpha) (uint8_t *dest, const uint8_t *src, int len);
18 typedef Eina_Bool (*Cspace_Convert_Func) (void *dst, const void *src, int w, int h, int src_stride, int dst_stride, Eina_Bool has_alpha, Efl_Gfx_Colorspace srccs, Efl_Gfx_Colorspace dstcs);
19
20 int efl_draw_init(void);
21
22 RGBA_Comp_Func efl_draw_func_span_get (Efl_Gfx_Render_Op op, uint32_t color, Eina_Bool src_alpha);
23 RGBA_Comp_Func_Solid efl_draw_func_solid_span_get (Efl_Gfx_Render_Op op, uint32_t color);
24 RGBA_Comp_Func_Mask efl_draw_func_mask_span_get (Efl_Gfx_Render_Op op, uint32_t color);
25 Draw_Func_ARGB_Mix3 efl_draw_func_argb_mix3_get (Efl_Gfx_Render_Op op, uint32_t color);
26 Draw_Func_Alpha efl_draw_alpha_func_get (Efl_Gfx_Render_Op op, Eina_Bool has_mask);
27 Cspace_Convert_Func efl_draw_convert_func_get (Efl_Gfx_Colorspace origcs, Efl_Gfx_Colorspace dstcs, Eina_Bool *region_can);
28
29 int efl_draw_argb_premul(uint32_t *data, unsigned int len);
30 void efl_draw_argb_unpremul(uint32_t *data, unsigned int len);
31
32 Eina_Bool efl_draw_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint32_t *color_table, int size);
33
34
35 /* common sw draw helpers */
36
37 #ifndef MIN
38 #define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
39 #endif
40
41 #ifndef MAX
42 #define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
43 #endif
44
45 #ifndef A_VAL
46 #ifndef WORDS_BIGENDIAN
47 /* x86 */
48 #define A_VAL(p) (((uint8_t *)(p))[3])
49 #define R_VAL(p) (((uint8_t *)(p))[2])
50 #define G_VAL(p) (((uint8_t *)(p))[1])
51 #define B_VAL(p) (((uint8_t *)(p))[0])
52 #define AR_VAL(p) ((uint16_t *)(p)[1])
53 #define GB_VAL(p) ((uint16_t *)(p)[0])
54 #else
55 /* ppc */
56 #define A_VAL(p) (((uint8_t *)(p))[0])
57 #define R_VAL(p) (((uint8_t *)(p))[1])
58 #define G_VAL(p) (((uint8_t *)(p))[2])
59 #define B_VAL(p) (((uint8_t *)(p))[3])
60 #define AR_VAL(p) ((uint16_t *)(p)[0])
61 #define GB_VAL(p) ((uint16_t *)(p)[1])
62 #endif
63 #endif
64
65 #define DRAW_ARGB_JOIN(a,r,g,b) \
66 (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
67
68 /* argb multiply */
69 #define DRAW_MUL4_SYM(x, y) \
70 ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) + \
71 ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
72 ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
73 (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
74
75 /* alpha from 1 to 256 */
76 static inline uint32_t
draw_mul_256(int a,uint32_t c)77 draw_mul_256(int a, uint32_t c)
78 {
79 return (((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) |
80 (((((c) & 0x00ff00ff) * (a)) >> 8) & 0x00ff00ff);
81 }
82
83 static inline uint32_t
draw_interpolate_256(uint32_t x,int a,uint32_t y,int b)84 draw_interpolate_256(uint32_t x, int a, uint32_t y, int b)
85 {
86 uint32_t t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
87 t >>= 8;
88 t &= 0xff00ff;
89 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
90 x &= 0xff00ff00;
91 x |= t;
92 return x;
93 }
94
95 static inline void
draw_memset32(uint32_t * dest,uint32_t value,int length)96 draw_memset32(uint32_t *dest, uint32_t value, int length)
97 {
98 int n;
99
100 if (length <= 0)
101 return;
102
103 // Cute hack to align future memcopy operation
104 // and do unroll the loop a bit. Not sure it is
105 // the most efficient, but will do for now.
106 n = (length + 7) / 8;
107 switch (length & 0x07)
108 {
109 case 0: do { *dest++ = value;
110 EINA_FALLTHROUGH;
111 case 7: *dest++ = value;
112 EINA_FALLTHROUGH;
113 case 6: *dest++ = value;
114 EINA_FALLTHROUGH;
115 case 5: *dest++ = value;
116 EINA_FALLTHROUGH;
117 case 4: *dest++ = value;
118 EINA_FALLTHROUGH;
119 case 3: *dest++ = value;
120 EINA_FALLTHROUGH;
121 case 2: *dest++ = value;
122 EINA_FALLTHROUGH;
123 case 1: *dest++ = value;
124 } while (--n > 0);
125 }
126 }
127
128 #endif
129