#### End of Ecore_Buffer
+
+#### src/examples/ephysics/Makefile
AC_CONFIG_FILES([
Makefile
data/Makefile
--- /dev/null
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: ector
+Description: Enlightenned retained mode drawing library
+Requires.private: efl >= 1.13.0 eo >= 1.13.0 eina >= 1.13.0
+Version: 1.13.0
+Libs: -L${libdir} -lector
+Libs.private: -lm
+Cflags: -I${includedir}/efl-1 -I${includedir}/ector-1
lib/ector/software/ector_software_surface.eo \
lib/ector/software/ector_renderer_software_base.eo \
lib/ector/software/ector_renderer_software_shape.eo \
- lib/ector/software/ector_renderer_software_gradient_linear.eo \
- lib/ector/software/ector_renderer_software_gradient_radial.eo
+ lib/ector/software/ector_renderer_software_gradient_radial.eo \
+ lib/ector/software/ector_renderer_software_gradient_linear.eo
ector_eolian_c = $(ector_eolian_files:%.eo=%.eo.c)
ector_eolian_h = $(ector_eolian_files:%.eo=%.eo.h)
installed_ectormainheadersdir = $(includedir)/ector-@VMAJ@
dist_installed_ectormainheaders_DATA = \
lib/ector/Ector.h \
+lib/ector/ector_util.h \
lib/ector/cairo/Ector_Cairo.h \
lib/ector/software/Ector_Software.h
-# And the cairo header
+# And the generic implementation
lib_ector_libector_la_SOURCES = \
lib/ector/ector_main.c \
lib/ector/cairo/ector_renderer_cairo_gradient_linear.c \
lib/ector/cairo/ector_renderer_cairo_gradient_radial.c \
lib/ector/cairo/ector_renderer_cairo_shape.c \
+lib/ector/cairo/ector_renderer_cairo_base.c \
lib/ector/cairo/ector_cairo_surface.c
# And now the software backend
lib/ector/software/ector_renderer_software_gradient_linear.c \
lib/ector/software/ector_renderer_software_gradient_radial.c \
lib/ector/software/ector_renderer_software_shape.c \
-lib/ector/software/ector_software_surface.c \
lib/ector/software/ector_software_gradient.c \
+lib/ector/software/ector_software_rasterizer.c \
+lib/ector/software/ector_software_surface.c \
lib/ector/software/sw_ft_math.c \
lib/ector/software/sw_ft_raster.c \
lib/ector/software/sw_ft_stroker.c \
-lib/ector/software/ector_software_rasterizer.c
+lib/ector/software/ector_drawhelper.c \
+lib/ector/software/ector_drawhelper_sse2.c
lib_ector_libector_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
@ECTOR_CFLAGS@ \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/ector\" \
-@VALGRIND_CFLAGS@
+@VALGRIND_CFLAGS@ \
+@SSE3_CFLAGS@
lib_ector_libector_la_LIBADD = @ECTOR_LIBS@ @DL_LIBS@
lib_ector_libector_la_DEPENDENCIES = @ECTOR_INTERNAL_LIBS@ @DL_INTERNAL_LIBS@
EXTRA_DIST += \
src/lib/ector/ector_private.h \
-src/lib/ector/cairo/ector_cairo_private,h \
-src/lib/ector/software/sw_ft_types.h \
+src/lib/ector/cairo/ector_cairo_private.h \
+src/lib/ector/software/ector_drawhelper_private.h \
+src/lib/ector/software/ector_software_private.h \
src/lib/ector/software/sw_ft_math.h \
src/lib/ector/software/sw_ft_raster.h \
src/lib/ector/software/sw_ft_stroker.h \
-src/lib/ector/software/ector_software_private.h
\ No newline at end of file
+src/lib/ector/software/sw_ft_types.h
lib/efl/interfaces/efl_text.eo \
lib/efl/interfaces/efl_text_properties.eo \
lib/efl/interfaces/efl_gfx_base.eo \
+ lib/efl/interfaces/efl_gfx_stack.eo \
+ lib/efl/interfaces/efl_gfx_fill.eo \
+ lib/efl/interfaces/efl_gfx_view.eo \
lib/efl/interfaces/efl_gfx_shape.eo \
- lib/efl/interfaces/efl_gfx_gradient.eo \
+ lib/efl/interfaces/efl_gfx_gradient_base.eo \
lib/efl/interfaces/efl_gfx_gradient_linear.eo \
lib/efl/interfaces/efl_gfx_gradient_radial.eo
EXTRA_DIST += \
lib/efl/Efl_Config.h \
lib/efl/Efl.h \
- lib/efl/interfaces/efl_gfx_utils.h \
$(efl_eolian_files)
efleolianfilesdir = $(datadir)/eolian/include/efl-@VMAJ@
lib_efl_libefl_la_SOURCES = \
lib/efl/interfaces/efl_interfaces_main.c \
-lib/efl/interfaces/efl_gfx_utils.c
+lib/efl/interfaces/efl_gfx_shape.c
lib_efl_libefl_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_srcdir)/src/lib/efl @EFL_CFLAGS@
lib_efl_libefl_la_LIBADD = @EFL_LIBS@
installed_eflinterfacesdir = $(includedir)/efl-@VMAJ@/interfaces
nodist_installed_eflinterfaces_DATA = \
-$(efl_eolian_files_h) \
-lib/efl/interfaces/efl_gfx_utils.h
+$(efl_eolian_files_h)
if HAVE_ELUA
lib/evas/canvas/evas_3d_scene.eo\
lib/evas/canvas/evas_3d_object.eo \
lib/evas/canvas/evas_vg.eo \
- lib/evas/canvas/evas_vg_node.eo \
- lib/evas/canvas/evas_vg_container.eo \
- lib/evas/canvas/evas_vg_shape.eo \
- lib/evas/canvas/evas_vg_root_node.eo \
- lib/evas/canvas/evas_vg_gradient.eo \
- lib/evas/canvas/evas_vg_gradient_radial.eo \
- lib/evas/canvas/evas_vg_gradient_linear.eo \
- lib/evas/canvas/evas_vg_image.eo
+ lib/evas/canvas/efl_vg_base.eo \
+ lib/evas/canvas/efl_vg_container.eo \
+ lib/evas/canvas/efl_vg_shape.eo \
+ lib/evas/canvas/efl_vg_root_node.eo \
+ lib/evas/canvas/efl_vg_gradient.eo \
+ lib/evas/canvas/efl_vg_gradient_radial.eo \
+ lib/evas/canvas/efl_vg_gradient_linear.eo \
+ lib/evas/canvas/efl_vg_image.eo
evas_eolian_c = $(evas_eolian_files:%.eo=%.eo.c)
evas_eolian_h = $(evas_eolian_files:%.eo=%.eo.h) \
lib/evas/filters/blur/blur_box_rgba_sse3.c \
lib/evas/filters/blur/blur_box_rgba_neon.c
+### Vector surface helper
+
+EXTRA_DIST += \
+modules/evas/engines/software_generic/ector_cairo_software_surface.eo \
+modules/evas/engines/gl_generic/ector_cairo_software_surface.eo
### Engines
if EVAS_STATIC_BUILD_SOFTWARE_GENERIC
-evas_eolian_files += modules/evas/engines/software_generic/ector_cairo_software_surface.eo
+BUILT_SOURCES += \
+modules/evas/engines/software_generic/ector_cairo_software_surface.eo.c \
+modules/evas/engines/software_generic/ector_cairo_software_surface.eo.h
lib_evas_libevas_la_SOURCES += modules/evas/engines/software_generic/evas_engine.c modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h
lib_evas_libevas_la_LIBADD +=
else
endif
if BUILD_ENGINE_GL_COMMON
+BUILT_SOURCES += \
+modules/evas/engines/gl_generic/ector_cairo_software_surface.eo.c \
+modules/evas/engines/gl_generic/ector_cairo_software_surface.eo.h
+
GL_COMMON_SOURCES = \
modules/evas/engines/gl_common/evas_gl_private.h \
modules/evas/engines/gl_common/evas_gl_common.h \
#include "ector_surface.h"
#include "ector_renderer.h"
+#include "ector_util.h"
#endif
struct _Ector_Cairo_Surface_Data
{
cairo_t *cairo;
+ struct {
+ double x, y;
+ } current;
+
+ Eina_Bool internal : 1;
};
#define CHECK_CAIRO(Parent) (!(Parent && Parent->cairo))
-#define USE(Obj, Sym, Error) \
- if (!Sym) _ector_cairo_symbol_get(Obj, #Sym); \
+#define USE(Obj, Sym, Error) \
+ if (!Sym) Sym = _ector_cairo_symbol_get(Obj, #Sym); \
if (!Sym) return Error;
static inline void *
#undef LOAD
}
+ if (!_cairo_so)
+ {
+ ERR("Couldn't find cairo library. Please make sure that your system can locate it.");
+ return NULL;
+ }
+
return eina_module_symbol_get(_cairo_so, name);
}
+#undef USE
+#define USE(Obj, Sym, Error) \
+ if (!Sym) Sym = _ector_cairo_surface_symbol_get(Obj, NULL, #Sym); \
+ if (!Sym) return Error;
static Ector_Renderer *
_ector_cairo_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
Ector_Cairo_Surface_Data *pd EINA_UNUSED,
const Eo_Class *type)
{
- if (eo_isa(type, ECTOR_RENDERER_CAIRO_SHAPE_CLASS))
+ if (type == ECTOR_RENDERER_GENERIC_SHAPE_MIXIN)
return eo_add(ECTOR_RENDERER_CAIRO_SHAPE_CLASS, obj);
- else if (eo_isa(type, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS))
+ else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN)
return eo_add(ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS, obj);
- else if (eo_isa(type, ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS))
+ else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN)
return eo_add(ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS, obj);
+ ERR("Couldn't find class for type: %s\n", eo_class_name_get(type));
return NULL;
}
+typedef struct _cairo_surface_t cairo_surface_t;
+
+static void (*cairo_translate)(cairo_t *cr, double tx, double ty) = NULL;
+static void (*cairo_destroy)(cairo_t *cr) = NULL;
+static cairo_surface_t *(*cairo_image_surface_create)(int format,
+ int width,
+ int height) = NULL;
+static cairo_t *(*cairo_create)(cairo_surface_t *target) = NULL;
+
+static cairo_surface_t *internal = NULL;
+
static void
-_ector_cairo_surface_context_set(Eo *obj EINA_UNUSED,
+_ector_cairo_surface_context_set(Eo *obj,
Ector_Cairo_Surface_Data *pd,
cairo_t *ctx)
{
+ if (pd->internal)
+ {
+ USE(obj, cairo_destroy, );
+
+ if (pd->cairo) cairo_destroy(pd->cairo);
+ pd->internal = EINA_FALSE;
+ }
+ if (!ctx)
+ {
+ USE(obj, cairo_image_surface_create, );
+ USE(obj, cairo_create, );
+
+ if (!internal) internal = cairo_image_surface_create(0, 1, 1);
+ ctx = cairo_create(internal);
+ }
+ pd->current.x = pd->current.y = 0;
pd->cairo = ctx;
}
}
static void
-_ector_cairo_surface_eo_base_constructor(Eo *obj EINA_UNUSED,
- Ector_Cairo_Surface_Data *pd EINA_UNUSED)
+_ector_cairo_surface_ector_generic_surface_reference_point_set(Eo *obj EINA_UNUSED,
+ Ector_Cairo_Surface_Data *pd,
+ int x, int y)
{
+ if (pd->cairo)
+ {
+ USE(obj, cairo_translate, );
+ cairo_translate(pd->cairo, x, y);
+ }
+}
+
+static void
+_ector_cairo_surface_eo_base_constructor(Eo *obj,
+ Ector_Cairo_Surface_Data *pd)
+{
+ eo_do_super(obj, ECTOR_CAIRO_SURFACE_CLASS, eo_constructor());
_cairo_count++;
+
+ _ector_cairo_surface_context_set(obj, pd, NULL);
}
static void
_ector_cairo_surface_eo_base_destructor(Eo *obj EINA_UNUSED,
Ector_Cairo_Surface_Data *pd EINA_UNUSED)
{
+ eo_do_super(obj, ECTOR_CAIRO_SURFACE_CLASS, eo_destructor());
+
if (--_cairo_count) return ;
if (_cairo_so) eina_module_free(_cairo_so);
_cairo_so = NULL;
}
-
#include "ector_cairo_surface.eo.c"
-#include "ector_renderer_cairo_base.eo.c"
}
implements {
Ector.Generic.Surface.renderer_factory_new;
+ Ector.Generic.Surface.reference_point.set;
Eo.Base.destructor;
Eo.Base.constructor;
}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <math.h>
+#include <float.h>
+
+#include <Eina.h>
+#include <Ector.h>
+#include <cairo/Ector_Cairo.h>
+
+#include "ector_private.h"
+#include "ector_cairo_private.h"
+
+typedef struct {
+ double xx; double yx;
+ double xy; double yy;
+ double x0; double y0;
+} cairo_matrix_t;
+
+typedef enum {
+ CAIRO_OPERATOR_CLEAR,
+
+ CAIRO_OPERATOR_SOURCE,
+ CAIRO_OPERATOR_OVER,
+ CAIRO_OPERATOR_IN,
+ CAIRO_OPERATOR_OUT,
+ CAIRO_OPERATOR_ATOP,
+
+ CAIRO_OPERATOR_DEST,
+ CAIRO_OPERATOR_DEST_OVER,
+ CAIRO_OPERATOR_DEST_IN,
+ CAIRO_OPERATOR_DEST_OUT,
+ CAIRO_OPERATOR_DEST_ATOP,
+
+ CAIRO_OPERATOR_XOR,
+ CAIRO_OPERATOR_ADD,
+ CAIRO_OPERATOR_SATURATE,
+
+ CAIRO_OPERATOR_MULTIPLY,
+ CAIRO_OPERATOR_SCREEN,
+ CAIRO_OPERATOR_OVERLAY,
+ CAIRO_OPERATOR_DARKEN,
+ CAIRO_OPERATOR_LIGHTEN,
+ CAIRO_OPERATOR_COLOR_DODGE,
+ CAIRO_OPERATOR_COLOR_BURN,
+ CAIRO_OPERATOR_HARD_LIGHT,
+ CAIRO_OPERATOR_SOFT_LIGHT,
+ CAIRO_OPERATOR_DIFFERENCE,
+ CAIRO_OPERATOR_EXCLUSION,
+ CAIRO_OPERATOR_HSL_HUE,
+ CAIRO_OPERATOR_HSL_SATURATION,
+ CAIRO_OPERATOR_HSL_COLOR,
+ CAIRO_OPERATOR_HSL_LUMINOSITY
+} cairo_operator_t;
+
+static void (*cairo_translate)(cairo_t *cr, double tx, double ty) = NULL;
+static void (*cairo_matrix_init)(cairo_matrix_t *matrix,
+ double xx, double yx,
+ double xy, double yy,
+ double x0, double y0) = NULL;
+static void (*cairo_transform)(cairo_t *cr, const cairo_matrix_t *matrix) = NULL;
+static void (*cairo_set_source_rgba)(cairo_t *cr,
+ double red, double green, double blue,
+ double alpha) = NULL;
+static void (*cairo_set_operator)(cairo_t *cr, cairo_operator_t op) = NULL;
+static void (*cairo_matrix_init_identity)(cairo_matrix_t *matrix) = NULL;
+
+typedef struct _Ector_Renderer_Cairo_Base_Data Ector_Renderer_Cairo_Base_Data;
+struct _Ector_Renderer_Cairo_Base_Data
+{
+ Ector_Cairo_Surface_Data *parent;
+ Ector_Renderer_Generic_Base_Data *generic;
+
+ cairo_matrix_t *m;
+};
+
+static cairo_matrix_t identity;
+
+// Cairo need unpremul color, so force unpremul here
+void
+_ector_renderer_cairo_base_ector_renderer_generic_base_color_set(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Cairo_Base_Data *pd,
+ int r, int g, int b, int a)
+{
+ ector_color_argb_unpremul(a, &r ,&g, &b);
+ pd->generic->color.r = r;
+ pd->generic->color.g = g;
+ pd->generic->color.b = b;
+ pd->generic->color.a = a;
+}
+
+void
+_ector_renderer_cairo_base_ector_renderer_generic_base_color_get(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Cairo_Base_Data *pd,
+ int *r, int *g, int *b, int *a)
+{
+ if (r) *r = pd->generic->color.r;
+ if (g) *g = pd->generic->color.g;
+ if (b) *b = pd->generic->color.b;
+ if (a) *a = pd->generic->color.a;
+
+ ector_color_argb_premul(pd->generic->color.a, r, g, b);
+}
+
+static Eina_Bool
+_ector_renderer_cairo_base_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Cairo_Base_Data *pd)
+{
+ if (!pd->parent)
+ {
+ Eo *parent;
+
+ eo_do(obj, parent = eo_parent_get());
+ if (!parent) return EINA_FALSE;
+ pd->parent = eo_data_xref(parent, ECTOR_CAIRO_SURFACE_CLASS, obj);
+ }
+ if (pd->generic->m)
+ {
+ USE(obj, cairo_matrix_init, EINA_FALSE);
+
+ if (!pd->m) pd->m = malloc(sizeof (cairo_matrix_t));
+ cairo_matrix_init(pd->m,
+ pd->generic->m->xx, pd->generic->m->yx,
+ pd->generic->m->xy, pd->generic->m->yy,
+ pd->generic->m->xz, pd->generic->m->yz);
+ }
+ else
+ {
+ free(pd->m);
+ pd->m = NULL;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ector_renderer_cairo_base_ector_renderer_generic_base_draw(Eo *obj,
+ Ector_Renderer_Cairo_Base_Data *pd,
+ Ector_Rop op,
+ Eina_Array *clips EINA_UNUSED,
+ unsigned int mul_col)
+{
+ double r, g, b, a;
+ cairo_operator_t cop;
+ double cx, cy;
+
+ USE(obj, cairo_translate, EINA_FALSE);
+ USE(obj, cairo_set_source_rgba, EINA_FALSE);
+ USE(obj, cairo_transform, EINA_FALSE);
+ USE(obj, cairo_set_operator, EINA_FALSE);
+
+ switch (op)
+ {
+ case ECTOR_ROP_BLEND:
+ cop = CAIRO_OPERATOR_OVER;
+ break;
+ case ECTOR_ROP_COPY:
+ default:
+ cop = CAIRO_OPERATOR_SOURCE;
+ break;
+ }
+
+ r = ((double)((pd->generic->color.r * R_VAL(&mul_col)) >> 8)) / 255;
+ g = ((double)((pd->generic->color.g * G_VAL(&mul_col)) >> 8)) / 255;
+ b = ((double)((pd->generic->color.b * B_VAL(&mul_col)) >> 8)) / 255;
+ a = ((double)((pd->generic->color.a * A_VAL(&mul_col)) >> 8)) / 255;
+
+ cairo_set_operator(pd->parent->cairo, cop);
+ cairo_transform(pd->parent->cairo, &identity);
+ if (pd->m) cairo_transform(pd->parent->cairo, pd->m);
+ cx = pd->generic->origin.x - pd->parent->current.x;
+ cy = pd->generic->origin.y - pd->parent->current.y;
+ cairo_translate(pd->parent->cairo, cx, cy);
+ pd->parent->current.x = pd->generic->origin.x;
+ pd->parent->current.y = pd->generic->origin.y;
+
+ cairo_set_source_rgba(pd->parent->cairo, r, g, b, a);
+
+ return EINA_TRUE;
+}
+
+static void
+_ector_renderer_cairo_base_eo_base_constructor(Eo *obj, Ector_Renderer_Cairo_Base_Data *pd EINA_UNUSED)
+{
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_BASE_CLASS, eo_constructor());
+
+ pd->generic = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, obj);
+
+ USE(obj, cairo_matrix_init_identity, );
+
+ cairo_matrix_init_identity(&identity);
+}
+
+static void
+_ector_renderer_cairo_base_eo_base_destructor(Eo *obj, Ector_Renderer_Cairo_Base_Data *pd)
+{
+ Eo *parent;
+
+ free(pd->m);
+
+ eo_do(obj, parent = eo_parent_get());
+ eo_data_xunref(parent, pd->parent, obj);
+ eo_data_xunref(obj, pd->generic, obj);
+
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_BASE_CLASS, eo_destructor());
+}
+
+#include "ector_renderer_cairo_base.eo.c"
-interface Ector.Renderer.Cairo.Base
+abstract Ector.Renderer.Cairo.Base (Ector.Renderer.Generic.Base)
{
legacy_prefix: null;
methods {
return: bool;
}
}
+ implements {
+ @virtual .fill;
+ Ector.Renderer.Generic.Base.prepare;
+ Ector.Renderer.Generic.Base.draw;
+ Ector.Renderer.Generic.Base.color.set;
+ Ector.Renderer.Generic.Base.color.get;
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
}
Ector_Renderer_Generic_Gradient_Data *gd;
unsigned int i;
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS, ector_renderer_prepare());
+
if (pd->pat) return EINA_FALSE;
- gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS);
- gd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_CLASS);
+ gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN);
+ gd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_MIXIN);
if (!gld || !gd) return EINA_FALSE;
USE(obj, cairo_pattern_create_linear, EINA_FALSE);
static Eina_Bool
_ector_renderer_cairo_gradient_linear_ector_renderer_generic_base_draw(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd,
- Ector_Rop op, Eina_Array *clips, int x, int y, unsigned int mul_col)
+ Ector_Rop op, Eina_Array *clips, unsigned int mul_col)
{
Ector_Renderer_Generic_Gradient_Linear_Data *gld;
// FIXME: don't ignore clipping !
- gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS);
- if (!pd->pat || !gld || CHECK_CAIRO(pd->parent)) return EINA_FALSE;
+ gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN);
+ if (!pd->pat || !gld) return EINA_FALSE;
+
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS, ector_renderer_draw(op, clips, mul_col));
USE(obj, cairo_rectangle, EINA_FALSE);
+ USE(obj, cairo_fill, EINA_FALSE);
- cairo_rectangle(pd->parent->cairo, gld->start.x - x, gld->start.y - y,
+ cairo_rectangle(pd->parent->cairo, gld->start.x, gld->start.y,
gld->end.x - gld->start.x,
gld->end.y - gld->start.y);
eo_do(obj, ector_renderer_cairo_base_fill());
_ector_renderer_cairo_gradient_linear_ector_renderer_cairo_base_fill(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd)
{
- if (!pd->pat || CHECK_CAIRO(pd->parent)) return EINA_FALSE;
+ if (!pd->pat) return EINA_FALSE;
USE(obj, cairo_set_source, EINA_FALSE);
}
void
-_ector_renderer_cairo_gradient_linear_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Cairo_Gradient_Linear_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
+_ector_renderer_cairo_gradient_linear_efl_gfx_gradient_base_stop_set(Eo *obj, Ector_Renderer_Cairo_Gradient_Linear_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
{
USE(obj, cairo_pattern_destroy, );
-class Ector.Renderer.Cairo.Gradient_Linear (Ector.Renderer.Cairo.Base, Ector.Renderer.Generic.Gradient_Linear)
+class Ector.Renderer.Cairo.Gradient_Linear (Ector.Renderer.Cairo.Base, Ector.Renderer.Generic.Gradient, Ector.Renderer.Generic.Gradient_Linear)
{
eo_prefix: ector_renderer_cairo_gradient_linear;
legacy_prefix: null;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Cairo.Base.fill;
Eo.Base.destructor;
- Efl.Gfx.Gradient.stop.set;
+ Efl.Gfx.Gradient.Base.stop.set;
}
}
double radius1) = NULL;
static void (*cairo_set_source)(cairo_t *cr, cairo_pattern_t *source) = NULL;
static void (*cairo_fill)(cairo_t *cr) = NULL;
-static void (*cairo_rectangle)(cairo_t *cr,
- double x, double y,
- double width, double height) = NULL;
+static void (*cairo_arc)(cairo_t *cr,
+ double xc, double yc,
+ double radius,
+ double angle1, double angle2) = NULL;
static void (*cairo_pattern_add_color_stop_rgba)(cairo_pattern_t *pattern, double offset,
double red, double green, double blue, double alpha) = NULL;
static void (*cairo_pattern_destroy)(cairo_pattern_t *pattern) = NULL;
Ector_Renderer_Generic_Gradient_Data *gd;
unsigned int i;
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS, ector_renderer_prepare());
+
if (pd->pat) return EINA_FALSE;
- grd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_CLASS);
- gd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_CLASS);
+ grd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN);
+ gd = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_MIXIN);
if (!grd || !gd) return EINA_FALSE;
USE(obj, cairo_pattern_create_radial, EINA_FALSE);
// Clearly duplicated and should be in a common place...
static Eina_Bool
-_ector_renderer_cairo_gradient_radial_ector_renderer_generic_base_draw(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd, Ector_Rop op, Eina_Array *clips, int x, int y, unsigned int mul_col)
+_ector_renderer_cairo_gradient_radial_ector_renderer_generic_base_draw(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd, Ector_Rop op, Eina_Array *clips, unsigned int mul_col)
{
- Ector_Renderer_Generic_Gradient_Linear_Data *gld;
+ Ector_Renderer_Generic_Gradient_Radial_Data *gld;
// FIXME: don't ignore clipping !
- gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS);
- if (!pd->pat || !gld || CHECK_CAIRO(pd->parent)) return EINA_FALSE;
+ gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN);
+ if (!pd->pat || !gld) return EINA_FALSE;
+
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS, ector_renderer_draw(op, clips, mul_col));
- USE(obj, cairo_rectangle, EINA_FALSE);
+ USE(obj, cairo_arc, EINA_FALSE);
+ USE(obj, cairo_fill, EINA_FALSE);
- cairo_rectangle(pd->parent->cairo, gld->start.x - x, gld->start.y - y,
- gld->end.x - gld->start.x, gld->end.y - gld->start.y);
+ cairo_arc(pd->parent->cairo,
+ gld->radial.x, gld->radial.y,
+ gld->radius,
+ 0, 2 * M_PI);
eo_do(obj, ector_renderer_cairo_base_fill());
cairo_fill(pd->parent->cairo);
static Eina_Bool
_ector_renderer_cairo_gradient_radial_ector_renderer_cairo_base_fill(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd)
{
- if (!pd->pat || CHECK_CAIRO(pd->parent)) return EINA_FALSE;
+ if (!pd->pat) return EINA_FALSE;
USE(obj, cairo_set_source, EINA_FALSE);
}
void
-_ector_renderer_cairo_gradient_radial_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
+_ector_renderer_cairo_gradient_radial_efl_gfx_gradient_base_stop_set(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
{
USE(obj, cairo_pattern_destroy, );
if (pd->pat) cairo_pattern_destroy(pd->pat);
pd->pat = NULL;
- eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS,
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS,
efl_gfx_gradient_stop_set(colors, length));
}
-class Ector.Renderer.Cairo.Gradient_Radial (Ector.Renderer.Cairo.Base, Ector.Renderer.Generic.Gradient_Radial)
+class Ector.Renderer.Cairo.Gradient_Radial (Ector.Renderer.Cairo.Base, Ector.Renderer.Generic.Gradient, Ector.Renderer.Generic.Gradient_Radial)
{
eo_prefix: ector_renderer_cairo_gradient_radial;
legacy_prefix: null;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Cairo.Base.fill;
Eo.Base.destructor;
- Efl.Gfx.Gradient.stop.set;
+ Efl.Gfx.Gradient.Base.stop.set;
}
}
};
static Eina_Bool
+_ector_renderer_cairo_shape_path_changed(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ Ector_Renderer_Cairo_Shape_Data *pd = data;
+
+ USE(obj, cairo_path_destroy, EINA_TRUE);
+
+ if (pd->path) cairo_path_destroy(pd->path);
+ pd->path = NULL;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
_ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
{
- // FIXME: shouldn't that be part of the shape generic implementation ?
+ const Efl_Gfx_Path_Command *cmds = NULL;
+ const double *pts = NULL;
+
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, ector_renderer_prepare());
+
if (pd->shape->fill)
eo_do(pd->shape->fill, ector_renderer_prepare());
if (pd->shape->stroke.fill)
eo_do(pd->shape->stroke.fill, ector_renderer_prepare());
if (pd->shape->stroke.marker)
eo_do(pd->shape->stroke.marker, ector_renderer_prepare());
- eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, ector_renderer_prepare());
// shouldn't that be moved to the cairo base object
if (!pd->parent)
if (!pd->parent) return EINA_FALSE;
}
- if (!pd->path && pd->shape->path.cmd)
+ eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
+ if (!pd->path && cmds)
{
- double *pts;
- unsigned int i;
-
USE(obj, cairo_new_path, EINA_FALSE);
cairo_new_path(pd->parent->cairo);
- pts = pd->shape->path.pts;
- for (i = 0; pd->shape->path.cmd[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+ for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
{
- switch (pd->shape->path.cmd[i])
+ switch (*cmds)
{
case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
USE(obj, cairo_move_to, EINA_FALSE);
}
static Eina_Bool
-_ector_renderer_cairo_shape_ector_renderer_generic_base_draw(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd, Ector_Rop op, Eina_Array *clips, int x, int y, unsigned int mul_col)
+_ector_renderer_cairo_shape_ector_renderer_generic_base_draw(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd, Ector_Rop op, Eina_Array *clips, unsigned int mul_col)
{
if (pd->path == NULL) return EINA_FALSE;
- // FIXME: find a way to offset the drawing and setting multiple clips
-
- eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, ector_renderer_draw(op, clips, x, y, mul_col));
+ // FIXME: find a way to set multiple clips
+ eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, ector_renderer_draw(op, clips, mul_col));
USE(obj, cairo_new_path, EINA_FALSE);
USE(obj, cairo_append_path, EINA_FALSE);
}
static Eina_Bool
-_ector_renderer_cairo_shape_ector_renderer_cairo_base_fill(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
+_ector_renderer_cairo_shape_ector_renderer_cairo_base_fill(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Cairo_Shape_Data *pd EINA_UNUSED)
{
// FIXME: let's find out how to fill a shape with a shape later.
// I need to read SVG specification and see how to map that with cairo.
+#warning "fill for a shape object is unhandled at this moment in cairo backend."
+ ERR("fill with shape not implemented\n");
+ return EINA_FALSE;
}
-static void
-_ector_renderer_cairo_shape_efl_gfx_shape_path_set(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd,
- const Efl_Gfx_Path_Command *op, const double *points)
-{
- USE(obj, cairo_path_destroy, );
-
- if (pd->path) cairo_path_destroy(pd->path);
- pd->path = NULL;
-
- eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, efl_gfx_shape_path_set(op, points));
-}
-
-
void
_ector_renderer_cairo_shape_eo_base_constructor(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
{
eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, eo_constructor());
- pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_CLASS, obj);
+ pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_MIXIN, obj);
pd->base = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, obj);
+
+ eo_do(obj,
+ eo_event_callback_add(EFL_GFX_PATH_CHANGED, _ector_renderer_cairo_shape_path_changed, pd));
}
void
{
Eo *parent;
- USE(obj, cairo_path_destroy, );
- if (pd->path) cairo_path_destroy(pd->path);
-
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->parent, obj);
eo_data_xunref(obj, pd->shape, obj);
eo_data_xunref(obj, pd->base, obj);
+
eo_do_super(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, eo_destructor());
+
+ USE(obj, cairo_path_destroy, );
+ if (pd->path) cairo_path_destroy(pd->path);
}
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Cairo.Base.fill;
- Efl.Gfx.Shape.path.set;
Eo.Base.constructor;
Eo.Base.destructor;
}
int h; /*@ in */
}
}
- surface {
+ reference_point {
set {
- }
- get {
- }
- values {
- void *pixels;
- uint width;
- uint height;
- }
- }
+ /*@ This define where is (0,0) in pixels coordinate inside the surface */
+ }
+ values {
+ int x;
+ int y;
+ }
+ }
}
methods {
renderer_factory_new {
}
implements {
@virtual .renderer_factory_new;
+ @virtual .reference_point.set;
}
}
#include <Ector.h>
#include "ector_private.h"
-int _ector_log_dom = 0;
+int _ector_log_dom_global = 0;
static int _ector_main_count = 0;
eina_init();
eo_init();
- _ector_log_dom = eina_log_domain_register("ector", ECTOR_DEFAULT_LOG_COLOR);
- if (_ector_log_dom < 0)
+ _ector_log_dom_global = eina_log_domain_register("ector", ECTOR_DEFAULT_LOG_COLOR);
+ if (_ector_log_dom_global < 0)
{
EINA_LOG_ERR("Could not register log domain: ector");
goto on_error;
_ector_main_count = 1;
- eina_log_timing(_ector_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
+ eina_log_timing(_ector_log_dom_global, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
return _ector_main_count;
if (EINA_LIKELY(_ector_main_count > 0))
return _ector_main_count;
- eina_log_timing(_ector_log_dom,
+ eina_log_timing(_ector_log_dom_global,
EINA_LOG_STATE_START,
EINA_LOG_STATE_SHUTDOWN);
eo_shutdown();
- eina_log_domain_unregister(_ector_log_dom);
+ eina_log_domain_unregister(_ector_log_dom_global);
eina_shutdown();
return _ector_main_count;
#endif /* ifdef CRI */
#define CRI(...) EINA_LOG_DOM_CRIT(_ector_log_dom_global, __VA_ARGS__)
+typedef unsigned char DATA8;
+typedef unsigned short DATA16;
+
+#ifndef WORDS_BIGENDIAN
+/* x86 */
+#define A_VAL(p) (((DATA8 *)(p))[3])
+#define R_VAL(p) (((DATA8 *)(p))[2])
+#define G_VAL(p) (((DATA8 *)(p))[1])
+#define B_VAL(p) (((DATA8 *)(p))[0])
+#define AR_VAL(p) ((DATA16 *)(p)[1])
+#define GB_VAL(p) ((DATA16 *)(p)[0])
+#else
+/* ppc */
+#define A_VAL(p) (((DATA8 *)(p))[0])
+#define R_VAL(p) (((DATA8 *)(p))[1])
+#define G_VAL(p) (((DATA8 *)(p))[2])
+#define B_VAL(p) (((DATA8 *)(p))[3])
+#define AR_VAL(p) ((DATA16 *)(p)[0])
+#define GB_VAL(p) ((DATA16 *)(p)[1])
+#endif
+
+#define RGB_JOIN(r,g,b) \
+ (((r) << 16) + ((g) << 8) + (b))
+
+#define ARGB_JOIN(a,r,g,b) \
+ (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+
+static inline void
+ector_color_argb_premul(int a, int *r, int *g, int *b)
+{
+ a++;
+ if (r) { *r = (a * *r) >> 8; }
+ if (g) { *g = (a * *g) >> 8; }
+ if (b) { *b = (a * *b) >> 8; }
+}
+
+static inline void
+ector_color_argb_unpremul(int a, int *r, int *g, int *b)
+{
+ if (!a) return;
+ if (r) { *r = (255 * *r) / a; }
+ if (g) { *g = (255 * *g) / a; }
+ if (b) { *b = (255 * *b) / a; }
+}
+
+
static inline void
_ector_renderer_replace(Ector_Renderer **d, const Ector_Renderer *s)
{
struct _Ector_Renderer_Generic_Shape_Data
{
- struct {
- Efl_Gfx_Path_Command *cmd;
- double *pts;
- } path;
-
Ector_Renderer *fill;
struct {
Ector_Renderer *fill;
return pd->q;
}
+static Eina_Bool
+_ector_renderer_generic_base_prepare(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Generic_Base_Data *pd)
+{
+ if (pd->mask)
+ eo_do(pd->mask, ector_renderer_prepare());
+
+ return EINA_TRUE;
+}
+
#include "ector_renderer_generic_base.eo.c"
params {
@in Ector_Rop op;
@in array<Eina_Rectangle *> *clips; /*@ array of Eina_Rectangle clip */
- @in int x;
- @in int y;
@in uint mul_col;
}
}
implements {
@virtual .draw;
@virtual .bounds_get;
- @virtual .prepare;
@virtual .done;
}
}
-abstract Ector.Renderer.Generic.Gradient (Ector.Renderer.Generic.Base, Efl.Gfx.Gradient)
+mixin Ector.Renderer.Generic.Gradient (Efl.Gfx.Gradient.Base)
{
eo_prefix: ector_renderer_gradient;
legacy_prefix: null;
implements {
- Efl.Gfx.Gradient.stop.set;
- Efl.Gfx.Gradient.stop.get;
- Efl.Gfx.Gradient.spread.set;
- Efl.Gfx.Gradient.spread.get;
+ Efl.Gfx.Gradient.Base.stop.set;
+ Efl.Gfx.Gradient.Base.stop.get;
+ Efl.Gfx.Gradient.Base.spread.set;
+ Efl.Gfx.Gradient.Base.spread.get;
}
}
-abstract Ector.Renderer.Generic.Gradient_Linear (Ector.Renderer.Generic.Gradient, Efl.Gfx.Gradient_Linear)
+mixin Ector.Renderer.Generic.Gradient_Linear (Efl.Gfx.Gradient.Linear)
{
eo_prefix: ector_renderer_gradient_linear;
legacy_prefix: null;
implements {
- Efl.Gfx.Gradient_Linear.start.set;
- Efl.Gfx.Gradient_Linear.start.get;
- Efl.Gfx.Gradient_Linear.end.set;
- Efl.Gfx.Gradient_Linear.end.get;
+ Efl.Gfx.Gradient.Linear.start.set;
+ Efl.Gfx.Gradient.Linear.start.get;
+ Efl.Gfx.Gradient.Linear.end.set;
+ Efl.Gfx.Gradient.Linear.end.get;
}
}
-abstract Ector.Renderer.Generic.Gradient_Radial (Ector.Renderer.Generic.Gradient, Efl.Gfx.Gradient_Radial)
+mixin Ector.Renderer.Generic.Gradient_Radial (Efl.Gfx.Gradient.Radial)
{
eo_prefix: ector_renderer_gradient_radial;
legacy_prefix: null;
implements {
- Efl.Gfx.Gradient_Radial.center.set;
- Efl.Gfx.Gradient_Radial.center.get;
- Efl.Gfx.Gradient_Radial.radius.set;
- Efl.Gfx.Gradient_Radial.radius.get;
- Efl.Gfx.Gradient_Radial.focal.set;
- Efl.Gfx.Gradient_Radial.focal.get;
+ Efl.Gfx.Gradient.Radial.center.set;
+ Efl.Gfx.Gradient.Radial.center.get;
+ Efl.Gfx.Gradient.Radial.radius.set;
+ Efl.Gfx.Gradient.Radial.radius.get;
+ Efl.Gfx.Gradient.Radial.focal.set;
+ Efl.Gfx.Gradient.Radial.focal.get;
}
}
-class Ector.Renderer.Generic.Shape (Ector.Renderer.Generic.Base, Efl.Gfx.Shape)
+mixin Ector.Renderer.Generic.Shape (Efl.Gfx.Shape)
{
eo_prefix: ector_renderer_shape;
legacy_prefix: null;
Efl.Gfx.Shape.stroke_dash;
Efl.Gfx.Shape.stroke_cap;
Efl.Gfx.Shape.stroke_join;
- Efl.Gfx.Shape.path;
- Eo.Base.constructor;
- Eo.Base.destructor;
}
}
\ No newline at end of file
#include "ector_private.h"
static void
-_ector_renderer_generic_gradient_efl_gfx_gradient_stop_set(Eo *obj,
- Ector_Renderer_Generic_Gradient_Data *pd,
- const Efl_Gfx_Gradient_Stop *colors,
- unsigned int length)
+_ector_renderer_generic_gradient_efl_gfx_gradient_base_stop_set(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Generic_Gradient_Data *pd,
+ const Efl_Gfx_Gradient_Stop *colors,
+ unsigned int length)
{
pd->colors = realloc(pd->colors, length * sizeof(Efl_Gfx_Gradient_Stop));
if (!pd->colors)
}
static void
-_ector_renderer_generic_gradient_efl_gfx_gradient_stop_get(Eo *obj,
- Ector_Renderer_Generic_Gradient_Data *pd,
- const Efl_Gfx_Gradient_Stop **colors,
- unsigned int *length)
+_ector_renderer_generic_gradient_efl_gfx_gradient_base_stop_get(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Generic_Gradient_Data *pd,
+ const Efl_Gfx_Gradient_Stop **colors,
+ unsigned int *length)
{
if (colors) *colors = pd->colors;
if (length) *length = pd->colors_count;
}
static void
-_ector_renderer_generic_gradient_efl_gfx_gradient_spread_set(Eo *obj,
- Ector_Renderer_Generic_Gradient_Data *pd,
- Efl_Gfx_Gradient_Spread s)
+_ector_renderer_generic_gradient_efl_gfx_gradient_base_spread_set(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Generic_Gradient_Data *pd,
+ Efl_Gfx_Gradient_Spread s)
{
pd->s = s;
}
static Efl_Gfx_Gradient_Spread
-_ector_renderer_generic_gradient_efl_gfx_gradient_spread_get(Eo *obj,
- Ector_Renderer_Generic_Gradient_Data *pd)
+_ector_renderer_generic_gradient_efl_gfx_gradient_base_spread_get(Eo *obj EINA_UNUSED,
+ Ector_Renderer_Generic_Gradient_Data *pd)
{
return pd->s;
}
}
tmp = realloc(pd->stroke.dash, length * sizeof (Efl_Gfx_Dash));
- if (!tmp) return ;
+ if (!tmp && length) return ;
memcpy(tmp, dash, length * sizeof (Efl_Gfx_Dash));
pd->stroke.dash = tmp;
return pd->stroke.join;
}
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_path_set(Eo *obj EINA_UNUSED,
- Ector_Renderer_Generic_Shape_Data *pd,
- const Efl_Gfx_Path_Command *cmd,
- const double *points)
-{
- free(pd->path.cmd);
- pd->path.cmd = NULL;
- free(pd->path.pts);
- pd->path.pts = NULL;
-
- efl_gfx_path_dup(&pd->path.cmd, &pd->path.pts, cmd, points);
-}
-
-void
-_ector_renderer_generic_shape_efl_gfx_shape_path_get(Eo *obj EINA_UNUSED,
- Ector_Renderer_Generic_Shape_Data *pd,
- const Efl_Gfx_Path_Command **op,
- const double **points)
-{
- if (op) *op = pd->path.cmd;
- if (points) *points = pd->path.pts;
-}
-
-static void
-_ector_renderer_generic_shape_eo_base_constructor(Eo *obj,
- Ector_Renderer_Generic_Shape_Data *pd)
-{
- eo_do_super(obj, ECTOR_RENDERER_GENERIC_SHAPE_CLASS, eo_constructor());
-}
-
-static void
-_ector_renderer_generic_shape_eo_base_destructor(Eo *obj, Ector_Renderer_Generic_Shape_Data *pd)
-{
- eo_do_super(obj, ECTOR_RENDERER_GENERIC_SHAPE_CLASS, eo_destructor());
-}
-
#include "ector_renderer_generic_shape.eo.c"
{
}
-void _ector_generic_surface_surface_set(Eo *obj,
- Ector_Generic_Surface_Data *pd,
- void *pixels, unsigned int width, unsigned int height)
-{
-
-}
-
-void _ector_generic_surface_surface_get(Eo *obj,
- Ector_Generic_Surface_Data *pd,
- void **pixels, unsigned int *width, unsigned int *height)
-{
-
-}
-
-
Eina_Bool
_ector_generic_surface_update_push(Eo *obj,
Ector_Generic_Surface_Data *pd,
--- /dev/null
+#ifndef ECTOR_UTIL_H
+# define ECTOR_UTIL_H
+
+static inline unsigned int
+ector_color_multiply(unsigned int c1, unsigned int c2)
+{
+ return ( ((((((c1) >> 16) & 0xff00) * (((c2) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) +
+ ((((((c1) >> 8) & 0xff00) * (((c2) >> 16) & 0xff)) + 0xff00) & 0xff0000) +
+ ((((((c1) & 0xff00) * ((c2) & 0xff00)) + 0xff0000) >> 16) & 0xff00) +
+ (((((c1) & 0xff) * ((c2) & 0xff)) + 0xff) >> 8) );
+}
+
+#endif
+++ /dev/null
-#ifndef ECTOR_BLEND_PRIVATE_H
-#define ECTOR_BLEND_PRIVATE_H
-
-#ifndef MIN
-#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
-#endif
-
-#ifndef MAX
-#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
-#endif
-
-#define ECTOR_ARGB_JOIN(a,r,g,b) \
- (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
-
-#define ECTOR_MUL4_SYM(x, y) \
- ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) + \
- ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
- ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
- (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
-
-#define ECTOR_MUL_256(c, a) \
- ( (((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
- (((((c) & 0x00ff00ff) * (a)) >> 8) & 0x00ff00ff) )
-
-
-static inline void
-_ector_memfill(DATA32 *dest, uint value, int count)
-{
- if (!count)
- return;
-
- int n = (count + 7) / 8;
- switch (count & 0x07)
- {
- case 0: do { *dest++ = value;
- case 7: *dest++ = value;
- case 6: *dest++ = value;
- case 5: *dest++ = value;
- case 4: *dest++ = value;
- case 3: *dest++ = value;
- case 2: *dest++ = value;
- case 1: *dest++ = value;
- } while (--n > 0);
- }
-}
-
-
-static inline void
-_ector_comp_func_source_over_mul_c(uint *dest, uint *src, DATA32 c, int length, uint const_alpha)
-{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- uint s = src[i];
- DATA32 sc = ECTOR_MUL4_SYM(c, s);
- uint a = (~sc) >> 24;
- dest[i] = sc + ECTOR_MUL_256(dest[i], a);
- }
- } else {
- for (int i = 0; i < length; ++i) {
- uint s = src[i];
- DATA32 sc = ECTOR_MUL4_SYM(c, s);
- sc = ECTOR_MUL_256(sc, const_alpha);
- uint a = (~sc) >> 24;
- dest[i] = sc + ECTOR_MUL_256(dest[i], a);
- }
- }
-}
-
-
-static inline void
-_ector_comp_func_source_over(uint *dest, uint *src, int length, uint const_alpha)
-{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- uint s = src[i];
- if (s >= 0xff000000)
- dest[i] = s;
- else if (s != 0) {
- uint a = (~s) >> 24;
- dest[i] = s + ECTOR_MUL_256(dest[i], a);
- }
- }
- } else {
- for (int i = 0; i < length; ++i) {
- uint s = ECTOR_MUL_256(src[i], const_alpha);
- uint a = (~s) >> 24;
- dest[i] = s + ECTOR_MUL_256(dest[i], a);
- }
- }
-}
-
-
-static inline uint
-_ector_premultiply(uint data)
-{
- DATA32 a = 1 + (data >> 24);
- data = ( data & 0xff000000) +
- (((((data) >> 8) & 0xff) * a) & 0xff00) +
- (((((data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
-
- return data;
-}
-
-static inline uint
-INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
- uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
- t >>= 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
- x &= 0xff00ff00;
- x |= t;
- return x;
-}
-
-
-#endif
\ No newline at end of file
--- /dev/null
+
+#include <Ector.h>
+#include "ector_drawhelper_private.h"
+
+/*
+ s = source pixel
+ d = destination pixel
+ ca = const_alpha
+ sia = source inverse alpha
+ cia = const inverse alpha
+
+*/
+
+/*
+ result = s + d * sia
+ dest = (s + d * sia) * ca + d * cia
+ = s * ca + d * (sia * ca + cia)
+ = s * ca + d * (1 - sa*ca)
+*/
+void
+comp_func_solid_source_over(uint *dest, int length, uint color, uint const_alpha)
+{
+ int ialpha, i = 0;
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+ ialpha = Alpha(~color);
+ for (; i < length; ++i)
+ dest[i] = color + BYTE_MUL(dest[i], ialpha);
+}
+
+
+static void
+comp_func_source_over(uint *dest, const uint *src, int length, uint color, uint const_alpha)
+{
+ if (color == 0xffffffff) // No color multiplier
+ {
+ if (const_alpha == 255)
+ {
+ for (int i = 0; i < length; ++i)
+ {
+ uint s = src[i];
+ if (s >= 0xff000000)
+ dest[i] = s;
+ else if (s != 0)
+ {
+ uint sia = Alpha(~s);
+ dest[i] = s + BYTE_MUL(dest[i], sia);
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i < length; ++i)
+ {
+ uint s = BYTE_MUL(src[i], const_alpha);
+ uint sia = Alpha(~s);
+ dest[i] = s + BYTE_MUL(dest[i], sia);
+ }
+ }
+ }
+ else
+ {
+ if (const_alpha == 255)
+ {
+ for (int i = 0; i < length; ++i)
+ {
+ uint s = src[i];
+ uint sc = ECTOR_MUL4_SYM(color, s);
+ uint sia = Alpha(~sc);
+ dest[i] = sc + BYTE_MUL(dest[i], sia);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < length; ++i)
+ {
+ uint s = src[i];
+ uint sc = ECTOR_MUL4_SYM(color, s);
+ sc = BYTE_MUL(sc, const_alpha);
+ uint sia = Alpha(~sc);
+ dest[i] = sc + BYTE_MUL(dest[i], sia);
+ }
+ }
+ }
+}
+
+/*
+ result = s
+ dest = s * ca + d * cia
+*/
+static void
+comp_func_solid_source(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255) _ector_memfill(dest, length, color);
+ else
+ {
+ int ialpha, i = 0;
+ ialpha = 255 - const_alpha;
+ color = BYTE_MUL(color, const_alpha);
+ for (; i < length; ++i)
+ dest[i] = color + BYTE_MUL(dest[i], ialpha);
+ }
+}
+
+static void
+comp_func_source(uint *dest, const uint *src, int length, uint color, uint const_alpha)
+{
+ if (color == 0xffffffff) // No color multiplier
+ {
+ if (const_alpha == 255)
+ memcpy(dest, src, length * sizeof(uint));
+ else
+ {
+ int i, ialpha = 255 - const_alpha;
+ for (i = 0; i < length; ++i)
+ dest[i] = INTERPOLATE_PIXEL_256(src[i], const_alpha, dest[i], ialpha);
+ }
+ }
+ else
+ {
+ if (const_alpha == 255)
+ {
+ int i = 0;
+ for (; i < length; ++i)
+ dest[i] = ECTOR_MUL4_SYM(src[i], color);
+ }
+ else
+ {
+ int i, ialpha = 255 - const_alpha;
+ for (i = 0; i < length; ++i)
+ {
+ uint src_color = ECTOR_MUL4_SYM(src[i], color);
+ dest[i] = INTERPOLATE_PIXEL_256(src_color, const_alpha, dest[i], ialpha);
+ }
+ }
+ }
+}
+
+RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST] = {
+ comp_func_solid_source_over,
+ comp_func_solid_source
+};
+
+RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST] = {
+ comp_func_source_over,
+ comp_func_source
+};
+
+RGBA_Comp_Func_Solid
+ector_comp_func_solid_span_get(Ector_Rop op, uint color)
+{
+ if ((color & 0xff000000) == 0xff000000)
+ {
+ if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
+ }
+
+ return func_for_mode_solid[op];
+}
+
+RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool src_alpha)
+{
+ if (((color & 0xff000000) == 0xff000000) && !src_alpha)
+ {
+ if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
+ }
+ return func_for_mode[op];
+}
+
+extern void init_drawhelper_gradient();
+extern void init_draw_helper_sse2();
+
+void init_draw_helper()
+{
+ init_drawhelper_gradient();
+ init_draw_helper_sse2();
+}
--- /dev/null
+#ifndef ECTOR_DRAWHELPER_PRIVATE_H
+#define ECTOR_DRAWHELPER_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef MIN
+#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
+#endif
+
+#ifndef MAX
+#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#endif
+
+#ifndef uint
+typedef unsigned int uint;
+#endif
+
+inline int Alpha(uint c)
+{
+ return c>>24;
+}
+
+
+
+#define ECTOR_ARGB_JOIN(a,r,g,b) \
+ (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+
+#define ECTOR_MUL4_SYM(x, y) \
+ ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) + \
+ ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
+ ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
+ (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
+
+#define BYTE_MUL(c, a) \
+ ( (((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
+ (((((c) & 0x00ff00ff) * (a)) >> 8) & 0x00ff00ff) )
+
+#define LOOP_ALIGNED_U1_A4(DEST, LENGTH, UOP, A4OP) \
+ { \
+ while((uintptr_t)DEST & 0xF && LENGTH) UOP \
+ \
+ while(LENGTH) { \
+ switch(LENGTH) { \
+ case 3: \
+ case 2: \
+ case 1: \
+ UOP \
+ break; \
+ default: \
+ A4OP \
+ break; \
+ } \
+ } \
+ }
+
+static inline void
+_ector_memfill(uint *dest, int length, uint value)
+{
+ if (!length)
+ return;
+
+ int n = (length + 7) / 8;
+ switch (length & 0x07)
+ {
+ case 0: do { *dest++ = value;
+ case 7: *dest++ = value;
+ case 6: *dest++ = value;
+ case 5: *dest++ = value;
+ case 4: *dest++ = value;
+ case 3: *dest++ = value;
+ case 2: *dest++ = value;
+ case 1: *dest++ = value;
+ } while (--n > 0);
+ }
+}
+
+static inline uint
+INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
+{
+ uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+typedef void (*RGBA_Comp_Func)(uint *dest, const uint *src, int length, uint mul_col, uint const_alpha);
+typedef void (*RGBA_Comp_Func_Solid)(uint *dest, int length, uint color, uint const_alpha);
+extern RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST];
+extern RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST];
+
+void init_draw_helper();
+
+RGBA_Comp_Func_Solid ector_comp_func_solid_span_get(Ector_Rop op, uint color);
+RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool src_alpha);
+
+#endif
\ No newline at end of file
--- /dev/null
+
+#include <Ector.h>
+#include "ector_drawhelper_private.h"
+
+#ifdef BUILD_SSE3
+#include <immintrin.h>
+
+// Each 32bits components of alphaChannel must be in the form 0x00AA00AA
+inline static __m128i
+v4_byte_mul_sse2(__m128i c, __m128i a)
+{
+ const __m128i ag_mask = _mm_set1_epi32(0xFF00FF00);
+ const __m128i rb_mask = _mm_set1_epi32(0x00FF00FF);
+
+ /* for AG */
+ __m128i v_ag = _mm_and_si128(ag_mask, c);
+ v_ag = _mm_srli_epi32(v_ag, 8);
+ v_ag = _mm_mullo_epi16(a, v_ag);
+ v_ag = _mm_and_si128(ag_mask, v_ag);
+
+ /* for RB */
+ __m128i v_rb = _mm_and_si128(rb_mask, c);
+ v_rb = _mm_mullo_epi16(a, v_rb);
+ v_rb = _mm_srli_epi32(v_rb, 8);
+ v_rb = _mm_and_si128(rb_mask, v_rb);
+
+ /* combine */
+ return _mm_add_epi32(v_ag, v_rb);
+}
+
+static inline __m128i
+v4_interpolate_color_sse2(__m128i a, __m128i c0, __m128i c1)
+{
+ const __m128i rb_mask = _mm_set1_epi32(0xFF00FF00);
+ const __m128i zero = _mm_setzero_si128();
+
+ __m128i a_l = a;
+ __m128i a_h = a;
+ a_l = _mm_unpacklo_epi16(a_l, a_l);
+ a_h = _mm_unpackhi_epi16(a_h, a_h);
+
+ __m128i a_t = _mm_slli_epi64(a_l, 32);
+ __m128i a_t0 = _mm_slli_epi64(a_h, 32);
+
+ a_l = _mm_add_epi32(a_l, a_t);
+ a_h = _mm_add_epi32(a_h, a_t0);
+
+ __m128i c0_l = c0;
+ __m128i c0_h = c0;
+
+ c0_l = _mm_unpacklo_epi8(c0_l, zero);
+ c0_h = _mm_unpackhi_epi8(c0_h, zero);
+
+ __m128i c1_l = c1;
+ __m128i c1_h = c1;
+
+ c1_l = _mm_unpacklo_epi8(c1_l, zero);
+ c1_h = _mm_unpackhi_epi8(c1_h, zero);
+
+ __m128i cl_sub = _mm_sub_epi16(c0_l, c1_l);
+ __m128i ch_sub = _mm_sub_epi16(c0_h, c1_h);
+
+ cl_sub = _mm_mullo_epi16(cl_sub, a_l);
+ ch_sub = _mm_mullo_epi16(ch_sub, a_h);
+
+ __m128i c1ls = _mm_slli_epi16(c1_l, 8);
+ __m128i c1hs = _mm_slli_epi16(c1_h, 8);
+
+ cl_sub = _mm_add_epi16(cl_sub, c1ls);
+ ch_sub = _mm_add_epi16(ch_sub, c1hs);
+
+ cl_sub = _mm_and_si128(cl_sub, rb_mask);
+ ch_sub = _mm_and_si128(ch_sub, rb_mask);
+
+ cl_sub = _mm_srli_epi64(cl_sub, 8);
+ ch_sub = _mm_srli_epi64(ch_sub, 8);
+
+ cl_sub = _mm_packus_epi16(cl_sub, cl_sub);
+ ch_sub = _mm_packus_epi16(ch_sub, ch_sub);
+
+ return (__m128i) _mm_shuffle_ps( (__m128)cl_sub, (__m128)ch_sub, 0x44);
+}
+
+static inline __m128i
+v4_mul_color_sse2(__m128i x, __m128i y)
+{
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i sym4_mask = _mm_set_epi32(0x00FF00FF, 0x000000FF, 0x00FF00FF, 0x000000FF);
+ __m128i x_l = _mm_unpacklo_epi8(x, zero);
+ __m128i x_h = _mm_unpackhi_epi8(x, zero);
+
+ __m128i y_l = _mm_unpacklo_epi8(y, zero);
+ __m128i y_h = _mm_unpackhi_epi8(y, zero);
+
+ __m128i r_l = _mm_mullo_epi16(x_l, y_l);
+ __m128i r_h = _mm_mullo_epi16(x_h, y_h);
+
+ r_l = _mm_add_epi16(r_l, sym4_mask);
+ r_h = _mm_add_epi16(r_h, sym4_mask);
+
+ r_l = _mm_srli_epi16(r_l, 8);
+ r_h = _mm_srli_epi16(r_h, 8);
+
+ return _mm_packus_epi16(r_l, r_h);
+}
+
+static inline __m128i
+v4_ialpha_sse2(__m128i c)
+{
+ __m128i a = _mm_srli_epi32(c, 24);
+ return _mm_sub_epi32(_mm_set1_epi32(0xff), a);
+}
+
+// dest = color + (dest * alpha)
+inline static void
+comp_func_helper_sse2 (uint *dest, int length, uint color, uint alpha)
+{
+ const __m128i v_color = _mm_set1_epi32(color);
+ const __m128i v_a = _mm_set1_epi16(alpha);
+
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ *dest = color + BYTE_MUL(*dest, alpha);
+ dest++; length--;
+ },
+ { /* A4OP */
+ __m128i v_dest = _mm_load_si128((__m128i *)dest);
+
+ v_dest = v4_byte_mul_sse2(v_dest, v_a);
+ v_dest = _mm_add_epi32(v_dest, v_color);
+
+ _mm_store_si128((__m128i *)dest, v_dest);
+
+ dest += 4; length -= 4;
+ })
+}
+
+void
+comp_func_solid_source_sse2(uint *dest, int length, uint color, uint const_alpha)
+{
+ if (const_alpha == 255) _ector_memfill(dest, length, color);
+ else
+ {
+ int ialpha;
+ ialpha = 255 - const_alpha;
+ color = BYTE_MUL(color, const_alpha);
+ comp_func_helper_sse2(dest, length, color, ialpha);
+ }
+}
+
+void
+comp_func_solid_source_over_sse2(uint *dest, int length, uint color, uint const_alpha)
+{
+ int ialpha;
+ if (const_alpha != 255)
+ color = BYTE_MUL(color, const_alpha);
+ ialpha = Alpha(~color);
+ comp_func_helper_sse2(dest, length, color, ialpha);
+}
+
+// Load src and dest vector
+#define V4_FETCH_SRC_DEST \
+ __m128i v_src = _mm_loadu_si128((__m128i *)src); \
+ __m128i v_dest = _mm_load_si128((__m128i *)dest);
+
+#define V4_FETCH_SRC \
+ __m128i v_src = _mm_loadu_si128((__m128i *)src);
+
+#define V4_STORE_DEST \
+ _mm_store_si128((__m128i *)dest, v_src);
+
+#define V4_SRC_DEST_LEN_INC \
+ dest += 4; src +=4; length -= 4;
+
+// Multiply src color with color multiplier
+#define V4_COLOR_MULTIPLY \
+ v_src = v4_mul_color_sse2(v_src, v_color);
+
+// Multiply src color with const_alpha
+#define V4_ALPHA_MULTIPLY \
+ v_src = v4_byte_mul_sse2(v_src, v_alpha);
+
+// dest = src + dest * sia
+#define V4_COMP_OP_SRC_OVER \
+ __m128i v_sia = v4_ialpha_sse2(v_src); \
+ v_sia = _mm_add_epi32(v_sia, _mm_slli_epi32(v_sia, 16)); \
+ v_dest = v4_byte_mul_sse2(v_dest, v_sia); \
+ v_src = _mm_add_epi32(v_src, v_dest);
+
+// dest = src + dest * sia
+#define V4_COMP_OP_SRC \
+ v_src = v4_interpolate_color_sse2(v_alpha, v_src, v_dest);
+
+
+
+static void
+comp_func_source_sse2(uint *dest, const uint *src, int length, uint color, uint const_alpha)
+{
+ if (color == 0xffffffff) // No color multiplier
+ {
+ if (const_alpha == 255)
+ memcpy(dest, src, length * sizeof(uint));
+ else
+ {
+ int ialpha = 255 - const_alpha;
+ __m128i v_alpha = _mm_set1_epi32(const_alpha);
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ *dest = INTERPOLATE_PIXEL_256(*src, const_alpha, *dest, ialpha);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_COMP_OP_SRC
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ }
+ else
+ {
+ __m128i v_color = _mm_set1_epi32(color);
+ if (const_alpha == 255)
+ {
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ *dest = ECTOR_MUL4_SYM(*src, color);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC
+ V4_COLOR_MULTIPLY
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ else
+ {
+ int ialpha = 255 - const_alpha;
+ __m128i v_alpha = _mm_set1_epi32(const_alpha);
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ uint src_color = ECTOR_MUL4_SYM(*src, color);
+ *dest = INTERPOLATE_PIXEL_256(src_color, const_alpha, *dest, ialpha);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_COLOR_MULTIPLY
+ V4_COMP_OP_SRC
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ }
+}
+
+static void
+comp_func_source_over_sse2(uint *dest, const uint *src, int length, uint color, uint const_alpha)
+{
+ if (color == 0xffffffff) // No color multiplier
+ {
+ if (const_alpha == 255)
+ {
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ uint s = *src;
+ uint sia = Alpha(~s);
+ *dest = s + BYTE_MUL(*dest, sia);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_COMP_OP_SRC_OVER
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ else
+ {
+ __m128i v_alpha = _mm_set1_epi16(const_alpha);
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ uint s = BYTE_MUL(*src, const_alpha);
+ uint sia = Alpha(~s);
+ *dest = s + BYTE_MUL(*dest, sia);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_ALPHA_MULTIPLY
+ V4_COMP_OP_SRC_OVER
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ }
+ else
+ {
+ __m128i v_color = _mm_set1_epi32(color);
+ if (const_alpha == 255)
+ {
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ uint s = ECTOR_MUL4_SYM(*src, color);
+ uint sia = Alpha(~s);
+ *dest = s + BYTE_MUL(*dest, sia);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_COLOR_MULTIPLY
+ V4_COMP_OP_SRC_OVER
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ else
+ {
+ __m128i v_alpha = _mm_set1_epi16(const_alpha);
+ LOOP_ALIGNED_U1_A4(dest, length,
+ { /* UOP */
+ uint s = ECTOR_MUL4_SYM(*src, color);
+ s = BYTE_MUL(s, const_alpha);
+ uint sia = Alpha(~s);
+ *dest = s + BYTE_MUL(*dest, sia);
+ dest++; src++; length--;
+ },
+ { /* A4OP */
+ V4_FETCH_SRC_DEST
+ V4_COLOR_MULTIPLY
+ V4_ALPHA_MULTIPLY
+ V4_COMP_OP_SRC_OVER
+ V4_STORE_DEST
+ V4_SRC_DEST_LEN_INC
+ })
+ }
+ }
+}
+
+#endif
+
+void
+init_draw_helper_sse2()
+{
+#ifdef BUILD_SSE3
+ if (eina_cpu_features_get() & EINA_CPU_SSE2)
+ {
+ // update the comp_function table for solid color
+ func_for_mode_solid[ECTOR_ROP_COPY] = comp_func_solid_source_sse2;
+ func_for_mode_solid[ECTOR_ROP_BLEND] = comp_func_solid_source_over_sse2;
+
+ // update the comp_function table for source data
+ func_for_mode[ECTOR_ROP_COPY] = comp_func_source_sse2;
+ func_for_mode[ECTOR_ROP_BLEND] = comp_func_source_over_sse2;
+ }
+#endif
+}
+
-interface Ector.Renderer.Software.Base
+class Ector.Renderer.Software.Base (Ector.Renderer.Generic.Base)
{
legacy_prefix: null;
methods {
return: bool;
}
}
+ implements {
+ @virtual .fill;
+ }
}
static void
_update_linear_data(Ector_Renderer_Software_Gradient_Data *gdata)
{
- update_color_table(gdata);
- gdata->linear.x1 = gdata->gld->start.x;
- gdata->linear.y1 = gdata->gld->start.y;
-
- gdata->linear.x2 = gdata->gld->end.x;
- gdata->linear.y2 = gdata->gld->end.y;
-
- gdata->linear.dx = gdata->linear.x2 - gdata->linear.x1;
- gdata->linear.dy = gdata->linear.y2 - gdata->linear.y1;
- gdata->linear.l = gdata->linear.dx * gdata->linear.dx + gdata->linear.dy * gdata->linear.dy;
- gdata->linear.off = 0;
- if (gdata->linear.l != 0) {
+ update_color_table(gdata);
+ gdata->linear.x1 = gdata->gld->start.x;
+ gdata->linear.y1 = gdata->gld->start.y;
+
+ gdata->linear.x2 = gdata->gld->end.x;
+ gdata->linear.y2 = gdata->gld->end.y;
+
+ gdata->linear.dx = gdata->linear.x2 - gdata->linear.x1;
+ gdata->linear.dy = gdata->linear.y2 - gdata->linear.y1;
+ gdata->linear.l = gdata->linear.dx * gdata->linear.dx + gdata->linear.dy * gdata->linear.dy;
+ gdata->linear.off = 0;
+
+ if (gdata->linear.l != 0)
+ {
gdata->linear.dx /= gdata->linear.l;
gdata->linear.dy /= gdata->linear.l;
gdata->linear.off = -gdata->linear.dx * gdata->linear.x1 - gdata->linear.dy * gdata->linear.y1;
- }
+ }
}
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_generic_base_prepare(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
if (!pd->surface)
{
pd->surface = eo_data_xref(parent, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
}
- _update_linear_data(pd);
+ _update_linear_data(pd);
return EINA_FALSE;
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- Ector_Rop op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
- int x EINA_UNUSED, int y EINA_UNUSED, unsigned int mul_col EINA_UNUSED)
+ Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
+ Ector_Rop op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
+ unsigned int mul_col EINA_UNUSED)
{
-
return EINA_TRUE;
}
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_software_base_fill(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
- ector_software_rasterizer_linear_gradient_set(pd->surface->software, pd);
+ ector_software_rasterizer_linear_gradient_set(pd->surface->software, pd);
return EINA_TRUE;
}
void
_ector_renderer_software_gradient_linear_eo_base_constructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, eo_constructor());
- pd->gd = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_CLASS, obj);
- pd->gld = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS, obj);
+ pd->gd = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_MIXIN, obj);
+ pd->gld = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN, obj);
}
void
_ector_renderer_software_gradient_linear_eo_base_destructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
Eo *parent;
-
+
destroy_color_table(pd);
-
+
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->surface, obj);
eo_data_xunref(obj, pd->gd, obj);
eo_data_xunref(obj, pd->gld, obj);
-
+
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, eo_destructor());
}
void
-_ector_renderer_software_gradient_linear_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
+_ector_renderer_software_gradient_linear_efl_gfx_gradient_base_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
{
- eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS,
- efl_gfx_gradient_stop_set(colors, length));
-
- destroy_color_table(pd);
+ eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS,
+ efl_gfx_gradient_stop_set(colors, length));
+
+ destroy_color_table(pd);
}
#include "ector_renderer_software_gradient_linear.eo.c"
-class Ector.Renderer.Software.Gradient_Linear (Ector.Renderer.Generic.Gradient_Linear, Ector.Renderer.Software.Base)
+class Ector.Renderer.Software.Gradient_Linear (Ector.Renderer.Software.Base, Ector.Renderer.Generic.Gradient, Ector.Renderer.Generic.Gradient_Linear)
{
eo_prefix: ector_renderer_software_gradient_linear;
legacy_prefix: null;
Ector.Renderer.Software.Base.fill;
Eo.Base.constructor;
Eo.Base.destructor;
- Efl.Gfx.Gradient.stop.set;
+ Efl.Gfx.Gradient.Base.stop.set;
}
}
static void
_update_radial_data(Ector_Renderer_Software_Gradient_Data *gdata)
{
- update_color_table(gdata);
+ update_color_table(gdata);
- gdata->radial.cx = gdata->grd->radial.x;
- gdata->radial.cy = gdata->grd->radial.y;
- gdata->radial.cradius = gdata->grd->radius;
+ gdata->radial.cx = gdata->grd->radial.x;
+ gdata->radial.cy = gdata->grd->radial.y;
+ gdata->radial.cradius = gdata->grd->radius;
- if(!gdata->grd->focal.x)
- gdata->radial.fx = gdata->grd->radial.x;
- else
- gdata->radial.fx = gdata->grd->focal.x;
+ if (!gdata->grd->focal.x)
+ gdata->radial.fx = gdata->grd->radial.x;
+ else
+ gdata->radial.fx = gdata->grd->focal.x;
- if(!gdata->grd->focal.y)
- gdata->radial.fy = gdata->grd->radial.y;
- else
- gdata->radial.fy = gdata->grd->focal.y;
+ if (!gdata->grd->focal.y)
+ gdata->radial.fy = gdata->grd->radial.y;
+ else
+ gdata->radial.fy = gdata->grd->focal.y;
- gdata->radial.fradius = 0;
+ gdata->radial.fradius = 0;
- gdata->radial.dx = gdata->radial.cx - gdata->radial.fx;
- gdata->radial.dy = gdata->radial.cy - gdata->radial.fy;
+ gdata->radial.dx = gdata->radial.cx - gdata->radial.fx;
+ gdata->radial.dy = gdata->radial.cy - gdata->radial.fy;
- gdata->radial.dr = gdata->radial.cradius - gdata->radial.fradius;
- gdata->radial.sqrfr = gdata->radial.fradius * gdata->radial.fradius;
+ gdata->radial.dr = gdata->radial.cradius - gdata->radial.fradius;
+ gdata->radial.sqrfr = gdata->radial.fradius * gdata->radial.fradius;
- gdata->radial.a = gdata->radial.dr * gdata->radial.dr -
- gdata->radial.dx * gdata->radial.dx -
- gdata->radial.dy * gdata->radial.dy;
- gdata->radial.inv2a = 1 / (2 * gdata->radial.a);
+ gdata->radial.a = gdata->radial.dr * gdata->radial.dr -
+ gdata->radial.dx * gdata->radial.dx -
+ gdata->radial.dy * gdata->radial.dy;
+ gdata->radial.inv2a = 1 / (2 * gdata->radial.a);
- gdata->radial.extended = (gdata->radial.fradius >= 0.00001f) || gdata->radial.a >= 0.00001f;
+ gdata->radial.extended = (gdata->radial.fradius >= 0.00001f) || gdata->radial.a >= 0.00001f;
}
pd->surface = eo_data_xref(parent, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
}
- _update_radial_data(pd);
+ _update_radial_data(pd);
return EINA_FALSE;
}
// Clearly duplicated and should be in a common place...
static Eina_Bool
_ector_renderer_software_gradient_radial_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- Ector_Rop op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
- int x EINA_UNUSED, int y EINA_UNUSED, unsigned int mul_col EINA_UNUSED)
+ Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
+ Ector_Rop op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
+ unsigned int mul_col EINA_UNUSED)
{
return EINA_TRUE;
}
static Eina_Bool
_ector_renderer_software_gradient_radial_ector_renderer_software_base_fill(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Gradient_Data *pd)
{
- ector_software_rasterizer_radial_gradient_set(pd->surface->software, pd);
+ ector_software_rasterizer_radial_gradient_set(pd->surface->software, pd);
return EINA_TRUE;
}
void
_ector_renderer_software_gradient_radial_eo_base_constructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, eo_constructor());
- pd->gd = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_CLASS, obj);
- pd->gld = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_CLASS, obj);
+ pd->gd = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_MIXIN, obj);
+ pd->gld = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN, obj);
}
void
_ector_renderer_software_gradient_radial_eo_base_destructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
+ Ector_Renderer_Software_Gradient_Data *pd)
{
- Eo *parent;
+ Eo *parent;
- destroy_color_table(pd);
+ destroy_color_table(pd);
- eo_do(obj, parent = eo_parent_get());
- eo_data_xunref(parent, pd->surface, obj);
+ eo_do(obj, parent = eo_parent_get());
+ eo_data_xunref(parent, pd->surface, obj);
- eo_data_xunref(obj, pd->gd, obj);
- eo_data_xunref(obj, pd->gld, obj);
+ eo_data_xunref(obj, pd->gd, obj);
+ eo_data_xunref(obj, pd->gld, obj);
- eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, eo_destructor());
+ eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, eo_destructor());
}
void
-_ector_renderer_software_gradient_radial_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
+_ector_renderer_software_gradient_radial_efl_gfx_gradient_base_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
{
- eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS,
- efl_gfx_gradient_stop_set(colors, length));
+ eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS,
+ efl_gfx_gradient_stop_set(colors, length));
- destroy_color_table(pd);
+ destroy_color_table(pd);
}
#include "ector_renderer_software_gradient_radial.eo.c"
-class Ector.Renderer.Software.Gradient_Radial (Ector.Renderer.Generic.Gradient_Radial, Ector.Renderer.Software.Base)
+class Ector.Renderer.Software.Gradient_Radial (Ector.Renderer.Software.Base, Ector.Renderer.Generic.Gradient, Ector.Renderer.Generic.Gradient_Radial)
{
eo_prefix: ector_renderer_software_gradient_radial;
legacy_prefix: null;
Ector.Renderer.Software.Base.fill;
Eo.Base.constructor;
Eo.Base.destructor;
- Efl.Gfx.Gradient.stop.set;
+ Efl.Gfx.Gradient.Base.stop.set;
}
}
int contours_alloc;
}Outline;
-static Outline *
+static Outline *
_outline_create()
{
- Outline *outline = (Outline *) calloc(1, sizeof(Outline));
-
- outline->ft_outline.points = (SW_FT_Vector *) calloc(50, sizeof(SW_FT_Vector));
- outline->ft_outline.tags = (char *) calloc(50, sizeof(char));
+ Outline *outline = (Outline *) calloc(1, sizeof(Outline));
- outline->ft_outline.contours = (short *) calloc(5, sizeof(short));
+ outline->ft_outline.points = (SW_FT_Vector *) calloc(50, sizeof(SW_FT_Vector));
+ outline->ft_outline.tags = (char *) calloc(50, sizeof(char));
- outline->points_alloc = 50;
- outline->contours_alloc = 5;
- return outline;
-}
+ outline->ft_outline.contours = (short *) calloc(5, sizeof(short));
-static
+ outline->points_alloc = 50;
+ outline->contours_alloc = 5;
+ return outline;
+}
+
+static
void _outline_destroy(Outline *outline)
{
- if (outline)
- {
- free(outline->ft_outline.points);
- free(outline->ft_outline.tags);
- free(outline->ft_outline.contours);
- free(outline);
- outline = NULL;
- }
-
+ if (outline)
+ {
+ free(outline->ft_outline.points);
+ free(outline->ft_outline.tags);
+ free(outline->ft_outline.contours);
+ free(outline);
+ outline = NULL;
+ }
}
static void
_outline_move_to(Outline *outline, double x, double y)
{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- if (ft_outline->n_contours == outline->contours_alloc)
- {
- outline->contours_alloc += 5;
- ft_outline->contours = (short *) realloc(ft_outline->contours, outline->contours_alloc * sizeof(short));
- }
- ft_outline->points[ft_outline->n_points].x = x;
- ft_outline->points[ft_outline->n_points].y = y;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
-
- if (ft_outline->n_points)
- {
- ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
- ft_outline->n_contours++;
- }
-
- ft_outline->n_points++;
+ SW_FT_Outline *ft_outline = &outline->ft_outline;
+
+ if (ft_outline->n_contours == outline->contours_alloc)
+ {
+ outline->contours_alloc += 5;
+ ft_outline->contours = (short *) realloc(ft_outline->contours, outline->contours_alloc * sizeof(short));
+ }
+ ft_outline->points[ft_outline->n_points].x = x;
+ ft_outline->points[ft_outline->n_points].y = y;
+ ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
+
+ if (ft_outline->n_points)
+ {
+ ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
+ ft_outline->n_contours++;
+ }
+
+ ft_outline->n_points++;
}
static void
_outline_end(Outline *outline)
{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
- if (ft_outline->n_contours == outline->contours_alloc)
- {
- outline->contours_alloc += 1;
- ft_outline->contours = (short *) realloc(ft_outline->contours, outline->contours_alloc * sizeof(short));
- }
-
- if (ft_outline->n_points)
- {
- ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
- ft_outline->n_contours++;
- }
+ SW_FT_Outline *ft_outline = &outline->ft_outline;
+
+ if (ft_outline->n_contours == outline->contours_alloc)
+ {
+ outline->contours_alloc += 1;
+ ft_outline->contours = (short *) realloc(ft_outline->contours, outline->contours_alloc * sizeof(short));
+ }
+
+ if (ft_outline->n_points)
+ {
+ ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
+ ft_outline->n_contours++;
+ }
}
static void _outline_line_to(Outline *outline, double x, double y)
{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- if (ft_outline->n_points == outline->points_alloc)
- {
- outline->points_alloc += 50;
- ft_outline->points = (SW_FT_Vector *) realloc(ft_outline->points, outline->points_alloc * sizeof(SW_FT_Vector));
- ft_outline->tags = (char *) realloc(ft_outline->tags, outline->points_alloc * sizeof(char));
- }
- ft_outline->points[ft_outline->n_points].x = x;
- ft_outline->points[ft_outline->n_points].y = y;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
- ft_outline->n_points++;
+ SW_FT_Outline *ft_outline = &outline->ft_outline;
+
+ if (ft_outline->n_points == outline->points_alloc)
+ {
+ outline->points_alloc += 50;
+ ft_outline->points = (SW_FT_Vector *) realloc(ft_outline->points, outline->points_alloc * sizeof(SW_FT_Vector));
+ ft_outline->tags = (char *) realloc(ft_outline->tags, outline->points_alloc * sizeof(char));
+ }
+ ft_outline->points[ft_outline->n_points].x = x;
+ ft_outline->points[ft_outline->n_points].y = y;
+ ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
+ ft_outline->n_points++;
}
{
SW_FT_Outline *ft_outline = &outline->ft_outline;
int index ;
-
+
if (ft_outline->n_contours)
- {
- index = ft_outline->contours[ft_outline->n_contours - 1] + 1;
+ {
+ index = ft_outline->contours[ft_outline->n_contours - 1] + 1;
+ }
+ else
+ {
+ // first path
+ index = 0;
+ }
- } else {
- // first path
- index = 0;
- }
-
// make sure there is atleast one point in the current path
if (ft_outline->n_points == index) return EINA_FALSE;
-
+
_outline_line_to(outline, ft_outline->points[index].x, ft_outline->points[index].y);
return EINA_TRUE;
}
static void _outline_cubic_to(Outline *outline, double cx1, double cy1, double cx2, double cy2, double x, double y)
{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- if (ft_outline->n_points == outline->points_alloc)
- {
- outline->points_alloc += 50;
- ft_outline->points = (SW_FT_Vector *) realloc(ft_outline->points, outline->points_alloc * sizeof(SW_FT_Vector));
- ft_outline->tags = (char *) realloc(ft_outline->tags, outline->points_alloc * sizeof(char));
- }
-
- ft_outline->points[ft_outline->n_points].x = cx1;
- ft_outline->points[ft_outline->n_points].y = cy1;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
- ft_outline->n_points++;
-
- ft_outline->points[ft_outline->n_points].x = cx2;
- ft_outline->points[ft_outline->n_points].y = cy2;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
- ft_outline->n_points++;
-
- ft_outline->points[ft_outline->n_points].x = x;
- ft_outline->points[ft_outline->n_points].y = y;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
- ft_outline->n_points++;
+ SW_FT_Outline *ft_outline = &outline->ft_outline;
+
+ if (ft_outline->n_points == outline->points_alloc)
+ {
+ outline->points_alloc += 50;
+ ft_outline->points = (SW_FT_Vector *) realloc(ft_outline->points, outline->points_alloc * sizeof(SW_FT_Vector));
+ ft_outline->tags = (char *) realloc(ft_outline->tags, outline->points_alloc * sizeof(char));
+ }
+
+ ft_outline->points[ft_outline->n_points].x = cx1;
+ ft_outline->points[ft_outline->n_points].y = cy1;
+ ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
+ ft_outline->n_points++;
+
+ ft_outline->points[ft_outline->n_points].x = cx2;
+ ft_outline->points[ft_outline->n_points].y = cy2;
+ ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
+ ft_outline->n_points++;
+
+ ft_outline->points[ft_outline->n_points].x = x;
+ ft_outline->points[ft_outline->n_points].y = y;
+ ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
+ ft_outline->n_points++;
}
static void _outline_transform(Outline *outline, Eina_Matrix3 *m)
{
- int i;
- SW_FT_Outline *ft_outline = &outline->ft_outline;
- if(m) {
+ int i;
+ SW_FT_Outline *ft_outline = &outline->ft_outline;
+
+ if (m)
+ {
double x, y;
- for(i = 0; i < ft_outline->n_points ; i++) {
- eina_matrix3_point_transform(m, ft_outline->points[i].x, ft_outline->points[i].y, &x, &y);
- ft_outline->points[i].x = (int)(x * 64);// to freetype 26.6 coordinate.
- ft_outline->points[i].y = (int)(y * 64);
- }
- } else {
- for(i = 0; i < ft_outline->n_points ; i++) {
- ft_outline->points[i].x = ft_outline->points[i].x <<6;// to freetype 26.6 coordinate.
- ft_outline->points[i].y = ft_outline->points[i].y <<6;
- }
- }
+ for (i = 0; i < ft_outline->n_points; i++)
+ {
+ eina_matrix3_point_transform(m, ft_outline->points[i].x, ft_outline->points[i].y, &x, &y);
+ ft_outline->points[i].x = (int)(x * 64);// to freetype 26.6 coordinate.
+ ft_outline->points[i].y = (int)(y * 64);
+ }
+ }
+ else
+ {
+ for (i = 0; i < ft_outline->n_points; i++)
+ {
+ ft_outline->points[i].x = ft_outline->points[i].x <<6;// to freetype 26.6 coordinate.
+ ft_outline->points[i].y = ft_outline->points[i].y <<6;
+ }
+ }
}
static Eina_Bool
_ector_renderer_software_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
{
+ const Efl_Gfx_Path_Command *cmds = NULL;
+ const double *pts = NULL;
+
// FIXME: shouldn't that be part of the shape generic implementation ?
if (pd->shape->fill)
eo_do(pd->shape->fill, ector_renderer_prepare());
if (!pd->surface) return EINA_FALSE;
}
- if (!pd->shape_data && pd->shape->path.cmd)
+ eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
+ if (!pd->shape_data && cmds)
{
- double *pts;
- unsigned int i;
Eina_Bool close_path = EINA_FALSE;
Outline * outline = _outline_create();
- pts = pd->shape->path.pts;
- for (i = 0; pd->shape->path.cmd[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+ for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
{
- switch (pd->shape->path.cmd[i])
+ switch (*cmds)
{
case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
// cairo, first is destination point, followed by
// the control point. The opposite of cairo.
_outline_cubic_to(outline,
- pts[2], pts[3], pts[4], pts[5], // control points
- pts[0], pts[1]); // destination point
+ pts[2], pts[3], pts[4], pts[5], // control points
+ pts[0], pts[1]); // destination point
pts += 6;
break;
break;
}
}
- _outline_end(outline);
- _outline_transform(outline, pd->base->m);
- // generate the shape data.
- pd->shape_data = ector_software_rasterizer_generate_rle_data(pd->surface->software, &outline->ft_outline);
- if (!pd->outline_data) {
+
+ _outline_end(outline);
+ _outline_transform(outline, pd->base->m);
+
+ // generate the shape data.
+ pd->shape_data = ector_software_rasterizer_generate_rle_data(pd->surface->software, &outline->ft_outline);
+ if (!pd->outline_data)
+ {
ector_software_rasterizer_stroke_set(pd->surface->software, (pd->shape->stroke.width * pd->shape->stroke.scale), pd->shape->stroke.cap,
pd->shape->stroke.join);
pd->outline_data = ector_software_rasterizer_generate_stroke_rle_data(pd->surface->software, &outline->ft_outline, close_path);
}
- _outline_destroy(outline);
- }
+ _outline_destroy(outline);
+ }
return EINA_TRUE;
}
static Eina_Bool
-_ector_renderer_software_shape_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Shape_Data *pd, Ector_Rop op, Eina_Array *clips, int x, int y, unsigned int mul_col)
+_ector_renderer_software_shape_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Shape_Data *pd, Ector_Rop op, Eina_Array *clips, unsigned int mul_col)
{
+ int x, y;
+
// adjust the offset
- x = x + (int)pd->base->origin.x;
- y = y + (int)pd->base->origin.y;
+ x = pd->surface->x + (int)pd->base->origin.x;
+ y = pd->surface->y + (int)pd->base->origin.y;
// fill the span_data structure
ector_software_rasterizer_clip_rect_set(pd->surface->software, clips);
ector_software_rasterizer_transform_set(pd->surface->software, pd->base->m);
- if (pd->shape->fill) {
- eo_do(pd->shape->fill, ector_renderer_software_base_fill());
- ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->shape_data);
- } else {
- if (pd->base->color.a > 0) {
- ector_software_rasterizer_color_set(pd->surface->software, pd->base->color.r, pd->base->color.g, pd->base->color.b, pd->base->color.a);
- ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->shape_data);
- }
- }
-
- if (pd->shape->stroke.fill) {
- eo_do(pd->shape->stroke.fill, ector_renderer_software_base_fill());
- ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->outline_data);
- } else {
- if (pd->shape->stroke.color.a > 0) {
- ector_software_rasterizer_color_set(pd->surface->software, pd->shape->stroke.color.r, pd->shape->stroke.color.g,
- pd->shape->stroke.color.b, pd->shape->stroke.color.a);
- ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->outline_data);
- }
-
- }
+ if (pd->shape->fill)
+ {
+ eo_do(pd->shape->fill, ector_renderer_software_base_fill());
+ ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->shape_data);
+ }
+ else
+ {
+ if (pd->base->color.a > 0)
+ {
+ ector_software_rasterizer_color_set(pd->surface->software, pd->base->color.r, pd->base->color.g, pd->base->color.b, pd->base->color.a);
+ ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->shape_data);
+ }
+ }
+
+ if (pd->shape->stroke.fill)
+ {
+ eo_do(pd->shape->stroke.fill, ector_renderer_software_base_fill());
+ ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->outline_data);
+ }
+ else
+ {
+ if (pd->shape->stroke.color.a > 0)
+ {
+ ector_software_rasterizer_color_set(pd->surface->software,
+ pd->shape->stroke.color.r, pd->shape->stroke.color.g,
+ pd->shape->stroke.color.b, pd->shape->stroke.color.a);
+ ector_software_rasterizer_draw_rle_data(pd->surface->software, x, y, mul_col, op, pd->outline_data);
+ }
+ }
+
return EINA_TRUE;
}
{
// FIXME: let's find out how to fill a shape with a shape later.
// I need to read SVG specification and see how to map that with software.
- return EINA_FALSE;
+ return EINA_FALSE;
}
static void
_ector_renderer_software_shape_efl_gfx_shape_path_set(Eo *obj, Ector_Renderer_Software_Shape_Data *pd,
const Efl_Gfx_Path_Command *op, const double *points)
{
- if(pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
- if(pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
+ if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
+ if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
pd->shape_data = NULL;
pd->outline_data = NULL;
}
+static Eina_Bool
+_ector_renderer_software_shape_path_changed(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Ector_Renderer_Software_Shape_Data *pd = data;
+
+ if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
+ if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
+
+ pd->shape_data = NULL;
+ pd->outline_data = NULL;
+
+ return EINA_TRUE;
+}
+
void
_ector_renderer_software_shape_eo_base_constructor(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
{
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, eo_constructor());
- pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_CLASS, obj);
+ pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_MIXIN, obj);
pd->base = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, obj);
+ eo_do(obj,
+ eo_event_callback_add(EFL_GFX_PATH_CHANGED, _ector_renderer_software_shape_path_changed, pd));
}
void
{
Eo *parent;
- if(pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
- if(pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
+ if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
+ if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->surface, obj);
-class Ector.Renderer.Software.Shape (Ector.Renderer.Generic.Shape, Ector.Renderer.Software.Base)
+class Ector.Renderer.Software.Shape (Ector.Renderer.Software.Base, Ector.Renderer.Generic.Shape)
{
eo_prefix: ector_renderer_software_shape;
legacy_prefix: null;
+#include <assert.h>
+#include <math.h>
#include <software/Ector_Software.h>
+
#include "ector_private.h"
#include "ector_software_private.h"
-#include "ector_blend_private.h"
+#include "ector_drawhelper_private.h"
-//Remove
-#include <assert.h>
-#include <math.h>
#define GRADIENT_STOPTABLE_SIZE 1024
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
+typedef void (*Radial_Helper_Func)(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
+ float det, float delta_det, float delta_delta_det, float b, float delta_b);
+
+typedef void (*Linear_Helper_Func)(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
+ int t_fixed, int inc_fixed);
-static inline int _gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos)
+Radial_Helper_Func radial_helper;
+Linear_Helper_Func linear_helper;
+
+static inline int
+_gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos)
{
- if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT) {
+ if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT)
+ {
ipos = ipos % GRADIENT_STOPTABLE_SIZE;
ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos;
- } else if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT) {
+ }
+ else if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT)
+ {
const int limit = GRADIENT_STOPTABLE_SIZE * 2;
ipos = ipos % limit;
ipos = ipos < 0 ? limit + ipos : ipos;
ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos;
- }else {
- if (ipos < 0)
- ipos = 0;
+ }
+ else
+ {
+ if (ipos < 0) ipos = 0;
else if (ipos >= GRADIENT_STOPTABLE_SIZE)
- ipos = GRADIENT_STOPTABLE_SIZE-1;
- }
-
- return ipos;
+ ipos = GRADIENT_STOPTABLE_SIZE-1;
+ }
+ return ipos;
}
-static uint _gradient_pixel_fixed(const Ector_Renderer_Software_Gradient_Data *data, int fixed_pos)
+static uint
+_gradient_pixel_fixed(const Ector_Renderer_Software_Gradient_Data *data, int fixed_pos)
{
- int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
- return data->colorTable[_gradient_clamp(data, ipos)];
+ int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
+ return data->color_table[_gradient_clamp(data, ipos)];
}
-static inline uint _gradient_pixel(const Ector_Renderer_Software_Gradient_Data *data, float pos)
- {
- int ipos = (int)(pos * (GRADIENT_STOPTABLE_SIZE - 1) + (float)(0.5));
- return data->colorTable[_gradient_clamp(data, ipos)];
- }
+static inline uint
+_gradient_pixel(const Ector_Renderer_Software_Gradient_Data *data, float pos)
+{
+ int ipos = (int)(pos * (GRADIENT_STOPTABLE_SIZE - 1) + (float)(0.5));
+ return data->color_table[_gradient_clamp(data, ipos)];
+}
-typedef double (*BLEND_FUNC)(double progress);
+#ifdef BUILD_SSE3
+#include <immintrin.h>
+
+#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
+typedef union{ __m128i v; int i[4];}vec4_i;
+typedef union{ __m128 v; float f[4];}vec4_f;
+
+#define FETCH_CLAMP_INIT_F \
+ __m128 v_min = _mm_set1_ps(0.0f); \
+ __m128 v_max = _mm_set1_ps((float)(GRADIENT_STOPTABLE_SIZE-1)); \
+ __m128 v_halff = _mm_set1_ps(0.5f); \
+ __m128i v_repeat_mask = _mm_set1_epi32(~((uint)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); \
+ __m128i v_reflect_mask = _mm_set1_epi32(~((uint)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); \
+ __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
+
+#define FETCH_CLAMP_REPEAT_F \
+ vec4_i index_vec; \
+ index_vec.v = _mm_and_si128(v_repeat_mask, _mm_cvttps_epi32(v_index));
+
+#define FETCH_CLAMP_REFLECT_F \
+ vec4_i index_vec; \
+ __m128i v_index_i = _mm_and_si128(v_reflect_mask, _mm_cvttps_epi32(v_index)); \
+ __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
+ index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
+
+#define FETCH_CLAMP_PAD_F \
+ vec4_i index_vec; \
+ index_vec.v = _mm_cvttps_epi32(_mm_min_ps(v_max, _mm_max_ps(v_min, v_index)));
+
-static double _ease_linear(double t)
+#define FETCH_EPILOGUE_CPY \
+ *buffer++ = g_data->color_table[index_vec.i[0]]; \
+ *buffer++ = g_data->color_table[index_vec.i[1]]; \
+ *buffer++ = g_data->color_table[index_vec.i[2]]; \
+ *buffer++ = g_data->color_table[index_vec.i[3]]; \
+}
+
+static void
+loop_break(unsigned int *buffer, int length, int *lprealign, int *lby4 , int *lremaining)
+{
+ int l1=0,l2=0,l3=0;
+ while ((int)buffer & 0xF)
+ buffer++ , l1++;
+
+ if(length <= l1)
+ l1 = length;
+ else
+ {
+ l3 = (length - l1)%4;
+ l2 = length - l1 - l3 ;
+ }
+ *lprealign = l1;
+ *lby4 = l2;
+ *lremaining = l3;
+}
+
+static void
+_radial_helper_sse3(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
+ float det, float delta_det, float delta_delta_det, float b, float delta_b)
{
- return t;
+ int lprealign, lby4, lremaining;
+ loop_break(buffer, length, &lprealign, &lby4, &lremaining);
+ // prealign loop
+ for (int i = 0 ; i < lprealign ; i++)
+ {
+ *buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ }
+
+ // lby4 16byte align loop
+ vec4_f det_vec;
+ vec4_f delta_det4_vec;
+ vec4_f b_vec;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ det_vec.f[i] = det;
+ delta_det4_vec.f[i] = 4 * delta_det;
+ b_vec.f[i] = b;
+
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ }
+
+ __m128 v_delta_delta_det16 = _mm_set1_ps(16 * delta_delta_det);
+ __m128 v_delta_delta_det6 = _mm_set1_ps(6 * delta_delta_det);
+ __m128 v_delta_b4 = _mm_set1_ps(4 * delta_b);
+
+#define FETCH_RADIAL_PROLOGUE \
+ for (int i = 0 ; i < lby4 ; i+=4) { \
+ __m128 v_index_local = _mm_sub_ps(_mm_sqrt_ps(det_vec.v), b_vec.v); \
+ __m128 v_index = _mm_add_ps(_mm_mul_ps(v_index_local, v_max), v_halff); \
+ det_vec.v = _mm_add_ps(_mm_add_ps(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \
+ delta_det4_vec.v = _mm_add_ps(delta_det4_vec.v, v_delta_delta_det16); \
+ b_vec.v = _mm_add_ps(b_vec.v, v_delta_b4);
+
+
+#define FETCH_RADIAL_LOOP(FETCH_CLAMP) \
+ FETCH_RADIAL_PROLOGUE \
+ FETCH_CLAMP \
+ FETCH_EPILOGUE_CPY
+
+ FETCH_CLAMP_INIT_F
+ switch (g_data->gd->s)
+ {
+ case EFL_GFX_GRADIENT_SPREAD_REPEAT:
+ FETCH_RADIAL_LOOP(FETCH_CLAMP_REPEAT_F)
+ break;
+ case EFL_GFX_GRADIENT_SPREAD_REFLECT:
+ FETCH_RADIAL_LOOP( FETCH_CLAMP_REFLECT_F)
+ break;
+ default:
+ FETCH_RADIAL_LOOP(FETCH_CLAMP_PAD_F)
+ break;
+ }
+
+ // remaining loop
+ for (int i = 0 ; i < lremaining ; i++)
+ *buffer++ = _gradient_pixel(g_data, sqrt(det_vec.f[i]) - b_vec.f[i]);
}
static void
-_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint *colorTable, int size)
+_linear_helper_sse3(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, int t, int inc)
{
- int pos = 0;
- Efl_Gfx_Gradient_Stop *curr, *next;
- assert(stop_count > 0);
+ int lprealign, lby4, lremaining;
+ loop_break(buffer, length, &lprealign, &lby4, &lremaining);
+ // prealign loop
+ for (int i = 0 ; i < lprealign ; i++)
+ {
+ *buffer++ = _gradient_pixel_fixed(g_data, t);
+ t += inc;
+ }
+
+ // lby4 16byte align loop
+ vec4_i t_vec;
+ for (int i = 0; i < 4; ++i)
+ {
+ t_vec.i[i] = t;
+ t += inc;
+ }
+
+ __m128i v_inc = _mm_set1_epi32(4 * inc);
+ __m128i v_fxtpt_size = _mm_set1_epi32(FIXPT_SIZE * 0.5);
+
+ __m128i v_min = _mm_set1_epi32(0);
+ __m128i v_max = _mm_set1_epi32((GRADIENT_STOPTABLE_SIZE-1));
+
+ __m128i v_repeat_mask = _mm_set1_epi32(~((uint)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT));
+ __m128i v_reflect_mask = _mm_set1_epi32(~((uint)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)));
+
+ __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
+
+#define FETCH_LINEAR_LOOP_PROLOGUE \
+ for (int i = 0 ; i < lby4 ; i+=4) { \
+ vec4_i index_vec;\
+ __m128i v_index;\
+ v_index = _mm_srai_epi32(_mm_add_epi32(t_vec.v, v_fxtpt_size), FIXPT_BITS); \
+ t_vec.v = _mm_add_epi32(t_vec.v, v_inc);
+
+#define FETCH_LINEAR_LOOP_CLAMP_REPEAT \
+ index_vec.v = _mm_and_si128(v_repeat_mask, v_index);
+
+#define FETCH_LINEAR_LOOP_CLAMP_REFLECT \
+ __m128i v_index_i = _mm_and_si128(v_reflect_mask, v_index); \
+ __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
+ index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
+
+#define FETCH_LINEAR_LOOP_CLAMP_PAD \
+ index_vec.v = _mm_min_epi16(v_max, _mm_max_epi16(v_min, v_index));
+
+
+
+#define FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP) \
+ FETCH_LINEAR_LOOP_PROLOGUE \
+ FETCH_LINEAR_LOOP_CLAMP \
+ FETCH_EPILOGUE_CPY
+
+ switch (g_data->gd->s)
+ {
+ case EFL_GFX_GRADIENT_SPREAD_REPEAT:
+ FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REPEAT)
+ break;
+ case EFL_GFX_GRADIENT_SPREAD_REFLECT:
+ FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REFLECT)
+ break;
+ default:
+ FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_PAD)
+ break;
+ }
+
+ // remaining loop
+ for (int i = 0 ; i < lremaining ; i++)
+ *buffer++ = _gradient_pixel_fixed(g_data, t_vec.i[i]);
+}
+
+#endif
- curr = gradient_stops;
- uint current_color = ECTOR_ARGB_JOIN(curr->a, curr->r, curr->g, curr->b);
- double incr = 1.0 / (double)size;
- double fpos = 1.5 * incr;
- current_color = _ector_premultiply(current_color);
+typedef double (*BLEND_FUNC)(double progress);
- colorTable[pos++] = current_color;
+static double
+_ease_linear(double t)
+{
+ return t;
+}
- while (fpos <= curr->offset) {
- colorTable[pos] = colorTable[pos - 1];
+static Eina_Bool
+_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint *color_table, int size)
+{
+ int pos = 0;
+ Eina_Bool alpha = EINA_FALSE;
+ Efl_Gfx_Gradient_Stop *curr, *next;
+ assert(stop_count > 0);
+
+ curr = gradient_stops;
+ if (curr->a != 255) alpha = EINA_TRUE;
+ uint current_color = ECTOR_ARGB_JOIN(curr->a, curr->r, curr->g, curr->b);
+ double incr = 1.0 / (double)size;
+ double fpos = 1.5 * incr;
+
+ color_table[pos++] = current_color;
+
+ while (fpos <= curr->offset)
+ {
+ color_table[pos] = color_table[pos - 1];
pos++;
fpos += incr;
- }
+ }
- for (int i = 0; i < stop_count - 1; ++i) {
+ for (int i = 0; i < stop_count - 1; ++i)
+ {
curr = (gradient_stops + i);
next = (gradient_stops + i + 1);
double delta = 1/(next->offset - curr->offset);
+ if (next->a != 255) alpha = EINA_TRUE;
uint next_color = ECTOR_ARGB_JOIN(next->a, next->r, next->g, next->b);
- next_color = _ector_premultiply(next_color);
BLEND_FUNC func = &_ease_linear;
- while (fpos < next->offset && pos < size) {
- double t = func((fpos - curr->offset) * delta);
- int dist = (int)(256 * t);
- int idist = 256 - dist;
- colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
- ++pos;
- fpos += incr;
- }
+ while (fpos < next->offset && pos < size)
+ {
+ double t = func((fpos - curr->offset) * delta);
+ int dist = (int)(256 * t);
+ int idist = 256 - dist;
+ color_table[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
+ ++pos;
+ fpos += incr;
+ }
current_color = next_color;
- }
+ }
- uint last_color = _ector_premultiply(current_color);
- for (;pos < size; ++pos)
- colorTable[pos] = last_color;
+ for (;pos < size; ++pos)
+ color_table[pos] = current_color;
- // Make sure the last color stop is represented at the end of the table
- colorTable[size-1] = last_color;
+ // Make sure the last color stop is represented at the end of the table
+ color_table[size-1] = current_color;
+ return alpha;
}
-void
+void
update_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
{
- if(gdata->colorTable) return;
+ if (gdata->color_table) return;
- gdata->colorTable = malloc(GRADIENT_STOPTABLE_SIZE * 4);
- _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count, gdata->colorTable, GRADIENT_STOPTABLE_SIZE);
+ gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
+ gdata->alpha = _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count, gdata->color_table, GRADIENT_STOPTABLE_SIZE);
}
-void
+void
destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
{
- if (gdata->colorTable) {
- free(gdata->colorTable);
- gdata->colorTable = NULL;
- }
+ if (gdata->color_table)
+ {
+ free(gdata->color_table);
+ gdata->color_table = NULL;
+ }
}
+inline static void
+_linear_helper_generic(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
+ int t_fixed, int inc_fixed)
+{
+ for (int i = 0 ; i < length ; i++)
+ {
+ *buffer++ = _gradient_pixel_fixed(g_data, t_fixed);
+ t_fixed += inc_fixed;
+ }
+}
void
fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
{
- Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
- float t, inc;
- float rx=0, ry=0;
- if (g_data->linear.l == 0) {
+ Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
+ float t, inc;
+ float rx=0, ry=0;
+
+ if (g_data->linear.l == 0)
+ {
t = inc = 0;
- } else {
+ }
+ else
+ {
rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
t = g_data->linear.dx*rx + g_data->linear.dy*ry + g_data->linear.off;
t *= (GRADIENT_STOPTABLE_SIZE - 1);
inc *= (GRADIENT_STOPTABLE_SIZE - 1);
- }
-
- uint *end = buffer + length;
- if (inc > (float)(-1e-5) && inc < (float)(1e-5)) {
- _ector_memfill(buffer, _gradient_pixel_fixed(g_data, (int)(t * FIXPT_SIZE)), length);
- } else {
- if (t + inc*length < (float)(INT_MAX >> (FIXPT_BITS + 1)) &&
- t+inc*length > (float)(INT_MIN >> (FIXPT_BITS + 1))) {
- // we can use fixed point math
- int t_fixed = (int)(t * FIXPT_SIZE);
- int inc_fixed = (int)(inc * FIXPT_SIZE);
- // #ifdef BUILD_SSE3
- // if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3)) {
- // _fetch_linear_sse3(buffer, length, g_data, t_fixed, inc_fixed);
- // } else
- // #endif
- {
- while (buffer < end) {
- *buffer++ = _gradient_pixel_fixed(g_data, t_fixed);
- t_fixed += inc_fixed;
+ }
+
+ uint *end = buffer + length;
+ if (inc > (float)(-1e-5) && inc < (float)(1e-5))
+ {
+ _ector_memfill(buffer, length, _gradient_pixel_fixed(g_data, (int)(t * FIXPT_SIZE)));
+ }
+ else
+ {
+ if (t + inc*length < (float)(INT_MAX >> (FIXPT_BITS + 1)) &&
+ t+inc*length > (float)(INT_MIN >> (FIXPT_BITS + 1)))
+ {
+ // we can use fixed point math
+ int t_fixed = (int)(t * FIXPT_SIZE);
+ int inc_fixed = (int)(inc * FIXPT_SIZE);
+ linear_helper(buffer, length, g_data, t_fixed, inc_fixed);
+ }
+ else
+ {
+ // we have to fall back to float math
+ while (buffer < end)
+ {
+ *buffer++ = _gradient_pixel(g_data, t/GRADIENT_STOPTABLE_SIZE);
+ t += inc;
}
- }
- } else {
- // we have to fall back to float math
- while (buffer < end) {
- *buffer++ = _gradient_pixel(g_data, t/GRADIENT_STOPTABLE_SIZE);
- t += inc;
- }
- }
- }
+ }
+ }
}
-static void
+
+inline static void
_radial_helper_generic(uint *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, float det,
- float delta_det, float delta_delta_det, float b, float delta_b)
+ float delta_det, float delta_delta_det, float b, float delta_b)
{
- for (int i = 0 ; i < length ; i++) {
+ for (int i = 0 ; i < length ; i++)
+ {
*buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
det += delta_det;
delta_det += delta_delta_det;
b += delta_b;
- }
+ }
}
void
fetch_radial_gradient(uint *buffer, Span_Data *data, int y, int x, int length)
{
- Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
- // avoid division by zero
- if (abs(g_data->radial.a) <= 0.00001f) {
- _ector_memfill(buffer, 0, length);
+ Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
+
+ // avoid division by zero
+ if (abs(g_data->radial.a) <= 0.00001f)
+ {
+ _ector_memfill(buffer, length, 0);
return;
- }
+ }
- float rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
- float ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
+ float rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
+ float ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
- rx -= g_data->radial.fx;
- ry -= g_data->radial.fy;
+ rx -= g_data->radial.fx;
+ ry -= g_data->radial.fy;
- float inv_a = 1 / (float)(2 * g_data->radial.a);
+ float inv_a = 1 / (float)(2 * g_data->radial.a);
- const float delta_rx = data->inv.xx;
- const float delta_ry = data->inv.yx;
+ const float delta_rx = data->inv.xx;
+ const float delta_ry = data->inv.yx;
- float b = 2*(g_data->radial.dr*g_data->radial.fradius + rx * g_data->radial.dx + ry * g_data->radial.dy);
- float delta_b = 2*(delta_rx * g_data->radial.dx + delta_ry * g_data->radial.dy);
- const float b_delta_b = 2 * b * delta_b;
- const float delta_b_delta_b = 2 * delta_b * delta_b;
+ float b = 2*(g_data->radial.dr*g_data->radial.fradius + rx * g_data->radial.dx + ry * g_data->radial.dy);
+ float delta_b = 2*(delta_rx * g_data->radial.dx + delta_ry * g_data->radial.dy);
+ const float b_delta_b = 2 * b * delta_b;
+ const float delta_b_delta_b = 2 * delta_b * delta_b;
- const float bb = b * b;
- const float delta_bb = delta_b * delta_b;
- b *= inv_a;
- delta_b *= inv_a;
+ const float bb = b * b;
+ const float delta_bb = delta_b * delta_b;
+ b *= inv_a;
+ delta_b *= inv_a;
- const float rxrxryry = rx * rx + ry * ry;
- const float delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
- const float rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
- const float delta_rx_plus_ry = 2 * delta_rxrxryry;
+ const float rxrxryry = rx * rx + ry * ry;
+ const float delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
+ const float rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
+ const float delta_rx_plus_ry = 2 * delta_rxrxryry;
- inv_a *= inv_a;
+ inv_a *= inv_a;
- float det = (bb - 4 * g_data->radial.a * (g_data->radial.sqrfr - rxrxryry)) * inv_a;
- float delta_det = (b_delta_b + delta_bb + 4 * g_data->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
- const float delta_delta_det = (delta_b_delta_b + 4 * g_data->radial.a * delta_rx_plus_ry) * inv_a;
+ float det = (bb - 4 * g_data->radial.a * (g_data->radial.sqrfr - rxrxryry)) * inv_a;
+ float delta_det = (b_delta_b + delta_bb + 4 * g_data->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
+ const float delta_delta_det = (delta_b_delta_b + 4 * g_data->radial.a * delta_rx_plus_ry) * inv_a;
- // #ifdef BUILD_SSE3
- // if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3)) {
- // _radial_helper_sse3(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b);
- // } else
- // #endif
- { // generic fallback
- _radial_helper_generic(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b);
- }
+ radial_helper(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b);
+}
+
+void
+init_drawhelper_gradient()
+{
+ radial_helper = _radial_helper_generic;
+ linear_helper = _linear_helper_generic;
+ #ifdef BUILD_SSE3
+ if (eina_cpu_features_get() & EINA_CPU_SSE3)
+ {
+ radial_helper = _radial_helper_sse3;
+ linear_helper = _linear_helper_sse3;
+ }
+ #endif
}
#ifndef ECTOR_SOFTWARE_PRIVATE_H_
# define ECTOR_SOFTWARE_PRIVATE_H_
-
#include "sw_ft_raster.h"
#include "sw_ft_stroker.h"
#ifndef DATA32
typedef unsigned int DATA32;
-#endif
+#endif
+
#ifndef uint
typedef unsigned int uint;
#endif
-
typedef struct _Ector_Software_Surface_Data Ector_Software_Surface_Data;
-#define CHECK_SOFTWARE(Parent) (!(Parent && Parent->software))
-
-
// Gradient related structure
+typedef struct _Software_Gradient_Linear_Data
+{
+ float x1, y1, x2, y2;
+ float dx, dy, l, off;
+} Software_Gradient_Linear_Data;
- typedef struct _Software_Gradient_Linear_Data
- {
- float x1, y1, x2, y2;
- float dx, dy, l, off;
- }Software_Gradient_Linear_Data;
-
-
- typedef struct _Software_Gradient_Radial_Data
- {
- float cx, cy, fx, fy, cradius, fradius;
- float dx, dy, dr, sqrfr, a, inv2a;
- Eina_Bool extended;
- }Software_Gradient_Radial_Data;
+typedef struct _Software_Gradient_Radial_Data
+{
+ float cx, cy, fx, fy, cradius, fradius;
+ float dx, dy, dr, sqrfr, a, inv2a;
+ Eina_Bool extended;
+} Software_Gradient_Radial_Data;
typedef struct _Ector_Renderer_Software_Gradient_Data
{
- Ector_Software_Surface_Data *surface;
- Ector_Renderer_Generic_Gradient_Data *gd;
- union {
- Ector_Renderer_Generic_Gradient_Linear_Data *gld;
- Ector_Renderer_Generic_Gradient_Radial_Data *grd;
- };
- union {
- Software_Gradient_Linear_Data linear;
- Software_Gradient_Radial_Data radial;
- };
- uint* colorTable;
-}Ector_Renderer_Software_Gradient_Data;
-
+ Ector_Software_Surface_Data *surface;
+ Ector_Renderer_Generic_Gradient_Data *gd;
+ union {
+ Ector_Renderer_Generic_Gradient_Linear_Data *gld;
+ Ector_Renderer_Generic_Gradient_Radial_Data *grd;
+ };
+ union {
+ Software_Gradient_Linear_Data linear;
+ Software_Gradient_Radial_Data radial;
+ };
+ Eina_Bool alpha;
+ uint* color_table;
+} Ector_Renderer_Software_Gradient_Data;
// Rasterizer related structure
-
typedef struct _Raster_Buffer
{
- int width;
- int height;
- DATA32 *buffer;
-
-}Raster_Buffer;
+ int width;
+ int height;
+ DATA32 *buffer;
+} Raster_Buffer;
typedef struct _Shape_Rle_Data
{
- unsigned short alloc;
- unsigned short size;
- SW_FT_Span *spans;// array of Scanlines.
-}Shape_Rle_Data;
+ unsigned short alloc;
+ unsigned short size;
+ SW_FT_Span *spans;// array of Scanlines.
+} Shape_Rle_Data;
typedef struct _Clip_Data
{
- Eina_Array *clips; //Eina_Rectangle
- Shape_Rle_Data *path;
- unsigned int enabled : 1;
- unsigned int hasRectClip : 1;
- unsigned int hasPathClip : 1;
-}Clip_Data;
+ Eina_Array *clips; //Eina_Rectangle
+ Shape_Rle_Data *path;
+ unsigned int enabled : 1;
+ unsigned int has_rect_clip : 1;
+ unsigned int has_path_clip : 1;
+} Clip_Data;
typedef enum _Span_Data_Type {
- None,
- Solid,
- LinearGradient,
- RadialGradient,
- Image
-}Span_Data_Type;
+ None,
+ Solid,
+ LinearGradient,
+ RadialGradient,
+ Image
+} Span_Data_Type;
typedef struct _Span_Data
{
- Raster_Buffer raster_buffer;
-
- SW_FT_SpanFunc blend;
- SW_FT_SpanFunc unclipped_blend;
-
- int offx, offy;
- Clip_Data clip;
- Eina_Matrix3 inv;
- Span_Data_Type type;
- Eina_Bool fast_matrix ;
- DATA32 mul_col;
- Ector_Rop op;
- union {
- DATA32 color;
- Ector_Renderer_Software_Gradient_Data *gradient;
- //ImageData texture;
- };
-}Span_Data;
+ Raster_Buffer raster_buffer;
+
+ SW_FT_SpanFunc blend;
+ SW_FT_SpanFunc unclipped_blend;
+
+ int offx, offy;
+ Clip_Data clip;
+ Eina_Matrix3 inv;
+ Span_Data_Type type;
+ Eina_Bool fast_matrix ;
+ DATA32 mul_col;
+ Ector_Rop op;
+ union {
+ DATA32 color;
+ Ector_Renderer_Software_Gradient_Data *gradient;
+ //ImageData texture;
+ };
+} Span_Data;
typedef struct _Software_Rasterizer
{
- SW_FT_Raster raster;
- SW_FT_Stroker stroker;
+ SW_FT_Raster raster;
+ SW_FT_Stroker stroker;
- Span_Data fillData;
- Eina_Matrix3 *transform;
- Eina_Rectangle systemClip;
-
-}Software_Rasterizer;
+ Span_Data fill_data;
+ Eina_Matrix3 *transform;
+ Eina_Rectangle system_clip;
+} Software_Rasterizer;
struct _Ector_Software_Surface_Data
{
Software_Rasterizer *software;
+ int x;
+ int y;
};
-
-
-
void ector_software_rasterizer_init(Software_Rasterizer *rasterizer);
void ector_software_rasterizer_done(Software_Rasterizer *rasterizer);
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Ector.h>
#include <software/Ector_Software.h>
+
#include "ector_private.h"
#include "ector_software_private.h"
-#include "ector_blend_private.h"
-static void _blend_color_argb(int count, const SW_FT_Span *spans, void *userData)
+#include "ector_drawhelper_private.h"
+
+static void
+_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
{
- Span_Data *data = (Span_Data *)(userData);
-
- // multiply the color with mul_col if any
- uint color = ECTOR_MUL4_SYM(data->color, data->mul_col);
-
- Eina_Bool solidSource = ((color >> 24) == 255);
-
- // move to the offset location
- uint *buffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx);
+ RGBA_Comp_Func_Solid comp_func;
+ Span_Data *data = (Span_Data *)(user_data);
-
- if (solidSource) {
- while (count--) {
- uint *target = buffer + (data->raster_buffer.width * spans->y + spans->x);
- if (spans->coverage == 255) {
- _ector_memfill(target, color, spans->len);
- } else {
- uint c = ECTOR_MUL_256(color, spans->coverage);
- int ialpha = 255 - spans->coverage;
- for (int i = 0; i < spans->len; ++i)
- target[i] = c + ECTOR_MUL_256(target[i], ialpha);
- }
- ++spans;
- }
- return;
- }
+ // multiply the color with mul_col if any
+ uint color = ECTOR_MUL4_SYM(data->color, data->mul_col);
+ comp_func = ector_comp_func_solid_span_get(data->op, color);
- while (count--) {
+ // move to the offset location
+ uint *buffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx);
+
+ while (count--)
+ {
uint *target = buffer + (data->raster_buffer.width * spans->y + spans->x);
- uint c = ECTOR_MUL_256(color, spans->coverage);
- int ialpha = (~c) >> 24;
- for (int i = 0; i < spans->len; ++i)
- target[i] = c + ECTOR_MUL_256(target[i], ialpha);
+ comp_func(target, spans->len, color, spans->coverage);
++spans;
- }
+ }
}
int buffer_size = 2048;
typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length);
+
static void
-_blend_gradient(int count, const SW_FT_Span *spans, void *userData)
+_blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
{
- Span_Data *data = (Span_Data *)(userData);
- src_fetch fetchfunc = NULL;
- if(data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
- if(data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
+ RGBA_Comp_Func comp_func;
+ Span_Data *data = (Span_Data *)(user_data);
+ src_fetch fetchfunc = NULL;
+
+ //@TODO, Get the proper composition function using ,color, ECTOR_OP etc.
+ if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
+ if (data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
+
+ comp_func = ector_comp_func_span_get(data->op, data->mul_col, data->gradient->alpha);
+
+ unsigned int buffer[buffer_size];
- unsigned int buffer[buffer_size];
- // move to the offset location
- unsigned int *destbuffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx);
+ // move to the offset location
+ unsigned int *destbuffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx);
- while (count--) {
+ while (count--)
+ {
unsigned int *target = destbuffer + (data->raster_buffer.width * spans->y + spans->x);
int length = spans->len;
- while (length) {
- int l = MIN(length, buffer_size);
- fetchfunc(buffer, data, spans->y, spans->x, l);
- if (data->mul_col == 0xffffffff)
- _ector_comp_func_source_over(target, buffer, l, spans->coverage); // TODO use proper composition func
- else
- _ector_comp_func_source_over_mul_c(target, buffer, data->mul_col, l, spans->coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
+ while (length)
+ {
+ int l = MIN(length, buffer_size);
+ fetchfunc(buffer, data, spans->y, spans->x, l);
+ comp_func(target, buffer, l, data->mul_col, spans->coverage);
+ target += l;
+ length -= l;
+ }
+ ++spans;
+ }
}
*/
static const
SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip, const SW_FT_Span *spans, const SW_FT_Span *end,
- SW_FT_Span **outSpans, int available)
+ SW_FT_Span **out_spans, int available)
+{
+ SW_FT_Span *out = *out_spans;
+ const short minx = clip->x;
+ const short miny = clip->y;
+ const short maxx = minx + clip->w - 1;
+ const short maxy = miny + clip->h - 1;
+
+ while (available && spans < end )
+ {
+ if (spans->y > maxy)
+ {
+ spans = end;// update spans so that we can breakout
+ break;
+ }
+ if (spans->y < miny
+ || spans->x > maxx
+ || spans->x + spans->len <= minx)
+ {
+ ++spans;
+ continue;
+ }
+ if (spans->x < minx)
+ {
+ out->len = MIN(spans->len - (minx - spans->x), maxx - minx + 1);
+ out->x = minx;
+ }
+ else
+ {
+ out->x = spans->x;
+ out->len = MIN(spans->len, (maxx - spans->x + 1));
+ }
+ if (out->len != 0)
+ {
+ out->y = spans->y;
+ out->coverage = spans->coverage;
+ ++out;
+ }
+
+ ++spans;
+ --available;
+ }
+
+ *out_spans = out;
+
+ return spans;
+}
+
+static inline int
+_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
+
+static const
+SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip, int *currentClip,
+ const SW_FT_Span *spans, const SW_FT_Span *end,
+ SW_FT_Span **out_spans, int available)
{
- SW_FT_Span *out = *outSpans;
- const short minx = clip->x;
- const short miny = clip->y;
- const short maxx = minx + clip->w - 1;
- const short maxy = miny + clip->h - 1;
+ SW_FT_Span *out = *out_spans;
+
+ const SW_FT_Span *clipSpans = clip->spans + *currentClip;
+ const SW_FT_Span *clipEnd = clip->spans + clip->size;
while (available && spans < end ) {
- if (spans->y > maxy) {
- spans = end;// update spans so that we can breakout
+ if (clipSpans >= clipEnd) {
+ spans = end;
break;
}
- if (spans->y < miny
- || spans->x > maxx
- || spans->x + spans->len <= minx) {
+ if (clipSpans->y > spans->y) {
++spans;
continue;
}
- if (spans->x < minx) {
- out->len = MIN(spans->len - (minx - spans->x), maxx - minx + 1);
- out->x = minx;
- } else {
- out->x = spans->x;
- out->len = MIN(spans->len, (maxx - spans->x + 1));
+ if (spans->y != clipSpans->y) {
+ ++clipSpans;
+ continue;
}
- if (out->len != 0) {
+ //assert(spans->y == clipSpans->y);
+
+ int sx1 = spans->x;
+ int sx2 = sx1 + spans->len;
+ int cx1 = clipSpans->x;
+ int cx2 = cx1 + clipSpans->len;
+
+ if (cx1 < sx1 && cx2 < sx1) {
+ ++clipSpans;
+ continue;
+ } else if (sx1 < cx1 && sx2 < cx1) {
+ ++spans;
+ continue;
+ }
+ int x = MAX(sx1, cx1);
+ int len = MIN(sx2, cx2) - x;
+ if (len) {
+ out->x = MAX(sx1, cx1);
+ out->len = MIN(sx2, cx2) - out->x;
out->y = spans->y;
- out->coverage = spans->coverage;
+ out->coverage = _div_255(spans->coverage * clipSpans->coverage);
++out;
+ --available;
+ }
+ if (sx2 < cx2) {
+ ++spans;
+ } else {
+ ++clipSpans;
}
-
- ++spans;
- --available;
}
- *outSpans = out;
-
+ *out_spans = out;
+ *currentClip = clipSpans - clip->spans;
return spans;
}
static void
-_span_fill_clipRect(int spanCount, const SW_FT_Span *spans, void *userData)
+_span_fill_clipRect(int span_count, const SW_FT_Span *spans, void *user_data)
{
const int NSPANS = 256;
int clip_count, i;
SW_FT_Span cspans[NSPANS];
- Span_Data *fillData = (Span_Data *) userData;
- Clip_Data clip = fillData->clip;
+ Span_Data *fill_data = (Span_Data *) user_data;
+ Clip_Data clip = fill_data->clip;
+
clip_count = eina_array_count(clip.clips);
- for(i = 0; i < clip_count ; i ++)
+ for (i = 0; i < clip_count ; i ++)
{
Eina_Rectangle *rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i);
Eina_Rectangle tmpRect;
+
// invert transform the offset
- tmpRect.x = rect->x - fillData->offx;
- tmpRect.y = rect->y - fillData->offy;
+ tmpRect.x = rect->x - fill_data->offx;
+ tmpRect.y = rect->y - fill_data->offy;
tmpRect.w = rect->w;
tmpRect.h = rect->h;
- //printf("Clip after Offset : %d , %d ,%d , %d\n",tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
- //printf("Offset = %d , %d \n", fillData->offx, fillData->offy);
- const SW_FT_Span *end = spans + spanCount;
- while (spans < end) {
- SW_FT_Span *clipped = cspans;
- spans = _intersect_spans_rect(&tmpRect,spans, end, &clipped, NSPANS);
- if (clipped - cspans)
- fillData->unclipped_blend(clipped - cspans, cspans, fillData);
- }
- }
+ const SW_FT_Span *end = spans + span_count;
+
+ while (spans < end)
+ {
+ SW_FT_Span *clipped = cspans;
+ spans = _intersect_spans_rect(&tmpRect,spans, end, &clipped, NSPANS);
+ if (clipped - cspans)
+ fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
+ }
+ }
+}
+
+static void
+_span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
+{
+ const int NSPANS = 256;
+ int current_clip = 0;
+ SW_FT_Span cspans[NSPANS];
+ Span_Data *fill_data = (Span_Data *) user_data;
+ Clip_Data clip = fill_data->clip;
+
+ //TODO take clip path offset into account.
+
+ const SW_FT_Span *end = spans + span_count;
+ while (spans < end)
+ {
+ SW_FT_Span *clipped = cspans;
+ spans = _intersect_spans_region(clip.path, ¤t_clip, spans, end, &clipped, NSPANS);
+ if (clipped - cspans)
+ fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
+ }
}
static void
_adjust_span_fill_methods(Span_Data *spdata)
{
- switch(spdata->type) {
- case None:
- spdata->unclipped_blend = 0;
- break;
- case Solid:
- spdata->unclipped_blend = &_blend_color_argb;
- break;
- case LinearGradient:
- case RadialGradient:
- spdata->unclipped_blend = &_blend_gradient;
- break;
- case Image:
- spdata->unclipped_blend = 0;//&_blend_image;
- break;
- }
- // setup clipping
- if (!spdata->unclipped_blend) {
+ switch(spdata->type)
+ {
+ case None:
+ spdata->unclipped_blend = 0;
+ break;
+ case Solid:
+ spdata->unclipped_blend = &_blend_color_argb;
+ break;
+ case LinearGradient:
+ case RadialGradient:
+ spdata->unclipped_blend = &_blend_gradient;
+ break;
+ case Image:
+ spdata->unclipped_blend = 0;//&_blend_image;
+ break;
+ }
+
+ // setup clipping
+ if (!spdata->unclipped_blend)
+ {
spdata->blend = 0;
- } else if (!spdata->clip.enabled) {
+ }
+ else if (!spdata->clip.enabled)
+ {
spdata->blend = spdata->unclipped_blend;
- } else if (spdata->clip.hasRectClip) {
+ }
+ else if (spdata->clip.has_rect_clip)
+ {
spdata->blend = &_span_fill_clipRect;
- } else {
- spdata->blend = &_span_fill_clipRect; //TODO change when do path clipping
- }
+ }
+ else
+ {
+ spdata->blend = &_span_fill_clipPath;
+ }
}
void ector_software_rasterizer_init(Software_Rasterizer *rasterizer)
{
- // initialize the rasterizer and stroker
- unsigned char* renderPool = (unsigned char*) malloc(1024 * 100);
- sw_ft_grays_raster.raster_new(&rasterizer->raster);
- sw_ft_grays_raster.raster_reset(rasterizer->raster, renderPool, 1024*100);
-
- SW_FT_Stroker_New(&rasterizer->stroker);
- SW_FT_Stroker_Set(rasterizer->stroker, 1<<6,SW_FT_STROKER_LINECAP_BUTT,SW_FT_STROKER_LINEJOIN_MITER,0);
-
- //initialize the span data.
- rasterizer->fillData.raster_buffer.buffer = NULL;
- rasterizer->fillData.clip.enabled = EINA_FALSE;
- rasterizer->fillData.unclipped_blend = 0;
- rasterizer->fillData.blend = 0;
+ // initialize the rasterizer and stroker
+ unsigned char* renderPool = (unsigned char*) malloc(1024 * 100);
+ sw_ft_grays_raster.raster_new(&rasterizer->raster);
+ sw_ft_grays_raster.raster_reset(rasterizer->raster, renderPool, 1024*100);
+
+ SW_FT_Stroker_New(&rasterizer->stroker);
+ SW_FT_Stroker_Set(rasterizer->stroker, 1<<6,SW_FT_STROKER_LINECAP_BUTT,SW_FT_STROKER_LINEJOIN_MITER,0);
+
+ //initialize the span data.
+ rasterizer->fill_data.raster_buffer.buffer = NULL;
+ rasterizer->fill_data.clip.enabled = EINA_FALSE;
+ rasterizer->fill_data.unclipped_blend = 0;
+ rasterizer->fill_data.blend = 0;
+ init_draw_helper();
}
void ector_software_rasterizer_done(Software_Rasterizer *rasterizer)
{
- sw_ft_grays_raster.raster_done(rasterizer->raster);
- SW_FT_Stroker_Done(rasterizer->stroker);
- //TODO free the pool memory
+ sw_ft_grays_raster.raster_done(rasterizer->raster);
+ SW_FT_Stroker_Done(rasterizer->stroker);
+ //TODO free the pool memory
}
void ector_software_rasterizer_stroke_set(Software_Rasterizer *rasterizer, double width,
Efl_Gfx_Cap cap_style, Efl_Gfx_Join join_style)
{
- SW_FT_Stroker_LineCap cap;
- SW_FT_Stroker_LineJoin join;
-
- switch (cap_style) {
- case EFL_GFX_CAP_SQUARE:
- cap = SW_FT_STROKER_LINECAP_SQUARE;
- break;
- case EFL_GFX_CAP_ROUND:
- cap = SW_FT_STROKER_LINECAP_ROUND;
- break;
- default:
- cap = SW_FT_STROKER_LINECAP_BUTT;
- break;
- }
- switch (join_style) {
- case EFL_GFX_JOIN_BEVEL:
- join = SW_FT_STROKER_LINEJOIN_BEVEL;
- break;
- case EFL_GFX_JOIN_ROUND:
- join = SW_FT_STROKER_LINEJOIN_ROUND;
- break;
- default:
- join = SW_FT_STROKER_LINEJOIN_MITER;
- break;
- }
- int stroke_width = (int)(width * 64);
- SW_FT_Stroker_Set(rasterizer->stroker, stroke_width, cap, join, 0);
+ SW_FT_Stroker_LineCap cap;
+ SW_FT_Stroker_LineJoin join;
+
+ switch (cap_style)
+ {
+ case EFL_GFX_CAP_SQUARE:
+ cap = SW_FT_STROKER_LINECAP_SQUARE;
+ break;
+ case EFL_GFX_CAP_ROUND:
+ cap = SW_FT_STROKER_LINECAP_ROUND;
+ break;
+ default:
+ cap = SW_FT_STROKER_LINECAP_BUTT;
+ break;
+ }
+
+ switch (join_style)
+ {
+ case EFL_GFX_JOIN_BEVEL:
+ join = SW_FT_STROKER_LINEJOIN_BEVEL;
+ break;
+ case EFL_GFX_JOIN_ROUND:
+ join = SW_FT_STROKER_LINEJOIN_ROUND;
+ break;
+ default:
+ join = SW_FT_STROKER_LINEJOIN_MITER;
+ break;
+ }
+
+ int stroke_width = (int)(width * 64);
+ SW_FT_Stroker_Set(rasterizer->stroker, stroke_width, cap, join, 0);
}
static void
_rle_generation_cb( int count, const SW_FT_Span* spans,void *user)
{
- Shape_Rle_Data *rle = (Shape_Rle_Data *) user;
- int newsize = rle->size + count;
-
- // allocate enough memory for new spans
- // alloc is required to prevent free and reallocation
- // when the rle needs to be regenerated because of attribute change.
- if(rle->alloc < newsize) {
+ Shape_Rle_Data *rle = (Shape_Rle_Data *) user;
+ int newsize = rle->size + count;
+
+ // allocate enough memory for new spans
+ // alloc is required to prevent free and reallocation
+ // when the rle needs to be regenerated because of attribute change.
+ if(rle->alloc < newsize)
+ {
rle->spans = (SW_FT_Span *) realloc(rle->spans, newsize * sizeof(SW_FT_Span));
rle->alloc = newsize;
- }
+ }
- // copy the new spans to the allocated memory
- SW_FT_Span *lastspan = (rle->spans + rle->size);
- memcpy(lastspan,spans, count * sizeof(SW_FT_Span));
+ // copy the new spans to the allocated memory
+ SW_FT_Span *lastspan = (rle->spans + rle->size);
+ memcpy(lastspan,spans, count * sizeof(SW_FT_Span));
- // update the size
- rle->size = newsize;
+ // update the size
+ rle->size = newsize;
}
Shape_Rle_Data *
ector_software_rasterizer_generate_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline)
{
- Shape_Rle_Data *rle_data = (Shape_Rle_Data *) calloc(1, sizeof(Shape_Rle_Data));
- SW_FT_Raster_Params params;
- params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ;
- params.gray_spans = &_rle_generation_cb;
- params.user = rle_data;
- params.source = outline;
+ Shape_Rle_Data *rle_data = (Shape_Rle_Data *) calloc(1, sizeof(Shape_Rle_Data));
+ SW_FT_Raster_Params params;
+
+ params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ;
+ params.gray_spans = &_rle_generation_cb;
+ params.user = rle_data;
+ params.source = outline;
- sw_ft_grays_raster.raster_render(rasterizer->raster, ¶ms);
+ sw_ft_grays_raster.raster_render(rasterizer->raster, ¶ms);
- return rle_data;
+ return rle_data;
}
Shape_Rle_Data *
ector_software_rasterizer_generate_stroke_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath)
{
- uint points,contors;
-
- SW_FT_Stroker_ParseOutline(rasterizer->stroker, outline, !closePath);
- SW_FT_Stroker_GetCounts(rasterizer->stroker,&points, &contors);
+ uint points,contors;
- SW_FT_Outline strokeOutline = {0};
- strokeOutline.points = (SW_FT_Vector *) calloc(points, sizeof(SW_FT_Vector));
- strokeOutline.tags = (char *) calloc(points, sizeof(char));
- strokeOutline.contours = (short *) calloc(contors, sizeof(short));
+ SW_FT_Stroker_ParseOutline(rasterizer->stroker, outline, !closePath);
+ SW_FT_Stroker_GetCounts(rasterizer->stroker,&points, &contors);
- SW_FT_Stroker_Export(rasterizer->stroker, &strokeOutline);
+ SW_FT_Outline strokeOutline = {0};
+ strokeOutline.points = (SW_FT_Vector *) calloc(points, sizeof(SW_FT_Vector));
+ strokeOutline.tags = (char *) calloc(points, sizeof(char));
+ strokeOutline.contours = (short *) calloc(contors, sizeof(short));
- Shape_Rle_Data *rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline);
+ SW_FT_Stroker_Export(rasterizer->stroker, &strokeOutline);
- // cleanup the outline data.
- free(strokeOutline.points);
- free(strokeOutline.tags);
- free(strokeOutline.contours);
+ Shape_Rle_Data *rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline);
- return rle_data;
+ // cleanup the outline data.
+ free(strokeOutline.points);
+ free(strokeOutline.tags);
+ free(strokeOutline.contours);
+
+ return rle_data;
}
void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle)
{
- if (rle) {
+ if (rle)
+ {
if (rle->spans)
- free(rle->spans);
+ free(rle->spans);
free(rle);
- }
+ }
}
static
void _setup_span_fill_matrix(Software_Rasterizer *rasterizer)
{
- if (rasterizer->transform)
- {
- eina_matrix3_inverse(rasterizer->transform, &rasterizer->fillData.inv);
- } else {
- eina_matrix3_identity(&rasterizer->fillData.inv);
- eina_matrix3_identity(&rasterizer->fillData.inv);
- }
+ if (rasterizer->transform)
+ {
+ eina_matrix3_inverse(rasterizer->transform, &rasterizer->fill_data.inv);
+ }
+ else
+ {
+ eina_matrix3_identity(&rasterizer->fill_data.inv);
+ eina_matrix3_identity(&rasterizer->fill_data.inv);
+ }
}
void ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Eina_Matrix3 *t)
{
- rasterizer->transform = t;
+ rasterizer->transform = t;
}
void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips)
{
- if (clips) {
- rasterizer->fillData.clip.clips = clips;
- rasterizer->fillData.clip.hasRectClip = EINA_TRUE;
- rasterizer->fillData.clip.enabled = EINA_TRUE;
- } else {
- rasterizer->fillData.clip.clips = NULL;
- rasterizer->fillData.clip.hasRectClip = EINA_FALSE;
- rasterizer->fillData.clip.enabled = EINA_FALSE;
- }
+ if (clips)
+ {
+ rasterizer->fill_data.clip.clips = clips;
+ rasterizer->fill_data.clip.has_rect_clip = EINA_TRUE;
+ rasterizer->fill_data.clip.enabled = EINA_TRUE;
+ }
+ else
+ {
+ rasterizer->fill_data.clip.clips = NULL;
+ rasterizer->fill_data.clip.has_rect_clip = EINA_FALSE;
+ rasterizer->fill_data.clip.enabled = EINA_FALSE;
+ }
}
void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip)
{
- rasterizer->fillData.clip.path = clip;
- rasterizer->fillData.clip.hasPathClip = EINA_TRUE;
- rasterizer->fillData.clip.enabled = EINA_TRUE;
+ rasterizer->fill_data.clip.path = clip;
+ rasterizer->fill_data.clip.has_path_clip = EINA_TRUE;
+ rasterizer->fill_data.clip.enabled = EINA_TRUE;
}
void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a)
{
- uint color = ECTOR_ARGB_JOIN(a, r, g, b);
- rasterizer->fillData.color = _ector_premultiply(color);
- rasterizer->fillData.type = Solid;
+ rasterizer->fill_data.color = ECTOR_ARGB_JOIN(a, r, g, b);
+ rasterizer->fill_data.type = Solid;
}
void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear)
{
- rasterizer->fillData.gradient = linear;
- rasterizer->fillData.type = LinearGradient;
+ rasterizer->fill_data.gradient = linear;
+ rasterizer->fill_data.type = LinearGradient;
}
void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial)
{
- rasterizer->fillData.gradient = radial;
- rasterizer->fillData.type = RadialGradient;
+ rasterizer->fill_data.gradient = radial;
+ rasterizer->fill_data.type = RadialGradient;
}
-void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
+void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
int x, int y, uint mul_col, Ector_Rop op, Shape_Rle_Data* rle)
{
- rasterizer->fillData.offx = x;
- rasterizer->fillData.offy = y;
- rasterizer->fillData.mul_col = mul_col;
- rasterizer->fillData.op = op;
+ // check for NULL rle data
+ if (!rle) return;
- _setup_span_fill_matrix(rasterizer);
- _adjust_span_fill_methods(&rasterizer->fillData);
-
- if(rasterizer->fillData.blend)
- rasterizer->fillData.blend(rle->size, rle->spans, &rasterizer->fillData);
-}
+ rasterizer->fill_data.offx = x;
+ rasterizer->fill_data.offy = y;
+ rasterizer->fill_data.mul_col = mul_col;
+ rasterizer->fill_data.op = op;
+ _setup_span_fill_matrix(rasterizer);
+ _adjust_span_fill_methods(&rasterizer->fill_data);
+ if(rasterizer->fill_data.blend)
+ rasterizer->fill_data.blend(rle->size, rle->spans, &rasterizer->fill_data);
+}
static unsigned int _software_count = 0;
+typedef struct _Ector_Renderer_Software_Base_Data Ector_Renderer_Software_Base_Data;
+struct _Ector_Renderer_Software_Base_Data
+{
+};
static Ector_Renderer *
_ector_software_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
- Ector_Software_Surface_Data *pd EINA_UNUSED,
- const Eo_Class *type)
+ Ector_Software_Surface_Data *pd EINA_UNUSED,
+ const Eo_Class *type)
{
- if (type == ECTOR_RENDERER_GENERIC_SHAPE_CLASS)
+ if (type == ECTOR_RENDERER_GENERIC_SHAPE_MIXIN)
return eo_add(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, obj);
- else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS)
+ else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN)
return eo_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, obj);
- else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_CLASS)
+ else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN)
return eo_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, obj);
+ ERR("Couldn't find class for type: %s\n", eo_class_name_get(type));
return NULL;
}
static void
_ector_software_surface_context_set(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- Software_Rasterizer *ctx)
+ Ector_Software_Surface_Data *pd,
+ Software_Rasterizer *ctx)
{
pd->software = ctx;
}
static Software_Rasterizer *
_ector_software_surface_context_get(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd)
+ Ector_Software_Surface_Data *pd)
{
return pd->software;
}
-void _ector_software_surface_ector_generic_surface_surface_set(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- void *pixels, unsigned int width, unsigned int height)
+void
+_ector_software_surface_surface_set(Eo *obj EINA_UNUSED,
+ Ector_Software_Surface_Data *pd,
+ void *pixels, unsigned int width, unsigned int height)
{
- pd->software->fillData.raster_buffer.buffer = pixels;
- pd->software->fillData.raster_buffer.width = width;
- pd->software->fillData.raster_buffer.height = height;
+ pd->software->fill_data.raster_buffer.buffer = pixels;
+ pd->software->fill_data.raster_buffer.width = width;
+ pd->software->fill_data.raster_buffer.height = height;
}
-
-void _ector_software_surface_ector_generic_surface_surface_get(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- void **pixels, unsigned int *width, unsigned int *height)
+void
+_ector_software_surface_surface_get(Eo *obj EINA_UNUSED,
+ Ector_Software_Surface_Data *pd,
+ void **pixels, unsigned int *width, unsigned int *height)
{
- *pixels = pd->software->fillData.raster_buffer.buffer;
- *width = pd->software->fillData.raster_buffer.width;
- *height = pd->software->fillData.raster_buffer.height;
+ *pixels = pd->software->fill_data.raster_buffer.buffer;
+ *width = pd->software->fill_data.raster_buffer.width;
+ *height = pd->software->fill_data.raster_buffer.height;
}
-
-
static void
_ector_software_surface_eo_base_constructor(Eo *obj,
- Ector_Software_Surface_Data *pd EINA_UNUSED)
+ Ector_Software_Surface_Data *pd EINA_UNUSED)
{
eo_do_super(obj, ECTOR_SOFTWARE_SURFACE_CLASS, eo_constructor());
- if(_software_count == 0) {
- pd->software = (Software_Rasterizer *) calloc(1, sizeof(Software_Rasterizer));
- ector_software_rasterizer_init(pd->software);
- }
+ if(_software_count == 0)
+ {
+ pd->software = (Software_Rasterizer *) calloc(1, sizeof(Software_Rasterizer));
+ ector_software_rasterizer_init(pd->software);
+ }
_software_count++;
}
eo_do_super(obj, ECTOR_SOFTWARE_SURFACE_CLASS, eo_destructor());
}
+static void
+_ector_software_surface_ector_generic_surface_reference_point_set(Eo *obj EINA_UNUSED,
+ Ector_Software_Surface_Data *pd,
+ int x, int y)
+{
+ pd->x = x;
+ pd->y = y;
+}
#include "ector_software_surface.eo.c"
#include "ector_renderer_software_base.eo.c"
Software_Rasterizer *ctx;
}
}
+ surface {
+ set {
+ }
+ get {
+ }
+ values {
+ void *pixels;
+ uint width;
+ uint height;
+ }
+ }
}
implements {
Ector.Generic.Surface.renderer_factory_new;
- Ector.Generic.Surface.surface.set;
- Ector.Generic.Surface.surface.get;
+ Ector.Generic.Surface.reference_point.set;
Eo.Base.destructor;
Eo.Base.constructor;
}
# endif
#endif /* ! _WIN32 */
-#ifdef EFL_BETA_API_SUPPORT
-
-/* Interfaces */
-#include "interfaces/efl_control.eo.h"
-#include "interfaces/efl_file.eo.h"
-#include "interfaces/efl_image.eo.h"
-#include "interfaces/efl_player.eo.h"
-#include "interfaces/efl_text.eo.h"
-#include "interfaces/efl_text_properties.eo.h"
-
-#endif
/**
* These values determine how the points are interpreted in a stream of points.
*
- * @see efl_gfx_path_dup()
- * @see efl_gfx_path_append_move_to()
- * @see efl_gfx_path_append_line_to()
- * @see efl_gfx_path_append_quadratic_to()
- * @see efl_gfx_path_append_cubic_to()
- * @see efl_gfx_path_append_scubic_to()
- * @see efl_gfx_path_append_arc_to()
- * @see efl_gfx_path_append_arc()
- * @see efl_gfx_path_append_rounded_rect()
- * @see efl_gfx_path_append_close()
- * @see efl_gfx_path_append_circle()
- *
* @since 1.14
*/
typedef enum _Efl_Gfx_Path_Command
EFL_GFX_GRADIENT_SPREAD_LAST /**< End of enum value */
} Efl_Gfx_Gradient_Spread;
-#include "interfaces/efl_gfx_utils.h"
+/**
+ * Type defining how an image content get filled.
+ * @since 1.14
+ */
+typedef enum _Efl_Gfx_Fill_Spread
+{
+ EFL_GFX_FILL_REFLECT = 0, /**< image fill tiling mode - tiling reflects */
+ EFL_GFX_FILL_REPEAT = 1, /**< tiling repeats */
+ EFL_GFX_FILL_RESTRICT = 2, /**< tiling clamps - range offset ignored */
+ EFL_GFX_FILL_RESTRICT_REFLECT = 3, /**< tiling clamps and any range offset reflects */
+ EFL_GFX_FILL_RESTRICT_REPEAT = 4, /**< tiling clamps and any range offset repeats */
+ EFL_GFX_FILL_PAD = 5 /**< tiling extends with end values */
+} Efl_Gfx_Fill_Spread;
+
+#ifdef EFL_BETA_API_SUPPORT
+
+/* Interfaces */
+#include "interfaces/efl_control.eo.h"
+#include "interfaces/efl_file.eo.h"
+#include "interfaces/efl_image.eo.h"
+#include "interfaces/efl_player.eo.h"
+#include "interfaces/efl_text.eo.h"
+#include "interfaces/efl_text_properties.eo.h"
+
+EAPI extern const Eo_Event_Description _EFL_GFX_CHANGED;
+EAPI extern const Eo_Event_Description _EFL_GFX_PATH_CHANGED;
+
+#define EFL_GFX_CHANGED (&(_EFL_GFX_CHANGED))
+#define EFL_GFX_PATH_CHANGED (&(_EFL_GFX_PATH_CHANGED))
#include "interfaces/efl_gfx_base.eo.h"
+#include "interfaces/efl_gfx_stack.eo.h"
+#include "interfaces/efl_gfx_fill.eo.h"
+#include "interfaces/efl_gfx_view.eo.h"
#include "interfaces/efl_gfx_shape.eo.h"
-#include "interfaces/efl_gfx_gradient.eo.h"
+#include "interfaces/efl_gfx_gradient_base.eo.h"
#include "interfaces/efl_gfx_gradient_linear.eo.h"
#include "interfaces/efl_gfx_gradient_radial.eo.h"
int a; /*@ The alpha component of the given color. */
}
}
+ color_part {
+ set {
+ /*@
+ Sets a specifc color of the given Efl.Gfx.Base object to the given
+ one.
+
+ @see evas_object_color_get() (for an example)
+ @note These color values are expected to be premultiplied by @p a.
+
+ */
+ return: bool;
+ }
+ get {
+ /*@
+ Retrieves a specific color of the given Evas object.
+
+ Retrieves a specific color's RGB component (and alpha channel)
+ values, <b>which range from 0 to 255</b>. For the alpha channel,
+ which defines the object's transparency level, 0 means totally
+ transparent, while 255 means opaque. These color values are
+ premultiplied by the alpha value.
+
+ The “main“ color being mapped to @c NULL.
+
+ Usually you’ll use this attribute for text and rectangle objects,
+ where the “main” color is their unique one. If set for objects
+ which themselves have colors, like the images one, those colors get
+ modulated by this one.
+
+ @note Use @c NULL pointers on the components you're not interested
+ in: they'll be ignored by the function.
+
+ */
+ return: bool;
+ }
+ keys {
+ const (char)* part; /*@ The part you are interested in. */
+ }
+ values {
+ int r; /*@ The red component of the given color. */
+ int g; /*@ The green component of the given color. */
+ int b; /*@ The blue component of the given color. */
+ int a; /*@ The alpha component of the given color. */
+ }
+ }
visible {
set {
/*@ Makes the given Evas object visible or invisible. */
--- /dev/null
+interface Efl.Gfx.Fill {
+ legacy_prefix: null;
+ properties {
+ fill_spread {
+ set {
+ /*@
+ Sets the tiling mode for the given evas image object's fill.
+ EFL_GFX_FILL_RESTRICT, or EFL_GFX_FILL_PAD. */
+ }
+ get {
+ /*@
+ Retrieves the spread (tiling mode) for the given image object's
+ fill.
+
+ @return The current spread mode of the image object. */
+ }
+ values {
+ Efl_Gfx_Fill_Spread spread; /*@ One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT, */
+ }
+ }
+ fill {
+ set {
+ /*@
+ Set how to fill an image object's drawing rectangle given the
+ (real) image bound to it.
+
+ Note that if @p w or @p h are smaller than the dimensions of
+ @p obj, the displayed image will be @b tiled around the object's
+ area. To have only one copy of the bound image drawn, @p x and @p y
+ must be 0 and @p w and @p h need to be the exact width and height
+ of the image object itself, respectively.
+
+ See the following image to better understand the effects of this
+ call. On this diagram, both image object and original image source
+ have @c a x @c a dimensions and the image itself is a circle, with
+ empty space around it:
+
+ @image html image-fill.png
+ @image rtf image-fill.png
+ @image latex image-fill.eps
+
+ @warning The default values for the fill parameters are @p x = 0,
+ @p y = 0, @p w = 0 and @p h = 0. Thus, if you're not using the
+ evas_object_image_filled_add() helper and want your image
+ displayed, you'll have to set valid values with this function on
+ your object.
+
+ @note evas_object_image_filled_set() is a helper function which
+ will @b override the values set here automatically, for you, in a
+ given way. */
+ }
+ get {
+ /*@
+ Retrieve how an image object is to fill its drawing rectangle,
+ given the (real) image bound to it.
+
+ @note Use @c NULL pointers on the fill components you're not
+ interested in: they'll be ignored by the function.
+
+ See @ref evas_object_image_fill_set() for more details. */
+ }
+ values {
+ int x; /*@ The x coordinate (from the top left corner of the bound
+ image) to start drawing from. */
+ int y; /*@ The y coordinate (from the top left corner of the bound
+ image) to start drawing from. */
+ int w; /*@ The width the bound image will be displayed at. */
+ int h; /*@ The height the bound image will be displayed at. */
+ }
+ }
+ }
+}
--- /dev/null
+interface Efl.Gfx.Gradient.Base
+{
+ eo_prefix: efl_gfx_gradient;
+ legacy_prefix: null;
+ properties {
+ stop {
+ set {
+ /*@
+ Set the list of color stops for the gradient
+ */
+ }
+ get {
+ /*@
+ get the list of color stops.
+ */
+ }
+ values {
+ const(Efl_Gfx_Gradient_Stop) *colors; /*@ color stops list*/
+ uint length; /*@ length of the list */
+ }
+ }
+ spread {
+ set {
+ /*@
+ Specifies the spread method that should be used for this gradient.
+ */
+ }
+ get {
+ /*@
+ Returns the spread method use by this gradient. The default is EFL_GFX_GRADIENT_SPREAD_PAD.
+ */
+ }
+ values {
+ Efl_Gfx_Gradient_Spread s; /*@ spread type to be used */
+ }
+ }
+ }
+}
-interface Efl.Gfx.Gradient_Linear (Efl.Gfx.Gradient)
+interface Efl.Gfx.Gradient.Linear (Efl.Gfx.Gradient.Base)
{
legacy_prefix: null;
properties {
set {
/*@
Sets the start point of this linear gradient.
- @since 1.14
*/
}
get {
/*@
Gets the start point of this linear gradient.
- @since 1.14
*/
}
values {
set {
/*@
Sets the end point of this linear gradient.
- @since 1.14
*/
}
get {
/*@
Gets the end point of this linear gradient.
- @since 1.14
*/
}
values {
-interface Efl.Gfx.Gradient_Radial (Efl.Gfx.Gradient)
+interface Efl.Gfx.Gradient.Radial (Efl.Gfx.Gradient.Base)
{
legacy_prefix: null;
properties {
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+
+#include <Efl.h>
+
+typedef struct _Efl_Gfx_Shape_Data Efl_Gfx_Shape_Data;
+struct _Efl_Gfx_Shape_Data
+{
+ struct {
+ double x;
+ double y;
+ } current, current_ctrl;
+
+ Efl_Gfx_Path_Command *commands;
+ double *points;
+
+ unsigned int commands_count;
+ unsigned int points_count;
+};
+
+static inline unsigned int
+_efl_gfx_path_command_length(Efl_Gfx_Path_Command command)
+{
+ switch (command)
+ {
+ case EFL_GFX_PATH_COMMAND_TYPE_END: return 0;
+ case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO: return 2;
+ case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO: return 2;
+ case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO: return 6;
+ case EFL_GFX_PATH_COMMAND_TYPE_CLOSE: return 0;
+ case EFL_GFX_PATH_COMMAND_TYPE_LAST: return 0;
+ }
+ return 0;
+}
+
+static inline void
+_efl_gfx_path_length(const Efl_Gfx_Path_Command *commands,
+ unsigned int *cmd_length,
+ unsigned int *pts_length)
+{
+ if (commands)
+ while (commands[*cmd_length] != EFL_GFX_PATH_COMMAND_TYPE_END)
+ {
+ *pts_length += _efl_gfx_path_command_length(commands[*cmd_length]);
+ (*cmd_length)++;
+ }
+
+ // Accounting for END command and handle gracefully the NULL case at the same time
+ (*cmd_length)++;
+}
+
+static inline Eina_Bool
+efl_gfx_path_grow(Efl_Gfx_Path_Command command,
+ Efl_Gfx_Shape_Data *pd,
+ double **offset_point)
+{
+ Efl_Gfx_Path_Command *cmd_tmp;
+ double *pts_tmp;
+ unsigned int cmd_length = 0, pts_length = 0;
+
+ cmd_length = pd->commands_count ? pd->commands_count : 1;
+ pts_length = pd->points_count;
+
+ if (_efl_gfx_path_command_length(command))
+ {
+ pts_length += _efl_gfx_path_command_length(command);
+ pts_tmp = realloc(pd->points, pts_length * sizeof (double));
+ if (!pts_tmp) return EINA_FALSE;
+
+ pd->points = pts_tmp;
+ *offset_point = pd->points +
+ pts_length - _efl_gfx_path_command_length(command);
+ }
+
+ cmd_tmp = realloc(pd->commands,
+ (cmd_length + 1) * sizeof (Efl_Gfx_Path_Command));
+ if (!cmd_tmp) return EINA_FALSE;
+ pd->commands = cmd_tmp;
+
+ pd->commands_count = cmd_length + 1;
+ pd->points_count = pts_length;
+
+ // Append the command
+ cmd_tmp[cmd_length - 1] = command;
+ // NULL terminate the stream
+ cmd_tmp[cmd_length] = EFL_GFX_PATH_COMMAND_TYPE_END;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_current_search(const Efl_Gfx_Path_Command *cmd,
+ const double *points,
+ double *current_x, double *current_y,
+ double *current_ctrl_x, double *current_ctrl_y)
+{
+ unsigned int i;
+
+ if (current_x) *current_x = 0;
+ if (current_y) *current_y = 0;
+ if (current_ctrl_x) *current_ctrl_x = 0;
+ if (current_ctrl_y) *current_ctrl_y = 0;
+ if (!cmd || !points) return EINA_FALSE;
+
+ for (i = 0; cmd[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+ {
+ switch (cmd[i])
+ {
+ case EFL_GFX_PATH_COMMAND_TYPE_END:
+ break;
+ case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
+ case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO:
+ if (current_x) *current_x = points[0];
+ if (current_y) *current_y = points[1];
+
+ points += 2;
+ break;
+ case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO:
+ if (current_x) *current_x = points[0];
+ if (current_y) *current_y = points[1];
+ if (current_ctrl_x) *current_ctrl_x = points[4];
+ if (current_ctrl_y) *current_ctrl_y = points[5];
+
+ points += 6;
+ break;
+ case EFL_GFX_PATH_COMMAND_TYPE_CLOSE:
+ break;
+ case EFL_GFX_PATH_COMMAND_TYPE_LAST:
+ default:
+ return EINA_FALSE;
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+void
+_efl_gfx_shape_path_set(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ const Efl_Gfx_Path_Command *commands,
+ const double *points)
+{
+ Efl_Gfx_Path_Command *cmds;
+ double *pts;
+ unsigned int cmds_length = 0, pts_length = 0;
+
+ if (!commands)
+ {
+ free(pd->commands); pd->commands = NULL;
+ free(pd->points); pd->points = NULL;
+ pd->current.x = pd->current.y = 0;
+ pd->current_ctrl.x = pd->current_ctrl.y = 0;
+ goto end;
+ }
+
+ _efl_gfx_path_length(commands, &cmds_length, &pts_length);
+
+ cmds = realloc(pd->commands,
+ sizeof (Efl_Gfx_Path_Command) * cmds_length);
+ if (!cmds) return ;
+ pd->commands = cmds;
+
+ pts = realloc(pd->points,
+ sizeof (double) * pts_length);
+ if (!pts) return ;
+ pd->points = pts;
+
+ pd->commands_count = cmds_length;
+ pd->points_count = pts_length;
+
+ memcpy(pd->commands, commands, sizeof (Efl_Gfx_Path_Command) * cmds_length);
+ memcpy(pd->points, points, sizeof (double) * pts_length);
+
+ _efl_gfx_path_current_search(pd->commands, pd->points,
+ &pd->current.x, &pd->current.y,
+ &pd->current_ctrl.x, &pd->current_ctrl.y);
+
+ end:
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_path_get(Eo *obj EINA_UNUSED, Efl_Gfx_Shape_Data *pd,
+ const Efl_Gfx_Path_Command **commands,
+ const double **points)
+{
+ if (commands) *commands = pd->commands;
+ if (points) *points = pd->points;
+}
+
+void
+_efl_gfx_shape_path_length_get(Eo *obj EINA_UNUSED, Efl_Gfx_Shape_Data *pd,
+ unsigned int *commands, unsigned int *points)
+{
+ if (commands) *commands = pd->commands_count;
+ if (points) *points = pd->points_count;
+}
+
+void
+_efl_gfx_shape_current_get(Eo *obj EINA_UNUSED, Efl_Gfx_Shape_Data *pd,
+ double *x, double *y)
+{
+ if (x) *x = pd->current.x;
+ if (y) *y = pd->current.y;
+}
+
+void
+_efl_gfx_shape_current_ctrl_get(Eo *obj EINA_UNUSED, Efl_Gfx_Shape_Data *pd,
+ double *x, double *y)
+{
+ if (x) *x = pd->current_ctrl.x;
+ if (y) *y = pd->current_ctrl.y;
+}
+
+static Eina_Bool
+_efl_gfx_shape_equal_commands_internal(Efl_Gfx_Shape_Data *a,
+ Efl_Gfx_Shape_Data *b)
+{
+ unsigned int i;
+
+ if (a->commands_count != b->commands_count) return EINA_FALSE;
+
+ for (i = 0; a->commands[i] == b->commands[i] &&
+ a->commands[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+ ;
+
+ return (a->commands[i] == b->commands[i]);
+}
+
+static inline double
+interpolate(double from, double to, double pos_map)
+{
+ return (from * pos_map) + (to * (1.0 - pos_map));
+}
+
+static inline int
+interpolatei(int from, int to, double pos_map)
+{
+ return (from * pos_map) + (to * (1.0 - pos_map));
+}
+
+typedef struct _Efl_Gfx_Stroke Efl_Gfx_Stroke;
+struct _Efl_Gfx_Stroke
+{
+ double scale;
+ int r, g, b, a;
+ double w;
+ double centered;
+ const Efl_Gfx_Dash *dash;
+ unsigned int dash_length;
+ Efl_Gfx_Cap c;
+ Efl_Gfx_Join j;
+};
+
+static inline void
+stroke_get(const Eo *obj, Efl_Gfx_Stroke *stroke)
+{
+ eo_do(obj,
+ stroke->scale = efl_gfx_shape_stroke_scale_get(),
+ efl_gfx_shape_stroke_color_get(&stroke->r, &stroke->g, &stroke->b, &stroke->a),
+ stroke->w = efl_gfx_shape_stroke_width_get(),
+ stroke->centered = efl_gfx_shape_stroke_location_get(),
+ efl_gfx_shape_stroke_dash_get(&stroke->dash, &stroke->dash_length),
+ stroke->c = efl_gfx_shape_stroke_cap_get(),
+ stroke->j = efl_gfx_shape_stroke_join_get());
+}
+
+Eina_Bool
+_efl_gfx_shape_interpolate(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ const Eo *from, const Eo *to, double pos_map)
+{
+ Efl_Gfx_Shape_Data *from_pd, *to_pd;
+ Efl_Gfx_Path_Command *cmds;
+ double *pts, *from_pts, *to_pts;
+ unsigned int i, j;
+ Efl_Gfx_Stroke stroke_from, stroke_to;
+ Efl_Gfx_Dash *dash;
+
+ from_pd = eo_data_scope_get(from, EFL_GFX_SHAPE_MIXIN);
+ to_pd = eo_data_scope_get(to, EFL_GFX_SHAPE_MIXIN);
+ if (!eo_isa(from, EFL_GFX_SHAPE_MIXIN) ||
+ !eo_isa(to, EFL_GFX_SHAPE_MIXIN)) return EINA_FALSE;
+ if (pd == from_pd || pd == to_pd) return EINA_FALSE;
+ if (!_efl_gfx_shape_equal_commands_internal(from_pd, to_pd))
+ return EINA_FALSE;
+
+ stroke_get(from, &stroke_from);
+ stroke_get(to, &stroke_to);
+
+ if (stroke_from.dash_length != stroke_to.dash_length) return EINA_FALSE;
+
+ cmds = realloc(pd->commands,
+ sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
+ if (!cmds && from_pd->commands_count) return EINA_FALSE;
+ pd->commands = cmds;
+
+ pts = realloc(pd->points,
+ sizeof (double) * from_pd->points_count);
+ if (!pts && from_pd->points_count) return EINA_FALSE;
+ pd->points = pts;
+
+ memcpy(cmds, from_pd->commands,
+ sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
+
+ to_pts = to_pd->points;
+ from_pts = from_pd->points;
+
+ for (i = 0; cmds[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+ for (j = 0; j < _efl_gfx_path_command_length(cmds[i]); j++)
+ {
+ *pts = interpolate(*from_pts, *to_pts, pos_map);
+
+ pts++;
+ from_pts++;
+ to_pts++;
+ }
+
+ pd->points_count = from_pd->points_count;
+ pd->commands_count = from_pd->commands_count;
+
+ pd->current.x = interpolate(from_pd->current.x,
+ to_pd->current.x,
+ pos_map);
+ pd->current.y = interpolate(from_pd->current.y,
+ to_pd->current.y,
+ pos_map);
+ pd->current_ctrl.x = interpolate(from_pd->current_ctrl.x,
+ to_pd->current_ctrl.x,
+ pos_map);
+ pd->current_ctrl.y = interpolate(from_pd->current_ctrl.y,
+ to_pd->current_ctrl.y,
+ pos_map);
+
+ dash = malloc(sizeof (Efl_Gfx_Dash) * stroke_to.dash_length);
+ if (dash)
+ {
+ for (i = 0; i < stroke_to.dash_length; i++)
+ {
+ dash[i].length = interpolate(stroke_from.dash[i].length,
+ stroke_to.dash[i].length, pos_map);
+ dash[i].gap = interpolate(stroke_from.dash[i].gap,
+ stroke_to.dash[i].gap, pos_map);
+ }
+ }
+ else
+ {
+ stroke_to.dash_length = 0;
+ }
+
+ eo_do(obj,
+ efl_gfx_shape_stroke_scale_set(interpolate(stroke_to.scale, stroke_from.scale, pos_map)),
+ efl_gfx_shape_stroke_color_set(interpolatei(stroke_to.r, stroke_from.r, pos_map),
+ interpolatei(stroke_to.g, stroke_from.g, pos_map),
+ interpolatei(stroke_to.b, stroke_from.b, pos_map),
+ interpolatei(stroke_to.a, stroke_from.a, pos_map)),
+ efl_gfx_shape_stroke_width_set(interpolate(stroke_to.w, stroke_from.w, pos_map)),
+ efl_gfx_shape_stroke_location_set(interpolate(stroke_to.centered, stroke_from.centered, pos_map)),
+ efl_gfx_shape_stroke_dash_set(dash, stroke_to.dash_length),
+ efl_gfx_shape_stroke_cap_set(pos_map < 0.5 ? stroke_from.c : stroke_to.c),
+ efl_gfx_shape_stroke_join_set(pos_map < 0.5 ? stroke_from.j : stroke_to.j),
+
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+_efl_gfx_shape_equal_commands(Eo *obj EINA_UNUSED,
+ Efl_Gfx_Shape_Data *pd,
+ const Eo *with)
+{
+ Efl_Gfx_Shape_Data *with_pd;
+
+ with_pd = eo_data_scope_get(with, EFL_GFX_SHAPE_MIXIN);
+ if (!with_pd) return EINA_FALSE;
+
+ return _efl_gfx_shape_equal_commands_internal(with_pd, pd);
+}
+
+void
+_efl_gfx_shape_dup(Eo *obj, Efl_Gfx_Shape_Data *pd, Eo *dup_from)
+{
+ const Efl_Gfx_Dash *dash = NULL;
+ Efl_Gfx_Shape_Data *from;
+ unsigned int dash_length = 0;
+ Efl_Gfx_Cap cap;
+ Efl_Gfx_Join j;
+ int sr, sg, sb, sa;
+ double scale, location;
+ double sw;
+
+ if (obj == dup_from) return ;
+ from = eo_data_scope_get(dup_from, EFL_GFX_SHAPE_MIXIN);
+ if (!from) return ;
+
+ eo_do(dup_from,
+ scale = efl_gfx_shape_stroke_scale_get(),
+ efl_gfx_shape_stroke_color_get(&sr, &sg, &sb, &sa),
+ sw = efl_gfx_shape_stroke_width_get(),
+ location = efl_gfx_shape_stroke_location_get(),
+ efl_gfx_shape_stroke_dash_get(&dash, &dash_length),
+ cap = efl_gfx_shape_stroke_cap_get(),
+ j = efl_gfx_shape_stroke_join_get());
+ eo_do(obj,
+ efl_gfx_shape_stroke_scale_set(scale),
+ efl_gfx_shape_stroke_color_set(sr, sg, sb, sa),
+ efl_gfx_shape_stroke_width_set(sw),
+ efl_gfx_shape_stroke_location_set(location),
+ efl_gfx_shape_stroke_dash_set(dash, dash_length),
+ efl_gfx_shape_stroke_cap_set(cap),
+ efl_gfx_shape_stroke_join_set(j));
+
+ _efl_gfx_shape_path_set(obj, pd, from->commands, from->points);
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_reset(Eo *obj, Efl_Gfx_Shape_Data *pd)
+{
+ free(pd->commands);
+ pd->commands = NULL;
+ pd->commands_count = 0;
+
+ free(pd->points);
+ pd->points = NULL;
+ pd->points_count = 0;
+
+ pd->current.x = 0;
+ pd->current.y = 0;
+ pd->current_ctrl.x = 0;
+ pd->current_ctrl.y = 0;
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_append_move_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y)
+{
+ double *offset_point;
+
+ if (!efl_gfx_path_grow(EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO,
+ pd, &offset_point))
+ return ;
+
+ offset_point[0] = x;
+ offset_point[1] = y;
+
+ pd->current.x = x;
+ pd->current.y = y;
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_append_line_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y)
+{
+ double *offset_point;
+
+ if (!efl_gfx_path_grow(EFL_GFX_PATH_COMMAND_TYPE_LINE_TO,
+ pd, &offset_point))
+ return ;
+
+ offset_point[0] = x;
+ offset_point[1] = y;
+
+ pd->current.x = x;
+ pd->current.y = y;
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_append_cubic_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y,
+ double ctrl_x0, double ctrl_y0,
+ double ctrl_x1, double ctrl_y1)
+{
+ double *offset_point;
+
+ if (!efl_gfx_path_grow(EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO,
+ pd, &offset_point))
+ return ;
+
+ offset_point[0] = x;
+ offset_point[1] = y;
+ offset_point[2] = ctrl_x0;
+ offset_point[3] = ctrl_y0;
+ offset_point[4] = ctrl_x1;
+ offset_point[5] = ctrl_y1;
+
+ pd->current.x = x;
+ pd->current.y = y;
+ pd->current_ctrl.x = ctrl_x1;
+ pd->current_ctrl.y = ctrl_y1;
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_append_scubic_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y,
+ double ctrl_x, double ctrl_y)
+{
+ double ctrl_x0, ctrl_y0;
+ double current_x = 0, current_y = 0;
+ double current_ctrl_x = 0, current_ctrl_y = 0;
+
+ current_x = pd->current.x;
+ current_y = pd->current.x;
+ current_ctrl_x = pd->current_ctrl.x;
+ current_ctrl_y = pd->current_ctrl.y;
+
+ ctrl_x0 = 2 * current_x - current_ctrl_x;
+ ctrl_y0 = 2 * current_y - current_ctrl_y;
+
+ _efl_gfx_shape_append_cubic_to(obj, pd, x, y,
+ ctrl_x0, ctrl_y0, ctrl_x, ctrl_y);
+}
+
+void
+_efl_gfx_shape_append_quadratic_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y,
+ double ctrl_x, double ctrl_y)
+{
+ double current_x = 0, current_y = 0;
+ double ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
+
+ current_x = pd->current.x;
+ current_y = pd->current.y;
+
+ // Convert quadratic bezier to cubic
+ ctrl_x0 = (current_x + 2 * ctrl_x) * (1.0 / 3.0);
+ ctrl_y0 = (current_y + 2 * ctrl_y) * (1.0 / 3.0);
+ ctrl_x1 = (x + 2 * ctrl_x) * (1.0 / 3.0);
+ ctrl_y1 = (y + 2 * ctrl_y) * (1.0 / 3.0);
+
+ _efl_gfx_shape_append_cubic_to(obj, pd, x, y,
+ ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1);
+}
+
+void
+_efl_gfx_shape_append_squadratic_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y)
+{
+ double xc, yc; /* quadratic control point */
+ double ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
+ double current_x = 0, current_y = 0;
+ double current_ctrl_x = 0, current_ctrl_y = 0;
+
+ current_x = pd->current.x;
+ current_y = pd->current.x;
+ current_ctrl_x = pd->current_ctrl.x;
+ current_ctrl_y = pd->current_ctrl.y;
+
+ xc = 2 * current_x - current_ctrl_x;
+ yc = 2 * current_y - current_ctrl_y;
+ /* generate a quadratic bezier with control point = xc, yc */
+ ctrl_x0 = (current_x + 2 * xc) * (1.0 / 3.0);
+ ctrl_y0 = (current_y + 2 * yc) * (1.0 / 3.0);
+ ctrl_x1 = (x + 2 * xc) * (1.0 / 3.0);
+ ctrl_y1 = (y + 2 * yc) * (1.0 / 3.0);
+
+ _efl_gfx_shape_append_cubic_to(obj, pd, x, y,
+ ctrl_x0, ctrl_y0,
+ ctrl_x1, ctrl_y1);
+}
+
+/*
+ * code adapted from enesim which was adapted from moonlight sources
+ */
+void
+_efl_gfx_shape_append_arc_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y,
+ double rx, double ry,
+ double angle,
+ Eina_Bool large_arc, Eina_Bool sweep)
+{
+ double cxp, cyp, cx, cy;
+ double sx, sy;
+ double cos_phi, sin_phi;
+ double dx2, dy2;
+ double x1p, y1p;
+ double x1p2, y1p2;
+ double rx2, ry2;
+ double lambda;
+ double c;
+ double at;
+ double theta1, delta_theta;
+ double nat;
+ double delta, bcp;
+ double cos_phi_rx, cos_phi_ry;
+ double sin_phi_rx, sin_phi_ry;
+ double cos_theta1, sin_theta1;
+ int segments, i;
+
+ // some helpful stuff is available here:
+ // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
+ sx = pd->current.x;
+ sy = pd->current.y;
+
+ // if start and end points are identical, then no arc is drawn
+ if ((fabs(x - sx) < (1 / 256.0)) && (fabs(y - sy) < (1 / 256.0)))
+ return;
+
+ // Correction of out-of-range radii, see F6.6.1 (step 2)
+ rx = fabs(rx);
+ ry = fabs(ry);
+ if ((rx < 0.5) || (ry < 0.5))
+ {
+ _efl_gfx_shape_append_line_to(obj, pd, x, y);
+ return;
+ }
+
+ angle = angle * M_PI / 180.0;
+ cos_phi = cos(angle);
+ sin_phi = sin(angle);
+ dx2 = (sx - x) / 2.0;
+ dy2 = (sy - y) / 2.0;
+ x1p = cos_phi * dx2 + sin_phi * dy2;
+ y1p = cos_phi * dy2 - sin_phi * dx2;
+ x1p2 = x1p * x1p;
+ y1p2 = y1p * y1p;
+ rx2 = rx * rx;
+ ry2 = ry * ry;
+ lambda = (x1p2 / rx2) + (y1p2 / ry2);
+
+ // Correction of out-of-range radii, see F6.6.2 (step 4)
+ if (lambda > 1.0)
+ {
+ // see F6.6.3
+ double lambda_root = sqrt(lambda);
+
+ rx *= lambda_root;
+ ry *= lambda_root;
+ // update rx2 and ry2
+ rx2 = rx * rx;
+ ry2 = ry * ry;
+ }
+
+ c = (rx2 * ry2) - (rx2 * y1p2) - (ry2 * x1p2);
+
+ // check if there is no possible solution
+ // (i.e. we can't do a square root of a negative value)
+ if (c < 0.0)
+ {
+ // scale uniformly until we have a single solution
+ // (see F6.2) i.e. when c == 0.0
+ double scale = sqrt(1.0 - c / (rx2 * ry2));
+ rx *= scale;
+ ry *= scale;
+ // update rx2 and ry2
+ rx2 = rx * rx;
+ ry2 = ry * ry;
+
+ // step 2 (F6.5.2) - simplified since c == 0.0
+ cxp = 0.0;
+ cyp = 0.0;
+ // step 3 (F6.5.3 first part) - simplified since cxp and cyp == 0.0
+ cx = 0.0;
+ cy = 0.0;
+ }
+ else
+ {
+ // complete c calculation
+ c = sqrt(c / ((rx2 * y1p2) + (ry2 * x1p2)));
+ // inverse sign if Fa == Fs
+ if (large_arc == sweep)
+ c = -c;
+
+ // step 2 (F6.5.2)
+ cxp = c * ( rx * y1p / ry);
+ cyp = c * (-ry * x1p / rx);
+
+ // step 3 (F6.5.3 first part)
+ cx = cos_phi * cxp - sin_phi * cyp;
+ cy = sin_phi * cxp + cos_phi * cyp;
+ }
+
+ // step 3 (F6.5.3 second part) we now have the center point of the ellipse
+ cx += (sx + x) / 2.0;
+ cy += (sy + y) / 2.0;
+
+ // step 4 (F6.5.4)
+ // we dont' use arccos (as per w3c doc),
+ // see http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
+ // note: atan2 (0.0, 1.0) == 0.0
+ at = atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx));
+ theta1 = (at < 0.0) ? 2.0 * M_PI + at : at;
+
+ nat = atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx));
+ delta_theta = (nat < at) ? 2.0 * M_PI - at + nat : nat - at;
+
+ if (sweep)
+ {
+ // ensure delta theta < 0 or else add 360 degrees
+ if (delta_theta < 0.0)
+ delta_theta += 2.0 * M_PI;
+ }
+ else
+ {
+ // ensure delta theta > 0 or else substract 360 degrees
+ if (delta_theta > 0.0)
+ delta_theta -= 2.0 * M_PI;
+ }
+
+ // add several cubic bezier to approximate the arc
+ // (smaller than 90 degrees)
+ // we add one extra segment because we want something
+ // smaller than 90deg (i.e. not 90 itself)
+ segments = (int) (fabs(delta_theta / M_PI_2)) + 1;
+ delta = delta_theta / segments;
+
+ // http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13)
+ bcp = 4.0 / 3 * (1 - cos(delta / 2)) / sin(delta / 2);
+
+ cos_phi_rx = cos_phi * rx;
+ cos_phi_ry = cos_phi * ry;
+ sin_phi_rx = sin_phi * rx;
+ sin_phi_ry = sin_phi * ry;
+
+ cos_theta1 = cos(theta1);
+ sin_theta1 = sin(theta1);
+
+ for (i = 0; i < segments; ++i)
+ {
+ // end angle (for this segment) = current + delta
+ double c1x, c1y, ex, ey, c2x, c2y;
+ double theta2 = theta1 + delta;
+ double cos_theta2 = cos(theta2);
+ double sin_theta2 = sin(theta2);
+
+ // first control point (based on start point sx,sy)
+ c1x = sx - bcp * (cos_phi_rx * sin_theta1 + sin_phi_ry * cos_theta1);
+ c1y = sy + bcp * (cos_phi_ry * cos_theta1 - sin_phi_rx * sin_theta1);
+
+ // end point (for this segment)
+ ex = cx + (cos_phi_rx * cos_theta2 - sin_phi_ry * sin_theta2);
+ ey = cy + (sin_phi_rx * cos_theta2 + cos_phi_ry * sin_theta2);
+
+ // second control point (based on end point ex,ey)
+ c2x = ex + bcp * (cos_phi_rx * sin_theta2 + sin_phi_ry * cos_theta2);
+ c2y = ey + bcp * (sin_phi_rx * sin_theta2 - cos_phi_ry * cos_theta2);
+
+ _efl_gfx_shape_append_cubic_to(obj, pd, ex, ey, c1x, c1y, c2x, c2y);
+
+ // next start point is the current end point (same for angle)
+ sx = ex;
+ sy = ey;
+ theta1 = theta2;
+ // avoid recomputations
+ cos_theta1 = cos_theta2;
+ sin_theta1 = sin_theta2;
+ }
+}
+
+void
+_efl_gfx_shape_append_close(Eo *obj, Efl_Gfx_Shape_Data *pd)
+{
+ double *offset_point;
+
+ efl_gfx_path_grow(EFL_GFX_PATH_COMMAND_TYPE_CLOSE,
+ pd, &offset_point);
+
+ eo_do(obj,
+ eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+ eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+void
+_efl_gfx_shape_append_circle(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y, double radius)
+{
+ _efl_gfx_shape_append_move_to(obj, pd, x - radius, y);
+ _efl_gfx_shape_append_arc_to(obj, pd, x + radius, y, radius, radius, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_arc_to(obj, pd, x, y + radius, radius, radius, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_arc_to(obj, pd, x - radius, y, radius, radius, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_arc_to(obj, pd, x, y - radius, radius, radius, 0, EINA_FALSE, EINA_TRUE);
+}
+
+void
+_efl_gfx_shape_append_rect(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y, double w, double h,
+ double rx, double ry)
+{
+ _efl_gfx_shape_append_move_to(obj, pd, x, y + ry);
+ // Top left corner
+ _efl_gfx_shape_append_arc_to(obj, pd, x + rx, y, rx, ry, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_line_to(obj, pd, x + w - rx, y);
+ // Top right corner
+ _efl_gfx_shape_append_arc_to(obj, pd, x + w, y + ry, rx, ry, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_line_to(obj, pd, x + w, y + h - ry);
+ // Bottom right corner
+ _efl_gfx_shape_append_arc_to(obj, pd, x + w - rx, y + h, rx, ry, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_line_to(obj, pd, x + rx, y + h);
+ // Bottom left corner
+ _efl_gfx_shape_append_arc_to(obj, pd, x, y + h - ry, rx, ry, 0, EINA_FALSE, EINA_TRUE);
+ _efl_gfx_shape_append_close(obj, pd);
+}
+
+static void
+_efl_gfx_path_append_horizontal_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double d, double current_x EINA_UNUSED, double current_y)
+{
+ _efl_gfx_shape_append_line_to(obj, pd, d, current_y);
+}
+
+static void
+_efl_gfx_path_append_vertical_to(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double d, double current_x, double current_y EINA_UNUSED)
+{
+ _efl_gfx_shape_append_line_to(obj, pd, current_x, d);
+}
+
+static char *
+_strcomma(const char *content)
+{
+ while (*content && isspace(*content)) content++;
+ if (*content != ',') return NULL;
+ return (char*) content + 1;
+}
+
+static inline Eina_Bool
+_next_isnumber(const char *content)
+{
+ char *tmp = NULL;
+
+ (void) strtod(content, &tmp);
+ return content != tmp;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_pair(const char *content, char **end, double *x, double *y)
+{
+ /* "x,y" */
+ char *end1 = NULL;
+ char *end2 = NULL;
+
+ *x = strtod(content, &end1);
+ end1 = _strcomma(end1);
+ if (!end1) return EINA_FALSE;
+ *y = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *end = end2;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_pair_to(const char *content, char **end,
+ Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double *current_x, double *current_y,
+ void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double x, double y),
+ Eina_Bool rel)
+{
+ double x, y;
+
+ *end = (char*) content;
+ do
+ {
+ Eina_Bool r;
+
+ r = _efl_gfx_path_parse_pair(content, end, &x, &y);
+ if (!r) return EINA_FALSE;
+
+ if (rel)
+ {
+ x += *current_x;
+ y += *current_y;
+ }
+
+ func(obj, pd, x, y);
+ content = *end;
+
+ *current_x = x;
+ *current_y = y;
+ }
+ while (_next_isnumber(content));
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_double_to(const char *content, char **end,
+ Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double *current, double current_x, double current_y,
+ void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double d, double current_x, double current_y),
+ Eina_Bool rel)
+{
+ double d;
+ Eina_Bool first = EINA_FALSE;
+
+ *end = (char*) content;
+ do
+ {
+ d = strtod(content, end);
+ if (content == *end)
+ return first;
+ first = EINA_TRUE;
+
+ if (rel)
+ {
+ d += *current;
+ }
+
+ func(obj, pd, d, current_x, current_y);
+ content = *end;
+
+ *current = d;
+ }
+ while (1); // This is an optimisation as we have only one parameter.
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_six(const char *content, char **end,
+ double *x, double *y,
+ double *ctrl_x0, double *ctrl_y0,
+ double *ctrl_x1, double *ctrl_y1)
+{
+ /* "x,y ctrl_x0,ctrl_y0 ctrl_x1,ctrl_y1" */
+ char *end1 = NULL;
+ char *end2 = NULL;
+
+ *ctrl_x0 = strtod(content, &end1);
+ end1 = _strcomma(end1);
+ if (!end1) return EINA_FALSE;
+ *ctrl_y0 = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *ctrl_x1 = strtod(end2, &end2);
+ end2 = _strcomma(end2);
+ if (!end2) return EINA_FALSE;
+ *ctrl_y1 = strtod(end2, &end1);
+ if (end1 == end2) return EINA_FALSE;
+
+ *x = strtod(end1, &end2);
+ end2 = _strcomma(end2);
+ if (!end2) return EINA_FALSE;
+ *y = strtod(end2, &end1);
+ if (end1 == end2) return EINA_FALSE;
+
+ *end = end1;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_six_to(const char *content, char **end,
+ Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double *current_x, double *current_y,
+ void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double x, double y, double ctrl_x0, double ctrl_y0, double ctrl_x1, double ctrl_y1),
+ Eina_Bool rel)
+{
+ double x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
+
+ *end = (char*) content;
+ do
+ {
+ Eina_Bool r;
+
+ r = _efl_gfx_path_parse_six(content, end,
+ &x, &y,
+ &ctrl_x0, &ctrl_y0,
+ &ctrl_x1, &ctrl_y1);
+ if (!r) return EINA_FALSE;
+
+ if (rel)
+ {
+ x += *current_x;
+ y += *current_y;
+ }
+
+ func(obj, pd, x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1);
+ content = *end;
+
+ *current_x = x;
+ *current_y = y;
+ }
+ while (_next_isnumber(content));
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_quad(const char *content, char **end,
+ double *x, double *y,
+ double *ctrl_x0, double *ctrl_y0)
+{
+ /* "x,y ctrl_x0,ctrl_y0" */
+ char *end1 = NULL;
+ char *end2 = NULL;
+
+ *ctrl_x0 = strtod(content, &end1);
+ end1 = _strcomma(end1);
+ if (!end1) return EINA_FALSE;
+ *ctrl_y0 = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *x = strtod(end2, &end1);
+ end1 = _strcomma(end2);
+ if (!end1) return EINA_FALSE;
+ *y = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *end = end2;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_quad_to(const char *content, char **end,
+ Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double *current_x, double *current_y,
+ void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y, double ctrl_x0, double ctrl_y0),
+ Eina_Bool rel)
+{
+ double x, y, ctrl_x0, ctrl_y0;
+
+ *end = (char*) content;
+ do
+ {
+ Eina_Bool r;
+
+ r = _efl_gfx_path_parse_quad(content, end,
+ &x, &y,
+ &ctrl_x0, &ctrl_y0);
+ if (!r) return EINA_FALSE;
+
+ if (rel)
+ {
+ x += *current_x;
+ y += *current_y;
+ }
+
+ func(obj, pd, x, y, ctrl_x0, ctrl_y0);
+ content = *end;
+
+ *current_x = x;
+ *current_y = y;
+ }
+ while (_next_isnumber(content));
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_arc(const char *content, char **end,
+ double *x, double *y,
+ double *rx, double *ry,
+ double *radius,
+ Eina_Bool *large_arc, Eina_Bool *sweep)
+{
+ /* "rx,ry r large-arc-flag,sweep-flag x,y" */
+ char *end1 = NULL;
+ char *end2 = NULL;
+
+ *rx = strtod(content, &end1);
+ end1 = _strcomma(end1);
+ if (!end1) return EINA_FALSE;
+ *ry = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *radius = strtod(end2, &end1);
+ if (end1 == end2) return EINA_FALSE;
+
+ *large_arc = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE;
+ end1 = _strcomma(end2);
+ if (!end1) return EINA_FALSE;
+ *sweep = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE;
+ if (end1 == end2) return EINA_FALSE;
+
+ *x = strtod(end2, &end1);
+ end1 = _strcomma(end2);
+ if (!end1) return EINA_FALSE;
+ *y = strtod(end1, &end2);
+ if (end1 == end2) return EINA_FALSE;
+
+ *end = end2;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_gfx_path_parse_arc_to(const char *content, char **end,
+ Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double *current_x, double *current_y,
+ void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ double x, double y, double rx, double ry, double angle,
+ Eina_Bool large_arc, Eina_Bool sweep),
+ Eina_Bool rel)
+{
+ double x, y, rx, ry, angle;
+ Eina_Bool large_arc, sweep; // FIXME: handle those flag
+
+ *end = (char*) content;
+ do
+ {
+ Eina_Bool r;
+
+ r = _efl_gfx_path_parse_arc(content, end,
+ &x, &y,
+ &rx, &ry,
+ &angle,
+ &large_arc, &sweep);
+ if (!r) return EINA_FALSE;
+
+ if (rel)
+ {
+ x += *current_x;
+ y += *current_y;
+ }
+
+ func(obj, pd, x, y, rx, ry, angle, large_arc, sweep);
+ content = *end;
+
+ *current_x = x;
+ *current_y = y;
+ }
+ while (_next_isnumber(content));
+
+ return EINA_TRUE;
+}
+
+void
+_efl_gfx_shape_append_svg_path(Eo *obj, Efl_Gfx_Shape_Data *pd,
+ const char *svg_path_data)
+{
+ double current_x = 0, current_y = 0;
+ char *content = (char*) svg_path_data;
+
+ if (!content) return ;
+
+ while (content[0] != '\0')
+ {
+ while (isspace(content[0])) content++;
+
+ switch (content[0])
+ {
+ case 'M':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_move_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'm':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_move_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'z':
+ _efl_gfx_shape_append_close(obj, pd);
+ content++;
+ break;
+ case 'L':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_line_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'l':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_line_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'H':
+ if (!_efl_gfx_path_parse_double_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, current_x, current_y,
+ _efl_gfx_path_append_horizontal_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'h':
+ if (!_efl_gfx_path_parse_double_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, current_x, current_y,
+ _efl_gfx_path_append_horizontal_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'V':
+ if (!_efl_gfx_path_parse_double_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_y, current_x, current_y,
+ _efl_gfx_path_append_vertical_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'v':
+ if (!_efl_gfx_path_parse_double_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_y, current_x, current_y,
+ _efl_gfx_path_append_vertical_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'C':
+ if (!_efl_gfx_path_parse_six_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_cubic_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'c':
+ if (!_efl_gfx_path_parse_six_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_cubic_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'S':
+ if (!_efl_gfx_path_parse_quad_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_scubic_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 's':
+ if (!_efl_gfx_path_parse_quad_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_scubic_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'Q':
+ if (!_efl_gfx_path_parse_quad_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_quadratic_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'q':
+ if (!_efl_gfx_path_parse_quad_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_quadratic_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'T':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_squadratic_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 't':
+ if (!_efl_gfx_path_parse_pair_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_squadratic_to,
+ EINA_TRUE))
+ return ;
+ break;
+ case 'A':
+ if (!_efl_gfx_path_parse_arc_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_arc_to,
+ EINA_FALSE))
+ return ;
+ break;
+ case 'a':
+ if (!_efl_gfx_path_parse_arc_to(&content[1],
+ &content,
+ obj, pd,
+ ¤t_x, ¤t_y,
+ _efl_gfx_shape_append_arc_to,
+ EINA_TRUE))
+ return ;
+ break;
+ default:
+ return ;
+ }
+ }
+}
+
+#include "interfaces/efl_gfx_shape.eo.c"
-interface Efl.Gfx.Shape
+mixin Efl.Gfx.Shape
{
legacy_prefix: null;
properties {
const(double) *points; /*@ point list */
}
}
+ path_length {
+ get {
+ }
+ values {
+ uint commands;
+ uint points;
+ }
+ }
+ current {
+ get {
+ }
+ values {
+ double x;
+ double y;
+ }
+ }
+ current_ctrl {
+ get {
+ }
+ values {
+ double x;
+ double y;
+ }
+ }
+ }
+ methods {
+ dup {
+ params {
+ @in Eo *dup_from;
+ }
+ }
+ reset {
+ }
+ append_move_to {
+ params {
+ @in double x;
+ @in double y;
+ }
+ }
+ append_line_to {
+ params {
+ @in double x;
+ @in double y;
+ }
+ }
+ append_quadratic_to {
+ params {
+ @in double x;
+ @in double y;
+ @in double ctrl_x;
+ @in double ctrl_y;
+ }
+ }
+ append_squadratic_to {
+ params {
+ @in double x;
+ @in double y;
+ }
+ }
+ append_cubic_to {
+ params {
+ @in double x;
+ @in double y;
+ @in double ctrl_x0;
+ @in double ctrl_y0;
+ @in double ctrl_x1;
+ @in double ctrl_y1;
+ }
+ }
+ append_scubic_to {
+ params {
+ @in double x;
+ @in double y;
+ @in double ctrl_x;
+ @in double ctrl_y;
+ }
+ }
+ append_arc_to {
+ params {
+ @in double x;
+ @in double y;
+ @in double rx;
+ @in double ry;
+ @in double angle;
+ @in bool large_arc;
+ @in bool sweep;
+ }
+ }
+ append_close {
+ }
+ append_circle {
+ params {
+ @in double x;
+ @in double y;
+ @in double radius;
+ }
+ }
+ append_rect {
+ params {
+ @in double x;
+ @in double y;
+ @in double w;
+ @in double h;
+ @in double rx;
+ @in double ry;
+ }
+ }
+ append_svg_path {
+ params {
+ @in const(char)* svg_path_data;
+ }
+ }
+ interpolate {
+ return: bool;
+ params {
+ @in const(Eo)* from;
+ @in const(Eo)* to;
+ @in double pos_map;
+ }
+ }
+ equal_commands {
+ return: bool;
+ params {
+ @in const(Eo)* with;
+ }
+ }
+ }
+ implements {
+ @virtual .stroke_scale.get;
+ @virtual .stroke_scale.set;
+ @virtual .stroke_color.get;
+ @virtual .stroke_color.set;
+ @virtual .stroke_width.get;
+ @virtual .stroke_width.set;
+ @virtual .stroke_location.get;
+ @virtual .stroke_location.set;
+ @virtual .stroke_dash.get;
+ @virtual .stroke_dash.set;
+ @virtual .stroke_cap.get;
+ @virtual .stroke_cap.set;
+ @virtual .stroke_join.get;
+ @virtual .stroke_join.set;
}
}
--- /dev/null
+interface Efl.Gfx.Stack {
+ legacy_prefix: null;
+ properties {
+ layer {
+ set {
+ /*@
+ Sets the layer of its canvas that the given object will be part of.
+
+ If you don't use this function, you'll be dealing with an @b unique
+ layer of objects, the default one. Additional layers are handy when
+ you don't want a set of objects to interfere with another set with
+ regard to @b stacking. Two layers are completely disjoint in that
+ matter.
+
+ This is a low-level function, which you'd be using when something
+ should be always on top, for example.
+
+ @warning Be careful, it doesn't make sense to change the layer of
+ smart objects' children. Smart objects have a layer of their own,
+ which should contain all their children objects.
+
+ @see evas_object_layer_get() */
+ }
+ get {
+ /*@
+ Retrieves the layer of its canvas that the given object is part of.
+
+ @return Number of its layer
+
+ @see evas_object_layer_set() */
+ }
+ values {
+ short l; /*@ The number of the layer to place the object on.
+ Must be between #EVAS_LAYER_MIN and #EVAS_LAYER_MAX. */
+ }
+ }
+ below {
+ get {
+ /*@
+ Get the Evas object stacked right below @p obj
+
+ @return the #Efl_Gfx_Stack directly below @p obj, if any, or @c NULL,
+ if none
+
+ This function will traverse layers in its search, if there are
+ objects on layers below the one @p obj is placed at.
+
+ @see evas_object_layer_get()
+ @see evas_object_layer_set()
+ @see evas_object_below_get() */
+ return: Efl_Gfx_Stack * @warn_unused;
+ }
+ }
+ above {
+ get {
+ /*@
+ Get the Evas object stacked right above @p obj
+
+ @return the #Efl_Gfx_Stack directly above @p obj, if any, or @c NULL,
+ if none
+
+ This function will traverse layers in its search, if there are
+ objects on layers above the one @p obj is placed at.
+
+ @see evas_object_layer_get()
+ @see evas_object_layer_set()
+ @see evas_object_below_get() */
+ return: Efl_Gfx_Stack * @warn_unused;
+ }
+ }
+ }
+ methods {
+ stack_below {
+ /*@
+ Stack @p obj immediately below @p below
+
+ Objects, in a given canvas, are stacked in the order they get added
+ to it. This means that, if they overlap, the highest ones will
+ cover the lowest ones, in that order. This function is a way to
+ change the stacking order for the objects.
+
+ This function is intended to be used with <b>objects belonging to
+ the same layer</b> in a given canvas, otherwise it will fail (and
+ accomplish nothing).
+
+ If you have smart objects on your canvas and @p obj is a member of
+ one of them, then @p below must also be a member of the same
+ smart object.
+
+ Similarly, if @p obj is not a member of a smart object, @p below
+ must not be either.
+
+ @see evas_object_layer_get()
+ @see evas_object_layer_set()
+ @see evas_object_stack_below() */
+
+ params {
+ @in Efl_Gfx_Stack *below @nonull; /*@ the object below which to stack */
+ }
+ }
+ raise {
+ /*@
+ Raise @p obj to the top of its layer.
+
+ @p obj will, then, be the highest one in the layer it belongs
+ to. Object on other layers won't get touched.
+
+ @see evas_object_stack_above()
+ @see evas_object_stack_below()
+ @see evas_object_lower() */
+
+ }
+ stack_above {
+ /*@
+ Stack @p obj immediately above @p above
+
+ Objects, in a given canvas, are stacked in the order they get added
+ to it. This means that, if they overlap, the highest ones will
+ cover the lowest ones, in that order. This function is a way to
+ change the stacking order for the objects.
+
+ This function is intended to be used with <b>objects belonging to
+ the same layer</b> in a given canvas, otherwise it will fail (and
+ accomplish nothing).
+
+ If you have smart objects on your canvas and @p obj is a member of
+ one of them, then @p above must also be a member of the same
+ smart object.
+
+ Similarly, if @p obj is not a member of a smart object, @p above
+ must not be either.
+
+ @see evas_object_layer_get()
+ @see evas_object_layer_set()
+ @see evas_object_stack_below() */
+
+ params {
+ @in Efl_Gfx_Stack *above @nonull; /*@ the object above which to stack */
+ }
+ }
+ lower {
+ /*@
+ Lower @p obj to the bottom of its layer.
+
+ @p obj will, then, be the lowest one in the layer it belongs
+ to. Objects on other layers won't get touched.
+
+ @see evas_object_stack_above()
+ @see evas_object_stack_below()
+ @see evas_object_raise() */
+
+ }
+ }
+}
--- /dev/null
+interface Efl.Gfx.View {
+ legacy_prefix: null;
+ properties {
+ size {
+ set {
+ /*@
+ Sets the size of the given image object.
+
+ This function will scale down or crop the image so that it is
+ treated as if it were at the given size. If the size given is
+ smaller than the image, it will be cropped. If the size given is
+ larger, then the image will be treated as if it were in the upper
+ left hand corner of a larger image that is otherwise transparent. */
+ }
+ get {
+ /*@
+ Retrieves the size of the given image object.
+
+ See @ref evas_object_image_size_set() for more details. */
+ }
+ values {
+ int w; /*@ The new width of the image. */
+ int h; /*@ The new height of the image. */
+ }
+ }
+ }
+}
#include "interfaces/efl_text_properties.eo.c"
#include "interfaces/efl_gfx_base.eo.c"
-#include "interfaces/efl_gfx_shape.eo.c"
-#include "interfaces/efl_gfx_gradient.eo.c"
+#include "interfaces/efl_gfx_stack.eo.c"
+#include "interfaces/efl_gfx_fill.eo.c"
+#include "interfaces/efl_gfx_view.eo.c"
+
+#include "interfaces/efl_gfx_gradient_base.eo.c"
#include "interfaces/efl_gfx_gradient_linear.eo.c"
#include "interfaces/efl_gfx_gradient_radial.eo.c"
+
+EAPI const Eo_Event_Description _EFL_GFX_CHANGED =
+ EO_EVENT_DESCRIPTION("Graphics changed", "The visual representation of the object changed");
+
+EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
+ EO_EVENT_DESCRIPTION("Graphics path changed", "The path of a shape object changed");
/* This define is used in H files generated by Eolian */
#define _EVAS_OBJECT_EO_CLASS_TYPE
+/**
+ * Type of abstract VG node
+ */
+typedef Eo Efl_VG;
+
typedef void Evas_Performance; /**< An Evas Performance handle */
typedef struct _Evas_Modifier Evas_Modifier; /**< An opaque type containing information on which modifier keys are registered in an Evas canvas */
typedef struct _Evas_Lock Evas_Lock; /**< An opaque type containing information on which lock keys are registered in an Evas canvas */
EVAS_ALLOC_ERROR_RECOVERED = 2 /**< Allocation succeeded, but extra memory had to be found by freeing up speculative resources */
} Evas_Alloc_Error; /**< Possible allocation errors returned by evas_alloc_error() */
-typedef enum _Evas_Fill_Spread
-{
- EVAS_TEXTURE_REFLECT = 0, /**< image fill tiling mode - tiling reflects */
- EVAS_TEXTURE_REPEAT = 1, /**< tiling repeats */
- EVAS_TEXTURE_RESTRICT = 2, /**< tiling clamps - range offset ignored */
- EVAS_TEXTURE_RESTRICT_REFLECT = 3, /**< tiling clamps and any range offset reflects */
- EVAS_TEXTURE_RESTRICT_REPEAT = 4, /**< tiling clamps and any range offset repeats */
- EVAS_TEXTURE_PAD = 5 /**< tiling extends with end values */
-} Evas_Fill_Spread; /**< Fill types used for evas_object_image_fill_spread_set() */
+typedef Efl_Gfx_Fill_Spread Evas_Fill_Spread;
+#define EVAS_TEXTURE_REFLECT EFL_GFX_FILL_REFLECT
+#define EVAS_TEXTURE_REPEAT EFL_GFX_FILL_REPEAT
+#define EVAS_TEXTURE_RESTRICT EFL_GFX_FILL_RESTRICT
+#define EVAS_TEXTURE_RESTRICT_REFLECT EFL_GFX_FILL_RESTRICT_REFLECT
+#define EVAS_TEXTURE_RESTRICT_REPEAT EFL_GFX_FILL_RESTRICT_REPEAT
+#define EVAS_TEXTURE_PAD EFL_GFX_FILL_PAD
typedef enum _Evas_Pixel_Import_Pixel_Format
{
* @}
*/
-#include "canvas/evas_vg_node.eo.h"
-#include "canvas/evas_vg_container.eo.h"
-#include "canvas/evas_vg_shape.eo.h"
-#include "canvas/evas_vg_gradient.eo.h"
-#include "canvas/evas_vg_gradient_linear.eo.h"
-#include "canvas/evas_vg_gradient_radial.eo.h"
-#include "canvas/evas_vg_image.eo.h"
+#include "canvas/efl_vg_base.eo.h"
+#include "canvas/efl_vg_container.eo.h"
+#include "canvas/efl_vg_shape.eo.h"
+#include "canvas/efl_vg_gradient.eo.h"
+#include "canvas/efl_vg_gradient_linear.eo.h"
+#include "canvas/efl_vg_gradient_radial.eo.h"
+#include "canvas/efl_vg_image.eo.h"
*/
EAPI Evas_Object *evas_object_vg_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
-#include "canvas/evas_vg_node.eo.legacy.h"
#include "canvas/evas_vg.eo.legacy.h"
-#include "canvas/evas_vg_shape.eo.legacy.h"
-#include "canvas/evas_vg_gradient.eo.legacy.h"
-#include "canvas/evas_vg_gradient_linear.eo.legacy.h"
-#include "canvas/evas_vg_gradient_radial.eo.legacy.h"
-#include "canvas/evas_vg_image.eo.legacy.h"
-#include "canvas/evas_vg_root_node.eo.legacy.h"
+
+EAPI Eina_Bool evas_vg_node_visible_get(Eo *obj);
+EAPI void evas_vg_node_visible_set(Eo *obj, Eina_Bool v);
+EAPI void evas_vg_node_color_get(Eo *obj, int *r, int *g, int *b, int *a);
+EAPI void evas_vg_node_color_set(Eo *obj, int r, int g, int b, int a);
+EAPI void evas_vg_node_geometry_get(Eo *obj, int *x, int *y, int *w, int *h);
+EAPI void evas_vg_node_geometry_set(Eo *obj, int x, int y, int w, int h);
+EAPI void evas_vg_node_stack_below(Eo *obj, Eo *below);
+EAPI void evas_vg_node_stack_above(Eo *obj, Eo *above);
+EAPI void evas_vg_node_raise(Eo *obj);
+EAPI void evas_vg_node_lower(Eo *obj);
+
+#include "canvas/efl_vg_base.eo.legacy.h"
+
+EAPI double evas_vg_shape_stroke_scale_get(Eo *obj);
+EAPI void evas_vg_shape_stroke_scale_set(Eo *obj, double s);
+EAPI void evas_vg_shape_stroke_color_get(Eo *obj, int *r, int *g, int *b, int *a);
+EAPI void evas_vg_shape_stroke_color_set(Eo *obj, int r, int g, int b, int a);
+EAPI double evas_vg_shape_stroke_width_get(Eo *obj);
+EAPI void evas_vg_shape_stroke_width_set(Eo *obj, double w);
+EAPI double evas_vg_shape_stroke_location_get(Eo *obj);
+EAPI void evas_vg_shape_stroke_location_set(Eo *obj, double centered);
+EAPI void evas_vg_shape_stroke_dash_get(Eo *obj, const Efl_Gfx_Dash **dash, unsigned int *length);
+EAPI void evas_vg_shape_stroke_dash_set(Eo *obj, const Efl_Gfx_Dash *dash, unsigned int length);
+EAPI Efl_Gfx_Cap evas_vg_shape_stroke_cap_get(Eo *obj);
+EAPI void evas_vg_shape_stroke_cap_set(Eo *obj, Efl_Gfx_Cap c);
+EAPI Efl_Gfx_Join evas_vg_shape_stroke_join_get(Eo *obj);
+EAPI void evas_vg_shape_stroke_join_set(Eo *obj, Efl_Gfx_Join j);
+EAPI void evas_vg_shape_shape_path_set(Eo *obj, const Efl_Gfx_Path_Command *op, const double *points);
+EAPI void evas_vg_shape_shape_path_get(Eo *obj, const Efl_Gfx_Path_Command **op, const double **points);
+EAPI void evas_vg_shape_shape_path_length_get(Eo *obj, unsigned int *commands, unsigned int *points);
+EAPI void evas_vg_shape_shape_current_get(Eo *obj, double *x, double *y);
+EAPI void evas_vg_shape_shape_current_ctrl_get(Eo *obj, double *x, double *y);
+EAPI void evas_vg_shape_shape_dup(Eo *obj, Eo *dup_from);
+EAPI void evas_vg_shape_shape_reset(Eo *obj);
+EAPI void evas_vg_shape_shape_append_move_to(Eo *obj, double x, double y);
+EAPI void evas_vg_shape_shape_append_line_to(Eo *obj, double x, double y);
+EAPI void evas_vg_shape_shape_append_quadratic_to(Eo *obj, double x, double y, double ctrl_x, double ctrl_y);
+EAPI void evas_vg_shape_shape_append_squadratic_to(Eo *obj, double x, double y);
+EAPI void evas_vg_shape_shape_append_cubic_to(Eo *obj, double x, double y, double ctrl_x0, double ctrl_y0, double ctrl_x1, double ctrl_y1);
+EAPI void evas_vg_shape_shape_append_scubic_to(Eo *obj, double x, double y, double ctrl_x, double ctrl_y);
+EAPI void evas_vg_shape_shape_append_arc_to(Eo *obj, double x, double y, double rx, double ry, double angle, Eina_Bool large_arc, Eina_Bool sweep);
+EAPI void evas_vg_shape_shape_append_close(Eo *obj);
+EAPI void evas_vg_shape_shape_append_circle(Eo *obj, double x, double y, double radius);
+EAPI void evas_vg_shape_shape_append_rect(Eo *obj, double x, double y, double w, double h, double rx, double ry);
+EAPI void evas_vg_shape_shape_append_svg_path(Eo *obj, const char *svg_path_data);
+EAPI Eina_Bool evas_vg_shape_shape_interpolate(Eo *obj, const Eo *from, const Eo *to, double pos_map);
+EAPI Eina_Bool evas_vg_shape_shape_equal_commands(Eo *obj, const Eo *with);
+
+#include "canvas/efl_vg_shape.eo.legacy.h"
+
+EAPI void evas_vg_gradient_stop_set(Eo *obj, const Efl_Gfx_Gradient_Stop *colors, unsigned int length);
+EAPI void evas_vg_gradient_stop_get(Eo *obj, const Efl_Gfx_Gradient_Stop **colors, unsigned int *length);
+EAPI void evas_vg_gradient_spread_set(Eo *obj, Efl_Gfx_Gradient_Spread s);
+EAPI Efl_Gfx_Gradient_Spread evas_vg_gradient_spread_get(Eo *obj);
+
+#include "canvas/efl_vg_gradient.eo.legacy.h"
+
+EAPI void evas_vg_gradient_linear_start_set(Eo *obj, double x, double y);
+EAPI void evas_vg_gradient_linear_start_get(Eo *obj, double *x, double *y);
+EAPI void evas_vg_gradient_linear_end_set(Eo *obj, double x, double y);
+EAPI void evas_vg_gradient_linear_end_get(Eo *obj, double *x, double *y);
+
+#include "canvas/efl_vg_gradient_linear.eo.legacy.h"
+
+EAPI void evas_vg_gradient_radial_center_set(Eo *obj, double x, double y);
+EAPI void evas_vg_gradient_radial_center_get(Eo *obj, double *x, double *y);
+EAPI void evas_vg_gradient_radial_radius_set(Eo *obj, double r);
+EAPI double evas_vg_gradient_radial_radius_get(Eo *obj);
+EAPI void evas_vg_gradient_radial_focal_set(Eo *obj, double x, double y);
+EAPI void evas_vg_gradient_radial_focal_get(Eo *obj, double *x, double *y);
+
+#include "canvas/efl_vg_gradient_radial.eo.legacy.h"
+>>>>>>> f359123... ector : integration of ector library in efl1.30.0 branch for tizen2.4
/**
* @}
--- /dev/null
+abstract Efl.VG.Base (Eo.Base, Efl.Gfx.Base, Efl.Gfx.Stack)
+{
+ eo_prefix: efl_vg;
+ legacy_prefix: evas_vg_node;
+ properties {
+ transformation {
+ set {
+ /*@
+ Sets the transformation matrix to be used for this node object.
+ @since 1.14
+ */
+ }
+ get {
+ /*@
+ Gets the transformation matrix used for this node object.
+ @since 1.14
+ */
+ }
+ values {
+ const(Eina_Matrix3) *m; /*@ transformation matrix */
+ }
+ }
+ origin {
+ set {
+ /*@
+ Sets the origin position of this node object. This origin position
+ affects to node transformation
+ @since 1.14
+ */
+ }
+ get {
+ /*@
+ Gets the origin position of this node object.
+ @since 1.14
+ */
+ }
+ values {
+ double x; /* @origin x position */
+ double y; /* @origin y position */
+ }
+ }
+ mask {
+ set {
+ }
+ get {
+ }
+ values {
+ Efl_VG *m;
+ }
+ }
+/* quality {
+ set {
+ }
+ get {
+ }
+ values {
+ Evas_VG_Quality q;
+ }
+ } */
+ }
+ methods {
+ bound_get {
+ /*@
+ Give the bounding box in screen coordinate as being drawn.
+ It will start as the control box until it is refined once the shape
+ is computed.
+ @since 1.14
+ */
+ return: bool @warn_unused;
+ params {
+ @out Eina_Rectangle r; /*@ bounding box to be returned */
+ }
+ }
+ original_bound_get {
+ /*@
+ Give the bounding box in screen coordinate as defined in
+ the file or at the insertion of the object (before any scaling).
+ @since 1.14
+ */
+ return: bool @warn_unused;
+ params {
+ @out Eina_Rectangle r; /*@ original bounding box to be returned */
+ }
+ }
+ }
+ implements {
+ Eo.Base.parent.set;
+ Eo.Base.constructor;
+ Efl.Gfx.Base.visible.set;
+ Efl.Gfx.Base.visible.get;
+ Efl.Gfx.Base.color.set;
+ Efl.Gfx.Base.color.get;
+ Efl.Gfx.Base.color_part.set;
+ Efl.Gfx.Base.color_part.get;
+ Efl.Gfx.Base.size.get;
+ Efl.Gfx.Base.position.set;
+ Efl.Gfx.Base.position.get;
+ Efl.Gfx.Stack.below.get;
+ Efl.Gfx.Stack.above.get;
+ Efl.Gfx.Stack.stack_below;
+ Efl.Gfx.Stack.stack_above;
+ Efl.Gfx.Stack.raise;
+ Efl.Gfx.Stack.lower;
+ @virtual .bound_get;
+ }
+}
\ No newline at end of file
--- /dev/null
+class Efl.VG.Container (Efl.VG.Base)
+{
+ legacy_prefix: evas_vg_container;
+ implements {
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ Efl.VG.Base.bound_get;
+ }
+}
--- /dev/null
+abstract Efl.VG.Gradient (Efl.VG.Base, Efl.Gfx.Gradient.Base)
+{
+ legacy_prefix: evas_vg_gradient;
+ implements {
+ Efl.Gfx.Gradient.Base.stop.set;
+ Efl.Gfx.Gradient.Base.stop.get;
+ Efl.Gfx.Gradient.Base.spread.set;
+ Efl.Gfx.Gradient.Base.spread.get;
+ }
+}
--- /dev/null
+class Efl.VG.Gradient_Linear (Efl.VG.Gradient, Efl.Gfx.Gradient.Linear)
+{
+ legacy_prefix: evas_vg_gradient_linear;
+ implements {
+ Efl.Gfx.Gradient.Linear.start.set;
+ Efl.Gfx.Gradient.Linear.start.get;
+ Efl.Gfx.Gradient.Linear.end.set;
+ Efl.Gfx.Gradient.Linear.end.get;
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
--- /dev/null
+class Efl.VG.Gradient_Radial (Efl.VG.Gradient, Efl.Gfx.Gradient.Radial)
+{
+ legacy_prefix: evas_vg_gradient_radial;
+ implements {
+ Efl.Gfx.Gradient.Radial.center.set;
+ Efl.Gfx.Gradient.Radial.center.get;
+ Efl.Gfx.Gradient.Radial.radius.set;
+ Efl.Gfx.Gradient.Radial.radius.get;
+ Efl.Gfx.Gradient.Radial.focal.set;
+ Efl.Gfx.Gradient.Radial.focal.get;
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
--- /dev/null
+class Efl.VG.Image (Efl.VG.Base, Efl.File)
+{
+ legacy_prefix: evas_vg_image;
+ properties {
+ position {
+ set {
+ }
+ get {
+ }
+ values {
+ int x;
+ int y;
+ }
+ }
+ size {
+ set {
+ }
+ get {
+ }
+ values {
+ uint w;
+ uint h;
+ }
+ }
+ // FIXME: add aspect ratio following SVG specification
+ }
+ implements {
+ Efl.File.file.set;
+ Efl.File.file.get;
+ Efl.File.mmap.set;
+ Efl.File.mmap.get;
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
\ No newline at end of file
--- /dev/null
+class Efl.VG.Root_Node (Efl.VG.Container)
+{
+ legacy_prefix: evas_vg_root_node;
+ implements {
+ Eo.Base.parent.set;
+ Eo.Base.constructor;
+ }
+}
--- /dev/null
+class Efl.VG.Shape (Efl.VG.Base, Efl.Gfx.Shape)
+{
+ legacy_prefix: evas_vg_shape;
+ properties {
+ fill {
+ set {
+ }
+ get {
+ }
+ values {
+ Efl_VG *f;
+ }
+ }
+ stroke_fill {
+ set {
+ }
+ get {
+ }
+ values {
+ Efl_VG *f;
+ }
+ }
+ stroke_marker {
+ set {
+ }
+ get {
+ }
+ values {
+ Efl_VG *m;
+ }
+ }
+ }
+ implements {
+ Efl.Gfx.Shape.stroke_scale;
+ Efl.Gfx.Shape.stroke_color;
+ Efl.Gfx.Shape.stroke_width;
+ Efl.Gfx.Shape.stroke_location;
+ Efl.Gfx.Shape.stroke_dash;
+ Efl.Gfx.Shape.stroke_cap;
+ Efl.Gfx.Shape.stroke_join;
+ Efl.Gfx.Base.color_part.set;
+ Efl.Gfx.Base.color_part.get;
+ Efl.VG.Base.bound_get;
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
#include "evas_private.h"
#include "evas_vg_private.h"
-#include "evas_vg_root_node.eo.h"
+#include "efl_vg_root_node.eo.h"
#define MY_CLASS EVAS_VG_CLASS
struct _Evas_VG_Data
{
- void *engine_data;
- Evas_VG_Node *root;
+ void *engine_data;
+ Efl_VG *root;
/* Opening an SVG file (could actually be inside an eet section */
Eina_File *f;
Eina_Rectangle fill;
- int width, height;
- void *backing_store;
+ unsigned int width, height;
};
static void evas_object_vg_render(Evas_Object *eo_obj,
return eo_obj;
}
-Evas_VG_Node *
+Efl_VG *
_evas_vg_root_node_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd)
{
return pd->root;
void
_evas_vg_eo_base_destructor(Eo *eo_obj, Evas_VG_Data *pd)
{
- if (pd->backing_store) {
- Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
- obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
- pd->backing_store);
- }
eo_unref(pd->root);
eo_do_super(eo_obj, MY_CLASS, eo_destructor());
}
obj->type = o_type;
/* root node */
- pd->root = eo_add(EVAS_VG_ROOT_NODE_CLASS, eo_obj);
+ pd->root = eo_add(EFL_VG_ROOT_NODE_CLASS, eo_obj);
eo_ref(pd->root);
eo_do(eo_obj, parent = eo_parent_get());
static void
_evas_vg_render(Evas_Object_Protected_Data *obj,
- void *output, void *context, void *surface, Evas_VG_Node *node,
- Eina_Array *clips, int x, int y, Eina_Bool do_async)
+ void *output, void *context, void *surface, Efl_VG *n,
+ Eina_Array *clips, Eina_Bool do_async)
{
- // FIXME if the class is not container ,
- // some times its returning garbage container data.
- if (eo_isa(node, EVAS_VG_CONTAINER_CLASS))
+ Efl_VG_Container_Data *vd = eo_data_scope_get(n, EFL_VG_CONTAINER_CLASS);
+
+ if (eo_isa(n, EFL_VG_CONTAINER_CLASS))
{
- Evas_VG_Container_Data *cd = eo_data_scope_get(node,
- EVAS_VG_CONTAINER_CLASS);
- Evas_VG_Node *child;
+ Efl_VG *child;
Eina_List *l;
- EINA_LIST_FOREACH(cd->children, l, child)
- _evas_vg_render(obj, output, context, surface, child, clips, x, y,
- do_async);
+ EINA_LIST_FOREACH(vd->children, l, child)
+ _evas_vg_render(obj,
+ output, context, surface, child,
+ clips, do_async);
}
else
{
- Evas_VG_Node_Data *nd = eo_data_scope_get(node, EVAS_VG_NODE_CLASS);
- obj->layer->evas->engine.func->ector_draw(output, context, surface,
- nd->renderer, clips, x, y,
- do_async);
+ Efl_VG_Base_Data *nd;
+
+ nd = eo_data_scope_get(n, EFL_VG_BASE_CLASS);
+
+ obj->layer->evas->engine.func->ector_renderer_draw(output, context, surface, nd->renderer, clips, do_async);
}
}
{
Evas_VG_Data *vd = type_private_data;
- vd->backing_store = obj->layer->evas->engine.func->ector_begin(obj->layer->evas->engine.data.output,
- vd->backing_store,
- obj->cur->geometry.w,
- obj->cur->geometry.h);
-
// FIXME: Set context (that should affect Ector_Surface) and
// then call Ector_Renderer render from bottom to top. Get the
// Ector_Surface that match the output from Evas engine API.
context);
obj->layer->evas->engine.func->context_render_op_set(output, context,
obj->cur->render_op);
- if (!vd->backing_store) {
+ obj->layer->evas->engine.func->ector_begin(output, context, surface,
+ obj->cur->geometry.x + x, obj->cur->geometry.y + y,
+ do_async);
_evas_vg_render(obj, output, context, surface, vd->root, NULL,
- obj->cur->geometry.x + x, obj->cur->geometry.y + y,
do_async);
- } else {
-
- _evas_vg_render(obj, output, context, vd->backing_store, vd->root, NULL,
- 0 , 0,
- do_async);
- obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, vd->backing_store,
- 0, 0, 0, 0);
- obj->layer->evas->engine.func->image_draw(output, context, surface,
- vd->backing_store, 0, 0,
- obj->cur->geometry.w, obj->cur->geometry.h, obj->cur->geometry.x + x,
- obj->cur->geometry.y + y, obj->cur->geometry.w, obj->cur->geometry.h,
- EINA_TRUE, do_async);
- }
+ obj->layer->evas->engine.func->ector_end(output, context, surface, do_async);
}
static void
void *type_private_data)
{
Evas_VG_Data *vd = type_private_data;
+ Efl_VG_Base_Data *rnd;
Evas_Public_Data *e = obj->layer->evas;
int is_v, was_v;
- Ector_Surface *surface;
- Eina_Bool change = EINA_FALSE;
+ Ector_Surface *s;
/* dont pre-render the obj twice! */
if (obj->pre_render_done) return;
obj->pre_render_done = EINA_TRUE;
+
/* pre-render phase. this does anything an object needs to do just before */
/* rendering. this could mean loading the image data, retrieving it from */
/* elsewhere, decoding video etc. */
if (!(is_v | was_v)) goto done;
// FIXME: handle damage only on changed renderer.
- surface = e->engine.func->ector_get(e->engine.data.output);
- if (surface)
- change = _evas_vg_render_pre(vd->root, surface, NULL);
-
- if (change)
+ s = e->engine.func->ector_get(e->engine.data.output);
+ if (vd->root && s)
+ _evas_vg_render_pre(vd->root, s, NULL);
+
+ // FIXME: for now the walking Evas_VG_Node tree doesn't trigger any damage
+ // So just forcing it here if necessary
+ rnd = eo_data_scope_get(vd->root, EFL_VG_BASE_CLASS);
+ if (rnd->changed)
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
- eo_obj, obj);
+ rnd->changed = EINA_FALSE;
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (is_v != was_v)
{
- evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes,
- eo_obj, is_v, was_v);
+ evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
goto done;
}
-
if (obj->changed_map || obj->changed_src_visible)
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
- eo_obj, obj);
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* it's not visible - we accounted for it appearing or not so just abort */
if (!is_v) goto done;
/* clipper changed this is in addition to anything else for obj */
- evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes,
- eo_obj);
+ evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, eo_obj);
/* if we restacked (layer or just within a layer) and don't clip anyone */
if ((obj->restack) && (!obj->clip.clipees))
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
- eo_obj, obj);
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* if it changed render op */
if (obj->cur->render_op != obj->prev->render_op)
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
- eo_obj, obj);
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* if it changed color */
(obj->cur->color.b != obj->prev->color.b) ||
(obj->cur->color.a != obj->prev->color.a))
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
- eo_obj, obj);
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* if it changed geometry - and obviously not visibility or color */
y + obj->layer->evas->framespace.y,
w, h);
}
-done:
- evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes,
- eo_obj, is_v, was_v);
+ done:
+ evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
}
static void
}
void
-_evas_vg_size_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
- unsigned int *w, unsigned int *h)
+_evas_vg_efl_gfx_view_size_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
+ int *w, int *h)
{
if (w) *w = pd->width;
if (h) *h = pd->height;
}
void
-_evas_vg_size_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
- unsigned int w, unsigned int h)
+_evas_vg_efl_gfx_view_size_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
+ int w, int h)
{
pd->width = w;
pd->height = h;
}
void
-_evas_vg_fill_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
- Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+_evas_vg_efl_gfx_fill_fill_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
+ int x, int y, int w, int h)
{
pd->fill.x = x;
pd->fill.y = y;
}
void
-_evas_vg_fill_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
- Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+_evas_vg_efl_gfx_fill_fill_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd,
+ int *x, int *y, int *w, int *h)
{
if (x) *x = pd->fill.x;
if (y) *y = pd->fill.y;
-class Evas.VG (Evas.Object, Efl.File)
+class Evas.VG (Evas.Object, Efl.File, Efl.Gfx.Fill, Efl.Gfx.View)
{
legacy_prefix: evas_object_vg;
eo_prefix: evas_obj_vg;
*/
}
values {
- Evas_VG_Node *container; /*@ Root node of the VG canvas */
- }
- }
- size {
- get {
- /*@
- Get the size as defined in the original data before any scaling
- (as in the file or when the object were added).
- @since 1.14
- */
- }
- set {
- /*@
- Set the size defined in the original data before any scaling
- (as in the file or when the object were added).
- @since 1.14
- */
- }
- values {
- uint w; /*@ width of the vg object */
- uint h; /*@ height of the vg object */
- }
- }
- fill {
- set {
- /*@
- Set how to fill an image object's drawing rectangle given the
- (real) image bound to it. Note that if @p w or @p h are smaller
- than the dimensions of @p obj, the displayed image will be
- @b tiled around the object's area. To have only one copy of the
- bound image drawn, @p x and @p y must be 0 and @p w and @p h
- need to be the exact width and height of the image object
- itself, respectively. See the following image to better
- understand the effects of this call. On this diagram, both
- image object and original image source have @c a x @c a
- dimensions and the image itself is a circle, with empty space
- around it:
-
- @image html image-fill.png
- @image rtf image-fill.png
- @image latex image-fill.eps
- @warning The default values for the fill parameters are
- @p x = 0, @p y = 0, @p w = 0 and @p h = 0. Thus,
- if you're not using the evas_object_image_filled_add()
- helper and want your image displayed, you'll have to
- set valid values with this function on your object.
- @note evas_object_image_filled_set() is a helper function which
- will @b override the values set here automatically, for
- you, in a given way.
- @sine 1.14 */
- }
- get {
- /*@
- Retrieve how an image object is to fill its drawing rectangle,
- given the (real) image bound to it.
-
- @note Use @c NULL pointers on the fill components you're not
- interested in: they'll be ignored by the function.
- See @ref evas_object_image_fill_set() for more details.
- @since 1.14 */
- }
- values {
- Evas_Coord x; /*@ The x coordinate (from the top left corner of
- the bound image) to start drawing from. */
- Evas_Coord y; /*@ The y coordinate (from the top left corner of
- the bound image) to start drawing from. */
- Evas_Coord w; /*@ The width the bound image will be displayed
- at. */
- Evas_Coord h; /*@ The height the bound image will be displayed
- at. */
+ Efl_VG *container; /*@ Root node of the VG canvas */
}
}
}
Efl.File.file.get;
Efl.File.mmap.set;
Efl.File.mmap.get;
+ Efl.Gfx.Fill.fill.set;
+ Efl.Gfx.Fill.fill.get;
+ Efl.Gfx.View.size.set;
+ Efl.Gfx.View.size.get;
}
}
#include "evas_vg_private.h"
-#define MY_CLASS EVAS_VG_CONTAINER_CLASS
+#define MY_CLASS EFL_VG_CONTAINER_CLASS
-static Eina_Bool
-_evas_vg_container_render_pre(Eo *obj EINA_UNUSED,
- Eina_Matrix3 *parent,
- Ector_Surface *s,
- void *data,
- Evas_VG_Node_Data *nd)
+static void
+_efl_vg_container_render_pre(Eo *obj EINA_UNUSED,
+ Eina_Matrix3 *parent,
+ Ector_Surface *s,
+ void *data,
+ Efl_VG_Base_Data *nd)
{
- Evas_VG_Container_Data *pd = data;
+ Efl_VG_Container_Data *pd = data;
Eina_List *l;
Eo *child;
- Eina_Bool change = EINA_FALSE;
- EVAS_VG_COMPUTE_MATRIX(current, parent, nd);
- EINA_LIST_FOREACH(pd->children, l, child)
- change |= _evas_vg_render_pre(child, s, current);
+ if (!nd->changed) return ;
+ nd->changed = EINA_FALSE;
- return change;
+ EFL_VG_COMPUTE_MATRIX(current, parent, nd);
+
+ EINA_LIST_FOREACH(pd->children, l, child)
+ _evas_vg_render_pre(child, s, current);
}
static void
-_evas_vg_container_eo_base_constructor(Eo *obj,
- Evas_VG_Container_Data *pd)
+_efl_vg_container_eo_base_constructor(Eo *obj,
+ Efl_VG_Container_Data *pd)
{
- Evas_VG_Node_Data *nd;
+ Efl_VG_Base_Data *nd;
eo_do_super(obj, MY_CLASS, eo_constructor());
- nd = eo_data_scope_get(obj, EVAS_VG_NODE_CLASS);
- nd->render_pre = &_evas_vg_container_render_pre;
+ nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+ nd->render_pre = _efl_vg_container_render_pre;
nd->data = pd;
}
static void
-_evas_vg_container_eo_base_destructor(Eo *obj,
- Evas_VG_Container_Data *pd EINA_UNUSED)
+_efl_vg_container_eo_base_destructor(Eo *obj,
+ Efl_VG_Container_Data *pd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, eo_destructor());
}
static Eina_Bool
-_evas_vg_container_evas_vg_node_bound_get(Eo *obj EINA_UNUSED,
- Evas_VG_Container_Data *pd,
- Eina_Rectangle *r)
+_efl_vg_container_efl_vg_base_bound_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Container_Data *pd,
+ Eina_Rectangle *r)
{
Eina_Rectangle s;
Eina_Bool first = EINA_TRUE;
{
if (first)
{
- eo_do(child, evas_vg_node_bound_get(r));
+ eo_do(child, efl_vg_bound_get(r));
first = EINA_FALSE;
}
else
{
- eo_do(child, evas_vg_node_bound_get(&s));
+ eo_do(child, efl_vg_bound_get(&s));
eina_rectangle_union(r, &s);
}
}
}
-#include "evas_vg_container.eo.c"
+#include "efl_vg_container.eo.c"
#include <strings.h>
-#define MY_CLASS EVAS_VG_GRADIENT_CLASS
-
static void
-_evas_vg_gradient_efl_gfx_gradient_stop_set(Eo *obj,
- Evas_VG_Gradient_Data *pd,
- const Efl_Gfx_Gradient_Stop *colors,
- unsigned int length)
+_efl_vg_gradient_efl_gfx_gradient_base_stop_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Data *pd,
+ const Efl_Gfx_Gradient_Stop *colors,
+ unsigned int length)
{
pd->colors = realloc(pd->colors, length * sizeof(Efl_Gfx_Gradient_Stop));
if (!pd->colors)
memcpy(pd->colors, colors, length * sizeof(Efl_Gfx_Gradient_Stop));
pd->colors_count = length;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_gradient_efl_gfx_gradient_stop_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Data *pd,
- const Efl_Gfx_Gradient_Stop **colors,
- unsigned int *length)
+_efl_vg_gradient_efl_gfx_gradient_base_stop_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Data *pd,
+ const Efl_Gfx_Gradient_Stop **colors,
+ unsigned int *length)
{
if (colors) *colors = pd->colors;
if (length) *length = pd->colors_count;
}
static void
-_evas_vg_gradient_efl_gfx_gradient_spread_set(Eo *obj,
- Evas_VG_Gradient_Data *pd,
- Efl_Gfx_Gradient_Spread s)
+_efl_vg_gradient_efl_gfx_gradient_base_spread_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Data *pd,
+ Efl_Gfx_Gradient_Spread s)
{
pd->s = s;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+
+ _efl_vg_base_changed(obj);
}
static Efl_Gfx_Gradient_Spread
-_evas_vg_gradient_efl_gfx_gradient_spread_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Data *pd)
+_efl_vg_gradient_efl_gfx_gradient_base_spread_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Data *pd)
{
return pd->s;
}
-#include "evas_vg_gradient.eo.c"
+EAPI void
+evas_vg_gradient_stop_set(Eo *obj, const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
+{
+ eo_do(obj, efl_gfx_gradient_stop_set(colors, length));
+}
+
+EAPI void
+evas_vg_gradient_stop_get(Eo *obj, const Efl_Gfx_Gradient_Stop **colors, unsigned int *length)
+{
+ eo_do(obj, efl_gfx_gradient_stop_get(colors, length));
+}
+
+EAPI void
+evas_vg_gradient_spread_set(Eo *obj, Efl_Gfx_Gradient_Spread s)
+{
+ eo_do(obj, efl_gfx_gradient_spread_set(s));
+}
+
+EAPI Efl_Gfx_Gradient_Spread
+evas_vg_gradient_spread_get(Eo *obj)
+{
+
+ return eo_do(obj, efl_gfx_gradient_spread_get());
+}
+
+#include "efl_vg_gradient.eo.c"
#include <strings.h>
-#define MY_CLASS EVAS_VG_GRADIENT_LINEAR_CLASS
+#define MY_CLASS EFL_VG_GRADIENT_LINEAR_CLASS
-typedef struct _Evas_VG_Gradient_Linear_Data Evas_VG_Gradient_Linear_Data;
-struct _Evas_VG_Gradient_Linear_Data
+typedef struct _Efl_VG_Gradient_Linear_Data Efl_VG_Gradient_Linear_Data;
+struct _Efl_VG_Gradient_Linear_Data
{
struct {
double x, y;
};
static void
-_evas_vg_gradient_linear_efl_gfx_gradient_linear_start_set(Eo *obj,
- Evas_VG_Gradient_Linear_Data *pd,
- double x, double y)
+_efl_vg_gradient_linear_efl_gfx_gradient_linear_start_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Linear_Data *pd,
+ double x, double y)
{
pd->start.x = x;
pd->start.y = y;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_gradient_linear_efl_gfx_gradient_linear_start_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Linear_Data *pd,
- double *x, double *y)
+_efl_vg_gradient_linear_efl_gfx_gradient_linear_start_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Linear_Data *pd,
+ double *x, double *y)
{
if (x) *x = pd->start.x;
if (y) *y = pd->start.y;
}
static void
-_evas_vg_gradient_linear_efl_gfx_gradient_linear_end_set(Eo *obj,
- Evas_VG_Gradient_Linear_Data *pd,
- double x, double y)
+_efl_vg_gradient_linear_efl_gfx_gradient_linear_end_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Linear_Data *pd,
+ double x, double y)
{
pd->end.x = x;
pd->end.y = y;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Linear_Data *pd,
- double *x, double *y)
+_efl_vg_gradient_linear_efl_gfx_gradient_linear_end_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Linear_Data *pd,
+ double *x, double *y)
{
if (x) *x = pd->end.x;
if (y) *y = pd->end.y;
}
-static Eina_Bool
-_evas_vg_gradient_linear_render_pre(Eo *obj,
- Eina_Matrix3 *parent,
- Ector_Surface *s,
- void *data,
- Evas_VG_Node_Data *nd)
+static void
+_efl_vg_gradient_linear_render_pre(Eo *obj,
+ Eina_Matrix3 *parent,
+ Ector_Surface *s,
+ void *data,
+ Efl_VG_Base_Data *nd)
{
- Evas_VG_Gradient_Linear_Data *pd = data;
- Evas_VG_Gradient_Data *gd = eo_data_scope_get(obj, EVAS_VG_GRADIENT_CLASS);
- EVAS_VG_COMPUTE_MATRIX(current, parent, nd);
+ Efl_VG_Gradient_Linear_Data *pd = data;
+ Efl_VG_Gradient_Data *gd;
+
+ if (!nd->changed) return ;
+ nd->changed = EINA_FALSE;
+
+ gd = eo_data_scope_get(obj, EFL_VG_GRADIENT_CLASS);
+ EFL_VG_COMPUTE_MATRIX(current, parent, nd);
if (!nd->renderer)
{
- eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_CLASS));
+ eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN));
}
eo_do(nd->renderer,
efl_gfx_gradient_linear_start_set(pd->start.x, pd->start.y),
efl_gfx_gradient_linear_end_set(pd->end.x, pd->end.y),
ector_renderer_prepare());
-
- return EINA_TRUE;
}
static void
-_evas_vg_gradient_linear_eo_base_constructor(Eo *obj,
- Evas_VG_Gradient_Linear_Data *pd)
+_efl_vg_gradient_linear_eo_base_constructor(Eo *obj,
+ Efl_VG_Gradient_Linear_Data *pd)
{
- Evas_VG_Node_Data *nd;
+ Efl_VG_Base_Data *nd;
eo_do_super(obj, MY_CLASS, eo_constructor());
- nd = eo_data_scope_get(obj, EVAS_VG_NODE_CLASS);
- nd->render_pre = &_evas_vg_gradient_linear_render_pre;
+ nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+ nd->render_pre = _efl_vg_gradient_linear_render_pre;
nd->data = pd;
}
void
-_evas_vg_gradient_linear_eo_base_destructor(Eo *obj, Evas_VG_Gradient_Linear_Data *pd EINA_UNUSED)
+_efl_vg_gradient_linear_eo_base_destructor(Eo *obj, Efl_VG_Gradient_Linear_Data *pd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, eo_destructor());
}
-#include "evas_vg_gradient_linear.eo.c"
+EAPI void
+evas_vg_gradient_linear_start_set(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_gradient_linear_start_set(x, y));
+}
+
+EAPI void
+evas_vg_gradient_linear_start_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_gradient_linear_start_get(x, y));
+}
+
+EAPI void
+evas_vg_gradient_linear_end_set(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_gradient_linear_end_set(x, y));
+}
+
+EAPI void
+evas_vg_gradient_linear_end_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_gradient_linear_end_get(x, y));
+}
+
+#include "efl_vg_gradient_linear.eo.c"
#include "evas_vg_private.h"
-#define MY_CLASS EVAS_VG_GRADIENT_RADIAL_CLASS
+#define MY_CLASS EFL_VG_GRADIENT_RADIAL_CLASS
-typedef struct _Evas_VG_Gradient_Radial_Data Evas_VG_Gradient_Radial_Data;
-struct _Evas_VG_Gradient_Radial_Data
+typedef struct _Efl_VG_Gradient_Radial_Data Efl_VG_Gradient_Radial_Data;
+struct _Efl_VG_Gradient_Radial_Data
{
struct {
double x, y;
};
static void
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_center_set(Eo *obj,
- Evas_VG_Gradient_Radial_Data *pd,
- double x, double y)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_center_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd,
+ double x, double y)
{
pd->center.x = x;
pd->center.y = y;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_center_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Radial_Data *pd,
- double *x, double *y)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_center_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd,
+ double *x, double *y)
{
if (x) *x = pd->center.x;
if (y) *y = pd->center.y;
}
static void
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_radius_set(Eo *obj,
- Evas_VG_Gradient_Radial_Data *pd,
- double r)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_radius_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd,
+ double r)
{
pd->radius = r;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+
+ _efl_vg_base_changed(obj);
}
static double
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_radius_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Radial_Data *pd)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_radius_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd)
{
return pd->radius;
}
static void
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_focal_set(Eo *obj,
- Evas_VG_Gradient_Radial_Data *pd,
- double x, double y)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_focal_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd,
+ double x, double y)
{
pd->focal.x = x;
pd->focal.y = y;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_gradient_radial_efl_gfx_gradient_radial_focal_get(Eo *obj EINA_UNUSED,
- Evas_VG_Gradient_Radial_Data *pd,
- double *x, double *y)
+_efl_vg_gradient_radial_efl_gfx_gradient_radial_focal_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Gradient_Radial_Data *pd,
+ double *x, double *y)
{
if (x) *x = pd->focal.x;
if (y) *y = pd->focal.y;
}
-static Eina_Bool
-_evas_vg_gradient_radial_render_pre(Eo *obj,
+static void
+_efl_vg_gradient_radial_render_pre(Eo *obj,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
- Evas_VG_Node_Data *nd)
+ Efl_VG_Base_Data *nd)
{
- Evas_VG_Gradient_Radial_Data *pd = data;
- Evas_VG_Gradient_Data *gd = eo_data_scope_get(obj, EVAS_VG_GRADIENT_CLASS);
- EVAS_VG_COMPUTE_MATRIX(current, parent, nd);
+ Efl_VG_Gradient_Radial_Data *pd = data;
+ Efl_VG_Gradient_Data *gd;
+
+ if (!nd->changed) return ;
+ nd->changed = EINA_FALSE;
+
+ gd = eo_data_scope_get(obj, EFL_VG_GRADIENT_CLASS);
+ EFL_VG_COMPUTE_MATRIX(current, parent, nd);
if (!nd->renderer)
{
- eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_CLASS));
+ eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN));
}
eo_do(nd->renderer,
efl_gfx_gradient_radial_focal_set(pd->focal.x, pd->focal.y),
efl_gfx_gradient_radial_radius_set(pd->radius),
ector_renderer_prepare());
-
- return EINA_TRUE;
}
static void
-_evas_vg_gradient_radial_eo_base_constructor(Eo *obj, Evas_VG_Gradient_Radial_Data *pd)
+_efl_vg_gradient_radial_eo_base_constructor(Eo *obj, Efl_VG_Gradient_Radial_Data *pd)
{
- Evas_VG_Node_Data *nd;
+ Efl_VG_Base_Data *nd;
eo_do_super(obj, MY_CLASS, eo_constructor());
- nd = eo_data_scope_get(obj, EVAS_VG_NODE_CLASS);
- nd->render_pre = &_evas_vg_gradient_radial_render_pre;
+ nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+ nd->render_pre = _efl_vg_gradient_radial_render_pre;
nd->data = pd;
}
static void
-_evas_vg_gradient_radial_eo_base_destructor(Eo *obj,
- Evas_VG_Gradient_Radial_Data *pd EINA_UNUSED)
+_efl_vg_gradient_radial_eo_base_destructor(Eo *obj,
+ Efl_VG_Gradient_Radial_Data *pd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, eo_destructor());
}
-#include "evas_vg_gradient_radial.eo.c"
+EAPI void
+evas_vg_gradient_radial_center_set(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_gradient_radial_center_set(x, y));
+}
+
+EAPI void
+evas_vg_gradient_radial_center_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_gradient_radial_center_get(x, y));
+}
+
+EAPI void
+evas_vg_gradient_radial_radius_set(Eo *obj, double r)
+{
+ eo_do(obj, efl_gfx_gradient_radial_radius_set(r));
+}
+
+EAPI double
+evas_vg_gradient_radial_radius_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_gradient_radial_radius_get());
+}
+
+EAPI void
+evas_vg_gradient_radial_focal_set(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_gradient_radial_focal_set(x, y));
+}
+
+EAPI void
+evas_vg_gradient_radial_focal_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_gradient_radial_focal_get(x, y));
+}
+
+#include "efl_vg_gradient_radial.eo.c"
#include <strings.h>
-typedef struct _Evas_VG_Image_Data Evas_VG_Image_Data;
-struct _Evas_VG_Image_Data
+#include "evas_vg_private.h"
+
+typedef struct _Efl_VG_Image_Data Efl_VG_Image_Data;
+struct _Efl_VG_Image_Data
{
// FIXME: only manipulate Eina_File internally.
Eina_File *f;
};
static void
-_evas_vg_image_position_set(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
- int x, int y)
+_efl_vg_image_position_set(Eo *obj, Efl_VG_Image_Data *pd, int x, int y)
{
pd->x = x;
pd->y = y;
+
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_image_position_get(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
- int *x, int *y)
+_efl_vg_image_position_get(Eo *obj, Efl_VG_Image_Data *pd, int *x, int *y)
{
if (x) *x = pd->x;
if (y) *y = pd->y;
}
static void
-_evas_vg_image_size_set(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
+_efl_vg_image_size_set(Eo *obj, Efl_VG_Image_Data *pd,
unsigned int w, unsigned int h)
{
pd->w = w;
pd->h = h;
+
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_image_size_get(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
+_efl_vg_image_size_get(Eo *obj, Efl_VG_Image_Data *pd,
unsigned int *w, unsigned int *h)
{
if (w) *w = pd->w;
}
static Eina_Bool
-_evas_vg_image_efl_file_mmap_set(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
+_efl_vg_image_efl_file_mmap_set(Eo *obj EINA_UNUSED, Efl_VG_Image_Data *pd,
const Eina_File *f, const char *key)
{
Eina_File *tmp = pd->f;
eina_file_close(tmp);
eina_stringshare_replace(&pd->key, key);
+ _efl_vg_base_changed(obj);
+
return EINA_TRUE;
}
static void
-_evas_vg_image_efl_file_mmap_get(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
+_efl_vg_image_efl_file_mmap_get(Eo *obj EINA_UNUSED, Efl_VG_Image_Data *pd,
const Eina_File **f, const char **key)
{
if (f) *f = pd->f;
}
static Eina_Bool
-_evas_vg_image_efl_file_file_set(Eo *obj, Evas_VG_Image_Data *pd,
+_efl_vg_image_efl_file_file_set(Eo *obj, Efl_VG_Image_Data *pd,
const char *file, const char *key)
{
Eina_File *tmp;
Eina_Bool r;
tmp = eina_file_open(file, EINA_FALSE);
- r = _evas_vg_image_efl_file_mmap_set(obj, pd, tmp, key);
+ r = _efl_vg_image_efl_file_mmap_set(obj, pd, tmp, key);
eina_file_close(tmp);
return r;
}
static void
-_evas_vg_image_efl_file_file_get(Eo *obj EINA_UNUSED, Evas_VG_Image_Data *pd,
+_efl_vg_image_efl_file_file_get(Eo *obj EINA_UNUSED, Efl_VG_Image_Data *pd,
const char **file, const char **key)
{
if (file) *file = eina_file_filename_get(pd->f);
}
static void
-_evas_vg_image_eo_base_constructor(Eo *obj, Evas_VG_Image_Data *pd EINA_UNUSED)
+_efl_vg_image_eo_base_constructor(Eo *obj, Efl_VG_Image_Data *pd)
{
eo_error_set(obj);
}
static void
-_evas_vg_image_eo_base_destructor(Eo *obj, Evas_VG_Image_Data *pd EINA_UNUSED)
+_efl_vg_image_eo_base_destructor(Eo *obj, Efl_VG_Image_Data *pd)
{
eo_error_set(obj);
}
-#include "evas_vg_image.eo.c"
+#include "efl_vg_image.eo.c"
static Eina_Bool
_attrs_size_parser(void *data, const char *key, const char *value)
{
- unsigned int width, height;
+ int width, height;
Evas_Object *vg = data;
Eina_Bool get_w = EINA_FALSE, get_h = EINA_FALSE;
- eo_do(vg, evas_obj_vg_size_get(&width, &height));
+ eo_do(vg, efl_gfx_view_size_get(&width, &height));
if (!strcmp(key, "width"))
get_w = EINA_TRUE;
else if (!strcmp(key, "height"))
if (get_w) width = r;
else if (get_h) height = r;
}
- eo_do(vg, evas_obj_vg_size_set(width, height));
+ eo_do(vg, efl_gfx_view_size_set(width, height));
}
return EINA_TRUE;
_attrs_id_parser, &id);
if (!id) return EINA_FALSE;
- node = eo_add(EVAS_VG_GRADIENT_LINEAR_CLASS, NULL);
+ node = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, NULL);
if (!node) return EINA_FALSE;
eina_hash_direct_add(loader->definition, id, node);
if (((int)eina_array_count(loader->stack) - 1) < 0) return EINA_FALSE;
node = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1);
- if (!eo_isa(node, EFL_GFX_GRADIENT_INTERFACE))
+ if (!eo_isa(node, EFL_GFX_GRADIENT_BASE_INTERFACE))
return EINA_FALSE;
eina_simple_xml_attributes_parse(attrs, attrs_length,
parent = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1);
- node = eo_add(EVAS_VG_CONTAINER_CLASS, parent);
+ node = eo_add(EFL_VG_CONTAINER_CLASS, parent);
eina_array_push(loader->stack, node);
return EINA_TRUE;
#include <string.h>
#include <math.h>
-#define MY_CLASS EVAS_VG_NODE_CLASS
+#define MY_CLASS EFL_VG_BASE_CLASS
-// FIXME:
-// - share private structure with evas_object_vg
-// - mark parent canvas evas_object dirty after any change on the object
-// - add a virtual render function as part of the private data field
+static Eina_Bool
+_efl_vg_base_property_changed(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
+{
+ Efl_VG_Base_Data *pd = data;
+ Eo *parent;
+
+ if (pd->changed) return EINA_TRUE;
+ pd->changed = EINA_TRUE;
+
+ eo_do(obj, parent = eo_parent_get());
+ eo_do(parent, eo_event_callback_call(desc, event_info));
+ return EINA_TRUE;
+}
void
-_evas_vg_node_transformation_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- const Eina_Matrix3 *m)
+_efl_vg_base_transformation_set(Eo *obj,
+ Efl_VG_Base_Data *pd,
+ const Eina_Matrix3 *m)
{
if (!pd->m)
{
if (!pd->m) return ;
}
memcpy(pd->m, m, sizeof (Eina_Matrix3));
+
+ _efl_vg_base_changed(obj);
}
const Eina_Matrix3 *
-_evas_vg_node_transformation_get(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+_efl_vg_base_transformation_get(Eo *obj EINA_UNUSED, Efl_VG_Base_Data *pd)
{
return pd->m;
}
void
-_evas_vg_node_origin_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- double x, double y)
+_efl_vg_base_origin_set(Eo *obj,
+ Efl_VG_Base_Data *pd,
+ double x, double y)
{
pd->x = x;
pd->y = y;
+
+ _efl_vg_base_changed(obj);
}
void
-_evas_vg_node_origin_get(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- double *x, double *y)
+_efl_vg_base_origin_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ double *x, double *y)
{
if (x) *x = pd->x;
if (y) *y = pd->y;
}
void
-_evas_vg_node_efl_gfx_base_position_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- int x, int y)
+_efl_vg_base_efl_gfx_base_position_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ int x, int y)
{
pd->x = lrint(x);
pd->y = lrint(y);
+
+ _efl_vg_base_changed(obj);
}
void
-_evas_vg_node_efl_gfx_base_position_get(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- int *x, int *y)
+_efl_vg_base_efl_gfx_base_position_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ int *x, int *y)
{
if (x) *x = pd->x;
if (y) *y = pd->y;
}
void
-_evas_vg_node_efl_gfx_base_visible_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd, Eina_Bool v)
+_efl_vg_base_efl_gfx_base_visible_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd, Eina_Bool v)
{
pd->visibility = v;
+
+ _efl_vg_base_changed(obj);
}
Eina_Bool
-_evas_vg_node_efl_gfx_base_visible_get(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd)
+_efl_vg_base_efl_gfx_base_visible_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd)
{
return pd->visibility;
}
void
-_evas_vg_node_efl_gfx_base_color_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- int r, int g, int b, int a)
+_efl_vg_base_efl_gfx_base_color_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ int r, int g, int b, int a)
{
+ if (r > 255) r = 255; if (r < 0) r = 0;
+ if (g > 255) g = 255; if (g < 0) g = 0;
+ if (b > 255) b = 255; if (b < 0) b = 0;
+ if (a > 255) a = 255; if (a < 0) a = 0;
+ if (r > a)
+ {
+ r = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+ if (g > a)
+ {
+ g = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+ if (b > a)
+ {
+ b = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+
pd->r = r;
pd->g = g;
pd->b = b;
pd->a = a;
+
+ _efl_vg_base_changed(obj);
+}
+
+Eina_Bool
+_efl_vg_base_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Base_Data *pd,
+ const char *part,
+ int r, int g, int b, int a)
+{
+ if (part) return EINA_FALSE;
+
+ _efl_vg_base_efl_gfx_base_color_set(obj, pd, r, g, b, a);
+ return EINA_TRUE;
}
void
-_evas_vg_node_efl_gfx_base_color_get(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- int *r, int *g, int *b, int *a)
+_efl_vg_base_efl_gfx_base_color_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ int *r, int *g, int *b, int *a)
{
if (r) *r = pd->r;
if (g) *g = pd->g;
if (a) *a = pd->a;
}
+Eina_Bool
+_efl_vg_base_efl_gfx_base_color_part_get(Eo *obj, Efl_VG_Base_Data *pd,
+ const char *part,
+ int *r, int *g, int *b, int *a)
+{
+ if (part) return EINA_FALSE;
+
+ _efl_vg_base_efl_gfx_base_color_get(obj, pd, r, g, b, a);
+ return EINA_TRUE;
+}
+
void
-_evas_vg_node_mask_set(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd,
- Evas_VG_Node *r)
+_efl_vg_base_mask_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Base_Data *pd,
+ Efl_VG_Base *r)
{
- Evas_VG_Node *tmp = pd->mask;
+ Efl_VG_Base *tmp = pd->mask;
pd->mask = eo_ref(r);
eo_unref(tmp);
+
+ _efl_vg_base_changed(obj);
}
-Evas_VG_Node*
-_evas_vg_node_mask_get(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+Efl_VG_Base*
+_efl_vg_base_mask_get(Eo *obj EINA_UNUSED, Efl_VG_Base_Data *pd)
{
return pd->mask;
}
void
-_evas_vg_node_efl_gfx_base_size_get(Eo *obj,
- Evas_VG_Node_Data *pd EINA_UNUSED,
- int *w, int *h)
+_efl_vg_base_efl_gfx_base_size_get(Eo *obj,
+ Efl_VG_Base_Data *pd EINA_UNUSED,
+ int *w, int *h)
{
Eina_Rectangle bound = { 0, 0, 0, 0 };
- eo_do(obj, evas_vg_node_bound_get(&bound));
+ eo_do(obj, efl_vg_bound_get(&bound));
if (w) *w = bound.w;
if (h) *h = bound.h;
}
// Parent should be a container otherwise dismissing the stacking operation
static Eina_Bool
-_evas_vg_node_parent_checked_get(Eo *obj,
- Eo **parent, Evas_VG_Container_Data **cd)
+_efl_vg_base_parent_checked_get(Eo *obj,
+ Eo **parent,
+ Efl_VG_Container_Data **cd)
{
+ *cd = NULL;
eo_do(obj, *parent = eo_parent_get());
- if (eo_isa(*parent, EVAS_VG_CONTAINER_CLASS))
+
+ if (eo_isa(*parent, EFL_VG_CONTAINER_CLASS))
{
- *cd = eo_data_scope_get(*parent, EVAS_VG_CONTAINER_CLASS);
+ *cd = eo_data_scope_get(*parent, EFL_VG_CONTAINER_CLASS);
if (!*cd)
{
- ERR("Can't get EVAS_VG_CONTAINER_CLASS data.");
+ ERR("Can't get EFL_VG_CONTAINER_CLASS data.");
goto on_error;
}
}
+ else if (*parent != NULL)
+ {
+ ERR("Parent of unauthorized class.");
+ goto on_error;
+ }
+
return EINA_TRUE;
on_error:
+ *parent = NULL;
*cd = NULL;
return EINA_FALSE;
}
void
-_evas_vg_node_eo_base_constructor(Eo *obj,
- Evas_VG_Node_Data *pd EINA_UNUSED)
+_efl_vg_base_eo_base_constructor(Eo *obj,
+ Efl_VG_Base_Data *pd)
{
- Evas_VG_Container_Data *cd = NULL;
+ Efl_VG_Container_Data *cd = NULL;
Eo *parent;
- Evas_VG_Node_Data *parent_nd = NULL;
eo_do_super(obj, MY_CLASS, eo_constructor());
- if (!_evas_vg_node_parent_checked_get(obj, &parent, &cd))
+ if (!_efl_vg_base_parent_checked_get(obj, &parent, &cd))
eo_error_set(obj);
- //Link the vector object
- if (parent)
- {
- parent_nd = eo_data_scope_get(parent, EVAS_VG_NODE_CLASS);
- pd->eo_vg = parent_nd->eo_vg;
- }
+ eo_do(obj, eo_event_callback_add(EFL_GFX_CHANGED, _efl_vg_base_property_changed, pd));
+ pd->changed = EINA_TRUE;
}
void
-_evas_vg_node_eo_base_parent_set(Eo *obj,
- Evas_VG_Node_Data *pd EINA_UNUSED,
- Eo *parent)
+_efl_vg_base_eo_base_parent_set(Eo *obj,
+ Efl_VG_Base_Data *pd EINA_UNUSED,
+ Eo *parent)
{
- Evas_VG_Container_Data *cd = NULL;
- Evas_VG_Container_Data *old_cd = NULL;
+ Efl_VG_Container_Data *cd = NULL;
+ Efl_VG_Container_Data *old_cd = NULL;
Eo *old_parent;
- if (eo_isa(parent, EVAS_VG_CONTAINER_CLASS))
+ if (eo_isa(parent, EFL_VG_CONTAINER_CLASS))
{
- cd = eo_data_scope_get(parent, EVAS_VG_CONTAINER_CLASS);
+ cd = eo_data_scope_get(parent, EFL_VG_CONTAINER_CLASS);
if (!cd)
{
- ERR("Can't get EVAS_VG_CONTAINER_CLASS data from %p.", parent);
+ ERR("Can't get EFL_VG_CONTAINER_CLASS data from %p.", parent);
goto on_error;
}
}
- else if (parent != NULL && !eo_isa(parent, EVAS_VG_CLASS))
+ else if (parent != NULL)
{
ERR("%p not even an EVAS_VG_CLASS.", parent);
goto on_error;
}
- if (!_evas_vg_node_parent_checked_get(obj, &old_parent, &old_cd))
+ if (!_efl_vg_base_parent_checked_get(obj, &old_parent, &old_cd))
goto on_error;
// FIXME: this may become slow with to much object
if (cd)
cd->children = eina_list_append(cd->children, obj);
+ _efl_vg_base_changed(old_parent);
+ _efl_vg_base_changed(obj);
+ _efl_vg_base_changed(parent);
+
return ;
on_error:
}
void
-_evas_vg_node_raise(Eo *obj, Evas_VG_Node_Data *pd EINA_UNUSED)
+_efl_vg_base_efl_gfx_stack_raise(Eo *obj, Efl_VG_Base_Data *pd EINA_UNUSED)
{
- Evas_VG_Container_Data *cd;
+ Efl_VG_Container_Data *cd;
Eina_List *lookup, *next;
Eo *parent;
eo_do(obj, parent = eo_parent_get());
- cd = eo_data_scope_get(parent, EVAS_VG_CONTAINER_CLASS);
- if (!cd) goto on_error;
+ if (!eo_isa(parent, EFL_VG_CONTAINER_CLASS)) goto on_error;
+ cd = eo_data_scope_get(parent, EFL_VG_CONTAINER_CLASS);
// FIXME: this could become slow with to much object
lookup = eina_list_data_find_list(cd->children, obj);
cd->children = eina_list_remove_list(cd->children, lookup);
cd->children = eina_list_append_relative_list(cd->children, obj, next);
+ _efl_vg_base_changed(parent);
return ;
on_error:
}
void
-_evas_vg_node_stack_above(Eo *obj,
- Evas_VG_Node_Data *pd EINA_UNUSED,
- Evas_VG_Node *above)
+_efl_vg_base_efl_gfx_stack_stack_above(Eo *obj,
+ Efl_VG_Base_Data *pd EINA_UNUSED,
+ Efl_Gfx_Stack *above)
{
- Evas_VG_Container_Data *cd;
+ Efl_VG_Container_Data *cd;
Eina_List *lookup, *ref;
Eo *parent;
eo_do(obj, parent = eo_parent_get());
- cd = eo_data_scope_get(parent, EVAS_VG_CONTAINER_CLASS);
- if (!cd) goto on_error;
+ if (!eo_isa(parent, EFL_VG_CONTAINER_CLASS)) goto on_error;
+ cd = eo_data_scope_get(parent, EFL_VG_CONTAINER_CLASS);
// FIXME: this could become slow with to much object
lookup = eina_list_data_find_list(cd->children, obj);
cd->children = eina_list_remove_list(cd->children, lookup);
cd->children = eina_list_append_relative_list(cd->children, obj, ref);
+ _efl_vg_base_changed(parent);
return ;
on_error:
}
void
-_evas_vg_node_stack_below(Eo *obj,
- Evas_VG_Node_Data *pd EINA_UNUSED,
- Evas_Object *below)
+_efl_vg_base_efl_gfx_stack_stack_below(Eo *obj,
+ Efl_VG_Base_Data *pd EINA_UNUSED,
+ Efl_Gfx_Stack *below)
{
- Evas_VG_Container_Data *cd;
+ Efl_VG_Container_Data *cd;
Eina_List *lookup, *ref;
Eo *parent;
eo_do(obj, parent = eo_parent_get());
- cd = eo_data_scope_get(parent, EVAS_VG_CONTAINER_CLASS);
- if (!cd) goto on_error;
+ if (!eo_isa(parent, EFL_VG_CONTAINER_CLASS)) goto on_error;
+ cd = eo_data_scope_get(parent, EFL_VG_CONTAINER_CLASS);
// FIXME: this could become slow with to much object
lookup = eina_list_data_find_list(cd->children, obj);
cd->children = eina_list_remove_list(cd->children, lookup);
cd->children = eina_list_prepend_relative_list(cd->children, obj, ref);
+ _efl_vg_base_changed(parent);
return ;
on_error:
}
void
-_evas_vg_node_lower(Eo *obj, Evas_VG_Node_Data *pd EINA_UNUSED)
+_efl_vg_base_efl_gfx_stack_lower(Eo *obj, Efl_VG_Base_Data *pd EINA_UNUSED)
{
- Evas_VG_Container_Data *cd;
+ Efl_VG_Container_Data *cd;
Eina_List *lookup, *prev;
Eo *parent;
eo_do(obj, parent = eo_parent_get());
- cd = eo_data_scope_get(parent, EVAS_VG_CONTAINER_CLASS);
- if (!cd) goto on_error;
+ if (!eo_isa(parent, EFL_VG_CONTAINER_CLASS)) goto on_error;
+ cd = eo_data_scope_get(parent, EFL_VG_CONTAINER_CLASS);
// FIXME: this could become slow with to much object
lookup = eina_list_data_find_list(cd->children, obj);
cd->children = eina_list_remove_list(cd->children, lookup);
cd->children = eina_list_prepend_relative_list(cd->children, obj, prev);
+ _efl_vg_base_changed(parent);
return ;
on_error:
eo_error_set(obj);
}
+Efl_Gfx_Stack *
+_efl_vg_base_efl_gfx_stack_below_get(Eo *obj, Efl_VG_Base_Data *pd)
+{
+ // FIXME: need to implement bound_get
+ return NULL;
+}
+
+Efl_Gfx_Stack *
+_efl_vg_base_efl_gfx_stack_above_get(Eo *obj, Efl_VG_Base_Data *pd)
+{
+ // FIXME: need to implement bound_get
+ return NULL;
+}
+
Eina_Bool
-_evas_vg_node_original_bound_get(Eo *obj EINA_UNUSED,
- Evas_VG_Node_Data *pd EINA_UNUSED,
- Eina_Rectangle *r EINA_UNUSED)
+_efl_vg_base_original_bound_get(Eo *obj,
+ Efl_VG_Base_Data *pd,
+ Eina_Rectangle *r)
{
return EINA_FALSE;
}
+EAPI Eina_Bool
+evas_vg_node_visible_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_visible_get());
+}
-void
-_evas_vg_node_changed(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+EAPI void
+evas_vg_node_visible_set(Eo *obj, Eina_Bool v)
+{
+ eo_do(obj, efl_gfx_visible_set(v));
+}
+
+EAPI void
+evas_vg_node_color_get(Eo *obj, int *r, int *g, int *b, int *a)
+{
+ eo_do(obj, efl_gfx_color_get(r, g, b, a));
+}
+
+EAPI void
+evas_vg_node_color_set(Eo *obj, int r, int g, int b, int a)
+{
+ eo_do(obj, efl_gfx_color_set(r, g, b, a));
+}
+
+EAPI void
+evas_vg_node_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
+{
+ eo_do(obj,
+ efl_gfx_position_get(x, y),
+ efl_gfx_size_get(w, h));
+}
+
+EAPI void
+evas_vg_node_geometry_set(Eo *obj, int x, int y, int w, int h)
+{
+ eo_do(obj,
+ efl_gfx_position_set(x, y),
+ efl_gfx_size_set(w, h));
+}
+
+EAPI void
+evas_vg_node_stack_below(Eo *obj, Eo *below)
+{
+ eo_do(obj, efl_gfx_stack_below(below));
+}
+
+EAPI void
+evas_vg_node_stack_above(Eo *obj, Eo *above)
+{
+ eo_do(obj, efl_gfx_stack_above(above));
+}
+
+EAPI void
+evas_vg_node_raise(Eo *obj)
+{
+ eo_do(obj, efl_gfx_stack_raise());
+}
+
+EAPI void
+evas_vg_node_lower(Eo *obj)
{
- if (!pd->eo_vg) return;
- Evas_Object_Protected_Data *obj_vg = eo_data_scope_get(pd->eo_vg,
- EVAS_OBJECT_CLASS);
- evas_object_change(pd->eo_vg, obj_vg);
+ eo_do(obj, efl_gfx_stack_lower());
}
-#include "evas_vg_node.eo.c"
+#include "efl_vg_base.eo.c"
#include <Ector.h>
-typedef struct _Evas_VG_Node_Data Evas_VG_Node_Data;
-typedef struct _Evas_VG_Container_Data Evas_VG_Container_Data;
-typedef struct _Evas_VG_Gradient_Data Evas_VG_Gradient_Data;
+typedef struct _Efl_VG_Base_Data Efl_VG_Base_Data;
+typedef struct _Efl_VG_Container_Data Efl_VG_Container_Data;
+typedef struct _Efl_VG_Gradient_Data Efl_VG_Gradient_Data;
-struct _Evas_VG_Node_Data
+struct _Efl_VG_Base_Data
{
Eina_Matrix3 *m;
- Evas_VG_Node *mask;
+ Efl_VG *mask;
Ector_Renderer *renderer;
- Evas_VG *eo_vg;
- Eina_Bool (*render_pre)(Eo *obj, Eina_Matrix3 *parent, Ector_Surface *s, void *data, Evas_VG_Node_Data *nd);
+ void (*render_pre)(Eo *obj, Eina_Matrix3 *parent, Ector_Surface *s, void *data, Efl_VG_Base_Data *nd);
void *data;
double x, y;
Eina_Bool changed : 1;
};
-struct _Evas_VG_Container_Data
+struct _Efl_VG_Container_Data
{
Eina_List *children;
};
-struct _Evas_VG_Gradient_Data
+struct _Efl_VG_Gradient_Data
{
// FIXME: Later on we should deduplicate it somehow (Using Ector ?).
Efl_Gfx_Gradient_Stop *colors;
Efl_Gfx_Gradient_Spread s;
};
-static inline Eina_Bool
-_evas_vg_render_pre(Evas_VG_Node *node, Ector_Surface *s, Eina_Matrix3 *m)
+static inline Efl_VG_Base_Data *
+_evas_vg_render_pre(Efl_VG *child, Ector_Surface *s, Eina_Matrix3 *m)
{
- Evas_VG_Node_Data *nd;
-
- if (!node) return EINA_FALSE;
+ Efl_VG_Base_Data *child_nd = NULL;
// FIXME: Prevent infinite loop
- nd = eo_data_scope_get(node, EVAS_VG_NODE_CLASS);
- if (nd->render_pre) return nd->render_pre(node, m, s, nd->data, nd);
- else return EINA_FALSE;
+ if (child)
+ child_nd = eo_data_scope_get(child, EFL_VG_BASE_CLASS);
+ if (child_nd)
+ child_nd->render_pre(child, m, s, child_nd->data, child_nd);
+
+ return child_nd;
}
-#define EVAS_VG_COMPUTE_MATRIX(Current, Parent, Nd) \
- Eina_Matrix3 *Current = Nd->m; \
- Eina_Matrix3 _matrix_tmp; \
- \
+static inline void
+_efl_vg_base_changed(Eo *obj)
+{
+ eo_do(obj, eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+#define EFL_VG_COMPUTE_MATRIX(Current, Parent, Nd) \
+ Eina_Matrix3 *Current = Nd->m; \
+ Eina_Matrix3 _matrix_tmp, translate; \
+ \
if (Parent) \
{ \
if (Current) \
} \
else \
{ \
- Current = Parent; \
+ eina_matrix3_translate(&translate, -(Nd->x), -(Nd->y)); \
+ eina_matrix3_compose(Parent, &translate, &_matrix_tmp); \
+ eina_matrix3_translate(&translate, (Nd->x), (Nd->y)); \
+ eina_matrix3_compose(&_matrix_tmp, &translate, &_matrix_tmp); \
+ Current = &_matrix_tmp; \
} \
}
+
#endif
#include "evas_common_private.h"
#include "evas_private.h"
+
#include "evas_vg_private.h"
-#include "evas_vg_root_node.eo.h"
+#include "efl_vg_root_node.eo.h"
#include <string.h>
-#define MY_CLASS EVAS_VG_ROOT_NODE_CLASS
+#define MY_CLASS EFL_VG_ROOT_NODE_CLASS
-typedef struct _Evas_VG_Root_Node_Data Evas_VG_Root_Node_Data;
-struct _Evas_VG_Root_Node_Data
+typedef struct _Efl_VG_Root_Node_Data Efl_VG_Root_Node_Data;
+struct _Efl_VG_Root_Node_Data
{
+ Evas_Object *parent;
+ Evas_Object_Protected_Data *data;
};
static void
-evas_vg_root_node_vg_set(Evas_VG_Root_Node *root, Evas_VG *vg)
-{
- Evas_Object_Protected_Data *obj_vg;
- Evas_VG_Node_Data *nd;
-
- nd = eo_data_scope_get(root, EVAS_VG_NODE_CLASS);
- nd->eo_vg = vg;
- if (!vg) return;
- obj_vg = eo_data_scope_get(vg, EVAS_OBJECT_CLASS);
- evas_object_change(vg, obj_vg);
-}
-
-static Eina_Bool
_evas_vg_root_node_render_pre(Eo *obj EINA_UNUSED,
Eina_Matrix3 *parent,
Ector_Surface *s,
- void *data EINA_UNUSED,
- Evas_VG_Node_Data *nd)
+ void *data,
+ Efl_VG_Base_Data *nd)
{
- Evas_VG_Container_Data *cd = eo_data_scope_get(obj, EVAS_VG_CONTAINER_CLASS);
+ Efl_VG_Container_Data *pd = data;
Eina_List *l;
Eo *child;
- Eina_Bool change = EINA_FALSE;
- EVAS_VG_COMPUTE_MATRIX(current, parent, nd);
- EINA_LIST_FOREACH(cd->children, l, child)
- change |= _evas_vg_render_pre(child, s, current);
+ EFL_VG_COMPUTE_MATRIX(current, parent, nd);
- return change;
+ EINA_LIST_FOREACH(pd->children, l, child)
+ _evas_vg_render_pre(child, s, current);
+}
+
+static Eina_Bool
+_evas_vg_root_node_changed(void *data, Eo *obj,
+ const Eo_Event_Description *desc EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Efl_VG_Root_Node_Data *pd = data;
+ Efl_VG_Base_Data *bd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+
+ if (bd->changed) return EINA_TRUE;
+ bd->changed = EINA_TRUE;
+
+ if (pd->parent) evas_object_change(pd->parent, pd->data);
+ return EINA_TRUE;
}
void
-_evas_vg_root_node_eo_base_parent_set(Eo *obj,
- Evas_VG_Root_Node_Data *pd EINA_UNUSED,
- Eo *parent)
+_efl_vg_root_node_eo_base_parent_set(Eo *obj,
+ Efl_VG_Root_Node_Data *pd,
+ Eo *parent)
{
- // Nice little hack, jump over parent parent_set in Evas_VG_Root
- eo_do_super(obj, EVAS_VG_NODE_CLASS, eo_parent_set(parent));
+ // Nice little hack, jump over parent parent_set in Efl_VG_Root
+ eo_do_super(obj, EFL_VG_BASE_CLASS, eo_parent_set(parent));
if (parent && !eo_isa(parent, EVAS_VG_CLASS))
- eo_error_set(obj);
+ {
+ eo_error_set(obj);
+ }
+ else
+ {
+ pd->parent = parent;
+ pd->data = parent ? eo_data_scope_get(parent, EVAS_OBJECT_CLASS) : NULL;
+ }
}
void
-_evas_vg_root_node_eo_base_constructor(Eo *obj,
- Evas_VG_Root_Node_Data *pd EINA_UNUSED)
+_efl_vg_root_node_eo_base_constructor(Eo *obj,
+ Efl_VG_Root_Node_Data *pd)
{
+ Efl_VG_Container_Data *cd;
+ Efl_VG_Base_Data *nd;
Eo *parent;
- Evas_VG_Node_Data *nd;
- // Nice little hack, jump over parent constructor in Evas_VG_Root
- eo_do_super(obj, EVAS_VG_NODE_CLASS, eo_constructor());
+ // Nice little hack, jump over parent constructor in Efl_VG_Root
+ eo_do_super(obj, EFL_VG_BASE_CLASS, eo_constructor());
eo_do(obj, parent = eo_parent_get());
- nd = eo_data_scope_get(obj, EVAS_VG_NODE_CLASS);
- nd->render_pre = &_evas_vg_root_node_render_pre;
+ if (!eo_isa(parent, EVAS_VG_CLASS))
+ eo_error_set(obj);
- evas_vg_root_node_vg_set(obj, parent);
-}
+ cd = eo_data_scope_get(obj, EFL_VG_CONTAINER_CLASS);
+ cd->children = NULL;
-void
-_evas_vg_root_node_eo_base_destructor(Eo *obj,
- Evas_VG_Root_Node_Data *pd EINA_UNUSED)
-{
- evas_vg_root_node_vg_set(obj, NULL);
- eo_do_super(obj, MY_CLASS, eo_destructor());
+ nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+ nd->render_pre = _evas_vg_root_node_render_pre;
+ nd->data = cd;
+
+ eo_do(obj, eo_event_callback_add(EFL_GFX_CHANGED, _evas_vg_root_node_changed, pd));
}
-#include "evas_vg_root_node.eo.c"
+#include "efl_vg_root_node.eo.c"
#include "evas_vg_private.h"
-#define MY_CLASS EVAS_VG_SHAPE_CLASS
+#define MY_CLASS EFL_VG_SHAPE_CLASS
-typedef struct _Evas_VG_Shape_Data Evas_VG_Shape_Data;
-struct _Evas_VG_Shape_Data
+typedef struct _Efl_VG_Shape_Data Efl_VG_Shape_Data;
+struct _Efl_VG_Shape_Data
{
- Efl_Gfx_Path_Command *ops;
- double *points;
-
- Evas_VG_Node *fill;
+ Efl_VG *fill;
struct {
Efl_Gfx_Dash *dash;
- Evas_VG_Node *fill;
- Evas_VG_Node *marker;
+ Efl_VG *fill;
+ Efl_VG *marker;
double scale;
double width;
} stroke;
};
-static void
-_evas_vg_shape_efl_gfx_shape_path_set(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- const Efl_Gfx_Path_Command *ops,
- const double *points)
-{
- free(pd->points);
- pd->points = NULL;
- free(pd->ops);
- pd->ops = NULL;
- efl_gfx_path_dup(&pd->ops, &pd->points, ops, points);
-
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
-}
-
-static void
-_evas_vg_shape_efl_gfx_shape_path_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- const Efl_Gfx_Path_Command **op,
- const double **points)
-{
- if (op) *op = pd->ops;
- if (points) *points = pd->points;
-}
-
static Eina_Bool
-_evas_vg_shape_evas_vg_node_bound_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd EINA_UNUSED,
- Eina_Rectangle *r EINA_UNUSED)
+_efl_vg_shape_efl_vg_base_bound_get(Eo *obj,
+ Efl_VG_Shape_Data *pd,
+ Eina_Rectangle *r)
{
return EINA_FALSE;
}
static void
-_evas_vg_shape_fill_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- Evas_VG_Node *f)
+_efl_vg_shape_fill_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ Efl_VG *f)
{
- Evas_VG_Node *tmp = pd->fill;
+ Efl_VG *tmp = pd->fill;
pd->fill = eo_ref(f);
eo_unref(tmp);
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
-static Evas_VG_Node *
-_evas_vg_shape_fill_get(Eo *obj EINA_UNUSED, Evas_VG_Shape_Data *pd)
+static Efl_VG *
+_efl_vg_shape_fill_get(Eo *obj EINA_UNUSED, Efl_VG_Shape_Data *pd)
{
return pd->fill;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_scale_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- double s)
+_efl_vg_shape_efl_gfx_shape_stroke_scale_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ double s)
{
pd->stroke.scale = s;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static double
-_evas_vg_shape_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+_efl_vg_shape_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.scale;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_color_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- int r, int g, int b, int a)
+_efl_vg_shape_efl_gfx_shape_stroke_color_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ int r, int g, int b, int a)
{
pd->stroke.r = r;
pd->stroke.g = g;
pd->stroke.b = b;
pd->stroke.a = a;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+
+ _efl_vg_base_changed(obj);
+}
+
+static Eina_Bool
+_efl_vg_shape_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Shape_Data *pd,
+ const char * part,
+ int r, int g, int b, int a)
+{
+ Eina_Bool ret;
+
+ if (part && !strcmp(part, "stroke"))
+ {
+ _efl_vg_shape_efl_gfx_shape_stroke_color_set(obj, pd, r, g, b, a);
+ return EINA_TRUE;
+ }
+
+ eo_do_super(obj, EFL_VG_SHAPE_CLASS,
+ ret = efl_gfx_color_part_set(part, r, g, b, a));
+
+ return ret;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- int *r, int *g, int *b, int *a)
+_efl_vg_shape_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ int *r, int *g, int *b, int *a)
{
if (r) *r = pd->stroke.r;
if (g) *g = pd->stroke.g;
if (a) *a = pd->stroke.a;
}
+static Eina_Bool
+_efl_vg_shape_efl_gfx_base_color_part_get(Eo *obj, Efl_VG_Shape_Data *pd,
+ const char * part,
+ int *r, int *g, int *b, int *a)
+{
+ Eina_Bool ret;
+
+ if (part && !strcmp(part, "stroke"))
+ {
+ _efl_vg_shape_efl_gfx_shape_stroke_color_get(obj, pd, r, g, b, a);
+ return EINA_TRUE;
+ }
+
+ eo_do_super(obj, EFL_VG_SHAPE_CLASS,
+ ret = efl_gfx_color_part_get(part, r, g, b, a));
+
+ return ret;
+}
+
static void
-_evas_vg_shape_stroke_fill_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- Evas_VG_Node *f)
+_efl_vg_shape_stroke_fill_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ Efl_VG *f)
{
- Evas_VG_Node *tmp = pd->fill;
+ Efl_VG *tmp = pd->fill;
pd->stroke.fill = eo_ref(f);
eo_unref(tmp);
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
-static Evas_VG_Node *
-_evas_vg_shape_stroke_fill_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+static Efl_VG *
+_efl_vg_shape_stroke_fill_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.fill;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_width_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- double w)
+_efl_vg_shape_efl_gfx_shape_stroke_width_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ double w)
{
pd->stroke.width = w;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+
+ _efl_vg_base_changed(obj);
}
static double
-_evas_vg_shape_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+_efl_vg_shape_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.width;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_location_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- double centered)
+_efl_vg_shape_efl_gfx_shape_stroke_location_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ double centered)
{
pd->stroke.centered = centered;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+
+ _efl_vg_base_changed(obj);
}
static double
-_evas_vg_shape_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+_efl_vg_shape_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.centered;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_dash_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- const Efl_Gfx_Dash *dash,
- unsigned int length)
+_efl_vg_shape_efl_gfx_shape_stroke_dash_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ const Efl_Gfx_Dash *dash,
+ unsigned int length)
{
free(pd->stroke.dash);
pd->stroke.dash = NULL;
memcpy(pd->stroke.dash, dash, sizeof (Efl_Gfx_Dash) * length);
pd->stroke.dash_count = length;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- const Efl_Gfx_Dash **dash,
- unsigned int *length)
+_efl_vg_shape_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ const Efl_Gfx_Dash **dash,
+ unsigned int *length)
{
if (dash) *dash = pd->stroke.dash;
if (length) *length = pd->stroke.dash_count;
}
static void
-_evas_vg_shape_stroke_marker_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- Evas_VG_Shape *m)
+_efl_vg_shape_stroke_marker_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ Efl_VG_Shape *m)
{
- Evas_VG_Node *tmp = pd->stroke.marker;
+ Efl_VG *tmp = pd->stroke.marker;
pd->stroke.marker = eo_ref(m);
eo_unref(tmp);
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
-static Evas_VG_Shape *
-_evas_vg_shape_stroke_marker_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+static Efl_VG_Shape *
+_efl_vg_shape_stroke_marker_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.marker;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- Efl_Gfx_Cap c)
+_efl_vg_shape_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ Efl_Gfx_Cap c)
{
pd->stroke.cap = c;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static Efl_Gfx_Cap
-_evas_vg_shape_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+_efl_vg_shape_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.cap;
}
static void
-_evas_vg_shape_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd,
- Efl_Gfx_Join j)
+_efl_vg_shape_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd,
+ Efl_Gfx_Join j)
{
pd->stroke.join = j;
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
+ _efl_vg_base_changed(obj);
}
static Efl_Gfx_Join
-_evas_vg_shape_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
- Evas_VG_Shape_Data *pd)
+_efl_vg_shape_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
+ Efl_VG_Shape_Data *pd)
{
return pd->stroke.join;
}
static void
-_evas_vg_shape_efl_gfx_base_color_set(Eo *obj,
- Evas_VG_Shape_Data *pd,
- int r, int g, int b, int a)
+_efl_vg_shape_render_pre(Eo *obj EINA_UNUSED,
+ Eina_Matrix3 *parent,
+ Ector_Surface *s,
+ void *data,
+ Efl_VG_Base_Data *nd)
{
- eo_do_super(obj, MY_CLASS, efl_gfx_color_set(r, g, b, a));
- eo_do_super(obj, MY_CLASS, evas_vg_node_changed());
-}
+ Efl_VG_Shape_Data *pd = data;
+ Efl_VG_Base_Data *fill, *stroke_fill, *stroke_marker, *mask;
+ double xn = nd->x, yn = nd->y ;
-static Eina_Bool
-_evas_vg_shape_render_pre(Eo *obj EINA_UNUSED,
- Eina_Matrix3 *parent,
- Ector_Surface *s,
- void *data,
- Evas_VG_Node_Data *nd)
-{
- Evas_VG_Shape_Data *pd = data;
- Ector_Renderer *fill_r = NULL, *stroke_r = NULL;
- EVAS_VG_COMPUTE_MATRIX(current, parent, nd);
+ if (!nd->changed) return ;
+ nd->changed = EINA_FALSE;
- if(pd->fill)
- {
- _evas_vg_render_pre(pd->fill, s, current);
- Evas_VG_Node_Data *filld = eo_data_scope_get(pd->fill, EVAS_VG_NODE_CLASS);
- fill_r = filld->renderer;
- }
- if(pd->stroke.fill)
- {
- _evas_vg_render_pre(pd->stroke.fill, s, current);
- Evas_VG_Node_Data *filld = eo_data_scope_get(pd->stroke.fill, EVAS_VG_NODE_CLASS);
- stroke_r = filld->renderer;
- }
+ if(parent) eina_matrix3_point_transform(parent, nd->x, nd->y, &xn, &yn);
+
+ EFL_VG_COMPUTE_MATRIX(current, parent, nd);
- _evas_vg_render_pre(pd->stroke.marker, s, current);
- _evas_vg_render_pre(nd->mask, s, current);
+ fill = _evas_vg_render_pre(pd->fill, s, current);
+ stroke_fill = _evas_vg_render_pre(pd->stroke.fill, s, current);
+ stroke_marker = _evas_vg_render_pre(pd->stroke.marker, s, current);
+ mask = _evas_vg_render_pre(nd->mask, s, current);
if (!nd->renderer)
{
- eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_SHAPE_CLASS));
+ eo_do(s, nd->renderer = ector_surface_renderer_factory_new(ECTOR_RENDERER_GENERIC_SHAPE_MIXIN));
}
eo_do(nd->renderer,
ector_renderer_transformation_set(current),
- ector_renderer_origin_set(nd->x, nd->y),
+ ector_renderer_origin_set(xn, yn),
ector_renderer_color_set(nd->r, nd->g, nd->b, nd->a),
ector_renderer_visibility_set(nd->visibility),
- ector_renderer_mask_set(nd->mask),
- ector_renderer_shape_fill_set(fill_r),
- ector_renderer_shape_stroke_fill_set(stroke_r),
- ector_renderer_shape_stroke_marker_set(pd->stroke.marker),
- efl_gfx_shape_stroke_scale_set(pd->stroke.scale),
- efl_gfx_shape_stroke_color_set(pd->stroke.r,
- pd->stroke.g,
- pd->stroke.b,
- pd->stroke.a),
- efl_gfx_shape_stroke_width_set(pd->stroke.width),
- efl_gfx_shape_stroke_location_set(pd->stroke.centered),
- efl_gfx_shape_stroke_dash_set(pd->stroke.dash, pd->stroke.dash_count),
- efl_gfx_shape_stroke_cap_set(pd->stroke.cap),
- efl_gfx_shape_stroke_join_set(pd->stroke.join),
- efl_gfx_shape_path_set(pd->ops, pd->points),
+ ector_renderer_mask_set(mask ? mask->renderer : NULL),
+ ector_renderer_shape_fill_set(fill ? fill->renderer : NULL),
+ ector_renderer_shape_stroke_fill_set(stroke_fill ? stroke_fill->renderer : NULL),
+ ector_renderer_shape_stroke_marker_set(stroke_marker ? stroke_marker->renderer : NULL),
+ efl_gfx_shape_dup(obj),
ector_renderer_prepare());
-
- return EINA_TRUE;
}
static void
-_evas_vg_shape_eo_base_constructor(Eo *obj, Evas_VG_Shape_Data *pd)
+_efl_vg_shape_eo_base_constructor(Eo *obj, Efl_VG_Shape_Data *pd)
{
- Evas_VG_Node_Data *nd;
+ Efl_VG_Base_Data *nd;
eo_do_super(obj, MY_CLASS, eo_constructor());
pd->stroke.cap = EFL_GFX_CAP_BUTT;
pd->stroke.join = EFL_GFX_JOIN_MITER;
pd->stroke.scale = 1;
- pd->stroke.a = 0;
pd->stroke.centered = 0.5;
- nd = eo_data_scope_get(obj, EVAS_VG_NODE_CLASS);
- nd->render_pre = &_evas_vg_shape_render_pre;
+ nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
+ nd->render_pre = _efl_vg_shape_render_pre;
nd->data = pd;
}
static void
-_evas_vg_shape_eo_base_destructor(Eo *obj, Evas_VG_Shape_Data *pd EINA_UNUSED)
+_efl_vg_shape_eo_base_destructor(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, eo_destructor());
}
-#include "evas_vg_shape.eo.c"
+EAPI double
+evas_vg_shape_stroke_scale_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_shape_stroke_scale_get());
+}
+
+EAPI void
+evas_vg_shape_stroke_scale_set(Eo *obj, double s)
+{
+ eo_do(obj, efl_gfx_shape_stroke_scale_set(s));
+}
+
+EAPI void
+evas_vg_shape_stroke_color_get(Eo *obj, int *r, int *g, int *b, int *a)
+{
+ eo_do(obj, efl_gfx_shape_stroke_color_get(r, g, b, a));
+}
+
+EAPI void
+evas_vg_shape_stroke_color_set(Eo *obj, int r, int g, int b, int a)
+{
+ eo_do(obj, efl_gfx_shape_stroke_color_set(r, g, b, a));
+}
+
+EAPI double
+evas_vg_shape_stroke_width_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_shape_stroke_width_get());
+}
+
+EAPI void
+evas_vg_shape_stroke_width_set(Eo *obj, double w)
+{
+ eo_do(obj, efl_gfx_shape_stroke_width_set(w));
+}
+
+EAPI double
+evas_vg_shape_stroke_location_get(Eo *obj)
+{
+
+ return eo_do(obj, efl_gfx_shape_stroke_location_get());
+}
+
+EAPI void
+evas_vg_shape_stroke_location_set(Eo *obj, double centered)
+{
+ eo_do(obj, efl_gfx_shape_stroke_location_set(centered));
+}
+
+EAPI void
+evas_vg_shape_stroke_dash_get(Eo *obj, const Efl_Gfx_Dash **dash, unsigned int *length)
+{
+ eo_do(obj, efl_gfx_shape_stroke_dash_get(dash, length));
+}
+
+EAPI void
+evas_vg_shape_stroke_dash_set(Eo *obj, const Efl_Gfx_Dash *dash, unsigned int length)
+{
+ eo_do(obj, efl_gfx_shape_stroke_dash_set(dash, length));
+}
+
+EAPI Efl_Gfx_Cap
+evas_vg_shape_stroke_cap_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_shape_stroke_cap_get());
+}
+
+EAPI void
+evas_vg_shape_stroke_cap_set(Eo *obj, Efl_Gfx_Cap c)
+{
+ eo_do(obj, efl_gfx_shape_stroke_cap_set(c));
+}
+
+EAPI Efl_Gfx_Join
+evas_vg_shape_stroke_join_get(Eo *obj)
+{
+ return eo_do(obj, efl_gfx_shape_stroke_join_get());
+}
+
+EAPI void
+evas_vg_shape_stroke_join_set(Eo *obj, Efl_Gfx_Join j)
+{
+ eo_do(obj, efl_gfx_shape_stroke_join_set(j));
+}
+
+EAPI void
+evas_vg_shape_shape_path_set(Eo *obj, const Efl_Gfx_Path_Command *op, const double *points)
+{
+ eo_do(obj, efl_gfx_shape_path_set(op, points));
+}
+
+EAPI void
+evas_vg_shape_shape_path_get(Eo *obj, const Efl_Gfx_Path_Command **op, const double **points)
+{
+ eo_do(obj, efl_gfx_shape_path_get(op, points));
+}
+
+EAPI void
+evas_vg_shape_shape_path_length_get(Eo *obj, unsigned int *commands, unsigned int *points)
+{
+ eo_do(obj, efl_gfx_shape_path_length_get(commands, points));
+}
+
+EAPI void
+evas_vg_shape_shape_current_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_shape_current_get(x, y));
+}
+
+EAPI void
+evas_vg_shape_shape_current_ctrl_get(Eo *obj, double *x, double *y)
+{
+ eo_do(obj, efl_gfx_shape_current_ctrl_get(x, y));
+}
+
+EAPI void
+evas_vg_shape_shape_dup(Eo *obj, Eo *dup_from)
+{
+ eo_do(obj, efl_gfx_shape_dup(dup_from));
+}
+
+EAPI void
+evas_vg_shape_shape_reset(Eo *obj)
+{
+ eo_do(obj, efl_gfx_shape_reset());
+}
+
+EAPI void
+evas_vg_shape_shape_append_move_to(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_shape_append_move_to(x, y));
+}
+
+EAPI void
+evas_vg_shape_shape_append_line_to(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_shape_append_line_to(x, y));
+}
+
+EAPI void
+evas_vg_shape_shape_append_quadratic_to(Eo *obj, double x, double y, double ctrl_x, double ctrl_y)
+{
+ eo_do(obj, efl_gfx_shape_append_quadratic_to(x, y, ctrl_x, ctrl_y));
+}
+
+EAPI void
+evas_vg_shape_shape_append_squadratic_to(Eo *obj, double x, double y)
+{
+ eo_do(obj, efl_gfx_shape_append_squadratic_to(x, y));
+}
+
+EAPI void
+evas_vg_shape_shape_append_cubic_to(Eo *obj, double x, double y, double ctrl_x0, double ctrl_y0, double ctrl_x1, double ctrl_y1)
+{
+ eo_do(obj, efl_gfx_shape_append_cubic_to(x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1));
+}
+
+EAPI void
+evas_vg_shape_shape_append_scubic_to(Eo *obj, double x, double y, double ctrl_x, double ctrl_y)
+{
+ eo_do(obj, efl_gfx_shape_append_scubic_to(x, y, ctrl_x, ctrl_y));
+}
+
+EAPI void
+evas_vg_shape_shape_append_arc_to(Eo *obj, double x, double y, double rx, double ry, double angle, Eina_Bool large_arc, Eina_Bool sweep)
+{
+ eo_do(obj, efl_gfx_shape_append_arc_to(x, y, rx, ry, angle, large_arc, sweep));
+}
+
+EAPI void
+evas_vg_shape_shape_append_close(Eo *obj)
+{
+ eo_do(obj, efl_gfx_shape_append_close());
+}
+
+EAPI void
+evas_vg_shape_shape_append_circle(Eo *obj, double x, double y, double radius)
+{
+ eo_do(obj, efl_gfx_shape_append_circle(x, y, radius));
+}
+
+EAPI void
+evas_vg_shape_shape_append_rect(Eo *obj, double x, double y, double w, double h, double rx, double ry)
+{
+ eo_do(obj, efl_gfx_shape_append_rect(x, y, w, h, rx, ry));
+}
+
+EAPI void
+evas_vg_shape_shape_append_svg_path(Eo *obj, const char *svg_path_data)
+{
+ eo_do(obj, efl_gfx_shape_append_svg_path(svg_path_data));
+}
+
+EAPI Eina_Bool
+evas_vg_shape_shape_interpolate(Eo *obj, const Eo *from, const Eo *to, double pos_map)
+{
+ return eo_do(obj, efl_gfx_shape_interpolate(from, to, pos_map));
+}
+
+EAPI Eina_Bool
+evas_vg_shape_shape_equal_commands(Eo *obj, const Eo *with)
+{
+
+ return eo_do(obj, efl_gfx_shape_equal_commands(with));
+}
+
+#include "efl_vg_shape.eo.c"
#include <Eina.h>
#include <eina_safety_checks.h>
+#include <Ector.h>
#include "Evas.h"
struct {
Evas_Module *module;
Evas_Func *func;
+ Ector_Surface *surface;
struct {
void *output;
void (*texture_image_set) (void *data, void *texture, void *image);
void (*output_copy) (void *data, void *buffer, int stride, int width, int height, uint format, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh);
- void *(*ector_begin) (void *data, void *surface, int width, int height);
Ector_Surface *(*ector_get) (void *data);
- void (*ector_draw) (void *data, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, int x, int y, Eina_Bool do_async);
+ void (*ector_begin) (void *data, void *context, void *surface, int x, int y, Eina_Bool do_async);
+ void (*ector_renderer_draw) (void *data, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
+ void (*ector_end) (void *data, void *context, void *surface, Eina_Bool do_async);
};
struct _Evas_Image_Save_Func
--- /dev/null
+class Ector.Cairo_Software.Surface (Ector.Cairo.Surface)
+{
+ eo_prefix: ector_cairo_software_surface;
+ legacy_prefix: null;
+ properties {
+ surface {
+ set {
+ }
+ get {
+ }
+ values {
+ void *pixels;
+ uint width;
+ uint height;
+ }
+ }
+ }
+}
#include "Evas_Engine_GL_Generic.h"
-
-#include "software/Ector_Software.h"
-
-
#ifdef EVAS_CSERVE2
#include "evas_cs2_private.h"
#endif
+#include "cairo/Ector_Cairo.h"
+#include "software/Ector_Software.h"
+
+#include "ector_cairo_software_surface.eo.h"
+
#define EVAS_GL_NO_GL_H_CHECK 1
#include "Evas_GL.h"
e3d_texture_import((E3D_Texture *)texture, im->tex->pt->texture);
}
-
-// Opengl hack for ector START
-
static Ector_Surface *_software_ector = NULL;
+static Eina_Bool use_cairo;
static Ector_Surface *
eng_ector_get(void *data EINA_UNUSED)
{
if (!_software_ector)
{
- _software_ector = eo_add(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
+ const char *ector_backend;
+
+ ector_backend = getenv("ECTOR_BACKEND");
+ if (ector_backend && !strcasecmp(ector_backend, "freetype"))
+ {
+ _software_ector = eo_add(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
+ use_cairo = EINA_FALSE;
+ }
+ else
+ {
+ _software_ector = eo_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
+ use_cairo = EINA_TRUE;
+ }
}
return _software_ector;
}
-static void *
-eng_ector_begin(void *data, void *surface, int width, int height )
-{
- if (!surface) {
- return eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- } else {
- int cur_w , cur_h;
- Evas_GL_Image *glim = surface;
- cur_w = glim->im->cache_entry.w;
- cur_h = glim->im->cache_entry.h;
- if (width != cur_w || height != cur_h) {
- eng_image_free(data, surface);
- return eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- }
- // clear the buffer.
- void *pixels = evas_cache_image_pixels(&glim->im->cache_entry);
- memset(pixels, 0, cur_w * cur_h *4);
- }
- return surface;
-}
-
-struct _Evas_Thread_Command_Ector
-{
- void *surface;
- Ector_Renderer *r;
- Eina_Array *clips;
-
- DATA32 mul_col;
- Ector_Rop render_op;
- int x, y;
-
- Eina_Bool free_it;
-};
-
-typedef struct _Evas_Thread_Command_Ector Evas_Thread_Command_Ector;
-
static Ector_Rop
_evas_render_op_to_ector_rop(Evas_Render_Op op)
{
}
static void
-_draw_thread_ector_cleanup(Evas_Thread_Command_Ector *ector)
+eng_ector_renderer_draw(void *data, void *context EINA_UNUSED, void *surface, Ector_Renderer *renderer, Eina_Array *clips, int x, int y, Eina_Bool do_async EINA_UNUSED)
{
+ Evas_GL_Image *dst = surface;
+ Evas_Engine_GL_Context *gc;
+ Render_Engine_GL_Generic *re = data;
Eina_Rectangle *r;
-
- while ((r = eina_array_pop(ector->clips)))
- eina_rectangle_free(r);
- eina_array_free(ector->clips);
- eo_unref(ector->r);
-
-}
-
-static void
-_draw_thread_ector_draw(void *data)
-{
- Evas_Thread_Command_Ector *ector = data;
- RGBA_Image *surface = ector->surface;
- void *pixels = evas_cache_image_pixels(&surface->cache_entry);
- unsigned int w, h;
-
- w = surface->cache_entry.w;
- h = surface->cache_entry.h;
-
- // FIXME: do not reset cairo context if not necessary
- eo_do(_software_ector,
- ector_surface_set(pixels, w, h));
-
- eo_do(ector->r,
- ector_renderer_draw(ector->render_op,
- ector->clips,
- ector->x,
- ector->y,
- ector->mul_col));
-
- evas_common_cpu_end_opt();
-
- _draw_thread_ector_cleanup(ector);
-}
-
-static void
-eng_ector_draw(void *data EINA_UNUSED, void *context,
- void *surface, Ector_Renderer *renderer,
- Eina_Array *clips, int x, int y, Eina_Bool do_async EINA_UNUSED)
-{
- Evas_GL_Image *gl_img = surface;
- RGBA_Image *dst = gl_img->im;
- RGBA_Draw_Context *dc = context;
- Evas_Thread_Command_Ector ector;
Eina_Array *c;
- Eina_Rectangle *r;
Eina_Rectangle clip;
Eina_Array_Iterator it;
unsigned int i;
- if (0 && dc->clip.use)
+ gc = re->window_gl_context_get(re->software.ob);
+ if (gc->dc->clip.use)
{
- clip.x = dc->clip.x;
- clip.y = dc->clip.y;
- clip.w = dc->clip.w;
- clip.h = dc->clip.h;
+ clip.x = gc->dc->clip.x;
+ clip.y = gc->dc->clip.y;
+ clip.w = gc->dc->clip.w;
+ clip.h = gc->dc->clip.h;
}
else
{
clip.x = 0;
clip.y = 0;
- clip.w = dst->cache_entry.w;
- clip.h = dst->cache_entry.h;
+ clip.w = dst->w;
+ clip.h = dst->h;
}
- //Hermet: Multiple Clippers???
+
+ c = eina_array_new(8);
if (clips)
{
- //printf("Multiple clips \n");
- c = eina_array_new(8);
EINA_ARRAY_ITER_NEXT(clips, i, r, it)
{
Eina_Rectangle *rc;
- //printf("Multiple :%d , %d ,%d , %d\n",r->x, r->y, r->w, r->h);
+
rc = eina_rectangle_new(r->x, r->y, r->w, r->h);
if (!rc) continue;
else
eina_rectangle_free(rc);
}
+
+ if (eina_array_count(c) == 0 &&
+ eina_array_count(clips) > 0)
+ return ;
+ }
+
+ if (eina_array_count(c) == 0)
+ eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
+
+ eo_do(renderer,
+ ector_renderer_draw(_evas_render_op_to_ector_rop(gc->dc->render_op),
+ c,
+ // mul_col will be applied by GL during ector_end
+ 0xffffffff));
+
+ while ((r = eina_array_pop(c)))
+ eina_rectangle_free(r);
+ eina_array_free(c);
+}
+
+static void *software_buffer = NULL;
+
+static void
+eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, void *surface, int x, int y, Eina_Bool do_async EINA_UNUSED)
+{
+ Evas_Engine_GL_Context *gl_context;
+ Render_Engine_GL_Generic *re = data;
+ int w, h;
+
+ re->window_use(re->software.ob);
+ gl_context = re->window_gl_context_get(re->software.ob);
+ evas_gl_common_context_target_surface_set(gl_context, surface);
+ gl_context->dc = context;
+
+ w = gl_context->w; h = gl_context->h;
+
+ software_buffer = realloc(software_buffer, sizeof (unsigned int) * w * h);
+ if (use_cairo)
+ {
+ eo_do(_software_ector,
+ ector_cairo_software_surface_set(software_buffer, w, h));
}
else
{
- //printf("Single Clip : %d , %d ,%d , %d\n",clip.x, clip.y, clip.w, clip.h);
- c = eina_array_new(1);
- eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
+ eo_do(_software_ector,
+ ector_software_surface_set(software_buffer, w, h));
}
+}
- ector.surface = dst;
- ector.r = eo_ref(renderer);
- ector.clips = c;
- ector.render_op = _evas_render_op_to_ector_rop(dc->render_op);
- ector.mul_col = dc->col.col;
- ector.x = x;
- ector.y = y;
- ector.free_it = EINA_FALSE;
+static void
+eng_ector_end(void *data, void *context EINA_UNUSED, void *surface EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
+{
+ Evas_Engine_GL_Context *gl_context;
+ Render_Engine_GL_Generic *re = data;
+ Evas_GL_Image *im;
+ int w, h;
- _draw_thread_ector_draw(&ector);
-}
+ gl_context = re->window_gl_context_get(re->software.ob);
+ w = gl_context->w; h = gl_context->h;
+
+ if (use_cairo)
+ {
+ eo_do(_software_ector,
+ ector_cairo_software_surface_set(NULL, 0, 0));
+ }
+ else
+ {
+ eo_do(_software_ector,
+ ector_software_surface_set(NULL, 0, 0));
+ }
+ im = evas_gl_common_image_new_from_copied_data(gl_context, w, h, software_buffer, 1, EVAS_COLORSPACE_ARGB8888);
+ // We actually just bluntly push the pixel all over the
+ // destination surface. We don't have the actual information
+ // of the widget size. This is not a problem.
+ // Later on, we don't want that information and today when
+ // using GL backend, you just need to turn on Evas_Map on
+ // the Evas_Object_VG.
+ evas_gl_common_image_draw(gl_context, im, 0, 0, w, h, 0, 0, w, h, 0);
-// opengl hack for ector END
+ evas_gl_common_image_free(im);
+}
static Evas_Func func, pfunc;
ORD(texture_filter_get);
ORD(texture_image_set);
- /* ector features */
- ORD(ector_begin);
ORD(ector_get);
- ORD(ector_draw);
+ ORD(ector_begin);
+ ORD(ector_renderer_draw);
+ ORD(ector_end);
/* now advertise out own api */
em->functions = (void *)(&func);
{
eo_prefix: ector_cairo_software_surface;
legacy_prefix: null;
- implements {
- Ector.Generic.Surface.surface.set;
- Ector.Generic.Surface.surface.get;
+ properties {
+ surface {
+ set {
+ }
+ get {
+ }
+ values {
+ void *pixels;
+ uint width;
+ uint height;
+ }
+ }
}
implements {
Eo.Base.finalize;
#include "cairo/Ector_Cairo.h"
-#include "ector_cairo_software_surface.eo.h"
-
#include "software/Ector_Software.h"
+#include "ector_cairo_software_surface.eo.h"
+
#ifdef EVAS_GL
//----------------------------------//
// OSMesa...
typedef struct _Evas_Thread_Command_Font Evas_Thread_Command_Font;
typedef struct _Evas_Thread_Command_Map Evas_Thread_Command_Map;
typedef struct _Evas_Thread_Command_Multi_Font Evas_Thread_Command_Multi_Font;
+typedef struct _Evas_Thread_Command_Ector Evas_Thread_Command_Ector;
+typedef struct _Evas_Thread_Command_Ector_Surface Evas_Thread_Command_Ector_Surface;
struct _Evas_Thread_Command_Rect
{
Evas_Font_Array *texts;
};
+struct _Evas_Thread_Command_Ector
+{
+ Ector_Renderer *r;
+ Eina_Array *clips;
+
+ DATA32 mul_col;
+ Ector_Rop render_op;
+
+ Eina_Bool free_it;
+};
+
+struct _Evas_Thread_Command_Ector_Surface
+{
+ void *surface;
+ int x, y;
+};
+
Eina_Mempool *_mp_command_rect = NULL;
Eina_Mempool *_mp_command_line = NULL;
Eina_Mempool *_mp_command_polygon = NULL;
Eina_Mempool *_mp_command_font = NULL;
Eina_Mempool *_mp_command_map = NULL;
Eina_Mempool *_mp_command_multi_font = NULL;
-
+Eina_Mempool *_mp_command_ector = NULL;
+Eina_Mempool *_mp_command_ector_surface = NULL;
/*
*****
**
}
static Ector_Surface *_software_ector = NULL;
+static Eina_Bool use_cairo;
static Ector_Surface *
eng_ector_get(void *data EINA_UNUSED)
{
if (!_software_ector)
{
- //TODO FIX it Properly
- _software_ector = eo_add(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
- //_software_ector = eo_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
+ const char *ector_backend;
+
+ ector_backend = getenv("ECTOR_BACKEND");
+ if (ector_backend && !strcasecmp(ector_backend, "freetype"))
+ {
+ _software_ector = eo_add(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
+ use_cairo = EINA_FALSE;
+ }
+ else
+ {
+ _software_ector = eo_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
+ use_cairo = EINA_TRUE;
+ }
}
return _software_ector;
}
-static void *
-eng_ector_begin(void *data EINA_UNUSED, void *surface EINA_UNUSED, int width EINA_UNUSED, int height EINA_UNUSED)
-{
- return NULL;
-}
-
static Ector_Rop
_evas_render_op_to_ector_rop(Evas_Render_Op op)
{
_draw_thread_ector_draw(void *data)
{
Evas_Thread_Command_Ector *ector = data;
- RGBA_Image *surface = ector->surface;
- void *pixels = evas_cache_image_pixels(&surface->cache_entry);
- unsigned int w, h;
-
- w = surface->cache_entry.w;
- h = surface->cache_entry.h;
-
- // FIXME: do not reset cairo context if not necessary
- eo_do(_software_ector,
- ector_surface_set(pixels, w, h));
eo_do(ector->r,
ector_renderer_draw(ector->render_op,
ector->clips,
- ector->x,
- ector->y,
ector->mul_col));
evas_common_cpu_end_opt();
}
static void
-eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips, int x, int y, Eina_Bool do_async)
+eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
{
RGBA_Image *dst = surface;
RGBA_Draw_Context *dc = context;
clip.w = dst->cache_entry.w;
clip.h = dst->cache_entry.h;
}
- //Hermet: Multiple Clippers???
+
+ c = eina_array_new(8);
if (clips)
{
- //printf("Multiple clips \n");
- c = eina_array_new(8);
EINA_ARRAY_ITER_NEXT(clips, i, r, it)
{
Eina_Rectangle *rc;
- //printf("Multiple :%d , %d ,%d , %d\n",r->x, r->y, r->w, r->h);
+
rc = eina_rectangle_new(r->x, r->y, r->w, r->h);
if (!rc) continue;
else
eina_rectangle_free(rc);
}
- }
- else
- {
- //printf("Single Clip : %d , %d ,%d , %d\n",clip.x, clip.y, clip.w, clip.h);
- c = eina_array_new(1);
- eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
+
+ if (eina_array_count(c) == 0 &&
+ eina_array_count(clips) > 0)
+ return ;
}
- ector.surface = surface;
+ if (eina_array_count(c) == 0)
+ eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
+
ector.r = eo_ref(renderer);
ector.clips = c;
ector.render_op = _evas_render_op_to_ector_rop(dc->render_op);
- ector.mul_col = dc->col.col;
- ector.x = x;
- ector.y = y;
+ ector.mul_col = ector_color_multiply(dc->mul.use ? dc->mul.col : 0xffffffff,
+ dc->col.col);;
ector.free_it = EINA_FALSE;
if (do_async)
}
}
+static void
+_draw_thread_ector_surface_set(void *data)
+{
+ Evas_Thread_Command_Ector_Surface *ector_surface = data;
+ RGBA_Image *surface = ector_surface->surface;
+ void *pixels = NULL;
+ unsigned int w = 0;
+ unsigned int h = 0;
+ unsigned int x = 0;
+ unsigned int y = 0;
+
+ if (surface)
+ {
+ pixels = evas_cache_image_pixels(&surface->cache_entry);
+ w = surface->cache_entry.w;
+ h = surface->cache_entry.h;
+ x = ector_surface->x;
+ y = ector_surface->y;
+ }
+
+ if (use_cairo)
+ {
+ eo_do(_software_ector,
+ ector_cairo_software_surface_set(pixels, w, h),
+ ector_surface_reference_point_set(x, y));
+ }
+ else
+ {
+ eo_do(_software_ector,
+ ector_software_surface_set(pixels, w, h),
+ ector_surface_reference_point_set(x, y));
+ }
+
+ evas_common_cpu_end_opt();
+
+ eina_mempool_free(_mp_command_ector_surface, ector_surface);
+}
+
+static void
+eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, void *surface, int x, int y, Eina_Bool do_async)
+{
+ if (do_async)
+ {
+ Evas_Thread_Command_Ector_Surface *nes;
+
+ nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
+ if (!nes) return ;
+
+ nes->surface = surface;
+ nes->x = x;
+ nes->y = y;
+
+ evas_thread_cmd_enqueue(_draw_thread_ector_surface_set, nes);
+ }
+ else
+ {
+ RGBA_Image *sf = surface;
+ void *pixels = NULL;
+ unsigned int w = 0;
+ unsigned int h = 0;
+
+ pixels = evas_cache_image_pixels(&sf->cache_entry);
+ w = sf->cache_entry.w;
+ h = sf->cache_entry.h;
+
+ if (use_cairo)
+ {
+ eo_do(_software_ector,
+ ector_cairo_software_surface_set(pixels, w, h),
+ ector_surface_reference_point_set(x, y));
+ }
+ else
+ {
+ eo_do(_software_ector,
+ ector_software_surface_set(pixels, w, h),
+ ector_surface_reference_point_set(x, y));
+ }
+ }
+}
+
+static void
+eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, void *surface EINA_UNUSED, Eina_Bool do_async)
+{
+ if (do_async)
+ {
+ Evas_Thread_Command_Ector_Surface *nes;
+
+ nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
+ if (!nes) return ;
+
+ nes->surface = NULL;
+
+ evas_thread_cmd_enqueue(_draw_thread_ector_surface_set, nes);
+ }
+ else
+ {
+ eo_do(_software_ector, ector_cairo_software_surface_set(NULL, 0, 0));
+
+ evas_common_cpu_end_opt();
+ }
+}
+
//------------------------------------------------//
/*
NULL, // eng_texture_filter_set
NULL, // eng_texture_filter_get
NULL, // eng_texture_image_set
- eng_ector_begin,
eng_ector_get,
- eng_ector_renderer_draw
+ eng_ector_begin,
+ eng_ector_renderer_draw,
+ eng_ector_end
/* FUTURE software generic calls go here */
};
_mp_command_multi_font =
eina_mempool_add("chained_mempool", "Evas_Thread_Command_Multi_Font",
NULL, sizeof(Evas_Thread_Command_Multi_Font), 128);
+ _mp_command_ector =
+ eina_mempool_add("chained_mempool", "Evas_Thread_Command_Ector",
+ NULL, sizeof(Evas_Thread_Command_Ector), 128);
+ _mp_command_ector_surface =
+ eina_mempool_add("chained_mempool", "Evas_Thread_Command_Ector_Surface",
+ NULL, sizeof(Evas_Thread_Command_Ector_Surface), 128);
init_gl();
evas_common_pipe_init();
eina_mempool_del(_mp_command_image);
eina_mempool_del(_mp_command_font);
eina_mempool_del(_mp_command_map);
+ eina_mempool_del(_mp_command_ector);
eina_log_domain_unregister(_evas_soft_gen_log_dom);
}
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_generic);
+Eina_Bool evas_engine_software_generic_init(void)
+{
+ return evas_module_register(&evas_modapi, EVAS_MODULE_TYPE_ENGINE);
+}
+
+// Time to destroy the ector context
+void evas_engine_software_generic_shutdown(void)
+{
+ if (_software_ector) eo_del(_software_ector);
+ _software_ector = NULL;
+
+ evas_module_unregister(&evas_modapi, EVAS_MODULE_TYPE_ENGINE);
+}
+
#ifndef EVAS_STATIC_BUILD_SOFTWARE_GENERIC
EVAS_EINA_MODULE_DEFINE(engine, software_generic);
#endif
+#define USE(Obj, Sym, Error) \
+ if (!Sym) Sym = _ector_cairo_symbol_get(Obj, #Sym); \
+ if (!Sym) return Error;
+
+static inline void *
+_ector_cairo_symbol_get(Eo *ector_surface, const char *name)
+{
+ void *sym;
+
+ eo_do(ector_surface,
+ sym = ector_cairo_surface_symbol_get(name));
+ return sym;
+}
+
+typedef struct _cairo_surface_t cairo_surface_t;
+typedef enum {
+ CAIRO_FORMAT_INVALID = -1,
+ CAIRO_FORMAT_ARGB32 = 0,
+ CAIRO_FORMAT_RGB24 = 1,
+ CAIRO_FORMAT_A8 = 2,
+ CAIRO_FORMAT_A1 = 3,
+ CAIRO_FORMAT_RGB16_565 = 4,
+ CAIRO_FORMAT_RGB30 = 5
+} cairo_format_t;
+
+static cairo_surface_t *(*cairo_image_surface_create_for_data)(unsigned char *data,
+ cairo_format_t format,
+ int width,
+ int height,
+ int stride) = NULL;
+static void (*cairo_surface_destroy)(cairo_surface_t *surface) = NULL;
+static cairo_t *(*cairo_create)(cairo_surface_t *target) = NULL;
+static void (*cairo_destroy)(cairo_t *cr) = NULL;
+
typedef struct _Ector_Cairo_Software_Surface_Data Ector_Cairo_Software_Surface_Data;
struct _Ector_Cairo_Software_Surface_Data
{
};
void
-_ector_cairo_software_surface_ector_generic_surface_surface_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void *pixels, unsigned int width, unsigned int height)
+_ector_cairo_software_surface_surface_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void *pixels, unsigned int width, unsigned int height)
{
+ USE(obj, cairo_image_surface_create_for_data, );
+ USE(obj, cairo_surface_destroy, );
+ USE(obj, cairo_create, );
+ USE(obj, cairo_destroy, );
+
+ if (pd->surface) cairo_surface_destroy(pd->surface); pd->surface = NULL;
+ if (pd->ctx) cairo_destroy(pd->ctx); pd->ctx = NULL;
+
+ pd->pixels = NULL;
+ pd->width = 0;
+ pd->height = 0;
+
+ if (pixels)
+ {
+ pd->surface = cairo_image_surface_create_for_data(pixels,
+ CAIRO_FORMAT_ARGB32,
+ width, height, width * sizeof (int));
+ if (!pd->surface) goto end;
+
+ pd->ctx = cairo_create(pd->surface);
+ if (!pd->ctx) goto end;
+ }
+
+ pd->pixels = pixels;
+ pd->width = width;
+ pd->height = height;
+
+ end:
+ eo_do(obj, ector_cairo_surface_context_set(pd->ctx));
}
void
-_ector_cairo_software_surface_ector_generic_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
+_ector_cairo_software_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
{
}