merged evas image masking code from brett
[framework/uifw/evas.git] / src / lib / include / evas_inline.x
1 #ifndef EVAS_INLINE_H
2 #define EVAS_INLINE_H
3
4 static inline void
5 _evas_object_event_new(void)
6 {
7    _evas_event_counter++;
8 }
9
10 static inline int
11 evas_object_was_visible(Evas_Object *obj)
12 {
13    if ((obj->prev.visible) &&
14        ((obj->prev.cache.clip.visible) || (obj->smart.smart)) &&
15        ((obj->prev.cache.clip.a > 0 && obj->prev.render_op == EVAS_RENDER_BLEND)
16        || obj->prev.render_op != EVAS_RENDER_BLEND))
17      {
18         if (obj->func->was_visible)
19           return obj->func->was_visible(obj);
20         return 1;
21      }
22    return 0;
23 }
24
25 static inline void
26 evas_add_rect(Eina_Array *rects, int x, int y, int w, int h)
27 {
28    Eina_Rectangle *r;
29
30    NEW_RECT(r, x, y, w, h);
31    if (r) eina_array_push(rects, r);
32 }
33
34 static inline Cutout_Rect*
35 evas_common_draw_context_cutouts_add(Cutout_Rects* rects,
36                                      int x, int y, int w, int h)
37 {
38    Cutout_Rect* rect;
39
40    if (rects->max < (rects->active + 1))
41      {
42         rects->max += 128;
43         rects->rects = (Cutout_Rect *)realloc(rects->rects, sizeof(Cutout_Rect) * rects->max);
44      }
45
46    rect = rects->rects + rects->active;
47    rect->x = x;
48    rect->y = y;
49    rect->w = w;
50    rect->h = h;
51    rects->active++;
52
53    return rect;
54 }
55
56 static inline int
57 evas_object_is_opaque(Evas_Object *obj)
58 {
59    if (obj->smart.smart) return 0;
60    /* If a mask: Assume alpha */
61    if (obj->cur.mask) return 0;
62    if (obj->cur.cache.clip.a == 255)
63      {
64         if (obj->func->is_opaque)
65           return obj->func->is_opaque(obj);
66         return 1;
67      }
68    if (obj->cur.render_op == EVAS_RENDER_COPY)
69      return 1;
70    return 0;
71 }
72
73 static inline int
74 evas_event_passes_through(Evas_Object *obj)
75 {
76    if (obj->layer->evas->events_frozen > 0) return 1;
77    if (obj->pass_events) return 1;
78    if (obj->parent_cache_valid) return obj->parent_pass_events;
79    if (obj->smart.parent)
80      {
81         int par_pass;
82
83         par_pass = evas_event_passes_through(obj->smart.parent);
84         obj->parent_cache_valid = 1;
85         obj->parent_pass_events = par_pass;
86         return par_pass;
87      }
88    return 0;
89 }
90
91 static inline int
92 evas_object_is_visible(Evas_Object *obj)
93 {
94    if ((obj->cur.visible) &&
95        ((obj->cur.cache.clip.visible) || (obj->smart.smart)) &&
96        ((obj->cur.cache.clip.a > 0 && obj->cur.render_op == EVAS_RENDER_BLEND)
97        || obj->cur.render_op != EVAS_RENDER_BLEND))
98      {
99         if (obj->func->is_visible)
100           return obj->func->is_visible(obj);
101         return 1;
102      }
103    return 0;
104 }
105
106 static inline int
107 evas_object_clippers_is_visible(Evas_Object *obj)
108 {
109    if (obj->cur.visible)
110      {
111         if (obj->cur.clipper)
112           return evas_object_clippers_is_visible(obj->cur.clipper);
113         return 1;
114      }
115    return 0;
116 }
117
118 static inline int
119 evas_object_is_in_output_rect(Evas_Object *obj, int x, int y, int w, int h)
120 {
121    /* assumes coords have been recalced */
122    if ((RECTS_INTERSECT(x, y, w, h,
123                         obj->cur.cache.clip.x,
124                         obj->cur.cache.clip.y,
125                         obj->cur.cache.clip.w,
126                         obj->cur.cache.clip.h)))
127      return 1;
128    return 0;
129 }
130
131 static inline int
132 evas_object_is_active(Evas_Object *obj)
133 {
134    if (evas_object_is_visible(obj) || evas_object_was_visible(obj))
135      {
136         if (obj->smart.smart)
137           {
138              int mapsmt = 0;
139              if (obj->smart.smart && (obj->cur.map && obj->cur.usemap)) mapsmt = 1;
140              if (!mapsmt) return 1;
141              if (evas_object_is_in_output_rect(obj, 0, 0, obj->layer->evas->output.w,
142                                                obj->layer->evas->output.h) ||
143                  evas_object_was_in_output_rect(obj, 0, 0, obj->layer->evas->output.w,
144                                                 obj->layer->evas->output.h))
145                return 1;
146           }
147         else
148           {
149              if (evas_object_is_in_output_rect(obj, 0, 0, obj->layer->evas->output.w,
150                                                obj->layer->evas->output.h) ||
151                  evas_object_was_in_output_rect(obj, 0, 0, obj->layer->evas->output.w,
152                                                 obj->layer->evas->output.h))
153                return 1;
154           }
155      }
156    return 0;
157 }
158
159 static inline void
160 evas_object_coords_recalc(Evas_Object *obj)
161 {
162 ////   if (obj->cur.cache.geometry.validity == obj->layer->evas->output_validity)
163 ////     return;
164 ////   obj->cur.cache.geometry.x =
165 ////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur.geometry.x);
166 ////   obj->cur.cache.geometry.y =
167 ////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur.geometry.y);
168 ////   obj->cur.cache.geometry.w =
169 ////     evas_coord_world_x_to_screen(obj->layer->evas, obj->cur.geometry.w) -
170 ////     evas_coord_world_x_to_screen(obj->layer->evas, 0);
171 ////   obj->cur.cache.geometry.h =
172 ////     evas_coord_world_y_to_screen(obj->layer->evas, obj->cur.geometry.h) -
173 ////     evas_coord_world_y_to_screen(obj->layer->evas, 0);
174    if (obj->func->coords_recalc) obj->func->coords_recalc(obj);
175 ////   obj->cur.cache.geometry.validity = obj->layer->evas->output_validity;
176 }
177
178 static inline void
179 evas_object_clip_recalc(Evas_Object *obj)
180 {
181    int cx, cy, cw, ch, cvis, cr, cg, cb, ca;
182    int nx, ny, nw, nh, nvis, nr, ng, nb, na;
183
184    if ((!obj->cur.cache.clip.dirty) &&
185        !(!obj->cur.clipper || obj->cur.clipper->cur.cache.clip.dirty))
186      return;
187    if (obj->layer->evas->events_frozen > 0) return;
188    evas_object_coords_recalc(obj);
189    if ((obj->cur.map) && (obj->cur.usemap))
190      {
191         cx = obj->cur.map->normal_geometry.x;
192         cy = obj->cur.map->normal_geometry.y;
193         cw = obj->cur.map->normal_geometry.w;
194         ch = obj->cur.map->normal_geometry.h;
195      }
196    else
197      {
198         cx = obj->cur.geometry.x;
199         cy = obj->cur.geometry.y;
200         cw = obj->cur.geometry.w;
201         ch = obj->cur.geometry.h;
202      }
203 ////   cx = obj->cur.cache.geometry.x; cy = obj->cur.cache.geometry.y;
204 ////   cw = obj->cur.cache.geometry.w; ch = obj->cur.cache.geometry.h;
205    if (obj->cur.color.a == 0 && obj->cur.render_op == EVAS_RENDER_BLEND) cvis = 0;
206    else cvis = obj->cur.visible;
207    cr = obj->cur.color.r; cg = obj->cur.color.g;
208    cb = obj->cur.color.b; ca = obj->cur.color.a;
209    if ((obj->cur.clipper) &&
210        (obj->cur.clipper->cur.map_parent == obj->cur.map_parent))
211      {
212 // this causes problems... hmmm
213         if (obj->cur.clipper->cur.cache.clip.dirty)
214           evas_object_clip_recalc(obj->cur.clipper);
215         nx = obj->cur.clipper->cur.cache.clip.x;
216         ny = obj->cur.clipper->cur.cache.clip.y;
217         nw = obj->cur.clipper->cur.cache.clip.w;
218         nh = obj->cur.clipper->cur.cache.clip.h;
219         RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
220
221         nvis = obj->cur.clipper->cur.cache.clip.visible;
222         nr = obj->cur.clipper->cur.cache.clip.r;
223         ng = obj->cur.clipper->cur.cache.clip.g;
224         nb = obj->cur.clipper->cur.cache.clip.b;
225         na = obj->cur.clipper->cur.cache.clip.a;
226         cvis = cvis * nvis;
227         cr = (cr * (nr + 1)) >> 8;
228         cg = (cg * (ng + 1)) >> 8;
229         cb = (cb * (nb + 1)) >> 8;
230         ca = (ca * (na + 1)) >> 8;
231      }
232    if ((ca == 0 && obj->cur.render_op == EVAS_RENDER_BLEND) || (cw <= 0) || (ch <= 0)) cvis = 0;
233    obj->cur.cache.clip.x = cx;
234    obj->cur.cache.clip.y = cy;
235    obj->cur.cache.clip.w = cw;
236    obj->cur.cache.clip.h = ch;
237    obj->cur.cache.clip.visible = cvis;
238    obj->cur.cache.clip.r = cr;
239    obj->cur.cache.clip.g = cg;
240    obj->cur.cache.clip.b = cb;
241    obj->cur.cache.clip.a = ca;
242    obj->cur.cache.clip.dirty = 0;
243 }
244
245 #endif