Merge branch 'devs/cedric/evas_vg'

This commit add Evas_Object_VG, a new Evas_Object that provide a vector graphics
scenegraph following SVG specification. It will be considered a bug if some behavior
did not follow the SVG standard. Evas_Object_VG provide 3 kind of object for now:
shape, linear and radial gradient.

Vector object are very different in nature from what Evas did manipulate until now,
especially SVG defined one. They don't allow the easy detection of opaque area, thus
no cutout possible during the rendering and they usually require a large number of
them to draw something nice on scree. The cutout optimization in Evas is directly
impacted by the number of object, so splitting the two scenegraph did make sense.
Also SVG use matrix transformation everywhere, while Evas is using an UV mapping.
This make it a clear choice to have two scenegraph.

A part from the author you will see with git, there is two big thanks that needs to
be said here. First special thanks goes to Jorge Luis "turran" Zapata who is
developping is own vector stack: http://enesim.org/ since a long time now and did
share is technical advice and also influenced strongly the design. We did evaluate
the possibility to include enesim in efl, but that wasn't really possible sadly.
Another thanks goes to Jose O Gonzalez who did support and answer a lot of my
question and helped me a lot to.
This commit is contained in:
Cedric BAIL 2015-04-03 17:15:52 +02:00
commit 6a909d7a4f
160 changed files with 20570 additions and 707 deletions

View File

@ -77,6 +77,14 @@ Eo
--
Tom Hacohen <tom@stosb.com>
Cedric Bail <cedric.bail@free.fr>
Ector
-----
Cedric Bail <cedric.bail@free.fr>
Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
Jose O Gonzalez <jose_ogp@juno.com>
Evas
----

31
NOTES Normal file
View File

@ -0,0 +1,31 @@
Evas_VG_Color_List
- List of color
Evas_VG_Gradient
gradient_type_set (radial, linear)
color_list_set
point_set (i, x, y)
Evas_VG_Fill
- abstract
Evas_VG_Root_Node (only one at the top, Evas_VG_Container)
Evas_VG_Shape
fill
stroke_scale
stroke_color
stroke_fill
stroke_width
stroke_location
stroke_dash(length[], gap[])
stroke_marker(Evas_VG_Shape *)
stroke_cap
stroke_join
Evas_VG_Filter
??
bounds_get -> Evas_VG_Node
Eina_Matrix3

View File

@ -1212,9 +1212,54 @@ EFL_PLATFORM_DEPEND([EFL], [evil])
EFL_INTERNAL_DEPEND_PKG([EFL], [eina])
EFL_INTERNAL_DEPEND_PKG([EFL], [eo])
EFL_ADD_LIBS([EFL], [-lm])
EFL_LIB_END([Efl])
#### End of Efl
#### Ector
EFL_LIB_START([Ector])
### Default values
### Additional options to configure
### Checks for programs
### Checks for libraries
## Compatibility layers
EFL_PLATFORM_DEPEND([ECTOR], [evil])
EFL_INTERNAL_DEPEND_PKG([ECTOR], [eina])
EFL_INTERNAL_DEPEND_PKG([ECTOR], [eo])
EFL_INTERNAL_DEPEND_PKG([ECTOR], [efl])
EFL_ADD_LIBS([ECTOR], [-lm])
EFL_EVAL_PKGS([ECTOR])
### Checks for header files
### Checks for types
### Checks for structures
### Checks for compiler characteristics
### Checks for linker characteristics
### Checks for library functions
### Check availability
EFL_LIB_END([ECTOR])
#### End of Ector
#### Evas
EFL_LIB_START([Evas])
@ -1676,6 +1721,7 @@ EFL_INTERNAL_DEPEND_PKG([EVAS], [eet])
EFL_INTERNAL_DEPEND_PKG([EVAS], [eina])
EFL_INTERNAL_DEPEND_PKG([EVAS], [efl])
EFL_INTERNAL_DEPEND_PKG([EVAS], [emile])
EFL_INTERNAL_DEPEND_PKG([EVAS], [ector])
EFL_ADD_LIBS([EVAS], [-lm])
@ -4524,6 +4570,7 @@ pc/ecore-imf-evas.pc
pc/ecore-audio.pc
pc/ecore-audio-cxx.pc
pc/ecore-avahi.pc
pc/ector.pc
pc/embryo.pc
pc/eio.pc
pc/eldbus.pc
@ -4691,6 +4738,7 @@ fi
echo "Ecore_Audio.....: ${efl_lib_optional_ecore_audio} (${features_ecore_audio})"
echo "Ecore_Avahi.....: yes (${features_ecore_avahi})"
echo "Ecore_Evas......: yes (${features_ecore_evas})"
echo "Ector...........: yes"
echo "Eeze............: ${efl_lib_optional_eeze} (${features_eeze})"
echo "EPhysics........: ${efl_lib_optional_ephysics}"
echo "Edje............: yes (${features_edje})"

1
pc/.gitignore vendored
View File

@ -17,6 +17,7 @@
/ecore-win32.pc
/ecore-x.pc
/ecore.pc
/ector.pc
/edje.pc
/eet.pc
/eeze.pc

12
pc/ector.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: ector
Description: Enlightenned retained mode drawing library
Requires.private: @requirements_pc_ector@
Version: @VERSION@
Libs: -L${libdir} -lector
Libs.private: @requirements_libs_ector@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/ector-@VMAJ@

View File

@ -4,6 +4,7 @@ BUILT_SOURCES =
EOLIAN_FLAGS = -I$(srcdir)\
-I$(srcdir)/lib/eo \
-I$(srcdir)/lib/ector \
-I$(srcdir)/lib/evas/canvas \
-I$(srcdir)/lib/edje \
-I$(srcdir)/lib/efl/interfaces \
@ -34,6 +35,7 @@ include Makefile_Efl.am
include Makefile_Emile.am
include Makefile_Eet.am
include Makefile_Eolian.am
include Makefile_Ector.am
include Makefile_Evas.am
include Makefile_Ecore.am
include Makefile_Ecore_Con.am

View File

@ -282,7 +282,8 @@ endif
bin_PROGRAMS += \
bin/ecore_evas/ecore_evas_convert \
bin/ecore_evas/eetpack
bin/ecore_evas/eetpack \
bin/ecore_evas/ecore_evas_svg
bin_ecore_evas_ecore_evas_convert_SOURCES = bin/ecore_evas/ecore_evas_convert.c
bin_ecore_evas_ecore_evas_convert_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_EVAS_CFLAGS@
@ -293,3 +294,8 @@ bin_ecore_evas_eetpack_SOURCES = bin/ecore_evas/eetpack.c
bin_ecore_evas_eetpack_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_EVAS_CFLAGS@ @EINA_CFLAGS@ @EET_CFLAGS@ @EVAS_CFLAGS@
bin_ecore_evas_eetpack_LDADD = @USE_ECORE_EVAS_LIBS@ @USE_EINA_LIBS@ @USE_EET_LIBS@ @USE_EVAS_LIBS@
bin_ecore_evas_eetpack_DEPENDENCIES = @USE_ECORE_EVAS_INTERNAL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_EET_INTERNAL_LIBS@ @USE_EVAS_INTERNAL_LIBS@
bin_ecore_evas_ecore_evas_svg_SOURCES = bin/ecore_evas/ecore_evas_svg.c
bin_ecore_evas_ecore_evas_svg_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_EVAS_CFLAGS@
bin_ecore_evas_ecore_evas_svg_LDADD = @USE_ECORE_EVAS_LIBS@
bin_ecore_evas_ecore_evas_svg_DEPENDENCIES = @USE_ECORE_EVAS_INTERNAL_LIBS@

138
src/Makefile_Ector.am Normal file
View File

@ -0,0 +1,138 @@
### Library
ector_eolian_files = \
lib/ector/ector_generic_surface.eo \
lib/ector/ector_renderer_generic_base.eo \
lib/ector/ector_renderer_generic_shape.eo \
lib/ector/ector_renderer_generic_gradient.eo \
lib/ector/ector_renderer_generic_gradient_radial.eo \
lib/ector/ector_renderer_generic_gradient_linear.eo
# Handle cairo backend
ector_eolian_files += \
lib/ector/cairo/ector_cairo_surface.eo \
lib/ector/cairo/ector_renderer_cairo_base.eo \
lib/ector/cairo/ector_renderer_cairo_shape.eo \
lib/ector/cairo/ector_renderer_cairo_gradient_linear.eo \
lib/ector/cairo/ector_renderer_cairo_gradient_radial.eo
# Handle FreeType rasterizer
ector_eolian_files += \
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_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)
BUILT_SOURCES += \
$(ector_eolian_c) \
$(ector_eolian_h)
CLEANFILES += \
$(ector_eolian_c) \
$(ector_eolian_h)
ectoreolianfilesdir = $(datadir)/eolian/include/ector-@VMAJ@
ectoreolianfiles_DATA = $(ector_eolian_files)
EXTRA_DIST += $(ectoreolianfiles_DATA)
lib_LTLIBRARIES += lib/ector/libector.la
installed_ectormainheadersdir = $(includedir)/ector-@VMAJ@
dist_installed_ectormainheaders_DATA = \
lib/ector/Ector.h \
lib/ector/ector_util.h \
lib/ector/ector_surface.h \
lib/ector/ector_renderer.h \
lib/ector/cairo/Ector_Cairo.h \
lib/ector/software/Ector_Software.h
# And the generic implementation
lib_ector_libector_la_SOURCES = \
lib/ector/ector_main.c \
lib/ector/ector_surface.c \
lib/ector/ector_renderer_shape.c \
lib/ector/ector_renderer_base.c \
lib/ector/ector_renderer_gradient.c \
lib/ector/ector_renderer_gradient_radial.c \
lib/ector/ector_renderer_gradient_linear.c
# And now the cairo backend
lib_ector_libector_la_SOURCES += \
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 the Freetype rasterizer
lib_ector_libector_la_SOURCES += \
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_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_libector_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/ector \
-I$(top_builddir)/src/lib/ector/cairo \
-I$(top_builddir)/src/lib/ector/software \
@ECTOR_CFLAGS@ \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/ector\" \
@VALGRIND_CFLAGS@
lib_ector_libector_la_LIBADD = @ECTOR_LIBS@ @DL_LIBS@
lib_ector_libector_la_DEPENDENCIES = @ECTOR_INTERNAL_LIBS@ @DL_INTERNAL_LIBS@
lib_ector_libector_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
### Unit tests
if EFL_ENABLE_TESTS
check_PROGRAMS += tests/ector/ector_suite tests/ector/cxx_compile_test
TESTS += tests/ector/ector_suite
tests_ector_ector_suite_SOURCES = \
tests/ector/ector_suite.c \
tests/ector/ector_suite.h \
tests/ector/ector_test_init.c
tests_ector_cxx_compile_test_SOURCES = tests/ector/cxx_compile_test.cxx
tests_ector_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECTOR_CFLAGS@
tests_ector_cxx_compile_test_LDADD = @USE_ECTOR_LIBS@
tests_ector_cxx_compile_test_DEPENDENCIES = @USE_ECTOR_INTERNAL_LIBS@
tests_ector_ector_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/ector\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/ector\" \
-DTESTS_BUILD_DIR=PACKAGE_BUILD_DIR \
@CHECK_CFLAGS@ \
@ECTOR_CFLAGS@
tests_ector_ector_suite_LDADD = @CHECK_LIBS@ @USE_ECTOR_LIBS@
tests_ector_ector_suite_DEPENDENCIES = @USE_ECTOR_INTERNAL_LIBS@
endif
EXTRA_DIST += \
lib/ector/ector_private.h \
lib/ector/cairo/ector_cairo_private.h \
lib/ector/software/ector_blend_private.h \
lib/ector/software/ector_software_private.h \
lib/ector/software/sw_ft_math.h \
lib/ector/software/sw_ft_raster.h \
lib/ector/software/sw_ft_stroker.h \
lib/ector/software/sw_ft_types.h

View File

@ -4,7 +4,15 @@ efl_eolian_files = \
lib/efl/interfaces/efl_image.eo \
lib/efl/interfaces/efl_player.eo \
lib/efl/interfaces/efl_text.eo \
lib/efl/interfaces/efl_text_properties.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_base.eo \
lib/efl/interfaces/efl_gfx_gradient_linear.eo \
lib/efl/interfaces/efl_gfx_gradient_radial.eo
efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h)
efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c)
@ -27,7 +35,10 @@ efleolianfiles_DATA = $(efl_eolian_files)
lib_LTLIBRARIES += lib/efl/libefl.la
lib_efl_libefl_la_SOURCES = lib/efl/interfaces/efl_interfaces_main.c
lib_efl_libefl_la_SOURCES = \
lib/efl/interfaces/efl_interfaces_main.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@
lib_efl_libefl_la_DEPENDENCIES = @EFL_INTERNAL_LIBS@
@ -39,7 +50,8 @@ dist_installed_eflheaders_DATA = \
lib/efl/Efl.h
installed_eflinterfacesdir = $(includedir)/efl-@VMAJ@/interfaces
nodist_installed_eflinterfaces_DATA = $(efl_eolian_files_h)
nodist_installed_eflinterfaces_DATA = \
$(efl_eolian_files_h)
if HAVE_ELUA

View File

@ -8,7 +8,15 @@ generated_efl_cxx_bindings = \
lib/efl/interfaces/efl_image.eo.hh \
lib/efl/interfaces/efl_player.eo.hh \
lib/efl/interfaces/efl_text.eo.hh \
lib/efl/interfaces/efl_text_properties.eo.hh
lib/efl/interfaces/efl_text_properties.eo.hh \
lib/efl/interfaces/efl_gfx_base.eo.hh \
lib/efl/interfaces/efl_gfx_stack.eo.hh \
lib/efl/interfaces/efl_gfx_fill.eo.hh \
lib/efl/interfaces/efl_gfx_view.eo.hh \
lib/efl/interfaces/efl_gfx_shape.eo.hh \
lib/efl/interfaces/efl_gfx_gradient_base.eo.hh \
lib/efl/interfaces/efl_gfx_gradient_linear.eo.hh \
lib/efl/interfaces/efl_gfx_gradient_radial.eo.hh
lib/efl/Efl.hh: $(generated_efl_cxx_bindings)
@echo @ECHO_E@ "#ifndef EFL_CXX_EDJE_HH\n#define EFL_CXX_EDJE_HH\n" > $(top_builddir)/src/lib/efl/Efl.hh

View File

@ -85,7 +85,9 @@ lib/eina/eina_tmpstr.h \
lib/eina/eina_alloca.h \
lib/eina/eina_cow.h \
lib/eina/eina_inline_unicode.x \
lib/eina/eina_thread_queue.h
lib/eina/eina_thread_queue.h \
lib/eina/eina_matrix.h \
lib/eina/eina_quad.h
# Will be back for developper after 1.2.
# lib/eina/eina_model.h
@ -144,7 +146,9 @@ lib/eina/eina_xattr.c \
lib/eina/eina_share_common.h \
lib/eina/eina_private.h \
lib/eina/eina_strbuf_common.h \
lib/eina/eina_thread_queue.c
lib/eina/eina_thread_queue.c \
lib/eina/eina_matrix.c \
lib/eina/eina_quad.c
# Will be back for developper after 1.2
# lib/eina/eina_model.c \

View File

@ -31,7 +31,15 @@ evas_eolian_files = \
lib/evas/canvas/evas_3d_mesh.eo\
lib/evas/canvas/evas_3d_node.eo\
lib/evas/canvas/evas_3d_scene.eo\
lib/evas/canvas/evas_3d_object.eo
lib/evas/canvas/evas_3d_object.eo \
lib/evas/canvas/evas_vg.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
evas_eolian_c = $(evas_eolian_files:%.eo=%.eo.c)
evas_eolian_h = $(evas_eolian_files:%.eo=%.eo.h) \
@ -76,7 +84,8 @@ lib/evas/include/evas_macros.h \
lib/evas/include/evas_mmx.h \
lib/evas/include/evas_common_private.h \
lib/evas/include/evas_blend_ops.h \
lib/evas/include/evas_filter.h
lib/evas/include/evas_filter.h \
lib/evas/canvas/evas_vg_private.h
# Linebreak
@ -176,6 +185,7 @@ lib/evas/file/evas_path.h
lib_evas_libevas_la_SOURCES += \
$(lib_evas_file_SOURCES)
# Evas_3D
noinst_HEADERS += \
lib/evas/include/evas_3d_utils.h
@ -201,6 +211,18 @@ modules/evas/model_savers/obj/evas_model_save_obj.c \
modules/evas/model_savers/ply/evas_model_save_ply.c \
lib/evas/canvas/evas_3d_eet.c
# Evas_VG
lib_evas_libevas_la_SOURCES += \
lib/evas/canvas/evas_object_vg.c \
lib/evas/canvas/evas_vg_node.c \
lib/evas/canvas/evas_vg_container.c \
lib/evas/canvas/evas_vg_root_node.c \
lib/evas/canvas/evas_vg_gradient.c \
lib/evas/canvas/evas_vg_gradient_linear.c \
lib/evas/canvas/evas_vg_gradient_radial.c \
lib/evas/canvas/evas_vg_utils.c \
lib/evas/canvas/evas_vg_shape.c
# Engine
lib_evas_libevas_la_SOURCES += \
lib/evas/common/evas_op_copy_main_.c \
@ -293,6 +315,9 @@ lib_evas_libevas_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/evas/file \
-I$(top_srcdir)/src/lib/evas/include \
-I$(top_srcdir)/src/static_libs/libunibreak \
-I$(top_builddir)/src/lib/evas/canvas \
-I$(top_builddir)/src/modules/evas/engines/software_generic \
-I$(top_builddir)/src/modules/evas/engines/gl_generic \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/evas\" \
@ -492,10 +517,18 @@ lib/evas/filters/blur/blur_box_rgba_i386.c \
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
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
@ -511,6 +544,7 @@ modules_evas_engines_software_generic_module_la_SOURCES = modules/evas/engines/s
modules_evas_engines_software_generic_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/evas/include \
-I$(top_srcdir)/src/lib/evas/cserve2 \
-I$(top_builddir)/src/modules/evas/engines/software_generic \
@EVAS_CFLAGS@
modules_evas_engines_software_generic_module_la_LIBADD = @USE_EVAS_LIBS@
modules_evas_engines_software_generic_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@
@ -584,6 +618,10 @@ endif
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 \
@ -695,6 +733,7 @@ modules_evas_engines_gl_generic_module_la_CFLAGS = \
-I$(top_srcdir)/src/lib/evas/include \
-I$(top_srcdir)/src/lib/evas/cserve2 \
-I$(top_srcdir)/src/modules/evas/engines/gl_common \
-I$(top_builddir)/src/modules/evas/engines/gl_generic \
@evas_engine_gl_common_cflags@ \
@EVAS_CFLAGS@
modules_evas_engines_gl_generic_module_la_LIBADD = \

View File

@ -33,7 +33,16 @@ lib/evas/canvas/evas_3d_mesh.eo.hh \
lib/evas/canvas/evas_3d_node.eo.hh \
lib/evas/canvas/evas_3d_object.eo.hh \
lib/evas/canvas/evas_3d_scene.eo.hh \
lib/evas/canvas/evas_3d_texture.eo.hh
lib/evas/canvas/evas_3d_texture.eo.hh \
lib/evas/canvas/evas_vg.eo.hh \
lib/evas/canvas/efl_vg_base.eo.hh \
lib/evas/canvas/efl_vg_container.eo.hh \
lib/evas/canvas/efl_vg_shape.eo.hh \
lib/evas/canvas/efl_vg_root_node.eo.hh \
lib/evas/canvas/efl_vg_gradient.eo.hh \
lib/evas/canvas/efl_vg_gradient_radial.eo.hh \
lib/evas/canvas/efl_vg_gradient_linear.eo.hh \
lib/evas/canvas/efl_vg_image.eo.hh
lib/evas/Evas.hh: $(generated_evas_canvas_cxx_bindings)
@echo @ECHO_E@ "#ifndef EFL_CXX_EVAS_HH\n#define EFL_CXX_EVAS_HH\n" > $(top_builddir)/src/lib/evas/Evas.hh

View File

@ -1,2 +1,3 @@
/ecore_evas_convert
/eetpack
/ecore_evas_svg

View File

@ -0,0 +1,198 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_EVIL
# include <Evil.h>
#endif
#include <Eina.h>
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Getopt.h>
#include <Ecore_Evas.h>
#undef EINA_LOG_DOMAIN_DEFAULT
#define EINA_LOG_DOMAIN_DEFAULT _log_dom
static int _log_dom = -1;
static void
_cb_delete(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
static unsigned char
_parse_color(const Ecore_Getopt *parser EINA_UNUSED,
const Ecore_Getopt_Desc *desc EINA_UNUSED,
const char *str,
void *data EINA_UNUSED, Ecore_Getopt_Value *storage)
{
unsigned char *color = (unsigned char *)storage->ptrp;
if (sscanf(str, "%hhu,%hhu,%hhu", color, color + 1, color + 2) != 3)
{
fprintf(stderr, "ERROR: incorrect color value '%s'\n", str);
return 0;
}
return 1;
}
const Ecore_Getopt optdesc = {
"ecore_evas_svg",
"%prog [options] <filename-source> [<filename-destination>]",
PACKAGE_VERSION,
"(C) 2014 Enlightenment",
"BSD with advertisement clause",
"Simple application to display or convert SVG in their vector form.",
0,
{
ECORE_GETOPT_STORE_INT('q', "quality", "define encoding quality in percent."),
ECORE_GETOPT_STORE_TRUE('c', "compress", "define if data should be compressed."),
ECORE_GETOPT_STORE_STR('c', "codec", "define the codec (for TGV files: etc1, etc2)"),
ECORE_GETOPT_CALLBACK_NOARGS('E', "list-engines", "list Ecore-Evas engines",
ecore_getopt_callback_ecore_evas_list_engines, NULL),
ECORE_GETOPT_STORE_STR('e', "engine", "The Ecore-Evas engine to use (see --list-engines)"),
ECORE_GETOPT_CALLBACK_ARGS('c', "bg-color",
"Color of the background (if not shaped or alpha)",
"RRGGBB", _parse_color, NULL),
ECORE_GETOPT_CALLBACK_ARGS('Z', "size", "size to use in wxh form.", "WxH",
ecore_getopt_callback_size_parse, NULL),
ECORE_GETOPT_STORE_TRUE('a', "alpha", "Display window with alpha channel "
" (needs composite manager!)"),
ECORE_GETOPT_STORE_STR('t', "title", "Define the window title string"),
ECORE_GETOPT_LICENSE('L', "license"),
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
ECORE_GETOPT_VERSION('V', "version"),
ECORE_GETOPT_HELP('h', "help"),
ECORE_GETOPT_SENTINEL
}
};
int
main(int argc, char *argv[])
{
Ecore_Evas *ee;
Evas *e;
Evas_Object *im = NULL;
Evas_Object *vg;
Evas_Object *r;
char *encoding = NULL;
char *engine = NULL;
char *title = NULL;
Eina_Rectangle size = { 0, 0, 800, 600 };
unsigned char color[3] = { 0, 0, 0 };
int arg_index;
int quality = -1;
Eina_Bool compress = 1;
Eina_Bool quit_option = EINA_FALSE;
Eina_Bool display = EINA_FALSE;
Eina_Bool alpha = EINA_FALSE;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_INT(quality),
ECORE_GETOPT_VALUE_BOOL(compress),
ECORE_GETOPT_VALUE_STR(encoding),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_STR(engine),
ECORE_GETOPT_VALUE_PTR_CAST(color),
ECORE_GETOPT_VALUE_PTR_CAST(size),
ECORE_GETOPT_VALUE_BOOL(alpha),
ECORE_GETOPT_VALUE_STR(title),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_NONE
};
eina_init();
_log_dom = eina_log_domain_register(argv[0], EINA_COLOR_CYAN);
ecore_init();
ecore_evas_init();
arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
if (quit_option) goto end;
if (arg_index < 0)
{
EINA_LOG_ERR("Could not parse argument.");
goto end;
}
if (arg_index + 1 == argc)
{
display = EINA_TRUE;
}
else if (arg_index + 2 != argc)
{
EINA_LOG_ERR("File not correctly specified.");
goto end;
}
if (!display)
{
Ecore_Evas *sub_ee;
ee = ecore_evas_buffer_new(1, 1);
im = ecore_evas_object_image_new(ee);
sub_ee = ecore_evas_object_ecore_evas_get(im);
ecore_evas_resize(sub_ee, size.w, size.h);
e = ecore_evas_object_evas_get(im);
}
else
{
ee = ecore_evas_new(engine, 0, 0, size.w, size.h, NULL);
e = ecore_evas_get(ee);
}
ecore_evas_alpha_set(ee, alpha);
ecore_evas_callback_delete_request_set(ee, _cb_delete);
ecore_evas_title_set(ee, title ? title : "Ecore Evas SVG");
r = eo_add(EVAS_RECTANGLE_CLASS, e,
efl_gfx_color_set(color[0], color[1], color[2], alpha ? 0 : 255),
efl_gfx_visible_set(EINA_TRUE));
ecore_evas_object_associate(ee, r, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
vg = eo_add(EVAS_VG_CLASS, e,
efl_file_set(argv[arg_index], NULL),
efl_gfx_visible_set(EINA_TRUE));
ecore_evas_object_associate(ee, vg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
if (display)
{
ecore_evas_show(ee);
ecore_main_loop_begin();
}
else
{
Eina_Strbuf *flags = NULL;
flags = eina_strbuf_new();
eina_strbuf_append_printf(flags, "compress=%d", compress);
if (quality >= 0)
eina_strbuf_append_printf(flags, " quality=%d", quality);
if (encoding)
eina_strbuf_append_printf(flags, " encoding=%s", encoding);
evas_object_image_save(im, argv[arg_index + 1],
NULL, eina_strbuf_string_get(flags));
eina_strbuf_free(flags);
}
ecore_evas_free(ee);
end:
ecore_evas_shutdown();
ecore_shutdown();
eina_shutdown();
return 0;
}

View File

@ -235,23 +235,23 @@ template <typename Args, typename... E>
EAPI void inherit_constructor(void* this_, Args args)
{
typedef void (*func_t)(Eo *, void *, void*, Args);
Eo_Op_Call_Data call;
Eo_Op_Call_Data ___call;
static Eo_Op op = EO_NOOP;
if ( op == EO_NOOP )
op = _eo_api_op_id_get
(reinterpret_cast<void*>
(static_cast<void(*)(void*, Args)>(&detail::inherit_constructor<Args, E...>)),
::eina_main_loop_is(), __FILE__, __LINE__);
if (!_eo_call_resolve("detail::inherit_constructor", op, &call,
if (!_eo_call_resolve("detail::inherit_constructor", op, &___call,
::eina_main_loop_is(), __FILE__, __LINE__))
{
assert(_eo_call_resolve("detail::inherit_constructor", op, &call,
assert(_eo_call_resolve("detail::inherit_constructor", op, &___call,
::eina_main_loop_is(), __FILE__, __LINE__));
return;
}
func_t func = (func_t) call.func;
func_t func = (func_t) ___call.func;
EO_HOOK_CALL_PREPARE(eo_hook_call_pre, "");
func(call.obj, call.data, this_, args);
func(___call.obj, ___call.data, this_, args);
EO_HOOK_CALL_PREPARE(eo_hook_call_post, "");
}

View File

@ -70,20 +70,20 @@ example_complex_types()
bg.color_set(255, 255, 255, 255);
bg.position_set(0, 0);
bg.size_set(500, 250);
bg.visibility_set(true);
bg.visible_set(true);
efl::evas::grid grid(efl::eo::parent = canvas);
grid.position_set(0, 0);
grid.object_smart::color_set(0, 0, 0, 255);
grid.size_set(5, 5);
grid.visibility_set(true);
grid.visible_set(true);
efl::evas::text text1(efl::eo::parent = canvas);
text1.style_set(EVAS_TEXT_STYLE_OUTLINE);
text1.color_set(255, 0, 0, 255);
text1.font_set("DejaVu", 32);
text1.text_set("EFL++ Examples");
text1.visibility_set(true);
text1.visible_set(true);
int t1w, t1h;
text1.size_get(&t1w, &t1h);
grid.pack(text1, 1, 1, t1w, t1h);
@ -96,7 +96,7 @@ example_complex_types()
std::stringstream ss;
ss << "version " << EFL_VERSION_MAJOR << "." << EFL_VERSION_MINOR;
text2.text_set(ss.str().c_str());
text2.visibility_set(true);
text2.visible_set(true);
int t2w, t2h;
text2.size_get(&t2w, &t2h);

View File

@ -73,7 +73,7 @@ example_complex_types()
bg.color_set(255, 255, 255, 255);
bg.position_set(0, 0);
bg.size_set(500, 250);
bg.visibility_set(true);
bg.visible_set(true);
efl::eo::signal_connection conn =
bg.callback_mouse_down_add

View File

@ -39,3 +39,5 @@
/evas_3d_mmap
/evas_3d_shadows
/evas_3d_parallax_occlusion
/evas_vg_simple
/evas_vg_batman

View File

@ -7,9 +7,11 @@ AM_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl/interfaces \
-I$(top_srcdir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eo \
-I$(top_srcdir)/src/lib/ector \
-I$(top_srcdir)/src/lib/evas \
-I$(top_builddir)/src/lib/eina \
-I$(top_builddir)/src/lib/eo \
-I$(top_builddir)/src/lib/ector \
-I$(top_builddir)/src/lib/evas \
@EVAS_CFLAGS@
@ -30,6 +32,7 @@ evas_init_shutdown_LDADD = $(top_builddir)/src/lib/evas/libevas.la @EVAS_LDFLAGS
ECORE_EVAS_COMMON_CPPFLAGS = \
-I$(top_srcdir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eo \
-I$(top_srcdir)/src/lib/ector \
-I$(top_srcdir)/src/lib/evas \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/ecore_file \
@ -38,6 +41,7 @@ ECORE_EVAS_COMMON_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/eina \
-I$(top_builddir)/src/lib/eo \
-I$(top_builddir)/src/lib/ector \
-I$(top_builddir)/src/lib/evas \
-I$(top_builddir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore_file \
@ -54,6 +58,7 @@ $(top_builddir)/src/lib/ecore/libecore.la \
$(top_builddir)/src/lib/ecore_file/libecore_file.la \
$(top_builddir)/src/lib/ecore_input/libecore_input.la \
$(top_builddir)/src/lib/ecore_evas/libecore_evas.la \
$(top_builddir)/src/lib/ector/libector.la \
$(top_builddir)/src/lib/evas/libevas.la \
@EVAS_LDFLAGS@ -lm
@ -66,7 +71,9 @@ EDJE_COMMON_CPPFLAGS = \
-I$(top_builddir)/src/lib/eo \
-I$(top_srcdir)/src/lib/eet \
-I$(top_builddir)/src/lib/eet \
-I$(top_srcdir)/src/lib/ector \
-I$(top_srcdir)/src/lib/evas \
-I$(top_builddir)/src/lib/ector \
-I$(top_builddir)/src/lib/evas \
-I$(top_srcdir)/src/lib/ecore \
-I$(top_builddir)/src/lib/ecore \
@ -282,6 +289,16 @@ evas_gl_SOURCES = evas-gl.c
evas_gl_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
evas_gl_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
EXTRA_PROGRAMS += evas_vg_simple
evas_vg_simple_SOURCES = evas-vg-simple.c
evas_vg_simple_LDADD = $(ECORE_EVAS_COMMON_LDADD)
evas_vg_simple_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
EXTRA_PROGRAMS += evas_vg_batman
evas_vg_batman_SOURCES = evas-vg-batman.c
evas_vg_batman_LDADD = $(ECORE_EVAS_COMMON_LDADD)
evas_vg_batman_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
.edc.edj:
$(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) $< $(builddir)/$(@F)
@ -324,7 +341,9 @@ evas-smart-object.c \
evas-stacking.c \
evas-table.c \
evas-multi-touch.c \
evas-text.c
evas-text.c \
evas-vg-simple.c \
evas-vg-batman.c
DATA_FILES = \
resources/images/enlightenment.png \

View File

@ -112,8 +112,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -243,14 +243,14 @@ main(void)
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
evas_object_focus_set(image, EINA_TRUE);
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -136,8 +136,8 @@ _on_canvas_resize(Ecore_Evas *ee)
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
evas_object_resize(background, w, h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool

View File

@ -121,8 +121,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(bg, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(bg, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -409,8 +409,8 @@ int main(int argc, char **argv)
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
evas_object_focus_set(image, EINA_TRUE);
eo_do(image, evas_obj_image_scene_set(globalscene.scene));

View File

@ -110,8 +110,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -260,15 +260,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(data.scene));

View File

@ -79,8 +79,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -259,15 +259,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(data.scene));

View File

@ -93,8 +93,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
int
@ -214,15 +214,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -68,8 +68,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
int
@ -178,15 +178,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -34,7 +34,7 @@
extention##_file = eina_file_open(buffer , 0); \
mesh_##extention = eo_add(EVAS_3D_MESH_CLASS, evas); \
eo_do(mesh_##extention, \
evas_3d_mesh_mmap_set(extention##_file, NULL), \
efl_file_mmap_set(extention##_file, NULL), \
evas_3d_mesh_frame_material_set(0, material), \
evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG)); \
node_##extention = eo_add(EVAS_3D_NODE_CLASS, evas, \
@ -161,8 +161,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
int
@ -258,15 +258,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(20, 20, 200, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(20, 20, 200, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -139,8 +139,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
int
@ -235,15 +235,15 @@ main(void)
/* Add a background rectangle MESHES. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -80,8 +80,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -259,15 +259,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE),
evas_object_focus_set(image, EINA_TRUE));
/* Set the image object as render target for 3D scene. */

View File

@ -199,15 +199,15 @@ main(void)
/* Add evas objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_image_scene_set(scene),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
evas_object_event_callback_add(image, EVAS_CALLBACK_MOUSE_DOWN,
_on_mouse_down, NULL);

View File

@ -91,8 +91,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
int
@ -227,15 +227,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(100, 100, 100, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(100, 100, 100, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Set the image object as render target for 3D scene. */
eo_do(image, evas_obj_image_scene_set(scene));

View File

@ -56,8 +56,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static Eina_Bool
@ -218,23 +218,23 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add a background image. */
source = evas_object_image_filled_add(evas);
eo_do(source,
evas_obj_image_size_set(IMG_WIDTH, IMG_HEIGHT),
evas_obj_position_set((WIDTH / 2), (HEIGHT / 2)),
evas_obj_size_set((WIDTH / 2), (HEIGHT / 2)),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_view_size_set(IMG_WIDTH, IMG_HEIGHT),
efl_gfx_position_set((WIDTH / 2), (HEIGHT / 2)),
efl_gfx_size_set((WIDTH / 2), (HEIGHT / 2)),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set((WIDTH / 2), (HEIGHT / 2)),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set((WIDTH / 2), (HEIGHT / 2)),
efl_gfx_visible_set(EINA_TRUE));
/* Setup scene */
_scene_setup(&data);

View File

@ -147,8 +147,8 @@ _on_canvas_resize(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(background, evas_obj_size_set(w, h));
eo_do(image, evas_obj_size_set(w, h));
eo_do(background, efl_gfx_size_set(w, h));
eo_do(image, efl_gfx_size_set(w, h));
}
static void
@ -525,15 +525,15 @@ main(void)
/* Add a background rectangle objects. */
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
eo_do(background,
evas_obj_color_set(0, 0, 0, 255),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_color_set(0, 0, 0, 255),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
/* Add an image object for 3D scene rendering. */
image = evas_object_image_filled_add(evas);
eo_do(image,
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
evas_object_focus_set(image, EINA_TRUE);
/* Set the image object as render target for 3D scene. */

View File

@ -59,7 +59,7 @@ _canvas_resize_cb(Ecore_Evas *ee)
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
eo_do(d.bg, evas_obj_size_set(w, h));
eo_do(d.bg, efl_gfx_size_set(w, h));
}
static void
@ -80,7 +80,7 @@ _on_keydown(void *data EINA_UNUSED,
{
int alpha, r, g, b;
eo_do(d.clipper, evas_obj_color_get(&r, &g, &b, &alpha));
eo_do(d.clipper, efl_gfx_color_get(&r, &g, &b, &alpha));
evas_color_argb_unpremul(alpha, &r, &g, &b);
alpha -= 20;
@ -88,7 +88,7 @@ _on_keydown(void *data EINA_UNUSED,
alpha = 255;
evas_color_argb_premul(alpha, &r, &g, &b);
eo_do(d.clipper, evas_obj_color_set(r, g, b, alpha));
eo_do(d.clipper, efl_gfx_color_set(r, g, b, alpha));
fprintf(stdout, "Changing clipper's opacity: %d%%\n",
(int)((alpha / 255.0) * 100));
@ -102,7 +102,7 @@ _on_keydown(void *data EINA_UNUSED,
fprintf(stdout, "Changing clipper's color to");
eo_do(d.clipper, evas_obj_color_get(&r, &g, &b, &alpha));
eo_do(d.clipper, efl_gfx_color_get(&r, &g, &b, &alpha));
evas_color_argb_unpremul(alpha, &r, &g, &b);
if (g > 0)
@ -117,7 +117,7 @@ _on_keydown(void *data EINA_UNUSED,
}
evas_color_argb_premul(alpha, &r, &g, &b);
eo_do(d.clipper, evas_obj_color_set(r, g, b, alpha));
eo_do(d.clipper, efl_gfx_color_set(r, g, b, alpha));
return;
}
@ -145,8 +145,8 @@ _on_keydown(void *data EINA_UNUSED,
Eina_Bool visibility;
/* Don't use "get"-"set" expressions in one eo_do call,
* if you pass parameter to "set" by value. */
eo_do(d.clipper, visibility = evas_obj_visibility_get());
eo_do(d.clipper, evas_obj_visibility_set(!visibility));
eo_do(d.clipper, visibility = efl_gfx_visible_get());
eo_do(d.clipper, efl_gfx_visible_set(!visibility));
fprintf(stdout, "Clipper is now %s\n", visibility ? "hidden" : "visible");
return;
}
@ -178,10 +178,10 @@ main(void)
/* Eo-styled way to perform actions on an object*/
eo_do(d.bg, evas_obj_name_set("background rectangle"),
evas_obj_color_set(255, 255, 255, 255), /* white bg */
evas_obj_position_set(0, 0), /* at canvas' origin */
evas_obj_size_set(WIDTH, HEIGHT), /* covers full canvas */
evas_obj_visibility_set(EINA_TRUE),
efl_gfx_color_set(255, 255, 255, 255), /* white bg */
efl_gfx_position_set(0, 0), /* at canvas' origin */
efl_gfx_size_set(WIDTH, HEIGHT), /* covers full canvas */
efl_gfx_visible_set(EINA_TRUE),
evas_obj_focus_set(EINA_TRUE));
evas_object_event_callback_add(
@ -204,9 +204,9 @@ main(void)
}
else
{
eo_do(d.img, evas_obj_position_set(0, 0),
evas_obj_size_set(WIDTH, HEIGHT),
evas_obj_visibility_set(EINA_TRUE));
eo_do(d.img, efl_gfx_position_set(0, 0),
efl_gfx_size_set(WIDTH, HEIGHT),
efl_gfx_visible_set(EINA_TRUE));
const char *type = NULL;
eo_do(d.img, type = evas_obj_type_get());
@ -228,9 +228,9 @@ main(void)
eo_do(d.clipper_border,
evas_obj_image_border_set(3, 3, 3, 3),
evas_obj_image_border_center_fill_set(EVAS_BORDER_FILL_NONE),
evas_obj_position_set((WIDTH / 4) -3, (HEIGHT / 4) - 3),
evas_obj_size_set((WIDTH / 2) + 6, (HEIGHT / 2) + 6),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_position_set((WIDTH / 4) -3, (HEIGHT / 4) - 3),
efl_gfx_size_set((WIDTH / 2) + 6, (HEIGHT / 2) + 6),
efl_gfx_visible_set(EINA_TRUE));
}
/* solid white clipper (note that it's the default color for a
* rectangle) - it won't change clippees' colors, then (multiplying
@ -238,9 +238,9 @@ main(void)
d.clipper = eo_add(EVAS_RECTANGLE_CLASS, d.canvas);
eo_do(d.clipper,
evas_obj_position_set( WIDTH / 4, HEIGHT / 4),
evas_obj_size_set(WIDTH / 2, HEIGHT / 2),
evas_obj_visibility_set(EINA_TRUE));
efl_gfx_position_set( WIDTH / 4, HEIGHT / 4),
efl_gfx_size_set(WIDTH / 2, HEIGHT / 2),
efl_gfx_visible_set(EINA_TRUE));
eo_do(d.img, evas_obj_clip_set(d.clipper));

View File

@ -0,0 +1,171 @@
/**
* Simple Evas example illustrating the use of Evas_VG animation
*
* You'll need at least one engine built for it (excluding the buffer
* one). See stdout/stderr for output.
*
* @verbatim
* gcc -o evas_vg_batman evas-vg-batman.c `pkg-config --libs --cflags evas ecore ecore-evas eina ector eo efl`
* @endverbatim
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PACKAGE_EXAMPLES_DIR "."
#endif
#define WIDTH 800
#define HEIGHT 600
#ifndef EFL_BETA_API_SUPPORT
#define EFL_BETA_API_SUPPORT 1
#endif
#include <Eo.h>
#include <Efl.h>
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <math.h>
#include <Eina.h>
static Evas_Object *background = NULL;
static Evas_Object *vg = NULL;
static Efl_VG *batman = NULL;
static int animation_position = 0;
static Ecore_Animator *animation = NULL;
static Efl_VG **batmans_vg = NULL;
static const char *batmans_path[] = {
"M 256,213 C 245,181 206,187 234,262 147,181 169,71.2 233,18 220,56 235,81 283,88 285,78.7 286,69.3 288,60 289,61.3 290,62.7 291,64 291,64 297,63 300,63 303,63 309,64 309,64 310,62.7 311,61.3 312,60 314,69.3 315,78.7 317,88 365,82 380,56 367,18 431,71 453,181 366,262 394,187 356,181 344,213 328,185 309,184 300,284 291,184 272,185 256,213 Z",
"M 212,220 C 197,171 156,153 123,221 109,157 120,109 159,63.6 190,114 234,115 254,89.8 260,82.3 268,69.6 270,60.3 273,66.5 275,71.6 280,75.6 286,79.5 294,79.8 300,79.8 306,79.8 314,79.5 320,75.6 325,71.6 327,66.5 330,60.3 332,69.6 340,82.3 346,89.8 366,115 410,114 441,63.6 480,109 491,157 477,221 444,153 403,171 388,220 366,188 316,200 300,248 284,200 234,188 212,220 Z",
"M 213,222 C 219,150 165,139 130,183 125,123 171,73.8 247,51.6 205,78 236,108 280,102 281,90.3 282,79 286,68.2 287,72 288,75.8 289,79.7 293,79.7 296,79.7 300,79.7 304,79.7 307,79.7 311,79.7 312,75.8 313,72 314,68.2 318,79 319,90.3 320,102 364,108 395,78 353,51.6 429,73.8 475,123 470,183 435,139 381,150 387,222 364,176 315,172 300,248 285,172 236,176 213,222 Z",
"M 218,231 C 191,238 165,252 140,266 144,209 156,153 193,93.7 218,106 249,105 280,102 282,90.3 284,78.6 289,67.8 290,71.6 291,75.8 292,79.7 292,79.7 297,79.7 300,79.7 303,79.7 308,79.7 308,79.7 309,75.8 310,71.6 311,67.8 316,78.6 318,90.3 320,102 351,105 382,106 407,93.7 444,153 456,209 460,266 435,252 409,238 382,231 355,224 328,223 300,223 272,223 245,224 218,231 Z",
"M 258,243 C 220,201 221,220 253,281 154,243 150,108 229,61.9 242,83 257,98.1 275,110 278,88 282,65.8 285,43.6 287,49.9 288,56.2 290,62.5 293,62.7 297,62.9 300,62.9 303,62.9 307,62.7 310,62.5 312,56.2 313,49.9 315,43.6 318,65.8 322,88 325,110 343,98.1 358,83 371,61.9 450,108 446,243 347,281 379,220 380,201 342,243 330,187 329,202 300,271 271,202 270,187 258,243 Z",
"M 235,210 C 214,139 143,145 183,229 108,175 135,70.1 242,48.3 190,85.6 245,142 278,95.5 281,80.2 281,62.7 284,48.7 287,53.9 287,59.1 289,64.5 292,64.7 297,64.2 300,64.2 303,64.2 308,64.7 311,64.5 313,59.1 313,53.9 316,48.7 319,62.7 319,80.2 322,95.5 355,142 410,85.6 358,48.3 465,70.1 492,175 417,229 457,145 386,139 365,210 357,147 309,190 300,271 291,190 243,147 235,210 Z",
"M 249,157 C 214,157 201,203 273,255 157,221 157,69 274,32.8 188,87.2 211,140 256,140 291,140 289,128 291,98.1 293,107 293,116 295,125 297,125 298,125 300,125 302,125 305,125 305,125 307,116 307,107 309,98.1 311,128 309,140 344,140 389,140 412,87.2 326,32.8 443,69 443,221 327,255 399,203 386,157 351,157 317,157 300,195 300,238 300,195 283,157 249,157 Z",
"M 264,212 C 213,138 150,171 232,244 101,217 112,55.1 257,36.9 182,86.6 222,106 266,106 285,106 284,66.7 286,36.8 288,42.6 289,48.4 291,54.2 291,54.2 297,54.2 300,54.2 303,54.2 309,54.2 309,54.2 311,48.4 312,42.6 314,36.8 316,66.7 315,106 334,106 378,106 418,86.6 343,36.9 488,55.1 499,217 368,244 450,171 387,138 336,212 354,161 300,163 300,249 300,163 246,161 264,212 Z",
"M 223,217 C 194,153 165,168 133,219 143,158 161,99.2 189,38.4 214,69.8 241,84.7 272,86.2 272,70.2 273,53.5 273,37.5 275,47.9 278,58.4 280,68.8 287,64.9 292,62.4 300,62.4 308,62.4 313,64.9 320,68.8 322,58.4 325,47.9 327,37.5 327,53.5 328,70.2 328,86.2 359,84.7 386,69.8 411,38.4 439,99.2 457,158 467,219 435,168 406,153 377,217 350,162 319,176 300,245 281,176 250,162 223,217 Z",
"M 231,185 C 186,159 161,180 190,215 86.2,180 92.6,99.6 211,68.9 195,112 254,141 279,96.7 279,83.2 279,69.8 279,56.3 283,63.6 288,70.8 292,78.1 295,78.1 297,78.1 300,78.1 303,78.1 305,78.1 308,78.1 312,70.8 317,63.6 321,56.3 321,69.8 321,83.2 321,96.7 346,141 405,112 389,68.9 507,99.6 514,180 410,215 439,180 414,159 369,185 351,165 324,167 300,216 276,167 249,165 231,185 Z",
"M 194,146 C 192,107 164,76.4 136,45.6 166,55.7 196,65.7 226,75.8 238,107 265,163 279,136 282,130 281,108 281,94.8 285,103 288,111 293,115 295,116 298,117 300,117 302,117 305,116 307,115 312,111 315,103 319,94.8 319,108 318,130 321,136 335,163 362,107 374,75.8 404,65.7 434,55.7 464,45.6 436,76.4 408,107 406,146 355,158 323,189 300,231 277,189 245,158 194,146 Z",
"M 209,182 C 184,132 176,138 113,161 140,136 168,111 196,86.5 221,104 247,115 278,115 281,99.9 285,85.5 287,70.2 289,78.5 292,88.4 294,96.7 296,96.7 298,96.7 300,96.7 302,96.7 304,96.7 306,96.7 308,88.4 311,78.5 313,70.2 315,85.5 319,99.9 322,115 353,115 379,104 404,86.5 432,111 460,136 487,161 424,138 416,132 391,182 332,150 341,161 300,214 259,161 268,150 209,182 Z",
"M 198,171 C 189,131 150,120 113,140 142,104 182,74.4 249,70.2 208,89 248,125 278,106 285,101 286,93.5 286,74.2 288,78.1 291,81.5 294,83.2 296,84.2 298,84.7 300,84.7 302,84.7 304,84.2 306,83.2 309,81.5 312,78.1 314,74.2 314,93.5 315,101 322,106 352,125 392,89 351,70.2 418,74.4 458,104 487,140 450,120 411,131 402,171 357,147 322,171 300,214 278,171 243,147 198,171 Z",
"M 202,170 C 188,115 157,108 124,105 146,84.3 171,71.5 199,70.2 211,98.6 243,103 277,106 279,99.3 281,92.6 283,86 285,91.9 287,97.9 290,104 293,104 297,104 300,104 303,104 307,104 310,104 313,97.9 315,91.9 317,86 319,92.6 321,99.3 323,106 357,103 389,98.6 401,70.2 429,71.5 454,84.3 476,105 443,108 412,115 398,170 349,157 318,175 300,214 282,175 251,157 202,170 Z",
"M 220,179 C 200,127 150,130 123,175 122,110 160,85.1 201,64 208,99.2 243,111 268,92.9 278,86.1 284,68.2 287,40.7 289,49.6 292,58.4 294,67.3 296,67.3 298,67.3 300,67.3 302,67.3 304,67.3 306,67.3 308,58.4 311,49.6 313,40.7 316,68.2 322,86.1 332,92.9 357,111 392,99.3 399,64 440,85.1 478,110 477,175 450,130 400,127 380,179 355,155 305,208 300,247 295,208 245,155 220,179 Z",
"M 166,154 C 179,119 154,95.4 114,79.3 155,79.1 197,78.9 239,78.7 242,103 250,109 283,109 289,109 290,93.9 291,83.7 292,88.3 292,92.9 293,97.5 295,97.5 298,97.5 300,97.5 302,97.5 305,97.5 307,97.5 308,92.9 308,88.3 309,83.7 310,93.9 311,109 317,109 350,109 358,103 361,78.7 403,78.9 445,79.1 486,79.3 446,95.4 421,119 434,154 377,151 320,151 300,207 280,151 223,151 166,154 Z",
};
static void
_on_delete(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
static void
_on_resize(Ecore_Evas *ee)
{
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
evas_object_resize(background, w, h);
evas_object_resize(vg, w, h);
}
static Eina_Bool
_animator(void *data EINA_UNUSED, double pos)
{
int next = (animation_position + 1) % (sizeof (batmans_path) / sizeof (batmans_path[0]));
evas_vg_shape_shape_interpolate(batman,
batmans_vg[next],
batmans_vg[animation_position],
ecore_animator_pos_map(pos, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0));
if (pos == 1.0)
{
animation_position = next;
animation = ecore_animator_timeline_add(1, _animator, NULL);
}
return EINA_TRUE;
}
int
main(void)
{
Ecore_Evas *ee;
Evas *e;
Efl_VG *circle;
Efl_VG *root;
unsigned int i;
if (!ecore_evas_init())
return -1;
//setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1);
ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!ee) return -1;
ecore_evas_callback_delete_request_set(ee, _on_delete);
ecore_evas_callback_resize_set(ee, _on_resize);
ecore_evas_show(ee);
e = ecore_evas_get(ee);
background = evas_object_rectangle_add(e);
evas_object_color_set(background, 70, 70, 70, 255);
evas_object_show(background);
vg = evas_object_vg_add(e);
evas_object_show(vg);
_on_resize(ee);
batmans_vg = malloc(sizeof (Efl_VG*) *
sizeof (batmans_path) / sizeof (batmans_path[0]));
if (!batmans_vg) return -1;
for (i = 0; i < sizeof (batmans_path) / sizeof (batmans_path[0]); i++)
{
batmans_vg[i] = evas_vg_shape_add(NULL);
evas_vg_node_color_set(batmans_vg[i], 0, 0, 0, 255);
evas_vg_shape_stroke_color_set(batmans_vg[i], 128, 10,10, 128);
evas_vg_shape_stroke_width_set(batmans_vg[i], 4.0);
evas_vg_shape_stroke_join_set(batmans_vg[i], EFL_GFX_JOIN_MITER);
if(i % 2)
{
evas_vg_shape_stroke_color_set(batmans_vg[i], 10, 10,128, 128);
evas_vg_shape_stroke_width_set(batmans_vg[i], 2.0);
evas_vg_node_color_set(batmans_vg[i], 120, 120, 120, 255);
evas_vg_shape_stroke_join_set(batmans_vg[i], EFL_GFX_JOIN_ROUND);
}
evas_vg_shape_shape_append_svg_path(batmans_vg[i], batmans_path[i]);
}
animation = ecore_animator_timeline_add(1, _animator, NULL);
root = evas_object_vg_root_node_get(vg);
Eina_Matrix3 matrix;
eina_matrix3_scale(&matrix, 1.1, 1.1);
evas_vg_node_transformation_set(root, &matrix);
circle = evas_vg_shape_add(root);
evas_vg_shape_shape_append_circle(circle, WIDTH / 2, HEIGHT / 2, 200);
evas_vg_node_color_set(circle, 255, 255, 255, 255);
evas_vg_shape_stroke_width_set(circle, 1);
evas_vg_shape_stroke_color_set(circle, 255, 0, 0, 255);
batman = evas_vg_shape_add(root);
evas_vg_node_color_set(batman, 0, 0, 0, 255);
evas_vg_node_origin_set(batman, 100, 150);
evas_vg_shape_shape_append_move_to(batman, 256, 213);
evas_vg_shape_shape_dup(batman, batmans_vg[0]);
ecore_main_loop_begin();
ecore_evas_shutdown();
return 0;
}

View File

@ -0,0 +1,572 @@
/**
* Simple Evas example illustrating a Evas_VG basic node usage.
*
* You'll need at least one engine built for it (excluding the buffer
* one). See stdout/stderr for output.
*
* @verbatim
* gcc -o evas_vg_simple evas-vg-simple.c `pkg-config --libs --cflags evas ecore ecore-evas eina ector eo efl`
* @endverbatim
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PACKAGE_EXAMPLES_DIR "."
#endif
#define WIDTH 400
#define HEIGHT 400
#ifndef EFL_BETA_API_SUPPORT
#define EFL_BETA_API_SUPPORT 1
#endif
#ifndef EFL_EO_API_SUPPORT
#define EFL_EO_API_SUPPORT 1
#endif
#include <Eo.h>
#include <Efl.h>
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <math.h>
#include <Eina.h>
#define PATH_KAPPA 0.5522847498
#define PI 3.1415926535
typedef struct _Bezier
{
float x1, y1, x2, y2, x3, y3, x4, y4;
}Bezier;
typedef struct _Point
{
int x;
int y;
}Point;
static
Bezier bezierFromPoints(Point p1, Point p2,
Point p3, Point p4)
{
Bezier b;
b.x1 = p1.x;
b.y1 = p1.y;
b.x2 = p2.x;
b.y2 = p2.y;
b.x3 = p3.x;
b.y3 = p3.y;
b.x4 = p4.x;
b.y4 = p4.y;
return b;
}
inline void
parameterSplitLeft(Bezier *b, float t, Bezier *left)
{
left->x1 = b->x1;
left->y1 = b->y1;
left->x2 = b->x1 + t * ( b->x2 - b->x1 );
left->y2 = b->y1 + t * ( b->y2 - b->y1 );
left->x3 = b->x2 + t * ( b->x3 - b->x2 ); // temporary holding spot
left->y3 = b->y2 + t * ( b->y3 - b->y2 ); // temporary holding spot
b->x3 = b->x3 + t * ( b->x4 - b->x3 );
b->y3 = b->y3 + t * ( b->y4 - b->y3 );
b->x2 = left->x3 + t * ( b->x3 - left->x3);
b->y2 = left->y3 + t * ( b->y3 - left->y3);
left->x3 = left->x2 + t * ( left->x3 - left->x2 );
left->y3 = left->y2 + t * ( left->y3 - left->y2 );
left->x4 = b->x1 = left->x3 + t * (b->x2 - left->x3);
left->y4 = b->y1 = left->y3 + t * (b->y2 - left->y3);
}
static
Bezier bezierOnInterval(Bezier *b, float t0, float t1)
{
if (t0 == 0 && t1 == 1)
return *b;
Bezier result;
parameterSplitLeft(b, t0, &result);
float trueT = (t1-t0)/(1-t0);
parameterSplitLeft(b, trueT, &result);
return result;
}
inline void
_bezier_coefficients(float t, float *ap, float *bp, float *cp, float *dp)
{
float a,b,c,d;
float m_t = 1. - t;
b = m_t * m_t;
c = t * t;
d = c * t;
a = b * m_t;
b *= 3. * t;
c *= 3. * m_t;
*ap = a;
*bp = b;
*cp = c;
*dp = d;
}
static
float _t_for_arc_angle(float angle)
{
if (angle < 0.00001)
return 0;
if (angle == 90.0)
return 1;
float radians = PI * angle / 180;
float cosAngle = cos(radians);
float sinAngle = sin(radians);
// initial guess
float tc = angle / 90;
// do some iterations of newton's method to approximate cosAngle
// finds the zero of the function b.pointAt(tc).x() - cosAngle
tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
/ (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative
tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
/ (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative
// initial guess
float ts = tc;
// do some iterations of newton's method to approximate sinAngle
// finds the zero of the function b.pointAt(tc).y() - sinAngle
ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle)
/ (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA);
ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle)
/ (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA);
// use the average of the t that best approximates cosAngle
// and the t that best approximates sinAngle
float t = 0.5 * (tc + ts);
return t;
}
static void
_find_ellipse_coords(int x, int y, int w, int h, float angle, float length,
Point* startPoint, Point *endPoint)
{
if (!w || !h ) {
if (startPoint)
startPoint->x = 0 , startPoint->y = 0;
if (endPoint)
endPoint->x = 0 , endPoint->y = 0;
return;
}
int w2 = w / 2;
int h2 = h / 2;
float angles[2] = { angle, angle + length };
Point *points[2] = { startPoint, endPoint };
int i =0;
for (i = 0; i < 2; ++i) {
if (!points[i])
continue;
float theta = angles[i] - 360 * floor(angles[i] / 360);
float t = theta / 90;
// truncate
int quadrant = (int)t;
t -= quadrant;
t = _t_for_arc_angle(90 * t);
// swap x and y?
if (quadrant & 1)
t = 1 - t;
float a, b, c, d;
_bezier_coefficients(t, &a, &b, &c, &d);
float px = a + b + c*PATH_KAPPA;
float py = d + c + b*PATH_KAPPA;
// left quadrants
if (quadrant == 1 || quadrant == 2)
px = -px;
// top quadrants
if (quadrant == 0 || quadrant == 1)
py = -py;
int cx = x+w/2;
int cy = y+h/2;
points[i]->x = cx + w2 * px;
points[i]->y = cy + h2 * py;
}
}
//// The return value is the starting point of the arc
static
Point _curves_for_arc(int x, int y, int w, int h,
float startAngle, float sweepLength,
Point *curves, int *point_count)
{
*point_count = 0;
int w2 = w / 2;
int w2k = w2 * PATH_KAPPA;
int h2 = h / 2;
int h2k = h2 * PATH_KAPPA;
Point points[16] =
{
// start point
{ x + w, y + h2 },
// 0 -> 270 degrees
{ x + w, y + h2 + h2k },
{ x + w2 + w2k, y + h },
{ x + w2, y + h },
// 270 -> 180 degrees
{ x + w2 - w2k, y + h },
{ x, y + h2 + h2k },
{ x, y + h2 },
// 180 -> 90 degrees
{ x, y + h2 - h2k },
{ x + w2 - w2k, y },
{ x + w2, y },
// 90 -> 0 degrees
{ x + w2 + w2k, y },
{ x + w, y + h2 - h2k },
{ x + w, y + h2 }
};
if (sweepLength > 360) sweepLength = 360;
else if (sweepLength < -360) sweepLength = -360;
// Special case fast paths
if (startAngle == 0) {
if (sweepLength == 360) {
int i;
for (i = 11; i >= 0; --i)
curves[(*point_count)++] = points[i];
return points[12];
} else if (sweepLength == -360) {
int i ;
for (i = 1; i <= 12; ++i)
curves[(*point_count)++] = points[i];
return points[0];
}
}
int startSegment = (int)(floor(startAngle / 90));
int endSegment = (int)(floor((startAngle + sweepLength) / 90));
float startT = (startAngle - startSegment * 90) / 90;
float endT = (startAngle + sweepLength - endSegment * 90) / 90;
int delta = sweepLength > 0 ? 1 : -1;
if (delta < 0) {
startT = 1 - startT;
endT = 1 - endT;
}
// avoid empty start segment
if (startT == 1.0) {
startT = 0;
startSegment += delta;
}
// avoid empty end segment
if (endT == 0) {
endT = 1;
endSegment -= delta;
}
startT = _t_for_arc_angle(startT * 90);
endT = _t_for_arc_angle(endT * 90);
Eina_Bool splitAtStart = !(fabs(startT) <= 0.00001f);
Eina_Bool splitAtEnd = !(fabs(endT - 1.0) <= 0.00001f);
const int end = endSegment + delta;
// empty arc?
if (startSegment == end) {
const int quadrant = 3 - ((startSegment % 4) + 4) % 4;
const int j = 3 * quadrant;
return delta > 0 ? points[j + 3] : points[j];
}
Point startPoint, endPoint;
_find_ellipse_coords(x, y, w, h, startAngle, sweepLength, &startPoint, &endPoint);
int i;
for (i = startSegment; i != end; i += delta) {
const int quadrant = 3 - ((i % 4) + 4) % 4;
const int j = 3 * quadrant;
Bezier b;
if (delta > 0)
b = bezierFromPoints(points[j + 3], points[j + 2], points[j + 1], points[j]);
else
b = bezierFromPoints(points[j], points[j + 1], points[j + 2], points[j + 3]);
// empty arc?
if (startSegment == endSegment && (startT == endT))
return startPoint;
if (i == startSegment) {
if (i == endSegment && splitAtEnd)
b = bezierOnInterval(&b, startT, endT);
else if (splitAtStart)
b = bezierOnInterval(&b, startT, 1);
} else if (i == endSegment && splitAtEnd) {
b = bezierOnInterval(&b, 0, endT);
}
// push control points
curves[(*point_count)].x = b.x2;
curves[(*point_count)++].y = b.y2;
curves[(*point_count)].x = b.x3;
curves[(*point_count)++].y = b.y3;
curves[(*point_count)].x = b.x4;
curves[(*point_count)++].y = b.y4;
}
curves[*(point_count)-1] = endPoint;
return startPoint;
}
void _arcto(Efl_VG *obj, int x, int y, int width, int height, int startAngle, int sweepLength)
{
int point_count;
Point pts[15];
Point curve_start = _curves_for_arc(x, y, width, height, startAngle, sweepLength, pts, &point_count);
int cx = x + (width)/2;
int cy = y + (height)/2;
int i;
evas_vg_shape_shape_append_move_to(obj, cx, cy);
evas_vg_shape_shape_append_line_to(obj, curve_start.x, curve_start.y);
for (i = 0; i < point_count; i += 3)
{
evas_vg_shape_shape_append_cubic_to(obj,
pts[i+2].x, pts[i+2].y,
pts[i].x, pts[i].y,
pts[i+1].x, pts[i+1].y);
}
evas_vg_shape_shape_append_close(obj);
}
void _rect_add(Efl_VG *obj, int x, int y, int w, int h)
{
evas_vg_shape_shape_append_move_to(obj, x, y);
evas_vg_shape_shape_append_line_to(obj, x + w, y);
evas_vg_shape_shape_append_line_to(obj, x + w, y +h);
evas_vg_shape_shape_append_line_to(obj, x, y +h);
evas_vg_shape_shape_append_close(obj);
}
struct example_data
{
Ecore_Evas *ee;
Evas *evas;
Evas_Object *bg;
Evas_Object *vg;
};
static struct example_data d;
static void
_on_delete(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
static void /* adjust canvas' contents on resizes */
_canvas_resize_cb(Ecore_Evas *ee)
{
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
evas_object_resize(d.bg, w, h);
evas_object_resize(d.vg, w, h);
}
static void
vector_set(int x, int y, int w, int h)
{
int vg_w = w, vg_h = h;
//Create VG Object
Evas_Object *tmp = evas_object_rectangle_add(d.evas);
evas_object_resize(tmp, vg_w, vg_h);
evas_object_color_set(tmp, 100, 100, 50, 100);
evas_object_move(tmp, x,y);
evas_object_show(tmp);
d.vg = evas_object_vg_add(d.evas);
evas_object_resize(d.vg, vg_w, vg_h);
evas_object_move(d.vg, x,y);
evas_object_show(d.vg);
evas_object_clip_set(d.vg, tmp);
// Applying map on the evas_object_vg
// Evas_Map *m = evas_map_new(4);
// evas_map_smooth_set(m, EINA_TRUE);
// evas_map_util_points_populate_from_object_full(m, d.vg, 0);
// evas_map_util_rotate(m, 10, 0,0);
// evas_object_map_enable_set(d.vg, EINA_TRUE);
// evas_object_map_set(d.vg, m);
// apply some transformation
double radian = 30.0 * 2 * 3.141 / 360.0;
Eina_Matrix3 matrix;
eina_matrix3_rotate(&matrix, radian);
Efl_VG *root = evas_object_vg_root_node_get(d.vg);
//eo_do(root, evas_vg_node_transformation_set(&matrix));
Efl_VG *bg = eo_add(EFL_VG_SHAPE_CLASS, root);
_rect_add(bg, 0, 0 , vg_w, vg_h);
evas_vg_node_origin_set(bg, 0,0);
evas_vg_shape_stroke_width_set(bg, 1.0);
evas_vg_node_color_set(bg, 80, 80, 80, 80);
Efl_VG *shape = eo_add(EFL_VG_SHAPE_CLASS, root);
Efl_VG *rgradient = eo_add(EFL_VG_GRADIENT_RADIAL_CLASS, root);
Efl_VG *lgradient = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, root);
_arcto(shape, 0, 0, 100, 100, 25, 330);
Efl_Gfx_Gradient_Stop stops[3];
stops[0].r = 255;
stops[0].g = 0;
stops[0].b = 0;
stops[0].a = 255;
stops[0].offset = 0;
stops[1].r = 0;
stops[1].g = 255;
stops[1].b = 0;
stops[1].a = 255;
stops[1].offset = 0.5;
stops[2].r = 0;
stops[2].g = 0;
stops[2].b = 255;
stops[2].a = 255;
stops[2].offset = 1;
evas_vg_node_origin_set(rgradient, 10, 10);
evas_vg_gradient_spread_set(rgradient, EFL_GFX_GRADIENT_SPREAD_REFLECT);
evas_vg_gradient_stop_set(rgradient, stops, 3);
evas_vg_gradient_radial_center_set(rgradient, 30, 30);
evas_vg_gradient_radial_radius_set(rgradient, 80);
evas_vg_node_origin_set(lgradient, 10, 10);
evas_vg_gradient_stop_set(lgradient, stops, 3);
evas_vg_gradient_spread_set(lgradient, EFL_GFX_GRADIENT_SPREAD_REFLECT);
evas_vg_gradient_stop_set(lgradient, stops, 3);
evas_vg_gradient_linear_start_set(lgradient, 10, 10);
evas_vg_gradient_linear_end_set(lgradient, 50, 50);
evas_vg_node_origin_set(shape, 10, 10);
evas_vg_shape_fill_set(shape, rgradient);
evas_vg_shape_stroke_scale_set(shape, 2.0);
evas_vg_shape_stroke_width_set(shape, 1.0);
evas_vg_node_color_set(shape, 0, 0, 255, 255);
evas_vg_shape_stroke_color_set(shape, 0, 0, 255, 128);
Efl_VG *rect = eo_add(EFL_VG_SHAPE_CLASS, root);
_rect_add(rect, 0, 0, 100, 100);
evas_vg_node_origin_set(rect, 100, 100);
evas_vg_shape_fill_set(rect, lgradient);
evas_vg_shape_stroke_width_set(rect, 2.0);
evas_vg_shape_stroke_join_set(rect, EFL_GFX_JOIN_ROUND);
evas_vg_shape_stroke_color_set(rect, 255, 255, 255, 255);
Efl_VG *rect1 = eo_add(EFL_VG_SHAPE_CLASS, root);
_rect_add(rect1, 0, 0, 70, 70);
evas_vg_node_origin_set(rect1, 50, 70);
evas_vg_shape_stroke_scale_set(rect1, 2);
evas_vg_shape_stroke_width_set(rect1, 8.0);
evas_vg_shape_stroke_join_set(rect1, EFL_GFX_JOIN_ROUND);
evas_vg_shape_stroke_color_set(rect1, 0, 100, 80, 100);
Efl_VG *circle = eo_add(EFL_VG_SHAPE_CLASS, root);
_arcto(circle, 0, 0, 250, 100, 30, 300);
evas_vg_shape_fill_set(circle, lgradient);
//evas_vg_node_transformation_set(&matrix),
evas_vg_node_origin_set(circle, 50,50);
evas_vg_node_color_set(circle, 50, 0, 0, 50);
// Foreground
Efl_VG *fg = eo_add(EFL_VG_SHAPE_CLASS, root);
_rect_add(fg, 0, 0, vg_w, vg_h);
evas_vg_node_origin_set(fg, 0, 0);
evas_vg_shape_stroke_width_set(fg, 5.0);
evas_vg_shape_stroke_join_set(fg, EFL_GFX_JOIN_ROUND);
evas_vg_shape_stroke_color_set(fg, 70, 70, 0, 70);
Efl_VG *tst = eo_add(EFL_VG_SHAPE_CLASS, root);
evas_vg_shape_shape_append_rect(tst, 50, 25, 200, 200, 3, 5);
evas_vg_node_color_set(tst, 0, 0, 200, 200);
evas_vg_shape_stroke_width_set(tst, 2);
evas_vg_shape_stroke_color_set(tst, 255, 0, 0, 255);
Efl_VG *vc = eo_add(EFL_VG_SHAPE_CLASS, root);
evas_vg_shape_shape_append_circle(vc, 100, 100, 23);
evas_vg_node_color_set(vc, 0, 200, 0, 255);
evas_vg_shape_stroke_width_set(vc, 4);
evas_vg_shape_stroke_color_set(vc, 255, 0, 0, 255);
}
int
main(void)
{
if (!ecore_evas_init())
return EXIT_FAILURE;
/* this will give you a window with an Evas canvas under the first
* engine available */
d.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!d.ee)
goto error;
ecore_evas_callback_delete_request_set(d.ee, _on_delete);
ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
ecore_evas_show(d.ee);
d.evas = ecore_evas_get(d.ee);
d.bg = evas_object_rectangle_add(d.evas);
evas_object_color_set(d.bg, 70, 70, 70, 255); /* white bg */
evas_object_show(d.bg);
_canvas_resize_cb(d.ee);
vector_set(50, 50, 300 ,300);
//vector_set(30, 90, 300 ,300);
ecore_main_loop_begin();
ecore_evas_shutdown();
return 0;
error:
ecore_evas_shutdown();
return -1;
}

View File

@ -44,7 +44,7 @@ int main()
rect.color_set(255, 0, 0, 255);
rect.position_set(10, 10);
rect.size_set(100, 100);
rect.visibility_set(true);
rect.visible_set(true);
canvas.render();
}

190
src/lib/ector/Ector.h Normal file
View File

@ -0,0 +1,190 @@
#ifndef ECTOR_H_
#define ECTOR_H_
#include <Eina.h>
#include <Eo.h>
#include <Efl.h>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EFL_ECTOR_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EFL_EO_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page ector_main Ector
*
* @date 2014 (created)
*
* @section toc Table of Contents
*
* @li @ref ector_main_intro
* @li @ref ector_main_compiling
* @li @ref ector_main_next_steps
* @li @ref ector_main_intro_example
*
* @section ector_main_intro Introduction
*
* Ector is a retained mode drawing library that is designed to work
* for and with an scenegraph like Evas.
*
* @section ector_main_compiling How to compile
*
* Ector is a library your application links to. The procedure for this is
* very simple. You simply have to compile your application with the
* appropriate compiler flags that the @c pkg-config script outputs. For
* example:
*
* Compiling C or C++ files into object files:
*
* @verbatim
gcc -c -o main.o main.c `pkg-config --cflags ector`
@endverbatim
*
* Linking object files into a binary executable:
*
* @verbatim
gcc -o my_application main.o `pkg-config --libs ector`
@endverbatim
*
* See @ref pkgconfig
*
* @section ector_main_next_steps Next Steps
*
* After you understood what Ector is and installed it in your system
* you should proceed understanding the programming interface.
*
* Recommended reading:
*
* @li @ref Ector_Surface
* @li @ref Ector_Renderer
*
* @section ector_main_intro_example Introductory Example
*
* @ref Ector_Tutorial
*
*
* @addtogroup Ector
* @{
*/
#ifdef EFL_BETA_API_SUPPORT
/**
* @typedef Ector_Surface
* The base type to render content into.
*/
typedef Eo Ector_Surface;
/**
* @typedef Ector_Renderer
* The base type describing what to render.
*/
typedef Eo Ector_Renderer;
/**
* @typedef Ector_Colorspace
* The definiton of colorspace.
*/
// FIXME: Enable that when we have merged Emile
/* typedef Evas_Colorspace Ector_Colorspace; */
/**
* Raster operations at pixel level
*/
typedef enum _Ector_Rop
{
ECTOR_ROP_BLEND, /**< D = S + D(1 - Sa) */
ECTOR_ROP_COPY, /**< D = S */
ECTOR_ROP_LAST
} Ector_Rop;
/**
* Quality values
*/
typedef enum _Ector_Quality
{
ECTOR_QUALITY_BEST, /**< Best quality */
ECTOR_QUALITY_GOOD, /**< Good quality */
ECTOR_QUALITY_FAST, /**< Lower quality, fastest */
ECTOR_QUALITY_LAST
} Ector_Quality;
/**
* Priorities
*/
typedef enum _Ector_Priority
{
ECTOR_PRIORITY_NONE = 0,
ECTOR_PRIORITY_MARGINAL = 64,
ECTOR_PRIORITY_SECONDARY = 128,
ECTOR_PRIORITY_PRIMARY = 256,
} Ector_Priority;
/**
* What kind of update is being pushed
*/
typedef enum _Ector_Update_Type
{
ECTOR_UPDATE_BACKGROUND = 1, /* All the previous state in that area is reset to the new updated profile */
ECTOR_UPDATE_EMPTY = 2, /* Pushing empty area (no visible pixels at all, no need to read this surface to render it) */
ECTOR_UPDATE_ALPHA = 4, /* Pushing some transparent pixels (this impact the under layer and will require to read back the surface where this surface is blitted) */
ECTOR_UPDATE_OPAQUE = 8 /* Pushing some opaque pixels (this means that their is no need to read the under layer when blitting this surface) */
} Ector_Update_Type;
/**
* @brief Init the ector subsystem
* @return @c EINA_TRUE on success.
*
* @see ector_shutfown()
*/
EAPI int ector_init(void);
/**
* @brief Shutdown the ector subsystem
* @return @c EINA_TRUE on success.
*
* @see ector_init()
*/
EAPI int ector_shutdown(void);
#include "ector_surface.h"
#include "ector_renderer.h"
#include "ector_util.h"
#endif
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,15 @@
#ifndef ECTOR_CAIRO_H_
# define ECTOR_CAIRO_H_
#include <Ector.h>
typedef Eo Ector_Cairo_Surface;
typedef struct _cairo_t cairo_t;
#include "cairo/ector_cairo_surface.eo.h"
#include "cairo/ector_renderer_cairo_base.eo.h"
#include "cairo/ector_renderer_cairo_shape.eo.h"
#include "cairo/ector_renderer_cairo_gradient_linear.eo.h"
#include "cairo/ector_renderer_cairo_gradient_radial.eo.h"
#endif

View File

@ -0,0 +1,75 @@
#ifndef ECTOR_CAIRO_PRIVATE_H_
# define ECTOR_CAIRO_PRIVATE_H_
typedef void cairo_pattern_t;
typedef struct {
double xx; double yx;
double xy; double yy;
double x0; double y0;
} cairo_matrix_t;
typedef struct _Ector_Cairo_Surface_Data Ector_Cairo_Surface_Data;
typedef struct _Ector_Renderer_Cairo_Base_Data Ector_Renderer_Cairo_Base_Data;
struct _Ector_Cairo_Surface_Data
{
cairo_t *cairo;
struct {
double x, y;
} current;
Eina_Bool internal : 1;
};
struct _Ector_Renderer_Cairo_Base_Data
{
Ector_Cairo_Surface_Data *parent;
Ector_Renderer_Generic_Base_Data *generic;
cairo_matrix_t *m;
};
typedef enum _cairo_extend {
CAIRO_EXTEND_NONE,
CAIRO_EXTEND_REPEAT,
CAIRO_EXTEND_REFLECT,
CAIRO_EXTEND_PAD
} cairo_extend_t;
static inline cairo_extend_t
_ector_cairo_extent_get(Efl_Gfx_Gradient_Spread s)
{
switch (s)
{
case EFL_GFX_GRADIENT_SPREAD_PAD:
return CAIRO_EXTEND_PAD;
case EFL_GFX_GRADIENT_SPREAD_REFLECT:
return CAIRO_EXTEND_REFLECT;
case EFL_GFX_GRADIENT_SPREAD_REPEAT:
return CAIRO_EXTEND_REPEAT;
default:
return CAIRO_EXTEND_NONE;
}
}
#define CHECK_CAIRO(Parent) (!(Parent && Parent->cairo))
#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 *obj, const char *name)
{
Eo *parent;
void *sym;
eo_do(obj, parent = eo_parent_get());
if (!parent) return NULL;
eo_do(parent, sym = ector_cairo_surface_symbol_get(name));
return sym;
}
#endif

View File

@ -0,0 +1,145 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include <cairo/Ector_Cairo.h>
#include "ector_private.h"
#include "ector_cairo_private.h"
static unsigned int _cairo_count = 0;
static Eina_Module *_cairo_so = NULL;
static void *
_ector_cairo_surface_symbol_get(Eo *obj EINA_UNUSED,
Ector_Cairo_Surface_Data *pd EINA_UNUSED,
const char *name)
{
if (!_cairo_so)
{
#define LOAD(x) \
if (!_cairo_so) \
{ \
_cairo_so = eina_module_new(x); \
if (_cairo_so && \
!eina_module_load(_cairo_so)) \
{ \
eina_module_free(_cairo_so); \
_cairo_so = NULL; \
} \
}
#if defined(_WIN32) || defined(__CYGWIN__)
LOAD("libcairo.dll");
#elif defined(__APPLE__) && defined(__MACH__)
LOAD("libcairo.dylib");
LOAD("libcairo.so");
#else
LOAD("libcairo.so");
#endif
#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 (type == ECTOR_RENDERER_GENERIC_SHAPE_MIXIN)
return eo_add(ECTOR_RENDERER_CAIRO_SHAPE_CLASS, obj);
else if (type == ECTOR_RENDERER_GENERIC_GRADIENT_LINEAR_MIXIN)
return eo_add(ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS, obj);
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_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,
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 cairo_t *
_ector_cairo_surface_context_get(Eo *obj EINA_UNUSED,
Ector_Cairo_Surface_Data *pd)
{
return pd->cairo;
}
static void
_ector_cairo_surface_ector_generic_surface_reference_point_set(Eo *obj EINA_UNUSED,
Ector_Cairo_Surface_Data *pd,
int x, int y)
{
pd->current.x = x;
pd->current.y = 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"

View File

@ -0,0 +1,30 @@
class Ector.Cairo.Surface (Ector.Generic.Surface)
{
eo_prefix: ector_cairo_surface;
legacy_prefix: null;
properties {
context {
set {
}
get {
}
values {
cairo_t *ctx;
}
}
}
methods {
symbol_get {
return: void * @warn_unused;
params {
@in const(char)* name;
}
}
}
implements {
Ector.Generic.Surface.renderer_factory_new;
Ector.Generic.Surface.reference_point.set;
Eo.Base.destructor;
Eo.Base.constructor;
}
}

View File

@ -0,0 +1,217 @@
#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 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;
static void (*cairo_new_path)(cairo_t *cr) = NULL;
static void (*cairo_rectangle)(cairo_t *cr, double x, double y, double width, double height) = NULL;
static void (*cairo_clip)(cairo_t *cr) = NULL;
static void (*cairo_device_to_user)(cairo_t *cr, double *x, double *y) = NULL;
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)
{
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;
}
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)
{
int 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 = ((pd->generic->color.r * R_VAL(&mul_col)) >> 8);
g = ((pd->generic->color.g * G_VAL(&mul_col)) >> 8);
b = ((pd->generic->color.b * B_VAL(&mul_col)) >> 8);
a = ((pd->generic->color.a * A_VAL(&mul_col)) >> 8);
ector_color_argb_unpremul(a, &r, &g, &b);
cairo_set_operator(pd->parent->cairo, cop);
cairo_transform(pd->parent->cairo, &identity);
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);
if (pd->m) cairo_transform(pd->parent->cairo, pd->m);
cairo_set_source_rgba(pd->parent->cairo, r/255.0, g/255.0, b/255.0, a/255.0);
USE(obj, cairo_new_path, EINA_FALSE);
USE(obj, cairo_rectangle, EINA_FALSE);
USE(obj, cairo_clip, EINA_FALSE);
USE(obj, cairo_device_to_user, EINA_FALSE);
if (clips)
{
int clip_count = eina_array_count(clips);
int i=0;
for (; i < clip_count ; i++)
{
Eina_Rectangle *clip = (Eina_Rectangle *)eina_array_data_get(clips, i);
double x = (double)clip->x;
double y = (double)clip->y;
cairo_new_path(pd->parent->cairo);
cairo_device_to_user(pd->parent->cairo, &x, &y);
cairo_rectangle(pd->parent->cairo, x, y, clip->w, clip->h);
}
cairo_clip(pd->parent->cairo);
}
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"

View File

@ -0,0 +1,18 @@
abstract Ector.Renderer.Cairo.Base (Ector.Renderer.Generic.Base)
{
legacy_prefix: null;
methods {
fill {
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;
}
}

View File

@ -0,0 +1,165 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include <cairo/Ector_Cairo.h>
#include "ector_private.h"
#include "ector_cairo_private.h"
static cairo_pattern_t *(*cairo_pattern_create_linear)(double x0, double y0,
double x1, double y1) = 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_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;
static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL;
typedef struct _Ector_Renderer_Cairo_Gradient_Linear_Data Ector_Renderer_Cairo_Gradient_Linear_Data;
struct _Ector_Renderer_Cairo_Gradient_Linear_Data
{
Ector_Cairo_Surface_Data *parent;
cairo_pattern_t *pat;
};
static Eina_Bool
_ector_renderer_cairo_gradient_linear_ector_renderer_generic_base_prepare(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd)
{
Ector_Renderer_Generic_Gradient_Linear_Data *gld;
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_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);
USE(obj, cairo_pattern_add_color_stop_rgba, EINA_FALSE);
pd->pat = cairo_pattern_create_linear(gld->start.x, gld->start.y,
gld->end.x, gld->end.y);
int r,g,b,a;
for (i = 0; i < gd->colors_count; i++)
{
r = gd->colors[i].r;
g = gd->colors[i].g;
b = gd->colors[i].b;
a = gd->colors[i].a;
ector_color_argb_unpremul(a, &r, &g, &b);
cairo_pattern_add_color_stop_rgba(pd->pat, gd->colors[i].offset, r/255.0, g/255.0, b/255.0, a/255.0);
}
USE(obj, cairo_pattern_set_extend, EINA_FALSE);
cairo_pattern_set_extend(pd->pat, _ector_cairo_extent_get(gd->s));
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);
}
return 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, unsigned int mul_col)
{
if (pd->pat) return EINA_FALSE;
Ector_Renderer_Generic_Gradient_Linear_Data *gld;
// FIXME: don't ignore clipping !
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, gld->start.y,
gld->end.x - gld->start.x,
gld->end.y - gld->start.y);
eo_do(obj, ector_renderer_cairo_base_fill());
cairo_fill(pd->parent->cairo);
return EINA_TRUE;
}
static Eina_Bool
_ector_renderer_cairo_gradient_linear_ector_renderer_cairo_base_fill(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd)
{
if (!pd->pat) return EINA_FALSE;
USE(obj, cairo_set_source, EINA_FALSE);
cairo_set_source(pd->parent->cairo, pd->pat);
return EINA_TRUE;
}
static void
_ector_renderer_cairo_gradient_linear_ector_renderer_generic_base_bounds_get(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd EINA_UNUSED,
Eina_Rectangle *r)
{
Ector_Renderer_Generic_Gradient_Linear_Data *gld;
Ector_Renderer_Cairo_Base_Data *bd;
gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN);
bd = eo_data_scope_get(obj, ECTOR_RENDERER_CAIRO_BASE_CLASS);
EINA_RECTANGLE_SET(r,
bd->generic->origin.x + gld->start.x,
bd->generic->origin.y + gld->start.y,
gld->end.x - gld->start.x,
gld->end.y - gld->start.x);
}
void
_ector_renderer_cairo_gradient_linear_eo_base_destructor(Eo *obj,
Ector_Renderer_Cairo_Gradient_Linear_Data *pd)
{
Eo *parent;
USE(obj, cairo_pattern_destroy, );
if (pd->pat) cairo_pattern_destroy(pd->pat);
pd->pat = NULL;
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->parent, obj);
eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS, eo_destructor());
}
void
_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, );
if (pd->pat) cairo_pattern_destroy(pd->pat);
pd->pat = NULL;
eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_LINEAR_CLASS,
efl_gfx_gradient_stop_set(colors, length));
}
#include "ector_renderer_cairo_gradient_linear.eo.c"

View File

@ -0,0 +1,13 @@
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;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Generic.Base.bounds_get;
Ector.Renderer.Cairo.Base.fill;
Eo.Base.destructor;
Efl.Gfx.Gradient.Base.stop.set;
}
}

View File

@ -0,0 +1,169 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include <cairo/Ector_Cairo.h>
#include "ector_private.h"
#include "ector_cairo_private.h"
static cairo_pattern_t *(*cairo_pattern_create_radial)(double cx0, double cy0,
double radius0,
double cx1, double cy1,
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_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;
static void (*cairo_pattern_set_extend)(cairo_pattern_t *pattern, cairo_extend_t extend) = NULL;
// FIXME: as long as it is not possible to directly access the parent structure
// this will be duplicated from the linear gradient renderer
typedef struct _Ector_Renderer_Cairo_Gradient_Radial_Data Ector_Renderer_Cairo_Gradient_Radial_Data;
struct _Ector_Renderer_Cairo_Gradient_Radial_Data
{
Ector_Cairo_Surface_Data *parent;
cairo_pattern_t *pat;
};
static Eina_Bool
_ector_renderer_cairo_gradient_radial_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Cairo_Gradient_Radial_Data *pd)
{
Ector_Renderer_Generic_Gradient_Radial_Data *grd;
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_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);
USE(obj, cairo_pattern_add_color_stop_rgba, EINA_FALSE);
pd->pat = cairo_pattern_create_radial(grd->focal.x, grd->focal.y, 0,
grd->radial.x, grd->radial.y, grd->radius);
int r,g,b,a;
for (i = 0; i < gd->colors_count; i++)
{
r = gd->colors[i].r;
g = gd->colors[i].g;
b = gd->colors[i].b;
a = gd->colors[i].a;
ector_color_argb_unpremul(a, &r, &g, &b);
cairo_pattern_add_color_stop_rgba(pd->pat, gd->colors[i].offset, r/255.0, g/255.0, b/255.0, a/255.0);
}
USE(obj, cairo_pattern_set_extend, EINA_FALSE);
cairo_pattern_set_extend(pd->pat, _ector_cairo_extent_get(gd->s));
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);
}
return 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, unsigned int mul_col)
{
if (pd->pat) return EINA_FALSE;
Ector_Renderer_Generic_Gradient_Radial_Data *gld;
// FIXME: don't ignore clipping !
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_arc, EINA_FALSE);
USE(obj, cairo_fill, EINA_FALSE);
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);
return EINA_TRUE;
}
// Clearly duplicated and should be in a common place...
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) return EINA_FALSE;
USE(obj, cairo_set_source, EINA_FALSE);
cairo_set_source(pd->parent->cairo, pd->pat);
return EINA_TRUE;
}
static void
_ector_renderer_cairo_gradient_radial_ector_renderer_generic_base_bounds_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Cairo_Gradient_Radial_Data *pd EINA_UNUSED,
Eina_Rectangle *r)
{
Ector_Renderer_Generic_Gradient_Radial_Data *gld;
Ector_Renderer_Cairo_Base_Data *bd;
gld = eo_data_scope_get(obj, ECTOR_RENDERER_GENERIC_GRADIENT_RADIAL_MIXIN);
bd = eo_data_scope_get(obj, ECTOR_RENDERER_CAIRO_BASE_CLASS);
EINA_RECTANGLE_SET(r,
bd->generic->origin.x + gld->radial.x - gld->radius,
bd->generic->origin.y + gld->radial.y - gld->radius,
gld->radius * 2, gld->radius * 2);
}
void
_ector_renderer_cairo_gradient_radial_eo_base_destructor(Eo *obj,
Ector_Renderer_Cairo_Gradient_Radial_Data *pd)
{
Eo *parent;
USE(obj, cairo_pattern_destroy, );
if (pd->pat) cairo_pattern_destroy(pd->pat);
pd->pat = NULL;
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->parent, obj);
eo_do_super(obj, ECTOR_RENDERER_CAIRO_GRADIENT_RADIAL_CLASS, eo_destructor());
}
void
_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_RADIAL_CLASS,
efl_gfx_gradient_stop_set(colors, length));
}
#include "ector_renderer_cairo_gradient_radial.eo.c"

View File

@ -0,0 +1,13 @@
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;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Generic.Base.bounds_get;
Ector.Renderer.Cairo.Base.fill;
Eo.Base.destructor;
Efl.Gfx.Gradient.Base.stop.set;
}
}

View File

@ -0,0 +1,277 @@
#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 _cairo_path_t cairo_path_t;
typedef enum _cairo_line_cap {
CAIRO_LINE_CAP_BUTT,
CAIRO_LINE_CAP_ROUND,
CAIRO_LINE_CAP_SQUARE
} cairo_line_cap_t;
typedef enum _cairo_line_join {
CAIRO_LINE_JOIN_MITER,
CAIRO_LINE_JOIN_ROUND,
CAIRO_LINE_JOIN_BEVEL
} cairo_line_join_t;
static void (*cairo_move_to)(cairo_t *cr, double x, double y) = NULL;
static void (*cairo_line_to)(cairo_t *cr, double x, double y) = NULL;
static void (*cairo_curve_to)(cairo_t *cr,
double x1, double y1,
double x2, double y2,
double x3, double y3) = NULL;
static void (*cairo_close_path)(cairo_t *cr) = NULL;
static void (*cairo_fill)(cairo_t *cr) = NULL;
static void (*cairo_fill_preserve)(cairo_t *cr) = NULL;
static void (*cairo_stroke)(cairo_t *cr) = NULL;
static void (*cairo_set_source_rgba)(cairo_t *cr,
double red, double green,
double blue, double alpha) = NULL;
static cairo_path_t *(*cairo_copy_path)(cairo_t *cr) = NULL;
static void (*cairo_path_destroy)(cairo_path_t *path) = NULL;
static void (*cairo_new_path)(cairo_t *cr) = NULL;
static void (*cairo_append_path)(cairo_t *cr, const cairo_path_t *path) = NULL;
static void (*cairo_set_line_width)(cairo_t *cr, double width) = NULL;
static void (*cairo_set_line_cap)(cairo_t *cr, cairo_line_cap_t line_cap) = NULL;
static void (*cairo_set_line_join)(cairo_t *cr, cairo_line_join_t line_join) = NULL;
static void (*cairo_save)(cairo_t *cr) = NULL;
static void (*cairo_restore)(cairo_t *cr) = NULL;
typedef struct _Ector_Renderer_Cairo_Shape_Data Ector_Renderer_Cairo_Shape_Data;
struct _Ector_Renderer_Cairo_Shape_Data
{
Ector_Cairo_Surface_Data *parent;
Ector_Renderer_Generic_Shape_Data *shape;
Ector_Renderer_Generic_Base_Data *base;
cairo_path_t *path;
};
static Eina_Bool
_ector_renderer_cairo_shape_path_changed(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
{
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)
{
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());
// shouldn't that be moved to the cairo base object
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->parent) return EINA_FALSE;
}
eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
if (!pd->path && cmds)
{
USE(obj, cairo_new_path, EINA_FALSE);
cairo_new_path(pd->parent->cairo);
for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
{
switch (*cmds)
{
case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
USE(obj, cairo_move_to, EINA_FALSE);
cairo_move_to(pd->parent->cairo, pts[0], pts[1]);
pts += 2;
break;
case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO:
USE(obj, cairo_line_to, EINA_FALSE);
cairo_line_to(pd->parent->cairo, pts[0], pts[1]);
pts += 2;
break;
case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO:
USE(obj, cairo_curve_to, EINA_FALSE);
// Be careful, we do have a different order than
// cairo, first is destination point, followed by
// the control point. The opposite of cairo.
cairo_curve_to(pd->parent->cairo,
pts[2], pts[3], pts[4], pts[5], // control points
pts[0], pts[1]); // destination point
pts += 6;
break;
case EFL_GFX_PATH_COMMAND_TYPE_CLOSE:
USE(obj, cairo_close_path, EINA_FALSE);
cairo_close_path(pd->parent->cairo);
break;
case EFL_GFX_PATH_COMMAND_TYPE_LAST:
case EFL_GFX_PATH_COMMAND_TYPE_END:
break;
}
}
USE(obj, cairo_copy_path, EINA_FALSE);
pd->path = cairo_copy_path(pd->parent->cairo);
}
return EINA_TRUE;
}
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, unsigned int mul_col)
{
int r, g, b, a;
if (pd->path == NULL) return EINA_FALSE;
USE(obj, cairo_save, EINA_FALSE);
cairo_save(pd->parent->cairo);
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);
cairo_new_path(pd->parent->cairo);
cairo_append_path(pd->parent->cairo, pd->path);
if (pd->shape->fill)
eo_do(pd->shape->fill, ector_renderer_cairo_base_fill());
if (pd->shape->stroke.fill || pd->shape->stroke.color.a > 0)
{
USE(obj, cairo_fill_preserve, EINA_FALSE);
USE(obj, cairo_set_source_rgba, EINA_FALSE);
USE(obj, cairo_stroke, EINA_FALSE);
USE(obj, cairo_set_line_width, EINA_FALSE);
USE(obj, cairo_set_line_cap, EINA_FALSE);
USE(obj, cairo_set_line_join, EINA_FALSE);
cairo_fill_preserve(pd->parent->cairo);
if (pd->shape->stroke.fill)
eo_do(pd->shape->stroke.fill, ector_renderer_cairo_base_fill());
else
{
r = (((pd->shape->stroke.color.r * R_VAL(&mul_col)) + 0xff) >> 8);
g = (((pd->shape->stroke.color.g * G_VAL(&mul_col)) + 0xff) >> 8);
b = (((pd->shape->stroke.color.b * B_VAL(&mul_col)) + 0xff) >> 8);
a = (((pd->shape->stroke.color.a * A_VAL(&mul_col)) + 0xff) >> 8);
ector_color_argb_unpremul(a, &r, &g, &b);
cairo_set_source_rgba(pd->parent->cairo, r/255.0, g/255.0, b/255.0, a/255.0);
}
// Set dash, cap and join
cairo_set_line_width(pd->parent->cairo, (pd->shape->stroke.width * pd->shape->stroke.scale * 2));
cairo_set_line_cap(pd->parent->cairo, pd->shape->stroke.cap);
cairo_set_line_join(pd->parent->cairo, pd->shape->stroke.join);
cairo_stroke(pd->parent->cairo);
}
else
{
USE(obj, cairo_fill, EINA_FALSE);
cairo_fill(pd->parent->cairo);
}
USE(obj, cairo_restore, EINA_FALSE);
cairo_restore(pd->parent->cairo);
return EINA_TRUE;
}
static Eina_Bool
_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_ector_renderer_generic_base_bounds_get(Eo *obj,
Ector_Renderer_Cairo_Shape_Data *pd EINA_UNUSED,
Eina_Rectangle *r)
{
Ector_Renderer_Cairo_Base_Data *bd;
// FIXME: It should be possible to actually ask cairo about that
eo_do(obj, efl_gfx_shape_bounds_get(r));
bd = eo_data_scope_get(obj, ECTOR_RENDERER_CAIRO_BASE_CLASS);
r->x += bd->generic->origin.x;
r->y += bd->generic->origin.y;
}
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_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
_ector_renderer_cairo_shape_eo_base_destructor(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
{
Eo *parent;
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);
}
#include "ector_renderer_cairo_shape.eo.c"

View File

@ -0,0 +1,13 @@
class Ector.Renderer.Cairo.Shape (Ector.Renderer.Cairo.Base, Ector.Renderer.Generic.Shape)
{
eo_prefix: ector_renderer_cairo_shape;
legacy_prefix: null;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Generic.Base.bounds_get;
Ector.Renderer.Cairo.Base.fill;
Eo.Base.constructor;
Eo.Base.destructor;
}
}

View File

@ -0,0 +1,39 @@
abstract Ector.Generic.Surface (Eo.Base)
{
eo_prefix: ector_surface;
properties {
size {
set {
/*@ Changes the size of the given Evas object. */
}
get {
/*@ Retrieves the (rectangular) size of the given Evas object. */
}
values {
int w; /*@ in */
int h; /*@ in */
}
}
reference_point {
set {
/*@ This define where is (0,0) in pixels coordinate inside the surface */
}
values {
int x;
int y;
}
}
}
methods {
renderer_factory_new {
return: Ector_Renderer *;
params {
@in const(Eo_Class) * type @nonull;
}
}
}
implements {
@virtual .renderer_factory_new;
@virtual .reference_point.set;
}
}

View File

@ -0,0 +1,81 @@
/* ECTOR - EFL retained mode drawing library
* Copyright (C) 2014 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Ector.h>
#include "ector_private.h"
int _ector_log_dom_global = 0;
static int _ector_main_count = 0;
EAPI int
ector_init(void)
{
if (EINA_LIKELY(_ector_main_count > 0))
return ++_ector_main_count;
eina_init();
eo_init();
_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_global, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
return _ector_main_count;
on_error:
eo_shutdown();
eina_shutdown();
return 0;
}
EAPI int
ector_shutdown(void)
{
if (_ector_main_count <= 0)
{
EINA_LOG_ERR("Init count not greater than 0 in shutdown of ector.");
return 0;
}
_ector_main_count--;
if (EINA_LIKELY(_ector_main_count > 0))
return _ector_main_count;
eina_log_timing(_ector_log_dom_global,
EINA_LOG_STATE_START,
EINA_LOG_STATE_SHUTDOWN);
eo_shutdown();
eina_log_domain_unregister(_ector_log_dom_global);
eina_shutdown();
return _ector_main_count;
}

View File

@ -0,0 +1,148 @@
#ifndef ECTOR_PRIVATE_H_
#define ECTOR_PRIVATE_H_
/*
* variable and macros used for the eina_log module
*/
extern int _ector_log_dom_global;
/*
* Macros that are used everywhere
*
* the first four macros are the general macros for the lib
*/
#ifdef ECTOR_DEFAULT_LOG_COLOR
# undef ECTOR_DEFAULT_LOG_COLOR
#endif /* ifdef ECTOR_DEFAULT_LOG_COLOR */
#define ECTOR_DEFAULT_LOG_COLOR EINA_COLOR_CYAN
#ifdef ERR
# undef ERR
#endif /* ifdef ERR */
#define ERR(...) EINA_LOG_DOM_ERR(_ector_log_dom_global, __VA_ARGS__)
#ifdef DBG
# undef DBG
#endif /* ifdef DBG */
#define DBG(...) EINA_LOG_DOM_DBG(_ector_log_dom_global, __VA_ARGS__)
#ifdef INF
# undef INF
#endif /* ifdef INF */
#define INF(...) EINA_LOG_DOM_INFO(_ector_log_dom_global, __VA_ARGS__)
#ifdef WRN
# undef WRN
#endif /* ifdef WRN */
#define WRN(...) EINA_LOG_DOM_WARN(_ector_log_dom_global, __VA_ARGS__)
#ifdef CRI
# undef CRI
#endif /* ifdef CRI */
#define CRI(...) EINA_LOG_DOM_CRIT(_ector_log_dom_global, __VA_ARGS__)
/* The following macro are internal to Ector only at this stage */
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_renderer_replace(Ector_Renderer **d, const Ector_Renderer *s)
{
Ector_Renderer *tmp = *d;
*d = eo_ref(s);
eo_unref(tmp);
}
typedef struct _Ector_Renderer_Generic_Base_Data Ector_Renderer_Generic_Base_Data;
typedef struct _Ector_Renderer_Generic_Gradient_Data Ector_Renderer_Generic_Gradient_Data;
typedef struct _Ector_Renderer_Generic_Gradient_Linear_Data Ector_Renderer_Generic_Gradient_Linear_Data;
typedef struct _Ector_Renderer_Generic_Gradient_Radial_Data Ector_Renderer_Generic_Gradient_Radial_Data;
typedef struct _Ector_Renderer_Generic_Shape_Data Ector_Renderer_Generic_Shape_Data;
struct _Ector_Renderer_Generic_Base_Data
{
Eina_Matrix3 *m;
struct {
double x;
double y;
} origin;
struct {
int r, g, b, a;
} color;
Ector_Renderer *mask;
Ector_Quality q;
Eina_Bool visibility;
};
struct _Ector_Renderer_Generic_Gradient_Data
{
Efl_Gfx_Gradient_Stop *colors;
unsigned int colors_count;
Efl_Gfx_Gradient_Spread s;
};
struct _Ector_Renderer_Generic_Gradient_Linear_Data
{
struct {
double x, y;
} start, end;
};
struct _Ector_Renderer_Generic_Gradient_Radial_Data
{
struct {
double x, y;
} radial, focal;
double radius;
};
struct _Ector_Renderer_Generic_Shape_Data
{
Ector_Renderer *fill;
struct {
Ector_Renderer *fill;
Ector_Renderer *marker;
double scale;
double width;
double centered;
struct {
int r, g, b, a;
} color;
Efl_Gfx_Dash *dash;
unsigned int dash_length;
Efl_Gfx_Cap cap;
Efl_Gfx_Cap join;
} stroke;
};
#endif

View File

@ -0,0 +1,10 @@
#ifndef ECTOR_RENDERER_H
#define ECTOR_RENDERER_H
#include "ector_renderer_generic_base.eo.h"
#include "ector_renderer_generic_shape.eo.h"
#include "ector_renderer_generic_gradient.eo.h"
#include "ector_renderer_generic_gradient_linear.eo.h"
#include "ector_renderer_generic_gradient_radial.eo.h"
#endif

View File

@ -0,0 +1,138 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
static void
_ector_renderer_generic_base_eo_base_destructor(Eo *obj, Ector_Renderer_Generic_Base_Data *pd)
{
if (pd->m) free(pd->m);
eo_do_super(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, eo_destructor());
}
static void
_ector_renderer_generic_base_transformation_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
const Eina_Matrix3 *m)
{
if (!m)
{
free(pd->m);
pd->m = NULL;
}
else
{
if (!pd->m) pd->m = malloc(sizeof (Eina_Matrix3));
if (!pd->m) return ;
memcpy(pd->m, m, sizeof (Eina_Matrix3));
}
}
static const Eina_Matrix3 *
_ector_renderer_generic_base_transformation_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd)
{
return pd->m;
}
static void
_ector_renderer_generic_base_origin_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
double x, double y)
{
pd->origin.x = x;
pd->origin.y = y;
}
static void
_ector_renderer_generic_base_origin_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
double *x, double *y)
{
if (x) *x = pd->origin.x;
if (y) *y = pd->origin.y;
}
static void
_ector_renderer_generic_base_visibility_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
Eina_Bool v)
{
pd->visibility = v;
}
static Eina_Bool
_ector_renderer_generic_base_visibility_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd)
{
return pd->visibility;
}
static void
_ector_renderer_generic_base_color_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
int r, int g, int b, int a)
{
pd->color.r = r;
pd->color.g = g;
pd->color.b = b;
pd->color.a = a;
}
static void
_ector_renderer_generic_base_color_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
int *r, int *g, int *b, int *a)
{
if (r) *r = pd->color.r;
if (g) *g = pd->color.g;
if (b) *b = pd->color.b;
if (a) *a = pd->color.a;
}
static void
_ector_renderer_generic_base_mask_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
Ector_Renderer *r)
{
_ector_renderer_replace(&pd->mask, r);
}
static Ector_Renderer *
_ector_renderer_generic_base_mask_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd)
{
return pd->mask;
}
static void
_ector_renderer_generic_base_quality_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd,
Ector_Quality q)
{
pd->q = q;
}
static Ector_Quality
_ector_renderer_generic_base_quality_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Base_Data *pd)
{
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"

View File

@ -0,0 +1,116 @@
abstract Ector.Renderer.Generic.Base (Eo.Base)
{
eo_prefix: ector_renderer;
legacy_prefix: null;
properties {
transformation {
set {
}
get {
}
values {
const(Eina_Matrix3) *m;
}
}
origin {
set {
}
get {
}
values {
double x;
double y;
}
}
visibility {
set {
/*@ Makes the given Ector renderer visible or invisible. */
}
get {
/*@ Retrieves whether or not the given Ector renderer is visible. */
}
values {
bool v; /*@ @c EINA_TRUE if to make the object visible, @c EINA_FALSE otherwise */
}
}
color {
set {
/*@
Sets the general/main color of the given Ector renderer to the given
one.
@note These color values are expected to be premultiplied by @p a.
@ingroup Ector_Renderer_Group_Basic */
}
get {
/*@
Retrieves the general/main color of the given Ector renderer.
Retrieves the “main” 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.
@note Use @c NULL pointers on the components you're not interested
in: they'll be ignored by the function.
@ingroup Ector_Renderer_Group_Basic */
}
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. */
}
}
mask {
set {
}
get {
}
values {
Ector_Renderer *r;
}
}
quality {
set {
}
get {
}
values {
Ector_Quality q;
}
}
}
methods {
bounds_get {
params {
@out Eina_Rectangle r;
}
}
draw {
return: bool @warn_unused;
params {
@in Ector_Rop op;
@in array<Eina_Rectangle *> *clips; /*@ array of Eina_Rectangle clip */
@in uint mul_col;
}
}
prepare {
return: bool @warn_unused;
params {
}
}
done {
return: bool @warn_unused;
}
}
implements {
Eo.Base.destructor;
@virtual .draw;
@virtual .bounds_get;
@virtual .done;
}
}

View File

@ -0,0 +1,11 @@
mixin Ector.Renderer.Generic.Gradient (Efl.Gfx.Gradient.Base)
{
eo_prefix: ector_renderer_gradient;
legacy_prefix: null;
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;
}
}

View File

@ -0,0 +1,11 @@
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;
}
}

View File

@ -0,0 +1,13 @@
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;
}
}

View File

@ -0,0 +1,43 @@
mixin Ector.Renderer.Generic.Shape (Efl.Gfx.Shape)
{
eo_prefix: ector_renderer_shape;
legacy_prefix: null;
properties {
fill {
set {
}
get {
}
values {
const(Ector_Renderer) *r;
}
}
stroke_fill {
set {
}
get {
}
values {
const(Ector_Renderer) *r;
}
}
stroke_marker {
set {
}
get {
}
values {
const(Ector_Renderer) *r;
}
}
}
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;
}
}

View File

@ -0,0 +1,53 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
static void
_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)
{
pd->colors_count = 0;
return ;
}
memcpy(pd->colors, colors, length * sizeof(Efl_Gfx_Gradient_Stop));
pd->colors_count = length;
}
static void
_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_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_base_spread_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Data *pd)
{
return pd->s;
}
#include "ector_renderer_generic_gradient.eo.c"

View File

@ -0,0 +1,46 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
static void
_ector_renderer_generic_gradient_linear_efl_gfx_gradient_linear_start_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Linear_Data *pd,
double x, double y)
{
pd->start.x = x;
pd->start.y = y;
}
static void
_ector_renderer_generic_gradient_linear_efl_gfx_gradient_linear_start_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Linear_Data *pd,
double *x, double *y)
{
if (x) *x = pd->start.x;
if (y) *y = pd->start.y;
}
static void
_ector_renderer_generic_gradient_linear_efl_gfx_gradient_linear_end_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Linear_Data *pd,
double x, double y)
{
pd->end.x = x;
pd->end.y = y;
}
static void
_ector_renderer_generic_gradient_linear_efl_gfx_gradient_linear_end_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Linear_Data *pd,
double *x, double *y)
{
if (x) *x = pd->end.x;
if (y) *y = pd->end.y;
}
#include "ector_renderer_generic_gradient_linear.eo.c"

View File

@ -0,0 +1,62 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
static void
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_center_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd,
double x, double y)
{
pd->radial.x = x;
pd->radial.y = y;
}
static void
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_center_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd,
double *x, double *y)
{
if (x) *x = pd->radial.x;
if (y) *y = pd->radial.y;
}
static void
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_radius_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd,
double r)
{
pd->radius = r;
}
static double
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_radius_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd)
{
return pd->radius;
}
static void
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_focal_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd,
double x, double y)
{
pd->focal.x = x;
pd->focal.y = y;
}
static void
_ector_renderer_generic_gradient_radial_efl_gfx_gradient_radial_focal_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Gradient_Radial_Data *pd,
double *x, double *y)
{
if (x) *x = pd->focal.x;
if (y) *y = pd->focal.y;
}
#include "ector_renderer_generic_gradient_radial.eo.c"

View File

@ -0,0 +1,186 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
static void
_ector_renderer_generic_shape_fill_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
const Ector_Renderer *r)
{
_ector_renderer_replace(&pd->fill, r);
}
static const Ector_Renderer *
_ector_renderer_generic_shape_fill_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->fill;
}
static void
_ector_renderer_generic_shape_stroke_fill_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
const Ector_Renderer *r)
{
_ector_renderer_replace(&pd->stroke.fill, r);
}
static const Ector_Renderer *
_ector_renderer_generic_shape_stroke_fill_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.fill;
}
static void
_ector_renderer_generic_shape_stroke_marker_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
const Ector_Renderer *r)
{
_ector_renderer_replace(&pd->stroke.marker, r);
}
static const Ector_Renderer *
_ector_renderer_generic_shape_stroke_marker_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.marker;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_scale_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
double s)
{
pd->stroke.scale = s;
}
static double
_ector_renderer_generic_shape_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.scale;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_color_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
int r, int g, int b, int a)
{
pd->stroke.color.r = r;
pd->stroke.color.g = g;
pd->stroke.color.b = b;
pd->stroke.color.a = a;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
int *r, int *g, int *b, int *a)
{
if (r) *r = pd->stroke.color.r;
if (g) *g = pd->stroke.color.g;
if (b) *b = pd->stroke.color.b;
if (a) *a = pd->stroke.color.a;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_width_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
double w)
{
pd->stroke.width = w;
}
static double
_ector_renderer_generic_shape_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.width;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_location_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
double centered)
{
pd->stroke.centered = centered;
}
static double
_ector_renderer_generic_shape_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.centered;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_dash_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
const Efl_Gfx_Dash *dash,
unsigned int length)
{
Efl_Gfx_Dash *tmp;
if (!dash)
{
free(pd->stroke.dash);
pd->stroke.dash = NULL;
pd->stroke.dash_length = 0;
return ;
}
tmp = realloc(pd->stroke.dash, length * sizeof (Efl_Gfx_Dash));
if (!tmp && length) return ;
memcpy(tmp, dash, length * sizeof (Efl_Gfx_Dash));
pd->stroke.dash = tmp;
pd->stroke.dash_length = length;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
const Efl_Gfx_Dash **dash,
unsigned int *length)
{
if (dash) *dash = pd->stroke.dash;
if (length) *length = pd->stroke.dash_length;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
Efl_Gfx_Cap c)
{
pd->stroke.cap = c;
}
static Efl_Gfx_Cap
_ector_renderer_generic_shape_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.cap;
}
static void
_ector_renderer_generic_shape_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd,
Efl_Gfx_Join j)
{
pd->stroke.join = j;
}
static Efl_Gfx_Join
_ector_renderer_generic_shape_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
Ector_Renderer_Generic_Shape_Data *pd)
{
return pd->stroke.join;
}
#include "ector_renderer_generic_shape.eo.c"

View File

@ -0,0 +1,34 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Ector.h>
#include "ector_private.h"
typedef struct _Ector_Generic_Surface_Data Ector_Generic_Surface_Data;
struct _Ector_Generic_Surface_Data
{
int w, h;
};
void
_ector_generic_surface_size_set(Eo *obj EINA_UNUSED,
Ector_Generic_Surface_Data *pd,
int w, int h)
{
pd->w = w;
pd->h = h;
}
void
_ector_generic_surface_size_get(Eo *obj EINA_UNUSED,
Ector_Generic_Surface_Data *pd,
int *w, int *h)
{
if (w) *w = pd->w;
if (h) *h = pd->h;
}
#include "ector_generic_surface.eo.c"

View File

@ -0,0 +1,6 @@
#ifndef ECTOR_SURFACE_H
#define ECTOR_SURFACE_H
#include "ector_generic_surface.eo.h"
#endif

View File

@ -0,0 +1,32 @@
#ifndef ECTOR_UTIL_H
# define ECTOR_UTIL_H
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 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

View File

@ -0,0 +1,15 @@
#ifndef ECTOR_SOFTWARE_H_
#define ECTOR_SOFTWARE_H_
#include <Ector.h>
typedef Eo Ector_Software_Surface;
typedef struct _Software_Rasterizer Software_Rasterizer;
#include "software/ector_software_surface.eo.h"
#include "software/ector_renderer_software_base.eo.h"
#include "software/ector_renderer_software_shape.eo.h"
#include "software/ector_renderer_software_gradient_linear.eo.h"
#include "software/ector_renderer_software_gradient_radial.eo.h"
#endif

View File

@ -0,0 +1,105 @@
#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
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

View File

@ -0,0 +1,12 @@
class Ector.Renderer.Software.Base (Ector.Renderer.Generic.Base)
{
legacy_prefix: null;
methods {
fill {
return: bool;
}
}
implements {
@virtual .fill;
}
}

View File

@ -0,0 +1,109 @@
#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"
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)
{
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)
{
if (!pd->surface)
{
Eo *parent;
eo_do(obj, parent = eo_parent_get());
if (!parent) return EINA_FALSE;
pd->surface = eo_data_xref(parent, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
}
_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,
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_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)
{
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, eo_constructor());
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)
{
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_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);
}
#include "ector_renderer_software_gradient_linear.eo.c"

View File

@ -0,0 +1,14 @@
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;
data: Ector_Renderer_Software_Gradient_Data;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Software.Base.fill;
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Gfx.Gradient.Base.stop.set;
}
}

View File

@ -0,0 +1,117 @@
#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"
static void
_update_radial_data(Ector_Renderer_Software_Gradient_Data *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;
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;
gdata->radial.fradius = 0;
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.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;
}
static Eina_Bool
_ector_renderer_software_gradient_radial_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd)
{
if (!pd->surface)
{
Eo *parent;
eo_do(obj, parent = eo_parent_get());
if (!parent) return EINA_FALSE;
pd->surface = eo_data_xref(parent, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
}
_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,
unsigned int mul_col EINA_UNUSED)
{
return EINA_TRUE;
}
// Clearly duplicated and should be in a common place...
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);
return EINA_TRUE;
}
void
_ector_renderer_software_gradient_radial_eo_base_constructor(Eo *obj,
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_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)
{
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_RADIAL_CLASS, eo_destructor());
}
void
_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));
destroy_color_table(pd);
}
#include "ector_renderer_software_gradient_radial.eo.c"

View File

@ -0,0 +1,14 @@
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;
data: Ector_Renderer_Software_Gradient_Data;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Software.Base.fill;
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Gfx.Gradient.Base.stop.set;
}
}

View File

@ -0,0 +1,392 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <float.h>
#include <Eina.h>
#include <Ector.h>
#include <software/Ector_Software.h>
#include "ector_private.h"
#include "ector_software_private.h"
typedef struct _Ector_Renderer_Software_Shape_Data Ector_Renderer_Software_Shape_Data;
struct _Ector_Renderer_Software_Shape_Data
{
Ector_Software_Surface_Data *surface;
Ector_Renderer_Generic_Shape_Data *shape;
Ector_Renderer_Generic_Base_Data *base;
Shape_Rle_Data *shape_data;
Shape_Rle_Data *outline_data;
};
typedef struct _Outline
{
SW_FT_Outline ft_outline;
int points_alloc;
int contours_alloc;
}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->ft_outline.contours = (short *) calloc(5, sizeof(short));
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;
}
}
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++;
}
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++;
}
}
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++;
}
static Eina_Bool
_outline_close_path(Outline *outline)
{
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;
}
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++;
}
static void _outline_transform(Outline *outline, Eina_Matrix3 *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;
}
}
}
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->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());
// shouldn't that be moved to the software base object
if (!pd->surface)
{
Eo *parent;
eo_do(obj, parent = eo_parent_get());
if (!parent) return EINA_FALSE;
pd->surface = eo_data_xref(parent, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
if (!pd->surface) return EINA_FALSE;
}
eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
if (!pd->shape_data && cmds)
{
Eina_Bool close_path = EINA_FALSE;
Outline * outline = _outline_create();
for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
{
switch (*cmds)
{
case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
_outline_move_to(outline, pts[0], pts[1]);
pts += 2;
break;
case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO:
_outline_line_to(outline, pts[0], pts[1]);
pts += 2;
break;
case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO:
// Be careful, we do have a different order than
// 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 += 6;
break;
case EFL_GFX_PATH_COMMAND_TYPE_CLOSE:
close_path = _outline_close_path(outline);
break;
case EFL_GFX_PATH_COMMAND_TYPE_LAST:
case EFL_GFX_PATH_COMMAND_TYPE_END:
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)
{
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);
}
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, unsigned int mul_col)
{
int x, y;
// adjust the offset
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);
}
}
return EINA_TRUE;
}
static Eina_Bool
_ector_renderer_software_shape_ector_renderer_software_base_fill(Eo *obj EINA_UNUSED, Ector_Renderer_Software_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 software.
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);
pd->shape_data = NULL;
pd->outline_data = NULL;
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, efl_gfx_shape_path_set(op, points));
}
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_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
_ector_renderer_software_shape_eo_base_destructor(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
{
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);
eo_do(obj, parent = eo_parent_get());
eo_data_xunref(parent, pd->surface, obj);
eo_data_xunref(obj, pd->shape, obj);
eo_data_xunref(obj, pd->base, obj);
eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, eo_destructor());
}
#include "ector_renderer_software_shape.eo.c"

View File

@ -0,0 +1,13 @@
class Ector.Renderer.Software.Shape (Ector.Renderer.Software.Base, Ector.Renderer.Generic.Shape)
{
eo_prefix: ector_renderer_software_shape;
legacy_prefix: null;
implements {
Ector.Renderer.Generic.Base.prepare;
Ector.Renderer.Generic.Base.draw;
Ector.Renderer.Software.Base.fill;
Efl.Gfx.Shape.path.set;
Eo.Base.constructor;
Eo.Base.destructor;
}
}

View File

@ -0,0 +1,266 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
//Remove
#include <assert.h>
#include <math.h>
#include <float.h>
#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"
#define GRADIENT_STOPTABLE_SIZE 1024
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
static inline int
_gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos)
{
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)
{
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 >= GRADIENT_STOPTABLE_SIZE)
ipos = GRADIENT_STOPTABLE_SIZE-1;
}
return ipos;
}
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->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->color_table[_gradient_clamp(data, ipos)];
}
typedef double (*BLEND_FUNC)(double progress);
static double
_ease_linear(double t)
{
return t;
}
static void
_generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_count, uint *color_table, int size)
{
int pos = 0;
Efl_Gfx_Gradient_Stop *curr, *next;
assert(stop_count > 0);
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;
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)
{
curr = (gradient_stops + i);
next = (gradient_stops + i + 1);
double delta = 1/(next->offset - curr->offset);
uint next_color = ECTOR_ARGB_JOIN(next->a, next->r, next->g, next->b);
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;
color_table[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
++pos;
fpos += incr;
}
current_color = next_color;
}
for (;pos < size; ++pos)
color_table[pos] = current_color;
// Make sure the last color stop is represented at the end of the table
color_table[size-1] = current_color;
}
void
update_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
{
if(gdata->color_table) return;
gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
_generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count, gdata->color_table, GRADIENT_STOPTABLE_SIZE);
}
void
destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
{
if (gdata->color_table)
{
free(gdata->color_table);
gdata->color_table = NULL;
}
}
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)
{
t = inc = 0;
}
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;
inc = g_data->linear.dx * data->inv.xx + g_data->linear.dx * data->inv.yx;
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;
}
}
}
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
_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)
{
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);
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);
rx -= g_data->radial.fx;
ry -= g_data->radial.fy;
float inv_a = 1 / (float)(2 * g_data->radial.a);
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;
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;
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;
// #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);
}
}

View File

@ -0,0 +1,152 @@
#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
#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_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* color_table;
} Ector_Renderer_Software_Gradient_Data;
// Rasterizer related structure
typedef struct _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;
typedef struct _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;
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;
typedef struct _Software_Rasterizer
{
SW_FT_Raster raster;
SW_FT_Stroker stroker;
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);
void ector_software_rasterizer_stroke_set(Software_Rasterizer *rasterizer, double width,
Efl_Gfx_Cap cap_style, Efl_Gfx_Join join_style);
void ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Eina_Matrix3 *t);
void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a);
void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear);
void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial);
void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips);
void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip);
Shape_Rle_Data * ector_software_rasterizer_generate_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline);
Shape_Rle_Data * ector_software_rasterizer_generate_stroke_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath);
void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, int x, int y, uint mul_col, Ector_Rop op, Shape_Rle_Data* rle);
void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
// Gradient Api
void update_color_table(Ector_Renderer_Software_Gradient_Data *gdata);
void destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata);
void fetch_linear_gradient(uint *buffer, Span_Data *data, int y, int x, int length);
void fetch_radial_gradient(uint *buffer, Span_Data *data, int y, int x, int length);
#endif

View File

@ -0,0 +1,516 @@
#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 *user_data)
{
Span_Data *data = (Span_Data *)(user_data);
// multiply the color with mul_col if any
uint color = ECTOR_MUL4_SYM(data->color, data->mul_col);
Eina_Bool solid_source = ((color >> 24) == 255);
// move to the offset location
uint *buffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx);
if (solid_source)
{
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;
}
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);
++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 *user_data)
{
Span_Data *data = (Span_Data *)(user_data);
src_fetch fetchfunc = NULL;
if(data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
if(data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
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);
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;
}
}
/*!
\internal
spans must be sorted on y
*/
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 **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 = *out_spans;
const SW_FT_Span *clipSpans = clip->spans + *currentClip;
const SW_FT_Span *clipEnd = clip->spans + clip->size;
while (available && spans < end ) {
if (clipSpans >= clipEnd) {
spans = end;
break;
}
if (clipSpans->y > spans->y) {
++spans;
continue;
}
if (spans->y != clipSpans->y) {
++clipSpans;
continue;
}
//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 = _div_255(spans->coverage * clipSpans->coverage);
++out;
--available;
}
if (sx2 < cx2) {
++spans;
} else {
++clipSpans;
}
}
*out_spans = out;
*currentClip = clipSpans - clip->spans;
return spans;
}
static void
_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 *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 ++)
{
Eina_Rectangle *rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i);
Eina_Rectangle tmpRect;
// invert transform the offset
tmpRect.x = rect->x - fill_data->offx;
tmpRect.y = rect->y - fill_data->offy;
tmpRect.w = rect->w;
tmpRect.h = rect->h;
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, &current_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)
{
spdata->blend = 0;
}
else if (!spdata->clip.enabled)
{
spdata->blend = spdata->unclipped_blend;
}
else if (spdata->clip.has_rect_clip)
{
spdata->blend = &_span_fill_clipRect;
}
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->fill_data.raster_buffer.buffer = NULL;
rasterizer->fill_data.clip.enabled = EINA_FALSE;
rasterizer->fill_data.unclipped_blend = 0;
rasterizer->fill_data.blend = 0;
}
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
}
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);
}
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)
{
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));
// 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;
sw_ft_grays_raster.raster_render(rasterizer->raster, &params);
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);
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_Export(rasterizer->stroker, &strokeOutline);
Shape_Rle_Data *rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline);
// 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->spans)
free(rle->spans);
free(rle);
}
}
static
void _setup_span_fill_matrix(Software_Rasterizer *rasterizer)
{
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;
}
void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips)
{
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->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)
{
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->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->fill_data.gradient = radial;
rasterizer->fill_data.type = RadialGradient;
}
void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
int x, int y, uint mul_col, Ector_Rop op, Shape_Rle_Data* rle)
{
// check for NULL rle data
if (!rle) return;
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);
}

View File

@ -0,0 +1,103 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Ector.h>
#include <software/Ector_Software.h>
#include "ector_private.h"
#include "ector_software_private.h"
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)
{
if (type == ECTOR_RENDERER_GENERIC_SHAPE_MIXIN)
return eo_add(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, obj);
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_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)
{
pd->software = ctx;
}
static Software_Rasterizer *
_ector_software_surface_context_get(Eo *obj EINA_UNUSED,
Ector_Software_Surface_Data *pd)
{
return pd->software;
}
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->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_surface_get(Eo *obj EINA_UNUSED,
Ector_Software_Surface_Data *pd,
void **pixels, unsigned int *width, unsigned int *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)
{
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);
}
_software_count++;
}
static void
_ector_software_surface_eo_base_destructor(Eo *obj EINA_UNUSED,
Ector_Software_Surface_Data *pd EINA_UNUSED)
{
--_software_count;
if (_software_count > 0) return;
ector_software_rasterizer_done(pd->software);
free(pd->software);
pd->software = NULL;
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"

View File

@ -0,0 +1,34 @@
class Ector.Software.Surface (Ector.Generic.Surface)
{
eo_prefix: ector_software_surface;
legacy_prefix: null;
properties {
context {
set {
}
get {
}
values {
Software_Rasterizer *ctx;
}
}
surface {
set {
}
get {
}
values {
void *pixels;
uint width;
uint height;
}
}
}
implements {
Ector.Generic.Surface.renderer_factory_new;
Ector.Generic.Surface.reference_point.set;
Eo.Base.destructor;
Eo.Base.constructor;
}
}

View File

@ -0,0 +1,528 @@
/***************************************************************************/
/* */
/* fttrigon.c */
/* */
/* FreeType trigonometric functions (body). */
/* */
/* Copyright 2001-2005, 2012-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <math.h>
#include "sw_ft_math.h"
#define SW_FT_MSB( x ) ( 31 - __builtin_clz( x ) )
#define SW_FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) )
#define SW_FT_PAD_ROUND( x, n ) SW_FT_PAD_FLOOR( (x) + ((n)/2), n )
#define SW_FT_PAD_CEIL( x, n ) SW_FT_PAD_FLOOR( (x) + ((n)-1), n )
#define SW_FT_BEGIN_STMNT do {
#define SW_FT_END_STMNT } while ( 0 )
/* transfer sign leaving a positive number */
#define SW_FT_MOVE_SIGN( x, s ) \
SW_FT_BEGIN_STMNT \
if ( x < 0 ) \
{ \
x = -x; \
s = -s; \
} \
SW_FT_END_STMNT
SW_FT_Long
SW_FT_MulFix( SW_FT_Long a,
SW_FT_Long b )
{
SW_FT_Int s = 1;
SW_FT_Long c;
SW_FT_MOVE_SIGN( a, s );
SW_FT_MOVE_SIGN( b, s );
c = (SW_FT_Long)( ( (SW_FT_Int64)a * b + 0x8000L ) >> 16 );
return ( s > 0 ) ? c : -c;
}
SW_FT_Long
SW_FT_MulDiv( SW_FT_Long a,
SW_FT_Long b,
SW_FT_Long c )
{
SW_FT_Int s = 1;
SW_FT_Long d;
SW_FT_MOVE_SIGN( a, s );
SW_FT_MOVE_SIGN( b, s );
SW_FT_MOVE_SIGN( c, s );
d = (SW_FT_Long)( c > 0 ? ( (SW_FT_Int64)a * b + ( c >> 1 ) ) / c
: 0x7FFFFFFFL );
return ( s > 0 ) ? d : -d;
}
SW_FT_Long
SW_FT_DivFix( SW_FT_Long a,
SW_FT_Long b )
{
SW_FT_Int s = 1;
SW_FT_Long q;
SW_FT_MOVE_SIGN( a, s );
SW_FT_MOVE_SIGN( b, s );
q = (SW_FT_Long)( b > 0 ? ( ( (SW_FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b
: 0x7FFFFFFFL );
return ( s < 0 ? -q : q );
}
/*************************************************************************/
/* */
/* This is a fixed-point CORDIC implementation of trigonometric */
/* functions as well as transformations between Cartesian and polar */
/* coordinates. The angles are represented as 16.16 fixed-point values */
/* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */
/* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */
/* discrete Cartesian grid can have the same or better angular */
/* resolution. Therefore, to maintain this precision, some functions */
/* require an interim upscaling of the vectors, whereas others operate */
/* with 24-bit long vectors directly. */
/* */
/*************************************************************************/
/* the Cordic shrink factor 0.858785336480436 * 2^32 */
#define SW_FT_TRIG_SCALE 0xDBD95B16UL
/* the highest bit in overflow-safe vector components, */
/* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */
#define SW_FT_TRIG_SAFE_MSB 29
/* this table was generated for SW_FT_PI = 180L << 16, i.e. degrees */
#define SW_FT_TRIG_MAX_ITERS 23
static const SW_FT_Fixed
ft_trig_arctan_table[] =
{
1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L,
14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
57L, 29L, 14L, 7L, 4L, 2L, 1L
};
/* multiply a given value by the CORDIC shrink factor */
static SW_FT_Fixed
ft_trig_downscale( SW_FT_Fixed val )
{
SW_FT_Fixed s;
SW_FT_Int64 v;
s = val;
val = SW_FT_ABS( val );
v = ( val * (SW_FT_Int64)SW_FT_TRIG_SCALE ) + 0x100000000UL;
val = (SW_FT_Fixed)( v >> 32 );
return ( s >= 0 ) ? val : -val;
}
/* undefined and never called for zero vector */
static SW_FT_Int
ft_trig_prenorm( SW_FT_Vector* vec )
{
SW_FT_Pos x, y;
SW_FT_Int shift;
x = vec->x;
y = vec->y;
shift = SW_FT_MSB( SW_FT_ABS( x ) | SW_FT_ABS( y ) );
if ( shift <= SW_FT_TRIG_SAFE_MSB )
{
shift = SW_FT_TRIG_SAFE_MSB - shift;
vec->x = (SW_FT_Pos)( (SW_FT_ULong)x << shift );
vec->y = (SW_FT_Pos)( (SW_FT_ULong)y << shift );
}
else
{
shift -= SW_FT_TRIG_SAFE_MSB;
vec->x = x >> shift;
vec->y = y >> shift;
shift = -shift;
}
return shift;
}
static void
ft_trig_pseudo_rotate( SW_FT_Vector* vec,
SW_FT_Angle theta )
{
SW_FT_Int i;
SW_FT_Fixed x, y, xtemp, b;
const SW_FT_Fixed *arctanptr;
x = vec->x;
y = vec->y;
/* Rotate inside [-PI/4,PI/4] sector */
while ( theta < -SW_FT_ANGLE_PI4 )
{
xtemp = y;
y = -x;
x = xtemp;
theta += SW_FT_ANGLE_PI2;
}
while ( theta > SW_FT_ANGLE_PI4 )
{
xtemp = -y;
y = x;
x = xtemp;
theta -= SW_FT_ANGLE_PI2;
}
arctanptr = ft_trig_arctan_table;
/* Pseudorotations, with right shifts */
for ( i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++ )
{
if ( theta < 0 )
{
xtemp = x + ( ( y + b ) >> i );
y = y - ( ( x + b ) >> i );
x = xtemp;
theta += *arctanptr++;
}
else
{
xtemp = x - ( ( y + b ) >> i );
y = y + ( ( x + b ) >> i );
x = xtemp;
theta -= *arctanptr++;
}
}
vec->x = x;
vec->y = y;
}
static void
ft_trig_pseudo_polarize( SW_FT_Vector* vec )
{
SW_FT_Angle theta;
SW_FT_Int i;
SW_FT_Fixed x, y, xtemp, b;
const SW_FT_Fixed *arctanptr;
x = vec->x;
y = vec->y;
/* Get the vector into [-PI/4,PI/4] sector */
if ( y > x )
{
if ( y > -x )
{
theta = SW_FT_ANGLE_PI2;
xtemp = y;
y = -x;
x = xtemp;
}
else
{
theta = y > 0 ? SW_FT_ANGLE_PI : -SW_FT_ANGLE_PI;
x = -x;
y = -y;
}
}
else
{
if ( y < -x )
{
theta = -SW_FT_ANGLE_PI2;
xtemp = -y;
y = x;
x = xtemp;
}
else
{
theta = 0;
}
}
arctanptr = ft_trig_arctan_table;
/* Pseudorotations, with right shifts */
for ( i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++ )
{
if ( y > 0 )
{
xtemp = x + ( ( y + b ) >> i );
y = y - ( ( x + b ) >> i );
x = xtemp;
theta += *arctanptr++;
}
else
{
xtemp = x - ( ( y + b ) >> i );
y = y + ( ( x + b ) >> i );
x = xtemp;
theta -= *arctanptr++;
}
}
/* round theta */
if ( theta >= 0 )
theta = SW_FT_PAD_ROUND( theta, 32 );
else
theta = -SW_FT_PAD_ROUND( -theta, 32 );
vec->x = x;
vec->y = theta;
}
/* documentation is in fttrigon.h */
SW_FT_Fixed
SW_FT_Cos( SW_FT_Angle angle )
{
SW_FT_Vector v;
v.x = SW_FT_TRIG_SCALE >> 8;
v.y = 0;
ft_trig_pseudo_rotate( &v, angle );
return ( v.x + 0x80L ) >> 8;
}
/* documentation is in fttrigon.h */
SW_FT_Fixed
SW_FT_Sin( SW_FT_Angle angle )
{
return SW_FT_Cos( SW_FT_ANGLE_PI2 - angle );
}
/* documentation is in fttrigon.h */
SW_FT_Fixed
SW_FT_Tan( SW_FT_Angle angle )
{
SW_FT_Vector v;
v.x = SW_FT_TRIG_SCALE >> 8;
v.y = 0;
ft_trig_pseudo_rotate( &v, angle );
return SW_FT_DivFix( v.y, v.x );
}
/* documentation is in fttrigon.h */
SW_FT_Angle
SW_FT_Atan2( SW_FT_Fixed dx,
SW_FT_Fixed dy )
{
SW_FT_Vector v;
if ( dx == 0 && dy == 0 )
return 0;
v.x = dx;
v.y = dy;
ft_trig_prenorm( &v );
ft_trig_pseudo_polarize( &v );
return v.y;
}
/* documentation is in fttrigon.h */
void
SW_FT_Vector_Unit( SW_FT_Vector* vec,
SW_FT_Angle angle )
{
vec->x = SW_FT_TRIG_SCALE >> 8;
vec->y = 0;
ft_trig_pseudo_rotate( vec, angle );
vec->x = ( vec->x + 0x80L ) >> 8;
vec->y = ( vec->y + 0x80L ) >> 8;
}
/* these macros return 0 for positive numbers,
and -1 for negative ones */
#define SW_FT_SIGN_LONG( x ) ( (x) >> ( SW_FT_SIZEOF_LONG * 8 - 1 ) )
#define SW_FT_SIGN_INT( x ) ( (x) >> ( SW_FT_SIZEOF_INT * 8 - 1 ) )
#define SW_FT_SIGN_INT32( x ) ( (x) >> 31 )
#define SW_FT_SIGN_INT16( x ) ( (x) >> 15 )
/* documentation is in fttrigon.h */
void
SW_FT_Vector_Rotate( SW_FT_Vector* vec,
SW_FT_Angle angle )
{
SW_FT_Int shift;
SW_FT_Vector v;
v.x = vec->x;
v.y = vec->y;
if ( angle && ( v.x != 0 || v.y != 0 ) )
{
shift = ft_trig_prenorm( &v );
ft_trig_pseudo_rotate( &v, angle );
v.x = ft_trig_downscale( v.x );
v.y = ft_trig_downscale( v.y );
if ( shift > 0 )
{
SW_FT_Int32 half = (SW_FT_Int32)1L << ( shift - 1 );
vec->x = ( v.x + half + SW_FT_SIGN_LONG( v.x ) ) >> shift;
vec->y = ( v.y + half + SW_FT_SIGN_LONG( v.y ) ) >> shift;
}
else
{
shift = -shift;
vec->x = (SW_FT_Pos)( (SW_FT_ULong)v.x << shift );
vec->y = (SW_FT_Pos)( (SW_FT_ULong)v.y << shift );
}
}
}
/* documentation is in fttrigon.h */
SW_FT_Fixed
SW_FT_Vector_Length( SW_FT_Vector* vec )
{
SW_FT_Int shift;
SW_FT_Vector v;
v = *vec;
/* handle trivial cases */
if ( v.x == 0 )
{
return SW_FT_ABS( v.y );
}
else if ( v.y == 0 )
{
return SW_FT_ABS( v.x );
}
/* general case */
shift = ft_trig_prenorm( &v );
ft_trig_pseudo_polarize( &v );
v.x = ft_trig_downscale( v.x );
if ( shift > 0 )
return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
return (SW_FT_Fixed)( (SW_FT_UInt32)v.x << -shift );
}
/* documentation is in fttrigon.h */
void
SW_FT_Vector_Polarize( SW_FT_Vector* vec,
SW_FT_Fixed *length,
SW_FT_Angle *angle )
{
SW_FT_Int shift;
SW_FT_Vector v;
v = *vec;
if ( v.x == 0 && v.y == 0 )
return;
shift = ft_trig_prenorm( &v );
ft_trig_pseudo_polarize( &v );
v.x = ft_trig_downscale( v.x );
*length = ( shift >= 0 ) ? ( v.x >> shift )
: (SW_FT_Fixed)( (SW_FT_UInt32)v.x << -shift );
*angle = v.y;
}
/* documentation is in fttrigon.h */
void
SW_FT_Vector_From_Polar( SW_FT_Vector* vec,
SW_FT_Fixed length,
SW_FT_Angle angle )
{
vec->x = length;
vec->y = 0;
SW_FT_Vector_Rotate( vec, angle );
}
/* documentation is in fttrigon.h */
SW_FT_Angle
SW_FT_Angle_Diff( SW_FT_Angle angle1,
SW_FT_Angle angle2 )
{
SW_FT_Angle delta = angle2 - angle1;
delta %= SW_FT_ANGLE_2PI;
if ( delta < 0 )
delta += SW_FT_ANGLE_2PI;
if ( delta > SW_FT_ANGLE_PI )
delta -= SW_FT_ANGLE_2PI;
return delta;
}
/* END */

View File

@ -0,0 +1,438 @@
#ifndef SW_FT_MATH_H
#define SW_FT_MATH_H
/***************************************************************************/
/* */
/* fttrigon.h */
/* */
/* FreeType trigonometric functions (specification). */
/* */
/* Copyright 2001, 2003, 2005, 2007, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include "sw_ft_types.h"
/*************************************************************************/
/* */
/* The min and max functions missing in C. As usual, be careful not to */
/* write things like SW_FT_MIN( a++, b++ ) to avoid side effects. */
/* */
#define SW_FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) )
#define SW_FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
#define SW_FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
/*
* Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
* algorithm. We use alpha = 1, beta = 3/8, giving us results with a
* largest error less than 7% compared to the exact value.
*/
#define SW_FT_HYPOT( x, y ) \
( x = SW_FT_ABS( x ), \
y = SW_FT_ABS( y ), \
x > y ? x + ( 3 * y >> 3 ) \
: y + ( 3 * x >> 3 ) )
/*************************************************************************/
/* */
/* <Function> */
/* SW_FT_MulFix */
/* */
/* <Description> */
/* A very simple function used to perform the computation */
/* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */
/* used to multiply a given value by a 16.16 fixed-point factor. */
/* */
/* <Input> */
/* a :: The first multiplier. */
/* b :: The second multiplier. Use a 16.16 factor here whenever */
/* possible (see note below). */
/* */
/* <Return> */
/* The result of `(a*b)/0x10000'. */
/* */
/* <Note> */
/* This function has been optimized for the case where the absolute */
/* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
/* As this happens mainly when scaling from notional units to */
/* fractional pixels in FreeType, it resulted in noticeable speed */
/* improvements between versions 2.x and 1.x. */
/* */
/* As a conclusion, always try to place a 16.16 factor as the */
/* _second_ argument of this function; this can make a great */
/* difference. */
/* */
SW_FT_Long
SW_FT_MulFix( SW_FT_Long a,
SW_FT_Long b );
/*************************************************************************/
/* */
/* <Function> */
/* SW_FT_MulDiv */
/* */
/* <Description> */
/* A very simple function used to perform the computation `(a*b)/c' */
/* with maximum accuracy (it uses a 64-bit intermediate integer */
/* whenever necessary). */
/* */
/* This function isn't necessarily as fast as some processor specific */
/* operations, but is at least completely portable. */
/* */
/* <Input> */
/* a :: The first multiplier. */
/* b :: The second multiplier. */
/* c :: The divisor. */
/* */
/* <Return> */
/* The result of `(a*b)/c'. This function never traps when trying to */
/* divide by zero; it simply returns `MaxInt' or `MinInt' depending */
/* on the signs of `a' and `b'. */
/* */
SW_FT_Long
SW_FT_MulDiv( SW_FT_Long a,
SW_FT_Long b,
SW_FT_Long c );
/*************************************************************************/
/* */
/* <Function> */
/* SW_FT_DivFix */
/* */
/* <Description> */
/* A very simple function used to perform the computation */
/* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */
/* used to divide a given value by a 16.16 fixed-point factor. */
/* */
/* <Input> */
/* a :: The numerator. */
/* b :: The denominator. Use a 16.16 factor here. */
/* */
/* <Return> */
/* The result of `(a*0x10000)/b'. */
/* */
SW_FT_Long
SW_FT_DivFix( SW_FT_Long a,
SW_FT_Long b );
/*************************************************************************/
/* */
/* <Section> */
/* computations */
/* */
/*************************************************************************/
/*************************************************************************
*
* @type:
* SW_FT_Angle
*
* @description:
* This type is used to model angle values in FreeType. Note that the
* angle is a 16.16 fixed-point value expressed in degrees.
*
*/
typedef SW_FT_Fixed SW_FT_Angle;
/*************************************************************************
*
* @macro:
* SW_FT_ANGLE_PI
*
* @description:
* The angle pi expressed in @SW_FT_Angle units.
*
*/
#define SW_FT_ANGLE_PI ( 180L << 16 )
/*************************************************************************
*
* @macro:
* SW_FT_ANGLE_2PI
*
* @description:
* The angle 2*pi expressed in @SW_FT_Angle units.
*
*/
#define SW_FT_ANGLE_2PI ( SW_FT_ANGLE_PI * 2 )
/*************************************************************************
*
* @macro:
* SW_FT_ANGLE_PI2
*
* @description:
* The angle pi/2 expressed in @SW_FT_Angle units.
*
*/
#define SW_FT_ANGLE_PI2 ( SW_FT_ANGLE_PI / 2 )
/*************************************************************************
*
* @macro:
* SW_FT_ANGLE_PI4
*
* @description:
* The angle pi/4 expressed in @SW_FT_Angle units.
*
*/
#define SW_FT_ANGLE_PI4 ( SW_FT_ANGLE_PI / 4 )
/*************************************************************************
*
* @function:
* SW_FT_Sin
*
* @description:
* Return the sinus of a given angle in fixed-point format.
*
* @input:
* angle ::
* The input angle.
*
* @return:
* The sinus value.
*
* @note:
* If you need both the sinus and cosinus for a given angle, use the
* function @SW_FT_Vector_Unit.
*
*/
SW_FT_Fixed
SW_FT_Sin( SW_FT_Angle angle );
/*************************************************************************
*
* @function:
* SW_FT_Cos
*
* @description:
* Return the cosinus of a given angle in fixed-point format.
*
* @input:
* angle ::
* The input angle.
*
* @return:
* The cosinus value.
*
* @note:
* If you need both the sinus and cosinus for a given angle, use the
* function @SW_FT_Vector_Unit.
*
*/
SW_FT_Fixed
SW_FT_Cos( SW_FT_Angle angle );
/*************************************************************************
*
* @function:
* SW_FT_Tan
*
* @description:
* Return the tangent of a given angle in fixed-point format.
*
* @input:
* angle ::
* The input angle.
*
* @return:
* The tangent value.
*
*/
SW_FT_Fixed
SW_FT_Tan( SW_FT_Angle angle );
/*************************************************************************
*
* @function:
* SW_FT_Atan2
*
* @description:
* Return the arc-tangent corresponding to a given vector (x,y) in
* the 2d plane.
*
* @input:
* x ::
* The horizontal vector coordinate.
*
* y ::
* The vertical vector coordinate.
*
* @return:
* The arc-tangent value (i.e. angle).
*
*/
SW_FT_Angle
SW_FT_Atan2( SW_FT_Fixed x,
SW_FT_Fixed y );
/*************************************************************************
*
* @function:
* SW_FT_Angle_Diff
*
* @description:
* Return the difference between two angles. The result is always
* constrained to the ]-PI..PI] interval.
*
* @input:
* angle1 ::
* First angle.
*
* angle2 ::
* Second angle.
*
* @return:
* Constrained value of `value2-value1'.
*
*/
SW_FT_Angle
SW_FT_Angle_Diff( SW_FT_Angle angle1,
SW_FT_Angle angle2 );
/*************************************************************************
*
* @function:
* SW_FT_Vector_Unit
*
* @description:
* Return the unit vector corresponding to a given angle. After the
* call, the value of `vec.x' will be `sin(angle)', and the value of
* `vec.y' will be `cos(angle)'.
*
* This function is useful to retrieve both the sinus and cosinus of a
* given angle quickly.
*
* @output:
* vec ::
* The address of target vector.
*
* @input:
* angle ::
* The input angle.
*
*/
void
SW_FT_Vector_Unit( SW_FT_Vector* vec,
SW_FT_Angle angle );
/*************************************************************************
*
* @function:
* SW_FT_Vector_Rotate
*
* @description:
* Rotate a vector by a given angle.
*
* @inout:
* vec ::
* The address of target vector.
*
* @input:
* angle ::
* The input angle.
*
*/
void
SW_FT_Vector_Rotate( SW_FT_Vector* vec,
SW_FT_Angle angle );
/*************************************************************************
*
* @function:
* SW_FT_Vector_Length
*
* @description:
* Return the length of a given vector.
*
* @input:
* vec ::
* The address of target vector.
*
* @return:
* The vector length, expressed in the same units that the original
* vector coordinates.
*
*/
SW_FT_Fixed
SW_FT_Vector_Length( SW_FT_Vector* vec );
/*************************************************************************
*
* @function:
* SW_FT_Vector_Polarize
*
* @description:
* Compute both the length and angle of a given vector.
*
* @input:
* vec ::
* The address of source vector.
*
* @output:
* length ::
* The vector length.
*
* angle ::
* The vector angle.
*
*/
void
SW_FT_Vector_Polarize( SW_FT_Vector* vec,
SW_FT_Fixed *length,
SW_FT_Angle *angle );
/*************************************************************************
*
* @function:
* SW_FT_Vector_From_Polar
*
* @description:
* Compute vector coordinates from a length and angle.
*
* @output:
* vec ::
* The address of source vector.
*
* @input:
* length ::
* The vector length.
*
* angle ::
* The vector angle.
*
*/
void
SW_FT_Vector_From_Polar( SW_FT_Vector* vec,
SW_FT_Fixed length,
SW_FT_Angle angle );
#endif // SW_FT_MATH_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,607 @@
#ifndef SW_FT_IMG_H
#define SW_FT_IMG_H
/***************************************************************************/
/* */
/* ftimage.h */
/* */
/* FreeType glyph image formats and default raster interface */
/* (specification). */
/* */
/* Copyright 1996-2010, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* Note: A `raster' is simply a scan-line converter, used to render */
/* SW_FT_Outlines into SW_FT_Bitmaps. */
/* */
/*************************************************************************/
#include "sw_ft_types.h"
/*************************************************************************/
/* */
/* <Struct> */
/* FT_BBox */
/* */
/* <Description> */
/* A structure used to hold an outline's bounding box, i.e., the */
/* coordinates of its extrema in the horizontal and vertical */
/* directions. */
/* */
/* <Fields> */
/* xMin :: The horizontal minimum (left-most). */
/* */
/* yMin :: The vertical minimum (bottom-most). */
/* */
/* xMax :: The horizontal maximum (right-most). */
/* */
/* yMax :: The vertical maximum (top-most). */
/* */
/* <Note> */
/* The bounding box is specified with the coordinates of the lower */
/* left and the upper right corner. In PostScript, those values are */
/* often called (llx,lly) and (urx,ury), respectively. */
/* */
/* If `yMin' is negative, this value gives the glyph's descender. */
/* Otherwise, the glyph doesn't descend below the baseline. */
/* Similarly, if `ymax' is positive, this value gives the glyph's */
/* ascender. */
/* */
/* `xMin' gives the horizontal distance from the glyph's origin to */
/* the left edge of the glyph's bounding box. If `xMin' is negative, */
/* the glyph extends to the left of the origin. */
/* */
typedef struct SW_FT_BBox_
{
SW_FT_Pos xMin, yMin;
SW_FT_Pos xMax, yMax;
} SW_FT_BBox;
/*************************************************************************/
/* */
/* <Struct> */
/* SW_FT_Outline */
/* */
/* <Description> */
/* This structure is used to describe an outline to the scan-line */
/* converter. */
/* */
/* <Fields> */
/* n_contours :: The number of contours in the outline. */
/* */
/* n_points :: The number of points in the outline. */
/* */
/* points :: A pointer to an array of `n_points' @SW_FT_Vector */
/* elements, giving the outline's point coordinates. */
/* */
/* tags :: A pointer to an array of `n_points' chars, giving */
/* each outline point's type. */
/* */
/* If bit~0 is unset, the point is `off' the curve, */
/* i.e., a Bézier control point, while it is `on' if */
/* set. */
/* */
/* Bit~1 is meaningful for `off' points only. If set, */
/* it indicates a third-order Bézier arc control point; */
/* and a second-order control point if unset. */
/* */
/* If bit~2 is set, bits 5-7 contain the drop-out mode */
/* (as defined in the OpenType specification; the value */
/* is the same as the argument to the SCANMODE */
/* instruction). */
/* */
/* Bits 3 and~4 are reserved for internal purposes. */
/* */
/* contours :: An array of `n_contours' shorts, giving the end */
/* point of each contour within the outline. For */
/* example, the first contour is defined by the points */
/* `0' to `contours[0]', the second one is defined by */
/* the points `contours[0]+1' to `contours[1]', etc. */
/* */
/* flags :: A set of bit flags used to characterize the outline */
/* and give hints to the scan-converter and hinter on */
/* how to convert/grid-fit it. See @SW_FT_OUTLINE_FLAGS.*/
/* */
typedef struct SW_FT_Outline_
{
short n_contours; /* number of contours in glyph */
short n_points; /* number of points in the glyph */
SW_FT_Vector* points; /* the outline's points */
char* tags; /* the points flags */
short* contours; /* the contour end points */
int flags; /* outline masks */
} SW_FT_Outline;
/*************************************************************************/
/* */
/* <Enum> */
/* SW_FT_OUTLINE_FLAGS */
/* */
/* <Description> */
/* A list of bit-field constants use for the flags in an outline's */
/* `flags' field. */
/* */
/* <Values> */
/* SW_FT_OUTLINE_NONE :: */
/* Value~0 is reserved. */
/* */
/* SW_FT_OUTLINE_OWNER :: */
/* If set, this flag indicates that the outline's field arrays */
/* (i.e., `points', `flags', and `contours') are `owned' by the */
/* outline object, and should thus be freed when it is destroyed. */
/* */
/* SW_FT_OUTLINE_EVEN_ODD_FILL :: */
/* By default, outlines are filled using the non-zero winding rule. */
/* If set to 1, the outline will be filled using the even-odd fill */
/* rule (only works with the smooth rasterizer). */
/* */
/* SW_FT_OUTLINE_REVERSE_FILL :: */
/* By default, outside contours of an outline are oriented in */
/* clock-wise direction, as defined in the TrueType specification. */
/* This flag is set if the outline uses the opposite direction */
/* (typically for Type~1 fonts). This flag is ignored by the scan */
/* converter. */
/* */
/* */
/* */
/* There exists a second mechanism to pass the drop-out mode to the */
/* B/W rasterizer; see the `tags' field in @SW_FT_Outline. */
/* */
/* Please refer to the description of the `SCANTYPE' instruction in */
/* the OpenType specification (in file `ttinst1.doc') how simple */
/* drop-outs, smart drop-outs, and stubs are defined. */
/* */
#define SW_FT_OUTLINE_NONE 0x0
#define SW_FT_OUTLINE_OWNER 0x1
#define SW_FT_OUTLINE_EVEN_ODD_FILL 0x2
#define SW_FT_OUTLINE_REVERSE_FILL 0x4
/* */
#define SW_FT_CURVE_TAG( flag ) ( flag & 3 )
#define SW_FT_CURVE_TAG_ON 1
#define SW_FT_CURVE_TAG_CONIC 0
#define SW_FT_CURVE_TAG_CUBIC 2
#define SW_FT_Curve_Tag_On SW_FT_CURVE_TAG_ON
#define SW_FT_Curve_Tag_Conic SW_FT_CURVE_TAG_CONIC
#define SW_FT_Curve_Tag_Cubic SW_FT_CURVE_TAG_CUBIC
/*************************************************************************/
/* */
/* A raster is a scan converter, in charge of rendering an outline into */
/* a a bitmap. This section contains the public API for rasters. */
/* */
/* Note that in FreeType 2, all rasters are now encapsulated within */
/* specific modules called `renderers'. See `ftrender.h' for more */
/* details on renderers. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Raster */
/* */
/* <Description> */
/* A handle (pointer) to a raster object. Each object can be used */
/* independently to convert an outline into a bitmap or pixmap. */
/* */
typedef struct SW_FT_RasterRec_* SW_FT_Raster;
/*************************************************************************/
/* */
/* <Struct> */
/* SW_FT_Span */
/* */
/* <Description> */
/* A structure used to model a single span of gray (or black) pixels */
/* when rendering a monochrome or anti-aliased bitmap. */
/* */
/* <Fields> */
/* x :: The span's horizontal start position. */
/* */
/* len :: The span's length in pixels. */
/* */
/* coverage :: The span color/coverage, ranging from 0 (background) */
/* to 255 (foreground). Only used for anti-aliased */
/* rendering. */
/* */
/* <Note> */
/* This structure is used by the span drawing callback type named */
/* @SW_FT_SpanFunc that takes the y~coordinate of the span as a */
/* parameter. */
/* */
/* The coverage value is always between 0 and 255. If you want less */
/* gray values, the callback function has to reduce them. */
/* */
typedef struct SW_FT_Span_
{
short x;
short y;
unsigned short len;
unsigned char coverage;
} SW_FT_Span;
/*************************************************************************/
/* */
/* <FuncType> */
/* SW_FT_SpanFunc */
/* */
/* <Description> */
/* A function used as a call-back by the anti-aliased renderer in */
/* order to let client applications draw themselves the gray pixel */
/* spans on each scan line. */
/* */
/* <Input> */
/* y :: The scanline's y~coordinate. */
/* */
/* count :: The number of spans to draw on this scanline. */
/* */
/* spans :: A table of `count' spans to draw on the scanline. */
/* */
/* user :: User-supplied data that is passed to the callback. */
/* */
/* <Note> */
/* This callback allows client applications to directly render the */
/* gray spans of the anti-aliased bitmap to any kind of surfaces. */
/* */
/* This can be used to write anti-aliased outlines directly to a */
/* given background bitmap, and even perform translucency. */
/* */
/* Note that the `count' field cannot be greater than a fixed value */
/* defined by the `SW_FT_MAX_GRAY_SPANS' configuration macro in */
/* `ftoption.h'. By default, this value is set to~32, which means */
/* that if there are more than 32~spans on a given scanline, the */
/* callback is called several times with the same `y' parameter in */
/* order to draw all callbacks. */
/* */
/* Otherwise, the callback is only called once per scan-line, and */
/* only for those scanlines that do have `gray' pixels on them. */
/* */
typedef void
(*SW_FT_SpanFunc)( int count,
const SW_FT_Span* spans,
void* user );
#define SW_FT_Raster_Span_Func SW_FT_SpanFunc
/*************************************************************************/
/* */
/* <Enum> */
/* SW_FT_RASTER_FLAG_XXX */
/* */
/* <Description> */
/* A list of bit flag constants as used in the `flags' field of a */
/* @SW_FT_Raster_Params structure. */
/* */
/* <Values> */
/* SW_FT_RASTER_FLAG_DEFAULT :: This value is 0. */
/* */
/* SW_FT_RASTER_FLAG_AA :: This flag is set to indicate that an */
/* anti-aliased glyph image should be */
/* generated. Otherwise, it will be */
/* monochrome (1-bit). */
/* */
/* SW_FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */
/* rendering. In this mode, client */
/* applications must provide their own span */
/* callback. This lets them directly */
/* draw or compose over an existing bitmap. */
/* If this bit is not set, the target */
/* pixmap's buffer _must_ be zeroed before */
/* rendering. */
/* */
/* Note that for now, direct rendering is */
/* only possible with anti-aliased glyphs. */
/* */
/* SW_FT_RASTER_FLAG_CLIP :: This flag is only used in direct */
/* rendering mode. If set, the output will */
/* be clipped to a box specified in the */
/* `clip_box' field of the */
/* @SW_FT_Raster_Params structure. */
/* */
/* Note that by default, the glyph bitmap */
/* is clipped to the target pixmap, except */
/* in direct rendering mode where all spans */
/* are generated if no clipping box is set. */
/* */
#define SW_FT_RASTER_FLAG_DEFAULT 0x0
#define SW_FT_RASTER_FLAG_AA 0x1
#define SW_FT_RASTER_FLAG_DIRECT 0x2
#define SW_FT_RASTER_FLAG_CLIP 0x4
/* deprecated */
#define ft_raster_flag_default SW_FT_RASTER_FLAG_DEFAULT
#define ft_raster_flag_aa SW_FT_RASTER_FLAG_AA
#define ft_raster_flag_direct SW_FT_RASTER_FLAG_DIRECT
#define ft_raster_flag_clip SW_FT_RASTER_FLAG_CLIP
/*************************************************************************/
/* */
/* <Struct> */
/* SW_FT_Raster_Params */
/* */
/* <Description> */
/* A structure to hold the arguments used by a raster's render */
/* function. */
/* */
/* <Fields> */
/* target :: The target bitmap. */
/* */
/* source :: A pointer to the source glyph image (e.g., an */
/* @SW_FT_Outline). */
/* */
/* flags :: The rendering flags. */
/* */
/* gray_spans :: The gray span drawing callback. */
/* */
/* black_spans :: The black span drawing callback. UNIMPLEMENTED! */
/* */
/* bit_test :: The bit test callback. UNIMPLEMENTED! */
/* */
/* bit_set :: The bit set callback. UNIMPLEMENTED! */
/* */
/* user :: User-supplied data that is passed to each drawing */
/* callback. */
/* */
/* clip_box :: An optional clipping box. It is only used in */
/* direct rendering mode. Note that coordinates here */
/* should be expressed in _integer_ pixels (and not in */
/* 26.6 fixed-point units). */
/* */
/* <Note> */
/* An anti-aliased glyph bitmap is drawn if the @SW_FT_RASTER_FLAG_AA */
/* bit flag is set in the `flags' field, otherwise a monochrome */
/* bitmap is generated. */
/* */
/* If the @SW_FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */
/* raster will call the `gray_spans' callback to draw gray pixel */
/* spans, in the case of an aa glyph bitmap, it will call */
/* `black_spans', and `bit_test' and `bit_set' in the case of a */
/* monochrome bitmap. This allows direct composition over a */
/* pre-existing bitmap through user-provided callbacks to perform the */
/* span drawing/composition. */
/* */
/* Note that the `bit_test' and `bit_set' callbacks are required when */
/* rendering a monochrome bitmap, as they are crucial to implement */
/* correct drop-out control as defined in the TrueType specification. */
/* */
typedef struct SW_FT_Raster_Params_
{
const void* source;
int flags;
SW_FT_SpanFunc gray_spans;
void* user;
SW_FT_BBox clip_box;
} SW_FT_Raster_Params;
/*************************************************************************/
/* */
/* <Function> */
/* SW_FT_Outline_Check */
/* */
/* <Description> */
/* Check the contents of an outline descriptor. */
/* */
/* <Input> */
/* outline :: A handle to a source outline. */
/* */
/* <Return> */
/* FreeType error code. 0~means success. */
/* */
SW_FT_Error
SW_FT_Outline_Check( SW_FT_Outline* outline );
/*************************************************************************/
/* */
/* <Function> */
/* SW_FT_Outline_Get_CBox */
/* */
/* <Description> */
/* Return an outline's `control box'. The control box encloses all */
/* the outline's points, including Bézier control points. Though it */
/* coincides with the exact bounding box for most glyphs, it can be */
/* slightly larger in some situations (like when rotating an outline */
/* that contains Bézier outside arcs). */
/* */
/* Computing the control box is very fast, while getting the bounding */
/* box can take much more time as it needs to walk over all segments */
/* and arcs in the outline. To get the latter, you can use the */
/* `ftbbox' component, which is dedicated to this single task. */
/* */
/* <Input> */
/* outline :: A pointer to the source outline descriptor. */
/* */
/* <Output> */
/* acbox :: The outline's control box. */
/* */
/* <Note> */
/* See @SW_FT_Glyph_Get_CBox for a discussion of tricky fonts. */
/* */
void
SW_FT_Outline_Get_CBox( const SW_FT_Outline* outline,
SW_FT_BBox *acbox );
/*************************************************************************/
/* */
/* <FuncType> */
/* SW_FT_Raster_NewFunc */
/* */
/* <Description> */
/* A function used to create a new raster object. */
/* */
/* <Input> */
/* memory :: A handle to the memory allocator. */
/* */
/* <Output> */
/* raster :: A handle to the new raster object. */
/* */
/* <Return> */
/* Error code. 0~means success. */
/* */
/* <Note> */
/* The `memory' parameter is a typeless pointer in order to avoid */
/* un-wanted dependencies on the rest of the FreeType code. In */
/* practice, it is an @SW_FT_Memory object, i.e., a handle to the */
/* standard FreeType memory allocator. However, this field can be */
/* completely ignored by a given raster implementation. */
/* */
typedef int
(*SW_FT_Raster_NewFunc)( SW_FT_Raster* raster );
#define SW_FT_Raster_New_Func SW_FT_Raster_NewFunc
/*************************************************************************/
/* */
/* <FuncType> */
/* SW_FT_Raster_DoneFunc */
/* */
/* <Description> */
/* A function used to destroy a given raster object. */
/* */
/* <Input> */
/* raster :: A handle to the raster object. */
/* */
typedef void
(*SW_FT_Raster_DoneFunc)( SW_FT_Raster raster );
#define SW_FT_Raster_Done_Func SW_FT_Raster_DoneFunc
/*************************************************************************/
/* */
/* <FuncType> */
/* SW_FT_Raster_ResetFunc */
/* */
/* <Description> */
/* FreeType provides an area of memory called the `render pool', */
/* available to all registered rasters. This pool can be freely used */
/* during a given scan-conversion but is shared by all rasters. Its */
/* content is thus transient. */
/* */
/* This function is called each time the render pool changes, or just */
/* after a new raster object is created. */
/* */
/* <Input> */
/* raster :: A handle to the new raster object. */
/* */
/* pool_base :: The address in memory of the render pool. */
/* */
/* pool_size :: The size in bytes of the render pool. */
/* */
/* <Note> */
/* Rasters can ignore the render pool and rely on dynamic memory */
/* allocation if they want to (a handle to the memory allocator is */
/* passed to the raster constructor). However, this is not */
/* recommended for efficiency purposes. */
/* */
typedef void
(*SW_FT_Raster_ResetFunc)( SW_FT_Raster raster,
unsigned char* pool_base,
unsigned long pool_size );
#define SW_FT_Raster_Reset_Func SW_FT_Raster_ResetFunc
/*************************************************************************/
/* */
/* <FuncType> */
/* SW_FT_Raster_RenderFunc */
/* */
/* <Description> */
/* Invoke a given raster to scan-convert a given glyph image into a */
/* target bitmap. */
/* */
/* <Input> */
/* raster :: A handle to the raster object. */
/* */
/* params :: A pointer to an @SW_FT_Raster_Params structure used to */
/* store the rendering parameters. */
/* */
/* <Return> */
/* Error code. 0~means success. */
/* */
/* <Note> */
/* The exact format of the source image depends on the raster's glyph */
/* format defined in its @SW_FT_Raster_Funcs structure. It can be an */
/* @SW_FT_Outline or anything else in order to support a large array of */
/* glyph formats. */
/* */
/* Note also that the render function can fail and return a */
/* `SW_FT_Err_Unimplemented_Feature' error code if the raster used does */
/* not support direct composition. */
/* */
/* XXX: For now, the standard raster doesn't support direct */
/* composition but this should change for the final release (see */
/* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */
/* for examples of distinct implementations that support direct */
/* composition). */
/* */
typedef int
(*SW_FT_Raster_RenderFunc)( SW_FT_Raster raster,
const SW_FT_Raster_Params* params );
#define SW_FT_Raster_Render_Func SW_FT_Raster_RenderFunc
/*************************************************************************/
/* */
/* <Struct> */
/* SW_FT_Raster_Funcs */
/* */
/* <Description> */
/* A structure used to describe a given raster class to the library. */
/* */
/* <Fields> */
/* glyph_format :: The supported glyph format for this raster. */
/* */
/* raster_new :: The raster constructor. */
/* */
/* raster_reset :: Used to reset the render pool within the raster. */
/* */
/* raster_render :: A function to render a glyph into a given bitmap. */
/* */
/* raster_done :: The raster destructor. */
/* */
typedef struct SW_FT_Raster_Funcs_
{
SW_FT_Raster_NewFunc raster_new;
SW_FT_Raster_ResetFunc raster_reset;
SW_FT_Raster_RenderFunc raster_render;
SW_FT_Raster_DoneFunc raster_done;
} SW_FT_Raster_Funcs;
extern const SW_FT_Raster_Funcs sw_ft_grays_raster;
#endif // SW_FT_IMG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,325 @@
#ifndef SW_FT_STROKER_H
#define SW_FT_STROKER_H
/***************************************************************************/
/* */
/* ftstroke.h */
/* */
/* FreeType path stroker (specification). */
/* */
/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include "sw_ft_raster.h"
/**************************************************************
*
* @type:
* SW_FT_Stroker
*
* @description:
* Opaque handler to a path stroker object.
*/
typedef struct SW_FT_StrokerRec_* SW_FT_Stroker;
/**************************************************************
*
* @enum:
* SW_FT_Stroker_LineJoin
*
* @description:
* These values determine how two joining lines are rendered
* in a stroker.
*
* @values:
* SW_FT_STROKER_LINEJOIN_ROUND ::
* Used to render rounded line joins. Circular arcs are used
* to join two lines smoothly.
*
* SW_FT_STROKER_LINEJOIN_BEVEL ::
* Used to render beveled line joins. The outer corner of
* the joined lines is filled by enclosing the triangular
* region of the corner with a straight line between the
* outer corners of each stroke.
*
* SW_FT_STROKER_LINEJOIN_MITER_FIXED ::
* Used to render mitered line joins, with fixed bevels if the
* miter limit is exceeded. The outer edges of the strokes
* for the two segments are extended until they meet at an
* angle. If the segments meet at too sharp an angle (such
* that the miter would extend from the intersection of the
* segments a distance greater than the product of the miter
* limit value and the border radius), then a bevel join (see
* above) is used instead. This prevents long spikes being
* created. SW_FT_STROKER_LINEJOIN_MITER_FIXED generates a miter
* line join as used in PostScript and PDF.
*
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE ::
* SW_FT_STROKER_LINEJOIN_MITER ::
* Used to render mitered line joins, with variable bevels if
* the miter limit is exceeded. The intersection of the
* strokes is clipped at a line perpendicular to the bisector
* of the angle between the strokes, at the distance from the
* intersection of the segments equal to the product of the
* miter limit value and the border radius. This prevents
* long spikes being created.
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line
* join as used in XPS. SW_FT_STROKER_LINEJOIN_MITER is an alias
* for SW_FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for
* backwards compatibility.
*/
typedef enum SW_FT_Stroker_LineJoin_
{
SW_FT_STROKER_LINEJOIN_ROUND = 0,
SW_FT_STROKER_LINEJOIN_BEVEL = 1,
SW_FT_STROKER_LINEJOIN_MITER_VARIABLE = 2,
SW_FT_STROKER_LINEJOIN_MITER = SW_FT_STROKER_LINEJOIN_MITER_VARIABLE,
SW_FT_STROKER_LINEJOIN_MITER_FIXED = 3
} SW_FT_Stroker_LineJoin;
/**************************************************************
*
* @enum:
* SW_FT_Stroker_LineCap
*
* @description:
* These values determine how the end of opened sub-paths are
* rendered in a stroke.
*
* @values:
* SW_FT_STROKER_LINECAP_BUTT ::
* The end of lines is rendered as a full stop on the last
* point itself.
*
* SW_FT_STROKER_LINECAP_ROUND ::
* The end of lines is rendered as a half-circle around the
* last point.
*
* SW_FT_STROKER_LINECAP_SQUARE ::
* The end of lines is rendered as a square around the
* last point.
*/
typedef enum SW_FT_Stroker_LineCap_
{
SW_FT_STROKER_LINECAP_BUTT = 0,
SW_FT_STROKER_LINECAP_ROUND,
SW_FT_STROKER_LINECAP_SQUARE
} SW_FT_Stroker_LineCap;
/**************************************************************
*
* @enum:
* SW_FT_StrokerBorder
*
* @description:
* These values are used to select a given stroke border
* in @SW_FT_Stroker_GetBorderCounts and @SW_FT_Stroker_ExportBorder.
*
* @values:
* SW_FT_STROKER_BORDER_LEFT ::
* Select the left border, relative to the drawing direction.
*
* SW_FT_STROKER_BORDER_RIGHT ::
* Select the right border, relative to the drawing direction.
*
* @note:
* Applications are generally interested in the `inside' and `outside'
* borders. However, there is no direct mapping between these and the
* `left' and `right' ones, since this really depends on the glyph's
* drawing orientation, which varies between font formats.
*
* You can however use @SW_FT_Outline_GetInsideBorder and
* @SW_FT_Outline_GetOutsideBorder to get these.
*/
typedef enum SW_FT_StrokerBorder_
{
SW_FT_STROKER_BORDER_LEFT = 0,
SW_FT_STROKER_BORDER_RIGHT
} SW_FT_StrokerBorder;
/**************************************************************
*
* @function:
* SW_FT_Stroker_New
*
* @description:
* Create a new stroker object.
*
* @input:
* library ::
* FreeType library handle.
*
* @output:
* astroker ::
* A new stroker object handle. NULL in case of error.
*
* @return:
* FreeType error code. 0~means success.
*/
SW_FT_Error
SW_FT_Stroker_New( SW_FT_Stroker *astroker );
/**************************************************************
*
* @function:
* SW_FT_Stroker_Set
*
* @description:
* Reset a stroker object's attributes.
*
* @input:
* stroker ::
* The target stroker handle.
*
* radius ::
* The border radius.
*
* line_cap ::
* The line cap style.
*
* line_join ::
* The line join style.
*
* miter_limit ::
* The miter limit for the SW_FT_STROKER_LINEJOIN_MITER_FIXED and
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles,
* expressed as 16.16 fixed-point value.
*
* @note:
* The radius is expressed in the same units as the outline
* coordinates.
*/
void
SW_FT_Stroker_Set( SW_FT_Stroker stroker,
SW_FT_Fixed radius,
SW_FT_Stroker_LineCap line_cap,
SW_FT_Stroker_LineJoin line_join,
SW_FT_Fixed miter_limit );
/**************************************************************
*
* @function:
* SW_FT_Stroker_ParseOutline
*
* @description:
* A convenience function used to parse a whole outline with
* the stroker. The resulting outline(s) can be retrieved
* later by functions like @SW_FT_Stroker_GetCounts and @SW_FT_Stroker_Export.
*
* @input:
* stroker ::
* The target stroker handle.
*
* outline ::
* The source outline.
*
* opened ::
* A boolean. If~1, the outline is treated as an open path instead
* of a closed one.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If `opened' is~0 (the default), the outline is treated as a closed
* path, and the stroker generates two distinct `border' outlines.
*
* If `opened' is~1, the outline is processed as an open path, and the
* stroker generates a single `stroke' outline.
*
* This function calls @SW_FT_Stroker_Rewind automatically.
*/
SW_FT_Error
SW_FT_Stroker_ParseOutline( SW_FT_Stroker stroker,
SW_FT_Outline* outline,
SW_FT_Bool opened );
/**************************************************************
*
* @function:
* SW_FT_Stroker_GetCounts
*
* @description:
* Call this function once you have finished parsing your paths
* with the stroker. It returns the number of points and
* contours necessary to export all points/borders from the stroked
* outline/path.
*
* @input:
* stroker ::
* The target stroker handle.
*
* @output:
* anum_points ::
* The number of points.
*
* anum_contours ::
* The number of contours.
*
* @return:
* FreeType error code. 0~means success.
*/
SW_FT_Error
SW_FT_Stroker_GetCounts( SW_FT_Stroker stroker,
SW_FT_UInt *anum_points,
SW_FT_UInt *anum_contours );
/**************************************************************
*
* @function:
* SW_FT_Stroker_Export
*
* @description:
* Call this function after @SW_FT_Stroker_GetBorderCounts to
* export all borders to your own @SW_FT_Outline structure.
*
* Note that this function appends the border points and
* contours to your outline, but does not try to resize its
* arrays.
*
* @input:
* stroker ::
* The target stroker handle.
*
* outline ::
* The target outline handle.
*/
void
SW_FT_Stroker_Export( SW_FT_Stroker stroker,
SW_FT_Outline* outline );
/**************************************************************
*
* @function:
* SW_FT_Stroker_Done
*
* @description:
* Destroy a stroker object.
*
* @input:
* stroker ::
* A stroker handle. Can be NULL.
*/
void
SW_FT_Stroker_Done( SW_FT_Stroker stroker );
#endif // SW_FT_STROKER_H

View File

@ -0,0 +1,160 @@
#ifndef SW_FT_TYPES_H
#define SW_FT_TYPES_H
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Fixed */
/* */
/* <Description> */
/* This type is used to store 16.16 fixed-point values, like scaling */
/* values or matrix coefficients. */
/* */
typedef signed long SW_FT_Fixed;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Int */
/* */
/* <Description> */
/* A typedef for the int type. */
/* */
typedef signed int SW_FT_Int;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_UInt */
/* */
/* <Description> */
/* A typedef for the unsigned int type. */
/* */
typedef unsigned int SW_FT_UInt;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Long */
/* */
/* <Description> */
/* A typedef for signed long. */
/* */
typedef signed long SW_FT_Long;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_ULong */
/* */
/* <Description> */
/* A typedef for unsigned long. */
/* */
typedef unsigned long SW_FT_ULong;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Short */
/* */
/* <Description> */
/* A typedef for signed short. */
/* */
typedef signed short SW_FT_Short;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Byte */
/* */
/* <Description> */
/* A simple typedef for the _unsigned_ char type. */
/* */
typedef unsigned char SW_FT_Byte;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Bool */
/* */
/* <Description> */
/* A typedef of unsigned char, used for simple booleans. As usual, */
/* values 1 and~0 represent true and false, respectively. */
/* */
typedef unsigned char SW_FT_Bool;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Error */
/* */
/* <Description> */
/* The FreeType error code type. A value of~0 is always interpreted */
/* as a successful operation. */
/* */
typedef int SW_FT_Error;
/*************************************************************************/
/* */
/* <Type> */
/* SW_FT_Pos */
/* */
/* <Description> */
/* The type SW_FT_Pos is used to store vectorial coordinates. Depending */
/* on the context, these can represent distances in integer font */
/* units, or 16.16, or 26.6 fixed-point pixel coordinates. */
/* */
typedef signed long SW_FT_Pos;
/*************************************************************************/
/* */
/* <Struct> */
/* SW_FT_Vector */
/* */
/* <Description> */
/* A simple structure used to store a 2D vector; coordinates are of */
/* the SW_FT_Pos type. */
/* */
/* <Fields> */
/* x :: The horizontal coordinate. */
/* y :: The vertical coordinate. */
/* */
typedef struct SW_FT_Vector_
{
SW_FT_Pos x;
SW_FT_Pos y;
} SW_FT_Vector;
typedef long long int SW_FT_Int64;
typedef unsigned long long int SW_FT_UInt64;
typedef signed int SW_FT_Int32;
typedef unsigned int SW_FT_UInt32;
#define SW_FT_BOOL( x ) ( (SW_FT_Bool)( x ) )
#define SW_FT_SIZEOF_LONG 4
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#endif // SW_FT_TYPES_H

View File

@ -212,5 +212,42 @@ Edje object
*/
EAPI void edje_object_file_get(const Eo *obj, const char **file, const char **group);
/**
*
* @brief Sets the @b EDJ file (and group within it) to load an Edje
* object's contents from
*
* @return @c EINA_TRUE, on success or @c EINA_FALSE, on errors (check
* edje_object_load_error_get() after this call to get errors causes)
*
* Edje expects EDJ files, which are theming objects' descriptions and
* resources packed together in an EET file, to read Edje object
* definitions from. They usually are created with the @c .edj
* extension. EDJ files, in turn, are assembled from @b textual object
* description files, where one describes Edje objects declaratively
* -- the EDC files (see @ref edcref "the syntax" for those files).
*
* Those description files were designed so that many Edje object
* definitions -- also called @b groups (or collections) -- could be
* packed together <b>in the same EDJ file</b>, so that a whole
* application's theme could be packed in one file only. This is the
* reason for the @p group argument.
*
* Use this function after you instantiate a new Edje object, so that
* you can "give him life", telling where to get its contents from.
*
* @see edje_object_add()
* @see edje_object_file_get()
* @see edje_object_mmap_set()
* @since 1.8
*
* @param[in] file The Eina.File pointing to the EDJ file to load @p from
* @param[in] group The name of the group, in @p file, which implements an
Edje object
*/
EAPI Eina_Bool edje_object_mmap_set(Eo *obj, const Eina_File *file, const char *group);
#include "edje_object.eo.legacy.h"
#include "edje_edit.eo.legacy.h"

View File

@ -1422,7 +1422,7 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
if (!chosen_desc->text.min_x)
{
eo_do(ep->object,
evas_obj_size_set(TO_INT(params->eval.w), TO_INT(params->eval.h)),
efl_gfx_size_set(TO_INT(params->eval.w), TO_INT(params->eval.h)),
evas_obj_textblock_size_formatted_get(&tw, &th));
}
else
@ -1450,7 +1450,7 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
if (!chosen_desc->text.max_x)
{
eo_do(ep->object,
evas_obj_size_set(TO_INT(params->eval.w), TO_INT(params->eval.h)),
efl_gfx_size_set(TO_INT(params->eval.w), TO_INT(params->eval.h)),
evas_obj_textblock_size_formatted_get(&tw, &th));
}
else
@ -1538,7 +1538,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
return;
// Note: No need to add padding to that, it's already in the geometry
eo_do(ep->object, evas_obj_size_get(&mw, &mh));
eo_do(ep->object, efl_gfx_size_get(&mw, &mh));
if (chosen_desc->text.max_x)
{
@ -1698,7 +1698,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
eo_do(ep->object,
evas_obj_text_style_set(style),
evas_obj_text_set(text),
evas_obj_size_get(&tw, &th));
efl_gfx_size_get(&tw, &th));
if (chosen_desc->text.max_x)
{
int l, r;
@ -2686,10 +2686,10 @@ _edje_proxy_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj
}
eo_do(ep->object,
evas_obj_image_fill_set(p3->type.common.fill.x,
p3->type.common.fill.y,
p3->type.common.fill.w,
p3->type.common.fill.h),
efl_gfx_fill_set(p3->type.common.fill.x,
p3->type.common.fill.y,
p3->type.common.fill.w,
p3->type.common.fill.h),
efl_image_smooth_scale_set(p3->smooth),
evas_obj_image_source_visible_set(chosen_desc->proxy.source_visible),
evas_obj_image_source_clip_set(chosen_desc->proxy.source_clip));
@ -2727,9 +2727,9 @@ _edje_image_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj
}
eo_do(ep->object,
evas_obj_image_fill_set(p3->type.common.fill.x, p3->type.common.fill.y,
p3->type.common.fill.w, p3->type.common.fill.h),
efl_image_smooth_scale_set(p3->smooth));
efl_gfx_fill_set(p3->type.common.fill.x, p3->type.common.fill.y,
p3->type.common.fill.w, p3->type.common.fill.h),
efl_image_smooth_scale_set(p3->smooth));
if (chosen_desc->image.border.scale)
{
if (p3->type.common.spec.image.border_scale_by > FROM_DOUBLE(0.0))
@ -3918,7 +3918,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
/* visibility and color have no meaning on SWALLOW and GROUP part. */
#ifdef HAVE_EPHYSICS
eo_do(ep->object,
evas_obj_size_set(pf->final.w, pf->final.h));
efl_gfx_size_set(pf->final.w, pf->final.h));
if ((ep->part->physics_body) && (!ep->body))
{
if (_edje_physics_world_geometry_check(ed->world))
@ -3936,19 +3936,19 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
}
else
eo_do(ep->object,
evas_obj_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
#else
eo_do(ep->object,
evas_obj_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
evas_obj_size_set(pf->final.w, pf->final.h));
efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
efl_gfx_size_set(pf->final.w, pf->final.h));
#endif
if (ep->nested_smart)
{ /* Move, Resize all nested parts */
/* Not really needed but will improve the bounding box evaluation done by Evas */
eo_do(ep->nested_smart,
evas_obj_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
evas_obj_size_set(pf->final.w, pf->final.h));
efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
efl_gfx_size_set(pf->final.w, pf->final.h));
}
if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
_edje_entry_real_part_configure(ed, ep);
@ -4012,9 +4012,9 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
if (ep->part->type == EDJE_PART_TYPE_GROUP)
vis = evas_object_visible_get(ed->obj);
eo_do(ep->typedata.swallow->swallowed_object,
evas_obj_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
evas_obj_size_set(pf->final.w, pf->final.h),
evas_obj_visibility_set(vis));
efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
efl_gfx_size_set(pf->final.w, pf->final.h),
efl_gfx_visible_set(vis));
}
else evas_object_hide(ep->typedata.swallow->swallowed_object);
mo = ep->typedata.swallow->swallowed_object;

View File

@ -182,43 +182,6 @@ class Edje.Object (Evas.Smart_Clipped, Efl.File)
that means the edc file is made based on scale 1.0. */
}
}
mmap {
set {
/*@
@brief Sets the @b EDJ file (and group within it) to load an Edje
object's contents from
@return @c EINA_TRUE, on success or @c EINA_FALSE, on errors (check
edje_object_load_error_get() after this call to get errors causes)
Edje expects EDJ files, which are theming objects' descriptions and
resources packed together in an EET file, to read Edje object
definitions from. They usually are created with the @c .edj
extension. EDJ files, in turn, are assembled from @b textual object
description files, where one describes Edje objects declaratively
-- the EDC files (see @ref edcref "the syntax" for those files).
Those description files were designed so that many Edje object
definitions -- also called @b groups (or collections) -- could be
packed together <b>in the same EDJ file</b>, so that a whole
application's theme could be packed in one file only. This is the
reason for the @p group argument.
Use this function after you instantiate a new Edje object, so that
you can "give him life", telling where to get its contents from.
@see edje_object_add()
@see edje_object_file_get()
@see edje_object_mmap_set()
@since 1.8 */
return: bool;
}
values {
const(Eina.File)* file; /*@ The Eina.File pointing to the EDJ file to load @p from */
const(char)* group; /*@ The name of the group, in @p file, which implements an
Edje object */
}
}
text_change_cb {
set {
/*@
@ -2414,5 +2377,7 @@ class Edje.Object (Evas.Smart_Clipped, Efl.File)
Evas.Object_Smart.resize;
Efl.File.file.set;
Efl.File.file.get;
Efl.File.mmap.set;
Efl.File.mmap.get;
}
}

View File

@ -337,7 +337,8 @@ _edje_object_efl_file_file_set(Eo *obj, Edje *_pd EINA_UNUSED, const char *file,
}
EOLIAN static Eina_Bool
_edje_object_mmap_set(Eo *obj, Edje *_pd EINA_UNUSED, const Eina_File *f, const char *group)
_edje_object_efl_file_mmap_set(Eo *obj, Edje *pd EINA_UNUSED,
const Eina_File *f, const char *key)
{
Eina_Bool ret;
Eina_Array *nested;
@ -346,7 +347,7 @@ _edje_object_mmap_set(Eo *obj, Edje *_pd EINA_UNUSED, const Eina_File *f, const
nested = eina_array_new(8);
if (_edje_object_file_set_internal(obj, f, group, NULL, NULL, nested))
if (_edje_object_file_set_internal(obj, f, key, NULL, NULL, nested))
ret = EINA_TRUE;
eina_array_free(nested);
@ -355,6 +356,22 @@ _edje_object_mmap_set(Eo *obj, Edje *_pd EINA_UNUSED, const Eina_File *f, const
return ret;
}
EOLIAN static void
_edje_object_efl_file_mmap_get(Eo *obj EINA_UNUSED, Edje *pd,
const Eina_File **f, const char **key)
{
if (f) *f = pd->file->f;
if (key) *key = pd->group;
}
EAPI Eina_Bool
edje_object_mmap_set(Edje_Object *obj, const Eina_File *file, const char *group)
{
Eina_Bool ret;
return eo_do_ret((Edje_Object *)obj, ret, efl_file_mmap_set(file, group));
}
EAPI Eina_Bool
edje_object_file_set(Eo *obj, const char *file, const char *group)
{
@ -370,4 +387,3 @@ edje_object_file_get(const Eo *obj, const char **file, const char **group)
}
#include "edje_object.eo.c"

View File

@ -18,7 +18,7 @@ static inline void
part_get_geometry(Edje_Real_Part *rp, Evas_Coord *w, Evas_Coord *h)
{
if (!rp->part->use_alternate_font_metrics)
eo_do(rp->object, evas_obj_size_get(w, h));
eo_do(rp->object, efl_gfx_size_get(w, h));
else
{
if (w) *w = evas_object_text_horiz_advance_get(rp->object);
@ -100,7 +100,7 @@ _edje_text_fit_x(Edje *ed, Edje_Real_Part *ep,
evas_obj_text_ellipsis_set(chosen_desc->text.min_x ? -1 : params->type.text.ellipsis),
efl_text_properties_font_set(font, size),
efl_text_set(text),
evas_obj_size_set(sw, sh));
efl_gfx_size_set(sw, sh));
return text;
}
@ -519,10 +519,10 @@ arrange_text:
if (!calc_only)
{
eo_do(ep->object,
evas_obj_position_set(ed->x + TO_INT(params->eval.x) + ep->typedata.text->offset.x,
ed->y + TO_INT(params->eval.y) + ep->typedata.text->offset.y);
efl_gfx_position_set(ed->x + TO_INT(params->eval.x) + ep->typedata.text->offset.x,
ed->y + TO_INT(params->eval.y) + ep->typedata.text->offset.y);
evas_obj_visibility_set(params->visible));
efl_gfx_visible_set(params->visible));
}

View File

@ -34,6 +34,109 @@ extern "C"
# endif
#endif /* ! _WIN32 */
/**
* These values determine how the points are interpreted in a stream of points.
*
* @since 1.14
*/
typedef enum _Efl_Gfx_Path_Command
{
EFL_GFX_PATH_COMMAND_TYPE_END = 0, /**< The end of stream , no more points to process. */
EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO, /**< The next point is the start point of a sub path */
EFL_GFX_PATH_COMMAND_TYPE_LINE_TO, /**< The next point is used to draw a line from current point */
EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO, /**< The next three point is used to draw a cubic bezier curve from current point */
EFL_GFX_PATH_COMMAND_TYPE_CLOSE, /**< Close the curent subpath by drawing a line between current point and the first point of current subpath */
EFL_GFX_PATH_COMMAND_TYPE_LAST, /**< Not a valid command, but last one according to this version header */
} Efl_Gfx_Path_Command;
/**
* Type describing dash
*
* @see efl_gfx_shape_stroke_dash_set()
*
* @since 1.14
*/
typedef struct _Efl_Gfx_Dash Efl_Gfx_Dash;
struct _Efl_Gfx_Dash
{
double length; /**< dash drawing length */
double gap; /**< distance bettwen two dashes */
};
/**
* These values determine how the end of opened sub-paths are rendered in a
* stroke.
*
* @see efl_gfx_shape_stroke_cap_set()
*
* @since 1.14
*/
typedef enum _Efl_Gfx_Cap
{
EFL_GFX_CAP_BUTT = 0, /**< The end of lines is rendered as a full stop on the last point itself */
EFL_GFX_CAP_ROUND, /**< The end of lines is rendered as a half-circle around the last point */
EFL_GFX_CAP_SQUARE, /**< The end of lines is rendered as a square around the last point */
EFL_GFX_CAP_LAST /**< End of enum value */
} Efl_Gfx_Cap;
/**
* These values determine how two joining lines are rendered in a stroker.
*
* @see efl_gfx_shape_stroke_join_set()
*
* @since 1.14
*/
typedef enum _Efl_Gfx_Join
{
EFL_GFX_JOIN_MITER = 0, /**< Used to render rounded line joins. Circular arcs are used to join two lines smoothly. */
EFL_GFX_JOIN_ROUND, /**< Used to render beveled line joins. The outer corner of the joined lines is filled by enclosing the triangular region of the corner with a straight line between the outer corners of each stroke. */
EFL_GFX_JOIN_BEVEL, /**< Used to render mitered line joins. The intersection of the strokes is clipped at a line perpendicular to the bisector of the angle between the strokes, at the distance from the intersection of the segments equal to the product of the miter limit value and the border radius. This prevents long spikes being created. */
EFL_GFX_JOIN_LAST /**< End of enum value */
} Efl_Gfx_Join;
/**
* Type defining gradient stop.
* @since 1.14
*/
typedef struct _Efl_Gfx_Gradient_Stop Efl_Gfx_Gradient_Stop;
struct _Efl_Gfx_Gradient_Stop
{
double offset; /**< The location of the gradient stop within the gradient vector*/
int r; /**< The component R color of the gradient stop */
int g; /**< The component G color of the gradient stop */
int b; /**< The component B color of the graident stop */
int a; /**< The component A color of the graident stop */
};
/**
* Specifies how the area outside the gradient area should be filled.
*
* @see efl_gfx_gradient_spread_set()
*
* @since 1.14
*/
typedef enum _Efl_Gfx_Gradient_Spread
{
EFL_GFX_GRADIENT_SPREAD_PAD, /**< The area is filled with the closest stop color. This is the default. */
EFL_GFX_GRADIENT_SPREAD_REFLECT, /**< The gradient is reflected outside the gradient area. */
EFL_GFX_GRADIENT_SPREAD_REPEAT, /**< The gradient is repeated outside the gradient area. */
EFL_GFX_GRADIENT_SPREAD_LAST /**< End of enum value */
} Efl_Gfx_Gradient_Spread;
/**
* 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 */
@ -44,6 +147,21 @@ extern "C"
#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_base.eo.h"
#include "interfaces/efl_gfx_gradient_linear.eo.h"
#include "interfaces/efl_gfx_gradient_radial.eo.h"
#endif
#if defined ( __cplusplus )

View File

@ -1,6 +1,37 @@
interface Efl.File {
legacy_prefix: null;
properties {
mmap {
set {
/*@
Set the source mmaped file from where an image object must fetch the real
image data (it must be an Eina_File).
If the file supports multiple data stored in it (as Eet files do),
you can specify the key to be used as the index of the image in
this file.
@since 1.8 */
return: bool;
}
get {
/*@
Get the source mmaped file from where an image object must fetch the real
image data (it must be an Eina_File).
If the file supports multiple data stored in it (as Eet files do),
you can get the key to be used as the index of the image in
this file.
@since 1.10 */
}
values {
const(Eina.File)* f; /*@ The mmaped file */
const(char)* key; /*@ The image key in @p file (if its an Eet one), or @c
NULL, otherwise. */
}
}
file {
set {
/*@

View File

@ -0,0 +1,134 @@
interface Efl.Gfx.Base {
legacy_prefix: null;
eo_prefix: efl_gfx;
properties {
position {
set {
/*@ Move the given Evas object to the given location inside its canvas' viewport. */
}
get {
/*@ Retrieves the position of the given Evas object. */
}
values {
int x; /*@ in */
int y; /*@ in */
}
}
size {
set {
/*@ Changes the size of the given Evas object. */
}
get {
/*@ Retrieves the (rectangular) size of the given Evas object. */
}
values {
int w; /*@ in */
int h; /*@ in */
}
}
color {
set {
/*@
Sets the general/main color of the given Evas 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.
@ingroup Evas_Object_Group_Basic */
}
get {
/*@
Retrieves the general/main color of the given Evas object.
Retrieves the “main” 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.
Usually youll 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 All newly created Evas rectangles get the default color
values of <code>255 255 255 255</code> (opaque white).
@note Use @c NULL pointers on the components you're not interested
in: they'll be ignored by the function.
Example:
@dontinclude evas-object-manipulation.c
@skip int alpha, r, g, b;
@until return
See the full @ref Example_Evas_Object_Manipulation "example".
@ingroup Evas_Object_Group_Basic */
}
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. */
}
}
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 youll 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. */
}
get {
/*@ Retrieves whether or not the given Evas object is visible. */
}
values {
bool v; /*@ @c EINA_TRUE if to make the object visible, @c EINA_FALSE otherwise */
}
}
}
}

View File

@ -0,0 +1,72 @@
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. */
}
}
}
}

View File

@ -0,0 +1,38 @@
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 */
}
}
}
}

View File

@ -0,0 +1,38 @@
interface Efl.Gfx.Gradient.Linear (Efl.Gfx.Gradient.Base)
{
legacy_prefix: null;
properties {
start {
set {
/*@
Sets the start point of this linear gradient.
*/
}
get {
/*@
Gets the start point of this linear gradient.
*/
}
values {
double x; /*@ x co-ordinate of start point */
double y; /*@ y co-ordinate of start point */
}
}
end {
set {
/*@
Sets the end point of this linear gradient.
*/
}
get {
/*@
Gets the end point of this linear gradient.
*/
}
values {
double x; /*@ x co-ordinate of end point */
double y; /*@ y co-ordinate of end point */
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More