efl

Форк
0
/
draw_main.c 
348 строк · 8.1 Кб
1
#ifdef HAVE_CONFIG_H
2
#include "config.h"
3
#endif
4

5
#include "draw_private.h"
6

7
int _draw_log_dom = -1;
8

9
/*
10
  s = source pixel
11
  d = destination pixel
12
  ca = const_alpha
13
  sia = source inverse alpha
14
  cia = const inverse alpha
15

16
*/
17

18
/*
19
  result = s + d * sia
20
  dest = (s + d * sia) * ca + d * cia
21
       = s * ca + d * (sia * ca + cia)
22
       = s * ca + d * (1 - sa*ca)
23
*/
24

25
static void
26
_comp_func_solid_source_over(uint32_t *dest, int length, uint32_t color, uint32_t const_alpha)
27
{
28
   int ialpha, i;
29

30
   if (const_alpha != 255)
31
     color = DRAW_BYTE_MUL(color, const_alpha);
32
   ialpha = alpha_inverse(color);
33
   for (i = 0; i < length; ++i)
34
     dest[i] = color + DRAW_BYTE_MUL(dest[i], ialpha);
35
}
36

37
static void
38
_comp_func_source_over(uint32_t *dest, const uint32_t *src, int length, uint32_t color, uint32_t const_alpha)
39
{
40
   int i;
41
   uint32_t s, sc, sia;
42

43
   if (const_alpha != 255)
44
     color = DRAW_BYTE_MUL(color, const_alpha);
45

46
   if (color == 0xffffffff) // No color multiplier
47
     {
48
        for (i = 0; i < length; ++i)
49
          {
50
             s = src[i];
51
             if (s >= 0xff000000)
52
               dest[i] = s;
53
             else if (s != 0)
54
               {
55
                  sia = alpha_inverse(s);
56
                  dest[i] = s + DRAW_BYTE_MUL(dest[i], sia);
57
               }
58
          }
59
     }
60
   else
61
     {
62
        for (i = 0; i < length; ++i)
63
          {
64
             s = src[i];
65
             sc = DRAW_MUL4_SYM(color, s);
66
             sia = alpha_inverse(sc);
67
             dest[i] = sc + DRAW_BYTE_MUL(dest[i], sia);
68
          }
69
     }
70
}
71

72
/*
73
  result = s
74
  dest = s * ca + d * cia
75
*/
76
static void
77
_comp_func_solid_source(uint32_t *dest, int length, uint32_t color, uint32_t const_alpha)
78
{
79
   int ialpha, i;
80

81
   if (const_alpha == 255)
82
     {
83
        draw_memset32(dest, color, length);
84
     }
85
   else
86
     {
87
        ialpha = 255 - const_alpha;
88
        color = DRAW_BYTE_MUL(color, const_alpha);
89
        for (i = 0; i < length; ++i)
90
          dest[i] = color + DRAW_BYTE_MUL(dest[i], ialpha);
91
     }
92
}
93

94
static void
95
_comp_func_source(uint32_t *dest, const uint32_t *src, int length, uint32_t color, uint32_t const_alpha)
96
{
97
   int i, ialpha;
98
   uint32_t src_color;
99

100
   if (color == 0xffffffff) // No color multiplier
101
     {
102
        if (const_alpha == 255)
103
          {
104
             memcpy(dest, src, length * sizeof(uint32_t));
105
          }
106
        else
107
          {
108
             ialpha = 255 - const_alpha;
109
             for (i = 0; i < length; ++i)
110
               dest[i] = draw_interpolate_256(src[i], const_alpha, dest[i], ialpha);
111
          }
112
     }
113
   else
114
     {
115
        if (const_alpha == 255)
116
          {
117
             for (i = 0; i < length; ++i)
118
               dest[i] = DRAW_MUL4_SYM(src[i], color);
119
          }
120
        else
121
          {
122
             ialpha = 255 - const_alpha;
123
             for (i = 0; i < length; ++i)
124
               {
125
                  src_color = DRAW_MUL4_SYM(src[i], color);
126
                  dest[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
 */
135
static void
136
_comp_func_mask_blend(uint32_t *dest, const uint8_t *mask, int length, uint32_t color)
137
{
138
   int k;
139

140
   for (k = 0; k < length; k++, dest++, mask++)
141
     {
142
        uint32_t c = draw_mul_256((*mask + 1), color);
143
        int a = 256 - (c >> 24);
144
        *dest = c + draw_mul_256(a, *dest);
145
     }
146
}
147

148
/* s = m * color
149
 * d = s * sa
150
 */
151
static void
152
_comp_func_mask_copy(uint32_t *dest, const uint8_t *mask, int length, uint32_t color)
153
{
154
   int k;
155

156
   for (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
 */
165
static void
166
_comp_func_mix3_blend(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color)
167
{
168
   int k, a;
169

170
   for (k = 0; k < len; k++, dest++, src++, mul++)
171
     {
172
        uint32_t c = DRAW_MUL4_SYM(*mul, color);
173
        c = DRAW_MUL4_SYM(c, *src);
174
        a = 256 - (c >> 24);
175
        *dest = c + draw_mul_256(a, *dest);
176
     }
177
}
178

179
/* d = s * m * c */
180
static void
181
_comp_func_mix3_copy(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color)
182
{
183
   int k;
184

185
   for (k = 0; k < len; k++, dest++, src++, mul++)
186
     {
187
        uint32_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
 */
195
static void
196
_comp_func_mix3_blend_nomul(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color EINA_UNUSED)
197
{
198
   int k, a;
199

200
   for (k = 0; k < len; k++, dest++, src++, mul++)
201
     {
202
        uint32_t c = DRAW_MUL4_SYM(*mul, *src);
203
        a = 256 - (c >> 24);
204
        *dest = c + draw_mul_256(a, *dest);
205
     }
206
}
207

208
/* d = s * m */
209
static void
210
_comp_func_mix3_copy_nomul(uint32_t *dest, const uint32_t *src, const uint32_t *mul, int len, uint32_t color EINA_UNUSED)
211
{
212
   int k;
213

214
   for (k = 0; k < len; k++, dest++, src++, mul++)
215
     {
216
        *dest = DRAW_MUL4_SYM(*mul, *src);
217
     }
218
}
219

220
RGBA_Comp_Func_Mask func_for_mode_mask[EFL_GFX_RENDER_OP_LAST] = {
221
   _comp_func_mask_blend,
222
   _comp_func_mask_copy
223
};
224

225
RGBA_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

230
RGBA_Comp_Func func_for_mode[EFL_GFX_RENDER_OP_LAST] = {
231
  _comp_func_source_over,
232
  _comp_func_source
233
};
234

235
Draw_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

242
RGBA_Comp_Func_Mask
243
efl_draw_func_mask_span_get(Efl_Gfx_Render_Op op, uint32_t color EINA_UNUSED)
244
{
245
   return func_for_mode_mask[op];
246
}
247

248
Draw_Func_ARGB_Mix3
249
efl_draw_func_argb_mix3_get(Efl_Gfx_Render_Op op, uint32_t color)
250
{
251
   if (color == 0xffffffff)
252
     return func_for_mode_argb_mix3[op + 2];
253
   else
254
     return func_for_mode_argb_mix3[op];
255
}
256

257
RGBA_Comp_Func_Solid
258
efl_draw_func_solid_span_get(Efl_Gfx_Render_Op op, uint32_t color)
259
{
260
   if ((color & 0xff000000) == 0xff000000)
261
     {
262
        if (op == EFL_GFX_RENDER_OP_BLEND) op = EFL_GFX_RENDER_OP_COPY;
263
     }
264

265
   return func_for_mode_solid[op];
266
}
267

268
RGBA_Comp_Func
269
efl_draw_func_span_get(Efl_Gfx_Render_Op op, uint32_t color, Eina_Bool src_alpha)
270
{
271
   if (((color & 0xff000000) == 0xff000000) && !src_alpha)
272
     {
273
        if (op == EFL_GFX_RENDER_OP_BLEND) op = EFL_GFX_RENDER_OP_COPY;
274
     }
275

276
   return func_for_mode[op];
277
}
278

279
static double
280
_ease_linear(double t)
281
{
282
   return t;
283
}
284

285
Eina_Bool
286
efl_draw_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint32_t *color_table, int size)
287
{
288
   int dist, idist, pos = 0, i;
289
   Eina_Bool alpha = EINA_FALSE;
290
   Efl_Gfx_Gradient_Stop *curr, *next;
291
   uint32_t current_color, next_color;
292
   double delta, t, incr, fpos;
293

294
   curr = gradient_stops;
295
   if (curr->a != 255) alpha = EINA_TRUE;
296
   current_color = DRAW_ARGB_JOIN(curr->a, curr->r, curr->g, curr->b);
297
   incr = 1.0 / (double)size;
298
   fpos = 1.5 * incr;
299

300
   color_table[pos++] = current_color;
301

302
   while (fpos <= curr->offset)
303
     {
304
        color_table[pos] = color_table[pos - 1];
305
        pos++;
306
        fpos += incr;
307
     }
308

309
   for (i = 0; i < stop_count - 1; ++i)
310
     {
311
        curr = (gradient_stops + i);
312
        next = (gradient_stops + i + 1);
313
        delta = 1/(next->offset - curr->offset);
314
        if (next->a != 255) alpha = EINA_TRUE;
315
        next_color = DRAW_ARGB_JOIN(next->a, next->r, next->g, next->b);
316
        while (fpos < next->offset && pos < size)
317
          {
318
             t = _ease_linear((fpos - curr->offset) * delta);
319
             dist = (int)(256 * t);
320
             idist = 256 - dist;
321
             color_table[pos] = draw_interpolate_256(current_color, idist, next_color, dist);
322
             ++pos;
323
             fpos += incr;
324
          }
325
        current_color = next_color;
326
     }
327

328
   for (;pos < size; ++pos)
329
     color_table[pos] = current_color;
330

331
   // Make sure the last color stop is represented at the end of the table
332
   color_table[size-1] = current_color;
333
   return alpha;
334
}
335

336

337
int
338
efl_draw_init(void)
339
{
340
   static int i = 0;
341
   if (!(i++))
342
     {
343
        _draw_log_dom = eina_log_domain_register("efl_draw", EINA_COLOR_ORANGE);
344
        efl_draw_sse2_init();
345
        efl_draw_neon_init();
346
     }
347
   return i;
348
}
349

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.