tizen 2.4 release
[framework/uifw/e17-mod-tizen-comp.git] / src / e_mod_comp_update.c
1 #include "e.h"
2 #include "e_mod_main.h"
3 #include "e_mod_comp_update.h"
4
5 //////////////////////////////////////////////////////////////////////////
6
7 static void
8 _e_mod_comp_tiles_alloc(E_Update *up)
9 {
10    if (up->tiles) return;
11    up->tiles = calloc(up->tw * up->th, sizeof(unsigned char));
12 }
13
14 //////////////////////////////////////////////////////////////////////////
15
16 E_Update *
17 e_mod_comp_update_new(void)
18 {
19    E_Update *up;
20
21    up = calloc(1, sizeof(E_Update));
22    if (!up) return NULL;
23
24    up->tsw = 32;
25    up->tsh = 32;
26    up->pol = E_UPDATE_POLICY_RAW;
27    return up;
28 }
29
30 void
31 e_mod_comp_update_free(E_Update *up)
32 {
33    if (!up) return;
34    if (up->tiles) free(up->tiles);
35    free(up);
36 }
37
38 void
39 e_mod_comp_update_policy_set(E_Update       *up,
40                              E_Update_Policy pol)
41 {
42    up->pol = pol;
43 }
44
45 void
46 e_mod_comp_update_tile_size_set(E_Update *up,
47                                 int       tsw,
48                                 int       tsh)
49 {
50    if ((up->tsw == tsw) && (up->tsh == tsh)) return;
51    up->tsw = tsw;
52    up->tsh = tsh;
53    e_mod_comp_update_clear(up);
54 }
55
56 void
57 e_mod_comp_update_resize(E_Update *up,
58                          int       w,
59                          int       h)
60 {
61    unsigned char *ptiles, *p, *pp;
62    int ptw, pth, x, y;
63
64    if ((!up) || ((up->w == w) && (up->h == h))) return;
65
66    ptw = up->tw;
67    pth = up->th;
68    ptiles = up->tiles;
69
70    up->w = w;
71    up->h = h;
72    up->tw = (up->w + up->tsw - 1) / up->tsw;
73    up->th = (up->h + up->tsh - 1) / up->tsh;
74    up->tiles = NULL;
75    _e_mod_comp_tiles_alloc(up);
76    if ((ptiles) && (up->tiles))
77      {
78         if (pth <= up->th)
79           {
80              for (y = 0; y < pth; y++)
81                {
82                   p = up->tiles + (y * up->tw);
83                   pp = ptiles + (y * ptw);
84                   if (ptw <= up->tw) for (x = 0; x < ptw; x++) *p++ = *pp++;
85                   else for (x = 0; x < up->tw; x++) *p++ = *pp++;
86                }
87           }
88         else
89           {
90              for (y = 0; y < up->th; y++)
91                {
92                   p = up->tiles + (y * up->tw);
93                   pp = ptiles + (y * ptw);
94                   if (ptw <= up->tw) for (x = 0; x < ptw; x++) *p++ = *pp++;
95                   else for (x = 0; x < up->tw; x++) *p++ = *pp++;
96                }
97           }
98      }
99    free(ptiles);
100 }
101
102 void
103 e_mod_comp_update_add(E_Update *up,
104                       int       x,
105                       int       y,
106                       int       w,
107                       int       h)
108 {
109    int tx, ty, txx, tyy, xx, yy;
110    unsigned char *t, *t2;
111
112    if ((w <= 0) || (h <= 0)) return;
113    if ((up->tw <= 0) || (up->th <= 0)) return;
114
115    _e_mod_comp_tiles_alloc(up);
116
117    E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, up->w, up->h);
118    if ((w <= 0) || (h <= 0)) return;
119
120    switch (up->pol)
121      {
122       case E_UPDATE_POLICY_RAW:
123         break;
124
125       case E_UPDATE_POLICY_HALF_WIDTH_OR_MORE_ROUND_UP_TO_FULL_WIDTH:
126         if (w > (up->w / 2))
127           {
128              x = 0;
129              w = up->w;
130           }
131         break;
132
133       default:
134         break;
135      }
136
137    tx = x / up->tsw;
138    ty = y / up->tsh;
139    txx = (x + w - 1) / up->tsw;
140    tyy = (y + h - 1) / up->tsh;
141    t = up->tiles + (ty * up->tw) + tx;
142    for (yy = ty; yy <= tyy; yy++)
143      {
144         t2 = t;
145         for (xx = tx; xx <= txx; xx++)
146           {
147              *t2 = 1;
148              t2++;
149           }
150         t += up->tw;
151      }
152 }
153
154 E_Update_Rect *
155 e_mod_comp_update_rects_get(E_Update *up)
156 {
157    E_Update_Rect *r;
158    int ri = 0;
159    int x, y;
160    unsigned char *t, *t2, *t3;
161
162    if (!up->tiles) return NULL;
163    r = calloc((up->tw * up->th) + 1, sizeof(E_Update_Rect));
164    if (!r) return NULL;
165    t = up->tiles;
166    for (y = 0; y < up->th; y++)
167      {
168         for (x = 0; x < up->tw; x++)
169           {
170              if (*t)
171                {
172                   int can_expand_x = 1, can_expand_y = 1;
173                   int xx = 0, yy = 0;
174
175                   t2 = t + 1;
176                   while (can_expand_x)
177                     {
178                        xx++;
179                        if ((x + xx) >= up->tw) can_expand_x = 0;
180                        else if (!*t2)
181                          can_expand_x = 0;
182                        if (can_expand_x) *t2 = 0;
183                        t2++;
184                     }
185                   t3 = t;
186                   while (can_expand_y)
187                     {
188                        int i;
189
190                        yy++;
191                        t3 += up->tw;
192                        if ((y + yy) >= up->th) can_expand_y = 0;
193                        if (can_expand_y)
194                          {
195                             t2 = t3;
196                             for (i = 0; i < xx; i++)
197                               {
198                                  if (!*t2)
199                                    {
200                                       can_expand_y = 0;
201                                       break;
202                                    }
203                                  t2++;
204                               }
205                          }
206                        if (can_expand_y)
207                          {
208                             t2 = t3;
209                             for (i = 0; i < xx; i++)
210                               {
211                                  *t2 = 0;
212                                  t2++;
213                               }
214                          }
215                     }
216                   *t = 0;
217                   r[ri].x = x * up->tsw;
218                   r[ri].y = y * up->tsh;
219                   r[ri].w = xx * up->tsw;
220                   r[ri].h = yy * up->tsh;
221                   if ((r[ri].x + r[ri].w) > up->w) r[ri].w = up->w - r[ri].x;
222                   if ((r[ri].y + r[ri].h) > up->h) r[ri].h = up->h - r[ri].y;
223                   if ((r[ri].w <= 0) || (r[ri].h <= 0)) r[ri].w = 0;
224                   else ri++;
225                   x += xx - 1;
226                   t += xx - 1;
227                }
228              t++;
229           }
230      }
231    return r;
232 }
233
234 void
235 e_mod_comp_update_clear(E_Update *up)
236 {
237    if (up->tiles)
238      {
239         free(up->tiles);
240         up->tiles = NULL;
241      }
242 }
243