efl
348 строк · 8.1 Кб
1#ifdef HAVE_CONFIG_H2#include "config.h"3#endif4
5#include "draw_private.h"6
7int _draw_log_dom = -1;8
9/*
10s = source pixel
11d = destination pixel
12ca = const_alpha
13sia = source inverse alpha
14cia = const inverse alpha
15
16*/
17
18/*
19result = s + d * sia
20dest = (s + d * sia) * ca + d * cia
21= s * ca + d * (sia * ca + cia)
22= s * ca + d * (1 - sa*ca)
23*/
24
25static void26_comp_func_solid_source_over(uint32_t *dest, int length, uint32_t color, uint32_t const_alpha)27{
28int ialpha, i;29
30if (const_alpha != 255)31color = DRAW_BYTE_MUL(color, const_alpha);32ialpha = alpha_inverse(color);33for (i = 0; i < length; ++i)34dest[i] = color + DRAW_BYTE_MUL(dest[i], ialpha);35}
36
37static void38_comp_func_source_over(uint32_t *dest, const uint32_t *src, int length, uint32_t color, uint32_t const_alpha)39{
40int i;41uint32_t s, sc, sia;42
43if (const_alpha != 255)44color = DRAW_BYTE_MUL(color, const_alpha);45
46if (color == 0xffffffff) // No color multiplier47{48for (i = 0; i < length; ++i)49{50s = src[i];51if (s >= 0xff000000)52dest[i] = s;53else if (s != 0)54{55sia = alpha_inverse(s);56dest[i] = s + DRAW_BYTE_MUL(dest[i], sia);57}58}59}60else61{62for (i = 0; i < length; ++i)63{64s = src[i];65sc = DRAW_MUL4_SYM(color, s);66sia = alpha_inverse(sc);67dest[i] = sc + DRAW_BYTE_MUL(dest[i], sia);68}69}70}
71
72/*
73result = s
74dest = s * ca + d * cia
75*/
76static void77_comp_func_solid_source(uint32_t *dest, int length, uint32_t color, uint32_t const_alpha)78{
79int ialpha, i;80
81if (const_alpha == 255)82{83draw_memset32(dest, color, length);84}85else86{87ialpha = 255 - const_alpha;88color = DRAW_BYTE_MUL(color, const_alpha);89for (i = 0; i < length; ++i)90dest[i] = color + DRAW_BYTE_MUL(dest[i], ialpha);91}92}
93
94static void95_comp_func_source(uint32_t *dest, const uint32_t *src, int length, uint32_t color, uint32_t const_alpha)96{
97int i, ialpha;98uint32_t src_color;99
100if (color == 0xffffffff) // No color multiplier101{102if (const_alpha == 255)103{104memcpy(dest, src, length * sizeof(uint32_t));105}106else107{108ialpha = 255 - const_alpha;109for (i = 0; i < length; ++i)110dest[i] = draw_interpolate_256(src[i], const_alpha, dest[i], ialpha);111}112}113else114{115if (const_alpha == 255)116{117for (i = 0; i < length; ++i)118dest[i] = DRAW_MUL4_SYM(src[i], color);119}120else121{122ialpha = 255 - const_alpha;123for (i = 0; i < length; ++i)124{125src_color = DRAW_MUL4_SYM(src[i], color);126dest[i] = draw_interpolate_256(src_color, const_alpha, dest[i], ialpha);127}128}129}130}
131
132/* s = m * color
133* d = d * (1-sa) + s * sa
134*/
135static void136_comp_func_mask_blend(uint32_t *dest, const uint8_t *mask, int length, uint32_t color)137{
138int k;139
140for (k = 0; k < length; k++, dest++, mask++)141{142uint32_t c = draw_mul_256((*mask + 1), color);143int a = 256 - (c >> 24);144*dest = c + draw_mul_256(a, *dest);145}146}
147
148/* s = m * color
149* d = s * sa
150*/
151static void152_comp_func_mask_copy(uint32_t *dest, const uint8_t *mask, int length, uint32_t color)153{
154int k;155
156for (k = 0; k < length; k++, dest++, mask++)157{158*dest = draw_mul_256(*mask + 1, color);159}160}
161
162/* w = s * m * c
163* d = d * (1-wa) + w * wa
164*/
165static void166_comp_func_mix3_blend(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color)167{
168int k, a;169
170for (k = 0; k < len; k++, dest++, src++, mul++)171{172uint32_t c = DRAW_MUL4_SYM(*mul, color);173c = DRAW_MUL4_SYM(c, *src);174a = 256 - (c >> 24);175*dest = c + draw_mul_256(a, *dest);176}177}
178
179/* d = s * m * c */
180static void181_comp_func_mix3_copy(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color)182{
183int k;184
185for (k = 0; k < len; k++, dest++, src++, mul++)186{187uint32_t c = DRAW_MUL4_SYM(*mul, color);188*dest = DRAW_MUL4_SYM(c, *src);189}190}
191
192/* w = s * m
193* d = d * (1-wa) + w * wa
194*/
195static void196_comp_func_mix3_blend_nomul(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color EINA_UNUSED)197{
198int k, a;199
200for (k = 0; k < len; k++, dest++, src++, mul++)201{202uint32_t c = DRAW_MUL4_SYM(*mul, *src);203a = 256 - (c >> 24);204*dest = c + draw_mul_256(a, *dest);205}206}
207
208/* d = s * m */
209static void210_comp_func_mix3_copy_nomul(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color EINA_UNUSED)211{
212int k;213
214for (k = 0; k < len; k++, dest++, src++, mul++)215{216*dest = DRAW_MUL4_SYM(*mul, *src);217}218}
219
220RGBA_Comp_Func_Mask func_for_mode_mask[EFL_GFX_RENDER_OP_LAST] = {221_comp_func_mask_blend,222_comp_func_mask_copy
223};224
225RGBA_Comp_Func_Solid func_for_mode_solid[EFL_GFX_RENDER_OP_LAST] = {226_comp_func_solid_source_over,227_comp_func_solid_source
228};229
230RGBA_Comp_Func func_for_mode[EFL_GFX_RENDER_OP_LAST] = {231_comp_func_source_over,232_comp_func_source
233};234
235Draw_Func_ARGB_Mix3 func_for_mode_argb_mix3[EFL_GFX_RENDER_OP_LAST * 2] = {236_comp_func_mix3_blend,237_comp_func_mix3_copy,238_comp_func_mix3_blend_nomul,239_comp_func_mix3_copy_nomul
240};241
242RGBA_Comp_Func_Mask
243efl_draw_func_mask_span_get(Efl_Gfx_Render_Op op, uint32_t color EINA_UNUSED)244{
245return func_for_mode_mask[op];246}
247
248Draw_Func_ARGB_Mix3
249efl_draw_func_argb_mix3_get(Efl_Gfx_Render_Op op, uint32_t color)250{
251if (color == 0xffffffff)252return func_for_mode_argb_mix3[op + 2];253else254return func_for_mode_argb_mix3[op];255}
256
257RGBA_Comp_Func_Solid
258efl_draw_func_solid_span_get(Efl_Gfx_Render_Op op, uint32_t color)259{
260if ((color & 0xff000000) == 0xff000000)261{262if (op == EFL_GFX_RENDER_OP_BLEND) op = EFL_GFX_RENDER_OP_COPY;263}264
265return func_for_mode_solid[op];266}
267
268RGBA_Comp_Func
269efl_draw_func_span_get(Efl_Gfx_Render_Op op, uint32_t color, Eina_Bool src_alpha)270{
271if (((color & 0xff000000) == 0xff000000) && !src_alpha)272{273if (op == EFL_GFX_RENDER_OP_BLEND) op = EFL_GFX_RENDER_OP_COPY;274}275
276return func_for_mode[op];277}
278
279static double280_ease_linear(double t)281{
282return t;283}
284
285Eina_Bool
286efl_draw_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint32_t *color_table, int size)287{
288int dist, idist, pos = 0, i;289Eina_Bool alpha = EINA_FALSE;290Efl_Gfx_Gradient_Stop *curr, *next;291uint32_t current_color, next_color;292double delta, t, incr, fpos;293
294curr = gradient_stops;295if (curr->a != 255) alpha = EINA_TRUE;296current_color = DRAW_ARGB_JOIN(curr->a, curr->r, curr->g, curr->b);297incr = 1.0 / (double)size;298fpos = 1.5 * incr;299
300color_table[pos++] = current_color;301
302while (fpos <= curr->offset)303{304color_table[pos] = color_table[pos - 1];305pos++;306fpos += incr;307}308
309for (i = 0; i < stop_count - 1; ++i)310{311curr = (gradient_stops + i);312next = (gradient_stops + i + 1);313delta = 1/(next->offset - curr->offset);314if (next->a != 255) alpha = EINA_TRUE;315next_color = DRAW_ARGB_JOIN(next->a, next->r, next->g, next->b);316while (fpos < next->offset && pos < size)317{318t = _ease_linear((fpos - curr->offset) * delta);319dist = (int)(256 * t);320idist = 256 - dist;321color_table[pos] = draw_interpolate_256(current_color, idist, next_color, dist);322++pos;323fpos += incr;324}325current_color = next_color;326}327
328for (;pos < size; ++pos)329color_table[pos] = current_color;330
331// Make sure the last color stop is represented at the end of the table332color_table[size-1] = current_color;333return alpha;334}
335
336
337int
338efl_draw_init(void)339{
340static int i = 0;341if (!(i++))342{343_draw_log_dom = eina_log_domain_register("efl_draw", EINA_COLOR_ORANGE);344efl_draw_sse2_init();345efl_draw_neon_init();346}347return i;348}
349