2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "evas_common.h"
6 #include "evas_private.h"
7 #include "../engines/common/evas_convert_color.h"
9 /* private magic number for gradient objects */
10 static const char o_type[] = "gradient";
12 /* private struct for gradient object internal data */
13 typedef struct _Evas_Object_Gradient Evas_Object_Gradient;
15 struct _Evas_Object_Gradient
26 Evas_Coord x, y, w, h;
34 unsigned char gradient_opaque : 1;
39 unsigned char changed : 1;
40 unsigned char gradient_changed : 1;
41 unsigned char type_changed : 1;
44 /* private methods for gradient objects */
45 static void evas_object_gradient_init(Evas_Object *obj);
46 static void *evas_object_gradient_new(void);
47 static void evas_object_gradient_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
48 static void evas_object_gradient_free(Evas_Object *obj);
49 static void evas_object_gradient_render_pre(Evas_Object *obj);
50 static void evas_object_gradient_render_post(Evas_Object *obj);
52 static int evas_object_gradient_is_opaque(Evas_Object *obj);
53 static int evas_object_gradient_was_opaque(Evas_Object *obj);
55 static const Evas_Object_Func object_func =
57 /* methods (compulsory) */
58 evas_object_gradient_free,
59 evas_object_gradient_render,
60 evas_object_gradient_render_pre,
61 evas_object_gradient_render_post,
62 /* these are optional. NULL = nothing */
67 evas_object_gradient_is_opaque,
68 evas_object_gradient_was_opaque,
74 /* the actual api call to add a gradient */
77 * @defgroup Evas_Object_Gradient_Group Evas Gradient Object Functions
79 * Functions that work on evas gradient objects.
81 * The following example shows how
85 * Adds a gradient object to the given evas.
86 * @param e The given evas.
87 * @return A new evas gradient object if successful. Otherwise, @c NULL.
88 * @ingroup Evas_Object_Gradient_Group
91 evas_object_gradient_add(Evas *e)
95 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
98 obj = evas_object_new();
99 evas_object_gradient_init(obj);
100 evas_object_inject(obj, e);
101 if (obj->object_data)
103 Evas_Object_Gradient *o = (Evas_Object_Gradient *)(obj->object_data);
105 o->engine_data = e->engine.func->gradient_new(e->engine.data.output);
107 evas_object_change(obj);
112 * Adds a color stop to the given evas gradient object.
114 * The @p delta parameter determines the proportion of the gradient
115 * object that is to be set to the color. For instance, if red is
116 * added with @p delta set to 2, and green is added with @p
117 * delta set to 1, two-thirds will be red or reddish and one-third
118 * will be green or greenish.
120 * Colors are added from the top downwards.
122 * @param obj The given evas gradient object.
123 * @param r Red component of the given color.
124 * @param g Green component of the given color.
125 * @param b Blue component of the given color.
126 * @param a Alpha component of the given color.
127 * @param delta Proportion of the gradient object that is this color.
128 * @ingroup Evas_Object_Gradient_Group
131 evas_object_gradient_color_stop_add(Evas_Object *obj, int r, int g, int b, int a, int delta)
133 Evas_Object_Gradient *o;
135 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
138 o = (Evas_Object_Gradient *)(obj->object_data);
139 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
143 obj->layer->evas->engine.func->gradient_color_stop_add(obj->layer->evas->engine.data.output,
146 o->gradient_changed = 1;
148 evas_object_change(obj);
152 * Adds an alpha stop to the given evas gradient object.
154 * The @p delta parameter determines the proportion of the gradient
155 * object that is to be set to the alpha value.
157 * Alphas are added from the top downwards.
159 * @param obj The given evas gradient object.
160 * @param a Alpha value.
161 * @param delta Proportion of the gradient object that is this alpha.
162 * @ingroup Evas_Object_Gradient_Group
165 evas_object_gradient_alpha_stop_add(Evas_Object *obj, int a, int delta)
167 Evas_Object_Gradient *o;
169 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
172 o = (Evas_Object_Gradient *)(obj->object_data);
173 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
177 obj->layer->evas->engine.func->gradient_alpha_stop_add(obj->layer->evas->engine.data.output,
178 o->engine_data, a, delta);
179 o->gradient_changed = 1;
181 evas_object_change(obj);
185 * Deletes all stops set for the given evas gradient object or any set data.
186 * @param obj The given evas gradient object.
187 * @ingroup Evas_Object_Gradient_Group
190 evas_object_gradient_clear(Evas_Object *obj)
192 Evas_Object_Gradient *o;
194 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
197 o = (Evas_Object_Gradient *)(obj->object_data);
198 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
202 obj->layer->evas->engine.func->gradient_clear(obj->layer->evas->engine.data.output,
204 o->gradient_changed = 1;
206 o->cur.gradient_opaque = 0;
207 evas_object_change(obj);
211 * Sets color data for the given evas gradient object.
213 * If data is so set, any existing gradient stops will be deleted,
214 * The data is not copied, so if it was allocated, do not free it while it's set.
216 * @param obj The given evas gradient object.
217 * @param data The color data to be set. Should be in argb32 pixel format.
218 * @param len The length of the data pointer - multiple of the pixel size.
219 * @param has_alpha A flag indicating if the data has alpha or not.
220 * @ingroup Evas_Object_Gradient_Group
223 evas_object_gradient_color_data_set(Evas_Object *obj, void *data, int len, Evas_Bool has_alpha)
225 Evas_Object_Gradient *o;
227 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
230 o = (Evas_Object_Gradient *)(obj->object_data);
231 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
235 obj->layer->evas->engine.func->gradient_color_data_set(obj->layer->evas->engine.data.output,
237 data, len, has_alpha);
238 o->gradient_changed = 1;
240 evas_object_change(obj);
244 * Sets alpha data for the given evas gradient object.
246 * If alpha data is so set, any existing gradient stops will be cleared,
247 * The data is not copied, so if it was allocated, do not free it while it's set.
249 * @param obj The given evas gradient object.
250 * @param data The alpha data to be set, in a8 format.
251 * @param len The length of the data pointer - multiple of the pixel size.
252 * @ingroup Evas_Object_Gradient_Group
255 evas_object_gradient_alpha_data_set(Evas_Object *obj, void *data, int len)
257 Evas_Object_Gradient *o;
259 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
262 o = (Evas_Object_Gradient *)(obj->object_data);
263 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
267 obj->layer->evas->engine.func->gradient_alpha_data_set(obj->layer->evas->engine.data.output,
270 o->gradient_changed = 1;
272 evas_object_change(obj);
276 * @defgroup Evas_Object_Gradient_Fill_Group Gradient Object Fill Rectangle Functions
278 * Functions that deal with what areas of the gradient object are to be
279 * tiled with the gradient.
283 * Sets the rectangle on the gradient object that the gradient will be
286 * Note that the gradient may be tiled around this one rectangle,
287 * according to its spread value - restrict, repeat, or reflect. To have
288 * only one 'cycle' of the gradient drawn, the spread value must be set
289 * to restrict, or @p x and @p y must be 0 and @p w and @p h need to be
290 * the width and height of the gradient object respectively.
292 * The default values for the fill parameters is @p x = 0, @p y = 0,
293 * @p w = 32 and @p h = 32.
295 * @param obj The given evas gradient object.
296 * @param x The X coordinate for the top left corner of the rect.
297 * @param y The Y coordinate for the top left corner of the rect.
298 * @param w The width of the rect.
299 * @param h The height of the rect.
300 * @ingroup Evas_Object_Gradient_Fill_Group
303 evas_object_gradient_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
305 Evas_Object_Gradient *o;
309 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
312 o = (Evas_Object_Gradient *)(obj->object_data);
313 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
316 if ((o->cur.fill.x == x) &&
317 (o->cur.fill.y == y) &&
318 (o->cur.fill.w == w) &&
319 (o->cur.fill.h == h)) return;
324 o->gradient_changed = 1;
326 evas_object_change(obj);
330 * Retrieves the dimensions of the rectangle on the gradient object that
331 * the gradient will use as its fill rect.
333 * See @ref evas_object_gradient_fill_set for more details.
335 * @param obj The given evas gradient object.
336 * @param x Pointer to an Evas_Coord to store the X coordinate in.
337 * @param y Pointer to an Evas_Coord to store the Y coordinate in.
338 * @param w Pointer to an Evas_Coord to store the width in.
339 * @param h Pointer to an Evas_Coord to store the height in.
340 * @ingroup Evas_Object_Gradient_Fill_Group
343 evas_object_gradient_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
345 Evas_Object_Gradient *o;
347 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
354 o = (Evas_Object_Gradient *)(obj->object_data);
355 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
362 if (x) *x = o->cur.fill.x;
363 if (y) *y = o->cur.fill.y;
364 if (w) *w = o->cur.fill.w;
365 if (h) *h = o->cur.fill.h;
370 * Sets the angle at which the given evas gradient object's fill sits clockwise
372 * @param obj The given evas gradient object.
373 * @param angle Angle in degrees. Can be negative.
374 * @ingroup Evas_Object_Gradient_Group
377 evas_object_gradient_fill_angle_set(Evas_Object *obj, Evas_Angle angle)
379 Evas_Object_Gradient *o;
381 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
384 o = (Evas_Object_Gradient *)(obj->object_data);
385 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
388 if (angle == o->cur.fill.angle) return;
389 o->cur.fill.angle = angle;
391 evas_object_change(obj);
395 * Retrieves the angle at which the given evas gradient object's fill sits
396 * clockwise from the vertical.
397 * @param obj The given evas gradient object.
398 * @return The current angle if successful. @c 0.0 otherwise.
399 * @ingroup Evas_Object_Gradient_Group
402 evas_object_gradient_fill_angle_get(const Evas_Object *obj)
404 Evas_Object_Gradient *o;
406 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
409 o = (Evas_Object_Gradient *)(obj->object_data);
410 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
413 return o->cur.fill.angle;
417 * Sets the tiling mode for the given evas gradient object's fill.
418 * @param obj The given evas gradient object.
419 * @param spread One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
420 * EVAS_TEXTURE_RESTRICT, EVAS_TEXTURE_RESTRICT_REFLECT, EVAS_TEXTURE_RESTRICT_REPEAT,
421 * or EVAS_TEXTURE_PAD.
422 * @ingroup Evas_Object_Gradient_Group
425 evas_object_gradient_fill_spread_set(Evas_Object *obj, int spread)
427 Evas_Object_Gradient *o;
429 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
432 o = (Evas_Object_Gradient *)(obj->object_data);
433 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
436 if (spread == o->cur.fill.spread) return;
437 o->cur.fill.spread = spread;
439 evas_object_change(obj);
443 * Retrieves the spread (tiling mode) for the given gradient object's fill.
444 * @param obj The given evas gradient object.
445 * @return The current spread mode of the gradient object.
446 * @ingroup Evas_Object_Gradient_Group
449 evas_object_gradient_fill_spread_get(const Evas_Object *obj)
451 Evas_Object_Gradient *o;
453 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
454 return EVAS_TEXTURE_REFLECT;
456 o = (Evas_Object_Gradient *)(obj->object_data);
457 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
458 return EVAS_TEXTURE_REFLECT;
460 return o->cur.fill.spread;
464 * Sets the angle at which the given evas gradient sits,
465 * relative to whatever intrinsic orientation of the grad type.
466 * Used mostly by 'linear' kinds of gradients.
467 * @param obj The given evas gradient object.
468 * @param angle Angle in degrees. Can be negative.
469 * @ingroup Evas_Object_Gradient_Group
472 evas_object_gradient_angle_set(Evas_Object *obj, Evas_Angle angle)
474 Evas_Object_Gradient *o;
476 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
479 o = (Evas_Object_Gradient *)(obj->object_data);
480 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
483 if (angle == o->cur.map.angle) return;
484 o->cur.map.angle = angle;
485 o->gradient_changed = 1;
487 evas_object_change(obj);
491 * Retrieves the angle at which the given evas gradient object sits
492 * rel to its intrinsic orientation.
493 * @param obj The given evas gradient object.
494 * @return The current angle if successful. @c 0.0 otherwise.
495 * @ingroup Evas_Object_Gradient_Group
498 evas_object_gradient_angle_get(const Evas_Object *obj)
500 Evas_Object_Gradient *o;
502 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
505 o = (Evas_Object_Gradient *)(obj->object_data);
506 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
509 return o->cur.map.angle;
513 * Sets the offset of the given evas gradient object's spectrum.
514 * @param obj The given evas gradient object.
515 * @param offset Values can be negative.
516 * @ingroup Evas_Object_Gradient_Group
519 evas_object_gradient_offset_set(Evas_Object *obj, float offset)
521 Evas_Object_Gradient *o;
523 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
526 o = (Evas_Object_Gradient *)(obj->object_data);
527 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
530 if (offset == o->cur.map.offset) return;
531 o->cur.map.offset = offset;
533 evas_object_change(obj);
537 * Retrieves the spectrum's offset
538 * @param obj The given evas gradient object.
539 * @return The current gradient offset if successful. @c 0.0 otherwise.
540 * @ingroup Evas_Object_Gradient_Group
543 evas_object_gradient_offset_get(const Evas_Object *obj)
545 Evas_Object_Gradient *o;
547 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
550 o = (Evas_Object_Gradient *)(obj->object_data);
551 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
554 return o->cur.map.offset;
558 * Sets the direction of the given evas gradient object's spectrum.
559 * @param obj The given evas gradient object.
560 * @param direction Values are either 1 (the default) or -1.
561 * @ingroup Evas_Object_Gradient_Group
564 evas_object_gradient_direction_set(Evas_Object *obj, int direction)
566 Evas_Object_Gradient *o;
568 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
571 o = (Evas_Object_Gradient *)(obj->object_data);
572 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
575 if (direction == o->cur.map.direction) return;
576 o->cur.map.direction = direction;
578 o->gradient_changed = 1;
579 evas_object_change(obj);
583 * Retrieves the evas gradient object's spectrum direction
584 * @param obj The given evas gradient object.
585 * @return The current gradient direction if successful. @c 1 otherwise.
586 * @ingroup Evas_Object_Gradient_Group
589 evas_object_gradient_direction_get(const Evas_Object *obj)
591 Evas_Object_Gradient *o;
593 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
596 o = (Evas_Object_Gradient *)(obj->object_data);
597 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
600 return o->cur.map.direction;
604 * @defgroup Evas_Object_Gradient_Type_Group Gradient Object Type Functions
606 * Functions that set or get a gradient's geometric type. Examples are "linear",
607 * "linear.diag", "linear.codiag", "radial", "rectangular", "angular", "sinusoidal", ...
608 * Some types may accept additional parameters to further specify the look.
612 * Sets the geometric type displayed by the given gradient object.
613 * @param obj The given gradient object.
614 * @param name Name of the geometric type that the gradient is to be drawn as.
615 * @param params List of allowable params that the given gradient type allows.
617 * @ingroup Evas_Object_Gradient_Type_Group
620 evas_object_gradient_type_set(Evas_Object *obj, const char *name, const char *params)
622 Evas_Object_Gradient *o;
624 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
627 o = (Evas_Object_Gradient *)(obj->object_data);
628 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
636 if (params && !*params)
638 if ((o->cur.type.name) && (!strcmp(o->cur.type.name, name)))
640 if ((!o->cur.type.params) && (!params))
642 if ((o->cur.type.params) && (params) && (!strcmp(o->cur.type.params, params)))
644 if (o->cur.type.params)
646 if (o->prev.type.params == o->cur.type.params)
647 o->prev.type.params = strdup(o->cur.type.params);
648 free(o->cur.type.params);
649 o->cur.type.params = NULL;
652 o->cur.type.params = strdup(params);
654 o->gradient_changed = 1;
656 evas_object_change(obj);
660 if (o->cur.type.name)
662 if (o->prev.type.name == o->cur.type.name)
663 o->prev.type.name = strdup(o->cur.type.name);
664 free(o->cur.type.name);
665 o->cur.type.name = NULL;
667 o->cur.type.name = strdup(name);
669 if (o->cur.type.params)
671 if (o->prev.type.params == o->cur.type.params)
672 o->prev.type.params = strdup(o->cur.type.params);
673 free(o->cur.type.params);
674 o->cur.type.params = NULL;
677 o->cur.type.params = strdup(params);
679 o->gradient_changed = 1;
681 evas_object_change(obj);
685 * Retrieves the type name and params of the given gradient object.
686 * @param obj The given gradient object.
687 * @param name Pointer to a character pointer to store the pointer to the type
689 * @param params Pointer to a character pointer to store the pointer to the type
691 * @ingroup Evas_Object_Gradient_Type_Group
694 evas_object_gradient_type_get(const Evas_Object *obj, char **name, char **params)
696 Evas_Object_Gradient *o;
698 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
699 if (name) *name = NULL;
700 if (params) *params = NULL;
703 o = (Evas_Object_Gradient *)(obj->object_data);
704 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
705 if (name) *name = NULL;
706 if (params) *params = NULL;
709 if (name) *name = o->cur.type.name;
710 if (params) *params = o->cur.type.params;
715 these two functions don't really belong here as they can apply to other
716 objs as well, but for now..
723 evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
725 evas_common_convert_color_hsv_to_rgb(h, s, v, r, g, b);
732 evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
734 evas_common_convert_color_rgb_to_hsv(r, g, b, h, s, v);
741 evas_color_argb_premul(int a, int *r, int *g, int *b)
743 evas_common_convert_color_argb_premul(a, r, g, b);
750 evas_color_argb_unpremul(int a, int *r, int *g, int *b)
752 evas_common_convert_color_argb_unpremul(a, r, g, b);
759 evas_data_argb_premul(unsigned int *data, unsigned int len)
761 if (!data || (len < 1)) return;
762 evas_common_convert_argb_premul(data, len);
769 evas_data_argb_unpremul(unsigned int *data, unsigned int len)
771 if (!data || (len < 1)) return;
772 evas_common_convert_argb_unpremul(data, len);
777 /* all nice and private */
779 evas_object_gradient_init(Evas_Object *obj)
781 /* alloc grad ob, setup methods and default values */
782 obj->object_data = evas_object_gradient_new();
783 /* set up default settings for this kind of object */
784 obj->cur.color.r = 255;
785 obj->cur.color.g = 255;
786 obj->cur.color.b = 255;
787 obj->cur.color.a = 255;
788 obj->cur.geometry.x = 0;
789 obj->cur.geometry.y = 0;
790 obj->cur.geometry.w = 0;
791 obj->cur.geometry.h = 0;
793 obj->cur.anti_alias = 1;
794 obj->cur.interpolation_color_space = EVAS_COLOR_SPACE_ARGB;
795 obj->cur.render_op = EVAS_RENDER_BLEND;
796 /* set up object-specific settings */
797 obj->prev = obj->cur;
798 /* set up methods (compulsory) */
799 obj->func = &object_func;
804 evas_object_gradient_new(void)
806 Evas_Object_Gradient *o;
808 /* alloc obj private data */
809 o = calloc(1, sizeof(Evas_Object_Gradient));
811 o->magic = MAGIC_OBJ_GRADIENT;
812 o->cur.map.angle = 0.0;
813 o->cur.map.offset = 0.0;
814 o->cur.map.direction = 1;
819 o->cur.fill.angle = 0.0;
820 o->cur.fill.spread = EVAS_TEXTURE_REFLECT;
821 o->cur.type.name = strdup("linear");
822 o->cur.type.params = NULL;
823 o->cur.gradient_opaque = 0;
826 o->gradient_changed = 1;
832 evas_object_gradient_free(Evas_Object *obj)
834 Evas_Object_Gradient *o;
836 /* frees private object data. very simple here */
837 o = (Evas_Object_Gradient *)(obj->object_data);
838 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
842 if (o->prev.type.name && (o->prev.type.name != o->cur.type.name))
843 free(o->prev.type.name);
844 if (o->prev.type.params && (o->prev.type.params != o->cur.type.params))
845 free(o->prev.type.params);
846 if (o->cur.type.name)
847 free(o->cur.type.name);
848 if (o->cur.type.params)
849 free(o->cur.type.params);
851 obj->layer->evas->engine.func->gradient_free(obj->layer->evas->engine.data.output,
854 obj->object_data = NULL;
859 evas_object_grad_get_fill_coords(Evas_Object *obj, Evas_Coord fx, Evas_Coord fy, Evas_Coord fw, Evas_Coord fh, Evas_Coord *fx_ret, Evas_Coord *fy_ret, Evas_Coord *fw_ret,
862 Evas_Coord x, y, w, h;
864 x = ((fx * obj->layer->evas->output.w) /
865 (Evas_Coord)obj->layer->evas->viewport.w);
866 w = ((fw * obj->layer->evas->output.w) /
867 (Evas_Coord)obj->layer->evas->viewport.w);
868 y = ((fy * obj->layer->evas->output.h) /
869 (Evas_Coord)obj->layer->evas->viewport.h);
870 h = ((fh * obj->layer->evas->output.h) /
871 (Evas_Coord)obj->layer->evas->viewport.h);
876 *fx_ret = x; *fw_ret = w;
877 *fy_ret = y; *fh_ret = h;
883 evas_object_gradient_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
885 Evas_Object_Gradient *o;
887 /* render object to surface with context, and offxet by x,y */
888 o = (Evas_Object_Gradient *)(obj->object_data);
889 obj->layer->evas->engine.func->context_multiplier_unset(output, context);
890 obj->layer->evas->engine.func->context_anti_alias_set(output, context, obj->cur.anti_alias);
891 obj->layer->evas->engine.func->context_render_op_set(output, context, obj->cur.render_op);
894 obj->layer->evas->engine.func->gradient_draw(output, context, surface,
896 obj->cur.geometry.x + x,
897 obj->cur.geometry.y + y,
899 obj->cur.geometry.h);
900 //// obj->cur.cache.geometry.x + x,
901 //// obj->cur.cache.geometry.y + y,
902 //// obj->cur.cache.geometry.w,
903 //// obj->cur.cache.geometry.h);
908 evas_object_gradient_render_pre(Evas_Object *obj)
910 Evas_Rectangles rects = { 0, 0, NULL };
911 Evas_Object_Gradient *o;
914 /* dont pre-render the obj twice! */
915 if (obj->pre_render_done) return;
916 obj->pre_render_done = 1;
917 /* pre-render phase. this does anything an object needs to do just before */
918 /* rendering. this could mean loading the image data, retrieving it from */
919 /* elsewhere, decoding video etc. */
920 /* then when this is done the object needs to figure if it changed and */
921 /* if so what and where and add the appropriate redraw rectangles */
922 o = (Evas_Object_Gradient *)(obj->object_data);
923 /* if someone is clipping this obj - go calculate the clipper */
924 if (obj->cur.clipper)
926 if (obj->cur.cache.clip.dirty)
927 evas_object_clip_recalc(obj->cur.clipper);
928 obj->cur.clipper->func->render_pre(obj->cur.clipper);
930 /* if it changed color */
931 if ((obj->cur.color.r != obj->prev.color.r) ||
932 (obj->cur.color.g != obj->prev.color.g) ||
933 (obj->cur.color.b != obj->prev.color.b) ||
934 (obj->cur.color.a != obj->prev.color.a))
935 { o->gradient_changed = 1; o->changed = 1; }
936 if ((!o->gradient_changed) && ((obj->cur.cache.clip.r != obj->prev.cache.clip.r) ||
937 (obj->cur.cache.clip.g != obj->prev.cache.clip.g) ||
938 (obj->cur.cache.clip.b != obj->prev.cache.clip.b) ||
939 (obj->cur.cache.clip.a != obj->prev.cache.clip.a)))
940 { o->gradient_changed = 1; o->changed = 1; }
941 if (!o->gradient_changed && (obj->cur.interpolation_color_space != obj->prev.interpolation_color_space))
942 { o->gradient_changed = 1; o->changed = 1; }
943 if (!o->changed && (obj->cur.render_op != obj->prev.render_op))
945 if (!o->changed && (obj->cur.anti_alias != obj->prev.anti_alias))
947 if (o->changed && o->engine_data)
949 Evas_Coord fx, fy, fw, fh;
951 evas_object_grad_get_fill_coords(obj, o->cur.fill.x, o->cur.fill.y,
952 o->cur.fill.w, o->cur.fill.h,
954 obj->layer->evas->engine.func->gradient_fill_set(obj->layer->evas->engine.data.output, o->engine_data,
956 obj->layer->evas->engine.func->gradient_fill_angle_set(obj->layer->evas->engine.data.output, o->engine_data,
958 obj->layer->evas->engine.func->gradient_fill_spread_set(obj->layer->evas->engine.data.output, o->engine_data,
960 obj->layer->evas->engine.func->gradient_angle_set(obj->layer->evas->engine.data.output, o->engine_data,
962 obj->layer->evas->engine.func->gradient_direction_set(obj->layer->evas->engine.data.output, o->engine_data,
963 o->cur.map.direction);
964 obj->layer->evas->engine.func->gradient_offset_set(obj->layer->evas->engine.data.output, o->engine_data,
967 obj->layer->evas->engine.func->gradient_type_set(obj->layer->evas->engine.data.output, o->engine_data,
968 o->cur.type.name, o->cur.type.params);
970 obj->layer->evas->engine.func->context_anti_alias_set(obj->layer->evas->engine.data.output,
971 obj->layer->evas->engine.data.context,
972 obj->cur.anti_alias);
973 obj->layer->evas->engine.func->context_render_op_set(obj->layer->evas->engine.data.output,
974 obj->layer->evas->engine.data.context, obj->cur.render_op);
975 obj->layer->evas->engine.func->context_multiplier_set(obj->layer->evas->engine.data.output,
976 obj->layer->evas->engine.data.context,
977 obj->cur.cache.clip.r, obj->cur.cache.clip.g,
978 obj->cur.cache.clip.b, obj->cur.cache.clip.a);
979 obj->layer->evas->engine.func->context_color_interpolation_set(obj->layer->evas->engine.data.output,
980 obj->layer->evas->engine.data.context,
981 obj->cur.interpolation_color_space);
982 if (o->gradient_changed)
983 obj->layer->evas->engine.func->gradient_render_pre(obj->layer->evas->engine.data.output,
984 obj->layer->evas->engine.data.context,
986 o->cur.gradient_opaque = obj->layer->evas->engine.func->gradient_is_opaque(obj->layer->evas->engine.data.output,
987 obj->layer->evas->engine.data.context,
989 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
990 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
992 if (obj->cur.cache.clip.a != 255)
993 o->cur.gradient_opaque = 0;
995 /* now figure what changed and add draw rects */
996 /* if it just became visible or invisible */
997 is_v = evas_object_is_visible(obj);
998 was_v = evas_object_was_visible(obj);
1001 evas_object_render_pre_visible_change(&rects, obj, is_v, was_v);
1004 /* its not visible - we accounted for it appearing or not so just abort */
1005 if (!is_v) goto done;
1006 /* clipper changed this is in addition to anything else for obj */
1007 evas_object_render_pre_clipper_change(&rects, obj);
1008 /* gradient changed */
1009 if (o->changed || obj->restack)
1011 evas_object_render_pre_prev_cur_add(&rects, obj);
1014 /* if it changed geometry */
1015 if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
1016 (obj->cur.geometry.y != obj->prev.geometry.y) ||
1017 (obj->cur.geometry.w != obj->prev.geometry.w) ||
1018 (obj->cur.geometry.h != obj->prev.geometry.h))
1020 evas_object_render_pre_prev_cur_add(&rects, obj);
1023 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
1024 /* area so if there were updates for it they get wiped. don't do it if we */
1025 /* arent fully opaque and we are visible */
1027 if (evas_object_is_visible(obj) &&
1028 evas_object_is_opaque(obj))
1029 obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output,
1030 obj->cur.cache.clip.x,
1031 obj->cur.cache.clip.y,
1032 obj->cur.cache.clip.w,
1033 obj->cur.cache.clip.h);
1036 evas_object_render_pre_effect_updates(&rects, obj, is_v, was_v);
1040 evas_object_gradient_render_post(Evas_Object *obj)
1042 Evas_Object_Gradient *o;
1044 /* this moves the current data to the previous state parts of the object */
1045 /* in whatever way is safest for the object. also if we don't need object */
1046 /* data anymore we can free it if the object deems this is a good idea */
1047 o = (Evas_Object_Gradient *)(obj->object_data);
1048 /* remove those pesky changes */
1049 while (obj->clip.changes)
1053 r = (Evas_Rectangle *)obj->clip.changes->data;
1054 obj->clip.changes = evas_list_remove(obj->clip.changes, r);
1057 /* move cur to prev safely for object data */
1058 obj->prev = obj->cur;
1059 if (o->prev.type.name && (o->prev.type.name != o->cur.type.name))
1060 free(o->prev.type.name);
1061 if (o->prev.type.params && (o->prev.type.params != o->cur.type.params))
1062 free(o->prev.type.params);
1065 o->gradient_changed = 0;
1066 o->type_changed = 0;
1070 evas_object_gradient_is_opaque(Evas_Object *obj)
1072 Evas_Object_Gradient *o;
1074 /* this returns 1 if the internal object data implies that the object is */
1075 /* currently fully opaque over the entire region it occupies */
1076 o = (Evas_Object_Gradient *)(obj->object_data);
1077 if (!o->engine_data) return 0;
1078 return o->cur.gradient_opaque;
1082 evas_object_gradient_was_opaque(Evas_Object *obj)
1084 Evas_Object_Gradient *o;
1086 /* this returns 1 if the internal object data implies that the object was */
1087 /* currently fully opaque over the entire region it occupies */
1088 o = (Evas_Object_Gradient *)(obj->object_data);
1089 if (!o->engine_data) return 0;
1090 return o->prev.gradient_opaque;