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 unsigned int evas_object_gradient_id_get(Evas_Object *obj);
53 static unsigned int evas_object_gradient_visual_id_get(Evas_Object *obj);
54 static void *evas_object_gradient_engine_data_get(Evas_Object *obj);
56 static int evas_object_gradient_is_opaque(Evas_Object *obj);
57 static int evas_object_gradient_was_opaque(Evas_Object *obj);
59 static const Evas_Object_Func object_func =
61 /* methods (compulsory) */
62 evas_object_gradient_free,
63 evas_object_gradient_render,
64 evas_object_gradient_render_pre,
65 evas_object_gradient_render_post,
66 evas_object_gradient_id_get,
67 evas_object_gradient_visual_id_get,
68 evas_object_gradient_engine_data_get,
69 /* these are optional. NULL = nothing */
74 evas_object_gradient_is_opaque,
75 evas_object_gradient_was_opaque,
85 /* the actual api call to add a gradient */
88 * @addtogroup Evas_Object_Gradient_Group
93 * Adds a gradient object to the given evas.
94 * @param e The given evas.
95 * @return A new evas gradient object if successful. Otherwise, @c NULL.
96 * @ingroup Evas_Object_Gradient_Group
99 evas_object_gradient_add(Evas *e)
103 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
106 obj = evas_object_new(e);
107 evas_object_gradient_init(obj);
108 evas_object_inject(obj, e);
109 if (obj->object_data)
111 Evas_Object_Gradient *o = (Evas_Object_Gradient *)(obj->object_data);
113 o->engine_data = e->engine.func->gradient_new(e->engine.data.output);
115 evas_object_change(obj);
120 * Adds a color stop to the given evas gradient object.
122 * The @p delta parameter determines the proportion of the gradient
123 * object that is to be set to the color. For instance, if red is
124 * added with @p delta set to 2, and green is added with @p
125 * delta set to 1, two-thirds will be red or reddish and one-third
126 * will be green or greenish.
128 * Colors are added from the top downwards.
130 * @param obj The given evas gradient object.
131 * @param r Red component of the given color.
132 * @param g Green component of the given color.
133 * @param b Blue component of the given color.
134 * @param a Alpha component of the given color.
135 * @param delta Proportion of the gradient object that is this color.
138 evas_object_gradient_color_stop_add(Evas_Object *obj, int r, int g, int b, int a, int delta)
140 Evas_Object_Gradient *o;
142 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
145 o = (Evas_Object_Gradient *)(obj->object_data);
146 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
151 #ifdef EVAS_FRAME_QUEUING
152 evas_common_pipe_op_grad_flush(o->engine_data);
155 obj->layer->evas->engine.func->gradient_color_stop_add(obj->layer->evas->engine.data.output,
159 o->gradient_changed = 1;
161 evas_object_change(obj);
165 * Adds an alpha stop to the given evas gradient object.
167 * The @p delta parameter determines the proportion of the gradient
168 * object that is to be set to the alpha value.
170 * Alphas are added from the top downwards.
172 * @param obj The given evas gradient object.
173 * @param a Alpha value.
174 * @param delta Proportion of the gradient object that is this alpha.
177 evas_object_gradient_alpha_stop_add(Evas_Object *obj, int a, int delta)
179 Evas_Object_Gradient *o;
181 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
184 o = (Evas_Object_Gradient *)(obj->object_data);
185 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
190 #ifdef EVAS_FRAME_QUEUING
191 evas_common_pipe_op_grad_flush(o->engine_data);
193 obj->layer->evas->engine.func->gradient_alpha_stop_add(obj->layer->evas->engine.data.output,
194 o->engine_data, a, delta);
196 o->gradient_changed = 1;
198 evas_object_change(obj);
202 * Deletes all stops set for the given evas gradient object or any set data.
203 * @param obj The given evas gradient object.
206 evas_object_gradient_clear(Evas_Object *obj)
208 Evas_Object_Gradient *o;
210 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
213 o = (Evas_Object_Gradient *)(obj->object_data);
214 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
219 #ifdef EVAS_FRAME_QUEUING
220 evas_common_pipe_op_grad_flush(o->engine_data);
222 obj->layer->evas->engine.func->gradient_clear(obj->layer->evas->engine.data.output,
225 o->gradient_changed = 1;
227 o->cur.gradient_opaque = 0;
228 evas_object_change(obj);
232 * Sets color data for the given evas gradient object.
234 * If data is so set, any existing gradient stops will be deleted,
235 * The data is not copied, so if it was allocated, do not free it while it's set.
237 * @param obj The given evas gradient object.
238 * @param data The color data to be set. Should be in argb32 pixel format.
239 * @param len The length of the data pointer - multiple of the pixel size.
240 * @param has_alpha A flag indicating if the data has alpha or not.
243 evas_object_gradient_color_data_set(Evas_Object *obj, void *data, int len, Eina_Bool has_alpha)
245 Evas_Object_Gradient *o;
247 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
250 o = (Evas_Object_Gradient *)(obj->object_data);
251 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
256 #ifdef EVAS_FRAME_QUEUING
257 evas_common_pipe_op_grad_flush(o->engine_data);
259 obj->layer->evas->engine.func->gradient_color_data_set(obj->layer->evas->engine.data.output,
261 data, len, has_alpha);
263 o->gradient_changed = 1;
265 evas_object_change(obj);
269 * Sets alpha data for the given evas gradient object.
271 * If alpha data is so set, any existing gradient stops will be cleared,
272 * The data is not copied, so if it was allocated, do not free it while it's set.
274 * @param obj The given evas gradient object.
275 * @param data The alpha data to be set, in a8 format.
276 * @param len The length of the data pointer - multiple of the pixel size.
279 evas_object_gradient_alpha_data_set(Evas_Object *obj, void *data, int len)
281 Evas_Object_Gradient *o;
283 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
286 o = (Evas_Object_Gradient *)(obj->object_data);
287 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
292 #ifdef EVAS_FRAME_QUEUING
293 evas_common_pipe_op_grad_flush(o->engine_data);
295 obj->layer->evas->engine.func->gradient_alpha_data_set(obj->layer->evas->engine.data.output,
299 o->gradient_changed = 1;
301 evas_object_change(obj);
305 * Sets the rectangle on the gradient object that the gradient will be
308 * Note that the gradient may be tiled around this one rectangle,
309 * according to its spread value - restrict, repeat, or reflect. To have
310 * only one 'cycle' of the gradient drawn, the spread value must be set
311 * to restrict, or @p x and @p y must be 0 and @p w and @p h need to be
312 * the width and height of the gradient object respectively.
314 * The default values for the fill parameters is @p x = 0, @p y = 0,
315 * @p w = 32 and @p h = 32.
317 * @param obj The given evas gradient object.
318 * @param x The X coordinate for the top left corner of the rect.
319 * @param y The Y coordinate for the top left corner of the rect.
320 * @param w The width of the rect.
321 * @param h The height of the rect.
324 evas_object_gradient_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
326 Evas_Object_Gradient *o;
330 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
333 o = (Evas_Object_Gradient *)(obj->object_data);
334 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
337 if ((o->cur.fill.x == x) &&
338 (o->cur.fill.y == y) &&
339 (o->cur.fill.w == w) &&
340 (o->cur.fill.h == h)) return;
345 o->gradient_changed = 1;
347 evas_object_change(obj);
351 * Retrieves the dimensions of the rectangle on the gradient object that
352 * the gradient will use as its fill rect.
354 * See @ref evas_object_gradient_fill_set for more details.
356 * @param obj The given evas gradient object.
357 * @param x Pointer to an Evas_Coord to store the X coordinate in.
358 * @param y Pointer to an Evas_Coord to store the Y coordinate in.
359 * @param w Pointer to an Evas_Coord to store the width in.
360 * @param h Pointer to an Evas_Coord to store the height in.
363 evas_object_gradient_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
365 Evas_Object_Gradient *o;
367 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
374 o = (Evas_Object_Gradient *)(obj->object_data);
375 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
382 if (x) *x = o->cur.fill.x;
383 if (y) *y = o->cur.fill.y;
384 if (w) *w = o->cur.fill.w;
385 if (h) *h = o->cur.fill.h;
390 * Sets the angle at which the given evas gradient object's fill sits clockwise
392 * @param obj The given evas gradient object.
393 * @param angle Angle in degrees. Can be negative.
396 evas_object_gradient_fill_angle_set(Evas_Object *obj, Evas_Angle angle)
398 Evas_Object_Gradient *o;
400 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
403 o = (Evas_Object_Gradient *)(obj->object_data);
404 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
407 if (angle == o->cur.fill.angle) return;
408 o->cur.fill.angle = angle;
410 evas_object_change(obj);
414 * Retrieves the angle at which the given evas gradient object's fill sits
415 * clockwise from the vertical.
416 * @param obj The given evas gradient object.
417 * @return The current angle if successful. @c 0.0 otherwise.
420 evas_object_gradient_fill_angle_get(const Evas_Object *obj)
422 Evas_Object_Gradient *o;
424 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
427 o = (Evas_Object_Gradient *)(obj->object_data);
428 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
431 return o->cur.fill.angle;
435 * Sets the tiling mode for the given evas gradient object's fill.
436 * @param obj The given evas gradient object.
437 * @param spread One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
438 * EVAS_TEXTURE_RESTRICT, EVAS_TEXTURE_RESTRICT_REFLECT, EVAS_TEXTURE_RESTRICT_REPEAT,
439 * or EVAS_TEXTURE_PAD.
442 evas_object_gradient_fill_spread_set(Evas_Object *obj, int spread)
444 Evas_Object_Gradient *o;
446 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
449 o = (Evas_Object_Gradient *)(obj->object_data);
450 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
453 if (spread == o->cur.fill.spread) return;
454 o->cur.fill.spread = spread;
456 evas_object_change(obj);
460 * Retrieves the spread (tiling mode) for the given gradient object's fill.
461 * @param obj The given evas gradient object.
462 * @return The current spread mode of the gradient object.
465 evas_object_gradient_fill_spread_get(const Evas_Object *obj)
467 Evas_Object_Gradient *o;
469 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
470 return EVAS_TEXTURE_REFLECT;
472 o = (Evas_Object_Gradient *)(obj->object_data);
473 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
474 return EVAS_TEXTURE_REFLECT;
476 return o->cur.fill.spread;
480 * Sets the angle at which the given evas gradient sits,
481 * relative to whatever intrinsic orientation of the grad type.
482 * Used mostly by 'linear' kinds of gradients.
483 * @param obj The given evas gradient object.
484 * @param angle Angle in degrees. Can be negative.
487 evas_object_gradient_angle_set(Evas_Object *obj, Evas_Angle angle)
489 Evas_Object_Gradient *o;
491 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
494 o = (Evas_Object_Gradient *)(obj->object_data);
495 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
498 if (angle == o->cur.map.angle) return;
499 o->cur.map.angle = angle;
500 o->gradient_changed = 1;
502 evas_object_change(obj);
506 * Retrieves the angle at which the given evas gradient object sits
507 * rel to its intrinsic orientation.
508 * @param obj The given evas gradient object.
509 * @return The current angle if successful. @c 0.0 otherwise.
512 evas_object_gradient_angle_get(const Evas_Object *obj)
514 Evas_Object_Gradient *o;
516 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
519 o = (Evas_Object_Gradient *)(obj->object_data);
520 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
523 return o->cur.map.angle;
527 * Sets the offset of the given evas gradient object's spectrum.
528 * @param obj The given evas gradient object.
529 * @param offset Values can be negative.
532 evas_object_gradient_offset_set(Evas_Object *obj, float offset)
534 Evas_Object_Gradient *o;
536 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
539 o = (Evas_Object_Gradient *)(obj->object_data);
540 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
543 if (offset == o->cur.map.offset) return;
544 o->cur.map.offset = offset;
546 evas_object_change(obj);
550 * Retrieves the spectrum's offset
551 * @param obj The given evas gradient object.
552 * @return The current gradient offset if successful. @c 0.0 otherwise.
555 evas_object_gradient_offset_get(const Evas_Object *obj)
557 Evas_Object_Gradient *o;
559 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
562 o = (Evas_Object_Gradient *)(obj->object_data);
563 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
566 return o->cur.map.offset;
570 * Sets the direction of the given evas gradient object's spectrum.
571 * @param obj The given evas gradient object.
572 * @param direction Values are either 1 (the default) or -1.
575 evas_object_gradient_direction_set(Evas_Object *obj, int direction)
577 Evas_Object_Gradient *o;
579 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
582 o = (Evas_Object_Gradient *)(obj->object_data);
583 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
586 if (direction == o->cur.map.direction) return;
587 o->cur.map.direction = direction;
589 o->gradient_changed = 1;
590 evas_object_change(obj);
594 * Retrieves the evas gradient object's spectrum direction
595 * @param obj The given evas gradient object.
596 * @return The current gradient direction if successful. @c 1 otherwise.
599 evas_object_gradient_direction_get(const Evas_Object *obj)
601 Evas_Object_Gradient *o;
603 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
606 o = (Evas_Object_Gradient *)(obj->object_data);
607 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
610 return o->cur.map.direction;
614 * Sets the geometric type displayed by the given gradient object.
615 * @param obj The given gradient object.
616 * @param name Name of the geometric type that the gradient is to be drawn as.
617 * @param params List of allowable params that the given gradient type allows.
621 evas_object_gradient_type_set(Evas_Object *obj, const char *name, const char *params)
623 Evas_Object_Gradient *o;
625 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
628 o = (Evas_Object_Gradient *)(obj->object_data);
629 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
637 if (params && !*params)
639 if ((o->cur.type.name) && (!strcmp(o->cur.type.name, name)))
641 if ((!o->cur.type.params) && (!params))
643 if ((o->cur.type.params) && (params) && (!strcmp(o->cur.type.params, params)))
645 if (o->cur.type.params)
647 if (o->prev.type.params == o->cur.type.params)
648 o->prev.type.params = strdup(o->cur.type.params);
649 free(o->cur.type.params);
650 o->cur.type.params = NULL;
653 o->cur.type.params = strdup(params);
655 o->gradient_changed = 1;
657 evas_object_change(obj);
661 if (o->cur.type.name)
663 if (o->prev.type.name == o->cur.type.name)
664 o->prev.type.name = strdup(o->cur.type.name);
665 free(o->cur.type.name);
666 o->cur.type.name = NULL;
668 o->cur.type.name = strdup(name);
670 if (o->cur.type.params)
672 if (o->prev.type.params == o->cur.type.params)
673 o->prev.type.params = strdup(o->cur.type.params);
674 free(o->cur.type.params);
675 o->cur.type.params = NULL;
678 o->cur.type.params = strdup(params);
680 o->gradient_changed = 1;
682 evas_object_change(obj);
686 * Retrieves the type name and params of the given gradient object.
687 * @param obj The given gradient object.
688 * @param name Pointer to a character pointer to store the pointer to the type
690 * @param params Pointer to a character pointer to store the pointer to the type
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;
720 these two functions don't really belong here as they can apply to other
721 objs as well, but for now..
725 * Convert a given color from HSV to RGB format.
727 * @param h The Hue component of the color.
728 * @param s The Saturation component of the color.
729 * @param v The Value component of the color.
730 * @param r The Red component of the color.
731 * @param g The Green component of the color.
732 * @param b The Blue component of the color.
734 * This function converts a given color in HSV color format to RGB
737 * @ingroup Evas_Utils
740 evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
742 evas_common_convert_color_hsv_to_rgb(h, s, v, r, g, b);
746 * Convert a given color from RGB to HSV format.
748 * @param r The Red component of the color.
749 * @param g The Green component of the color.
750 * @param b The Blue component of the color.
751 * @param h The Hue component of the color.
752 * @param s The Saturation component of the color.
753 * @param v The Value component of the color.
755 * This function converts a given color in RGB color format to HSV
758 * @ingroup Evas_Utils
761 evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
763 evas_common_convert_color_rgb_to_hsv(r, g, b, h, s, v);
767 * Pre-multiplies a rgb triplet by an alpha factor.
769 * @param a The alpha factor.
770 * @param r The Red component of the color.
771 * @param g The Green component of the color.
772 * @param b The Blue component of the color.
774 * This function pre-multiplies a given rbg triplet by an alpha
775 * factor. Alpha factor is used to define transparency.
777 * @ingroup Evas_Utils
780 evas_color_argb_premul(int a, int *r, int *g, int *b)
782 evas_common_convert_color_argb_premul(a, r, g, b);
786 * Undo pre-multiplication of a rgb triplet by an alpha factor.
788 * @param a The alpha factor.
789 * @param r The Red component of the color.
790 * @param g The Green component of the color.
791 * @param b The Blue component of the color.
793 * This function undoes pre-multiplication a given rbg triplet by an
794 * alpha factor. Alpha factor is used to define transparency.
796 * @see evas_color_argb_premul().
798 * @ingroup Evas_Utils
801 evas_color_argb_unpremul(int a, int *r, int *g, int *b)
803 evas_common_convert_color_argb_unpremul(a, r, g, b);
807 * Pre-multiplies data by an alpha factor.
809 * @param data The data value.
810 * @param len The lenght value.
812 * This function pre-multiplies a given data by an alpha
813 * factor. Alpha factor is used to define transparency.
815 * @ingroup Evas_Utils
818 evas_data_argb_premul(unsigned int *data, unsigned int len)
820 if (!data || (len < 1)) return;
821 evas_common_convert_argb_premul(data, len);
825 * Undo pre-multiplication data by an alpha factor.
827 * @param data The data value.
828 * @param len The lenght value.
830 * This function undoes pre-multiplication of a given data by an alpha
831 * factor. Alpha factor is used to define transparency.
833 * @ingroup Evas_Utils
836 evas_data_argb_unpremul(unsigned int *data, unsigned int len)
838 if (!data || (len < 1)) return;
839 evas_common_convert_argb_unpremul(data, len);
844 /* all nice and private */
846 evas_object_gradient_init(Evas_Object *obj)
848 /* alloc grad ob, setup methods and default values */
849 obj->object_data = evas_object_gradient_new();
850 /* set up default settings for this kind of object */
851 obj->cur.color.r = 255;
852 obj->cur.color.g = 255;
853 obj->cur.color.b = 255;
854 obj->cur.color.a = 255;
855 obj->cur.geometry.x = 0;
856 obj->cur.geometry.y = 0;
857 obj->cur.geometry.w = 0;
858 obj->cur.geometry.h = 0;
860 obj->cur.anti_alias = 1;
861 obj->cur.interpolation_color_space = EVAS_COLOR_SPACE_ARGB;
862 obj->cur.render_op = EVAS_RENDER_BLEND;
863 /* set up object-specific settings */
864 obj->prev = obj->cur;
865 /* set up methods (compulsory) */
866 obj->func = &object_func;
871 evas_object_gradient_new(void)
873 Evas_Object_Gradient *o;
875 /* alloc obj private data */
876 o = calloc(1, sizeof(Evas_Object_Gradient));
878 o->magic = MAGIC_OBJ_GRADIENT;
879 o->cur.map.angle = 0;
880 o->cur.map.offset = 0.0;
881 o->cur.map.direction = 1;
886 o->cur.fill.angle = 0;
887 o->cur.fill.spread = EVAS_TEXTURE_REFLECT;
888 o->cur.type.name = strdup("linear");
889 o->cur.type.params = NULL;
890 o->cur.gradient_opaque = 0;
893 o->gradient_changed = 1;
899 evas_object_gradient_free(Evas_Object *obj)
901 Evas_Object_Gradient *o;
903 /* frees private object data. very simple here */
904 o = (Evas_Object_Gradient *)(obj->object_data);
905 MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT);
909 if (o->prev.type.name && (o->prev.type.name != o->cur.type.name))
910 free(o->prev.type.name);
911 if (o->prev.type.params && (o->prev.type.params != o->cur.type.params))
912 free(o->prev.type.params);
913 if (o->cur.type.name)
914 free(o->cur.type.name);
915 if (o->cur.type.params)
916 free(o->cur.type.params);
918 obj->layer->evas->engine.func->gradient_free(obj->layer->evas->engine.data.output,
921 obj->object_data = NULL;
926 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,
929 Evas_Coord x, y, w, h;
931 x = ((fx * obj->layer->evas->output.w) /
932 (Evas_Coord)obj->layer->evas->viewport.w);
933 w = ((fw * obj->layer->evas->output.w) /
934 (Evas_Coord)obj->layer->evas->viewport.w);
935 y = ((fy * obj->layer->evas->output.h) /
936 (Evas_Coord)obj->layer->evas->viewport.h);
937 h = ((fh * obj->layer->evas->output.h) /
938 (Evas_Coord)obj->layer->evas->viewport.h);
943 *fx_ret = x; *fw_ret = w;
944 *fy_ret = y; *fh_ret = h;
950 evas_object_gradient_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
952 Evas_Object_Gradient *o;
954 /* render object to surface with context, and offxet by x,y */
955 o = (Evas_Object_Gradient *)(obj->object_data);
956 obj->layer->evas->engine.func->context_multiplier_unset(output, context);
957 obj->layer->evas->engine.func->context_anti_alias_set(output, context, obj->cur.anti_alias);
958 obj->layer->evas->engine.func->context_render_op_set(output, context, obj->cur.render_op);
961 obj->layer->evas->engine.func->gradient_draw(output, context, surface,
963 obj->cur.geometry.x + x,
964 obj->cur.geometry.y + y,
966 obj->cur.geometry.h);
967 //// obj->cur.cache.geometry.x + x,
968 //// obj->cur.cache.geometry.y + y,
969 //// obj->cur.cache.geometry.w,
970 //// obj->cur.cache.geometry.h);
975 evas_object_gradient_render_pre(Evas_Object *obj)
977 Evas_Object_Gradient *o;
980 /* dont pre-render the obj twice! */
981 if (obj->pre_render_done) return;
982 obj->pre_render_done = 1;
983 /* pre-render phase. this does anything an object needs to do just before */
984 /* rendering. this could mean loading the image data, retrieving it from */
985 /* elsewhere, decoding video etc. */
986 /* then when this is done the object needs to figure if it changed and */
987 /* if so what and where and add the appropriate redraw rectangles */
988 o = (Evas_Object_Gradient *)(obj->object_data);
989 /* if someone is clipping this obj - go calculate the clipper */
990 if (obj->cur.clipper)
992 if (obj->cur.cache.clip.dirty)
993 evas_object_clip_recalc(obj->cur.clipper);
994 obj->cur.clipper->func->render_pre(obj->cur.clipper);
996 /* if it changed color */
997 if ((obj->cur.color.r != obj->prev.color.r) ||
998 (obj->cur.color.g != obj->prev.color.g) ||
999 (obj->cur.color.b != obj->prev.color.b) ||
1000 (obj->cur.color.a != obj->prev.color.a))
1001 { o->gradient_changed = 1; o->changed = 1; }
1002 if ((!o->gradient_changed) && ((obj->cur.cache.clip.r != obj->prev.cache.clip.r) ||
1003 (obj->cur.cache.clip.g != obj->prev.cache.clip.g) ||
1004 (obj->cur.cache.clip.b != obj->prev.cache.clip.b) ||
1005 (obj->cur.cache.clip.a != obj->prev.cache.clip.a)))
1006 { o->gradient_changed = 1; o->changed = 1; }
1007 if (!o->gradient_changed && (obj->cur.interpolation_color_space != obj->prev.interpolation_color_space))
1008 { o->gradient_changed = 1; o->changed = 1; }
1009 if (!o->changed && (obj->cur.render_op != obj->prev.render_op))
1011 if (!o->changed && (obj->cur.anti_alias != obj->prev.anti_alias))
1013 if (o->changed && o->engine_data)
1015 Evas_Coord fx, fy, fw, fh;
1017 evas_object_grad_get_fill_coords(obj, o->cur.fill.x, o->cur.fill.y,
1018 o->cur.fill.w, o->cur.fill.h,
1019 &fx, &fy, &fw, &fh);
1020 obj->layer->evas->engine.func->gradient_fill_set(obj->layer->evas->engine.data.output, o->engine_data,
1022 obj->layer->evas->engine.func->gradient_fill_angle_set(obj->layer->evas->engine.data.output, o->engine_data,
1024 obj->layer->evas->engine.func->gradient_fill_spread_set(obj->layer->evas->engine.data.output, o->engine_data,
1025 o->cur.fill.spread);
1026 obj->layer->evas->engine.func->gradient_angle_set(obj->layer->evas->engine.data.output, o->engine_data,
1028 obj->layer->evas->engine.func->gradient_direction_set(obj->layer->evas->engine.data.output, o->engine_data,
1029 o->cur.map.direction);
1030 obj->layer->evas->engine.func->gradient_offset_set(obj->layer->evas->engine.data.output, o->engine_data,
1032 if (o->type_changed)
1033 obj->layer->evas->engine.func->gradient_type_set(obj->layer->evas->engine.data.output, o->engine_data,
1034 o->cur.type.name, o->cur.type.params);
1036 obj->layer->evas->engine.func->context_anti_alias_set(obj->layer->evas->engine.data.output,
1037 obj->layer->evas->engine.data.context,
1038 obj->cur.anti_alias);
1039 obj->layer->evas->engine.func->context_render_op_set(obj->layer->evas->engine.data.output,
1040 obj->layer->evas->engine.data.context, obj->cur.render_op);
1041 obj->layer->evas->engine.func->context_multiplier_set(obj->layer->evas->engine.data.output,
1042 obj->layer->evas->engine.data.context,
1043 obj->cur.cache.clip.r, obj->cur.cache.clip.g,
1044 obj->cur.cache.clip.b, obj->cur.cache.clip.a);
1045 obj->layer->evas->engine.func->context_color_interpolation_set(obj->layer->evas->engine.data.output,
1046 obj->layer->evas->engine.data.context,
1047 obj->cur.interpolation_color_space);
1048 if (o->gradient_changed)
1049 obj->layer->evas->engine.func->gradient_render_pre(obj->layer->evas->engine.data.output,
1050 obj->layer->evas->engine.data.context,
1052 o->cur.gradient_opaque = obj->layer->evas->engine.func->gradient_is_opaque(obj->layer->evas->engine.data.output,
1053 obj->layer->evas->engine.data.context,
1055 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
1056 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
1058 if (obj->cur.cache.clip.a != 255)
1059 o->cur.gradient_opaque = 0;
1061 /* now figure what changed and add draw rects */
1062 /* if it just became visible or invisible */
1063 is_v = evas_object_is_visible(obj);
1064 was_v = evas_object_was_visible(obj);
1067 evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
1070 if (obj->cur.map != obj->prev.map)
1072 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
1075 /* its not visible - we accounted for it appearing or not so just abort */
1076 if (!is_v) goto done;
1077 /* clipper changed this is in addition to anything else for obj */
1078 evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj);
1079 /* gradient changed */
1080 if (o->changed || obj->restack)
1082 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
1085 /* if it changed geometry */
1086 if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
1087 (obj->cur.geometry.y != obj->prev.geometry.y) ||
1088 (obj->cur.geometry.w != obj->prev.geometry.w) ||
1089 (obj->cur.geometry.h != obj->prev.geometry.h))
1091 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
1094 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
1095 /* area so if there were updates for it they get wiped. don't do it if we */
1096 /* arent fully opaque and we are visible */
1098 if (evas_object_is_visible(obj) &&
1099 evas_object_is_opaque(obj))
1100 obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output,
1101 obj->cur.cache.clip.x,
1102 obj->cur.cache.clip.y,
1103 obj->cur.cache.clip.w,
1104 obj->cur.cache.clip.h);
1107 evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v);
1111 evas_object_gradient_render_post(Evas_Object *obj)
1113 Evas_Object_Gradient *o;
1115 /* this moves the current data to the previous state parts of the object */
1116 /* in whatever way is safest for the object. also if we don't need object */
1117 /* data anymore we can free it if the object deems this is a good idea */
1118 o = (Evas_Object_Gradient *)(obj->object_data);
1119 /* remove those pesky changes */
1120 evas_object_clip_changes_clean(obj);
1121 /* move cur to prev safely for object data */
1122 obj->prev = obj->cur;
1123 if (o->prev.type.name && (o->prev.type.name != o->cur.type.name))
1124 free(o->prev.type.name);
1125 if (o->prev.type.params && (o->prev.type.params != o->cur.type.params))
1126 free(o->prev.type.params);
1129 o->gradient_changed = 0;
1130 o->type_changed = 0;
1133 static unsigned int evas_object_gradient_id_get(Evas_Object *obj)
1135 Evas_Object_Gradient *o;
1137 o = (Evas_Object_Gradient *)(obj->object_data);
1139 return MAGIC_OBJ_GRADIENT;
1142 static unsigned int evas_object_gradient_visual_id_get(Evas_Object *obj)
1144 Evas_Object_Gradient *o;
1146 o = (Evas_Object_Gradient *)(obj->object_data);
1148 return MAGIC_OBJ_GRADIENT;
1151 static void *evas_object_gradient_engine_data_get(Evas_Object *obj)
1153 Evas_Object_Gradient *o;
1155 o = (Evas_Object_Gradient *)(obj->object_data);
1156 if (!o) return NULL;
1157 return o->engine_data;
1161 evas_object_gradient_is_opaque(Evas_Object *obj)
1163 Evas_Object_Gradient *o;
1165 /* this returns 1 if the internal object data implies that the object is */
1166 /* currently fully opaque over the entire region it occupies */
1167 o = (Evas_Object_Gradient *)(obj->object_data);
1168 if (!o->engine_data) return 0;
1169 if ((obj->cur.map) && (obj->cur.usemap)) return 0;
1170 return o->cur.gradient_opaque;
1174 evas_object_gradient_was_opaque(Evas_Object *obj)
1176 Evas_Object_Gradient *o;
1178 /* this returns 1 if the internal object data implies that the object was */
1179 /* currently fully opaque over the entire region it occupies */
1180 o = (Evas_Object_Gradient *)(obj->object_data);
1181 if (!o->engine_data) return 0;
1182 return o->prev.gradient_opaque;