aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common/evas_map_image_internal.c
blob: d60117e8baf66335e7bcb1e97defa0d5267c0008 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// 66.74 % of time
static void
FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
          RGBA_Draw_Context *dc,
          RGBA_Map_Point *p, 
          int smooth, int level __UNUSED__) // level unused for now - for future use
{
   int i;
   int c, cx, cy, cw, ch;
   int ytop, ybottom, ystart, yend, y, sw, shp, swp, direct;
   Line *spans;
   DATA32 *buf = NULL, *sp;
   RGBA_Gfx_Func func = NULL;
   int havea = 0;
   int havecol = 4;

   // get the clip
   c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
   if (!c)
     {
        cx = 0;
        cy = 0;
        cw = dst->cache_entry.w;
        ch = dst->cache_entry.h;
     }
   
   // find y yop line and y bottom line
   ytop = p[0].y;
   if ((p[0].col >> 24) < 0xff) havea = 1;
   if (p[0].col == 0xffffffff) havecol--;
   for (i = 1; i < 4; i++)
     {
        if (p[i].y < ytop) ytop = p[i].y;
        if ((p[i].col >> 24) < 0xff) havea = 1;
        if (p[i].col == 0xffffffff) havecol--;
     }

   ybottom = p[0].y;
   for (i = 1; i < 4; i++)
     {
        if (p[i].y > ybottom) ybottom = p[i].y;
     }
   
   // convert to screen space from fixed point
   ytop = ytop >> FP;
   ybottom = ybottom >> FP;
   
   // if its outside the clip vertical bounds - don't bother
   if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
   
   // limit to the clip vertical bounds
   if (ytop < cy) ystart = cy;
   else ystart = ytop;
   if (ybottom >= (cy + ch)) yend = (cy + ch) - 1;
   else yend = ybottom;

   // get some source image information
   sp = src->image.data;
   sw = src->cache_entry.w;
   swp = sw << (FP + FPI);
   shp = src->cache_entry.h << (FP + FPI);

   // limit u,v coords of points to be within the source image
   for (i = 0; i < 4; i++)
     {
        if (p[i].u < 0) p[i].u = 0;
        else if (p[i].u > (int)(src->cache_entry.w << FP))
          p[i].u = src->cache_entry.w << FP;
        
        if (p[i].v < 0) p[i].v = 0;
        else if (p[i].v > (int)(src->cache_entry.h << FP))
          p[i].v = src->cache_entry.h << FP;
     }
   
   // allocate some spans to hold out span list
   spans = alloca((yend - ystart + 1) * sizeof(Line));
   if (!spans) return;
   memset(spans, 0, (yend - ystart + 1) * sizeof(Line));

   // calculate the spans list
   _calc_spans(p, spans, ystart, yend, cx, cy, cw, ch);
   
   // walk through spans and render
   
   // if operation is solid, bypass buf and draw func and draw direct to dst
   direct = 0;
   if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
       (!dc->mul.use) && (!havea))
     {
        direct = 1;
     }
   else
     {
        int pa;
        
        buf = alloca(cw * sizeof(DATA32));
        if (!buf) return;
        pa = src->cache_entry.flags.alpha;
        if (havea) src->cache_entry.flags.alpha = 1;
        if (dc->mul.use)
          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
        else
          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
        src->cache_entry.flags.alpha = pa;
     }
    
   if (!havecol)
     {
#undef COLMUL     
#include "evas_map_image_core.c"
     }
   else
     {
#define COLMUL 1
#include "evas_map_image_core.c"
     }
}