Makefile
Makefile.in
*.so
-.*.sw[po]
+*.sw[po]
/README
/aclocal.m4
/autom4te.cache/
m4/lt~obsolete.m4
src/bin/evas_cserve
src/bin/evas_cserve_tool
+src/bin/evas_cserve2
+src/bin/evas_cserve2_slave
+src/bin/evas_cserve2_client
+src/bin/dummy_slave
*.gcno
*.gcov
src/tests/evas_suite
/doc/man/
/*-doc.tar.bz2
/*-doc.tar.bz2.cdbs-config_list
+src/examples/aspect.edj
+src/examples/evas-smart-object
+src/examples/evas-stacking
+src/examples/evas_aspect_hints
+src/examples/evas_box
+src/examples/evas_buffer_simple
+src/examples/evas_events
+src/examples/evas_hints
+src/examples/evas_images
+src/examples/evas_images2
+src/examples/evas_images3
+src/examples/evas_init_shutdown
+src/examples/evas_map_utils
+src/examples/evas_object_manipulation
+src/examples/evas_smart_object
+src/examples/evas_stacking
+src/examples/evas_text
+
Jim Kukunas <james.t.kukunas@linux.intel.com>
Nicolas Aguirre <aguirre.nicolas@gmail.com>
Rafal Krypa <r.krypa@samsung.com>
-Yoyoung Chang <hyoyoung@gmail.com>
+Hyoyoung Chang <hyoyoung@gmail.com>
Jérôme Pinot <ngc891@gmail.com>
+Rafael Antognolli <antognolli@profusion.mobi>
+Daniel Zaoui <daniel.zaoui@samsung.com>
2012-01-06 Sung W. Park (sung_)
* Add EvasGL support to software backend using OSMesa. Requires OSMesa
- library. Due to caveats in OSMesa, surface config stays with a
- context rather than with a surface. So for now, the config of a
+ library. Due to caveats in OSMesa, surface config stays with a
+ context rather than with a surface. So for now, the config of a
surface remains with the first context that it binds to. May need
to come up with a different solution in the near future.
2012-01-20 Sung W. Park (sung_)
- * Add Direct Rendering to Evas' window optimization for Evas_GL. This
+ * Add Direct Rendering to Evas' window optimization for Evas_GL. This
optimization can be significant since it avoids and extra copy from
an offscreen buffer. Normally, Evas_GL will render to a render
- target using an FBO. This can be enabled by giving
- EVAS_GL_OPTIONS_DIRECT hint in the config options_bits. Direct
- rendering is actually done if the following conditions are met -
- 1) All GL rendering is done in the pixel_getter callback 2) No
- rotation on the image object 3) Corresponding image
+ target using an FBO. This can be enabled by giving
+ EVAS_GL_OPTIONS_DIRECT hint in the config options_bits. Direct
+ rendering is actually done if the following conditions are met -
+ 1) All GL rendering is done in the pixel_getter callback 2) No
+ rotation on the image object 3) Corresponding image
object has alpha disabled.
2012-01-23 Tom Hacohen (TAsn)
2012-05-30 ChunEon Park (Hermet)
* Fixed to clean up when map actually changed. Now rendering updates will be
+ correct after evas_map acutally disabled/enabled for the smart object.
+
+2012-05-30 Cedric Bail
+
+ * Don't wake up prepare thread if there is nothing to prepare.
+
+2012-05-30 Daniel Zaoui
+
+ * Fix evas_free callback deletion to not sometimes abort evas freeing
+ in some situations, thus leaking.
+
+2012-06-10 Carsten Haitzler (The Rasterman)
+
+ * Fix evas font handling so bitmap fonts work again like they
+ once did. This ifxes max height, and max ascent/descent
+ calculation for 0 em fonts with 0 bbox size (bitmap case), and
+ fixes 1 rounding error in text objects that placed ascent in the wrong
+ place by 1 pixel for even ascents.
+
+2012-06-10 Cedric Bail
+
+ * Limit the updated region to fit in CPU cache for Pipe rendering.
+
+2012-06-12 ChunEon Park (Hermet)
+
+ * Fixed simple line drawing on s/w backened. Unmatched loop scope caused the
+ destination buffer pointer march in place.
+
+2012-06-12 ChunEon Park (Hermet)
+
+ * Removed empty evas_object_map_source_set/get APIs. Will Not be implemented.
+
+2012-06-13 Mike Blumenkrantz
+
+ * Fix crash in evas_object_image_add() when called prior to setting an engine
+ for the given canvas.
+
+2012-06-14 Cedric Bail
+
+ * Cache convertion from Evas_Map to RGBA_Map.
+
+2012-06-15 Vincent Torri
+
+ * Add Textgrid object.
+
+2012-06-15 Mike Blumenkrantz
+
+ * evas_object_smart_members_get() now returns NULL on non-smart objects
+
+2012-04-26 Carsten Haitzler (The Rasterman)
+
+ * Fix GL engine bitmap font handling
+
+2012-06-19 Vincent Torri
+
+ * Remove uselesss software DirectDraw 16 bits engine
2012-06-27 Sung W. Park (sung_)
or context is NULL. Before, when that was the case, it just did
make_current(NULL, NULL) internally.
+2012-04-28 Carsten Haitzler (The Rasterman)
+
+ * Fix font instance refcounting for textprops that hang around.
+
+2012-06-29 Jiyoun Park
+
+ * upstream merge
+ * Merge remote-tracking branch 'remotes/origin/upstream'
+
+2012-07-03 Christopher Michael
+
+ * Merge Tizen changes to upstream EFL.
+ * Support gif scaling in evas gif loader.
+ * Create vertex & fragment shader(s) in the gl_common engine.
+ * Don't call glGetTexLevelParameteriv unless it is supported.
+ * Support evas_cserve2 in the wayland_shm engine.
+ * When freeing a gl_x11 window, make sure to call eglMakeCurrent with a null surface
+ to inform EGL that this window is no longer valid.
+
+2012-07-04 Cedric Bail
+
+ * Make pipeline rendering use more extensively the prepare stage.
+
+2012-07-04 Gustavo Lima Chaves
+
+ * Add simple interfaces support to Evas smart classes
+
+2012-07-05 ChunEon Park(Hermet)
+
+ * Fixed Map pipe region issue. It caused the incorrect object rendering order
+ on gl backened.
+
+2012-07-05 Cedric Bail
+
+ * Strongly disable Evas pipe rendering.
+
+2012-07-05 Cedric Bail
+
+ * Don't let bad map sneek at render time and ban them as early as possible.
+
+2012-07-07 ChunEon Park(Hermet)
+
+ * Let Draw Text with viewport size instead of window size. When map is enabled then it should be rendered completely.
+
+2012-07-11 Tom Hacohen (TAsn)
+
+ * Fixed runtime emboldenment with bitmap fonts.
+
+2012-07-16 Hermet (ChunEon Park)
+
+ * Fixed to do pre render for the children of mapped object.
+
+2012-07-17 Cedric Bail
+
+ * Fix garbage left by mapped smart object when they fly away from the canvas.
+ * Fix map life cycle.
+
+2012-07-18 Carsten Haitzler (The Rasterman)
+
+ * Fix evas box to not skip dealing with size hint changes
+ while it lays out objects. This breaks elementary badly and it should
+ never have done this. This broke the general logic of size
+ hint handling.
+
2012-07-19 Jiyoun Park(jypark)
- * Fix jpeg save bug related with error handler
+ * Fix jpeg save bug related with error handler
2012-07-22 Cedric Bail
* Keep track of inactive proxied object change so we always update the proxy correctly.
+2012-08-01 Jiyoun Park(jypark)
+
+ * Fix gif load bug. we initialize first frame buffer of gif loader
* Don't crash when calling evas_object_smart_type_check without type.
* Handle proxy with the right context.
* Force proxied object to stay active to keep track of change in them.
- * Fix evas_gl's internal resource surface bug when evas' window is deleted/recreated.
Removal:
* Remove EVAS_FRAME_QUEUING, EVAS_SLI, METRIC_CACHE and WORD_CACHE.
liblinebreak
Optional:
- XCB SDL OpenGL librsvg libtiff libgif edb DirectFB evas_generic_loaders
+ XCB SDL OpenGL esvg/librsvg libtiff libgif edb DirectFB evas_generic_loaders
Evas is a clean display canvas API for several target display systems
that can draw anti-aliased text, smooth super and sub-sampled scaled
disables it, some being enabled or disabled by default or if
dependencies are found):
+Also the wayland support (EGL and SHM engines) is considered experimental as
+wayland itself is still unstable and liable to change core protocol.
+If you use this api, it is possible it will break in future, until this
+notice is removed.
------------------------------------------------------------------------------
SCALING:
--enable-image-loader-svg[=static]
-this loader can load svg files via librsvg (thus it is a dependency).
-this loader supports load options to set the dpi to decode the svg at
-etc. which can then be used to create scalable images that scale to
-any size without becoming blocky or blurry, if the source is an svg
-file.
+this loader can load svg files via esvg or librsvg (thus it is a
+dependency). This loader supports load options to set the dpi to
+decode the svg at etc. which can then be used to create scalable
+images that scale to any size without becoming blocky or blurry, if
+the source is an svg file.
+
+Esvg can be found here:
+
+http://code.google.com/p/enesim/
+
+Install (in that order):
+
+enesim
+emage
+etex
+ender
+etch
+egueb
--enable-image-loader-tiff[=static]
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_maj], [1])
m4_define([v_min], [2])
-m4_define([v_mic], [0])
+m4_define([v_mic], [99])
m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n']))
m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))])
##-- When released, remove the dnl on the below line
-m4_undefine([v_rev])
+dnl m4_undefine([v_rev])
##-- When doing snapshots - change soname. remove dnl on below line
dnl m4_define([relname], [ver-pre-svn-07])
dnl m4_define([v_rel], [-release relname])
AC_LANG_POP([Objective C])])], [rw_cv_prog_objc_works=no])
])
-AC_INIT([evas], [v_ver]-beta, [enlightenment-devel@lists.sourceforge.net])
+AC_INIT([evas], [v_ver], [enlightenment-devel@lists.sourceforge.net])
AC_PREREQ([2.52])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])
want_harfbuzz="auto"
want_pixman="no"
want_evas_cserve="yes"
+want_evas_cserve2="yes"
want_evas_engine_buffer="yes"
want_evas_engine_software_xlib="no"
AC_MSG_CHECKING(whether to build shared cache server and support)
AC_MSG_RESULT(${want_evas_cserve})
+# (shm_open (for cache server)
+AC_ARG_ENABLE([evas-cserve2],
+ AC_HELP_STRING([--disable-evas-cserve2],
+ [disable shared cache server 2 support. @<:@default=enabled@:>@]),
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_evas_cserve2="yes"
+ else
+ want_evas_cserve2="no"
+ fi
+ ])
+AC_MSG_CHECKING(whether to build shared cache server 2 and support)
+AC_MSG_RESULT(${want_evas_cserve2})
+
+# cserve2 only works on Linux so far.
+if test "x${want_evas_cserve2}" = "xyes" ; then
+ AC_CHECK_HEADERS(
+ [sys/epoll.h sys/inotify.h sys/signalfd.h],
+ [],
+ [
+ want_evas_cserve2="no"
+ ]
+ )
+fi
+
+if test "x${want_evas_cserve2}" = "xyes"; then
+ want_evas_cserve="no"
+fi
+
shm_open_libs=""
-if test "x${want_evas_cserve}" = "xyes" ; then
+if test "x${want_evas_cserve}" = "xyes" -o "x${want_evas_cserve2}" = "xyes" ; then
EFL_CHECK_SHM_OPEN(
[
- want_evas_cserve="yes"
shm_open_libs=${EFL_SHM_OPEN_LIBS}
],
- [want_evas_cserve="no"])
+ [
+ want_evas_cserve="no"
+ want_evas_cserve2="no"
+ ])
fi
AC_SUBST([shm_open_libs])
AM_CONDITIONAL([EVAS_CSERVE], [test "x${want_evas_cserve}" = "xyes"])
+if test "x${want_evas_cserve2}" = "xyes" ; then
+ AC_DEFINE(EVAS_CSERVE2, 1, [Shared cache server.])
+fi
+
+AM_CONDITIONAL([EVAS_CSERVE2], [test "x${want_evas_cserve2}" = "xyes"])
+
#######################################
doc/Doxyfile
src/Makefile
src/bin/Makefile
+src/bin/loaders/Makefile
+src/bin/loaders/jpeg/Makefile
+src/bin/loaders/png/Makefile
+src/bin/loaders/eet/Makefile
+src/bin/loaders/tiff/Makefile
+src/bin/loaders/xpm/Makefile
+src/bin/loaders/bmp/Makefile
+src/bin/loaders/ico/Makefile
+src/bin/loaders/tga/Makefile
+src/bin/loaders/pmaps/Makefile
+src/bin/loaders/wbmp/Makefile
+src/bin/loaders/psd/Makefile
src/lib/Makefile
src/lib/canvas/Makefile
src/lib/file/Makefile
src/lib/cache/Makefile
+src/lib/cache2/Makefile
src/lib/cserve/Makefile
+src/lib/cserve2/Makefile
src/lib/engines/Makefile
src/lib/engines/common/Makefile
src/lib/engines/common/evas_op_add/Makefile
echo "Features:"
echo " MAGIC_DEBUG.............: $want_evas_magic_debug"
echo " Cache Server............: $want_evas_cserve"
+echo " Cache Server 2..........: $want_evas_cserve2"
echo
dnl
dnl ... DISABLED! some testing has shown that this seems to have some
$(srcdir)/e.css \
$(srcdir)/head.html \
$(srcdir)/foot.html \
- $(srcdir)/evas.dox.in
+ $(srcdir)/evas.dox.in \
+ $(srcdir)/examples.dox
* those switches until you get the idea of evas_object_fill_set().
*
* The 'f' command will toggle that image's "filled" property, which
- * is wheter it should track its size and set the fill one to fit the
+ * is whether it should track its size and set the fill one to fit the
* object's boundaries perfectly (stretching). Note that this command
* and the four above it will conflict: in real usage one would use
* one or other ways of setting an image object's viewport with regard
*
* While you have the border in 'blending mode', test the command 'm':
* it will set whether to use or not smooth scaling on the border's
- * source image. Since the image is small originallly (30 x 30), we're
+ * source image. Since the image is small originally (30 x 30), we're
* obviously up-scaling it (except the border pixels, do you
* remember?). With this last switch, you'll either see the
* transparent shape in the middle flat (no smoothing) or blurry
* @skip bg = evas_object_rectangle_add
* @until focus_set
*
- * Still exempliflying events and callbacks, we register a callback on
+ * Still exemplifying events and callbacks, we register a callback on
* the canvas event of an object being focused:
* @dontinclude evas-events.c
* @skip add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS
* different layout on the box object.
*
* The initial layout the box starts at is the one triggered by the
- * key @c '1' -- the horizontal layout. Thus, the initial appearence
+ * key @c '1' -- the horizontal layout. Thus, the initial appearance
* of this program, demonstrating this layout, is something like:
*
* @image html evas-box-example-00.png
* @image rtf evas-stacking-example-04.png
* @image latex evas-stacking-example-04.eps
* Like said above, we have two layers used at the beginning of the
- * example: the default one (0) and the one imeddiately below it (-1),
+ * example: the default one (0) and the one immediately below it (-1),
* for the white background. Let's change this setup by issuing the
* 'l' command, which will change the background's layer to 1, i.e., a
* layer @b above the one holding the other rectangles:
*
* The full code can be found @ref evas-map-utils.c "here".
*
- * To show how some funtions work, this example listens to keys pressed to
+ * To show how some functions work, this example listens to keys pressed to
* toggle several options.
* @skip typedef
* @until App_Data
* set a color for each vertex or apply one for all of them at once
* @until evas_map_util_points_color_set
*
- * For the first object, we'll have a plain rectangle. At its cration, this
+ * For the first object, we'll have a plain rectangle. At its creation, this
* rectangle was set to be semi-transparent, but whether its own alpha is
* used will be defined by the map's alpha setting. If the map's alpha is
* disabled, then the object will be completely opaque. The map's own color,
* @skip add a new example smart object to a canvas
* @until }
*
- * Smart objects are define by <b>smart classes</b>, which are structs
+ * Smart objects are defined by <b>smart classes</b>, which are structs
* defining their interfaces, or <b>smart functions</b> (see
* #Evas_Smart_Class, the base class for any smart object). As you
* see, one has to use the evas_object_smart_add() function to
* built-in smart object, the "clipped smart object", which implements
* a behavior mostly desired by many other smart object implementors:
* it will clip its children to its area and move them along with it,
- * on evas_object_resize() calls. Then, our example smart object will
+ * on evas_object_move() calls. Then, our example smart object will
* get that behavior for free.
*
* The first argument to the macro,
* mentioned function. Note how to tell Evas the border will be
* managed by our smart object from that time on:
* <code>evas_object_smart_member_add(priv->border, o);</code>.
- * The counterpart of this function is exemplifyed on the smart
+ * The counterpart of this function is exemplified on the smart
* object's interface function to remove children:
* @skip remove a child element
* @until set to
* @until "no"
* The evas_object_smart_type_check() one will assure we have the
* string naming our smart class really set to the live object. The
- * evas_object_smart_clipped_clipper_get() exemplifyes usage of
+ * evas_object_smart_clipped_clipper_get() exemplifies usage of
* "static clippers" -- clipped smart objects have their global
* clippers flagged static.
*
*
* Then, we set the text string itself, on it, with
* evas_object_text_text_set(). We set an explicit size of 30 points
- * for our font, as you could see, what we check back with the the
+ * for our font, as you could see, what we check back with the
* getter evas_object_text_font_get().
*
* Look at how it translates to code:
@pkgconfig_requires_private@: @requirement_evas@
Version: @VERSION@
Libs: -L${libdir} -levas @EINA_LIBS@ @shm_open_libs@
-Libs.private: @EFL_FNMATCH_LIBS@ @pthread_libs@
-Cflags: -I${includedir}/evas-@VMAJ@ @EINA_CFLAGS@
+Libs.private: @EFL_FNMATCH_LIBS@ @pthread_libs@ @shm_open_libs@
+Cflags: -I${includedir}/evas-@VMAJ@
[
requirement=""
-have_dep="no"
+have_esvg="no"
evas_image_loader_[]$1[]_cflags=""
evas_image_loader_[]$1[]_libs=""
-PKG_CHECK_MODULES([SVG], [librsvg-2.0 >= 2.14.0
- cairo >= 1.0.0],
- [have_dep="yes" requirement="librsvg-2.0 cairo"],
- [have_svg="no"]
-)
+PKG_CHECK_MODULES([SVG],
+ [esvg >= 0.0.16],
+ [have_dep="yes" have_esvg="yes" requirement="esvg"],
+ [have_dep="no"])
if test "x${have_dep}" = "xyes" ; then
evas_image_loader_[]$1[]_cflags="${SVG_CFLAGS}"
#sbs-git:slp/pkgs/e/evas evas 1.1.0+svn.69113slp2+build01 828d8bb285397266eb8985fd081fa2692fa3a7d6
Name: evas
Summary: Multi-platform Canvas Library
-Version: 1.2.0+svn.70433slp2+build18
+Version: 1.2.0+svn.72376slp2+build01
Release: 1
Group: System/Libraries
License: BSD
%{_libdir}/evas/modules/engines/*/*/module.so
%{_libdir}/evas/modules/loaders/*/*/module.so
%{_libdir}/evas/modules/savers/*/*/module.so
-%{_bindir}/evas_cserve
-%{_bindir}/evas_cserve_tool
-
+%{_libdir}/evas/cserve2/loaders/*/*/module.so
+%{_bindir}/evas_cserve2_client
+%{_libexecdir}/evas_cserve2
+%{_libexecdir}/evas_cserve2_slave
+%{_libexecdir}/dummy_slave
%files devel
%defattr(-,root,root,-)
@EINA_LIBS@
endif
+
+if EVAS_CSERVE2
+
+SUBDIRS = loaders
+
+libexec_PROGRAMS = evas_cserve2 evas_cserve2_slave dummy_slave
+bin_PROGRAMS = evas_cserve2_client
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_LIBEXEC_DIR=\"$(libexecdir)\" \
+@FREETYPE_CFLAGS@ \
+@EINA_CFLAGS@
+
+evas_cserve2_SOURCES = \
+evas_cserve2.h \
+evas_cserve2_slave.h \
+evas_cserve2_main.c \
+evas_cserve2_slaves.c \
+evas_cserve2_messages.c \
+evas_cserve2_shm.c \
+evas_cserve2_cache.c \
+evas_cserve2_requests.c \
+evas_cserve2_fonts.c \
+evas_cserve2_main_loop_linux.c
+
+evas_cserve2_LDADD = \
+@FREETYPE_LIBS@ \
+@EINA_LIBS@ \
+@EFL_SHM_OPEN_LIBS@
+
+evas_cserve2_client_SOURCES = \
+evas_cserve2_client.c
+
+evas_cserve2_slave_SOURCES = \
+evas_cserve2_slave.c \
+evas_cserve2_utils.c
+
+evas_cserve2_slave_LDFLAGS = -export-dynamic
+
+evas_cserve2_slave_LDADD = \
+@EINA_LIBS@ \
+@EFL_SHM_OPEN_LIBS@
+
+dummy_slave_SOURCES = \
+dummy_slave.c
+
+dummy_slave_LDADD = \
+@EINA_LIBS@ \
+@EFL_SHM_OPEN_LIBS@
+
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "evas_cserve2.h"
+
+static Eina_Bool
+command_read(int fd, Slave_Command *cmd, void **params)
+{
+ ssize_t ret;
+ int ints[2], size, got = 0;
+ char *buf;
+
+ ret = read(fd, ints, sizeof(int) * 2);
+ if (ret < (int)sizeof(int) * 2)
+ return EINA_FALSE;
+
+ size = ints[0];
+ buf = malloc(size);
+ if (!buf) return EINA_FALSE;
+
+ do {
+ ret = read(fd, buf + got, size - got);
+ if (ret < 0)
+ {
+ /* EINTR means we were interrupted by a signal before anything
+ * was sent, and if we are back here it means that signal was
+ * not meant for us to die. Any other error here is fatal and
+ * should result in the slave terminating.
+ */
+ if (errno == EINTR)
+ continue;
+ free(buf);
+ return EINA_FALSE;
+ }
+ got += ret;
+ } while (got < size);
+
+ *cmd = ints[1];
+ *params = buf;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+response_send(int fd, Slave_Command cmd, void *resp, int size)
+{
+ int sent = 0, ints[2];
+ const char *data = resp;
+ ssize_t ret;
+
+ ints[0] = size;
+ ints[1] = cmd;
+ ret = write(fd, ints, sizeof(int) * 2);
+ if (ret < 0)
+ return EINA_FALSE;
+ if (!size)
+ return EINA_TRUE;
+ do {
+ ret = write(fd, data + sent, size - sent);
+ if (ret < 0)
+ {
+ /* EINTR means we were interrupted by a signal before anything
+ * was sent, and if we are back here it means that signal was
+ * not meant for us to die. Any other error here is fatal and
+ * should result in the slave terminating.
+ */
+ if (errno == EINTR)
+ continue;
+ return EINA_FALSE;
+ }
+ sent += ret;
+ } while (sent < size);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+error_send(int fd, Error_Type err)
+{
+ return response_send(fd, ERROR, &err, sizeof(Error_Type));
+}
+
+void *
+cserve2_shm_map(const char *name, size_t length, off_t offset)
+{
+ void *map;
+ int fd;
+
+ fd = shm_open(name, O_RDWR, 0);
+ if (fd == -1)
+ return MAP_FAILED;
+
+ map = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, offset);
+
+ close(fd);
+
+ return map;
+}
+
+void
+cserve2_shm_unmap(void *map, size_t length)
+{
+ munmap(map, length);
+}
+
+static Error_Type
+image_open(const char *file __UNUSED__, const char *key __UNUSED__, Slave_Msg_Image_Opened *result)
+{
+ memset(result, 0, sizeof(*result));
+ result->w = 32;
+ result->h = 32;
+ result->frame_count = 1;
+ result->loop_count = 0;
+ result->loop_hint = 0;
+ result->alpha = EINA_TRUE;
+ return CSERVE2_NONE;
+}
+
+static Error_Type
+image_load(const char *shmfile, Slave_Msg_Image_Load *params)
+{
+ char *map = cserve2_shm_map(shmfile, params->shm.mmap_size,
+ params->shm.mmap_offset);
+ if (map == MAP_FAILED)
+ return CSERVE2_RESOURCE_ALLOCATION_FAILED;
+
+ memset(map + params->shm.image_offset, 'A', params->shm.image_size);
+
+ return CSERVE2_NONE;
+}
+
+int main(int c, char **v)
+{
+ int wfd, rfd;
+ Slave_Command cmd;
+ void *params = NULL;;
+ Eina_Bool quit = EINA_FALSE;
+
+ if (c < 3)
+ return 1;
+
+ wfd = atoi(v[1]);
+ rfd = atoi(v[2]);
+
+ while (!quit)
+ {
+ if (!command_read(rfd, &cmd, ¶ms))
+ {
+ error_send(wfd, CSERVE2_INVALID_COMMAND);
+ continue;
+ }
+
+ switch (cmd)
+ {
+ case IMAGE_OPEN:
+ {
+ Slave_Msg_Image_Opened result;
+ Slave_Msg_Image_Open *p;
+ Error_Type err;
+ const char *file, *key;
+ p = params;
+ file = (const char *)(p + sizeof(*p));
+ key = file + strlen(file) + 1;
+ if ((err = image_open(file, key, &result)) != CSERVE2_NONE)
+ error_send(wfd, err);
+ else
+ response_send(wfd, IMAGE_OPEN, &result,
+ sizeof(Slave_Msg_Image_Opened));
+ break;
+ }
+ case IMAGE_LOAD:
+ {
+ Slave_Msg_Image_Load *load_args = params;
+ Error_Type err;
+ const char *shmfile = ((const char *)params) +
+ sizeof(Slave_Msg_Image_Load);
+ if ((err = image_load(shmfile, load_args)) != CSERVE2_NONE)
+ error_send(wfd, err);
+ else
+ response_send(wfd, IMAGE_LOAD, NULL, 0);
+ break;
+ }
+ case SLAVE_QUIT:
+ {
+ quit = EINA_TRUE;
+ break;
+ }
+
+ default:
+ error_send(wfd, CSERVE2_INVALID_COMMAND);
+ }
+ free(params);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef _EVAS_CSERVE2_H
+#define _EVAS_CSERVE2_H
+
+#include <Eina.h>
+#include "evas_cs2.h"
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_bin_log_dom, __VA_ARGS__)
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_bin_log_dom, __VA_ARGS__)
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_bin_log_dom, __VA_ARGS__)
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_bin_log_dom, __VA_ARGS__)
+
+extern int _evas_cserve2_bin_log_dom;
+
+typedef struct _Slave Slave;
+typedef struct _Slave_Thread_Data Slave_Thread_Data;
+typedef struct _Shm_Handle Shm_Handle;
+
+typedef enum {
+ FD_READ = 1,
+ FD_WRITE = 2,
+ FD_ERROR = 4
+} Fd_Flags;
+
+struct _Client {
+ unsigned int id;
+ int socket;
+ struct {
+ Eina_Bool reading;
+ char *buf; // buffer of data being read
+ int done, size;
+ Eina_Binbuf *pending; // pending data to send
+ } msg;
+ struct {
+ Eina_Hash *referencing; // indexed by client file id
+ } files;
+ struct {
+ Eina_Hash *referencing; // indexed by client image id
+ } images;
+ struct {
+ Eina_List *referencing;
+ } fonts;
+};
+
+typedef struct _Client Client;
+
+struct _Image_Load_Opts {
+ unsigned int w, h;
+ unsigned int rx, ry, rw, rh;
+ unsigned int scale_down_by;
+ double dpi;
+ Eina_Bool orientation;
+};
+
+typedef struct _Image_Load_Opts Image_Load_Opts;
+
+typedef enum {
+ IMAGE_OPEN,
+ IMAGE_LOAD,
+ FONT_LOAD,
+ FONT_GLYPHS_LOAD,
+ SLAVE_QUIT,
+ ERROR
+} Slave_Command;
+
+struct _Slave_Msg_Image_Open {
+ Eina_Bool has_opts : 1;
+ Eina_Bool has_loader_data : 1;
+};
+
+struct _Slave_Msg_Image_Opened {
+ int w, h;
+ int degree;
+ int scale; /* used by jpeg when loading in smaller sizes */
+ int frame_count;
+ int loop_count;
+ int loop_hint; /* include Evas.h? Copy the enum around? */
+ Eina_Bool alpha : 1;
+ Eina_Bool animated : 1;
+ Eina_Bool rotated : 1;
+
+ Eina_Bool has_loader_data : 1;
+};
+
+struct _Slave_Msg_Image_Load {
+ int w, h;
+ Image_Load_Opts opts;
+ struct {
+ int mmap_offset;
+ int image_offset;
+ int mmap_size;
+ int image_size;
+ } shm;
+ Eina_Bool alpha : 1;
+ Eina_Bool has_loader_data : 1;
+};
+
+struct _Slave_Msg_Image_Loaded {
+ Eina_Bool alpha_sparse : 1;
+};
+
+typedef struct _Slave_Msg_Image_Open Slave_Msg_Image_Open;
+typedef struct _Slave_Msg_Image_Opened Slave_Msg_Image_Opened;
+typedef struct _Slave_Msg_Image_Load Slave_Msg_Image_Load;
+typedef struct _Slave_Msg_Image_Loaded Slave_Msg_Image_Loaded;
+
+struct _Slave_Msg_Font_Load {
+ void *ftdata1; // Freetype file source info comes here
+ void *ftdata2; // Freetype font info comes here
+ unsigned int rend_flags;
+ unsigned int hint;
+ unsigned int size;
+ unsigned int dpi;
+ const char *name;
+ const char *file;
+};
+
+struct _Slave_Msg_Font_Loaded {
+ void *ftdata1;
+ void *ftdata2;
+};
+
+typedef struct _Slave_Msg_Font_Load Slave_Msg_Font_Load;
+typedef struct _Slave_Msg_Font_Loaded Slave_Msg_Font_Loaded;
+
+typedef void *(*Font_Request_Msg_Create)(void *data, int *size);
+typedef void (*Font_Request_Msg_Free)(void *data);
+typedef void (*Font_Request_Response)(Client *c, void *data, void *resp, unsigned int rid);
+typedef void (*Font_Request_Error)(Client *c, void *data, Error_Type error, unsigned int rid);
+
+struct _Font_Request_Funcs {
+ Font_Request_Msg_Create msg_create;
+ Font_Request_Msg_Free msg_free;
+ Font_Request_Response response;
+ Font_Request_Error error;
+};
+
+typedef struct _Font_Request Font_Request;
+typedef struct _Font_Request_Funcs Font_Request_Funcs;
+
+typedef enum {
+ FONT_REND_REGULAR = 1,
+ FONT_REND_SLANT = 1 << 1,
+ FONT_REND_WEIGHT = 1 << 2
+} Font_Rend_Flags;
+
+typedef enum {
+ CSERVE2_REQ_FONT_LOAD = 0,
+ CSERVE2_REQ_FONT_GLYPHS_LOAD,
+ CSERVE2_REQ_LAST
+} Font_Request_Type;
+
+typedef void (*Fd_Watch_Cb)(int fd, Fd_Flags flags, void *data);
+typedef void (*Timeout_Cb)(void); /* void* for compat? */
+typedef void (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? */
+typedef void (*Slave_Dead_Cb)(Slave *slave, void *data);
+typedef void (*Slave_Read_Cb)(Slave *slave, Slave_Command cmd, void *msg, void *data);
+typedef void *(*Slave_Thread_Cb)(Slave_Thread_Data *sd, Slave_Command *cmd, const void *cmddata, void *userdata);
+typedef void (*File_Change_Cb)(const char *path, Eina_Bool deleted, void *data);
+
+void cserve2_client_accept(int fd);
+ssize_t cserve2_client_read(Client *client, void *buf, size_t len);
+ssize_t cserve2_client_write(Client *client, const void *buf, size_t len);
+void cserve2_client_del(Client *client);
+void cserve2_client_deliver(Client *client);
+void cserve2_client_error_send(Client *client, unsigned int rid, int error_code);
+ssize_t cserve2_client_send(Client *client, const void *data, size_t size);
+
+Eina_Bool cserve2_fd_watch_add(int fd, Fd_Flags flags, Fd_Watch_Cb cb, const void *data);
+Eina_Bool cserve2_fd_watch_del(int fd);
+Eina_Bool cserve2_fd_watch_flags_set(int fd, Fd_Flags flags);
+Eina_Bool cserve2_fd_watch_flags_get(int fd, Fd_Flags *flags);
+
+Eina_Bool cserve2_file_change_watch_add(const char *path, File_Change_Cb cb, const void *data);
+Eina_Bool cserve2_file_change_watch_del(const char *path);
+
+void cserve2_on_child_dead_set(Main_Loop_Child_Dead_Cb cb);
+
+void cserve2_timeout_cb_set(int t, Timeout_Cb cb);
+
+Eina_Bool cserve2_main_loop_setup(void);
+void cserve2_main_loop_run(void);
+void cserve2_main_loop_finish(void);
+
+Eina_Bool cserve2_slaves_init(void);
+void cserve2_slaves_shutdown(void);
+int cserve2_slave_available_get(void);
+Eina_Bool cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, int size);
+Slave *cserve2_slave_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data);
+Slave *cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data);
+void cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size);
+void cserve2_slave_kill(Slave *s);
+
+void cserve2_message_handler(int fd, Fd_Flags flags, void *data);
+
+Shm_Handle *cserve2_shm_request(size_t size);
+void cserve2_shm_unref(Shm_Handle *shm);
+const char *cserve2_shm_name_get(const Shm_Handle *shm);
+off_t cserve2_shm_map_offset_get(const Shm_Handle *shm);
+off_t cserve2_shm_offset_get(const Shm_Handle *shm);
+size_t cserve2_shm_map_size_get(const Shm_Handle *shm);
+size_t cserve2_shm_size_get(const Shm_Handle *shm);
+
+void cserve2_command_run(Client *client, Message_Type type);
+
+void cserve2_cache_init(void);
+void cserve2_cache_shutdown(void);
+void cserve2_cache_client_new(Client *client);
+void cserve2_cache_client_del(Client *client);
+int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
+void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
+int cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg);
+void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid);
+void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
+void cserve2_cache_image_unload(Client *client, unsigned int client_image_id);
+
+int cserve2_cache_font_load(Client *client, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int hint, unsigned int size, unsigned int dpi, unsigned int rid);
+
+
+Font_Request *cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs, void *data);
+void cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err);
+void cserve2_request_cancel_all(Font_Request *req, Error_Type err);
+void cserve2_requests_init(void);
+void cserve2_requests_shutdown(void);
+
+void cserve2_cache_requests_process(void);
+void cserve2_cache_requests_response(Slave_Command type, void *msg, void *data);
+
+void cserve2_font_init(void);
+void cserve2_font_shutdown(void);
+void *cserve2_font_slave_cb(Slave_Thread_Data *sd, Slave_Command *cmd, const void *cmddata, void *data);
+
+#endif /* _EVAS_CSERVE2_H */
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "evas_cserve2.h"
+
+typedef struct _Request_Funcs Request_Funcs;
+typedef struct _Request Request;
+
+typedef struct _Entry Entry;
+typedef struct _Reference Reference;
+typedef struct _Waiter Waiter;
+typedef struct _File_Data File_Data;
+typedef struct _Image_Data Image_Data;
+typedef struct _File_Watch File_Watch;
+
+typedef struct _Font_Source Font_Source;
+typedef struct _Font_Entry Font_Entry;
+typedef struct _Font_Cache Font_Cache;
+typedef struct _Glyph_Entry Glyph_Entry;
+
+typedef void *(*Request_Msg_Create)(Entry *e, int *size);
+typedef void (*Request_Response)(Entry *e, void *resp);
+typedef void (*Request_Error)(Entry *e, Error_Type error);
+
+struct _Request_Funcs {
+ Request_Msg_Create msg_create;
+ Request_Response response;
+ Request_Error error;
+};
+
+struct _Request {
+ Entry *entry;
+ Eina_List *waiters;
+ Eina_Bool processing;
+ Request_Funcs *funcs;
+};
+
+typedef enum {
+ CSERVE2_IMAGE_FILE,
+ CSERVE2_IMAGE_DATA,
+ CSERVE2_FONT_ENTRY
+} Entry_Type;
+
+struct _Entry {
+ unsigned int id;
+ Eina_List *references;
+ Request *request;
+ Entry_Type type;
+};
+
+struct _File_Data {
+ Entry base;
+ char *path;
+ char *key;
+ int w, h;
+ int frame_count;
+ int loop_count;
+ int loop_hint;
+ const char *loader_data;
+ File_Watch *watcher;
+ Eina_List *images;
+ Eina_Bool alpha : 1;
+ Eina_Bool invalid : 1;
+};
+
+// Default values for load options commented below
+struct _Image_Data {
+ Entry base;
+ unsigned int file_id;
+ File_Data *file;
+ struct {
+ double dpi; // dpi < -1
+ int w, h; // w and h < -1
+ int scale_down; // scale_down < -1
+ int rx, ry, rw, rh; // rx, ry, rw, rh < -1
+ Eina_Bool orientation; // orientation == 0
+ } opts;
+ Shm_Handle *shm;
+ Eina_Bool alpha_sparse : 1;
+ Eina_Bool unused : 1;
+ Eina_Bool doload : 1;
+};
+
+struct _Font_Source {
+ const char *name;
+ const char *file;
+ int references;
+ void *ft;
+};
+
+struct _Font_Entry {
+ Entry base;
+ Font_Request *request;
+ unsigned int rend_flags;
+ unsigned int hint;
+ unsigned int size;
+ unsigned int dpi;
+ Font_Source *src;
+ void *ft;
+};
+
+struct _Font_Cache {
+ Font_Entry *fe;
+ struct {
+ const char *name;
+ void *data;
+ unsigned int size;
+ unsigned int usage;
+ } shm;
+ Eina_Inlist *glyphs;
+};
+
+struct _Glyph_Entry {
+ EINA_INLIST;
+ Font_Entry *fe;
+ Font_Cache *fi;
+ unsigned int index;
+ unsigned int offset;
+};
+
+struct _Reference {
+ Client *client;
+ Entry *entry;
+ unsigned int client_entry_id; // for reverse lookup
+ int count;
+};
+
+struct _Waiter {
+ Reference *ref;
+ unsigned int rid;
+ Message_Type type;
+};
+
+struct _File_Watch {
+ const char *path;
+ Eina_List *entries;
+};
+
+static Eina_List *open_requests = NULL;
+static Eina_List *load_requests = NULL;
+static Eina_List *spload_requests = NULL; // speculative preload requests
+
+static unsigned int _file_id = 0; // id unique number
+static unsigned int _image_id = 0; // id unique number
+static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
+static Eina_Hash *file_entries = NULL; // maps file_id --> entry
+
+static Eina_Hash *image_ids = NULL; // maps file id + load opts --> image id
+static Eina_Hash *image_entries = NULL; // maps image_id --> entry
+
+static Eina_Hash *font_sources = NULL; // font path --> font source
+static Eina_Hash *font_entries = NULL; // maps font path + options --> entry
+
+static Eina_Hash *file_watch = NULL;
+
+static Eina_List *image_entries_lru = NULL;
+
+static int max_unused_mem_usage = 5 * 1024; /* in kbytes */
+static int unused_mem_usage = 0;
+
+static void
+_image_opened_send(Client *client, File_Data *entry, unsigned int rid)
+{
+ int size;
+ Msg_Opened msg;
+
+ DBG("Sending OPENED reply for entry: %d and RID: %d.", entry->base.id, rid);
+ // clear the struct with possible paddings, since it is not aligned.
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_OPENED;
+ msg.image.w = entry->w;
+ msg.image.h = entry->h;
+ msg.image.frame_count = entry->frame_count;
+ msg.image.loop_count = entry->loop_count;
+ msg.image.loop_hint = entry->loop_hint;
+ msg.image.alpha = entry->alpha;
+
+ size = sizeof(msg);
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, &msg, sizeof(msg));
+ // _cserve2_cache_load_requests_process();
+}
+
+static void
+_image_loaded_send(Client *client, Image_Data *entry, unsigned int rid)
+{
+ int size;
+ const char *shmpath = cserve2_shm_name_get(entry->shm);
+ Msg_Loaded msg;
+ int path_len;
+ char *buf;
+
+ DBG("Sending LOADED reply for entry %d and RID: %d.", entry->base.id, rid);
+ path_len = strlen(shmpath) + 1;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_LOADED;
+
+ msg.shm.mmap_offset = cserve2_shm_map_offset_get(entry->shm);
+ msg.shm.use_offset = cserve2_shm_offset_get(entry->shm);
+ msg.shm.mmap_size = cserve2_shm_map_size_get(entry->shm);
+ msg.shm.image_size = cserve2_shm_size_get(entry->shm);
+ msg.alpha_sparse = entry->alpha_sparse;
+
+ buf = malloc(sizeof(msg) + path_len);
+
+ memcpy(buf, &msg, sizeof(msg));
+ memcpy(buf + sizeof(msg), shmpath, path_len);
+
+ size = sizeof(msg) + path_len;
+
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, buf, size);
+
+ free(buf);
+}
+
+static void
+_image_preloaded_send(Client *client, unsigned int rid)
+{
+ int size;
+ Msg_Preloaded msg;
+
+ DBG("Sending PRELOADED reply for RID: %d.", rid);
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_PRELOADED;
+
+ size = sizeof(msg);
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, &msg, size);
+}
+
+static void
+_font_loaded_send(Client *client, Font_Entry *fe __UNUSED__, unsigned int rid)
+{
+ int size;
+ Msg_Font_Loaded msg;
+
+ DBG("Sending FONT_LOADED reply for RID: %d.", rid);
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_FONT_LOADED;
+
+ size = sizeof(msg);
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, &msg, size);
+}
+
+static void *
+_open_request_build(File_Data *f, int *bufsize)
+{
+ char *buf;
+ int size, pathlen, keylen;
+ Slave_Msg_Image_Open msg;
+
+ pathlen = strlen(f->path) + 1;
+ keylen = strlen(f->key) + 1;
+
+ size = sizeof(msg) + pathlen + keylen;
+ buf = malloc(size);
+ if (!buf) return NULL;
+
+ memset(&msg, 0, sizeof(msg));
+ memcpy(buf, &msg, sizeof(msg));
+ memcpy(buf + sizeof(msg), f->path, pathlen);
+ memcpy(buf + sizeof(msg) + pathlen, f->key, keylen);
+
+ *bufsize = size;
+ return buf;
+}
+
+static void
+_request_failed(Entry *e, Error_Type type)
+{
+ Waiter *w;
+ Eina_List *l;
+ Reference *ref;
+
+ DBG("Request for entry %p failed with error %d", e, type);
+ EINA_LIST_FREE(e->request->waiters, w)
+ {
+ cserve2_client_error_send(w->ref->client, w->rid, type);
+
+ w->ref->count--;
+ free(w);
+ }
+
+ EINA_LIST_FOREACH(e->references, l, ref)
+ {
+ Eina_Hash *hash = NULL;
+ if (e->type == CSERVE2_IMAGE_FILE)
+ hash = ref->client->files.referencing;
+ else if (e->type == CSERVE2_IMAGE_DATA)
+ hash = ref->client->images.referencing;
+ else
+ continue;
+
+ eina_hash_del_by_key(hash, &(ref->client_entry_id));
+ }
+}
+
+static void
+_open_request_response(File_Data *e, Slave_Msg_Image_Opened *resp)
+{
+ Waiter *w;
+
+ e->w = resp->w;
+ e->h = resp->h;
+ e->frame_count = resp->frame_count;
+ e->loop_count = resp->loop_count;
+ e->loop_hint = resp->loop_hint;
+ e->alpha = resp->alpha;
+ if (resp->has_loader_data)
+ {
+ const char *ldata = (const char *)resp +
+ sizeof(Slave_Msg_Image_Opened);
+ e->loader_data = eina_stringshare_add(ldata);
+ }
+
+ DBG("Finished opening file %d. Notifying %d waiters.", e->base.id,
+ e->base.request->waiters ? eina_list_count(e->base.request->waiters) : 0);
+ EINA_LIST_FREE(e->base.request->waiters, w)
+ {
+ _image_opened_send(w->ref->client, e, w->rid);
+ free(w);
+ }
+}
+
+static Request_Funcs _open_funcs = {
+ .msg_create = (Request_Msg_Create)_open_request_build,
+ .response = (Request_Response)_open_request_response,
+ .error = (Request_Error)_request_failed
+};
+
+static void *
+_load_request_build(Image_Data *i, int *bufsize)
+{
+ char *buf, *ptr;
+ const char *shmpath;
+ int size;
+ int shmlen, filelen, keylen, loaderlen;
+ Slave_Msg_Image_Load msg;
+
+ // opening shm for this file
+ i->shm = cserve2_shm_request(i->file->w * i->file->h * 4);
+
+ shmpath = cserve2_shm_name_get(i->shm);
+
+ shmlen = strlen(shmpath) + 1;
+ filelen = strlen(i->file->path) + 1;
+ keylen = strlen(i->file->key) + 1;
+ if (i->file->loader_data)
+ loaderlen = strlen(i->file->loader_data) + 1;
+ else
+ loaderlen = 0;
+
+ size = sizeof(msg) + shmlen + filelen + keylen + loaderlen;
+ buf = malloc(size);
+ if (!buf) return NULL;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.w = i->file->w;
+ msg.h = i->file->h;
+ msg.alpha = i->file->alpha;
+ msg.opts.w = i->opts.w;
+ msg.opts.h = i->opts.h;
+ msg.opts.rx = i->opts.rx;
+ msg.opts.ry = i->opts.ry;
+ msg.opts.rw = i->opts.rw;
+ msg.opts.rh = i->opts.rh;
+ msg.opts.scale_down_by = i->opts.scale_down;
+ msg.opts.dpi = i->opts.dpi;
+ msg.opts.orientation = i->opts.orientation;
+
+ msg.shm.mmap_offset = cserve2_shm_map_offset_get(i->shm);
+ msg.shm.image_offset = cserve2_shm_offset_get(i->shm);
+ msg.shm.mmap_size = cserve2_shm_map_size_get(i->shm);
+ msg.shm.image_size = cserve2_shm_size_get(i->shm);
+
+ msg.has_loader_data = !!loaderlen;
+
+ memcpy(buf, &msg, sizeof(msg));
+ ptr = buf + sizeof(msg);
+
+ memcpy(ptr, shmpath, shmlen);
+ ptr += shmlen;
+ memcpy(ptr, i->file->path, filelen);
+ ptr += filelen;
+ memcpy(ptr, i->file->key, keylen);
+ ptr += keylen;
+ memcpy(ptr, i->file->loader_data, loaderlen);
+
+ *bufsize = size;
+ return buf;
+}
+
+static void
+_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp)
+{
+ Waiter *w;
+
+ e->alpha_sparse = resp->alpha_sparse;
+ if (!e->doload)
+ DBG("Entry %d loaded by speculative preload.", e->base.id);
+
+ DBG("Finished loading image %d. Notifying %d waiters.", e->base.id,
+ e->base.request->waiters ? eina_list_count(e->base.request->waiters) : 0);
+ EINA_LIST_FREE(e->base.request->waiters, w)
+ {
+ if (w->type == CSERVE2_LOAD)
+ _image_loaded_send(w->ref->client, e, w->rid);
+ else if (w->type == CSERVE2_PRELOAD)
+ _image_preloaded_send(w->ref->client, w->rid);
+ // else w->type == CSERVE2_SETOPTS --> do nothing
+
+ free(w);
+ }
+}
+
+static Request_Funcs _load_funcs = {
+ .msg_create = (Request_Msg_Create)_load_request_build,
+ .response = (Request_Response)_load_request_response,
+ .error = (Request_Error)_request_failed
+};
+
+static unsigned int
+_img_opts_id_get(Image_Data *im, char *buf, int size)
+{
+ uintptr_t image_id;
+
+ snprintf(buf, size, "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:%d",
+ im->file_id, im->opts.dpi, im->opts.w, im->opts.h,
+ im->opts.scale_down, im->opts.rx, im->opts.ry,
+ im->opts.rw, im->opts.rh, im->opts.orientation);
+
+ image_id = (uintptr_t)eina_hash_find(image_ids, buf);
+
+ return image_id;
+}
+
+static int
+_image_entry_size_get(Image_Data *e)
+{
+ int size = sizeof(Image_Data);
+ /* XXX: get the overhead of the shm handler too */
+ if (e->shm)
+ size += cserve2_shm_size_get(e->shm);
+ return size / 1024;
+}
+
+static void
+_file_id_free(File_Data *entry)
+{
+ char buf[4096];
+
+ DBG("Removing entry file id: %d, file: \"%s:%s\"",
+ entry->base.id, entry->path, entry->key);
+ snprintf(buf, sizeof(buf), "%s:%s", entry->path, entry->key);
+ eina_hash_del_by_key(file_ids, buf);
+}
+
+static void
+_image_id_free(Image_Data *entry)
+{
+ char buf[4096];
+
+ DBG("Removing entry image id: %d", entry->base.id);
+
+ _img_opts_id_get(entry, buf, sizeof(buf));
+ eina_hash_del_by_key(image_ids, buf);
+}
+
+static void
+_image_entry_free(Image_Data *entry)
+{
+ File_Data *fentry = entry->file;
+
+ if (entry->base.request)
+ {
+ if (entry->base.request->processing)
+ entry->base.request->entry = NULL;
+ else if (!entry->base.request->waiters)
+ {
+ if (entry->doload)
+ load_requests = eina_list_remove(load_requests,
+ entry->base.request);
+ else
+ spload_requests = eina_list_remove(spload_requests,
+ entry->base.request);
+ }
+ }
+
+ if (entry->unused)
+ {
+ image_entries_lru = eina_list_remove(image_entries_lru, entry);
+ unused_mem_usage -= _image_entry_size_get(entry);
+ }
+
+ if (fentry)
+ fentry->images = eina_list_remove(fentry->images, entry);
+ if (entry->shm)
+ cserve2_shm_unref(entry->shm);
+ free(entry);
+}
+
+static void
+_hash_image_entry_free(void *data)
+{
+ Image_Data *entry = data;
+
+ _image_id_free(entry);
+ _image_entry_free(entry);
+}
+
+static void
+_file_entry_free(File_Data *entry)
+{
+ File_Watch *fw;
+
+ // Should we call free for each of the images too?
+ // If everything goes fine, it's not necessary.
+ if (entry->images)
+ {
+ ERR("Freeing file %d (\"%s:%s\") image data still referenced.",
+ entry->base.id, entry->path, entry->key);
+ eina_list_free(entry->images);
+ }
+
+ if (entry->base.request)
+ {
+ if (entry->base.request->processing)
+ entry->base.request->entry = NULL;
+ else if (!entry->base.request->waiters)
+ {
+ open_requests = eina_list_remove(open_requests,
+ entry->base.request);
+ free(entry->base.request);
+ }
+ }
+
+ if ((fw = entry->watcher))
+ {
+ fw->entries = eina_list_remove(fw->entries, entry);
+ if (!fw->entries)
+ eina_hash_del_by_key(file_watch, fw->path);
+ }
+
+ free(entry->key);
+ free(entry->path);
+ eina_stringshare_del(entry->loader_data);
+ free(entry);
+}
+
+static void
+_hash_file_entry_free(void *data)
+{
+ File_Data *entry = data;
+ // TODO: Add some checks to make sure that we are freeing an
+ // unused entry.
+
+ _file_id_free(entry);
+ _file_entry_free(entry);
+}
+
+static void
+_file_watch_free(void *data)
+{
+ File_Watch *fw = data;
+ cserve2_file_change_watch_del(fw->path);
+ eina_stringshare_del(fw->path);
+ eina_list_free(fw->entries);
+ free(fw);
+}
+
+static int
+_font_entry_cmp(const Font_Entry *k1, int k1_length __UNUSED__, const Font_Entry *k2, int k2_length __UNUSED__)
+{
+ if (k1->src->name == k2->src->name)
+ {
+ if (k1->size == k2->size)
+ {
+ if (k1->rend_flags == k2->rend_flags)
+ {
+ if (k1->hint == k2->hint)
+ return k1->dpi - k2->dpi;
+ return k1->hint - k2->hint;
+ }
+ return k1->rend_flags - k2->rend_flags;
+ }
+ return k1->size - k2->size;
+ }
+ return strcmp(k1->src->name, k2->src->name);
+}
+
+static int
+_font_entry_key_hash(const Font_Entry *key, int key_length __UNUSED__)
+{
+ int hash;
+ hash = eina_hash_djb2(key->src->name, eina_stringshare_strlen(key->src->name) + 1);
+ hash ^= eina_hash_int32(&key->rend_flags, sizeof(int));
+ hash ^= eina_hash_int32(&key->size, sizeof(int));
+ hash ^= eina_hash_int32(&key->dpi, sizeof(int));
+
+ return hash;
+}
+
+static void
+_font_entry_free(Font_Entry *fe)
+{
+ free(fe);
+}
+
+static void
+_font_source_free(Font_Source *fs)
+{
+ if (fs->name) eina_stringshare_del(fs->name);
+ if (fs->file) eina_stringshare_del(fs->file);
+
+ free(fs);
+}
+
+void
+cserve2_cache_init(void)
+{
+ file_ids = eina_hash_string_superfast_new(NULL);
+ file_entries = eina_hash_int32_new(_hash_file_entry_free);
+ image_ids = eina_hash_string_superfast_new(NULL);
+ image_entries = eina_hash_string_superfast_new(_hash_image_entry_free);
+ file_watch = eina_hash_string_superfast_new(_file_watch_free);
+
+ font_sources = eina_hash_string_small_new(EINA_FREE_CB(_font_source_free));
+ font_entries = eina_hash_new(NULL,
+ EINA_KEY_CMP(_font_entry_cmp),
+ EINA_KEY_HASH(_font_entry_key_hash),
+ EINA_FREE_CB(_font_entry_free),
+ 5);
+}
+
+void
+cserve2_cache_shutdown(void)
+{
+ eina_hash_free(image_entries);
+ eina_hash_free(image_ids);
+ eina_hash_free(file_entries);
+ eina_hash_free(file_ids);
+ eina_hash_free(file_watch);
+
+ eina_hash_free(font_entries);
+ eina_hash_free(font_sources);
+}
+
+static void
+_request_answer_del(Eina_List **requests, Request *req, Client *client, Error_Type err)
+{
+ Eina_List *l, *l_next;
+ Waiter *it;
+
+ DBG("Removing answer requests from entry: %d, client: %d",
+ req->entry->id, client->id);
+
+ EINA_LIST_FOREACH_SAFE(req->waiters, l, l_next, it)
+ {
+ if (it->ref->client->id == client->id)
+ {
+ cserve2_client_error_send(client, it->rid, err);
+ req->waiters = eina_list_remove_list(req->waiters, l);
+ free(it);
+ }
+ }
+
+ // FIXME: Should this be really here? I guess that it should be in the
+ // entry_free_cb function, or entry_reference_del, when there are no more
+ // references
+ if (!req->entry && !req->waiters)
+ {
+ *requests = eina_list_remove(*requests, req);
+ free(req);
+ }
+}
+
+static void
+_request_answer_all_del(Eina_List **requests, Request *req, Error_Type err)
+{
+ Waiter *it;
+
+ DBG("Removing all answer requests from entry: %d", req->entry->id);
+
+ EINA_LIST_FREE(req->waiters, it)
+ {
+ cserve2_client_error_send(it->ref->client, it->rid, err);
+ free(it);
+ }
+
+ *requests = eina_list_remove(*requests, req);
+ free(req);
+}
+
+static void
+_request_answer_add(Request *req, Reference *ref, unsigned int rid, Message_Type type)
+{
+ Waiter *w = malloc(sizeof(*w));
+
+ w->ref = ref;
+ w->rid = rid;
+ w->type = type;
+
+ DBG("Add answer request for entry id: %d, client: %d, rid: %d",
+ req->entry->id, ref->client->id, rid);
+ req->waiters = eina_list_append(req->waiters, w);
+}
+
+static void
+_request_add(Eina_List **requests, Entry *entry, Reference *ref, unsigned int rid, Message_Type type)
+{
+ Request *req;
+
+ // add the request if it doesn't exist yet
+ if (!entry->request)
+ {
+ req = malloc(sizeof(*req));
+ req->entry = entry;
+ req->waiters = NULL;
+ req->processing = EINA_FALSE;
+ entry->request = req;
+ if (type == CSERVE2_OPEN)
+ req->funcs = &_open_funcs;
+ else
+ req->funcs = &_load_funcs;
+ *requests = eina_list_append(*requests, req);
+ DBG("Add request for entry id: %d, client: %d, rid: %d",
+ req->entry->id, ref->client->id, rid);
+ }
+ else
+ req = entry->request;
+
+ if (type != CSERVE2_SETOPTS)
+ _request_answer_add(req, ref, rid, type);
+ else
+ DBG("Adding entry for speculative preload: id=%d", req->entry->id);
+}
+
+static Reference *
+_entry_reference_add(Entry *entry, Client *client, unsigned int client_entry_id)
+{
+ Reference *ref;
+
+ // increase reference for this file
+ ref = malloc(sizeof(*ref));
+ ref->client = client;
+ ref->entry = entry;
+ ref->client_entry_id = client_entry_id;
+ ref->count = 1;
+ entry->references = eina_list_append(entry->references, ref);
+
+ return ref;
+}
+
+static int
+_cserve2_cache_open_requests_process(int nloaders)
+{
+ Request *req;
+ char *slave_cmd_data;
+ int slave_cmd_size;
+
+ while ((nloaders > 0) && (open_requests))
+ {
+ // remove the first element from the list and process this element
+ req = eina_list_data_get(open_requests);
+ open_requests = eina_list_remove_list(open_requests, open_requests);
+
+ DBG("Processing OPEN request for file entry: %d", req->entry->id);
+
+ slave_cmd_data = req->funcs->msg_create(req->entry, &slave_cmd_size);
+
+ cserve2_slave_cmd_dispatch(req, IMAGE_OPEN, slave_cmd_data,
+ slave_cmd_size);
+
+ free(slave_cmd_data);
+
+ req->processing = EINA_TRUE;
+ nloaders--;
+ }
+
+ return nloaders;
+}
+
+static int
+_cserve2_cache_load_requests_list_process(Eina_List **queue, int nloaders)
+{
+ Eina_List *skipped = NULL;
+ Request *req;
+
+ while ((nloaders > 0) && (*queue))
+ {
+ Image_Data *ientry;
+ char *buf;
+ int size;
+
+ // remove the first element from the list and process this element
+ req = eina_list_data_get(*queue);
+ *queue = eina_list_remove_list(*queue, *queue);
+
+ ientry = (Image_Data *)req->entry;
+ if (!ientry->file)
+ {
+ ERR("File entry doesn't exist for entry id %d", req->entry->id);
+ _request_failed(req->entry, CSERVE2_INVALID_CACHE);
+ continue;
+ }
+
+ if (ientry->file->base.request)
+ {
+ /* OPEN still pending, skip this request */
+ skipped = eina_list_append(skipped, req);
+ continue;
+ }
+
+ DBG("Processing LOAD request for image entry: %d", req->entry->id);
+
+ buf = req->funcs->msg_create(req->entry, &size);
+
+ cserve2_slave_cmd_dispatch(req, IMAGE_LOAD, buf, size);
+
+ free(buf);
+
+ req->processing = EINA_TRUE;
+
+ nloaders--;
+ }
+
+ EINA_LIST_FREE(skipped, req)
+ *queue = eina_list_append(*queue, req);
+
+ return nloaders;
+}
+
+static void
+_cserve2_cache_load_requests_process(int nloaders)
+{
+ nloaders = _cserve2_cache_load_requests_list_process(&load_requests,
+ nloaders);
+ _cserve2_cache_load_requests_list_process(&spload_requests, nloaders - 1);
+}
+
+
+void
+cserve2_cache_requests_process(void)
+{
+ int avail_loaders;
+
+ avail_loaders = cserve2_slave_available_get();
+ avail_loaders = _cserve2_cache_open_requests_process(avail_loaders);
+ _cserve2_cache_load_requests_process(avail_loaders);
+}
+
+static void
+_entry_unused_push(Image_Data *e)
+{
+ int size = _image_entry_size_get(e);
+
+ if ((size > max_unused_mem_usage) || !(e->doload))
+ {
+ eina_hash_del_by_key(image_entries, &e->base.id);
+ return;
+ }
+ while (size > (max_unused_mem_usage - unused_mem_usage))
+ {
+ Entry *ie = eina_list_data_get(eina_list_last(image_entries_lru));
+ eina_hash_del_by_key(image_entries, &ie->id);
+ }
+ image_entries_lru = eina_list_append(image_entries_lru, e);
+ e->unused = EINA_TRUE;
+ unused_mem_usage += size;
+}
+
+static void
+_entry_reference_del(Entry *entry, Reference *ref)
+{
+ entry->references = eina_list_remove(entry->references, ref);
+
+ if (entry->references)
+ goto free_ref;
+
+ if (entry->type == CSERVE2_IMAGE_FILE)
+ {
+ File_Data *fentry = (File_Data *)entry;
+
+ if (fentry->invalid)
+ _file_entry_free(fentry);
+ else
+ {
+ Image_Data *ie;
+ EINA_LIST_FREE(fentry->images, ie)
+ ie->file = NULL;
+ eina_hash_del_by_key(file_entries, &entry->id);
+ }
+ }
+ else if (entry->type == CSERVE2_IMAGE_DATA)
+ {
+ Image_Data *ientry = (Image_Data *)entry;
+
+ if (!ientry->file)
+ eina_hash_del_by_key(image_entries, &entry->id);
+ else if (ientry->file->invalid)
+ _image_entry_free(ientry);
+ else
+ _entry_unused_push(ientry);
+ }
+ else if (entry->type == CSERVE2_FONT_ENTRY)
+ {
+ Font_Entry *fe = (Font_Entry *)entry;
+ eina_hash_del_by_key(font_entries, fe);
+ }
+ else
+ ERR("Wrong type of entry.");
+
+free_ref:
+ free(ref);
+}
+
+static void
+_entry_free_cb(void *data)
+{
+ Reference *ref = data;
+ Entry *entry;
+
+ DBG("Removing client reference for entry id: %d, client: %d",
+ ref->entry->id, ref->client->id);
+
+ entry = ref->entry;
+
+ if (entry->request && !entry->request->processing)
+ {
+ if (entry->type == CSERVE2_IMAGE_FILE)
+ _request_answer_del(&open_requests, entry->request, ref->client,
+ CSERVE2_REQUEST_CANCEL);
+ else if (entry->type == CSERVE2_IMAGE_DATA)
+ {
+ if (((Image_Data *)entry)->doload)
+ _request_answer_del(&load_requests, entry->request,
+ ref->client, CSERVE2_REQUEST_CANCEL);
+ else
+ _request_answer_del(&spload_requests, entry->request,
+ ref->client, CSERVE2_REQUEST_CANCEL);
+ }
+ }
+
+ _entry_reference_del(entry, ref);
+}
+
+static void
+_font_entry_reference_del(Client *client, Reference *ref)
+{
+ Entry *entry = ref->entry;
+
+ _entry_reference_del(entry, ref);
+}
+
+void
+cserve2_cache_client_new(Client *client)
+{
+ client->files.referencing = eina_hash_int32_new(_entry_free_cb);
+ client->images.referencing = eina_hash_int32_new(_entry_free_cb);
+ client->fonts.referencing = NULL;
+}
+
+void
+cserve2_cache_client_del(Client *client)
+{
+ Reference *ref;
+
+ // will call _entry_free_cb() for every entry
+ eina_hash_free(client->images.referencing);
+ // will call _entry_free_cb() for every entry
+ eina_hash_free(client->files.referencing);
+
+ EINA_LIST_FREE(client->fonts.referencing, ref)
+ {
+ _font_entry_reference_del(client, ref);
+ }
+}
+
+static Image_Data *
+_image_msg_new(Client *client, Msg_Setopts *msg)
+{
+ Reference *ref;
+ Image_Data *im_entry;
+
+ ref = eina_hash_find(client->files.referencing, &msg->file_id);
+ if (!ref)
+ {
+ ERR("Couldn't find file id: %d, for image id: %d",
+ msg->file_id, msg->image_id);
+ cserve2_client_error_send(client, msg->base.rid,
+ CSERVE2_INVALID_CACHE);
+ return NULL;
+ }
+ if (((File_Data *)ref->entry)->invalid)
+ {
+ cserve2_client_error_send(client, msg->base.rid,
+ CSERVE2_FILE_CHANGED);
+ return NULL;
+ }
+
+ im_entry = calloc(1, sizeof(*im_entry));
+ im_entry->base.type = CSERVE2_IMAGE_DATA;
+ im_entry->file_id = ref->entry->id;
+ im_entry->file = (File_Data *)ref->entry;
+ im_entry->opts.dpi = msg->opts.dpi;
+ im_entry->opts.w = msg->opts.w;
+ im_entry->opts.h = msg->opts.h;
+ im_entry->opts.scale_down = msg->opts.scale_down;
+ im_entry->opts.rx = msg->opts.rx;
+ im_entry->opts.ry = msg->opts.ry;
+ im_entry->opts.rw = msg->opts.rw;
+ im_entry->opts.rh = msg->opts.rh;
+ im_entry->opts.orientation = msg->opts.orientation;
+
+ return im_entry;
+}
+
+static void
+_file_changed_cb(const char *path __UNUSED__, Eina_Bool deleted __UNUSED__, void *data)
+{
+ File_Watch *fw = data;
+ File_Data *e;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(fw->entries, l, e)
+ {
+ Eina_List *ll;
+ Image_Data *ie;
+
+ e->invalid = EINA_TRUE;
+ e->watcher = NULL;
+
+ EINA_LIST_FOREACH(e->images, ll, ie)
+ {
+ _image_id_free(ie);
+ eina_hash_set(image_entries, &ie->base.id, NULL);
+ if (ie->base.request && !ie->base.request->processing)
+ {
+ if (ie->doload)
+ _request_answer_all_del(&load_requests, ie->base.request,
+ CSERVE2_FILE_CHANGED);
+ else
+ _request_answer_all_del(&spload_requests, ie->base.request,
+ CSERVE2_FILE_CHANGED);
+ }
+ ie->base.request = NULL;
+ if (ie->unused)
+ _image_entry_free(ie);
+ }
+
+ _file_id_free(e);
+ eina_hash_set(file_entries, &e->base.id, NULL);
+ if (e->base.request && !e->base.request->processing)
+ _request_answer_all_del(&open_requests, e->base.request,
+ CSERVE2_FILE_CHANGED);
+ e->base.request = NULL;
+ if (!e->images && !e->base.references)
+ _file_entry_free(e);
+ }
+
+ eina_hash_del_by_key(file_watch, fw->path);
+}
+
+static Font_Source *
+_cserve2_font_source_find(const char *name)
+{
+ Font_Source *fs;
+
+ fs = eina_hash_find(font_sources, name);
+
+ return fs;
+}
+
+static Font_Entry *
+_cserve2_font_entry_find(const char *name, unsigned int namelen, unsigned int size, unsigned int rend_flags, unsigned int hint, unsigned int dpi)
+{
+ Font_Entry tmp_fe;
+ Font_Source tmp_fs;
+ Font_Entry *fe;
+
+ tmp_fs.name = eina_stringshare_add_length(name, namelen);
+ tmp_fe.src = &tmp_fs;
+ tmp_fe.size = size;
+ tmp_fe.rend_flags = rend_flags;
+ tmp_fe.hint = hint;
+ tmp_fe.dpi = dpi;
+
+ fe = eina_hash_find(font_entries, &tmp_fe);
+ eina_stringshare_del(tmp_fs.name);
+
+ return fe;
+}
+
+static void *
+_font_load_request_build(void *data, int *size)
+{
+ Font_Entry *fe = data;
+ Slave_Msg_Font_Load *msg = calloc(1, sizeof(*msg));
+
+ msg->ftdata1 = fe->src->ft;
+ msg->ftdata2 = fe->ft;
+ msg->rend_flags = fe->rend_flags;
+ msg->hint = fe->hint;
+ msg->size = fe->size;
+ msg->dpi = fe->dpi;
+ msg->name = fe->src->name;
+ msg->file = fe->src->file;
+
+ *size = 0;
+
+ return msg;
+}
+
+static void
+_font_load_request_free(void *data)
+{
+ free(data);
+}
+
+static void
+_font_load_request_response(Client *client, void *data, void *resp, unsigned int rid)
+{
+ Slave_Msg_Font_Loaded *msg = resp;
+ Font_Entry *fe = data;
+
+ if (!fe->src->ft)
+ fe->src->ft = msg->ftdata1;
+
+ if (!fe->ft)
+ fe->ft = msg->ftdata2;
+
+ if (fe->request) fe->request = NULL;
+}
+
+static void
+_font_load_request_failed(Client *client, void *data, Error_Type error, unsigned int rid)
+{
+}
+
+static Font_Request_Funcs _font_load_funcs = {
+ .msg_create = (Font_Request_Msg_Create)_font_load_request_build,
+ .msg_free = (Font_Request_Msg_Free)_font_load_request_free,
+ .response = (Font_Request_Response)_font_load_request_response,
+ .error = (Font_Request_Error)_font_load_request_failed
+};
+
+int
+cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid)
+{
+ unsigned int file_id;
+ File_Data *entry;
+ Reference *ref;
+ File_Watch *fw;
+ char buf[4906];
+
+ // look for this file on client references
+ ref = eina_hash_find(client->files.referencing, &client_file_id);
+ if (ref)
+ {
+ entry = (File_Data *)ref->entry;
+
+ if (entry->invalid)
+ {
+ cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED);
+ return -1;
+ }
+
+ DBG("found client file id: %d", client_file_id);
+ ref->count++;
+
+ // File already being loaded, just add the request to be replied
+ if (entry->base.request)
+ _request_answer_add(entry->base.request, ref, rid, CSERVE2_OPEN);
+ else
+ _image_opened_send(client, entry, rid);
+ return 0;
+ }
+
+ // search whether the file is already opened by another client
+ snprintf(buf, sizeof(buf), "%s:%s", path, key);
+ file_id = (unsigned int)eina_hash_find(file_ids, buf);
+ if (file_id)
+ {
+ DBG("found file_id %u for client file id %d",
+ file_id, client_file_id);
+ entry = eina_hash_find(file_entries, &file_id);
+ if (!entry)
+ {
+ ERR("file \"%s\" is in file_ids hash but not in entries hash.",
+ buf);
+ cserve2_client_error_send(client, rid, CSERVE2_INVALID_CACHE);
+ return -1;
+ }
+ ref = _entry_reference_add((Entry *)entry, client, client_file_id);
+ eina_hash_add(client->files.referencing, &client_file_id, ref);
+ if (entry->base.request)
+ _request_answer_add(entry->base.request, ref, rid, CSERVE2_OPEN);
+ else // File already loaded, otherwise there would be a request
+ _image_opened_send(client, entry, rid);
+ return 0;
+ }
+
+ file_id = _file_id++;
+ while ((file_id == 0) || (eina_hash_find(file_entries, &file_id)))
+ file_id = _file_id++;
+
+ DBG("Creating new entry with file_id: %u for file \"%s:%s\"",
+ file_id, path, key);
+ entry = calloc(1, sizeof(*entry));
+ entry->base.type = CSERVE2_IMAGE_FILE;
+ entry->path = strdup(path);
+ entry->key = strdup(key);
+ entry->base.id = file_id;
+ eina_hash_add(file_entries, &file_id, entry);
+ eina_hash_add(file_ids, buf, (void *)file_id);
+ ref = _entry_reference_add((Entry *)entry, client, client_file_id);
+ eina_hash_add(client->files.referencing, &client_file_id, ref);
+
+ fw = eina_hash_find(file_watch, entry->path);
+ if (!fw)
+ {
+ fw = calloc(1, sizeof(File_Watch));
+ fw->path = eina_stringshare_add(entry->path);
+ cserve2_file_change_watch_add(fw->path, _file_changed_cb, fw);
+ eina_hash_direct_add(file_watch, fw->path, fw);
+ }
+ fw->entries = eina_list_append(fw->entries, entry);
+ entry->watcher = fw;
+
+ _request_add(&open_requests, (Entry *)entry, ref, rid, CSERVE2_OPEN);
+
+ // _open_image_default_set(entry);
+
+ return 0;
+}
+
+void
+cserve2_cache_file_close(Client *client, unsigned int client_file_id)
+{
+ Reference *ref = eina_hash_find(client->files.referencing,
+ &client_file_id);
+ if (!ref)
+ {
+ ERR("Couldn't find file %d in client hash.", client_file_id);
+ return;
+ }
+
+ ref->count--;
+ if (ref->count <= 0)
+ // will call _entry_free_cb() for this entry
+ eina_hash_del_by_key(client->files.referencing, &client_file_id);
+}
+
+int
+cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg)
+{
+ Image_Data *entry;
+ File_Data *fentry = NULL;
+ Reference *ref, *oldref;
+ unsigned int image_id;
+ char buf[4096];
+
+ oldref = eina_hash_find(client->images.referencing, &msg->image_id);
+
+ // search whether the image is already loaded by another client
+ entry = _image_msg_new(client, msg);
+ if (!entry)
+ return -1;
+ image_id = _img_opts_id_get(entry, buf, sizeof(buf));
+ if (image_id)
+ { // if so, just update the references
+ free(entry);
+ DBG("found image_id %d for client image id %d",
+ image_id, msg->image_id);
+ entry = eina_hash_find(image_entries, &image_id);
+ if (!entry)
+ {
+ ERR("image id %d is in file_ids hash, but not in entries hash"
+ "with entry id %d.", msg->image_id, image_id);
+ cserve2_client_error_send(client, msg->base.rid,
+ CSERVE2_INVALID_CACHE);
+ return -1;
+ }
+
+ if (entry->unused)
+ {
+ DBG("Re-using old image entry (id: %d) from the LRU list.",
+ entry->base.id);
+ entry->unused = EINA_FALSE;
+ image_entries_lru = eina_list_remove(image_entries_lru, entry);
+ unused_mem_usage -= _image_entry_size_get(entry);
+ }
+
+ if (oldref && (oldref->entry->id == image_id))
+ return 0;
+
+ ref = _entry_reference_add((Entry *)entry, client, msg->image_id);
+
+ if (oldref)
+ eina_hash_del_by_key(client->images.referencing, &msg->image_id);
+
+ eina_hash_add(client->images.referencing, &msg->image_id, ref);
+
+ return 0;
+ }
+
+ image_id = _image_id++;
+ while ((image_id == 0) || (eina_hash_find(image_entries, &image_id)))
+ image_id = _image_id++;
+
+ entry->base.id = image_id;
+ eina_hash_add(image_entries, &image_id, entry);
+ eina_hash_add(image_ids, buf, (void *)image_id);
+ ref = _entry_reference_add((Entry *)entry, client, msg->image_id);
+
+ if (oldref)
+ eina_hash_del_by_key(client->images.referencing, &msg->image_id);
+ eina_hash_add(client->images.referencing, &msg->image_id, ref);
+
+ fentry = entry->file;
+ fentry->images = eina_list_append(fentry->images, entry);
+
+ _request_add(&spload_requests, (Entry *)entry, ref, msg->base.rid,
+ CSERVE2_SETOPTS);
+ return 0;
+}
+
+void
+cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid)
+{
+ Image_Data *entry;
+ Reference *ref;
+
+ ref = eina_hash_find(client->images.referencing, &client_image_id);
+ if (!ref)
+ {
+ ERR("Can't load: client %d has no image id %d",
+ client->id, client_image_id);
+ return;
+ }
+
+ entry = (Image_Data *)ref->entry;
+
+ if (entry->file->invalid)
+ {
+ cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED);
+ return;
+ }
+
+ DBG("Loading image id: %d", ref->entry->id);
+
+ // File already being loaded, just add the request to be replied
+ if (entry->base.request)
+ {
+ _request_answer_add(entry->base.request, ref, rid, CSERVE2_LOAD);
+ if ((!entry->base.request->processing) && (!entry->doload))
+ {
+ DBG("Removing entry %d from speculative preload and adding "
+ "to normal load queue.", entry->base.id);
+ spload_requests = eina_list_remove(spload_requests,
+ entry->base.request);
+ load_requests = eina_list_append(load_requests,
+ entry->base.request);
+ }
+ }
+ else if (entry->shm)
+ _image_loaded_send(client, entry, rid);
+ else
+ _request_add(&load_requests, (Entry *)entry, ref, rid, CSERVE2_LOAD);
+
+ entry->doload = EINA_TRUE;
+}
+
+void
+cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid)
+{
+ Image_Data *entry;
+ Reference *ref;
+
+ ref = eina_hash_find(client->images.referencing, &client_image_id);
+ if (!ref)
+ {
+ ERR("Can't load: client %d has no image id %d",
+ client->id, client_image_id);
+ return;
+ }
+
+ entry = (Image_Data *)ref->entry;
+
+ if (entry->file->invalid)
+ {
+ cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED);
+ return;
+ }
+
+ DBG("Loading image id: %d", ref->entry->id);
+
+ // File already being loaded, just add the request to be replied
+ if (entry->base.request)
+ {
+ _request_answer_add(entry->base.request, ref, rid, CSERVE2_PRELOAD);
+ if ((!entry->base.request->processing) && (!entry->doload))
+ {
+ DBG("Removing entry %d from speculative preload and adding "
+ "to normal (pre)load queue.", entry->base.id);
+ spload_requests = eina_list_remove(spload_requests,
+ entry->base.request);
+ load_requests = eina_list_append(load_requests,
+ entry->base.request);
+ }
+ }
+ else if (entry->shm)
+ _image_preloaded_send(client, rid);
+ else
+ _request_add(&load_requests, (Entry *)entry, ref, rid, CSERVE2_PRELOAD);
+
+ entry->doload = EINA_TRUE;
+}
+
+void
+cserve2_cache_image_unload(Client *client, unsigned int client_image_id)
+{
+ Reference *ref = eina_hash_find(client->images.referencing,
+ &client_image_id);
+ if (!ref)
+ {
+ ERR("Couldn't find file %d in client hash.", client_image_id);
+ return;
+ }
+
+ ref->count--;
+ if (ref->count <= 0)
+ // will call _entry_free_cb() for this entry
+ eina_hash_del_by_key(client->images.referencing, &client_image_id);
+}
+
+int
+cserve2_cache_font_load(Client *client, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int hint, unsigned int size, unsigned int dpi, unsigned int rid)
+{
+ Reference *ref;
+ Font_Source *fs;
+ Font_Entry *fe = _cserve2_font_entry_find(name, namelen, size,
+ rend_flags, hint, dpi);
+
+ if (fe)
+ {
+ DBG("found font entry %s, rendflags: %d, hint: %d, size: %d, dpi: %d",
+ name, rend_flags, hint, size, dpi);
+
+ ref = _entry_reference_add((Entry *)fe, client, 0);
+ client->fonts.referencing = eina_list_append(
+ client->fonts.referencing, ref);
+
+ _font_loaded_send(client, fe, rid);
+ return 0;
+ }
+
+ fe = calloc(1, sizeof(*fe));
+ fe->rend_flags = rend_flags;
+ fe->hint = hint;
+ fe->size = size;
+ fe->dpi = dpi;
+ fe->base.type = CSERVE2_FONT_ENTRY;
+
+ fs = _cserve2_font_source_find(name);
+ if (!fs)
+ {
+ fs = calloc(1, sizeof(*fs));
+ fs->name = eina_stringshare_add_length(name, namelen);
+ fs->file = eina_stringshare_ref(fs->name);
+ eina_hash_direct_add(font_sources, fs->name, fs);
+ }
+
+
+ fe->src = fs;
+ fs->references++;
+ fe->request = cserve2_request_add(CSERVE2_REQ_FONT_LOAD, rid,
+ client, &_font_load_funcs, fe);
+
+ eina_hash_direct_add(font_entries, fe, fe);
+
+ return 0;
+}
+
+void
+cserve2_cache_requests_response(Slave_Command type, void *msg, void *data)
+{
+ Request *req = data;
+
+ if (!req->entry)
+ {
+ Waiter *w;
+ DBG("Request finished but it has no entry anymore.");
+ EINA_LIST_FREE(req->waiters, w)
+ {
+ cserve2_client_error_send(w->ref->client, w->rid,
+ CSERVE2_REQUEST_CANCEL);
+
+ w->ref->count--;
+ free(w);
+ }
+ }
+ else if (type == ERROR)
+ {
+ Error_Type *error = msg;
+ req->funcs->error(req->entry, *error);
+ }
+ else
+ req->funcs->response(req->entry, msg);
+
+ if (req->entry)
+ req->entry->request = NULL;
+ free(req);
+}
--- /dev/null
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "evas_cserve2.h"
+
+static const char *SOCK_PATH = "/tmp/cserve2.socket";
+static unsigned int _rid_count = 0;
+
+static struct sockaddr_un socket_local;
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(socket_local.sun_path)
+#endif
+
+static void
+debug_msg(const void *buf, int size)
+{
+ const char *str = buf;
+ int i;
+
+ printf("message: ");
+ for (i = 0; i < size; i++)
+ printf("%x ", str[i]);
+
+ printf("\n");
+}
+
+static int
+_read_line(char *buf, int size)
+{
+ int len;
+ char *c;
+
+ fgets(buf, size, stdin);
+ c = strchr(buf, '#');
+ if (c)
+ *c = '\0';
+ else
+ {
+ c = strchr(buf, '\n');
+ if (c)
+ *c = '\0';
+ }
+ len = strlen(buf);
+
+ return len + 1;
+}
+
+static void *
+parse_input_open(int *size)
+{
+ char path[4096];
+ char key[4096];
+ char line[4096];
+ int path_len, key_len;
+ Msg_Open msg;
+ char *buf;
+ int file_id;
+
+ _read_line(line, sizeof(line));
+ path_len = _read_line(path, sizeof(path));
+ key_len = _read_line(key, sizeof(key));
+
+ sscanf(line, "%d", &file_id);
+
+ buf = malloc(sizeof(msg) + path_len + key_len);
+
+ msg.base.rid = _rid_count++;
+ msg.base.type = CSERVE2_OPEN;
+ msg.file_id = file_id;
+ msg.path_offset = 0;
+ msg.key_offset = path_len;
+
+ memcpy(buf, &msg, sizeof(msg));
+ memcpy(buf + sizeof(msg), path, path_len);
+ memcpy(buf + sizeof(msg) + path_len, key, key_len);
+
+ *size = sizeof(msg) + path_len + key_len;
+
+ return buf;
+}
+
+static void *
+parse_input_setopts(int *size)
+{
+ Msg_Setopts *msg;
+ char line[4096];
+ int file_id, image_id;
+ double dpi;
+ int w, h;
+ int scale;
+ int rx, ry, rw, rh;
+ int orientation;
+
+ // reading file_id, image_id
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d %d", &file_id, &image_id);
+
+ // reading load dpi
+ _read_line(line, sizeof(line));
+ dpi = atof(line);
+
+ // reading load size
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d %d", &w, &h);
+
+ // reading load scale down
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &scale);
+
+ // reading load region
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d %d %d %d", &rx, &ry, &rw, &rh);
+
+ // reading orientation
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &orientation);
+
+
+ msg = calloc(1, sizeof(*msg));
+
+ msg->base.rid = _rid_count++;
+ msg->base.type = CSERVE2_SETOPTS;
+ msg->file_id = file_id;
+ msg->image_id = image_id;
+ msg->opts.dpi = dpi;
+ msg->opts.w = w;
+ msg->opts.h = h;
+ msg->opts.scale_down = scale;
+ msg->opts.rx = rx;
+ msg->opts.ry = ry;
+ msg->opts.rw = rw;
+ msg->opts.rh = rh;
+ msg->opts.orientation = !!orientation;
+
+ *size = sizeof(*msg);
+
+ return msg;
+}
+
+static void *
+parse_input_load(int *size)
+{
+ Msg_Load *msg;
+ char line[4096];
+ int image_id;
+
+ // read image_id
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &image_id);
+
+ msg = calloc(1, sizeof(*msg));
+
+ msg->base.rid = _rid_count++;
+ msg->base.type = CSERVE2_LOAD;
+ msg->image_id = image_id;
+
+ *size = sizeof(*msg);
+
+ return msg;
+}
+
+static void *
+parse_input_preload(int *size)
+{
+ Msg_Preload *msg;
+ char line[4096];
+ int image_id;
+
+ // read image_id
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &image_id);
+
+ msg = calloc(1, sizeof(*msg));
+
+ msg->base.rid = _rid_count++;
+ msg->base.type = CSERVE2_PRELOAD;
+ msg->image_id = image_id;
+
+ *size = sizeof(*msg);
+
+ return msg;
+}
+
+static void *
+parse_input_unload(int *size)
+{
+ Msg_Unload *msg;
+ char line[4096];
+ int image_id;
+
+ // read image_id
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &image_id);
+
+ msg = calloc(1, sizeof(*msg));
+
+ msg->base.rid = _rid_count++;
+ msg->base.type = CSERVE2_UNLOAD;
+ msg->image_id = image_id;
+
+ *size = sizeof(*msg);
+
+ return msg;
+}
+
+static void *
+parse_input_close(int *size)
+{
+ Msg_Close *msg;
+ char line[4096];
+ int file_id;
+
+ // read file_id
+ _read_line(line, sizeof(line));
+ sscanf(line, "%d", &file_id);
+
+ msg = calloc(1, sizeof(*msg));
+
+ msg->base.rid = _rid_count++;
+ msg->base.type = CSERVE2_CLOSE;
+ msg->file_id = file_id;
+
+ *size = sizeof(*msg);
+
+ return msg;
+}
+
+static void
+parse_answer_opened(const void *buf)
+{
+ const Msg_Opened *msg = buf;
+ printf("OPENED rid = %d\n", msg->base.rid);
+ printf("size: %dx%d, alpha: %d\n\n",
+ msg->image.w, msg->image.h, msg->image.alpha);
+}
+
+static void
+parse_answer_setoptsed(const void *buf)
+{
+ const Msg_Setoptsed *msg = buf;
+ printf("SETOPTSED rid = %d\n", msg->base.rid);
+}
+
+static void
+parse_answer_loaded(const void *buf)
+{
+ const Msg_Loaded *msg = buf;
+ const char *path;
+
+ path = ((const char *)msg) + sizeof(*msg);
+
+ printf("LOADED rid = %d\n", msg->base.rid);
+ printf("shm mmap_offset = 0x%x, use_offset = 0x%x, mmap size = %d bytes\n",
+ msg->shm.mmap_offset, msg->shm.use_offset, msg->shm.mmap_size);
+ printf("shm path: \"%s\"\n\n", path);
+}
+
+static void
+parse_answer_preloaded(const void *buf)
+{
+ const Msg_Preloaded *msg = buf;
+
+ printf("PRELOADED rid = %d\n", msg->base.rid);
+}
+
+static void
+parse_answer_error(const void *buf)
+{
+ const Msg_Error *msg = buf;
+
+ printf("ERROR rid = %d, error = %d\n", msg->base.rid, msg->error);
+}
+
+static void
+parse_answer(const void *buf)
+{
+ const Msg_Base *msg = buf;
+
+ switch (msg->type)
+ {
+ case CSERVE2_OPENED:
+ parse_answer_opened(buf);
+ break;
+ case CSERVE2_SETOPTSED:
+ parse_answer_setoptsed(buf);
+ break;
+ case CSERVE2_LOADED:
+ parse_answer_loaded(buf);
+ break;
+ case CSERVE2_PRELOADED:
+ parse_answer_preloaded(buf);
+ break;
+ case CSERVE2_ERROR:
+ parse_answer_error(buf);
+ break;
+ default:
+ printf("unhandled answer: %d\n", msg->type);
+ }
+}
+
+static struct {
+ const char *name;
+ Message_Type type;
+ void *(*parse_func)(int *size);
+} _msg_types[] = {
+ { "OPEN", CSERVE2_OPEN, parse_input_open },
+ { "OPENED", CSERVE2_OPENED, NULL },
+ { "SETOPTS", CSERVE2_SETOPTS, parse_input_setopts },
+ { "SETOPTSED", CSERVE2_SETOPTSED, NULL },
+ { "LOAD", CSERVE2_LOAD, parse_input_load },
+ { "LOADED", CSERVE2_LOADED, NULL },
+ { "PRELOAD", CSERVE2_PRELOAD, parse_input_preload },
+ { "PRELOADED", CSERVE2_PRELOADED, NULL },
+ { "UNLOAD", CSERVE2_UNLOAD, parse_input_unload },
+ { "CLOSE", CSERVE2_CLOSE, parse_input_close },
+ { NULL, 0, NULL }
+};
+
+int main(void)
+{
+ int s, t, len, skip_cmd = 0;
+ struct sockaddr_un remote;
+ char msgbuf[4096], buf[UNIX_PATH_MAX], *env;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ perror("socket");
+ exit(1);
+ }
+
+ printf("Trying to connect...\n");
+
+ remote.sun_family = AF_UNIX;
+ env = getenv("EVAS_CSERVE2_SOCKET");
+ if (!env)
+ {
+ snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket",
+ (int)getuid());
+ env = buf;
+ }
+ strncpy(remote.sun_path, env, UNIX_PATH_MAX - 1);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ if (connect(s, (struct sockaddr *)&remote, len) == -1)
+ {
+ perror("connect");
+ exit(1);
+ }
+
+ printf("Connected.\n");
+
+ while(!feof(stdin))
+ {
+ char cmd[1024];
+ int i;
+ int size;
+ void *msg;
+
+ if (skip_cmd)
+ skip_cmd = 0;
+ else
+ printf("\n> ");
+ fgets(cmd, sizeof(cmd), stdin);
+ len = strlen(cmd) - 1;
+ cmd[len] = '\0';
+
+ if (!len)
+ {
+ skip_cmd = 1;
+ continue;
+ }
+
+ for (i = 0; _msg_types[i].name; i++)
+ {
+ if (!strcmp(cmd, _msg_types[i].name))
+ break;
+ }
+
+ // discards the end of the message if we can't parse it
+ if (!_msg_types[i].name)
+ {
+ printf("Invalid command.\n");
+ continue;
+ }
+
+ if (!_msg_types[i].parse_func)
+ {
+ printf("Command %s still unhandled.\n", _msg_types[i].name);
+ continue;
+ }
+
+ msg = _msg_types[i].parse_func(&size);
+
+ if (send(s, &size, sizeof(size), MSG_NOSIGNAL) == -1)
+ {
+ perror("send size");
+ exit(1);
+ }
+ if (send(s, msg, size, MSG_NOSIGNAL) == -1)
+ {
+ perror("send");
+ exit(1);
+ }
+
+ free(msg);
+
+ usleep(100000);
+
+ if ((t=recv(s, &size, sizeof(size), MSG_DONTWAIT)) > 0)
+ {
+ len = recv(s, msgbuf, size, 0);
+ printf("size of received message: %d\n", len);
+ if (len != size)
+ {
+ printf("couldn't read entire message.\n");
+ continue;
+ }
+ debug_msg(&size, sizeof(size));
+ debug_msg(msgbuf, size);
+ parse_answer(msgbuf);
+ }
+ else
+ {
+ if (t < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
+ continue;
+ else fprintf(stderr, "Server closed connection\n");
+ exit(1);
+ }
+ }
+
+ close(s);
+
+ return 0;
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+#include FT_SIZES_H
+#include FT_MODULE_H
+
+#include "evas_cserve2.h"
+
+static FT_Library cserve2_ft_lib = 0;
+static int initialised = 0;
+
+struct _Font_Info
+{
+ FT_Size size;
+ int real_size;
+ int max_h;
+ unsigned int runtime_rend;
+};
+
+struct _Font_Source_Info
+{
+ FT_Face face;
+ int orig_upem;
+ int current_size;
+};
+
+typedef struct _Font_Info Font_Info;
+typedef struct _Font_Source_Info Font_Source_Info;
+
+static void *
+_font_slave_error_send(Error_Type error)
+{
+ Error_Type *e = calloc(1, sizeof(*e));
+ *e = error;
+
+ return e;
+}
+
+static Font_Source_Info *
+_font_slave_source_load(const char *file)
+{
+ int error;
+ Font_Source_Info *fsi = malloc(sizeof(*fsi));
+
+ error = FT_New_Face(cserve2_ft_lib, file, 0, &(fsi->face));
+ if (error)
+ {
+ free(fsi);
+ return NULL;
+ }
+
+ error = FT_Select_Charmap(fsi->face, ft_encoding_unicode);
+ if (error)
+ {
+ FT_Done_Face(fsi->face);
+ free(fsi);
+ return NULL;
+ }
+
+ fsi->orig_upem = fsi->face->units_per_EM;
+ fsi->current_size = 0;
+
+ return fsi;
+}
+
+static Font_Info *
+_font_slave_int_load(const Slave_Msg_Font_Load *msg, Font_Source_Info *fsi)
+{
+ int error;
+ int val, dv;
+ int ret;
+ Font_Info *fi = calloc(1, sizeof(*fi));
+
+ error = FT_New_Size(fsi->face, &(fi->size));
+ if (!error)
+ FT_Activate_Size(fi->size);
+
+ fi->real_size = msg->size * 64;
+ error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi);
+ if (error)
+ {
+ fi->real_size = msg->size;
+ error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);
+ }
+
+ if (error)
+ {
+ int i;
+ int chosen_size = 0;
+ int chosen_width = 0;
+
+ for (i = 0; i < fsi->face->num_fixed_sizes; i++)
+ {
+ int s;
+ int d, cd;
+
+ s = fsi->face->available_sizes[i].height;
+ cd = chosen_size - msg->size;
+ if (cd < 0) cd = -cd;
+ d = s - msg->size;
+ if (d < 0) d = -d;
+ if (d < cd)
+ {
+ chosen_width = fsi->face->available_sizes[i].width;
+ chosen_size = s;
+ }
+ if (d == 0) break;
+ }
+ fi->real_size = chosen_size;
+ error = FT_Set_Pixel_Sizes(fsi->face, chosen_width, fi->real_size);
+
+ if (error)
+ {
+ ERR("Could not choose the font size for font: '%s'.", msg->name);
+ FT_Done_Size(fi->size);
+ free(fi);
+ return NULL;
+ }
+ }
+
+ fi->max_h = 0;
+ val = (int)fsi->face->bbox.yMax;
+ if (fsi->face->units_per_EM != 0)
+ {
+ dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
+ ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
+ }
+ else ret = val;
+ fi->max_h += ret;
+ val = -(int)fsi->face->bbox.yMin;
+ if (fsi->face->units_per_EM != 0)
+ {
+ dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
+ ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
+ }
+ else ret = val;
+ fi->max_h += ret;
+
+ fi->runtime_rend = FONT_REND_REGULAR;
+ if ((msg->rend_flags & FONT_REND_SLANT) &&
+ !(fsi->face->style_flags & FT_STYLE_FLAG_ITALIC))
+ fi->runtime_rend |= FONT_REND_SLANT;
+ if ((msg->rend_flags & FONT_REND_WEIGHT) &&
+ !(fsi->face->style_flags & FT_STYLE_FLAG_BOLD))
+ fi->runtime_rend |= FONT_REND_WEIGHT;
+
+ return fi;
+}
+
+static Slave_Msg_Font_Loaded *
+_font_slave_load(const void *cmddata, void *data __UNUSED__)
+{
+ const Slave_Msg_Font_Load *msg = cmddata;
+ Slave_Msg_Font_Loaded *response;
+ Font_Source_Info *fsi;
+ Font_Info *fi;
+
+ fsi = msg->ftdata1;
+
+ /* Loading Font Source */
+ if (!fsi)
+ fsi = _font_slave_source_load(msg->file);
+
+ // FIXME: Return correct error message
+ if (!fsi)
+ {
+ ERR("Could not load font source: '%s'", msg->file);
+ return NULL;
+ }
+
+ fi = _font_slave_int_load(msg, fsi);
+ if (!fi)
+ {
+ FT_Done_Face(fsi->face);
+ free(fsi);
+ return NULL;
+ }
+
+ response = calloc(1, sizeof(*response));
+ response->ftdata1 = fsi;
+ response->ftdata2 = fi;
+
+ return response;
+}
+
+void *
+cserve2_font_slave_cb(Slave_Thread_Data *sd __UNUSED__, Slave_Command *cmd, const void *cmddata, void *data)
+{
+ void *response = NULL;
+
+ switch (*cmd)
+ {
+ case FONT_LOAD:
+ response = _font_slave_load(cmddata, data);
+ break;
+ case FONT_GLYPHS_LOAD:
+ // command for FONT_GLYPHS_LOAD
+ break;
+ default:
+ ERR("Invalid command for font slave: %d", *cmd);
+ *cmd = ERROR;
+ return _font_slave_error_send(CSERVE2_INVALID_COMMAND);
+ }
+
+ if (!response)
+ {
+ *cmd = ERROR;
+ return _font_slave_error_send(CSERVE2_GENERIC);
+ }
+
+ return response;
+}
+
+void
+cserve2_font_init(void)
+{
+ int error;
+
+ if (initialised++ > 0) return;
+
+ error = FT_Init_FreeType(&cserve2_ft_lib);
+ if (error) return;
+}
+
+void
+cserve2_font_shutdown(void)
+{
+ initialised--;
+ if (initialised > 0) return;
+ if (initialised < 0)
+ {
+ ERR("Invalid shutdown of cserve2 font.");
+ return;
+ }
+
+ FT_Done_FreeType(cserve2_ft_lib);
+ cserve2_ft_lib = 0;
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "evas_cserve2.h"
+
+#ifdef CSERVE2_BIN_DEFAULT_COLOR
+#undef CSERVE2_BIN_DEFAULT_COLOR
+#endif
+#define CSERVE2_BIN_DEFAULT_COLOR EINA_COLOR_BLUE
+
+#define MAX_SLAVES 3
+
+struct _Slave_Worker {
+ EINA_INLIST;
+ void *data;
+ Slave *slave;
+ Eina_Binbuf *ret;
+ int ret_size;
+ Eina_Bool done;
+ Eina_Bool delete_me;
+};
+
+typedef struct _Slave_Worker Slave_Worker;
+
+int _evas_cserve2_bin_log_dom = -1;
+static unsigned int _client_id = 0;
+static Eina_Hash *client_list = NULL;
+static Eina_Inlist *slaves_idle = NULL;
+static Eina_Inlist *slaves_working = NULL;
+
+struct _Glyph_Request {
+ unsigned int index;
+ unsigned int offset;
+};
+
+typedef struct _Glyph_Request Glyph_Request;
+
+void
+cserve2_client_error_send(Client *client, unsigned int rid, int error_code)
+{
+ int size;
+ Msg_Error msg;
+
+ // clear the struct with possible paddings, since it is not aligned.
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_ERROR;
+ msg.error = error_code;
+
+ size = sizeof(msg);
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, &msg, sizeof(msg));
+}
+
+static void
+_cserve2_client_image_setoptsed(Client *client, unsigned int rid)
+{
+ int size;
+ Msg_Setoptsed msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = rid;
+ msg.base.type = CSERVE2_SETOPTSED;
+
+ size = sizeof(msg);
+ cserve2_client_send(client, &size, sizeof(size));
+ cserve2_client_send(client, &msg, size);
+}
+
+static void
+_slave_dead_cb(Slave *s __UNUSED__, void *data)
+{
+ Slave_Worker *sw = data;
+
+ if (sw->delete_me)
+ {
+ DBG("Slave killed by cserve2. Restart routine.");
+ free(sw);
+ return;
+ }
+
+ if (!sw->data)
+ {
+ WRN("Slave died with no pending job, but not requested.");
+ slaves_idle = eina_inlist_remove(slaves_idle, EINA_INLIST_GET(sw));
+ free(sw);
+ return;
+ }
+
+ slaves_working = eina_inlist_remove(slaves_working, EINA_INLIST_GET(sw));
+ if (!sw->done)
+ cserve2_cache_requests_response(ERROR, (Error_Type[]){ CSERVE2_LOADER_DIED }, sw->data);
+ if (sw->ret)
+ eina_binbuf_free(sw->ret);
+ free(sw);
+}
+
+static void
+_slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data)
+{
+ Slave_Worker *sw = data;
+
+ DBG("Received reply command '%d' from slave '%p'", cmd, sw->slave);
+ switch (cmd)
+ {
+ case IMAGE_OPEN:
+ case IMAGE_LOAD:
+ sw->done = EINA_TRUE;
+ break;
+ case ERROR:
+ break;
+ default:
+ ERR("Unrecognized command received from slave: %d", cmd);
+ }
+ cserve2_cache_requests_response(cmd, msg, sw->data);
+ free(msg);
+
+ // slave finishes its work, put it back to idle list
+ sw->data = NULL;
+ slaves_working = eina_inlist_remove(slaves_working, EINA_INLIST_GET(sw));
+
+ if (!sw->delete_me) // if it is being deleted, it shouldn't be in any list
+ slaves_idle = eina_inlist_append(slaves_idle, EINA_INLIST_GET(sw));
+
+ cserve2_cache_requests_process();
+}
+
+int
+cserve2_slave_available_get(void)
+{
+ return MAX_SLAVES - eina_inlist_count(slaves_working);
+}
+
+Eina_Bool
+cserve2_slave_cmd_dispatch(void *data, Slave_Command cmd, const void *msg, int size)
+{
+ Slave_Worker *sw;
+ char *exe;
+
+ DBG("Dispatching command to slave. %d idle slaves, %d working slaves.",
+ eina_inlist_count(slaves_idle), eina_inlist_count(slaves_working));
+
+ // first check if there's an available slave
+ if (slaves_idle)
+ {
+ sw = EINA_INLIST_CONTAINER_GET(slaves_idle, Slave_Worker);
+ slaves_idle = eina_inlist_remove(slaves_idle, slaves_idle);
+ slaves_working = eina_inlist_append(slaves_working,
+ EINA_INLIST_GET(sw));
+
+ sw->data = data;
+ DBG("Dispatching command '%d' to slave '%p'", cmd, sw->slave);
+ cserve2_slave_send(sw->slave, cmd, msg, size);
+ return EINA_TRUE;
+ }
+
+ // no available slave, start a new one
+ sw = calloc(1, sizeof(Slave_Worker));
+ if (!sw) return EINA_FALSE;
+
+ sw->data = data;
+ exe = getenv("EVAS_CSERVE2_SLAVE");
+ if (!exe) exe = "evas_cserve2_slave";
+ sw->slave = cserve2_slave_run(exe, _slave_read_cb, _slave_dead_cb, sw);
+ if (!sw->slave)
+ {
+ ERR("Could not launch slave process");
+ cserve2_cache_requests_response(ERROR, (Error_Type[]){ CSERVE2_LOADER_EXEC_ERR }, sw->data);
+ free(sw);
+ return EINA_FALSE;
+ }
+ DBG("Dispatching command '%d' to slave '%p'", cmd, sw->slave);
+ cserve2_slave_send(sw->slave, cmd, msg, size);
+
+ slaves_working = eina_inlist_append(slaves_working, EINA_INLIST_GET(sw));
+
+ return EINA_TRUE;
+}
+
+static void
+_cserve2_client_close(Client *client)
+{
+ Msg_Close *msg = (Msg_Close *)client->msg.buf;
+
+ INF("Received CLOSE command: RID=%d", msg->base.rid);
+ INF("File_ID: %d\n", msg->file_id);
+
+ cserve2_cache_file_close(client, msg->file_id);
+}
+
+static void
+_cserve2_client_unload(Client *client)
+{
+ Msg_Unload *msg = (Msg_Unload *)client->msg.buf;
+
+ INF("Received UNLOAD command: RID=%d", msg->base.rid);
+ INF("Image_ID: %d\n", msg->image_id);
+
+ cserve2_cache_image_unload(client, msg->image_id);
+}
+
+static void
+_cserve2_client_preload(Client *client)
+{
+ Msg_Preload *msg = (Msg_Preload *)client->msg.buf;
+
+ INF("Received PRELOAD command: RID=%d", msg->base.rid);
+ INF("Image_ID: %d\n", msg->image_id);
+
+ cserve2_cache_image_preload(client, msg->image_id, msg->base.rid);
+ cserve2_cache_requests_process();
+}
+
+static void
+_cserve2_client_load(Client *client)
+{
+ Msg_Load *msg = (Msg_Load *)client->msg.buf;
+
+ INF("Received LOAD command: RID=%d", msg->base.rid);
+ INF("Image_ID: %d\n", msg->image_id);
+
+ cserve2_cache_image_load(client, msg->image_id, msg->base.rid);
+ cserve2_cache_requests_process();
+}
+
+static void
+_cserve2_client_setopts(Client *client)
+{
+ Msg_Setopts *msg = (Msg_Setopts *)client->msg.buf;
+
+ INF("Received SETOPTS command: RID=%d", msg->base.rid);
+ INF("File_ID: %d, Image_ID: %d", msg->file_id, msg->image_id);
+ INF("Load Options:");
+ INF("\tdpi: %03.1f", msg->opts.dpi);
+ INF("\tsize: %dx%d", msg->opts.w, msg->opts.h);
+ INF("\tscale down: %d", msg->opts.scale_down);
+ INF("\tregion: %d,%d + %dx%d",
+ msg->opts.rx, msg->opts.ry, msg->opts.rw, msg->opts.rh);
+ INF("\torientation: %d\n", msg->opts.orientation);
+
+ if (cserve2_cache_image_opts_set(client, msg) != 0)
+ return;
+
+ _cserve2_client_image_setoptsed(client, msg->base.rid);
+}
+
+static void
+_cserve2_client_open(Client *client)
+{
+ Msg_Open *msg = (Msg_Open *)client->msg.buf;
+ const char *path, *key;
+
+ path = ((const char *)msg) + sizeof(*msg) + msg->path_offset;
+ key = ((const char *)msg) + sizeof(*msg) + msg->key_offset;
+
+ INF("Received OPEN command: RID=%d", msg->base.rid);
+ INF("File_ID: %d, path=\"%s\", key=\"%s\"\n",
+ msg->file_id, path, key);
+
+ cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid);
+ cserve2_cache_requests_process();
+}
+
+static void
+_cserve2_client_font_load(Client *client)
+{
+ Msg_Font_Load *msg = (Msg_Font_Load *)client->msg.buf;
+ char name[PATH_MAX];
+
+ memcpy(name, msg + 1, msg->pathlen);
+
+ INF("Received %s command: RID=%d",
+ (msg->base.type == CSERVE2_FONT_LOAD) ? "FONT_LOAD" : "FONT_UNLOAD",
+ msg->base.rid);
+ INF("Font: %s, rend_flags: %d, hint: %d, size: %d, dpi: %d",
+ name, msg->rend_flags, msg->hint, msg->size, msg->dpi);
+
+ cserve2_cache_font_load(client, name, msg->pathlen, msg->rend_flags,
+ msg->hint, msg->size, msg->dpi, msg->base.rid);
+}
+
+static void
+_cserve2_client_font_glyphs_request(Client *client)
+{
+ Msg_Font_Glyphs_Request *msg = (Msg_Font_Glyphs_Request *)client->msg.buf;
+ char fontpath[PATH_MAX];
+ Glyph_Request *glyphs;
+ unsigned int i;
+ const char *bufpos = client->msg.buf;
+
+ memcpy(fontpath, msg + 1, msg->pathlen);
+
+ bufpos = bufpos + sizeof(msg) + msg->pathlen;
+ glyphs = malloc(sizeof(*glyphs) * msg->nglyphs);
+
+ for (i = 0; i < msg->nglyphs; i++)
+ {
+ memcpy(&glyphs[i], bufpos, sizeof(*glyphs));
+ bufpos += sizeof(*glyphs);
+ }
+
+ if (msg->base.type == CSERVE2_FONT_GLYPHS_LOAD)
+ {
+ INF("Received CSERVE2_FONT_GLYPHS_LOAD command: RID=%d",
+ msg->base.rid);
+ }
+ else
+ {
+ INF("Received CSERVE2_FONT_GLYPHS_USED command: RID=%d",
+ msg->base.rid);
+ }
+}
+
+void
+cserve2_command_run(Client *client, Message_Type type)
+{
+ switch (type)
+ {
+ case CSERVE2_OPEN:
+ _cserve2_client_open(client);
+ break;
+ case CSERVE2_SETOPTS:
+ _cserve2_client_setopts(client);
+ break;
+ case CSERVE2_LOAD:
+ _cserve2_client_load(client);
+ break;
+ case CSERVE2_PRELOAD:
+ _cserve2_client_preload(client);
+ break;
+ case CSERVE2_UNLOAD:
+ _cserve2_client_unload(client);
+ break;
+ case CSERVE2_CLOSE:
+ _cserve2_client_close(client);
+ break;
+ case CSERVE2_FONT_LOAD:
+ case CSERVE2_FONT_UNLOAD:
+ _cserve2_client_font_load(client);
+ break;
+ case CSERVE2_FONT_GLYPHS_LOAD:
+ case CSERVE2_FONT_GLYPHS_USED:
+ _cserve2_client_font_glyphs_request(client);
+ break;
+ default:
+ WRN("Unhandled message");
+ }
+}
+
+static void
+_slave_quit_send(Slave_Worker *sw)
+{
+ cserve2_slave_send(sw->slave, SLAVE_QUIT, NULL, 0);
+}
+
+static void
+_slaves_restart(void)
+{
+ Slave_Worker *list, *sw;
+
+ while (slaves_idle) // remove idle workers from idle list
+ {
+ sw = EINA_INLIST_CONTAINER_GET(slaves_idle, Slave_Worker);
+ slaves_idle = eina_inlist_remove(slaves_idle, slaves_idle);
+ sw->delete_me = EINA_TRUE;
+ _slave_quit_send(sw);
+ }
+
+ // working workers will be removed from the working list when they
+ // finish processing their jobs
+ list = EINA_INLIST_CONTAINER_GET(slaves_working, Slave_Worker);
+ EINA_INLIST_FOREACH(list, sw)
+ {
+ sw->delete_me = EINA_TRUE;
+ _slave_quit_send(sw);
+ }
+}
+
+static void
+_timeout_cb(void)
+{
+ static unsigned int slaves_restart = 0;
+
+ slaves_restart++;
+
+ if (slaves_restart == 10)
+ {
+ DBG("kill slaves");
+ _slaves_restart();
+ slaves_restart = 0;
+ }
+
+ cserve2_timeout_cb_set(3000, _timeout_cb);
+}
+
+void
+cserve2_client_accept(int fd)
+{
+ Client *client = calloc(1, sizeof(*client));
+
+ client->socket = fd;
+ client->id = _client_id++;
+
+ while (eina_hash_find(client_list, &client->id))
+ client->id = _client_id++;
+
+ if (!eina_hash_add(client_list, &client->id, client))
+ {
+ Eina_Error err = eina_error_get();
+ ERR("Could not add client to the list: \"%s\"",
+ eina_error_msg_get(err));
+ free(client);
+ close(fd);
+ }
+
+ cserve2_fd_watch_add(fd, FD_READ | FD_ERROR, cserve2_message_handler,
+ client);
+ INF("Client %d connection accepted.", client->id);
+
+ cserve2_cache_client_new(client);
+}
+
+void
+cserve2_client_del(Client *client)
+{
+ eina_hash_del_by_key(client_list, &client->id);
+}
+
+static void
+_client_free(void *data)
+{
+ Client *client = data;
+ cserve2_cache_client_del(client);
+ if (client->msg.pending)
+ eina_binbuf_free(client->msg.pending);
+ cserve2_fd_watch_del(client->socket);
+ close(client->socket);
+ free(data);
+}
+
+static void
+_clients_setup(void)
+{
+ client_list = eina_hash_int32_new(_client_free);
+}
+
+static void
+_clients_finish(void)
+{
+ eina_hash_free(client_list);
+}
+
+int
+main(int argc __UNUSED__, const char *argv[] __UNUSED__)
+{
+ eina_init();
+
+ _evas_cserve2_bin_log_dom = eina_log_domain_register
+ ("evas_cserve2_bin", CSERVE2_BIN_DEFAULT_COLOR);
+ if (_evas_cserve2_bin_log_dom < 0)
+ {
+ EINA_LOG_ERR("impossible to create a log domain.");
+ eina_shutdown();
+ exit(1);
+ }
+
+ if (!cserve2_main_loop_setup())
+ {
+ ERR("could not setup main loop.");
+ goto error;
+ }
+
+ if (!cserve2_slaves_init())
+ {
+ ERR("Could not init slaves subsystem.");
+ goto error;
+ }
+
+ cserve2_requests_init();
+
+ cserve2_font_init();
+
+ cserve2_cache_init();
+
+ _clients_setup();
+
+ cserve2_timeout_cb_set(3000, _timeout_cb);
+
+ cserve2_main_loop_run();
+
+ _clients_finish();
+
+ cserve2_cache_shutdown();
+
+ cserve2_font_shutdown();
+
+ cserve2_requests_shutdown();
+
+ _slaves_restart();
+ cserve2_slaves_shutdown();
+
+ cserve2_main_loop_finish();
+
+ eina_log_domain_unregister(_evas_cserve2_bin_log_dom);
+ eina_shutdown();
+ return 0;
+
+error:
+ eina_log_domain_unregister(_evas_cserve2_bin_log_dom);
+ eina_shutdown();
+ exit(1);
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "evas_cserve2.h"
+
+#include <errno.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/inotify.h>
+#include <sys/signalfd.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define MAX_EPOLL_EVENTS 10
+#define MAX_INCOMING_CONN 10
+
+struct _Watch_Data
+{
+ int fd;
+ Fd_Flags flags;
+ Fd_Watch_Cb callback;
+ const void *user_data;
+};
+
+typedef struct _Watch_Data Watch_Data;
+
+struct _Inotify_Data
+{
+ EINA_INLIST;
+ const char *path;
+ int watchid;
+ File_Change_Cb cb;
+ const void *data;
+};
+
+typedef struct _Inotify_Data Inotify_Data;
+
+static int epoll_fd = -1;
+static int signal_fd = -1;
+static int socket_fd = -1;
+static int inotify_fd = -1;
+static struct sockaddr_un socket_local;
+static Eina_Hash *watch_list;
+static Eina_Hash *inotify_path_hash;
+static Eina_Hash *inotify_id_hash;
+static Eina_Bool running;
+static Eina_Bool terminate;
+static int timeout = -1; // in miliseconds
+static long timeout_time = 0; // in miliseconds
+
+static Timeout_Cb timeout_func = NULL;
+static Main_Loop_Child_Dead_Cb reap_children_func = NULL;
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(socket_local.sun_path)
+#endif
+
+static void
+_signal_handle_child(struct signalfd_siginfo *sinfo __UNUSED__)
+{
+ int status;
+ pid_t pid;
+
+ while ((pid = waitpid(0, &status, WNOHANG)) > 0)
+ {
+ if (reap_children_func)
+ {
+ reap_children_func(pid, status);
+ continue;
+ }
+
+ DBG("Received SIGCHLD and no handler is set.");
+
+ if (WIFEXITED(status))
+ DBG("Child '%d' exited with status '%d'.", pid,
+ WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ DBG("Child '%d' exited with signal '%d'.", pid,
+ WTERMSIG(status));
+ }
+}
+
+static void
+_signal_handle_int(struct signalfd_siginfo *sinfo __UNUSED__)
+{
+ DBG("Received SIGINT. Honoring request.");
+ terminate = EINA_TRUE;
+}
+
+static void
+_signal_handle_term(struct signalfd_siginfo *sinfo __UNUSED__)
+{
+ DBG("Received SIGTERM. Honoring request.");
+ terminate = EINA_TRUE;
+}
+
+static void
+_signalfd_handler(int fd, Fd_Flags flags __UNUSED__, void *data __UNUSED__)
+{
+ struct signalfd_siginfo sinfo;
+ ssize_t ret;
+
+ for (;;)
+ {
+ ret = read(fd, &sinfo, sizeof(struct signalfd_siginfo));
+ if (ret == -1)
+ {
+ if (errno == EAGAIN)
+ break;
+ ERR("Error reading from signal fd: %m.");
+ return;
+ }
+
+ switch(sinfo.ssi_signo)
+ {
+ case SIGCHLD:
+ _signal_handle_child(&sinfo);
+ break;
+ case SIGINT:
+ _signal_handle_int(&sinfo);
+ break;
+ case SIGTERM:
+ _signal_handle_term(&sinfo);
+ break;
+ default:
+ ERR("Caught unexpected signal '%d'.", sinfo.ssi_signo);
+ }
+ }
+}
+
+static int
+_signalfd_setup(void)
+{
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
+ {
+ ERR("Could not set mask of handled signals.");
+ return -1;
+ }
+
+ signal_fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
+ if (signal_fd == -1)
+ ERR("Could not create file descriptor from signalfd.");
+
+ /* ignore SIGPIPE so it's handled by write() and send() as needed */
+ signal(SIGPIPE, SIG_IGN);
+
+ return signal_fd;
+}
+
+static void
+_signalfd_finish(void)
+{
+ sigset_t mask;
+
+ cserve2_fd_watch_del(signal_fd);
+
+ sigemptyset(&mask);
+ sigprocmask(SIG_BLOCK, NULL, &mask);
+
+ close(signal_fd);
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+ signal(SIGPIPE, SIG_DFL);
+}
+
+static void
+_socketfd_handler(int fd __UNUSED__, Fd_Flags flags __UNUSED__, void *data __UNUSED__)
+{
+ struct sockaddr_un remote;
+ unsigned int len;
+ int s;
+
+ len = sizeof(struct sockaddr_un);
+ s = accept4(socket_fd, &remote, &len, SOCK_CLOEXEC);
+ if (s == -1)
+ {
+ ERR("Could not accept socket: \"%s\"", strerror(errno));
+ return;
+ }
+
+ cserve2_client_accept(s);
+}
+
+static void
+_socket_path_set(char *path)
+{
+ char *env;
+ char buf[UNIX_PATH_MAX];
+
+ env = getenv("EVAS_CSERVE2_SOCKET");
+ if (env && env[0])
+ {
+ strncpy(path, env, UNIX_PATH_MAX - 1);
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
+ /* FIXME: check we can actually create this socket */
+ strcpy(path, buf);
+ return;
+#if 0
+ env = getenv("XDG_RUNTIME_DIR");
+ if (!env || !env[0])
+ {
+ env = getenv("HOME");
+ if (!env || !env[0])
+ {
+ env = getenv("TMPDIR");
+ if (!env || !env[0])
+ env = "/tmp";
+ }
+ }
+
+ snprintf(buf, sizeof(buf), "%s/evas-cserve2-%x.socket", env, getuid());
+ /* FIXME: check we can actually create this socket */
+ strcpy(path, buf);
+#endif
+}
+
+static int
+_socketfd_setup(void)
+{
+ int s;
+ int len;
+
+ s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (s == -1)
+ {
+ ERR("Could not create socketfd: \"%s\"", strerror(errno));
+ return -1;
+ }
+
+ socket_local.sun_family = AF_UNIX;
+ _socket_path_set(socket_local.sun_path);
+ DBG("Using '%s' as server socket.", socket_local.sun_path);
+ unlink(socket_local.sun_path);
+ len = strlen(socket_local.sun_path) + sizeof(socket_local.sun_family);
+ if (bind(s, (struct sockaddr *)&socket_local, len) == -1)
+ {
+ ERR("Could not bind socketfd: \"%s\"", strerror(errno));
+ close(s);
+ return -1;
+ }
+
+ if (listen(s, MAX_INCOMING_CONN) == -1)
+ {
+ ERR("Could not listen on socketfd: \"%s\"", strerror(errno));
+ close(s);
+ unlink(socket_local.sun_path);
+ return -1;
+ }
+
+ socket_fd = s;
+
+ return s;
+}
+
+static void
+_socketfd_finish(void)
+{
+ close(socket_fd);
+ unlink(socket_local.sun_path);
+}
+
+static void
+_inotifyfd_handler(int fd, Fd_Flags flags, void *data __UNUSED__)
+{
+ char buffer[16384];
+ int i = 0;
+ ssize_t size;
+
+ if (flags & FD_ERROR)
+ {
+ ERR("Error on inotify file handler, what to do?");
+ return;
+ }
+
+ size = read(fd, buffer, sizeof(buffer));
+ while (i < size)
+ {
+ struct inotify_event *event;
+ int event_size;
+ Eina_Inlist *ids, *itr;
+ Inotify_Data *id;
+ Eina_Bool deleted;
+
+ event = (struct inotify_event *)&buffer[i];
+ event_size = sizeof(struct inotify_event) + event->len;
+ i += event_size;
+
+ ids = eina_hash_find(inotify_id_hash, &event->wd);
+ if (!ids) continue;
+
+ deleted = !!(event->mask
+ & (IN_DELETE_SELF | IN_MOVE_SELF
+ | IN_IGNORED | IN_UNMOUNT));
+ EINA_INLIST_FOREACH_SAFE(ids, itr, id)
+ id->cb(id->path, deleted, (void *)id->data);
+ }
+}
+
+static void
+_inotify_id_hash_free_cb(void *data)
+{
+ Eina_Inlist *list = data;
+
+ while (list)
+ {
+ Inotify_Data *id;
+ id = EINA_INLIST_CONTAINER_GET(list, Inotify_Data);
+ list = eina_inlist_remove(list, list);
+ eina_stringshare_del(id->path);
+ free(id);
+ }
+}
+
+static int
+_inotifyfd_setup(void)
+{
+ inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (inotify_fd == -1)
+ {
+ ERR("Could not create inotifyfd: \"%s\"", strerror(errno));
+ return -1;
+ }
+ inotify_path_hash = eina_hash_string_superfast_new(NULL);
+ inotify_id_hash = eina_hash_int32_new(_inotify_id_hash_free_cb);
+
+ return inotify_fd;
+}
+
+static void
+_inotifyfd_finish(void)
+{
+ close(inotify_fd);
+
+ eina_hash_free(inotify_path_hash);
+ eina_hash_free(inotify_id_hash);
+}
+
+static void
+_watch_data_free_cb(void *data)
+{
+ free(data);
+}
+
+Eina_Bool
+cserve2_main_loop_setup(void)
+{
+ int sfd;
+ int sock;
+ int ifd;
+
+ epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+
+ if (epoll_fd < 0)
+ {
+ ERR("Could not create epoll fd.");
+ return EINA_FALSE;
+ }
+
+ watch_list = eina_hash_int32_new(_watch_data_free_cb);
+ if (!watch_list)
+ {
+ ERR("Could not create watch list hash struct.");
+ close(epoll_fd);
+ return EINA_FALSE;
+ }
+
+ sfd = _signalfd_setup();
+ if (sfd == -1)
+ {
+ ERR("Could not setup signalfd.");
+ close(epoll_fd);
+ eina_hash_free(watch_list);
+ return EINA_FALSE;
+ }
+
+ DBG("Add watch for signal fd: %d", sfd);
+ if (!cserve2_fd_watch_add(sfd, FD_READ, _signalfd_handler, NULL))
+ {
+ ERR("Could not add watch for signalfd.");
+ close(sfd);
+ close(epoll_fd);
+ eina_hash_free(watch_list);
+ return EINA_FALSE;
+ }
+
+ sock = _socketfd_setup();
+ if (sock == -1)
+ {
+ ERR("Could not setup socketfd.");
+ goto error_socket;
+ }
+
+ DBG("Add watch for socket fd: %d", sock);
+ if (!cserve2_fd_watch_add(sock, FD_READ, _socketfd_handler, NULL))
+ {
+ ERR("Could not add watch for socketf.");
+ close(sock);
+ goto error_socket;
+ }
+
+ ifd = _inotifyfd_setup();
+ if (ifd == -1)
+ {
+ ERR("Could not setup inotify.");
+ goto error_inotify;
+ }
+
+ DBG("Add watch for inotify fd: %d", ifd);
+ if (!cserve2_fd_watch_add(ifd, FD_READ, _inotifyfd_handler, NULL))
+ {
+ ERR("Could not add watch for inotifyfd.");
+ close(ifd);
+ goto error_inotify;
+ }
+
+ return EINA_TRUE;
+
+error_inotify:
+ _socketfd_finish();
+
+error_socket:
+ close(sfd);
+ close(epoll_fd);
+ eina_hash_free(watch_list);
+ return EINA_FALSE;
+}
+
+void
+cserve2_main_loop_finish(void)
+{
+ _socketfd_finish();
+
+ _signalfd_finish();
+
+ _inotifyfd_finish();
+
+ eina_hash_free(watch_list);
+
+ close(epoll_fd);
+}
+
+Eina_Bool
+cserve2_fd_watch_add(int fd, Fd_Flags flags, Fd_Watch_Cb cb, const void *data)
+{
+ Watch_Data *w_data;
+ struct epoll_event ev;
+ int err;
+
+ DBG("Add watch for fd %d, flags = 0x%x", fd, flags);
+
+ if ((fd < 0) || (!cb))
+ {
+ ERR("Can't add watch: fd = %d, callback = %p", fd, cb);
+ return EINA_FALSE;
+ }
+
+ w_data = calloc(1, sizeof(*w_data));
+ w_data->fd = fd;
+ w_data->flags = flags;
+ w_data->callback = cb;
+ w_data->user_data = data;
+
+ if (!eina_hash_add(watch_list, &fd, w_data))
+ {
+ ERR("Could not add watch for fd %d to the hash.", fd);
+ free(w_data);
+ return EINA_FALSE;
+ }
+
+ memset(&ev, 0, sizeof(ev));
+ if (flags & FD_READ)
+ ev.events |= EPOLLIN;
+ if (flags & FD_WRITE)
+ ev.events |= EPOLLOUT;
+ ev.data.ptr = w_data;
+
+ err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
+ if (!err < 0)
+ {
+ ERR("Could not create epoll watch for fd %d.", fd);
+ eina_hash_del(watch_list, &fd, NULL);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+cserve2_fd_watch_flags_set(int fd, Fd_Flags flags)
+{
+ Watch_Data *w_data;
+ struct epoll_event ev;
+ int err;
+
+ DBG("Set watch flags for fd %d, flags = 0x%x", fd, flags);
+
+ if (fd < 0)
+ {
+ ERR("Can't modify watch: fd = %d", fd);
+ return EINA_FALSE;
+ }
+
+ w_data = eina_hash_find(watch_list, &fd);
+ if (!w_data)
+ {
+ ERR("Couldn't find data for fd %d: not being watched.", fd);
+ return EINA_FALSE;
+ }
+
+ if (flags == w_data->flags)
+ return EINA_TRUE;
+
+ memset(&ev, 0, sizeof(ev));
+ if (flags & FD_READ)
+ ev.events |= EPOLLIN;
+ if (flags & FD_WRITE)
+ ev.events |= EPOLLOUT;
+ ev.data.ptr = w_data;
+
+ err = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ev);
+ if (err < 0)
+ {
+ ERR("Could not modify epoll watch for fd: %d", fd);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+cserve2_fd_watch_flags_get(int fd, Fd_Flags *flags)
+{
+ Watch_Data *w_data;
+ if (fd < 0)
+ {
+ ERR("Can't get flags for watch: fd = %d", fd);
+ return EINA_FALSE;
+ }
+
+ w_data = eina_hash_find(watch_list, &fd);
+ if (!w_data)
+ {
+ ERR("Couldn't find data for fd: %d. Is it really being watched?", fd);
+ return EINA_FALSE;
+ }
+
+ *flags = w_data->flags;
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+cserve2_fd_watch_del(int fd)
+{
+ int err;
+
+ DBG("Remove watch for fd %d", fd);
+
+ if (fd < 0)
+ return EINA_FALSE;
+
+ if (!eina_hash_del(watch_list, &fd, NULL))
+ ERR("Could not remove watch for fd %d from watch list hash.", fd);
+
+ err = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+ if (err < 0)
+ {
+ ERR("Could not remove epoll watch for fd %d.", fd);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+cserve2_file_change_watch_add(const char *path, File_Change_Cb cb, const void *data)
+{
+ Inotify_Data *id;
+ Eina_Inlist *ids;
+ unsigned int mask = IN_ATTRIB | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF;
+
+ id = eina_hash_find(inotify_path_hash, path);
+ if (id)
+ {
+ ERR("Attempt to watch changes for path '%s', which is already "
+ "being watched.", path);
+ return EINA_FALSE;
+ }
+
+ id = calloc(1, sizeof(Inotify_Data));
+ if (!id)
+ {
+ ERR("Could not alloc Inotify_Data instance.");
+ return EINA_FALSE;
+ }
+
+ id->watchid = inotify_add_watch(inotify_fd, path, mask);
+ if (id->watchid == -1)
+ {
+ ERR("Could not add inotify watch for %s: %m.", path);
+ free(id);
+ return EINA_FALSE;
+ }
+
+ id->path = eina_stringshare_add(path);
+ id->cb = cb;
+ id->data = data;
+
+ eina_hash_direct_add(inotify_path_hash, id->path, id);
+
+ ids = eina_hash_find(inotify_id_hash, &id->watchid);
+ ids = eina_inlist_append(ids, EINA_INLIST_GET(id));
+ eina_hash_set(inotify_id_hash, &id->watchid, ids);
+
+ return EINA_TRUE;
+}
+
+Eina_Bool
+cserve2_file_change_watch_del(const char *path)
+{
+ Inotify_Data *id;
+ Eina_Inlist *ids;
+ int wd;
+
+ id = eina_hash_set(inotify_path_hash, path, NULL);
+ if (!id)
+ {
+ ERR("Requested to remove change watch for %s, but it's not being "
+ "watched.", path);
+ return EINA_FALSE;
+ }
+
+ ids = eina_hash_find(inotify_id_hash, &id->watchid);
+ ids = eina_inlist_remove(ids, EINA_INLIST_GET(id));
+ eina_hash_set(inotify_id_hash, &id->watchid, ids);
+
+ wd = id->watchid;
+ eina_stringshare_del(id->path);
+ free(id);
+
+ if (!ids)
+ {
+ if (inotify_rm_watch(inotify_fd, wd) == -1)
+ {
+ ERR("Could not remove change watch for %s: %m", path);
+ return EINA_FALSE;
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_update_timeout(void)
+{
+ struct timeval timev;
+ long cur_time;
+
+ if (timeout <= 0)
+ return;
+
+ gettimeofday(&timev, NULL);
+ cur_time = timev.tv_sec * 1000 + timev.tv_usec / 1000;
+ timeout -= cur_time - timeout_time;
+ timeout_time = cur_time;
+
+ if (timeout < 0)
+ timeout = 0;
+}
+
+void
+cserve2_timeout_cb_set(int t, Timeout_Cb cb)
+{
+ struct timeval timev;
+ if (cb && t <= 0)
+ {
+ ERR("timeout must be a value greater than 0 to set a callback."
+ " given timeout: %d miliseconds", t);
+ return;
+ }
+
+ if (!cb)
+ {
+ DBG("Removing timeout callback.");
+ timeout = -1;
+ cb = NULL;
+ return;
+ }
+
+ //DBG("Setting timeout to: %d miliseconds", t);
+ gettimeofday(&timev, NULL);
+ timeout_time = timev.tv_sec * 1000 + timev.tv_usec / 1000;
+ timeout = t;
+ timeout_func = cb;
+}
+
+void
+cserve2_on_child_dead_set(Main_Loop_Child_Dead_Cb cb)
+{
+ reap_children_func = cb;
+}
+
+void
+cserve2_main_loop_run(void)
+{
+ running = EINA_TRUE;
+ terminate = EINA_FALSE;
+
+ for (;;)
+ {
+ struct epoll_event events[MAX_EPOLL_EVENTS];
+ int n, nfds;
+
+ if (terminate)
+ break;
+
+ nfds = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, timeout);
+ if (nfds < 0)
+ {
+ ERR("An error occurred when reading the epoll fd.");
+ ERR("%s", strerror(errno));
+ break;
+ }
+ if (nfds == 0) // timeout occurred
+ {
+ timeout = -1;
+ if (!timeout_func)
+ ERR("Timeout expired, but no timeout function set.");
+ else
+ timeout_func();
+ }
+
+ for (n = 0; n < nfds; n++)
+ {
+ Watch_Data *data = events[n].data.ptr;
+ Fd_Flags flags = 0;
+
+ if (!data)
+ continue;
+
+ if (!data->callback)
+ continue;
+
+ if (events[n].events & EPOLLIN)
+ flags |= FD_READ;
+ if (events[n].events & EPOLLOUT)
+ flags |= FD_WRITE;
+ if (events[n].events & EPOLLERR)
+ flags |= FD_ERROR;
+ data->callback(data->fd, flags, (void *)data->user_data);
+ }
+
+ _update_timeout();
+ }
+
+ running = EINA_FALSE;
+}
+
+ssize_t
+cserve2_client_read(Client *client, void *buf, size_t len)
+{
+ return recv(client->socket, buf, len, MSG_DONTWAIT);
+}
+
+ssize_t
+cserve2_client_write(Client *client, const void *data, size_t size)
+{
+ return send(client->socket, data, size, MSG_NOSIGNAL | MSG_DONTWAIT);
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+#include "evas_cserve2.h"
+
+// #define DEBUG_MSG 1
+
+static void
+debug_msg(const char *typestr, const void *buf, int size)
+{
+#ifdef DEBUG_MSG
+ const char *str = buf;
+ int i;
+
+ printf("message %s: ", typestr);
+ for (i = 0; i < size; i++)
+ printf("%x ", str[i]);
+
+ printf("\n");
+#else
+ (void)typestr;
+ (void)buf;
+ (void)size;
+#endif
+}
+
+static void
+_client_msg_allocate_buf(Client *client, int msgsize)
+{
+ client->msg.reading = EINA_TRUE;
+ client->msg.buf = malloc(msgsize + 1);
+ client->msg.size = msgsize;
+ client->msg.done = 0;
+}
+
+static void
+_client_msg_free(Client *client)
+{
+ client->msg.reading = EINA_FALSE;
+ free(client->msg.buf);
+}
+
+static void
+_client_msg_parse(Client *client)
+{
+ Msg_Base *msg = (Msg_Base *)client->msg.buf;
+ DBG("Message received. Size: %d; type = %d",
+ client->msg.size, msg->type);
+
+ cserve2_command_run(client, msg->type);
+}
+
+static void
+_client_msg_read(Client *client, int done)
+{
+ client->msg.done += done;
+ if (client->msg.done == client->msg.size)
+ {
+ debug_msg("received", client->msg.buf, client->msg.size);
+ _client_msg_parse(client);
+ _client_msg_free(client);
+ }
+}
+
+void
+cserve2_message_handler(int fd __UNUSED__, Fd_Flags flags, void *data)
+{
+ Client *client = data;
+ int len;
+ int msgsize;
+
+ if (flags & FD_ERROR)
+ {
+ ERR("Error on socket for client: %d", client->id);
+ goto client_close;
+ }
+
+ if (flags & FD_WRITE)
+ cserve2_client_deliver(client);
+
+ if (!(flags & FD_READ))
+ return;
+
+ if (!client->msg.reading)
+ len = cserve2_client_read(client, &msgsize, sizeof(msgsize));
+ else
+ len = cserve2_client_read(client, &client->msg.buf[client->msg.done],
+ client->msg.size - client->msg.done);
+
+ if (!len)
+ {
+ INF("Client %d connection closed.", client->id);
+ goto client_close;
+ }
+
+ if (len < 0)
+ {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ {
+ WRN("No data to read but the message handler was called.");
+ return;
+ }
+ WRN("Error when reading message from client: \"%s\"",
+ strerror(errno));
+ // FIXME: Should we close the connection, or just send an ERROR
+ // message?
+ goto client_close;
+ }
+
+ if (!client->msg.reading)
+ _client_msg_allocate_buf(client, msgsize);
+ else
+ _client_msg_read(client, len);
+
+ return;
+
+client_close:
+ if (client->msg.reading)
+ _client_msg_free(client);
+ cserve2_client_del(client);
+}
+
+void
+cserve2_client_deliver(Client *client)
+{
+ size_t sent, size;
+ const char *str;
+
+ if (!client->msg.pending)
+ {
+ Fd_Flags cur_flags;
+ cserve2_fd_watch_flags_get(client->socket, &cur_flags);
+ cur_flags ^= FD_WRITE;
+ cserve2_fd_watch_flags_set(client->socket, cur_flags);
+ return;
+ }
+
+ size = eina_binbuf_length_get(client->msg.pending);
+ str = (const char *)eina_binbuf_string_get(client->msg.pending);
+ sent = cserve2_client_write(client, str, size);
+ if (sent == size)
+ {
+ eina_binbuf_free(client->msg.pending);
+ client->msg.pending = NULL;
+ return;
+ }
+
+ eina_binbuf_remove(client->msg.pending, 0, sent);
+}
+
+ssize_t
+cserve2_client_send(Client *client, const void *data, size_t size)
+{
+ ssize_t sent;
+
+ debug_msg("sent", data, size);
+ if (client->msg.pending)
+ {
+ eina_binbuf_append_length
+ (client->msg.pending, (unsigned char *)data, size);
+ return size;
+ }
+
+ sent = cserve2_client_write(client, data, size);
+ if ((sent < 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK)))
+ {
+ // FIXME: Big error when writing on the socket to the client,
+ // so we must close the connection to the client and remove
+ // its references inside our cache.
+ WRN("Error on socket with client %d: %s", client->id, strerror(errno));
+ if (client->msg.reading)
+ _client_msg_free(client);
+ cserve2_client_del(client);
+ return sent;
+ }
+ if (sent < 0)
+ sent = 0;
+ if (sent < (int)size)
+ {
+ Fd_Flags cur_flags;
+ client->msg.pending = eina_binbuf_new();
+ eina_binbuf_append_length
+ (client->msg.pending, (unsigned char *)data + sent, size - sent);
+ cserve2_fd_watch_flags_get(client->socket, &cur_flags);
+ cur_flags |= FD_WRITE;
+ cserve2_fd_watch_flags_set(client->socket, cur_flags);
+ }
+ return size;
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "evas_cserve2.h"
+
+#define MAX_SLAVES 1
+
+typedef enum
+{
+ SLAVE_IMAGE,
+ SLAVE_FONT,
+ SLAVE_NONE
+} Slave_Type;
+
+struct _Slave_Worker
+{
+ Slave_Type type;
+ void *data;
+ Slave *slave;
+ Eina_Binbuf *ret;
+ int ret_size;
+ Eina_Bool done;
+ Eina_Bool delete_me;
+};
+
+typedef struct _Slave_Worker Slave_Worker;
+
+/* This struct is used to match font request types to the respective slave
+ * type, and the message type that will be used for that request. The order
+ * of the request types on it is the order in which these requests will
+ * be processed.
+ */
+static struct _Request_Match
+{
+ Font_Request_Type rtype;
+ Slave_Type stype;
+ Slave_Command ctype;
+} _request_match[] =
+{
+ { CSERVE2_REQ_FONT_LOAD, SLAVE_FONT, FONT_LOAD },
+ { CSERVE2_REQ_FONT_GLYPHS_LOAD, SLAVE_FONT, FONT_GLYPHS_LOAD },
+ { CSERVE2_REQ_LAST, 0 }
+};
+
+static Slave *_create_image_slave(void *data);
+static Slave *_create_font_slave(void *data);
+
+static struct _Worker
+{
+ Slave_Type type;
+ unsigned int max;
+ Eina_List *idle;
+ Eina_List *working;
+ Slave *(*create_slave)(void *data);
+} _workers[] =
+{
+ { SLAVE_IMAGE, 3, NULL, NULL, _create_image_slave },
+ { SLAVE_FONT, 1, NULL, NULL, _create_font_slave },
+};
+
+struct _Font_Request
+{
+ EINA_INLIST;
+ Font_Request_Type type;
+ void *data;
+ void *msg;
+ Eina_List *waiters;
+ Eina_Bool processing;
+ Font_Request_Funcs *funcs;
+};
+
+struct _Waiter
+{
+ unsigned int rid;
+ Client *client;
+};
+
+typedef struct _Waiter Waiter;
+
+struct _Request_Queue
+{
+ Eina_Inlist *waiting;
+ Eina_Inlist *processing;
+};
+
+typedef struct _Request_Queue Request_Queue;
+
+static Request_Queue *requests = NULL;
+// static Eina_List *processing = NULL;
+
+static void
+_request_waiter_add(Font_Request *req, Client *client, unsigned int rid)
+{
+ Waiter *w = malloc(sizeof(*w));
+
+ DBG("Add waiter to request. Client: %d, rid: %d", client->id, rid);
+
+ w->client = client;
+ w->rid = rid;
+
+ req->waiters = eina_list_append(req->waiters, w);
+}
+
+Font_Request *
+cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs, void *data)
+{
+ Font_Request *req, *r;
+
+ req = NULL;
+
+ EINA_INLIST_FOREACH(requests[type].processing, r)
+ {
+ if (r->data == data)
+ continue;
+
+ req = r;
+ break;
+ }
+
+ if (!req)
+ {
+ EINA_INLIST_FOREACH(requests[type].waiting, r)
+ {
+ if (r->data != data)
+ continue;
+
+ req = r;
+ break;
+ }
+ }
+
+ if (!req)
+ {
+ DBG("Add request for rid: %d", rid);
+ req = malloc(sizeof(*req));
+ req->data = data;
+ req->waiters = NULL;
+ req->processing = EINA_FALSE;
+ requests[type].waiting = eina_inlist_append(requests[type].waiting,
+ EINA_INLIST_GET(req));
+ }
+
+ _request_waiter_add(req, client, rid);
+
+ return req;
+}
+
+void
+cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err)
+{
+ Eina_List *l, *l_next;
+ Waiter *w;
+
+ EINA_LIST_FOREACH_SAFE(req->waiters, l, l_next, w)
+ {
+ if (w->client->id == client->id)
+ {
+ DBG("Removing answer from waiter client: %d, rid: %d",
+ client->id, w->rid);
+ if (req->funcs && req->funcs->error)
+ req->funcs->error(client, req->data, err, w->rid);
+ req->waiters = eina_list_remove_list(req->waiters, l);
+ free(w);
+ }
+ }
+
+ // TODO: When we have speculative preload, there may be no waiters,
+ // so we need a flag or something else to make things still load.
+ if (!req->waiters)
+ {
+ Eina_Inlist **reqlist = &requests[req->type].waiting;
+ *reqlist = eina_inlist_remove(*reqlist, EINA_INLIST_GET(req));
+ // TODO: If the request is being processed, it can't be deleted. Must
+ // be marked as delete_me instead.
+ req->funcs->msg_free(req->msg);
+ free(req);
+ }
+
+}
+
+void
+cserve2_request_cancel_all(Font_Request *req, Error_Type err)
+{
+ Waiter *w;
+
+ DBG("Removing all answers.");
+
+ EINA_LIST_FREE(req->waiters, w)
+ {
+ DBG("Removing answer from waiter client: %d, rid: %d",
+ w->client->id, w->rid);
+ if (req->funcs && req->funcs->error)
+ req->funcs->error(w->client, req->data, err, w->rid);
+ free(w);
+ }
+
+ requests[req->type].waiting = eina_inlist_remove(
+ requests[req->type].waiting, EINA_INLIST_GET(req));
+ req->funcs->msg_free(req->msg);
+ free(req);
+}
+
+void
+cserve2_requests_init(void)
+{
+ DBG("Initializing requests.");
+ requests = calloc(CSERVE2_REQ_LAST, sizeof(*requests));
+}
+
+void
+cserve2_requests_shutdown(void)
+{
+ DBG("Shutting down requests.");
+ free(requests);
+}
+
+static void
+_cserve2_request_failed(Font_Request *req, Error_Type type)
+{
+ Waiter *w;
+
+ EINA_LIST_FREE(req->waiters, w)
+ {
+ req->funcs->error(w->client, req->data, type, w->rid);
+ free(w);
+ }
+
+ req->funcs->msg_free(req->msg);
+ requests[req->type].processing = eina_inlist_remove(
+ requests[req->type].processing, EINA_INLIST_GET(req));
+ free(req);
+}
+
+static void
+_slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data)
+{
+ Slave_Worker *sw = data;
+ Font_Request *req = sw->data;
+ Eina_List **working, **idle;
+ Waiter *w;
+
+ EINA_LIST_FREE(req->waiters, w)
+ {
+ if (cmd == ERROR)
+ {
+ Error_Type *err = msg;
+ req->funcs->error(w->client, req->data, *err, w->rid);
+ }
+ else
+ req->funcs->response(w->client, req->data, msg, w->rid);
+ free(w);
+ }
+
+ req->funcs->msg_free(req->msg);
+ // FIXME: We shouldn't free this message directly, it must be freed by a
+ // callback.
+ free(msg);
+ requests[req->type].processing = eina_inlist_remove(
+ requests[req->type].processing, EINA_INLIST_GET(req));
+ free(req);
+ sw->data = NULL;
+
+ working = &_workers[sw->type].working;
+ idle = &_workers[sw->type].idle;
+ *working = eina_list_remove(*working, sw);
+ *idle = eina_list_append(*idle, sw);
+}
+
+static void
+_slave_dead_cb(Slave *s __UNUSED__, void *data)
+{
+ Slave_Worker *sw = data;
+ Font_Request *req = sw->data;
+ Eina_List **working = &_workers[sw->type].working;
+
+ if (req)
+ _cserve2_request_failed(req, CSERVE2_LOADER_DIED);
+
+ *working = eina_list_remove(*working, sw);
+ free(sw);
+}
+
+static Slave *
+_create_image_slave(void *data)
+{
+ char *exe;
+ Slave *slave;
+
+ exe = getenv("EVAS_CSERVE2_SLAVE");
+ if (!exe) exe = "evas_cserve2_slave";
+
+ slave = cserve2_slave_run(exe, _slave_read_cb,
+ _slave_dead_cb, data);
+
+ return slave;
+}
+
+static Slave *
+_create_font_slave(void *data)
+{
+ Slave *slave;
+
+ slave = cserve2_slave_thread_run(cserve2_font_slave_cb, NULL,
+ _slave_read_cb, _slave_dead_cb,
+ data);
+
+ return slave;
+}
+
+static Slave_Worker *
+_slave_for_request_create(Slave_Type type)
+{
+ Slave_Worker *sw;
+ Slave *slave;
+
+ sw = calloc(1, sizeof(Slave_Worker));
+ if (!sw) return NULL;
+
+ slave = _workers[type].create_slave(sw);
+ if (!slave)
+ {
+ ERR("Could not launch slave process");
+ free(sw);
+ return NULL;
+ }
+
+ sw->slave = slave;
+ sw->type = type;
+ _workers[type].idle = eina_list_append(_workers[type].idle, sw);
+
+ return sw;
+}
+
+static Eina_Bool
+_cserve2_request_dispatch(Slave_Worker *sw, Slave_Command ctype, Font_Request *req)
+{
+ int size;
+ char *slave_msg = req->funcs->msg_create(req->data, &size);
+
+ if (!slave_msg)
+ {
+ ERR("Could not create slave message for request type %d.", req->type);
+ return EINA_FALSE;
+ }
+
+ req->msg = slave_msg;
+ sw->data = req;
+ cserve2_slave_send(sw->slave, ctype, slave_msg, size);
+ req->processing = EINA_TRUE;
+
+ return EINA_TRUE;
+}
+
+void
+cserve2_requests_process(void)
+{
+ int rtype, j;
+
+ for (rtype = 0; rtype < CSERVE2_REQ_LAST; rtype++)
+ {
+ Slave_Type type = SLAVE_NONE;
+ Slave_Command ctype;
+ unsigned int max_workers;
+ Eina_List **idle, **working;
+
+ for (j = 0; _request_match[j].rtype != CSERVE2_REQ_LAST; j++)
+ {
+ if (_request_match[j].rtype == j)
+ {
+ type = _request_match[j].stype;
+ ctype = _request_match[j].ctype;
+ break;
+ }
+ }
+
+ if (type == SLAVE_NONE)
+ continue;
+
+ if (!requests[rtype].waiting)
+ continue;
+
+ /* Now we have the worker type to use (image or font), and the list
+ * of requests to process. Just process as many requests as we can.
+ */
+ max_workers = _workers[type].max;
+ idle = &_workers[type].idle;
+ working = &_workers[type].working;
+
+ while (requests[j].waiting &&
+ (eina_list_count(*working) < max_workers))
+ {
+ Slave_Worker *sw;
+ Font_Request *req = EINA_INLIST_CONTAINER_GET(
+ requests[rtype].waiting, Font_Request);
+
+ requests[rtype].waiting = eina_inlist_remove(
+ requests[rtype].waiting, requests[rtype].waiting);
+ requests[rtype].processing = eina_inlist_append(
+ requests[rtype].processing, EINA_INLIST_GET(req));
+
+ if (!(*idle))
+ sw = _slave_for_request_create(type);
+
+ if (!(*idle))
+ {
+ ERR("No idle slave available to process request type %d.",
+ rtype);
+ _cserve2_request_failed(req, CSERVE2_GENERIC);
+ continue;
+ }
+
+ sw = eina_list_data_get(*idle);
+ if (!_cserve2_request_dispatch(sw, ctype, req))
+ {
+ ERR("Could not dispatch request.");
+ _cserve2_request_failed(req, CSERVE2_GENERIC);
+ continue;
+ }
+
+ *idle = eina_list_remove_list(*idle, *idle);
+ *working = eina_list_append(*working, sw);
+
+ }
+ }
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "evas_cserve2.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+struct _Shm_Mapping
+{
+ const char *name;
+ size_t length;
+ Eina_Inlist *segments;
+};
+
+typedef struct _Shm_Mapping Shm_Mapping;
+
+struct _Shm_Handle
+{
+ EINA_INLIST;
+ Shm_Mapping *mapping;
+ off_t map_offset;
+ off_t image_offset;
+ size_t map_size;
+ size_t image_size;
+};
+
+static int id = 0;
+
+Shm_Handle *
+cserve2_shm_request(size_t size)
+{
+ Shm_Mapping *map;
+ Shm_Handle *shm;
+ char shmname[NAME_MAX];
+ size_t map_size;
+ long pagesize;
+ int fd;
+
+ map = calloc(1, sizeof(Shm_Mapping));
+ if (!map)
+ {
+ ERR("Failed to allocate mapping handler.");
+ return NULL;
+ }
+
+ do {
+ snprintf(shmname, sizeof(shmname), "/evas-shm-img-%d", id++);
+ fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ if (fd == -1 && errno != EEXIST)
+ {
+ ERR("Failed to create shared memory object '%s': %m", shmname);
+ free(map);
+ return NULL;
+ }
+ } while (fd == -1);
+
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize < 1)
+ {
+ ERR("sysconf() reported weird value for PAGESIZE, assuming 4096.");
+ pagesize = 4096;
+ }
+
+ map_size = ((size + pagesize - 1) / pagesize) * pagesize;
+
+ if (ftruncate(fd, map_size) == -1)
+ {
+ ERR("Failed to set size of shared file: %m");
+ close(fd);
+ free(map);
+ return NULL;
+ }
+ close(fd);
+
+ map->name = eina_stringshare_add(shmname);
+ map->length = map_size;
+
+ shm = calloc(1, sizeof(Shm_Handle));
+ if (!shm)
+ {
+ ERR("Failed to allocate shared memory handler.");
+ eina_stringshare_del(map->name);
+ free(map);
+ return NULL;
+ }
+
+ map->segments = eina_inlist_append(map->segments, EINA_INLIST_GET(shm));
+ shm->mapping = map;
+ shm->map_offset = 0;
+ shm->image_offset = 0;
+
+ shm->image_size = size;
+ shm->map_size = map_size;
+
+ return shm;
+}
+
+void
+cserve2_shm_unref(Shm_Handle *shm)
+{
+ Shm_Mapping *map = shm->mapping;
+
+ map->segments = eina_inlist_remove(map->segments, EINA_INLIST_GET(shm));
+ free(shm);
+
+ if (map->segments)
+ return;
+
+ shm_unlink(map->name);
+ eina_stringshare_del(map->name);
+ free(map);
+}
+
+const char *
+cserve2_shm_name_get(const Shm_Handle *shm)
+{
+ return shm->mapping->name;
+}
+
+off_t
+cserve2_shm_map_offset_get(const Shm_Handle *shm)
+{
+ return shm->map_offset;
+}
+
+off_t
+cserve2_shm_offset_get(const Shm_Handle *shm)
+{
+ return shm->image_offset;
+}
+
+size_t
+cserve2_shm_map_size_get(const Shm_Handle *shm)
+{
+ return shm->map_size;
+}
+
+size_t
+cserve2_shm_size_get(const Shm_Handle *shm)
+{
+ return shm->image_size;
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+static Eina_Hash *loaders = NULL;
+static Eina_List *modules = NULL;
+
+struct ext_loader_s
+{
+ unsigned int length;
+ const char *extension;
+ const char *loader;
+};
+
+#define MATCHING(Ext, Module) \
+ { sizeof (Ext), Ext, Module }
+
+static const struct ext_loader_s map_loaders[] =
+{ /* map extensions to loaders to use for good first-guess tries */
+ MATCHING(".png", "png"),
+ MATCHING(".jpg", "jpeg"),
+ MATCHING(".jpeg", "jpeg"),
+ MATCHING(".jfif", "jpeg"),
+ MATCHING(".eet", "eet"),
+ MATCHING(".edj", "eet"),
+ MATCHING(".eap", "eet"),
+ MATCHING(".edb", "edb"),
+ MATCHING(".xpm", "xpm"),
+ MATCHING(".tiff", "tiff"),
+ MATCHING(".tif", "tiff"),
+ MATCHING(".svg", "svg"),
+ MATCHING(".svgz", "svg"),
+ MATCHING(".svg.gz", "svg"),
+ MATCHING(".gif", "gif"),
+ MATCHING(".pbm", "pmaps"),
+ MATCHING(".pgm", "pmaps"),
+ MATCHING(".ppm", "pmaps"),
+ MATCHING(".pnm", "pmaps"),
+ MATCHING(".bmp", "bmp"),
+ MATCHING(".tga", "tga"),
+ MATCHING(".wbmp", "wbmp"),
+ MATCHING(".ico", "ico"),
+ MATCHING(".cur", "ico"),
+ MATCHING(".psd", "psd")
+};
+
+static const char *loaders_name[] =
+{ /* in order of most likely needed */
+ "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb"
+};
+
+Eina_Bool
+evas_cserve2_loader_register(Evas_Loader_Module_Api *api)
+{
+ eina_hash_direct_add(loaders, api->type, api);
+ return EINA_TRUE;
+}
+
+#if defined(__CEGCC__) || defined(__MINGW32CE__)
+# define EVAS_MODULE_NAME_IMAGE_LOADER "loader_%s.dll"
+#elif _WIN32
+# define EVAS_MODULE_NAME_IMAGE_LOADER "module.dll"
+#else
+# define EVAS_MODULE_NAME_IMAGE_LOADER "module.so"
+#endif
+
+static Evas_Loader_Module_Api *
+loader_module_find(const char *type)
+{
+ Evas_Loader_Module_Api *l;
+ Eina_Module *em;
+ char buf[PATH_MAX];
+
+ l = eina_hash_find(loaders, type);
+ if (l) return l;
+
+ /* FIXME: Look in every possible path, but what will those be? */
+ snprintf(buf, sizeof(buf), PACKAGE_LIB_DIR "/evas/cserve2/loaders/%s/%s/%s",
+ type, MODULE_ARCH, EVAS_MODULE_NAME_IMAGE_LOADER);
+
+ em = eina_module_new(buf);
+ if (!em) return NULL;
+
+ if (!eina_module_load(em))
+ {
+ eina_module_free(em);
+ return NULL;
+ }
+
+ l = eina_hash_find(loaders, type);
+ if (l)
+ {
+ modules = eina_list_append(modules, em);
+ return l;
+ }
+
+ eina_module_free(em);
+
+ return NULL;
+}
+
+static Eina_Bool
+command_read(int fd, Slave_Command *cmd, void **params)
+{
+ ssize_t ret;
+ int ints[2], size, got = 0;
+ char *buf;
+
+ ret = read(fd, ints, sizeof(int) * 2);
+ if (ret < (int)sizeof(int) * 2)
+ return EINA_FALSE;
+
+ size = ints[0];
+ buf = malloc(size);
+ if (!buf) return EINA_FALSE;
+
+ do {
+ ret = read(fd, buf + got, size - got);
+ if (ret < 0)
+ {
+ /* EINTR means we were interrupted by a signal before anything
+ * was sent, and if we are back here it means that signal was
+ * not meant for us to die. Any other error here is fatal and
+ * should result in the slave terminating.
+ */
+ if (errno == EINTR)
+ continue;
+ free(buf);
+ return EINA_FALSE;
+ }
+ got += ret;
+ } while (got < size);
+
+ *cmd = ints[1];
+ *params = buf;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+response_send(int fd, Slave_Command cmd, void *resp, int size)
+{
+ int sent = 0, ints[2];
+ const char *data = resp;
+ ssize_t ret;
+
+ ints[0] = size;
+ ints[1] = cmd;
+ ret = write(fd, ints, sizeof(int) * 2);
+ if (ret < 0)
+ return EINA_FALSE;
+ if (!size)
+ return EINA_TRUE;
+ do {
+ ret = write(fd, data + sent, size - sent);
+ if (ret < 0)
+ {
+ /* EINTR means we were interrupted by a signal before anything
+ * was sent, and if we are back here it means that signal was
+ * not meant for us to die. Any other error here is fatal and
+ * should result in the slave terminating.
+ */
+ if (errno == EINTR)
+ continue;
+ return EINA_FALSE;
+ }
+ sent += ret;
+ } while (sent < size);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+error_send(int fd, Error_Type err)
+{
+ return response_send(fd, ERROR, &err, sizeof(Error_Type));
+}
+
+void *
+cserve2_shm_map(const char *name, size_t length, off_t offset)
+{
+ void *map;
+ int fd;
+
+ fd = shm_open(name, O_RDWR, S_IWUSR);
+ if (fd == -1)
+ return MAP_FAILED;
+
+ map = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, offset);
+
+ close(fd);
+
+ return map;
+}
+
+void
+cserve2_shm_unmap(void *map, size_t length)
+{
+ munmap(map, length);
+}
+
+static Error_Type
+image_open(const char *file, const char *key, Image_Load_Opts *opts, Slave_Msg_Image_Opened *result, const char **use_loader)
+{
+ Evas_Img_Load_Params ilp;
+ Evas_Loader_Module_Api *api;
+ const char *loader = NULL, *end;
+ unsigned int i;
+ int len;
+ int err;
+
+ memset(&ilp, 0, sizeof(ilp));
+
+ if (opts)
+ {
+#define SETOPT(v) ilp.opts.v = opts->v
+ SETOPT(w);
+ SETOPT(h);
+ SETOPT(rx);
+ SETOPT(ry);
+ SETOPT(rw);
+ SETOPT(rh);
+ SETOPT(scale_down_by);
+ SETOPT(dpi);
+ SETOPT(orientation);
+#undef SETOPT
+ ilp.has_opts = EINA_TRUE;
+ }
+
+ if (!*use_loader)
+ goto try_extension;
+
+ loader = *use_loader;
+ api = loader_module_find(loader);
+ if (!api)
+ goto try_extension;
+
+ if (api->head_load(&ilp, file, key, &err))
+ goto done;
+
+try_extension:
+ len = strlen(file);
+ end = file + len;
+ for (i = 0; i < (sizeof (map_loaders) / sizeof(struct ext_loader_s)); i++)
+ {
+ int len2 = strlen(map_loaders[i].extension);
+ if (len2 > len) continue;
+ if (!strcasecmp(end - len2, map_loaders[i].extension))
+ {
+ loader = map_loaders[i].loader;
+ break;
+ }
+ }
+
+ if (!loader)
+ goto try_all_known;
+
+ api = loader_module_find(loader);
+ if (!api)
+ goto try_all_known;
+
+ if (api->head_load(&ilp, file, key, &err))
+ goto done;
+
+try_all_known:
+ for (i = 0; i < (sizeof(loaders_name) / sizeof(loaders_name[0])); i++)
+ {
+ loader = loaders_name[i];
+ api = loader_module_find(loader);
+ if (!api)
+ continue;
+ if (api->head_load(&ilp, file, key, &err))
+ goto done;
+ }
+
+ /* find every module available and try them, even if we don't know they
+ * exist. That will be our generic loader */
+
+ return err;
+
+done:
+ *use_loader = loader;
+
+ result->w = ilp.w;
+ result->h = ilp.h;
+ if ((result->rotated = ilp.rotated))
+ {
+ result->degree = ilp.degree;
+ }
+ if ((result->animated = ilp.animated))
+ {
+ result->frame_count = ilp.frame_count;
+ result->loop_count = ilp.loop_count;
+ result->loop_hint = ilp.loop_hint;
+ }
+ result->scale = ilp.scale;
+ result->alpha = ilp.alpha;
+ return CSERVE2_NONE;
+}
+
+static Error_Type
+image_load(const char *file, const char *key, const char *shmfile, Slave_Msg_Image_Load *params, Slave_Msg_Image_Loaded *result, const char *loader)
+{
+ Evas_Img_Load_Params ilp;
+ Evas_Loader_Module_Api *api;
+ int err;
+ Error_Type ret = CSERVE2_NONE;
+ char *map = cserve2_shm_map(shmfile, params->shm.mmap_size,
+ params->shm.mmap_offset);
+ if (map == MAP_FAILED)
+ return CSERVE2_RESOURCE_ALLOCATION_FAILED;
+
+ memset(&ilp, 0, sizeof(ilp));
+
+ api = loader_module_find(loader);
+ if (!api)
+ {
+ ret = CSERVE2_GENERIC;
+ goto done;
+ }
+
+ ilp.w = params->w;
+ ilp.h = params->h;
+ ilp.alpha = params->alpha;
+#define SETOPT(v) ilp.opts.v = params->opts.v
+ SETOPT(w);
+ SETOPT(h);
+ SETOPT(rx);
+ SETOPT(ry);
+ SETOPT(rw);
+ SETOPT(rh);
+ SETOPT(scale_down_by);
+ SETOPT(dpi);
+ SETOPT(orientation);
+#undef SETOPT
+
+ ilp.buffer = map + params->shm.image_offset;
+ if (!api->data_load(&ilp, file, key, &err))
+ ret = err;
+
+ result->alpha_sparse = ilp.alpha_sparse;
+
+done:
+ cserve2_shm_unmap(map, params->shm.mmap_size);
+
+ return ret;
+}
+
+static void
+handle_image_open(int wfd, void *params)
+{
+ Slave_Msg_Image_Open *p;
+ Slave_Msg_Image_Opened result;
+ Image_Load_Opts *load_opts = NULL;
+ Error_Type err;
+ const char *loader = NULL, *file, *key, *ptr;
+ char *resp;
+ size_t resp_size;
+
+ p = params;
+ file = (const char *)(p + sizeof(Slave_Msg_Image_Open));
+ key = file + strlen(file) + 1;
+ ptr = key + strlen(key) + 1;
+ if (p->has_opts)
+ {
+ load_opts = (Image_Load_Opts *)ptr;
+ ptr += sizeof(Image_Load_Opts);
+ }
+ if (p->has_loader_data)
+ loader = ptr;
+
+ memset(&result, 0, sizeof(result));
+ if ((err = image_open(file, key, load_opts, &result, &loader))
+ != CSERVE2_NONE)
+ {
+ error_send(wfd, err);
+ return;
+ }
+
+ result.has_loader_data = EINA_TRUE;
+
+ resp_size = sizeof(Slave_Msg_Image_Opened) + sizeof(int) + strlen(loader) + 1;
+ resp = alloca(resp_size);
+ memcpy(resp, &result, sizeof(Slave_Msg_Image_Opened));
+ memcpy(resp + sizeof(Slave_Msg_Image_Opened), loader, strlen(loader) + 1);
+ response_send(wfd, IMAGE_OPEN, resp, resp_size);
+}
+
+static void
+handle_image_load(int wfd, void *params)
+{
+ Slave_Msg_Image_Load *load_args = params;
+ Slave_Msg_Image_Loaded resp;
+ Error_Type err;
+ const char *shmfile;
+ const char *file, *key, *loader;
+
+ if (!load_args->has_loader_data)
+ {
+ error_send(wfd, CSERVE2_UNKNOWN_FORMAT);
+ return;
+ }
+
+ memset(&resp, 0, sizeof(resp));
+
+ shmfile = ((const char *)params) + sizeof(Slave_Msg_Image_Load);
+ file = shmfile + strlen(shmfile) + 1;
+ key = file + strlen(file) + 1;
+ loader = key + strlen(key) + 1;
+ if ((err = image_load(file, key, shmfile, load_args, &resp, loader))
+ != CSERVE2_NONE)
+ {
+ error_send(wfd, err);
+ return;
+ }
+
+ response_send(wfd, IMAGE_LOAD, &resp, sizeof(resp));
+}
+
+int main(int c, char **v)
+{
+ int wfd, rfd;
+ Slave_Command cmd;
+ void *params = NULL;
+ Eina_Module *m;
+ Eina_Bool quit = EINA_FALSE;
+
+ if (c < 3)
+ return 1;
+
+ eina_init();
+
+ loaders = eina_hash_string_superfast_new(NULL);
+
+ wfd = atoi(v[1]);
+ rfd = atoi(v[2]);
+
+ while (!quit)
+ {
+ if (!command_read(rfd, &cmd, ¶ms))
+ {
+ error_send(wfd, CSERVE2_INVALID_COMMAND);
+ return 1;
+ }
+ switch (cmd)
+ {
+ case IMAGE_OPEN:
+ handle_image_open(wfd, params);
+ break;
+ case IMAGE_LOAD:
+ handle_image_load(wfd, params);
+ break;
+ case SLAVE_QUIT:
+ quit = EINA_TRUE;
+ break;
+ default:
+ error_send(wfd, CSERVE2_INVALID_COMMAND);
+ }
+ }
+
+ eina_hash_free(loaders);
+
+ EINA_LIST_FREE(modules, m)
+ eina_module_free(m);
+
+ eina_shutdown();
+
+ return 0;
+}
--- /dev/null
+#ifndef _EVAS_CSERVE2_SLAVE_H
+#define _EVAS_CSERVE2_SLAVE_H
+
+#include <Evas.h>
+
+/* begin bunch of stuff from evas_common.h so that we don't need to drag
+ * a lot of useless @SOMETHING_CFLAGS@ around */
+typedef unsigned long long DATA64;
+typedef unsigned int DATA32;
+typedef unsigned short DATA16;
+typedef unsigned char DATA8;
+
+#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
+
+/* if more than 1/ALPHA_SPARSE_INV_FRACTION is "alpha" (1-254) then sparse
+ * alpha flag gets set */
+#define ALPHA_SPARSE_INV_FRACTION 3
+
+#define IMG_MAX_SIZE 65000
+
+#define IMG_TOO_BIG(w, h) \
+ ((((unsigned long long)w) * ((unsigned long long)h)) >= \
+ ((1ULL << (29 * (sizeof(void *) / 4))) - 2048))
+
+#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))
+/* end bunchf of stuff from evas_common.h */
+
+typedef struct _Evas_Loader_Module_Api Evas_Loader_Module_Api;
+typedef struct _Evas_Img_Load_Params Evas_Img_Load_Params;
+
+#define EVAS_CSERVE2_MODULE_API_VERSION 1
+struct _Evas_Loader_Module_Api {
+ int version;
+ const char *type;
+ Eina_Bool (*head_load)(Evas_Img_Load_Params *p, const char *file, const char *key, int *error);
+ Eina_Bool (*data_load)(Evas_Img_Load_Params *p, const char *file, const char *key, int *error);
+};
+
+struct _Evas_Img_Load_Params {
+ unsigned int w, h;
+ unsigned int degree;
+ unsigned int scale;
+ int frame_count;
+ int loop_count;
+ int loop_hint;
+ struct {
+ unsigned int w, h;
+ unsigned int rx, ry, rw, rh;
+ int scale_down_by;
+ double dpi;
+ Eina_Bool orientation;
+ } opts;
+ void *buffer;
+ Eina_Bool has_opts : 1;
+ Eina_Bool rotated : 1;
+ Eina_Bool alpha : 1;
+ Eina_Bool alpha_sparse : 1;
+ Eina_Bool animated : 1;
+};
+
+EAPI Eina_Bool evas_cserve2_loader_register(Evas_Loader_Module_Api *api);
+
+EAPI void evas_cserve2_image_premul(Evas_Img_Load_Params *ilp);
+EAPI void evas_cserve2_image_alpha_sparse_set(Evas_Img_Load_Params *ilp);
+
+#endif /* _EVAS_CSERVE2_SLAVE_H */
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "evas_cserve2.h"
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef enum
+{
+ SLAVE_PROCESS,
+ SLAVE_THREAD
+} Slave_Type;
+
+struct _Slave
+{
+ Slave_Type type;
+ int write_fd;
+ int read_fd;
+ Slave_Read_Cb read_cb;
+ Slave_Dead_Cb dead_cb;
+ const void *data;
+ Eina_Binbuf *pending;
+
+ struct {
+ int size;
+ int read_size;
+ Slave_Command cmd;
+ char *buf;
+ } read;
+};
+
+struct _Slave_Proc
+{
+ Slave base;
+ pid_t pid;
+ const char *name;
+ Eina_Bool killed : 1;
+};
+
+typedef struct _Slave_Thread Slave_Thread;
+typedef struct _Slave_Proc Slave_Proc;
+
+struct _Slave_Thread
+{
+ Slave base;
+ pthread_t tid;
+ Slave_Thread_Data *tdata;
+};
+
+struct _Slave_Thread_Data {
+ int write_fd;
+ int read_fd;
+ Slave_Thread_Cb cb;
+ void *cb_data;
+ const void *cmddata;
+ void *cmdanswer;
+};
+
+static Eina_List *slave_procs;
+static Eina_List *slave_threads;
+static pthread_attr_t slave_thread_attr;
+
+static Slave_Proc *
+_slave_proc_find(pid_t pid)
+{
+ Eina_List *l;
+ Slave_Proc *s;
+
+ EINA_LIST_FOREACH(slave_procs, l, s)
+ if (s->pid == pid)
+ return s;
+ return NULL;
+}
+
+static void
+_slave_free(Slave *s)
+{
+ if (s->write_fd)
+ close(s->write_fd);
+ if (s->read_fd)
+ {
+ cserve2_fd_watch_del(s->read_fd);
+ close(s->read_fd);
+ }
+
+ free(s->read.buf);
+
+ if (s->pending)
+ eina_binbuf_free(s->pending);
+
+ if (s->dead_cb)
+ s->dead_cb(s, (void *)s->data);
+
+}
+
+static void
+_slave_proc_free(Slave_Proc *s)
+{
+ _slave_free((Slave *)s);
+
+ eina_stringshare_del(s->name);
+
+ free(s);
+}
+
+static void
+_slave_thread_free(Slave_Thread *s)
+{
+ Slave_Thread_Data *sd = s->tdata;
+
+ close(sd->write_fd);
+ close(sd->read_fd);
+
+ free(sd);
+
+ _slave_free((Slave *)s);
+
+ free(s);
+}
+
+static void
+_slave_proc_dead_cb(int pid, int status __UNUSED__)
+{
+ Slave_Proc *s;
+
+ DBG("Child dead with pid '%d'.", pid);
+ s = _slave_proc_find(pid);
+ if (!s)
+ {
+ ERR("Unknown child dead '%d'.", pid);
+ return;
+ }
+
+ slave_procs = eina_list_remove(slave_procs, s);
+ _slave_proc_free(s);
+}
+
+static size_t
+_slave_write(Slave *s, const char *data, size_t size)
+{
+ size_t sent = 0;
+
+ do
+ {
+ ssize_t ret;
+ ret = write(s->write_fd, data + sent, size - sent);
+ if (ret == -1)
+ {
+ if (errno == EAGAIN)
+ break;
+ if (errno == EPIPE)
+ {
+ WRN("Slave unexpectedly gone.");
+ /* handle dead? */
+ break;
+ }
+ }
+ sent += ret;
+ } while(sent < size);
+
+ return sent;
+}
+
+static void
+_slave_write_cb(int fd __UNUSED__, Fd_Flags flags __UNUSED__, void *data)
+{
+ Slave *s = data;
+ size_t sent;
+ size_t size;
+ const char *str;
+
+ size = eina_binbuf_length_get(s->pending);
+ str = (const char *)eina_binbuf_string_get(s->pending);
+ sent = _slave_write(s, str, size);
+ if (sent == size)
+ {
+ eina_binbuf_free(s->pending);
+ s->pending = NULL;
+ cserve2_fd_watch_del(s->write_fd);
+ return;
+ }
+
+ eina_binbuf_remove(s->pending, 0, sent);
+}
+
+static void
+_slave_read_clear(Slave *s)
+{
+ s->read.buf = NULL;
+ s->read.cmd = 0;
+ s->read.read_size = s->read.size = 0;
+}
+
+static void
+_slave_proc_read_cb(int fd, Fd_Flags flags, void *data)
+{
+ Slave *s = data;
+ Eina_Bool done = EINA_FALSE;
+
+ /* handle error */
+ if (!(flags & FD_READ))
+ return;
+
+ if (!s->read.size)
+ {
+ int ints[2];
+ ssize_t ret;
+
+ ret = read(fd, ints, sizeof(int) * 2);
+ if (ret < (int)sizeof(int) * 2)
+ {
+ return;
+ }
+ s->read.size = ints[0];
+ s->read.cmd = ints[1];
+ if (s->read.size)
+ s->read.buf = malloc(s->read.size);
+ else
+ done = EINA_TRUE;
+ }
+
+ if (s->read.buf)
+ {
+ ssize_t ret;
+ do {
+ char *p = s->read.buf + s->read.read_size;
+ int sz = s->read.size - s->read.read_size;
+ ret = read(fd, p, sz);
+ if (ret < 0)
+ {
+ if (errno == EAGAIN)
+ break;
+ }
+ s->read.read_size += ret;
+ } while(s->read.read_size < s->read.size);
+
+ if (s->read.read_size == s->read.size)
+ done = EINA_TRUE;
+ }
+
+ if (done)
+ {
+ s->read_cb(s, s->read.cmd, s->read.buf, (void *)s->data);
+ _slave_read_clear(s);
+ }
+}
+
+static void
+_slave_thread_read_cb(int fd, Fd_Flags flags, void *data)
+{
+ Slave_Thread *s = data;
+ Slave_Thread_Data *sd = s->tdata;
+
+ if (!(flags & FD_READ))
+ return;
+
+ Slave_Command cmd;
+ ssize_t ret;
+
+ ret = read(fd, (char *)&cmd, sizeof(cmd));
+ if (ret < (int)sizeof(int))
+ {
+ return;
+ }
+
+ s->base.read_cb((Slave *)s, cmd, sd->cmdanswer, (void *)s->base.data);
+}
+
+Eina_Bool
+cserve2_slaves_init(void)
+{
+ cserve2_on_child_dead_set(_slave_proc_dead_cb);
+
+ if (pthread_attr_init(&slave_thread_attr))
+ {
+ ERR("Could not initialize attributes for thread.");
+ cserve2_on_child_dead_set(NULL);
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+void
+cserve2_slaves_shutdown(void)
+{
+ Slave_Proc *sp;
+ Slave_Thread *st;
+ Eina_List *l;
+
+ cserve2_on_child_dead_set(NULL);
+
+ if (!slave_procs && !slave_threads)
+ return;
+
+ DBG("Shutting down slaves subsystem with %d slaves alive!",
+ eina_list_count(slave_procs));
+
+ EINA_LIST_FREE(slave_procs, sp)
+ {
+ kill(sp->pid, SIGKILL);
+ _slave_proc_free(sp);
+ }
+
+ EINA_LIST_FOREACH(slave_threads, l, st)
+ pthread_cancel(st->tid);
+
+ EINA_LIST_FREE(slave_threads, st)
+ {
+ pthread_join(st->tid, NULL);
+ _slave_thread_free(st);
+ }
+}
+
+static const char *
+_slave_proc_path_get(const char *name)
+{
+ char buf[PATH_MAX], cwd[PATH_MAX];
+
+ if (name[0] == '/')
+ {
+ if (access(name, X_OK))
+ return NULL;
+ return eina_stringshare_add(name);
+ }
+
+ getcwd(cwd, sizeof(cwd));
+ snprintf(buf, sizeof(buf), "%s/%s", cwd, name);
+ if (!access(buf, X_OK))
+ return eina_stringshare_add(buf);
+
+ snprintf(buf, sizeof(buf), PACKAGE_LIBEXEC_DIR"/%s", name);
+ if (!access(buf, X_OK))
+ return eina_stringshare_add(buf);
+
+ return NULL;
+}
+
+static Slave *
+_cserve2_slave_proc_run(const char *exe, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data)
+{
+ Slave_Proc *s;
+ Slave *sb;
+ pid_t pid;
+ int child[2], parent[2];
+ int flags;
+ const char *name;
+
+ name = _slave_proc_path_get(exe);
+ if (!name)
+ {
+ ERR("Cannot execute slave '%s'. Not found or not executable.", exe);
+ return NULL;
+ }
+ DBG("Running slave '%s', resolved to path: %s", exe, name);
+
+ s = calloc(1, sizeof(Slave_Proc));
+ if (!s)
+ {
+ ERR("Could not create Slave_Proc handler.");
+ eina_stringshare_del(name);
+ return NULL;
+ }
+
+ sb = (Slave *)s;
+
+ if (pipe(child))
+ {
+ ERR("Could not create pipes for child.");
+ eina_stringshare_del(name);
+ free(s);
+ return NULL;
+ }
+
+ if (pipe(parent))
+ {
+ ERR("Could not create pipes for parent.");
+ eina_stringshare_del(name);
+ free(s);
+ close(child[0]);
+ close(child[1]);
+ return NULL;
+ }
+
+ pid = fork();
+ if (pid < 0)
+ {
+ ERR("Could not create sub process.");
+ eina_stringshare_del(name);
+ close(child[0]);
+ close(child[1]);
+ close(parent[0]);
+ close(parent[1]);
+ free(s);
+ return NULL;
+ }
+
+ if (!pid)
+ {
+ char *args[4], readfd[12], writefd[12];
+
+ close(child[1]);
+ close(parent[0]);
+
+ sprintf(readfd, "%d", child[0]);
+ sprintf(writefd, "%d", parent[1]);
+ args[0] = (char *)name;
+ args[1] = writefd;
+ args[2] = readfd;
+ args[3] = NULL;
+ execvp(name, args);
+ /* we only get here if execvp fails, which should not
+ * happen and if it does, it's baaaaaaaaad */
+ ERR("execvp() for slave at: '%s' failed! '%m'", name);
+ exit(1);
+ }
+
+ s->pid = pid;
+ s->name = name;
+ sb->type = SLAVE_PROCESS;
+ sb->write_fd = child[1];
+ flags = fcntl(sb->write_fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(sb->write_fd, F_SETFL, flags);
+ sb->read_fd = parent[0];
+ flags = fcntl(sb->read_fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(sb->read_fd, F_SETFL, flags);
+ sb->read_cb = read_cb;
+ sb->dead_cb = dead_cb;
+ sb->data = data;
+ cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_proc_read_cb, sb);
+
+ close(child[0]);
+ close(parent[1]);
+
+ slave_procs = eina_list_append(slave_procs, s);
+
+ return sb;
+}
+
+Slave *
+cserve2_slave_run(const char *name, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data)
+{
+ return _cserve2_slave_proc_run(name, read_cb, dead_cb, data);
+}
+
+static void *
+_slave_thread_cb(void *data)
+{
+ ssize_t n;
+ Slave_Command cmd;
+
+ Slave_Thread_Data *sd = data;
+
+ n = read(sd->read_fd, &cmd, sizeof(cmd));
+ while (n != 0)
+ {
+ /* EINTR means we were interrupted by a signal before anything
+ * was sent, and if we are back here it means that signal was
+ * not meant for us to die. Any other error here is fatal and
+ * should result in the slave terminating.
+ */
+ if (errno == EINTR)
+ continue;
+
+ if (n != sizeof(cmd))
+ {
+ ERR("Slave thread read invalid size of command from server: %d",
+ n);
+ continue;
+ }
+ sd->cmdanswer = sd->cb(sd, &cmd, sd->cmddata, sd->cb_data);
+ write(sd->write_fd, &cmd, sizeof(cmd));
+
+ n = read(sd->read_fd, &cmd, sizeof(cmd));
+ }
+
+ ERR("Pipe was closed on the side. Slave thread exiting...");
+
+ return NULL;
+}
+
+Slave *
+cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Read_Cb read_cb, Slave_Dead_Cb dead_cb, const void *data)
+{
+ Slave_Thread_Data *sd;
+ Slave_Thread *s;
+ Slave *sb;
+ pthread_t tid;
+ int child[2], parent[2];
+ int flags;
+
+ s = calloc(1, sizeof(Slave_Thread));
+ if (!s)
+ {
+ ERR("Could not create Slave_Thread handler.");
+ return NULL;
+ }
+
+ sb = (Slave *)s;
+
+ sd = calloc(1, sizeof(Slave_Thread_Data));
+ if (!sd)
+ {
+ ERR("Could not create Slave_Thread_Data.");
+ return NULL;
+ }
+
+ if (pipe(child))
+ {
+ ERR("Could not create pipes for child.");
+ free(s);
+ free(sd);
+ return NULL;
+ }
+
+ if (pipe(parent))
+ {
+ ERR("Could not create pipes for parent.");
+ free(s);
+ free(sd);
+ close(child[0]);
+ close(child[1]);
+ return NULL;
+ }
+
+ /* Setting data for slave thread */
+ sd->read_fd = child[0];
+ sd->write_fd = parent[1];
+
+ sd->cb = thread_cb;
+ sd->cb_data = thread_data;
+
+ if (pthread_create(&tid, &slave_thread_attr, _slave_thread_cb, sd))
+ {
+ ERR("Could not start slave thread.");
+ free(s);
+ free(sd);
+ close(child[0]);
+ close(child[1]);
+ close(parent[0]);
+ close(parent[1]);
+ return NULL;
+ }
+
+ s->tid = tid;
+ s->tdata = sd;
+ sb->type = SLAVE_THREAD;
+ sb->write_fd = child[1];
+ flags = fcntl(sb->write_fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(sb->write_fd, F_SETFL, flags);
+ sb->read_fd = parent[0];
+ flags = fcntl(sb->read_fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(sb->read_fd, F_SETFL, flags);
+ sb->read_cb = read_cb;
+ sb->dead_cb = dead_cb;
+ sb->data = data;
+ cserve2_fd_watch_add(sb->read_fd, FD_READ, _slave_thread_read_cb, sb);
+
+ slave_threads = eina_list_append(slave_threads, s);
+
+ return sb;
+}
+
+static void
+_slave_send_aux(Slave *s, const char *data, size_t size)
+{
+ size_t sent;
+
+ if (s->pending)
+ {
+ eina_binbuf_append_length(s->pending, (unsigned char *)data, size);
+ return;
+ }
+
+ sent = _slave_write(s, data, size);
+ if (sent < size)
+ {
+ s->pending = eina_binbuf_new();
+ eina_binbuf_append_length(s->pending, (unsigned char *)data + sent,
+ size - sent);
+ cserve2_fd_watch_add(s->write_fd, FD_WRITE, _slave_write_cb, s);
+ }
+}
+
+void
+_cserve2_slave_proc_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
+{
+ int ints[2];
+
+ ints[0] = size;
+ ints[1] = cmd;
+ _slave_send_aux(s, (char *)ints, sizeof(int) * 2);
+ if (size)
+ _slave_send_aux(s, (char *)data, size);
+}
+
+void
+_cserve2_slave_thread_send(Slave_Thread *s, Slave_Command cmd, const char *data)
+{
+ s->tdata->cmddata = data;
+
+ _slave_send_aux((Slave *)s, (char *)&cmd, sizeof(cmd));
+}
+
+void
+cserve2_slave_send(Slave *s, Slave_Command cmd, const char *data, size_t size)
+{
+ if (s->type == SLAVE_PROCESS)
+ _cserve2_slave_proc_send(s, cmd, data, size);
+ else
+ _cserve2_slave_thread_send((Slave_Thread *)s, cmd, data);
+}
+
+static void
+_cserve2_slave_proc_kill(Slave_Proc *s)
+{
+ if (s->killed)
+ {
+ if (!kill(s->pid, 0))
+ DBG("Slave %p(%d) requested to kill, but it's still alive.",
+ s, s->pid);
+ }
+
+ s->killed = EINA_TRUE;
+ kill(s->pid, SIGTERM);
+}
+
+void
+cserve2_slave_kill(Slave *s)
+{
+ _cserve2_slave_proc_kill((Slave_Proc *)s);
+}
--- /dev/null
+#include "evas_cserve2_slave.h"
+
+static unsigned int
+evas_cserve2_convert_argb_premul(unsigned int *data, unsigned int len)
+{
+ unsigned int *de = data + len;
+ unsigned int nas = 0;
+
+ while (data < de)
+ {
+ unsigned int a = 1 + (*data >> 24);
+
+ *data = (*data & 0xff000000) +
+ (((((*data) >> 8) & 0xff) * a) & 0xff00) +
+ (((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
+ data++;
+
+ if ((a == 1) || (a == 256))
+ nas++;
+ }
+
+ return nas;
+}
+
+EAPI void
+evas_cserve2_image_premul(Evas_Img_Load_Params *ilp)
+{
+ unsigned int nas;
+
+ if (!ilp->alpha) return;
+
+ nas = evas_cserve2_convert_argb_premul(ilp->buffer, ilp->w * ilp->h);
+ if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ilp->w * ilp->h))
+ ilp->alpha_sparse = EINA_TRUE;
+}
+
+EAPI void
+evas_cserve2_imave_alpha_sparse_set(Evas_Img_Load_Params *ilp)
+{
+ unsigned int *s, *se;
+ unsigned int nas = 0;
+ unsigned int len = ilp->w * ilp->h;
+
+ if (!ilp->alpha) return;
+
+ s = ilp->buffer;
+ se = s + len;
+ while (s < se)
+ {
+ unsigned int p = *s & 0xff000000;
+
+ if (!p || (p == 0xff000000))
+ nas++;
+ s++;
+ }
+ if ((ALPHA_SPARSE_INV_FRACTION * nas) >= len)
+ ilp->alpha_sparse = EINA_TRUE;
+}
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS =
+
+if BUILD_LOADER_BMP
+SUBDIRS += bmp
+endif
+
+if BUILD_LOADER_EET
+SUBDIRS += eet
+endif
+
+if BUILD_LOADER_ICO
+SUBDIRS += ico
+endif
+
+if BUILD_LOADER_JPEG
+SUBDIRS += jpeg
+endif
+
+if BUILD_LOADER_PMAPS
+SUBDIRS += pmaps
+endif
+
+if BUILD_LOADER_PNG
+SUBDIRS += png
+endif
+
+if BUILD_LOADER_PSD
+SUBDIRS += psd
+endif
+
+if BUILD_LOADER_TGA
+SUBDIRS += tga
+endif
+
+if BUILD_LOADER_TIFF
+SUBDIRS += tiff
+endif
+
+if BUILD_LOADER_WBMP
+SUBDIRS += wbmp
+endif
+
+if BUILD_LOADER_XPM
+SUBDIRS += xpm
+endif
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_BMP
+#if !EVAS_STATIC_BUILD_BMP
+
+pkgdir = $(libdir)/evas/cserve2/loaders/bmp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_bmp.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ -lm
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_bmp.la
+#libevas_loader_bmp_la_SOURCES = evas_image_load_bmp.c
+#libevas_loader_bmp_la_LIBADD =
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <math.h>
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+static Eina_Bool
+read_short(unsigned char *map, size_t length, size_t *position, short *ret)
+{
+ unsigned char b[2];
+
+ if (*position + 2 > length) return EINA_FALSE;
+ b[0] = map[(*position)++];
+ b[1] = map[(*position)++];
+ *ret = (b[1] << 8) | b[0];
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_ushort(unsigned char *map, size_t length, size_t *position, unsigned short *ret)
+{
+ unsigned char b[2];
+
+ if (*position + 2 > length) return EINA_FALSE;
+ b[0] = map[(*position)++];
+ b[1] = map[(*position)++];
+ *ret = (b[1] << 8) | b[0];
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_int(unsigned char *map, size_t length, size_t *position, int *ret)
+{
+ unsigned char b[4];
+ int i;
+
+ if (*position + 4 > length) return EINA_FALSE;
+ for (i = 0; i < 4; i++)
+ b[i] = map[(*position)++];
+ *ret = ARGB_JOIN(b[3], b[2], b[1], b[0]);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_uint(unsigned char *map, size_t length, size_t *position, unsigned int *ret)
+{
+ unsigned char b[4];
+ int i;
+
+ if (*position + 4 > length) return EINA_FALSE;
+ for (i = 0; i < 4; i++)
+ b[i] = map[(*position)++];
+ *ret = ARGB_JOIN(b[3], b[2], b[1], b[0]);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_uchar(unsigned char *map, size_t length, size_t *position, unsigned char *ret)
+{
+ if (*position + 1 > length) return EINA_FALSE;
+ *ret = map[(*position)++];
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_skip(size_t length, size_t *position, int skip)
+{
+ if (*position + skip > length) return EINA_FALSE;
+ *position += skip;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_mem(unsigned char *map, size_t length, size_t *position, void *buffer, int size)
+{
+ if (*position + size > length) return EINA_FALSE;
+ memcpy(buffer, map + *position, size);
+ *position += size;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_head_bmp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ char hasa = 0;
+ int w = 0, h = 0, bit_count = 0, image_size = 0, comp = 0;
+ unsigned int offset, head_size, amask = 0;
+ int fsize = 0;
+ unsigned int bmpsize;
+ unsigned short res1, res2;
+
+ f = eina_file_open(file, 0);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ fsize = eina_file_size_get(f);
+ if (fsize < 2) goto close_file;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto close_file;
+
+ if (strncmp(map, "BM", 2)) goto close_file; // magic number
+ position += 2;
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ if (!read_uint(map, fsize, &position, &bmpsize)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &res1)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &res2)) goto close_file;
+ if (!read_uint(map, fsize, &position, &offset)) goto close_file;
+ if (!read_uint(map, fsize, &position, &head_size)) goto close_file;
+ if (head_size == 12) // OS/2 V1 + Windows 3.0
+ {
+ short tmp;
+
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ w = tmp; // width
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ h = tmp; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8 & 24
+ }
+ else if (head_size == 64) // OS/2 V2
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_skip(fsize, &position, 24)) goto close_file; // skip unused header
+ if (image_size == 0) image_size = fsize - offset;
+ }
+ else if (head_size == 40) // Windows 3.0 + (v3)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (image_size == 0) image_size = fsize - offset;
+ if ((comp == 0) && (bit_count == 32)) hasa = 1; // GIMP seems to store it this way
+ }
+ else if (head_size == 108) // Windows 95/NT4 + (v4)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //rmask = tmp2; // red mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //gmask = tmp2; // green mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //bmask = tmp2; // blue mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ amask = tmp2; // alpha mask
+ if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie
+ if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma
+ if (image_size == 0) image_size = fsize - offset;
+ if ((amask) && (bit_count == 32)) hasa = 1;
+ }
+ else if (head_size == 124) // Windows 98/2000 + (v5)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //rmask = tmp2; // red mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //gmask = tmp2; // green mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //bmask = tmp2; // blue mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ amask = tmp2; // alpha mask
+ if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie
+ if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma
+ if (!read_skip(fsize, &position, 16)) goto close_file; // skip others
+ if (image_size == 0) image_size = fsize - offset;
+ if ((amask) && (bit_count == 32)) hasa = 1;
+ }
+ else
+ goto close_file;
+
+ if (h < 0)
+ {
+ h = -h;
+ //right_way_up = 1;
+ }
+
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+ /* It is not bad idea that bmp loader support scale down decoding
+ * because of memory issue in mobile world.*/
+ if (ilp->opts.scale_down_by > 1)
+ {
+ w /= ilp->opts.scale_down_by;
+ h /= ilp->opts.scale_down_by;
+ }
+
+ if (bit_count < 16)
+ {
+ //if ((palette_size < 0) || (palette_size > 256)) pal_num = 256;
+ //else pal_num = palette_size;
+ if (bit_count == 1)
+ {
+ if (comp == 0) // no compression
+ {
+ }
+ else
+ goto close_file;
+ }
+ else if (bit_count == 4)
+ {
+ if (comp == 0) // no compression
+ {
+ }
+ else if (comp == 2) // rle 4bit/pixel
+ {
+ }
+ else
+ goto close_file;
+ }
+ else if (bit_count == 8)
+ {
+ if (comp == 0) // no compression
+ {
+ }
+ else if (comp == 1) // rle 8bit/pixel
+ {
+ }
+ else
+ goto close_file;
+ }
+ }
+ else if ((bit_count == 16) || (bit_count == 24) || (bit_count == 32))
+ {
+ if (comp == 0) // no compression
+ {
+ // handled
+ }
+ else if (comp == 3) // bit field
+ {
+ // handled
+ }
+ else if (comp == 4) // jpeg - only printer drivers
+ goto close_file;
+ else if (comp == 3) // png - only printer drivers
+ goto close_file;
+ else
+ goto close_file;
+ }
+ else
+ goto close_file;
+
+ ilp->w = w;
+ ilp->h = h;
+ if (hasa) ilp->alpha = 1;
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_bmp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ unsigned char *buffer = NULL, *buffer_end = NULL, *p;
+ char hasa = 0;
+ int x = 0, y = 0, w = 0, h = 0, bit_count = 0, image_size = 0,
+ comp = 0, palette_size = -1;
+ unsigned int offset = 0, head_size = 0;
+ unsigned int *pal = NULL, pal_num = 0, *pix = NULL, *surface = NULL, fix,
+ rmask = 0, gmask = 0, bmask = 0, amask = 0;
+ int right_way_up = 0;
+ unsigned char r, g, b, a;
+ int fsize = 0;
+ unsigned int bmpsize;
+ unsigned short res1, res2;
+
+ /* for scale decoding */
+ unsigned int *scale_surface = NULL, *scale_pix = NULL;
+ int scale_ratio = 1, image_w = 0, image_h = 0;
+ int row_size = 0; /* Row size is rounded up to a multiple of 4bytes */
+ int read_line = 0; /* total read line */
+
+ f = eina_file_open(file, 0);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ fsize = eina_file_size_get(f);
+ if (fsize < 2) goto close_file;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto close_file;
+
+ if (strncmp(map, "BM", 2)) goto close_file; // magic number
+ position += 2;
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ if (!read_uint(map, fsize, &position, &bmpsize)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &res1)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &res2)) goto close_file;
+ if (!read_uint(map, fsize, &position, &offset)) goto close_file;
+ if (!read_uint(map, fsize, &position, &head_size)) goto close_file;
+ image_size = fsize - offset;
+ if (image_size < 1) goto close_file;
+
+ if (head_size == 12) // OS/2 V1 + Windows 3.0
+ {
+ short tmp;
+
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ w = tmp; // width
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ h = tmp; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8 & 24
+ }
+ else if (head_size == 64) // OS/2 V2
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_skip(fsize, &position, 24)) goto close_file; // skip unused header
+ if (image_size == 0) image_size = fsize - offset;
+ }
+ else if (head_size == 40) // Windows 3.0 + (v3)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (image_size == 0) image_size = fsize - offset;
+ if ((comp == 0) && (bit_count == 32)) hasa = 1; // GIMP seems to store it this way
+ }
+ else if (head_size == 108) // Windows 95/NT4 + (v4)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ rmask = tmp2; // red mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ gmask = tmp2; // green mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ bmask = tmp2; // blue mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ amask = tmp2; // alpha mask
+ if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie
+ if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma
+ if (image_size == 0) image_size = fsize - offset;
+ if ((amask) && (bit_count == 32)) hasa = 1;
+ }
+ else if (head_size == 124) // Windows 98/2000 + (v5)
+ {
+ short tmp;
+ int tmp2;
+
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ w = tmp2; // width
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ h = tmp2; // height
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ //planes = tmp; // must be 1
+ if (!read_short(map, fsize, &position, &tmp)) goto close_file;
+ bit_count = tmp; // bits per pixel: 1, 4, 8, 16, 24 & 32
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ comp = tmp2; // compression method
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ image_size = tmp2; // bitmap data size
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //vdpi = (tmp2 * 254) / 10000; // vertical pixles/meter
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ palette_size = tmp2; // number of palette colors power (2^n - so 0 - 8)
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ //important_colors = tmp2; // number of important colors - 0 if all
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ rmask = tmp2; // red mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ gmask = tmp2; // green mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ bmask = tmp2; // blue mask
+ if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
+ amask = tmp2; // alpha mask
+ if (!read_skip(fsize, &position, 36)) goto close_file; // skip unused cie
+ if (!read_skip(fsize, &position, 12)) goto close_file; // skip unused gamma
+ if (!read_skip(fsize, &position, 16)) goto close_file; // skip others
+ if (image_size == 0) image_size = fsize - offset;
+ if ((amask) && (bit_count == 32)) hasa = 1;
+ }
+ else
+ goto close_file;
+
+ if (h < 0)
+ {
+ h = -h;
+ right_way_up = 1;
+ }
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+ /* It is not bad idea that bmp loader support scale down decoding
+ * because of memory issue in mobile world. */
+ if (ilp->opts.scale_down_by > 1)
+ scale_ratio = ilp->opts.scale_down_by;
+ image_w = w;
+ image_h = h;
+
+ if (scale_ratio > 1)
+ {
+ w /= scale_ratio;
+ h /= scale_ratio;
+
+ if ((w < 1) || (h < 1) )
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+ }
+
+ if ((w != (int)ilp->w) || (h != (int)ilp->h))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+
+ row_size = ceil((double)(image_w * bit_count) / 32) * 4;
+
+ if (bit_count < 16)
+ {
+ unsigned int i;
+
+ if (bit_count == 1)
+ {
+ if ((palette_size <= 0) || (palette_size > 2)) pal_num = 2;
+ else pal_num = palette_size;
+ }
+ else if (bit_count == 4)
+ {
+ if ((palette_size <= 0) || (palette_size > 16)) pal_num = 16;
+ else pal_num = palette_size;
+ }
+ else if (bit_count == 8)
+ {
+ if ((palette_size <= 0) || (palette_size > 256)) pal_num = 256;
+ else pal_num = palette_size;
+ }
+ pal = alloca(256 * 4);
+ for (i = 0; i < pal_num; i++)
+ {
+ if (!read_uchar(map, fsize, &position, &b)) goto close_file;
+ if (!read_uchar(map, fsize, &position, &g)) goto close_file;
+ if (!read_uchar(map, fsize, &position, &r)) goto close_file;
+ if ((head_size != 12) /*&& (palette_size != 0)*/)
+ { // OS/2 V1 doesn't do the pad byte
+ if (!read_uchar(map, fsize, &position, &a)) goto close_file;
+ }
+ a = 0xff; // fillin a as solid for paletted images
+ pal[i] = ARGB_JOIN(a, r, g, b);
+ }
+ position = offset;
+
+ if ((scale_ratio == 1) || (comp !=0))
+ buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
+ else
+ {
+ scale_surface = malloc(image_w * sizeof(DATA32)); //for one line decoding
+ if (!scale_surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
+ }
+
+ if (!buffer)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ if ((scale_ratio == 1) || (comp !=0))
+ buffer_end = buffer + image_size;
+ else
+ buffer_end = buffer + row_size;
+ p = buffer;
+
+ if ((scale_ratio == 1) || (comp !=0))
+ {
+ if (!read_mem(map, fsize, &position, buffer, image_size)) goto close_file;
+ }
+ else
+ {
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ }
+
+ if (bit_count == 1)
+ {
+ if (comp == 0) // no compression
+ {
+ pix = surface;
+
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ if (scale_ratio > 1) pix = scale_surface; // one line decoding
+
+ for (x = 0; x < image_w; x++)
+ {
+ if ((x & 0x7) == 0x0)
+ {
+ *pix = pal[*p >> 7];
+ }
+ else if ((x & 0x7) == 0x1)
+ {
+ *pix = pal[(*p >> 6) & 0x1];
+ }
+ else if ((x & 0x7) == 0x2)
+ {
+ *pix = pal[(*p >> 5) & 0x1];
+ }
+ else if ((x & 0x7) == 0x3)
+ {
+ *pix = pal[(*p >> 4) & 0x1];
+ }
+ else if ((x & 0x7) == 0x4)
+ {
+ *pix = pal[(*p >> 3) & 0x1];
+ }
+ else if ((x & 0x7) == 0x5)
+ {
+ *pix = pal[(*p >> 2) & 0x1];
+ }
+ else if ((x & 0x7) == 0x6)
+ {
+ *pix = pal[(*p >> 1) & 0x1];
+ }
+ else
+ {
+ *pix = pal[*p & 0x1];
+ p++;
+ }
+ if (p >= buffer_end) break;
+ pix++;
+ }
+
+ if (scale_ratio > 1)
+ {
+ if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w);
+ else scale_pix = surface + (y * w);
+
+ pix = scale_surface;
+ for (x = 0; x < w; x++)
+ {
+ *scale_pix = *pix;
+ scale_pix ++;
+ pix += scale_ratio;
+ }
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ if ((x & 0x7) != 0) p++;
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else
+ goto close_file;
+ }
+ else if (bit_count == 4)
+ {
+ if (comp == 0) // no compression
+ {
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ if (scale_ratio > 1) pix = scale_surface; // one line decoding
+ for (x = 0; x < image_w; x++)
+ {
+ if ((x & 0x1) == 0x1)
+ {
+ *pix = pal[*p & 0x0f];
+ p++;
+ }
+ else
+ {
+ *pix = pal[*p >> 4];
+ }
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w);
+ else scale_pix = surface + (y * w);
+
+ pix = scale_surface;
+ for (x = 0; x < w; x++)
+ {
+ *scale_pix = *pix;
+ scale_pix ++;
+ pix += scale_ratio;
+ }
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ if ((x & 0x1) != 0) p++;
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if (comp == 2) // rle 4bit/pixel
+ {
+ int count = 0, done = 0, wpad;
+ int scale_x = 0, scale_y = 0;
+ Eina_Bool scale_down_line = EINA_TRUE;
+
+ pix = surface;
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ wpad = ((image_w + 1) / 2) * 2;
+ while (p < buffer_end)
+ {
+ if (p[0])
+ {
+ if (scale_down_line)
+ {
+ if ((x + p[0]) <= wpad)
+ {
+ unsigned int col1 = pal[p[1] >> 4];
+ unsigned int col2 = pal[p[1] & 0xf];
+
+ count = p[0] / 2;
+ while (count > 0)
+ {
+ if (x < w)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = col1;
+ pix++;
+ scale_x++;
+ }
+ x++;
+ }
+ if (x < w)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = col2;
+ pix++;
+ scale_x++;
+ }
+ x++;
+ }
+ count--;
+ }
+ if (p[0] & 0x1)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = col1;
+ pix++;
+ scale_x++;
+ }
+ x++;
+ }
+ }
+ }
+ p += 2;
+ }
+ else
+ {
+ switch (p[1])
+ {
+ case 0: // EOL
+ x = 0;
+ scale_x = 0;
+ y++;
+ if ((y % scale_ratio) == 0)
+ {
+ scale_y++;
+ scale_down_line = EINA_TRUE;
+ if (!right_way_up)
+ pix = surface + ((h - 1 - scale_y) * w);
+ else
+ pix = surface + (scale_y * w);
+ }
+ else
+ scale_down_line = EINA_FALSE;
+ if (scale_y >= h)
+ {
+ p = buffer_end;
+ }
+ p += 2;
+ break;
+ case 1: // EOB
+ p = buffer_end;
+ break;
+ case 2: // DELTA
+ x += p[2];
+ y += p[3];
+ scale_x = x / scale_ratio;
+ scale_y = y / scale_ratio;
+ if ((scale_x >= w) || (scale_y >= h))
+ {
+ p = buffer_end;
+ }
+ if (!right_way_up)
+ pix = surface + scale_x + ((h - 1 - scale_y) * w);
+ else
+ pix = surface + scale_x + (scale_y * w);
+ p += 4;
+ break;
+ default:
+ count = p[1];
+ if (((p + count) > buffer_end) ||
+ ((x + count) > w))
+ {
+ p = buffer_end;
+ break;
+ }
+ p += 2;
+ done = count;
+ count /= 2;
+ while (count > 0)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = pal[*p >> 4];
+ pix++;
+ scale_x++;
+ }
+ x++;
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = pal[*p & 0xf];
+ pix++;
+ scale_x++;
+ }
+ x++;
+
+ p++;
+ count--;
+ }
+
+ if (done & 0x1)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = pal[*p >> 4];
+ scale_x++;
+ }
+ x++;
+ p++;
+ }
+ if ((done & 0x3) == 0x1)
+ p += 2;
+ else if ((done & 0x3) == 0x2)
+ p += 1;
+ break;
+ }
+ }
+ }
+ }
+ else
+ goto close_file;
+ }
+ else if (bit_count == 8)
+ {
+ if (comp == 0) // no compression
+ {
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ *pix = pal[*p];
+ p += scale_ratio;
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if (comp == 1) // rle 8bit/pixel
+ {
+ int count = 0, done = 0;
+ int scale_x = 0, scale_y = 0;
+ Eina_Bool scale_down_line = EINA_TRUE;
+
+ pix = surface;
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+
+ while (p < buffer_end)
+ {
+ if (p[0])
+ {
+ if (scale_down_line)
+ {
+ if ((x + p[0]) <= image_w)
+ {
+ unsigned int col = pal[p[1]];
+
+ count = p[0];
+ while (count > 0)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = col;
+ pix++;
+ scale_x ++;
+ }
+ x++;
+ count--;
+ }
+ }
+ }
+ p += 2;
+ }
+ else
+ {
+ switch (p[1])
+ {
+ case 0: // EOL
+ x = 0;
+ scale_x = 0;
+ y++;
+ if ((y % scale_ratio) == 0)
+ {
+ scale_y++;
+ scale_down_line = EINA_TRUE;
+ if (!right_way_up)
+ pix = surface + ((h - 1 - scale_y) * w);
+ else
+ pix = surface + (scale_y * w);
+ }
+ else
+ scale_down_line = EINA_FALSE;
+
+ if (scale_y >= h)
+ {
+ p = buffer_end;
+ }
+ p += 2;
+ break;
+ case 1: // EOB
+ p = buffer_end;
+ break;
+ case 2: // DELTA
+ x += p[2];
+ y += p[3];
+ scale_x = x / scale_ratio;
+ scale_y = y / scale_ratio;
+ if ((scale_x >= w) || (scale_y >= h))
+ {
+ p = buffer_end;
+ }
+ if (!right_way_up)
+ pix = surface + scale_x + ((h - 1 - scale_y) * w);
+ else
+ pix = surface + scale_x + (scale_y * w);
+ p += 4;
+ break;
+ default:
+ count = p[1];
+ if (((p + count) > buffer_end) ||
+ ((x + count) > image_w))
+ {
+ p = buffer_end;
+ break;
+ }
+ p += 2;
+ done = count;
+ while (count > 0)
+ {
+ if (((x % scale_ratio) == 0) && (scale_x < w))
+ {
+ *pix = pal[*p];
+ pix++;
+ scale_x ++;
+ }
+ p++;
+ x++;
+ count--;
+ }
+ if (done & 0x1) p++;
+ break;
+ }
+ }
+ }
+ }
+ else
+ goto close_file;
+ }
+ }
+ else if ((bit_count == 16) || (bit_count == 24) || (bit_count == 32))
+ {
+ if (comp == 0) // no compression
+ {
+ position = offset;
+ if (scale_ratio == 1)
+ buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
+ else
+ buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
+ if (!buffer)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ if (scale_ratio == 1)
+ buffer_end = buffer + image_size;
+ else
+ buffer_end = buffer + row_size;
+
+ p = buffer;
+ if (scale_ratio == 1)
+ {
+ if (!read_mem(map, fsize, &position, buffer, image_size)) goto close_file;
+ }
+ else
+ {
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ }
+ if (bit_count == 16)
+ {
+ unsigned short tmp;
+
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ tmp = *((unsigned short *)(p));
+
+ r = (tmp >> 7) & 0xf8; r |= r >> 5;
+ g = (tmp >> 2) & 0xf8; g |= g >> 5;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ *pix = ARGB_JOIN(0xff, r, g, b);
+
+ p += 2 * scale_ratio;
+
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if (bit_count == 24)
+ {
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ b = p[0];
+ g = p[1];
+ r = p[2];
+ *pix = ARGB_JOIN(0xff, r, g, b);
+ p += 3 * scale_ratio;
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if (bit_count == 32)
+ {
+ int none_zero_alpha = 0;
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ b = p[0];
+ g = p[1];
+ r = p[2];
+ a = p[3];
+ if (a) none_zero_alpha = 1;
+ if (!hasa) a = 0xff;
+ *pix = ARGB_JOIN(a, r, g, b);
+ p += 4 * scale_ratio;
+
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ if (!none_zero_alpha)
+ {
+ ilp->alpha = 0;
+ if (hasa)
+ {
+ unsigned int *pixend = surface + (w * h);
+
+ for (pix = surface; pix < pixend; pix++)
+ A_VAL(pix) = 0xff;
+ }
+ }
+ }
+ else
+ goto close_file;
+ }
+ else if (comp == 3) // bit field
+ {
+ if (!read_uint(map, fsize, &position, &rmask)) goto close_file;
+ if (!read_uint(map, fsize, &position, &gmask)) goto close_file;
+ if (!read_uint(map, fsize, &position, &bmask)) goto close_file;
+
+ position = offset;
+ if (scale_ratio == 1)
+ buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
+ else
+ buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
+
+ if (!buffer)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ if (scale_ratio == 1)
+ buffer_end = buffer + image_size;
+ else
+ buffer_end = buffer + row_size;
+
+ p = buffer;
+ if (scale_ratio == 1)
+ {
+ if (!read_mem(map, fsize, &position, buffer, image_size)) goto close_file;
+ }
+ else
+ {
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ }
+
+ if ((bit_count == 16) &&
+ (rmask == 0xf800) && (gmask == 0x07e0) && (bmask == 0x001f)
+ )
+ {
+ unsigned short tmp;
+
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ tmp = *((unsigned short *)(p));
+
+ r = (tmp >> 8) & 0xf8; r |= r >> 5;
+ g = (tmp >> 3) & 0xfc; g |= g >> 6;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ *pix = ARGB_JOIN(0xff, r, g, b);
+
+ p += 2 * scale_ratio;
+
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if ((bit_count == 16) &&
+ (rmask == 0x7c00) && (gmask == 0x03e0) && (bmask == 0x001f)
+ )
+ {
+ unsigned short tmp;
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ tmp = *((unsigned short *)(p));
+
+ r = (tmp >> 7) & 0xf8; r |= r >> 5;
+ g = (tmp >> 2) & 0xf8; g |= g >> 5;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ *pix = ARGB_JOIN(0xff, r, g, b);
+ p += 2 * scale_ratio;
+
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer_end, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else if (bit_count == 32)
+ {
+ pix = surface;
+ for (y = 0; y < h; y++)
+ {
+ if (!right_way_up) pix = surface + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ b = p[0];
+ g = p[1];
+ r = p[2];
+ a = p[3];
+ if (!hasa) a = 0xff;
+ *pix = ARGB_JOIN(a, r, g, b);
+
+ p += 4 * scale_ratio;
+
+ if (p >= buffer_end) break;
+ pix++;
+ }
+ if (scale_ratio > 1)
+ {
+ read_line += scale_ratio;
+ if (read_line >= image_h) break;
+
+ position += row_size * (scale_ratio - 1);
+ if (!read_mem(map, fsize, &position, buffer, row_size)) goto close_file;
+ p = buffer;
+ buffer_end = buffer + row_size;
+ }
+ else
+ {
+ fix = (int)(((unsigned long)p) & 0x3);
+ if (fix > 0) p += 4 - fix; // align row read
+ if (p >= buffer_end) break;
+ }
+ }
+ }
+ else
+ goto close_file;
+ }
+ else if (comp == 4) // jpeg - only printer drivers
+ {
+ goto close_file;
+ }
+ else if (comp == 3) // png - only printer drivers
+ {
+ goto close_file;
+ }
+ else
+ goto close_file;
+ }
+ else
+ goto close_file;
+
+ if (buffer) free(buffer);
+ if (scale_surface) free(scale_surface);
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+
+ evas_cserve2_image_premul(ilp);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ if (buffer) free(buffer);
+ if (scale_surface) free(scale_surface);
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "bmp",
+ evas_image_load_file_head_bmp,
+ evas_image_load_file_data_bmp
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@evas_image_loader_eet_cflags@ \
+@EINA_CFLAGS@
+
+
+if BUILD_LOADER_EET
+#if !EVAS_STATIC_BUILD_EET
+
+pkgdir = $(libdir)/evas/cserve2/loaders/eet/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_eet.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_eet_libs@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_eet.la
+
+#libevas_loader_eet_la_SOURCES = evas_image_load_eet.c
+#libevas_loader_eet_la_LIBADD = @evas_image_loader_eet_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* so that EAPI in Eet.h is correctly defined */
+#endif
+
+#include <Eet.h>
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+
+static Eina_Bool
+evas_image_load_file_head_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ int alpha, compression, quality, lossy;
+ unsigned int w, h;
+ Eet_File *ef;
+ int ok;
+ Eina_Bool res = EINA_FALSE;
+
+ if (!key)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ ef = eet_open((char *)file, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ ok = eet_data_image_header_read(ef, key,
+ &w, &h, &alpha, &compression, &quality, &lossy);
+ if (!ok)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ goto on_error;
+ }
+ if (IMG_TOO_BIG(w, h))
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+ if (alpha) ilp->alpha = 1;
+ ilp->w = w;
+ ilp->h = h;
+ res = EINA_TRUE;
+ *error = CSERVE2_NONE;
+
+ on_error:
+ eet_close(ef);
+ return res;
+}
+
+Eina_Bool
+evas_image_load_file_data_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ unsigned int w, h;
+ int alpha, compression, quality, lossy, ok;
+ Eet_File *ef;
+ DATA32 *body, *p, *end, *data;
+ DATA32 nas = 0;
+ Eina_Bool res = EINA_FALSE;
+
+ if (!key)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ ef = eet_open(file, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ ok = eet_data_image_header_read(ef, key,
+ &w, &h, &alpha, &compression, &quality, &lossy);
+ if (IMG_TOO_BIG(w, h))
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+ if (!ok)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ goto on_error;
+ }
+ data = ilp->buffer;
+ if (!data)
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+ ok = eet_data_image_read_to_surface(ef, key, 0, 0,
+ data, w, h, w * 4,
+ &alpha, &compression, &quality, &lossy);
+ if (!ok)
+ {
+ *error = CSERVE2_GENERIC;
+ goto on_error;
+ }
+ if (alpha)
+ {
+ ilp->alpha = 1;
+
+ body = ilp->buffer;
+
+ end = body + (w * h);
+ for (p = body; p < end; p++)
+ {
+ DATA32 r, g, b, a;
+
+ a = A_VAL(p);
+ r = R_VAL(p);
+ g = G_VAL(p);
+ b = B_VAL(p);
+ if ((a == 0) || (a == 255)) nas++;
+ if (r > a) r = a;
+ if (g > a) g = a;
+ if (b > a) b = a;
+ *p = ARGB_JOIN(a, r, g, b);
+ }
+ if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (w * h))
+ ilp->alpha_sparse = 1;
+ }
+ *error = CSERVE2_NONE;
+ res = EINA_TRUE;
+
+ on_error:
+ eet_close(ef);
+ return res;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "eet",
+ evas_image_load_file_head_eet,
+ evas_image_load_file_data_eet
+};
+
+static Eina_Bool
+module_init(void)
+{
+ eet_init();
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+ eet_shutdown();
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_ICO
+#if !EVAS_STATIC_BUILD_ICO
+
+pkgdir = $(libdir)/evas/cserve2/loaders/ico/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_ico.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_ico.la
+#libevas_loader_ico_la_SOURCES = evas_image_load_ico.c
+#libevas_loader_ico_la_LIBADD =
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+static Eina_Bool
+read_ushort(unsigned char *map, size_t length, size_t *position, unsigned short *ret)
+{
+ unsigned char b[2];
+
+ if (*position + 2 > length) return EINA_FALSE;
+ b[0] = map[(*position)++];
+ b[1] = map[(*position)++];
+ *ret = (b[1] << 8) | b[0];
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_uint(unsigned char *map, size_t length, size_t *position, unsigned int *ret)
+{
+ unsigned char b[4];
+ unsigned int i;
+
+ if (*position + 4 > length) return EINA_FALSE;
+ for (i = 0; i < 4; i++)
+ b[i] = map[(*position)++];
+ *ret = ARGB_JOIN(b[3], b[2], b[1], b[0]);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_uchar(unsigned char *map, size_t length, size_t *position, unsigned char *ret)
+{
+ if (*position + 1 > length) return EINA_FALSE;
+ *ret = map[(*position)++];
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_mem(unsigned char *map, size_t length, size_t *position, void *buffer, int size)
+{
+ if (*position + size > length) return EINA_FALSE;
+ memcpy(buffer, map + *position, size);
+ *position += size;
+ return EINA_TRUE;
+}
+
+enum
+{
+ SMALLEST,
+ BIGGEST,
+ SMALLER,
+ BIGGER
+};
+
+enum
+{
+ ICON = 1,
+ CURSOR = 2
+};
+
+static Eina_Bool
+evas_image_load_file_head_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ unsigned short word;
+ unsigned char byte;
+ int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0,
+ bpp = 0, pdelta, search = -1, have_choice = 0,
+ hasa = 1;
+ unsigned int bmoffset, bmsize, fsize;
+ unsigned short reserved, type, count;
+ struct {
+ int pdelta;
+ int w, h;
+ int cols;
+ int bpp, planes;
+ int hot_x, hot_y;
+ unsigned int bmoffset, bmsize;
+ } chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ f = eina_file_open(file, EINA_FALSE);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ fsize = eina_file_size_get(f);
+ if (fsize < (6 + 16 + 40)) goto close_file;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto close_file;
+
+ // key:
+ // NULL == highest res
+ // biggest == highest res
+ // smallest == lowest res
+ //
+ // smaller == next size SMALLER than load opts WxH (if possible)
+ // bigger == next size BIGGER than load opts WxH (if possible)
+ // more ?
+
+ search = BIGGEST;
+ if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
+ {
+ wanted_w = ilp->opts.w;
+ wanted_h = ilp->opts.h;
+ search = SMALLER;
+ }
+
+ if (!read_ushort(map, fsize, &position, &reserved)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &type)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &count)) goto close_file;
+ if (!((reserved == 0) &&
+ ((type == ICON) || (type == CURSOR)) && (count > 0)))
+ goto close_file;
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+ if (key)
+ {
+ if (!strcmp(key, "biggest"))
+ {
+ wanted_w = 0;
+ wanted_h = 0;
+ search = BIGGEST;
+ chosen.pdelta = 0;
+ }
+ else if (!strcmp(key, "smallest"))
+ {
+ wanted_w = 1;
+ wanted_h = 1;
+ search = SMALLEST;
+ chosen.pdelta = 0x7fffffff;
+ }
+ else if (!strcmp(key, "smaller"))
+ {
+ chosen.pdelta = 0x7fffffff;
+ search = SMALLER;
+ }
+ else if (!strcmp(key, "bigger"))
+ {
+ chosen.pdelta = 0x7fffffff;
+ search = BIGGER;
+ }
+ }
+ for (i = 0; i < count; i++)
+ {
+ unsigned char tw = 0, th = 0, tcols = 0;
+ if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
+ w = tw;
+ if (w <= 0) w = 256;
+ if (!read_uchar(map, fsize, &position, &th)) goto close_file;
+ h = th;
+ if (h <= 0) h = 256;
+ if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
+ cols = tcols;
+ if (cols <= 0) cols = 256;
+ if (!read_uchar(map, fsize, &position, &byte)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file;
+ if (type == CURSOR) planes = word;
+ //else hot_x = word;
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file;
+ if (type == CURSOR) bpp = word;
+ //else hot_y = word;
+ if (!read_uint(map, fsize, &position, &bmsize)) goto close_file;
+ if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file;
+ if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
+ if (search == BIGGEST)
+ {
+ pdelta = w * h;
+ if ((!have_choice) ||
+ ((pdelta >= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else
+ {
+ if (search == SMALLEST)
+ {
+ pdelta = w * h;
+ if ((!have_choice) ||
+ ((pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else if (search == SMALLER)
+ {
+ pdelta = (wanted_w * wanted_h) - (w * h);
+ if ((!have_choice) ||
+ ((w <= wanted_w) && (h <= wanted_h) &&
+ (pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ if (pdelta < 0) pdelta = 0x7fffffff;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else if (search == BIGGER)
+ {
+ pdelta = (w * h) - (wanted_w * wanted_h);
+ if ((!have_choice) ||
+ ((w >= wanted_w) && (h >= wanted_h) &&
+ (pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ if (pdelta < 0) pdelta = 0x7fffffff;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ }
+ }
+ if (chosen.bmoffset == 0) goto close_file;
+ position = chosen.bmoffset;
+
+ w = chosen.w;
+ h = chosen.h;
+ if ((w > 256) || (h > 256)) goto close_file;
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+
+ ilp->w = w;
+ ilp->h = h;
+ if (hasa) ilp->alpha = 1;
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ unsigned short word;
+ unsigned char byte;
+ unsigned int dword;
+ int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0,
+ bpp = 0, pdelta, search = -1, have_choice = 0,
+ stride, pstride, j, right_way_up = 0, diff_size = 0, cols2;
+ unsigned int bmoffset, bmsize, bitcount, fsize,
+ *pal, *surface, *pix, none_zero_alpha = 0;
+ unsigned short reserved, type, count;
+ unsigned char *maskbuf, *pixbuf, *p;
+ struct {
+ int pdelta;
+ int w, h;
+ int cols;
+ int bpp, planes;
+ int hot_x, hot_y;
+ unsigned int bmoffset, bmsize;
+ } chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ f = eina_file_open(file, EINA_FALSE);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ fsize = eina_file_size_get(f);
+ if (fsize < (6 + 16 + 40)) goto close_file;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto close_file;
+
+ // key:
+ // NULL == highest res
+ // biggest == highest res
+ // smallest == lowest res
+ //
+ // smaller == next size SMALLER than load opts WxH (if possible)
+ // bigger == next size BIGGER than load opts WxH (if possible)
+ // more ?
+
+ search = BIGGEST;
+ if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
+ {
+ wanted_w = ilp->opts.w;
+ wanted_h = ilp->opts.h;
+ search = SMALLER;
+ }
+
+ if (!read_ushort(map, fsize, &position, &reserved)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &type)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &count)) goto close_file;
+ if (!((reserved == 0) &&
+ ((type == ICON) || (type == CURSOR)) && (count > 0)))
+ goto close_file;
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+ if (key)
+ {
+ if (!strcmp(key, "biggest"))
+ {
+ wanted_w = 0;
+ wanted_h = 0;
+ search = BIGGEST;
+ chosen.pdelta = 0;
+ }
+ else if (!strcmp(key, "smallest"))
+ {
+ wanted_w = 1;
+ wanted_h = 1;
+ search = SMALLEST;
+ chosen.pdelta = 0x7fffffff;
+ }
+ else if (!strcmp(key, "smaller"))
+ {
+ chosen.pdelta = 0x7fffffff;
+ search = SMALLER;
+ }
+ else if (!strcmp(key, "bigger"))
+ {
+ chosen.pdelta = 0x7fffffff;
+ search = BIGGER;
+ }
+ }
+ for (i = 0; i < count; i++)
+ {
+ unsigned char tw = 0, th = 0, tcols = 0;
+ if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
+ w = tw;
+ if (w <= 0) w = 256;
+ if (!read_uchar(map, fsize, &position, &th)) goto close_file;
+ h = th;
+ if (h <= 0) h = 256;
+ if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
+ cols = tcols;
+ if (cols <= 0) cols = 256;
+ if (!read_uchar(map, fsize, &position, &byte)) goto close_file;
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file;
+ if (type == 1) planes = word;
+ //else hot_x = word;
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file;
+ if (type == 1) bpp = word;
+ //else hot_y = word;
+ if (!read_uint(map, fsize, &position, &bmsize)) goto close_file;
+ if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file;
+ if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
+ if (search == BIGGEST)
+ {
+ pdelta = w * h;
+ if ((!have_choice) ||
+ ((pdelta >= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else
+ {
+ if (search == SMALLEST)
+ {
+ pdelta = w * h;
+ if ((!have_choice) ||
+ ((pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else if (search == SMALLER)
+ {
+ pdelta = (wanted_w * wanted_h) - (w * h);
+ if ((!have_choice) ||
+ ((w <= wanted_w) && (h <= wanted_h) &&
+ (pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ if (pdelta < 0) pdelta = 0x7fffffff;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ else if (search == BIGGER)
+ {
+ pdelta = (w * h) - (wanted_w * wanted_h);
+ if ((!have_choice) ||
+ ((w >= wanted_w) && (h >= wanted_h) &&
+ (pdelta <= chosen.pdelta) &&
+ (((bpp >= 3) && (bpp >= chosen.bpp)) ||
+ ((bpp < 3) && (cols >= chosen.cols)))))
+ {
+ have_choice = 1;
+ if (pdelta < 0) pdelta = 0x7fffffff;
+ chosen.pdelta = pdelta;
+ chosen.w = w;
+ chosen.h = h;
+ chosen.cols = cols;
+ chosen.bpp = bpp;
+ chosen.planes = planes;
+ chosen.bmsize = bmsize;
+ chosen.bmoffset = bmoffset;
+ }
+ }
+ }
+ }
+ if (chosen.bmoffset == 0) goto close_file;
+ position = chosen.bmoffset;
+
+ w = chosen.w;
+ h = chosen.h;
+ cols = chosen.cols;
+ bpp = chosen.bpp;
+ // changed since we loaded header?
+ if (((int)ilp->w != w) || ((int)ilp->h != h)) goto close_file;
+
+ // read bmp header time... let's do some checking
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // headersize - dont care
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // width
+ if (dword > 0)
+ {
+ if ((int)dword != w)
+ {
+ w = dword;
+ diff_size = 1;
+ }
+ }
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // height
+ if (dword > 0)
+ {
+ if ((int)dword != (h * 2))
+ {
+ h = dword / 2;
+ diff_size = 1;
+ }
+ }
+ if (diff_size)
+ {
+ ERR("Broken ICO file: %s - "
+ " Reporting size of %ix%i in index, but bitmap is %ix%i. "
+ " May be expanded or cropped.",
+ file, ilp->w, ilp->h, w, h);
+ }
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file; // planes
+ //planes2 = word;
+ if (!read_ushort(map, fsize, &position, &word)) goto close_file; // bitcount
+ bitcount = word;
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // compression
+ //compression = dword;
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // imagesize
+ //imagesize = dword;
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // z pixels per m
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // y pizels per m
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors used
+ //colorsused = dword;
+ if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors important
+ //colorsimportant = dword;
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ memset(surface, 0, ilp->w * ilp->h * 4);
+
+ if (!((bitcount == 1) || (bitcount == 4) || (bitcount == 8) ||
+ (bitcount == 24) || (bitcount == 32)))
+ goto close_file;
+ if (bitcount <= 8)
+ {
+ cols2 = 1 << bitcount;
+ if (cols == 0) cols = cols2;
+ if (cols > cols2) cols = cols2;
+ if (cols > 256) cols = 256;
+ }
+ else
+ cols = 0;
+ if (bitcount > 8) cols = 0;
+
+ pal = alloca(256 * 4);
+ for (i = 0; i < cols; i++)
+ {
+ unsigned char a, r, g, b;
+
+ if (!read_uchar(map, fsize, &position, &b)) goto close_file;
+ if (!read_uchar(map, fsize, &position, &g)) goto close_file;
+ if (!read_uchar(map, fsize, &position, &r)) goto close_file;
+ if (!read_uchar(map, fsize, &position, &a)) goto close_file;
+ a = 0xff;
+ pal[i] = ARGB_JOIN(a, r, g, b);
+ }
+ stride = ((w + 31) / 32);
+ maskbuf = alloca(stride * h);
+ pixbuf = alloca(stride * 32 * 4); // more than enough
+ if (bitcount == 1)
+ {
+ pstride = stride * 4;
+ for (i = 0; i < h; i++)
+ {
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
+ p = pixbuf;
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ if (j >= (int)ilp->w) break;
+ if ((j & 0x7) == 0x0)
+ {
+ *pix = pal[*p >> 7];
+ }
+ else if ((j & 0x7) == 0x1)
+ {
+ *pix = pal[(*p >> 6) & 0x1];
+ }
+ else if ((j & 0x7) == 0x2)
+ {
+ *pix = pal[(*p >> 5) & 0x1];
+ }
+ else if ((j & 0x7) == 0x3)
+ {
+ *pix = pal[(*p >> 4) & 0x1];
+ }
+ else if ((j & 0x7) == 0x4)
+ {
+ *pix = pal[(*p >> 3) & 0x1];
+ }
+ else if ((j & 0x7) == 0x5)
+ {
+ *pix = pal[(*p >> 2) & 0x1];
+ }
+ else if ((j & 0x7) == 0x6)
+ {
+ *pix = pal[(*p >> 1) & 0x1];
+ }
+ else
+ {
+ *pix = pal[*p & 0x1];
+ p++;
+ }
+ pix++;
+ }
+ }
+ }
+ else if (bitcount == 4)
+ {
+ pstride = ((w + 7) / 8) * 4;
+ for (i = 0; i < h; i++)
+ {
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
+ p = pixbuf;
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ if (j >= (int)ilp->w) break;
+ if ((j & 0x1) == 0x1)
+ {
+ *pix = pal[*p & 0x0f];
+ p++;
+ }
+ else
+ {
+ *pix = pal[*p >> 4];
+ }
+ pix++;
+ }
+ }
+ }
+ else if (bitcount == 8)
+ {
+ pstride = ((w + 3) / 4) * 4;
+ for (i = 0; i < h; i++)
+ {
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
+ p = pixbuf;
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ if (j >= (int)ilp->w) break;
+ *pix = pal[*p];
+ p++;
+ pix++;
+ }
+ }
+ }
+ else if (bitcount == 24)
+ {
+ pstride = w * 3;
+ for (i = 0; i < h; i++)
+ {
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
+ p = pixbuf;
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ unsigned char a, r, g, b;
+
+ if (j >= (int)ilp->w) break;
+ b = p[0];
+ g = p[1];
+ r = p[2];
+ p += 3;
+ a = 0xff;
+ *pix = ARGB_JOIN(a, r, g, b);
+ pix++;
+ }
+ }
+ }
+ else if (bitcount == 32)
+ {
+ pstride = w * 4;
+ for (i = 0; i < h; i++)
+ {
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
+ p = pixbuf;
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ unsigned char a, r, g, b;
+
+ if (j >= (int)ilp->w) break;
+ b = p[0];
+ g = p[1];
+ r = p[2];
+ a = p[3];
+ p += 4;
+ if (a) none_zero_alpha = 1;
+ *pix = ARGB_JOIN(a, r, g, b);
+ pix++;
+ }
+ }
+ }
+ if (!none_zero_alpha)
+ {
+ if (!read_mem(map, fsize, &position, maskbuf, stride * 4 * h)) goto close_file;
+ // apply mask
+ pix = surface;
+ for (i = 0; i < h; i++)
+ {
+ unsigned char *m;
+
+ pix = surface + (i * ilp->w);
+ if (!right_way_up) pix = surface + ((ilp->h - 1 - i) * ilp->w);
+ m = maskbuf + (stride * i * 4);
+ if (i >= (int)ilp->h) continue;
+ for (j = 0; j < w; j++)
+ {
+ if (j >= (int)ilp->w) break;
+ if (*m & (1 << (7 - (j & 0x7))))
+ A_VAL(pix) = 0x00;
+ else
+ A_VAL(pix) = 0xff;
+ if ((j & 0x7) == 0x7) m++;
+ pix++;
+ }
+ }
+ }
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+
+ evas_cserve2_image_premul(ilp);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "ico",
+ evas_image_load_file_head_ico,
+ evas_image_load_file_data_ico
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_jpeg_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_JPEG
+#if !EVAS_STATIC_BUILD_JPEG
+
+pkgdir = $(libdir)/evas/cserve2/loaders/jpeg/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_jpeg.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_jpeg_libs@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_jpeg.la
+#libevas_loader_jpeg_la_SOURCES = evas_image_load_jpeg.c
+#libevas_loader_jpeg_la_LIBADD = @evas_image_loader_jpeg_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <setjmp.h>
+#include <jpeglib.h>
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+typedef struct _JPEG_error_mgr *emptr;
+struct _JPEG_error_mgr
+{
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+};
+
+static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
+static void _JPEGErrorHandler(j_common_ptr cinfo);
+static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
+
+static void
+_JPEGFatalErrorHandler(j_common_ptr cinfo)
+{
+ emptr errmgr;
+
+ errmgr = (emptr) cinfo->err;
+ /* cinfo->err->output_message(cinfo);*/
+ longjmp(errmgr->setjmp_buffer, 1);
+ return;
+}
+
+static void
+_JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
+{
+/* emptr errmgr; */
+
+/* errmgr = (emptr) cinfo->err; */
+ /* cinfo->err->output_message(cinfo);*/
+ /* longjmp(errmgr->setjmp_buffer, 1);*/
+ return;
+}
+
+static void
+_JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
+{
+/* emptr errmgr; */
+
+/* errmgr = (emptr) cinfo->err; */
+ /* cinfo->err->output_message(cinfo);*/
+ /* longjmp(errmgr->setjmp_buffer, 1);*/
+ return;
+}
+
+struct jpeg_membuf_src
+{
+ struct jpeg_source_mgr pub;
+
+ const unsigned char *buf;
+ size_t len;
+ struct jpeg_membuf_src *self;
+};
+
+static void
+_evas_jpeg_membuf_src_init(j_decompress_ptr cinfo __UNUSED__)
+{
+}
+
+static boolean
+_evas_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
+{
+ static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
+ struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
+
+ src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
+ src->pub.next_input_byte = jpeg_eoi;
+
+ return TRUE;
+}
+
+static void
+_evas_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
+ long num_bytes)
+{
+ struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
+
+ if ((((long)src->pub.bytes_in_buffer - (long)src->len) > num_bytes) ||
+ ((long)src->pub.bytes_in_buffer < num_bytes))
+ {
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo));
+ return;
+ }
+ src->pub.bytes_in_buffer -= num_bytes;
+ src->pub.next_input_byte += num_bytes;
+}
+
+static void
+_evas_jpeg_membuf_src_term(j_decompress_ptr cinfo)
+{
+ struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
+ if (!src) return;
+ free(src);
+ cinfo->src = NULL;
+}
+
+static int
+_evas_jpeg_membuf_src(j_decompress_ptr cinfo,
+ void *map, size_t length)
+{
+ struct jpeg_membuf_src *src;
+
+ src = calloc(1, sizeof(*src));
+ if (!src)
+ return -1;
+
+ src->self = src;
+
+ cinfo->src = &src->pub;
+ src->buf = map;
+ src->len = length;
+ src->pub.init_source = _evas_jpeg_membuf_src_init;
+ src->pub.fill_input_buffer = _evas_jpeg_membuf_src_fill;
+ src->pub.skip_input_data = _evas_jpeg_membuf_src_skip;
+ src->pub.resync_to_restart = jpeg_resync_to_restart;
+ src->pub.term_source = _evas_jpeg_membuf_src_term;
+ src->pub.bytes_in_buffer = src->len;
+ src->pub.next_input_byte = src->buf;
+
+ return 0;
+}
+
+/*! Magic number for EXIF header & App1*/
+static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
+static const unsigned char App1[] = {0xff, 0xe1};
+typedef enum {
+ EXIF_BYTE_ALIGN_II,
+ EXIF_BYTE_ALIGN_MM
+} ExifByteAlign;
+
+static int
+_get_orientation(void *map, size_t length)
+{
+ char *buf;
+ char orientation[2];
+ ExifByteAlign byte_align;
+ unsigned int num_directory = 0;
+ unsigned int i, j;
+ int direction;
+
+ /* open file and get 22 byte frome file */
+ if (!map) return 0;
+ /* 1. read 22byte */
+ if (length < 22) return 0;
+ buf = (char *)map;
+
+ /* 2. check 2,3 bypte with APP1(0xFFE1) */
+ if (memcmp(buf + 2, App1, sizeof (App1))) return 0;
+
+ /* 3. check 6~11bype with Exif Header (0x45786966 0000) */
+ if (memcmp(buf + 6, ExifHeader, sizeof (ExifHeader))) return 0;
+
+ /* 4. get 12&13 byte get info of "II(0x4949)" or "MM(0x4d4d)" */
+ /* 5. get [20]&[21] get directory entry # */
+ if (!strncmp(buf + 12, "MM", 2))
+ {
+ byte_align = EXIF_BYTE_ALIGN_MM;
+ num_directory = ((*(buf + 20) << 8) + *(buf + 21));
+ orientation[0] = 0x01;
+ orientation[1] = 0x12;
+ }
+ else if (!strncmp(buf + 12, "II", 2))
+ {
+ byte_align = EXIF_BYTE_ALIGN_II;
+ num_directory = ((*(buf + 21) << 8) + *(buf + 20));
+ orientation[0] = 0x12;
+ orientation[1] = 0x01;
+ }
+ else return 0;
+
+ buf = map + 22;
+
+ if (length < (12 * num_directory + 22)) return 0;
+
+ j = 0;
+
+ for (i = 0; i < num_directory; i++ )
+ {
+ if (!strncmp(buf + j, orientation, 2))
+ {
+ /*get orientation tag */
+ if (byte_align == EXIF_BYTE_ALIGN_MM)
+ direction = *(buf+ j + 11);
+ else direction = *(buf+ j + 8);
+ switch (direction)
+ {
+ case 3:
+ case 4:
+ return 180;
+ case 6:
+ case 7:
+ return 90;
+ case 5:
+ case 8:
+ return 270;
+ default:
+ return 0;
+ }
+ }
+ else
+ j = j + 12;
+ }
+ return 0;
+}
+
+static Eina_Bool
+evas_image_load_file_head_jpeg_internal(Evas_Img_Load_Params *ilp,
+ void *map, size_t length,
+ int *error)
+{
+ unsigned int w, h, scalew, scaleh;
+ struct jpeg_decompress_struct cinfo;
+ struct _JPEG_error_mgr jerr;
+
+ /* for rotation decoding */
+ int degree = 0;
+ Eina_Bool change_wh = EINA_FALSE;
+ unsigned int load_opts_w = 0, load_opts_h = 0;
+
+ cinfo.err = jpeg_std_error(&(jerr.pub));
+ jerr.pub.error_exit = _JPEGFatalErrorHandler;
+ jerr.pub.emit_message = _JPEGErrorHandler2;
+ jerr.pub.output_message = _JPEGErrorHandler;
+ if (setjmp(jerr.setjmp_buffer))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ if (cinfo.saw_JFIF_marker)
+ *error = CSERVE2_CORRUPT_FILE;
+ else
+ *error = CSERVE2_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ degree = 0;
+ change_wh = EINA_FALSE;
+ jpeg_create_decompress(&cinfo);
+
+ if (_evas_jpeg_membuf_src(&cinfo, map, length))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ jpeg_read_header(&cinfo, TRUE);
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+ cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
+ cinfo.dither_mode = JDITHER_ORDERED;
+ jpeg_start_decompress(&cinfo);
+
+ /* rotation decoding */
+ if (ilp->opts.orientation)
+ {
+ degree = _get_orientation(map, length);
+ if (degree != 0)
+ {
+ ilp->degree = degree;
+ ilp->rotated = EINA_TRUE;
+
+ if (degree == 90 || degree == 270)
+ change_wh = EINA_TRUE;
+ }
+
+ }
+
+ /* head decoding */
+ w = cinfo.output_width;
+ h = cinfo.output_height;
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ (IMG_TOO_BIG(w, h)))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ if (IMG_TOO_BIG(w, h))
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = CSERVE2_GENERIC;
+ return EINA_FALSE;
+ }
+ if (ilp->opts.scale_down_by > 1)
+ {
+ w /= ilp->opts.scale_down_by;
+ h /= ilp->opts.scale_down_by;
+ }
+ else if (ilp->opts.dpi > 0.0)
+ {
+ w = (w * ilp->opts.dpi) / 90.0;
+ h = (h * ilp->opts.dpi) / 90.0;
+ }
+ else if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
+ {
+ unsigned int w2 = w, h2 = h;
+ /* user set load_opts' w,h on the assumption
+ that image already rotated according to it's orientation info */
+ if (change_wh)
+ {
+ load_opts_w = ilp->opts.w;
+ load_opts_h = ilp->opts.h;
+ ilp->opts.w = load_opts_h;
+ ilp->opts.h = load_opts_w;
+ }
+
+ if (ilp->opts.w > 0)
+ {
+ w2 = ilp->opts.w;
+ h2 = (ilp->opts.w * h) / w;
+ if ((ilp->opts.h > 0) && (h2 > ilp->opts.h))
+ {
+ unsigned int w3;
+ h2 = ilp->opts.h;
+ w3 = (ilp->opts.h * w) / h;
+ if (w3 > w2)
+ w2 = w3;
+ }
+ }
+ else if (ilp->opts.h > 0)
+ {
+ h2 = ilp->opts.h;
+ w2 = (ilp->opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ if (change_wh)
+ {
+ ilp->opts.w = load_opts_w;
+ ilp->opts.h = load_opts_h;
+ }
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+
+ if ((w != cinfo.output_width) || (h != cinfo.output_height))
+ {
+ scalew = cinfo.output_width / w;
+ scaleh = cinfo.output_height / h;
+
+ ilp->scale = scalew;
+ if (scaleh < scalew) ilp->scale = scaleh;
+
+ if (ilp->scale > 8) ilp->scale = 8;
+ else if (ilp->scale < 1) ilp->scale = 1;
+
+ if (ilp->scale == 3) ilp->scale = 2;
+ else if (ilp->scale == 5) ilp->scale = 4;
+ else if (ilp->scale == 6) ilp->scale = 4;
+ else if (ilp->scale == 7) ilp->scale = 4;
+ }
+
+ if (ilp->scale > 1)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ jpeg_create_decompress(&cinfo);
+
+ if (_evas_jpeg_membuf_src(&cinfo, map, length))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ jpeg_read_header(&cinfo, TRUE);
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+ cinfo.scale_num = 1;
+ cinfo.scale_denom = ilp->scale;
+ jpeg_calc_output_dimensions(&(cinfo));
+ jpeg_start_decompress(&cinfo);
+ }
+
+ ilp->w = cinfo.output_width;
+ ilp->h = cinfo.output_height;
+
+ // be nice and clip region to image. if its totally outside, fail load
+ if ((ilp->opts.rw > 0) && (ilp->opts.rh > 0))
+ {
+ unsigned int load_region_x = 0, load_region_y = 0;
+ unsigned int load_region_w = 0, load_region_h = 0;
+ if (ilp->rotated)
+ {
+ load_region_x = ilp->opts.rx;
+ load_region_y = ilp->opts.ry;
+ load_region_w = ilp->opts.rw;
+ load_region_h = ilp->opts.rh;
+
+ switch (degree)
+ {
+ case 90:
+ ilp->opts.rx = load_region_y;
+ ilp->opts.ry = h - (load_region_x + load_region_w);
+ ilp->opts.rw = load_region_h;
+ ilp->opts.rh = load_region_w;
+ break;
+ case 180:
+ ilp->opts.rx = w - (load_region_x+ load_region_w);
+ ilp->opts.ry = h - (load_region_y + load_region_h);
+
+ break;
+ case 270:
+ ilp->opts.rx = w - (load_region_y + load_region_h);
+ ilp->opts.ry = load_region_x;
+ ilp->opts.rw = load_region_h;
+ ilp->opts.rh = load_region_w;
+ break;
+ default:
+ break;
+ }
+
+ }
+ RECTS_CLIP_TO_RECT(ilp->opts.rx, ilp->opts.ry,
+ ilp->opts.rw, ilp->opts.rh,
+ 0, 0, ilp->w, ilp->h);
+ if ((ilp->opts.rw <= 0) || (ilp->opts.rh <= 0))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_GENERIC;
+ return EINA_FALSE;
+ }
+ ilp->w = ilp->opts.rw;
+ ilp->h = ilp->opts.rh;
+ if (ilp->rotated)
+ {
+ ilp->opts.rx = load_region_x;
+ ilp->opts.ry = load_region_y;
+ ilp->opts.rw = load_region_w;
+ ilp->opts.rh = load_region_h;
+ }
+ }
+/* end head decoding */
+
+ if (change_wh)
+ {
+ unsigned int tmp;
+ tmp = ilp->w;
+ ilp->w = ilp->h;
+ ilp->h = tmp;
+ }
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_NONE;
+ return EINA_TRUE;
+}
+
+/*
+static double
+get_time(void)
+{
+ struct timeval timev;
+
+ gettimeofday(&timev, NULL);
+ return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+}
+*/
+
+static Eina_Bool
+evas_image_load_file_data_jpeg_internal(Evas_Img_Load_Params *ilp,
+ void *map, size_t size,
+ int *error)
+{
+ unsigned int w, h;
+ struct jpeg_decompress_struct cinfo;
+ struct _JPEG_error_mgr jerr;
+ DATA8 *ptr, *line[16], *data;
+ DATA32 *ptr2, *ptr_rotate = NULL;
+ unsigned int x, y, l, i, scans;
+ int region = 0;
+ /* rotation setting */
+ unsigned int tmp;
+ unsigned int load_region_x = 0, load_region_y = 0;
+ unsigned int load_region_w = 0, load_region_h = 0;
+ volatile int degree = 0;
+ volatile Eina_Bool change_wh = EINA_FALSE;
+ Eina_Bool line_done = EINA_FALSE;
+
+ if (ilp->rotated)
+ {
+ degree = ilp->degree;
+ if (degree == 90 || degree == 270)
+ change_wh = EINA_TRUE;
+ }
+
+ cinfo.err = jpeg_std_error(&(jerr.pub));
+ jerr.pub.error_exit = _JPEGFatalErrorHandler;
+ jerr.pub.emit_message = _JPEGErrorHandler2;
+ jerr.pub.output_message = _JPEGErrorHandler;
+ if (setjmp(jerr.setjmp_buffer))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ jpeg_create_decompress(&cinfo);
+
+ if (_evas_jpeg_membuf_src(&cinfo, map, size))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ return 0;
+ }
+
+ jpeg_read_header(&cinfo, TRUE);
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+ cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
+ cinfo.dither_mode = JDITHER_ORDERED;
+
+ if (ilp->scale > 1)
+ {
+ cinfo.scale_num = 1;
+ cinfo.scale_denom = ilp->scale;
+ }
+
+ /* Colorspace conversion options */
+ /* libjpeg can do the following conversions: */
+ /* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
+ switch (cinfo.jpeg_color_space)
+ {
+ case JCS_UNKNOWN:
+ break;
+ case JCS_GRAYSCALE:
+ case JCS_RGB:
+ case JCS_YCbCr:
+ cinfo.out_color_space = JCS_RGB;
+ break;
+ case JCS_CMYK:
+ case JCS_YCCK:
+ cinfo.out_color_space = JCS_CMYK;
+ break;
+ default:
+ /* unhandled format, do something */
+ break;
+ }
+
+/* head decoding */
+ jpeg_calc_output_dimensions(&(cinfo));
+ jpeg_start_decompress(&cinfo);
+
+ w = cinfo.output_width;
+ h = cinfo.output_height;
+
+ if (change_wh)
+ {
+ tmp = ilp->w;
+ ilp->w = ilp->h;
+ ilp->h = tmp;
+ }
+
+ if ((ilp->opts.rw > 0) && (ilp->opts.rh > 0))
+ {
+ region = 1;
+
+ if (ilp->rotated)
+ {
+ load_region_x = ilp->opts.rx;
+ load_region_y = ilp->opts.ry;
+ load_region_w = ilp->opts.rw;
+ load_region_h = ilp->opts.rh;
+
+ switch (degree)
+ {
+ case 90:
+ ilp->opts.rx = load_region_y;
+ ilp->opts.ry = h - (load_region_x + load_region_w);
+ ilp->opts.rw = load_region_h;
+ ilp->opts.rh = load_region_w;
+ break;
+ case 180:
+ ilp->opts.rx = w - (load_region_x+ load_region_w);
+ ilp->opts.ry = h - (load_region_y + load_region_h);
+
+ break;
+ case 270:
+ ilp->opts.rx = w - (load_region_y + load_region_h);
+ ilp->opts.ry = load_region_x;
+ ilp->opts.rw = load_region_h;
+ ilp->opts.rh = load_region_w;
+ break;
+ default:
+ break;
+ }
+
+ }
+#ifdef BUILD_LOADER_JPEG_REGION
+ cinfo.region_x = ilp->opts.rx;
+ cinfo.region_y = ilp->opts.ry;
+ cinfo.region_w = ilp->opts.rw;
+ cinfo.region_h = ilp->opts.rh;
+#endif
+ }
+ /* what to do about this? We'll check for this kind of races on loaders
+ * or cache invalidation due to file modification should always be
+ * detected by the server? */
+
+ if ((!region) && ((w != ilp->w) || (h != ilp->h)))
+ {
+ // race condition, the file could have change from when we call header
+ // this test will not solve the problem with region code.
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_GENERIC;
+ return EINA_FALSE;
+ }
+
+ if ((region) &&
+ ((ilp->w != ilp->opts.rw) || (ilp->h != ilp->opts.rh)))
+ {
+ ilp->w = ilp->opts.rw;
+ ilp->h = ilp->opts.rh;
+ }
+
+ if (!(((cinfo.out_color_space == JCS_RGB) &&
+ ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
+ ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+/* end head decoding */
+/* data decoding */
+ if (cinfo.rec_outbuf_height > 16)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+ data = alloca(w * 16 * cinfo.output_components);
+ if ((ilp->rotated) && change_wh)
+ {
+ ptr2 = malloc(ilp->w * ilp->h * sizeof(DATA32));
+ ptr_rotate = ptr2;
+ }
+ else
+ ptr2 = ilp->buffer;;
+
+ if (!ptr2)
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ /* We handle first CMYK (4 components) */
+ if (cinfo.output_components == 4)
+ {
+ // FIXME: handle region
+ for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
+ line[i] = data + (i * w * 4);
+ for (l = 0; l < h; l += cinfo.rec_outbuf_height)
+ {
+ jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+ scans = cinfo.rec_outbuf_height;
+ if ((h - l) < scans) scans = h - l;
+ ptr = data;
+ if (!region)
+ {
+ for (y = 0; y < scans; y++)
+ {
+ if (cinfo.saw_Adobe_marker)
+ {
+ for (x = 0; x < w; x++)
+ {
+ /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
+ /* that is C is replaces by 255 - C, etc...*/
+ /* See the comment below for the computation of RGB values from CMYK ones. */
+ *ptr2 =
+ (0xff000000) |
+ ((ptr[0] * ptr[3] / 255) << 16) |
+ ((ptr[1] * ptr[3] / 255) << 8) |
+ ((ptr[2] * ptr[3] / 255));
+ ptr += 4;
+ ptr2++;
+ }
+ }
+ else
+ {
+ for (x = 0; x < w; x++)
+ {
+ /* Conversion from CMYK to RGB is done in 2 steps: */
+ /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
+ /* after computation, if C, M, Y and K are between 0 and 1, we have: */
+ /* R = (1 - C) * (1 - K) * 255 */
+ /* G = (1 - M) * (1 - K) * 255 */
+ /* B = (1 - Y) * (1 - K) * 255 */
+ /* libjpeg stores CMYK values between 0 and 255, */
+ /* so we replace C by C * 255 / 255, etc... and we obtain: */
+ /* R = (255 - C) * (255 - K) / 255 */
+ /* G = (255 - M) * (255 - K) / 255 */
+ /* B = (255 - Y) * (255 - K) / 255 */
+ /* with C, M, Y and K between 0 and 255. */
+ *ptr2 =
+ (0xff000000) |
+ (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
+ (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
+ (((255 - ptr[2]) * (255 - ptr[3]) / 255));
+ ptr += 4;
+ ptr2++;
+ }
+ }
+ }
+ }
+ else
+ {
+ // if line # > region last line, break
+ if (l >= (ilp->opts.ry + ilp->opts.rh))
+ {
+ line_done = EINA_TRUE;
+ /* if rotation flag is set , we have to rotate image */
+ goto done;
+ /*jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = NONE;
+ return EINA_FALSE;*/
+ }
+ // els if scan block intersects region start or later
+ else if ((l + scans) >
+ (ilp->opts.ry))
+ {
+ for (y = 0; y < scans; y++)
+ {
+ if (((y + l) >= ilp->opts.ry) &&
+ ((y + l) < (ilp->opts.ry + ilp->opts.rh)))
+ {
+ ptr += ilp->opts.rx;
+ if (cinfo.saw_Adobe_marker)
+ {
+ for (x = 0; x < ilp->opts.rw; x++)
+ {
+ /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
+ /* that is C is replaces by 255 - C, etc...*/
+ /* See the comment below for the computation of RGB values from CMYK ones. */
+ *ptr2 =
+ (0xff000000) |
+ ((ptr[0] * ptr[3] / 255) << 16) |
+ ((ptr[1] * ptr[3] / 255) << 8) |
+ ((ptr[2] * ptr[3] / 255));
+ ptr += 4;
+ ptr2++;
+ }
+ }
+ else
+ {
+ for (x = 0; x < ilp->opts.rw; x++)
+ {
+ /* Conversion from CMYK to RGB is done in 2 steps: */
+ /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
+ /* after computation, if C, M, Y and K are between 0 and 1, we have: */
+ /* R = (1 - C) * (1 - K) * 255 */
+ /* G = (1 - M) * (1 - K) * 255 */
+ /* B = (1 - Y) * (1 - K) * 255 */
+ /* libjpeg stores CMYK values between 0 and 255, */
+ /* so we replace C by C * 255 / 255, etc... and we obtain: */
+ /* R = (255 - C) * (255 - K) / 255 */
+ /* G = (255 - M) * (255 - K) / 255 */
+ /* B = (255 - Y) * (255 - K) / 255 */
+ /* with C, M, Y and K between 0 and 255. */
+ *ptr2 =
+ (0xff000000) |
+ (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
+ (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
+ (((255 - ptr[2]) * (255 - ptr[3]) / 255));
+ ptr += 4;
+ ptr2++;
+ }
+ }
+ ptr += (4 * (w - (ilp->opts.rx + ilp->opts.rw)));
+ }
+ else
+ ptr += (4 * w);
+ }
+ }
+ }
+ }
+ }
+ /* We handle then RGB with 3 components */
+ else if (cinfo.output_components == 3)
+ {
+/*
+ double t;
+ if (region)
+ {
+ // debug for now
+ printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
+ ie,
+ ie->w, ie->h,
+ ie->file,
+ ilp->opts.rx,
+ ilp->opts.ry,
+ ilp->opts.rw,
+ ilp->opts.rh);
+ }
+ t = get_time();
+ */
+ for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
+ line[i] = data + (i * w * 3);
+ for (l = 0; l < h; l += cinfo.rec_outbuf_height)
+ {
+ jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+ scans = cinfo.rec_outbuf_height;
+ if ((h - l) < scans) scans = h - l;
+ ptr = data;
+ if (!region)
+ {
+ for (y = 0; y < scans; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
+ ptr += 3;
+ ptr2++;
+ }
+ }
+ }
+ else
+ {
+ // if line # > region last line, break
+ // but not return immediately for rotation job
+ if (l >= (ilp->opts.ry + ilp->opts.rh))
+ {
+ line_done = EINA_TRUE;
+ /* if rotation flag is set , we have to rotate image */
+ goto done;
+ }
+ // else if scan block intersects region start or later
+ else if ((l + scans) >
+ (ilp->opts.ry))
+ {
+ for (y = 0; y < scans; y++)
+ {
+ if (((y + l) >= ilp->opts.ry) &&
+ ((y + l) < (ilp->opts.ry + ilp->opts.rh)))
+ {
+ ptr += (3 * ilp->opts.rx);
+ for (x = 0; x < ilp->opts.rw; x++)
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
+ ptr += 3;
+ ptr2++;
+ }
+ ptr += (3 * (w - (ilp->opts.rx + ilp->opts.rw)));
+ }
+ else
+ ptr += (3 * w);
+ }
+ }
+ }
+ }
+/*
+ t = get_time() - t;
+ printf("%3.3f\n", t);
+ */
+ }
+ /* We finally handle RGB with 1 component */
+ else if (cinfo.output_components == 1)
+ {
+ for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
+ line[i] = data + (i * w);
+ for (l = 0; l < h; l += cinfo.rec_outbuf_height)
+ {
+ jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+ scans = cinfo.rec_outbuf_height;
+ if ((h - l) < scans) scans = h - l;
+ ptr = data;
+ if (!region)
+ {
+ for (y = 0; y < scans; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ ptr++;
+ ptr2++;
+ }
+ }
+ }
+ else
+ {
+ // if line # > region last line, break
+ if (l >= (ilp->opts.ry + ilp->opts.rh))
+ {
+ line_done = EINA_TRUE;
+ /* if rotation flag is set , we have to rotate image */
+ goto done;
+ /*jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = NONE;
+ return EINA_TRUE;*/
+ }
+ // els if scan block intersects region start or later
+ else if ((l + scans) >
+ (ilp->opts.ry))
+ {
+ for (y = 0; y < scans; y++)
+ {
+ if (((y + l) >= ilp->opts.ry) &&
+ ((y + l) < (ilp->opts.ry + ilp->opts.rh)))
+ {
+ ptr += ilp->opts.rx;
+ for (x = 0; x < ilp->opts.rw; x++)
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ ptr++;
+ ptr2++;
+ }
+ ptr += w - (ilp->opts.rx + ilp->opts.rw);
+ }
+ else
+ ptr += w;
+ }
+ }
+ }
+ }
+ }
+ /* if rotation operation need, rotate it */
+done:
+
+ if (ilp->rotated)
+ {
+ DATA32 *data1, *data2, *to, *from;
+ int lx, ly, lw, lh, hw;
+
+ if (change_wh)
+ {
+ tmp = ilp->w;
+ ilp->w = ilp->h;
+ ilp->h = tmp;
+ }
+
+ lw = ilp->w;
+ lh = ilp->h;
+ hw = lw * lh;
+
+ data1 = ilp->buffer;
+
+ if (degree == 180)
+ {
+ DATA32 tmpd;
+
+ data2 = data1 + (lh * lw) -1;
+ for (lx = (lw * lh) / 2; --lx >= 0;)
+ {
+ tmpd = *data1;
+ *data1 = *data2;
+ *data2 = tmpd;
+ data1++;
+ data2--;
+ }
+ }
+ else
+ {
+ data2 = NULL;
+ to = NULL;
+ if (ptr_rotate) data2 = ptr_rotate;
+
+ if (degree == 90)
+ {
+ to = data1 + lw - 1;
+ hw = -hw - 1;
+ }
+ else if (degree == 270)
+ {
+ to = data1 + hw - lw;
+ lw = -lw;
+ hw = hw + 1;
+ }
+
+ if (to)
+ {
+ from = data2;
+ for (lx = ilp->w; --lx >= 0;)
+ {
+ for (ly = ilp->h; --ly >= 0;)
+ {
+ *to = *from;
+ from++;
+ to += lw;
+ }
+ to += hw;
+ }
+ }
+ if (ptr_rotate)
+ {
+ free(ptr_rotate);
+ ptr_rotate = NULL;
+ }
+ }
+ if (region)
+ {
+ ilp->opts.rx = load_region_x;
+ ilp->opts.ry = load_region_y;
+ ilp->opts.rw = load_region_w;
+ ilp->opts.rh = load_region_h;
+ }
+ }
+ if (line_done)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_NONE;
+ return EINA_FALSE;
+ }
+ /* end data decoding */
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ _evas_jpeg_membuf_src_term(&cinfo);
+ *error = CSERVE2_NONE;
+ return EINA_TRUE;
+}
+
+Eina_Bool
+evas_image_load_file_head_jpeg(Evas_Img_Load_Params *ilp,
+ const char *file, const char *key __UNUSED__,
+ int *error)
+{
+ Eina_File *f;
+ void *map;
+ Eina_Bool val = EINA_FALSE;
+
+ f = eina_file_open(file, EINA_FALSE);
+ if (!f)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ map = eina_file_map_all(f, EINA_FILE_WILLNEED);
+ if (!map)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ goto on_error;
+ }
+
+ val = evas_image_load_file_head_jpeg_internal(ilp,
+ map, eina_file_size_get(f),
+ error);
+
+ eina_file_map_free(f, map);
+
+ on_error:
+ eina_file_close(f);
+ return val;
+}
+
+static Eina_Bool
+evas_image_load_file_data_jpeg(Evas_Img_Load_Params *ilp,
+ const char *file, const char *key __UNUSED__,
+ int *error)
+{
+ Eina_File *f;
+ void *map;
+ Eina_Bool val = EINA_FALSE;
+
+ f = eina_file_open(file, EINA_FALSE);
+ if (!f)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ map = eina_file_map_all(f, EINA_FILE_WILLNEED);
+ if (!map)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ goto on_error;
+ }
+
+ val = evas_image_load_file_data_jpeg_internal(ilp,
+ map, eina_file_size_get(f),
+ error);
+
+ eina_file_map_free(f, map);
+
+ on_error:
+ eina_file_close(f);
+ return val;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "jpeg",
+ evas_image_load_file_head_jpeg,
+ evas_image_load_file_data_jpeg
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_pmaps_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_PMAPS
+#if !EVAS_STATIC_BUILD_PMAPS
+
+pkgdir = $(libdir)/evas/cserve2/loaders/pmaps/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_pmaps.c
+
+module_la_LIBADD = @evas_image_loader_pmaps_libs@ @EINA_LIBS@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_pmaps.la
+#libevas_loader_pmaps_la_SOURCES = evas_image_load_pmaps.c
+#libevas_loader_pmaps_la_LIBADD = @evas_image_loader_pmaps_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <ctype.h>
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+#define FILE_BUFFER_SIZE 1024 * 32
+#define FILE_BUFFER_UNREAD_SIZE 16
+
+/* The buffer to load pmaps images */
+typedef struct Pmaps_Buffer Pmaps_Buffer;
+
+struct Pmaps_Buffer
+{
+ Eina_File *file;
+ void *map;
+ size_t position;
+
+ /* the buffer */
+ DATA8 buffer[FILE_BUFFER_SIZE];
+ DATA8 unread[FILE_BUFFER_UNREAD_SIZE];
+ DATA8 *current;
+ DATA8 *end;
+ char type[3];
+ unsigned char unread_len:7;
+ unsigned char last_buffer:1;
+
+ /* image properties */
+ int w;
+ int h;
+ int max;
+
+ /* interface */
+ int (*int_get) (Pmaps_Buffer *b, int *val);
+ int (*color_get) (Pmaps_Buffer *b, DATA32 *color);
+};
+
+/* internal used functions */
+static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error);
+static void pmaps_buffer_close(Pmaps_Buffer *b);
+static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error);
+static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val);
+static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val);
+static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val);
+static int pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color);
+static int pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color);
+static int pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *color);
+
+static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b);
+static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
+static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
+
+static Eina_Bool
+evas_image_load_file_head_pmaps(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Pmaps_Buffer b;
+
+ if (!pmaps_buffer_open(&b, file, error))
+ {
+ pmaps_buffer_close(&b);
+ return EINA_FALSE;
+ }
+
+ if (!pmaps_buffer_header_parse(&b, error))
+ {
+ pmaps_buffer_close(&b);
+ return EINA_FALSE;
+ }
+
+ ilp->w = b.w;
+ ilp->h = b.h;
+
+ pmaps_buffer_close(&b);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_pmaps(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Pmaps_Buffer b;
+ int pixels;
+ DATA32 *ptr;
+
+ if (!pmaps_buffer_open(&b, file, error))
+ {
+ pmaps_buffer_close(&b);
+ return EINA_FALSE;
+ }
+
+ if (!pmaps_buffer_header_parse(&b, error))
+ {
+ pmaps_buffer_close(&b);
+ return EINA_FALSE;
+ }
+
+ pixels = b.w * b.h;
+
+ ptr = ilp->buffer;
+ if (!ptr)
+ {
+ pmaps_buffer_close(&b);
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ if (b.type[1] != '4')
+ {
+ while (pixels > 0 && b.color_get(&b, ptr))
+ {
+ pixels--;
+ ptr++;
+ }
+ }
+ else
+ {
+ while (pixels > 0
+ && (b.current != b.end || pmaps_buffer_raw_update(&b)))
+ {
+ int i;
+
+ for (i = 7; i >= 0 && pixels > 0; i--)
+ {
+ if (*b.current & (1 << i))
+ *ptr = 0xff000000;
+ else
+ *ptr = 0xffffffff;
+ ptr++;
+ pixels--;
+ }
+ b.current++;
+ }
+ }
+
+ /* if there are some pix missing, give them a proper default */
+ memset(ptr, 0xff, 4 * pixels);
+ pmaps_buffer_close(&b);
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+/* internal used functions */
+static Eina_Bool
+pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error)
+{
+ size_t len;
+
+ b->file = eina_file_open(filename, EINA_FALSE);
+ if (!b->file)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL);
+ if (!b->map)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ eina_file_close(b->file);
+ b->file = NULL;
+ return EINA_FALSE;
+ }
+
+ b->position = 0;
+ *b->buffer = 0;
+ *b->unread = 0;
+ b->last_buffer = 0;
+ b->unread_len = 0;
+
+ len = pmaps_buffer_plain_update(b);
+
+ if (len < 3)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ eina_file_map_free(b->file, b->map);
+ eina_file_close(b->file);
+ b->map = NULL;
+ b->file = NULL;
+ return EINA_FALSE;
+ }
+
+ /* copy the type */
+ b->type[0] = b->buffer[0];
+ b->type[1] = b->buffer[1];
+ b->type[2] = 0;
+ /* skip the PX */
+ b->current = b->buffer + 2;
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+static void
+pmaps_buffer_close(Pmaps_Buffer *b)
+{
+ if (b->file)
+ {
+ if (b->map) eina_file_map_free(b->file, b->map);
+ b->map = NULL;
+ eina_file_close(b->file);
+ b->file = NULL;
+ }
+}
+
+static Eina_Bool
+pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error)
+{
+ /* if there is no P at the beginning it is not a file we can parse */
+ if (b->type[0] != 'P')
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ /* get the width */
+ if (!pmaps_buffer_plain_int_get(b, &(b->w)) || b->w < 1)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ /* get the height */
+ if (!pmaps_buffer_plain_int_get(b, &(b->h)) || b->h < 1)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ /* get the maximum value. P1 and P4 don't have a maximum value. */
+ if (!(b->type[1] == '1' || b->type[1] == '4')
+ && (!pmaps_buffer_plain_int_get(b, &(b->max)) || b->max < 1))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ /* set up the color get callback */
+ switch (b->type[1])
+ {
+ /* Black and White */
+ case '1':
+ b->color_get = pmaps_buffer_plain_bw_get;
+ break;
+ case '4':
+ /* Binary black and white use another format */
+ b->color_get = NULL;
+ break;
+ case '2':
+ case '5':
+ b->color_get = pmaps_buffer_gray_get;
+ break;
+ case '3':
+ case '6':
+ b->color_get = pmaps_buffer_rgb_get;
+ break;
+ case '7':
+ /* XXX write me */
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ /* set up the int get callback */
+ switch (b->type[1])
+ {
+ /* RAW */
+ case '5':
+ case '6':
+ if (b->max < 256)
+ b->int_get = pmaps_buffer_1byte_int_get;
+ else
+ b->int_get = pmaps_buffer_2byte_int_get;
+
+ if (b->current == b->end && !pmaps_buffer_raw_update(b))
+ return 0;
+
+ b->current++;
+ break;
+ /* Plain */
+ case '2':
+ case '3':
+ b->int_get = pmaps_buffer_plain_int_get;
+ break;
+ /* Black and White Bitmaps don't use that callback */
+ case '1':
+ case '4':
+ b->int_get = NULL;
+ /* we need to skip the next character fpr P4 it
+ * doesn't hurt if we do it for the P1 as well */
+ b->current++;
+ break;
+ }
+ return 1;
+}
+
+static size_t
+pmaps_buffer_plain_update(Pmaps_Buffer *b)
+{
+ size_t r;
+ size_t max;
+
+ /* if we already are in the last buffer we can not update it */
+ if (b->last_buffer)
+ return 0;
+
+ /* if we have unread bytes we need to put them before the new read
+ * stuff */
+ if (b->unread_len)
+ memcpy(b->buffer, b->unread, b->unread_len);
+
+ max = FILE_BUFFER_SIZE - b->unread_len - 1;
+ if (b->position + max > eina_file_size_get(b->file))
+ max = eina_file_size_get(b->file) - b->position;
+
+ memcpy(&b->buffer[b->unread_len], b->map + b->position, max);
+ b->position += max;
+ r = max + b->unread_len;
+
+ /* we haven't read anything nor have we bytes in the unread buffer */
+ if (r == 0)
+ {
+ b->buffer[0] = '\0';
+ b->end = b->buffer;
+ b->last_buffer = 1;
+ return 0;
+ }
+
+ if (r < FILE_BUFFER_SIZE - 1)
+ {
+ /*we reached eof */ ;
+ b->last_buffer = 1;
+ }
+
+ b->buffer[r] = 0;
+
+ b->unread[0] = '\0';
+ b->unread_len = 0;
+
+ b->buffer[r] = '\0';
+ b->current = b->buffer;
+ b->end = b->buffer + r;
+
+ return r;
+}
+
+static size_t
+pmaps_buffer_raw_update(Pmaps_Buffer *b)
+{
+ size_t r;
+ size_t max;
+
+ if (b->last_buffer)
+ return 0;
+
+ if (b->unread_len)
+ memcpy(b->buffer, b->unread, b->unread_len);
+
+ max = FILE_BUFFER_SIZE - b->unread_len;
+ if (b->position + max > eina_file_size_get(b->file))
+ max = eina_file_size_get(b->file) - b->position;
+
+ memcpy(&b->buffer[b->unread_len], b->map + b->position, max);
+ b->position += max;
+ r = max + b->unread_len;
+
+ if (r < FILE_BUFFER_SIZE)
+ {
+ /*we reached eof */
+ b->last_buffer = 1;
+ }
+
+ b->end = b->buffer + r;
+ b->current = b->buffer;
+
+ if (b->unread_len)
+ {
+ /* the buffer is now read */
+ *b->unread = 0;
+ b->unread_len = 0;
+ }
+
+ return r;
+}
+
+static int
+pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val)
+{
+ char *start;
+ DATA8 lastc;
+
+ /* first skip all white space
+ * Note: we are skipping here actually every character than is not
+ * a digit */
+ while (!isdigit(*b->current))
+ {
+ if (*b->current == '\0')
+ {
+ if (!pmaps_buffer_plain_update(b))
+ return 0;
+
+ continue;
+ }
+ if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
+ return 0;
+ b->current++;
+ }
+
+ start = (char *)b->current;
+ /* now find the end of the number */
+ while (isdigit(*b->current))
+ b->current++;
+
+ lastc = *b->current;
+ *b->current = '\0';
+ *val = atoi(start);
+ *b->current = lastc;
+
+ return 1;
+}
+
+static int
+pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val)
+{
+ /* are we at the end of the buffer? */
+ if (b->current == b->end && !pmaps_buffer_raw_update(b))
+ return 0;
+
+ *val = *b->current;
+ b->current++;
+
+ return 1;
+}
+static int
+pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val)
+{
+ /* are we at the end of the buffer? */
+ if (b->current == b->end && !pmaps_buffer_raw_update(b))
+ return 0;
+
+ *val = (int)(*b->current << 8);
+ b->current++;
+
+ /* are we at the end of the buffer? */
+ if (b->current == b->end && !pmaps_buffer_raw_update(b))
+ return 0;
+
+ *val |= *b->current;
+ b->current++;
+
+ return 1;
+}
+
+static int
+pmaps_buffer_comment_skip(Pmaps_Buffer *b)
+{
+ while (*b->current != '\n')
+ {
+ if (*b->current == '\0')
+ {
+ if (!pmaps_buffer_plain_update(b))
+ return 0;
+
+ continue;
+ }
+ b->current++;
+ }
+ return 1;
+}
+
+static int
+pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color)
+{
+ int vr, vg, vb;
+
+ if (!b->int_get(b, &vr) || !b->int_get(b, &vg) || !b->int_get(b, &vb))
+ return 0;
+
+ if (b->max != 255)
+ {
+ vr = (vr * 255) / b->max;
+ vg = (vg * 255) / b->max;
+ vb = (vb * 255) / b->max;
+ }
+ if (vr > 255)
+ vr = 255;
+ if (vg > 255)
+ vg = 255;
+ if (vb > 255)
+ vb = 255;
+
+ *color = ARGB_JOIN(0xff, vr, vg, vb);
+
+ return 1;
+}
+
+static int
+pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color)
+{
+ int val;
+
+ if (!b->int_get(b, &val))
+ return 0;
+
+ if (b->max != 255)
+ val = (val * 255) / b->max;
+ if (val > 255)
+ val = 255;
+ *color = ARGB_JOIN(0xff, val, val, val);
+
+ return 1;
+}
+
+static int
+pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
+{
+ /* first skip all white space
+ * Note: we are skipping here actually every character than is not
+ * a digit */
+ while (!isdigit(*b->current))
+ {
+ if (*b->current == '\0')
+ {
+ if (!pmaps_buffer_raw_update(b))
+ return 0;
+
+ continue;
+ }
+ if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
+ return 0;
+ b->current++;
+ }
+
+ if (*b->current == '0')
+ *val = 0xffffffff;
+ else
+ *val = 0xff000000;
+
+ b->current++;
+
+ return 1;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "pmaps",
+ evas_image_load_file_head_pmaps,
+ evas_image_load_file_data_pmaps
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_png_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_PNG
+#if !EVAS_STATIC_BUILD_PNG
+
+pkgdir = $(libdir)/evas/cserve2/loaders/png/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_png.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_png.la
+#libevas_loader_png_la_SOURCES = evas_image_load_png.c
+#libevas_loader_png_la_LIBADD = @evas_image_loader_png_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <png.h>
+#include <setjmp.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#ifdef _WIN32_WCE
+# define E_FOPEN(file, mode) evil_fopen_native((file), (mode))
+# define E_FREAD(buffer, size, count, stream) evil_fread_native(buffer, size, count, stream)
+# define E_FCLOSE(stream) evil_fclose_native(stream)
+#else
+# define E_FOPEN(file, mode) fopen((file), (mode))
+# define E_FREAD(buffer, size, count, stream) fread(buffer, size, count, stream)
+# define E_FCLOSE(stream) fclose(stream)
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+#define PNG_BYTES_TO_CHECK 4
+
+
+static Eina_Bool
+evas_image_load_file_head_png(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ png_uint_32 w32, h32;
+ FILE *f;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ int bit_depth, color_type, interlace_type;
+ unsigned char buf[PNG_BYTES_TO_CHECK];
+ char hasa;
+
+ hasa = 0;
+ f = E_FOPEN(file, "rb");
+ if (!f)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ /* if we havent read the header before, set the header data */
+ if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1)
+ {
+ *error = CSERVE2_UNKNOWN_FORMAT;
+ goto close_file;
+ }
+
+ if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
+ {
+ *error = CSERVE2_UNKNOWN_FORMAT;
+ goto close_file;
+ }
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ *error = CSERVE2_CORRUPT_FILE;
+ goto close_file;
+ }
+ png_init_io(png_ptr, f);
+ png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
+ png_read_info(png_ptr, info_ptr);
+ png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
+ (png_uint_32 *) (&h32), &bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
+ if ((w32 < 1) || (h32 < 1) || (w32 > IMG_MAX_SIZE) || (h32 > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w32, h32))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ if (IMG_TOO_BIG(w32, h32))
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = CSERVE2_GENERIC;
+ goto close_file;
+ }
+ if (ilp->opts.scale_down_by > 1)
+ {
+ ilp->w = (int) w32 / ilp->opts.scale_down_by;
+ ilp->h = (int) h32 / ilp->opts.scale_down_by;
+ if ((ilp->w < 1) || (ilp->h < 1))
+ {
+ *error = CSERVE2_GENERIC;
+ goto close_file;
+ }
+ }
+ else
+ {
+ ilp->w = (int) w32;
+ ilp->h = (int) h32;
+ }
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
+ if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
+ if (hasa) ilp->alpha = 1;
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ E_FCLOSE(f);
+
+ *error = CSERVE2_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ E_FCLOSE(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_png(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ unsigned char *surface;
+ png_uint_32 w32, h32;
+ int w, h;
+ FILE *f;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ int bit_depth, color_type, interlace_type;
+ unsigned char buf[PNG_BYTES_TO_CHECK];
+ unsigned char **lines;
+ char hasa;
+ int i, j;
+ int scale_ratio = 1, image_w = 0;
+ unsigned char *tmp_line;
+ DATA32 *src_ptr, *dst_ptr;
+
+ hasa = 0;
+ f = E_FOPEN(file, "rb");
+ if (!f)
+ {
+ *error = CSERVE2_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ /* if we havent read the header before, set the header data */
+ if (E_FREAD(buf, PNG_BYTES_TO_CHECK, 1, f) != 1)
+ {
+ *error = CSERVE2_CORRUPT_FILE;
+ goto close_file;
+ }
+ if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
+ {
+ *error = CSERVE2_CORRUPT_FILE;
+ goto close_file;
+ }
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ {
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ *error = CSERVE2_CORRUPT_FILE;
+ goto close_file;
+ }
+ png_init_io(png_ptr, f);
+ png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
+ png_read_info(png_ptr, info_ptr);
+ png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
+ (png_uint_32 *) (&h32), &bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
+ image_w = w32;
+ if (ilp->opts.scale_down_by > 1)
+ {
+ scale_ratio = ilp->opts.scale_down_by;
+ w32 /= scale_ratio;
+ h32 /= scale_ratio;
+ }
+ surface = (unsigned char *) ilp->buffer;
+ if (!surface)
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ *error = CSERVE2_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+
+ if ((w32 != ilp->w) || (h32 != ilp->h))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ *error = CSERVE2_GENERIC;
+ goto close_file;
+ }
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
+ if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
+ if (hasa) ilp->alpha = 1;
+
+ /* Prep for transformations... ultimately we want ARGB */
+ /* expand palette -> RGB if necessary */
+ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
+ /* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
+ if ((color_type == PNG_COLOR_TYPE_GRAY) ||
+ (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ {
+ png_set_gray_to_rgb(png_ptr);
+ if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
+ }
+ /* expand transparency entry -> alpha channel if present */
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+ /* reduce 16bit color -> 8bit color if necessary */
+ if (bit_depth > 8) png_set_strip_16(png_ptr);
+ /* pack all pixels to byte boundaries */
+ png_set_packing(png_ptr);
+
+ w = ilp->w;
+ h = ilp->h;
+ /* we want ARGB */
+#ifdef WORDS_BIGENDIAN
+ png_set_swap_alpha(png_ptr);
+ if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
+#else
+ png_set_bgr(png_ptr);
+ if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+#endif
+
+ /* we read image line by line if scale down was set */
+ if (scale_ratio == 1)
+ {
+ lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
+ for (i = 0; i < h; i++)
+ lines[i] = surface + (i * w * sizeof(DATA32));
+ png_read_image(png_ptr, lines);
+ png_read_end(png_ptr, info_ptr);
+ }
+ else
+ {
+ tmp_line = (unsigned char *) alloca(image_w * sizeof(DATA32));
+ dst_ptr = (DATA32 *)surface;
+ for (i = 0; i < h; i++)
+ {
+ png_read_row(png_ptr, tmp_line, NULL);
+ src_ptr = (DATA32 *)tmp_line;
+ for (j = 0; j < w; j++)
+ {
+ *dst_ptr = *src_ptr;
+ dst_ptr++;
+ src_ptr += scale_ratio;
+ }
+ for (j = 0; j < (scale_ratio - 1); j++)
+ {
+ png_read_row(png_ptr, tmp_line, NULL);
+ }
+ }
+ }
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ E_FCLOSE(f);
+ evas_cserve2_image_premul(ilp);
+
+ *error = CSERVE2_NONE;
+ return EINA_TRUE;
+
+ close_file:
+ E_FCLOSE(f);
+ return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "png",
+ evas_image_load_file_head_png,
+ evas_image_load_file_data_png
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_PSD
+#if !EVAS_STATIC_BUILD_PSD
+
+pkgdir = $(libdir)/evas/cserve2/loaders/psd/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_psd.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_psd.la
+#libevas_loader_psd_la_SOURCES = evas_image_load_psd.c
+#libevas_loader_psd_la_LIBADD =
+
+#endif
+endif
--- /dev/null
+#define _XOPEN_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+typedef struct _PSD_Header PSD_Header;
+
+typedef enum _PSD_Mode
+ {
+ PSD_GREYSCALE = 1,
+ PSD_INDEXED = 2,
+ PSD_RGB = 3,
+ PSD_CMYK = 4
+ } PSD_Mode;
+
+struct _PSD_Header
+{
+ unsigned char signature[4];
+ unsigned short version;
+ unsigned char reserved[9];
+ unsigned short channels;
+ unsigned int height;
+ unsigned int width;
+ unsigned short depth;
+
+ unsigned short channel_num;
+
+ PSD_Mode mode;
+};
+
+enum {
+ READ_COMPRESSED_SUCCESS,
+ READ_COMPRESSED_ERROR_FILE_CORRUPT,
+ READ_COMPRESSED_ERROR_FILE_READ_ERROR
+};
+
+static Eina_Bool get_compressed_channels_length(PSD_Header *Head,
+ const unsigned char *map, size_t length, size_t *position,
+ unsigned short *rle_table,
+ unsigned int *chanlen);
+
+static int
+read_ushort(const unsigned char *map, size_t length, size_t *position, unsigned short *ret)
+{
+ if (*position + 2 > length) return 0;
+ // FIXME: need to check order
+ *ret = (map[(*position) + 0] << 8) | map[(*position) + 1];
+ *position += 2;
+ return 1;
+}
+
+static int
+read_uint(const unsigned char *map, size_t length, size_t *position, unsigned int *ret)
+{
+ if (*position + 4 > length) return 0;
+ // FIXME: need to check order
+ *ret = ARGB_JOIN(map[(*position) + 0], map[(*position) + 1], map[(*position) + 2], map[(*position) + 3]);
+ *position += 4;
+ return 1;
+}
+
+static int
+read_block(const unsigned char *map, size_t length, size_t *position, void *target, size_t size)
+{
+ if (*position + size > length) return 0;
+ memcpy(target, map + *position, size);
+ *position += size;
+ return 1;
+}
+
+// Internal function used to get the Psd header from the current file.
+Eina_Bool
+psd_get_header(PSD_Header *header, const unsigned char *map, size_t length, size_t *position)
+{
+ unsigned short tmp;
+
+#define CHECK_RET(Call) \
+ if (!Call) return EINA_FALSE;
+
+ CHECK_RET(read_block(map, length, position, header->signature, 4));
+ CHECK_RET(read_ushort(map, length, position, &header->version));
+ CHECK_RET(read_block(map, length, position, header->reserved, 6));
+ CHECK_RET(read_ushort(map, length, position, &header->channels));
+ CHECK_RET(read_uint(map, length, position, &header->height));
+ CHECK_RET(read_uint(map, length, position, &header->width));
+ CHECK_RET(read_ushort(map, length, position, &header->depth));
+
+ CHECK_RET(read_ushort(map, length, position, &tmp));
+ header->mode = tmp;
+
+#undef CHECK_RET
+
+ /* fprintf(stderr, "<<<<<<<<<<<\nsignature : %c%c%c%c\n", */
+ /* header->signature[0], */
+ /* header->signature[1], */
+ /* header->signature[2], */
+ /* header->signature[3]); */
+ /* fprintf(stderr, "version : %i\n", header->version); */
+ /* fprintf(stderr, "channels : %i\n", header->channels); */
+ /* fprintf(stderr, "width x height : %dx%d\n", header->width, header->height); */
+ /* fprintf(stderr, "depth : %i\n", header->depth); */
+ /* fprintf(stderr, "mode : %i\n>>>>>>>>>>>>\n", header->mode); */
+
+ return EINA_TRUE;
+}
+
+
+// Internal function used to check if the HEADER is a valid Psd header.
+Eina_Bool
+is_psd(PSD_Header *header)
+{
+ if (strncmp((char*)header->signature, "8BPS", 4))
+ return EINA_FALSE;
+ if (header->version != 1)
+ return EINA_FALSE;
+ if (header->channels < 1 || header->channels > 24)
+ return EINA_FALSE;
+ if (header->height < 1 || header->width < 1)
+ return EINA_FALSE;
+ if (header->depth != 1 && header->depth != 8 && header->depth != 16)
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_head_psd(Evas_Img_Load_Params *ilp, const char *FileName,
+ const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ void *map;
+ size_t length;
+ size_t position;
+ PSD_Header header;
+ Eina_Bool correct;
+
+ *error = EVAS_LOAD_ERROR_NONE;
+
+ f = eina_file_open(FileName, 0);
+ if (f == NULL)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ length = eina_file_size_get(f);
+ position = 0;
+ if (!map || length < 1)
+ {
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ correct = psd_get_header(&header, map, length, &position);
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+
+ if (!correct || !is_psd(&header))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ ilp->w = header.width;
+ ilp->h = header.height;
+ if (header.channels == 3) ilp->alpha = 0;
+ else ilp->alpha = 1;
+
+ return EINA_TRUE;
+}
+
+static unsigned int
+read_compressed_channel(const unsigned char *map, size_t length, size_t *position,
+ const unsigned int channel_length __UNUSED__,
+ unsigned int size,
+ unsigned char* channel)
+{
+ // FIXME: what does channel_length means, and why is it not used
+ unsigned int i;
+ char headbyte, c;
+
+#define CHECK_RET(Call) \
+ if (!Call) return READ_COMPRESSED_ERROR_FILE_READ_ERROR; \
+
+ for (i = 0; i < size; )
+ {
+ CHECK_RET(read_block(map, length, position, &headbyte, 1));
+
+ if (headbyte >= 0)
+ {
+ if (i + headbyte > size)
+ return READ_COMPRESSED_ERROR_FILE_CORRUPT;
+ CHECK_RET(read_block(map, length, position, channel + i, headbyte + 1));
+
+ i += headbyte + 1;
+ }
+ else if (headbyte >= -127 && headbyte <= -1)
+ {
+ int run;
+
+ CHECK_RET(read_block(map, length, position, &c, 1));
+
+ run = c;
+ /* if (run == -1) */
+ /* return READ_COMPRESSED_ERROR_FILE_READ_ERROR; */
+
+ if (i + (-headbyte + 1) > size)
+ return READ_COMPRESSED_ERROR_FILE_CORRUPT;
+
+ memset(channel + i, run, -headbyte + 1);
+ i += -headbyte + 1;
+ }
+ }
+
+#undef CHECK_RET
+
+ return READ_COMPRESSED_SUCCESS;
+}
+
+
+static Eina_Bool
+psd_get_data(PSD_Header *head,
+ const unsigned char *map, size_t length, size_t *position,
+ unsigned char *buffer, Eina_Bool compressed,
+ int *error)
+{
+ unsigned int c, x, y, numchan, bps, bpc, bpp;
+ unsigned int pixels_count;
+ unsigned char *channel = NULL;
+ unsigned char *data = NULL;
+
+ // Added 01-07-2009: This is needed to correctly load greyscale and
+ // paletted images.
+ switch (head->mode)
+ {
+ case PSD_GREYSCALE:
+ case PSD_INDEXED:
+ numchan = 1;
+ break;
+ default:
+ numchan = 3;
+ }
+
+ bpp = head->channels;
+ bpc = head->depth / 8;
+ pixels_count = head->width * head->height;
+
+ data = malloc(sizeof (unsigned char) * pixels_count * bpp);
+ if (!data) return EINA_FALSE;
+
+ channel = malloc(sizeof (unsigned char) * pixels_count * bpc);
+ if (!channel)
+ {
+ free(data);
+ return EINA_FALSE;
+ }
+
+ bps = head->width * head->channels * bpc;
+ // @TODO: Add support for this in, though I have yet to run across a .psd
+ // file that uses this.
+ if (compressed && bpc == 2)
+ {
+ free(data);
+ free(channel);
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+#define CHECK_RET(Call) \
+ if (!Call) \
+ { \
+ free(data); \
+ free(channel); \
+ return EINA_FALSE; \
+ }
+
+ if (!compressed)
+ {
+ if (bpc == 1)
+ {
+ for (c = 0; c < numchan; c++)
+ {
+ unsigned char *tmp = channel;
+
+ CHECK_RET(read_block(map, length, position, tmp, pixels_count));
+
+ for (y = 0; y < head->height * bps; y += bps)
+ {
+ for (x = 0; x < bps; x += bpp, tmp++)
+ {
+ data[y + x + c] = *tmp;
+ }
+ }
+ }
+
+ // Accumulate any remaining channels into a single alpha channel
+ //@TODO: This needs to be changed for greyscale images.
+ for (; c < head->channels; c++)
+ {
+ unsigned char *tmp = channel;
+
+ CHECK_RET(read_block(map, length, position, channel, pixels_count));
+
+ for (y = 0; y < head->height * bps; y += bps)
+ {
+ for (x = 0; x < bps; x += bpp, tmp++)
+ {
+ unsigned short newval;
+
+ // previous formula was : (old / 255 * new / 255) * 255
+ newval = (*tmp) * data[y + x + 3];
+
+ data[y + x + 3] = newval >> 8;
+ }
+ }
+ }
+ }
+ else
+ {
+ int bps2;
+
+ bps2 = bps / 2;
+
+ // iCurImage->Bpc == 2
+ for (c = 0; c < numchan; c++)
+ {
+ unsigned short *shortptr = (unsigned short*) channel;
+
+ CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
+
+ for (y = 0; y < head->height * bps2; y += bps2)
+ {
+ for (x = 0; x < (unsigned int)bps2; x += bpp, shortptr++)
+ {
+ ((unsigned short*)data)[y + x + c] = *shortptr;
+ }
+ }
+ }
+
+ // Accumulate any remaining channels into a single alpha channel
+ //@TODO: This needs to be changed for greyscale images.
+ for (; c < head->channels; c++)
+ {
+ unsigned short *shortptr = (unsigned short*) channel;
+
+ CHECK_RET(read_block(map, length, position, channel, pixels_count * 2));
+
+ for (y = 0; y < head->height * bps2; y += bps2)
+ {
+ for (x = 0; x < (unsigned int)bps2; x += bpp, shortptr)
+ {
+ unsigned int newval;
+
+ newval = *shortptr * ((unsigned short*)data)[y + x + 3];
+
+ ((unsigned short*)data)[y + x + 3] = newval >> 16;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short *rle_table;
+ unsigned int *chanlen;
+
+ rle_table = alloca(head->height * head->channel_num * sizeof (unsigned short));
+ chanlen = alloca(head->channel_num * sizeof (unsigned int));
+ if (!get_compressed_channels_length(head, map, length, position, rle_table, chanlen))
+ goto file_read_error;
+
+ for (c = 0; c < numchan; c++)
+ {
+ unsigned char *tmp = channel;
+ int err;
+
+ err = read_compressed_channel(map, length, position,
+ chanlen[c],
+ pixels_count,
+ channel);
+ if (err == READ_COMPRESSED_ERROR_FILE_CORRUPT)
+ goto file_corrupt;
+ else if (err == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
+ goto file_read_error;
+
+ for (y = 0; y < head->height * bps; y += bps)
+ {
+ for (x = 0; x < bps; x += bpp, tmp++)
+ {
+ data[y + x + c] = *tmp;
+ }
+ }
+ }
+
+ // Initialize the alpha channel to solid
+ //@TODO: This needs to be changed for greyscale images.
+ if (head->channels >= 4)
+ {
+ for (y = 0; y < head->height * bps; y += bps)
+ {
+ for (x = 0; x < bps; x += bpp)
+ {
+ data[y + x + 3] = 255;
+ }
+ }
+
+ for (; c < head->channels; c++)
+ {
+ unsigned char *tmp = channel;
+ int err;
+
+ err = read_compressed_channel(map, length, position,
+ chanlen[c],
+ pixels_count,
+ channel);
+ if (err == READ_COMPRESSED_ERROR_FILE_CORRUPT)
+ goto file_corrupt;
+ else if (err == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
+ goto file_read_error;
+
+ for (y = 0; y < head->height * bps; y += bps)
+ {
+ for (x = 0; x < bps; x += bpp, tmp++)
+ {
+ unsigned short newval;
+
+ newval = *tmp * data[y + x + 3];
+
+ data[y + x + 3] = newval >> 8;
+ }
+ }
+ }
+ }
+ }
+
+ if (bpp == 3)
+ {
+ for (x = 0; x < pixels_count; x++)
+ {
+ buffer[x * 4 + 0] = data[x * 3 + 2];
+ buffer[x * 4 + 1] = data[x * 3 + 1];
+ buffer[x * 4 + 2] = data[x * 3 + 0];
+ buffer[x * 4 + 3] = 255;
+ }
+ }
+ else
+ {
+ // BRGA to RGBA
+ for (x= 0; x < pixels_count; x++)
+ {
+ buffer[x * 4 + 0] = data[x * 4 + 2];
+ buffer[x * 4 + 1] = data[x * 4 + 1];
+ buffer[x * 4 + 2] = data[x * 4 + 0];
+ buffer[x * 4 + 3] = data[x * 4 + 3];
+ }
+ }
+
+ free(channel);
+ free(data);
+ return EINA_TRUE;
+
+#undef CHECK_RET
+
+ file_corrupt:
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+ file_read_error:
+ free(channel);
+ free(data);
+
+ return EINA_FALSE;
+}
+
+
+static Eina_Bool
+get_single_channel(PSD_Header *head,
+ const unsigned char *map, size_t length, size_t *position,
+ unsigned char *buffer,
+ Eina_Bool compressed)
+{
+ unsigned int i, bpc;
+ char headbyte;
+ int c;
+ int pixels_count;
+
+ bpc = (head->depth / 8);
+ pixels_count = head->width * head->height;
+
+#define CHECK_RET(Call) \
+ if (!Call) return EINA_FALSE;
+
+ if (!compressed)
+ {
+ if (bpc == 1)
+ {
+ CHECK_RET(read_block(map, length, position, buffer, pixels_count));
+ }
+ else
+ { // Bpc == 2
+ CHECK_RET(read_block(map, length, position, buffer, pixels_count * 2));
+ }
+ }
+ else
+ {
+ for (i = 0; i < (unsigned int)pixels_count; )
+ {
+ CHECK_RET(read_block(map, length, position, &headbyte, 1));
+
+ if (headbyte >= 0)
+ { // && HeadByte <= 127
+ CHECK_RET(read_block(map, length, position, buffer + i, headbyte + 1));
+
+ i += headbyte + 1;
+ }
+ if (headbyte >= -127 && headbyte <= -1)
+ {
+ int run;
+
+ CHECK_RET(read_block(map, length, position, &c, 1));
+
+ run = c;
+ if (run == -1) return EINA_FALSE;
+
+ memset(buffer + i, run, -headbyte + 1);
+ i += -headbyte + 1;
+ }
+ }
+ }
+
+#undef CHECK_RET
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+read_psd_grey(Evas_Img_Load_Params *ilp, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
+{
+ unsigned int color_mode, resource_size, misc_info;
+ unsigned short compressed;
+ void *surface = NULL;
+
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+#define CHECK_RET(Call) \
+ if (!Call) return EINA_FALSE;
+
+ CHECK_RET(read_uint(map, length, position, &color_mode));
+ // Skip over the 'color mode data section'
+ *position += color_mode;
+
+ CHECK_RET(read_uint(map, length, position, &resource_size));
+ // Read the 'image resources section'
+ *position += resource_size;
+
+ CHECK_RET(read_uint(map, length, position, &misc_info));
+ *position += misc_info;
+
+ CHECK_RET(read_ushort(map, length, position, &compressed));
+
+ ilp->w = head->width;
+ ilp->h = head->height;
+ if (head->channels == 3) ilp->alpha = 0;
+ else ilp->alpha = 1;
+
+ head->channel_num = head->channels;
+ // Temporary to read only one channel...some greyscale .psd files have 2.
+ head->channels = 1;
+
+ switch (head->depth)
+ {
+ case 8:
+ case 16:
+ break;
+ default:
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto cleanup_error;
+ }
+
+ if (!psd_get_data(head, map, length, position, surface, compressed, error))
+ goto cleanup_error;
+
+ return EINA_TRUE;
+
+#undef CHECK_RET
+
+ cleanup_error:
+ return EINA_FALSE;
+}
+
+
+Eina_Bool
+read_psd_indexed(Evas_Img_Load_Params *ilp, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
+{
+ unsigned int color_mode, resource_size, misc_info;
+ unsigned short compressed;
+ void *surface;
+
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+#define CHECK_RET(Call) \
+ if (!(Call)) return EINA_FALSE;
+
+ CHECK_RET(read_uint(map, length, position, &color_mode));
+ CHECK_RET(!(color_mode % 3));
+ /*
+ Palette = (unsigned char*)malloc(Colormode);
+ if (Palette == NULL)
+ return EINA_FALSE;
+ if (fread(&Palette, 1, Colormode, file) != Colormode)
+ goto cleanup_error;
+ */
+ // Skip over the 'color mode data section'
+ *position += color_mode;
+
+ // Read the 'image resources section'
+ CHECK_RET(read_uint(map, length, position, &resource_size));
+ *position += resource_size;
+
+ CHECK_RET(read_uint(map, length, position, &misc_info));
+ *position += misc_info;
+
+ CHECK_RET(read_ushort(map, length, position, &compressed));
+
+ if (head->channels != 1 || head->depth != 8)
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+ head->channel_num = head->channels;
+
+ ilp->w = head->width;
+ ilp->h = head->height;
+ if (head->channels == 3) ilp->alpha = 0;
+ else ilp->alpha = 1;
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ if (!psd_get_data(head, map, length, position, surface, compressed, error))
+ return EINA_FALSE;
+ return EINA_TRUE;
+
+#undef CHECK_RET
+}
+
+Eina_Bool
+read_psd_rgb(Evas_Img_Load_Params *ilp, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
+{
+ unsigned int color_mode, resource_size, misc_info;
+ unsigned short compressed;
+ void *surface;
+
+#define CHECK_RET(Call) \
+ if (!Call) return EINA_FALSE;
+
+ CHECK_RET(read_uint(map, length, position, &color_mode));
+ // Skip over the 'color mode data section'
+ *position += color_mode;
+
+ // Read the 'image resources section'
+ CHECK_RET(read_uint(map, length, position, &resource_size));
+ *position += resource_size;
+
+ CHECK_RET(read_uint(map, length, position, &misc_info));
+ *position += misc_info;
+
+ CHECK_RET(read_ushort(map, length, position, &compressed));
+
+ head->channel_num = head->channels;
+
+ switch (head->depth)
+ {
+ case 8:
+ case 16:
+ break;
+ default:
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+ ilp->w = head->width;
+ ilp->h = head->height;
+ if (head->channels == 3) ilp->alpha = 0;
+ else ilp->alpha = 1;
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto cleanup_error;
+ }
+
+ if (!psd_get_data(head, map, length, position, surface, compressed, error))
+ goto cleanup_error;
+
+ evas_cserve2_image_premul(ilp);
+ return EINA_TRUE;
+
+#undef CHECK_RET
+
+ cleanup_error:
+ return EINA_FALSE;
+}
+
+Eina_Bool
+read_psd_cmyk(Evas_Img_Load_Params *ilp, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
+{
+ unsigned int color_mode, resource_size, misc_info, size, j, data_size;
+ unsigned short compressed;
+ unsigned int format, type;
+ unsigned char *kchannel = NULL;
+ void *surface;
+
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+
+#define CHECK_RET(Call) \
+ if (!Call) return EINA_FALSE;
+
+ CHECK_RET(read_uint(map, length, position, &color_mode));
+ // Skip over the 'color mode data section'
+ *position += color_mode;
+
+ CHECK_RET(read_uint(map, length, position, &resource_size));
+ // Read the 'image resources section'
+ *position += resource_size;
+
+ CHECK_RET(read_uint(map, length, position, &misc_info));
+ *position += misc_info;
+
+ CHECK_RET(read_ushort(map, length, position, &compressed));
+
+ switch (head->channels)
+ {
+ case 4:
+ format = 0x1907;
+ head->channel_num = 4;
+ head->channels = 3;
+ break;
+ case 5:
+ format = 0x1908;
+ head->channel_num = 5;
+ head->channels = 4;
+ break;
+ default:
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ switch (head->depth)
+ {
+ case 8:
+ type = 1;
+ break;
+ case 16:
+ type = 2;
+ break;
+ default:
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ ilp->w = head->width;
+ ilp->h = head->height;
+ if (head->channels == 3) ilp->alpha = 0;
+ else ilp->alpha = 1;
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto cleanup_error;
+ }
+
+ if (!psd_get_data(head, map, length, position, surface, compressed, error))
+ goto cleanup_error;
+
+ size = type * ilp->w * ilp->h;
+ kchannel = malloc(size);
+ if (kchannel == NULL)
+ goto cleanup_error;
+ if (!get_single_channel(head, map, length, position, kchannel, compressed))
+ goto cleanup_error;
+
+ data_size = head->channels * type * ilp->w * ilp->h;
+ if (format == 0x1907)
+ {
+ unsigned char *tmp = surface;
+ const unsigned char *limit = tmp + data_size;
+
+ for (j = 0; tmp < limit; tmp++, j++)
+ {
+ int k;
+
+ for (k = 0; k < 3; k++)
+ *tmp = (*tmp * kchannel[j]) >> 8;
+
+ // FIXME: tmp[i+3] = 255;
+ }
+ }
+ else
+ { // RGBA
+ unsigned char *tmp = surface;
+ const unsigned char *limit = tmp + data_size;
+
+ // The KChannel array really holds the alpha channel on this one.
+ for (j = 0; tmp < limit; tmp += 4, j++)
+ {
+ tmp[0] = (tmp[0] * tmp[3]) >> 8;
+ tmp[1] = (tmp[1] * tmp[3]) >> 8;
+ tmp[2] = (tmp[2] * tmp[3]) >> 8;
+ tmp[3] = kchannel[j]; // Swap 'K' with alpha channel.
+ }
+ }
+
+ free(kchannel);
+
+ evas_cserve2_image_premul(ilp);
+ return EINA_TRUE;
+
+ cleanup_error:
+ free(kchannel);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_psd(Evas_Img_Load_Params *ilp,
+ const char *file,
+ const char *key __UNUSED__,
+ int *error)
+{
+ Eina_File *f;
+ void *map;
+ size_t length;
+ size_t position;
+ PSD_Header header;
+ Eina_Bool bpsd = EINA_FALSE;
+
+ f = eina_file_open(file, 0);
+ if (f == NULL)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return bpsd;
+ }
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ length = eina_file_size_get(f);
+ position = 0;
+ if (!map || length < 1)
+ {
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ if (!psd_get_header(&header, map, length, &position) || !is_psd(&header))
+ {
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
+ }
+
+ ilp->w = header.width;
+ ilp->h = header.height;
+
+ *error = EVAS_LOAD_ERROR_NONE;
+
+ switch (header.mode)
+ {
+ case PSD_GREYSCALE: // Greyscale
+ bpsd = read_psd_grey(ilp, &header, map, length, &position, error);
+ break;
+ case PSD_INDEXED: // Indexed
+ bpsd = read_psd_indexed(ilp, &header, map, length, &position, error);
+ break;
+ case PSD_RGB: // RGB
+ bpsd = read_psd_rgb(ilp, &header, map, length, &position, error);
+ break;
+ case PSD_CMYK: // CMYK
+ bpsd = read_psd_cmyk(ilp, &header, map, length, &position, error);
+ break;
+ default :
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ bpsd = EINA_FALSE;
+ }
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+
+ return bpsd;
+}
+
+static Eina_Bool
+get_compressed_channels_length(PSD_Header *head,
+ const unsigned char *map, size_t length, size_t *position,
+ unsigned short *rle_table,
+ unsigned int *chanlen)
+{
+ unsigned int j;
+ unsigned int c;
+
+ if (!read_block(map, length, position, rle_table,
+ sizeof (unsigned short) * head->height * head->channel_num))
+ return EINA_FALSE;
+
+ memset(chanlen, 0, head->channel_num * sizeof(unsigned int));
+ for (c = 0; c < head->channel_num; c++)
+ {
+ unsigned int i;
+
+ j = c * head->height;
+ for (i = 0; i < head->height; i++)
+ {
+ chanlen[c] += rle_table[i + j];
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "psd",
+ evas_image_load_file_head_psd,
+ evas_image_load_file_data_psd
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_TGA
+#if !EVAS_STATIC_BUILD_TGA
+
+pkgdir = $(libdir)/evas/cserve2/loaders/tga/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_tga.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_tga.la
+#libevas_loader_tga_la_SOURCES = evas_image_load_tga.c
+#libevas_loader_tga_la_LIBADD =
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+/* TGA pixel formats */
+#define TGA_TYPE_MAPPED 1 // handle
+#define TGA_TYPE_COLOR 2
+#define TGA_TYPE_GRAY 3
+#define TGA_TYPE_MAPPED_RLE 9 // handle
+#define TGA_TYPE_COLOR_RLE 10
+#define TGA_TYPE_GRAY_RLE 11
+
+/* TGA header flags */
+#define TGA_DESC_ABITS 0x0f
+#define TGA_DESC_HORIZONTAL 0x10
+#define TGA_DESC_VERTICAL 0x20
+
+#define TGA_SIGNATURE "TRUEVISION-XFILE"
+
+typedef struct _tga_header tga_header;
+typedef struct _tga_footer tga_footer;
+
+struct _tga_header
+{
+ unsigned char idLength;
+ unsigned char colorMapType;
+ unsigned char imageType;
+ unsigned char colorMapIndexLo, colorMapIndexHi;
+ unsigned char colorMapLengthLo, colorMapLengthHi;
+ unsigned char colorMapSize;
+ unsigned char xOriginLo, xOriginHi;
+ unsigned char yOriginLo, yOriginHi;
+ unsigned char widthLo, widthHi;
+ unsigned char heightLo, heightHi;
+ unsigned char bpp;
+ unsigned char descriptor;
+} __attribute__((packed));
+
+struct _tga_footer
+{
+ unsigned int extensionAreaOffset;
+ unsigned int developerDirectoryOffset;
+ char signature[16];
+ char dot;
+ char null;
+} __attribute__((packed));
+
+
+static Eina_Bool
+evas_image_load_file_head_tga(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ unsigned char *seg = NULL, *filedata;
+ tga_header *header;
+ tga_footer *footer, tfooter;
+ char hasa = 0;
+ int w = 0, h = 0, bpp;
+ int x, y;
+
+ f = eina_file_open(file, EINA_FALSE);
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ if (f == NULL) return EINA_FALSE;
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
+ goto close_file;
+ seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (seg == NULL) goto close_file;
+ filedata = seg;
+
+ header = (tga_header *)filedata;
+ // no unaligned data accessed, so ok
+ footer = (tga_footer *)(filedata + (eina_file_size_get(f) - sizeof(tga_footer)));
+ memcpy((unsigned char *)(&tfooter),
+ (unsigned char *)footer,
+ sizeof(tga_footer));
+ //printf("0\n");
+ if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature)))
+ {
+ if ((tfooter.dot == '.') && (tfooter.null == 0))
+ {
+ // footer is there and matches. this is a tga file - any problems now
+ // are a corrupt file
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ }
+ }
+// else goto close_file;
+ //printf("1\n");
+
+ filedata = (unsigned char *)filedata + sizeof(tga_header);
+ switch (header->imageType)
+ {
+ case TGA_TYPE_COLOR_RLE:
+ case TGA_TYPE_GRAY_RLE:
+// rle = 1;
+ break;
+ case TGA_TYPE_COLOR:
+ case TGA_TYPE_GRAY:
+// rle = 0;
+ break;
+ default:
+ goto close_file;
+ }
+ bpp = header->bpp;
+ if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8)))
+ goto close_file;
+ if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1;
+ // don't handle colormapped images
+ if ((header->colorMapType) != 0)
+ goto close_file;
+ // if colormap size is anything other than legal sizes or 0 - not real tga
+ if (!((header->colorMapSize == 0) ||
+ (header->colorMapSize == 15) ||
+ (header->colorMapSize == 16) ||
+ (header->colorMapSize == 24) ||
+ (header->colorMapSize == 32)))
+ goto close_file;
+ x = (header->xOriginHi << 8) | (header->xOriginLo);
+ y = (header->yOriginHi << 8) | (header->yOriginLo);
+ w = (header->widthHi << 8) | header->widthLo;
+ h = (header->heightHi << 8) | header->heightLo;
+ // x origin gerater that width, y origin greater than height - wrong file
+ if ((x >= w) || (y >= h))
+ goto close_file;
+ // if descriptor has either of the top 2 bits set... not tga
+ if (header->descriptor & 0xc0)
+ goto close_file;
+
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ goto close_file;
+
+ ilp->w = w;
+ ilp->h = h;
+ if (hasa) ilp->alpha = 1;
+
+ eina_file_map_free(f, seg);
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+close_file:
+ if (seg != NULL) eina_file_map_free(f, seg);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_tga(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ unsigned char *seg = NULL, *filedata;
+ tga_header *header;
+ tga_footer *footer, tfooter;
+ char hasa = 0, footer_present = 0, vinverted = 0, rle = 0;
+ int w = 0, h = 0, x, y, bpp;
+ off_t size;
+ unsigned int *surface, *dataptr;
+ unsigned int datasize;
+ unsigned char *bufptr, *bufend;
+ int abits;
+
+ f = eina_file_open(file, EINA_FALSE);
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ if (f == NULL) return EINA_FALSE;
+
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer)))
+ goto close_file;
+ seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (seg == NULL) goto close_file;
+ filedata = seg;
+ size = eina_file_size_get(f);
+
+ header = (tga_header *)filedata;
+ // no unaligned data accessed, so ok
+ footer = (tga_footer *)(filedata + (size - sizeof(tga_footer)));
+ memcpy((unsigned char *)&tfooter,
+ (unsigned char *)footer,
+ sizeof(tga_footer));
+ if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature)))
+ {
+ if ((tfooter.dot == '.') && (tfooter.null == 0))
+ {
+ // footer is there and matches. this is a tga file - any problems now
+ // are a corrupt file
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ footer_present = 1;
+ }
+ }
+
+ filedata = (unsigned char *)filedata + sizeof(tga_header);
+ vinverted = !(header->descriptor & TGA_DESC_VERTICAL);
+ switch (header->imageType)
+ {
+ case TGA_TYPE_COLOR_RLE:
+ case TGA_TYPE_GRAY_RLE:
+ rle = 1;
+ break;
+ case TGA_TYPE_COLOR:
+ case TGA_TYPE_GRAY:
+ rle = 0;
+ break;
+ default:
+ goto close_file;
+ }
+ bpp = header->bpp;
+ if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8)))
+ goto close_file;
+ if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1;
+ abits = header->descriptor & TGA_DESC_ABITS;
+ // don't handle colormapped images
+ if ((header->colorMapType) != 0)
+ goto close_file;
+ // if colormap size is anything other than legal sizes or 0 - not real tga
+ if (!((header->colorMapSize == 0) ||
+ (header->colorMapSize == 15) ||
+ (header->colorMapSize == 16) ||
+ (header->colorMapSize == 24) ||
+ (header->colorMapSize == 32)))
+ goto close_file;
+ x = (header->xOriginHi << 8) | (header->xOriginLo);
+ y = (header->yOriginHi << 8) | (header->yOriginLo);
+ w = (header->widthHi << 8) | header->widthLo;
+ h = (header->heightHi << 8) | header->heightLo;
+ // x origin gerater that width, y origin greater than height - wrong file
+ if ((x >= w) || (y >= h))
+ goto close_file;
+ // if descriptor has either of the top 2 bits set... not tga
+ if (header->descriptor & 0xc0)
+ goto close_file;
+
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ goto close_file;
+
+ if ((w != (int)ilp->w) || (h != (int)ilp->h))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto close_file;
+ }
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto close_file;
+ }
+
+ datasize = size - sizeof(tga_header) - header->idLength;
+ if (footer_present)
+ datasize = size - sizeof(tga_header) - header->idLength -
+ sizeof(tga_footer);
+
+ bufptr = filedata + header->idLength;
+ bufend = filedata + datasize;
+
+ if (!rle)
+ {
+ for (y = 0; y < h; y++)
+ {
+ if (vinverted)
+ /* some TGA's are stored upside-down! */
+ dataptr = surface + ((h - y - 1) * w);
+ else
+ dataptr = surface + (y * w);
+ switch (bpp)
+ {
+ case 32:
+ for (x = 0; (x < w) && ((bufptr + 4) <= bufend); x++)
+ {
+ if (hasa)
+ {
+ int a = bufptr[3];
+
+ switch (abits)
+ {
+ case 1:
+ a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a);
+ case 2:
+ a = (a << 6) | (a << 4) | (a << 2) | (a);
+ case 3:
+ a = (a << 5) | (a << 2) | (a >> 1);
+ case 4:
+ a = (a << 4) | (a);
+ case 5:
+ a = (a << 3) | (a >> 2);
+ case 6:
+ a = (a << 2) | (a >> 4);
+ case 7:
+ a = (a << 1) | (a >> 6);
+ default:
+ break;
+ }
+ *dataptr = ARGB_JOIN(a, bufptr[2], bufptr[1], bufptr[0]);
+ }
+ else
+ *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
+ dataptr++;
+ bufptr += 4;
+ }
+ break;
+ case 24:
+ for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++)
+ {
+ *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
+ dataptr++;
+ bufptr += 3;
+ }
+ break;
+ case 16:
+ for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++)
+ {
+ unsigned char r, g, b, a;
+ unsigned short tmp;
+
+ tmp =
+ (((unsigned short)bufptr[1]) << 8) |
+ (((unsigned short)bufptr[0]));
+ r = (tmp >> 7) & 0xf8; r |= r >> 5;
+ g = (tmp >> 2) & 0xf8; g |= g >> 5;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ a = 0xff;
+ if ((hasa) && (tmp & 0x8000)) a = 0;
+ *dataptr = ARGB_JOIN(a, r, g, b);
+ dataptr++;
+ bufptr += 2;
+ }
+ break;
+ case 8:
+ for (x = 0; (x < w) && ((bufptr + 1) <= bufend); x++)
+ {
+ *dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]);
+ dataptr++;
+ bufptr += 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ int count, i;
+ unsigned char val;
+ unsigned int *dataend;
+
+ dataptr = surface;
+ dataend = dataptr + (w * h);
+ while ((bufptr < bufend) && (dataptr < dataend))
+ {
+ val = *bufptr;
+ bufptr++;
+ count = (val & 0x7f) + 1;
+ if (val & 0x80) // rel packet
+ {
+ switch (bpp)
+ {
+ case 32:
+ if (bufptr < (bufend - 4))
+ {
+ unsigned char r, g, b;
+ int a = bufptr[3];
+
+ switch (abits)
+ {
+ case 1:
+ a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a);
+ case 2:
+ a = (a << 6) | (a << 4) | (a << 2) | (a);
+ case 3:
+ a = (a << 5) | (a << 2) | (a >> 1);
+ case 4:
+ a = (a << 4) | (a);
+ case 5:
+ a = (a << 3) | (a >> 2);
+ case 6:
+ a = (a << 2) | (a >> 4);
+ case 7:
+ a = (a << 1) | (a >> 6);
+ default:
+ break;
+ }
+ r = bufptr[2];
+ g = bufptr[1];
+ b = bufptr[0];
+ if (!hasa) a = 0xff;
+ bufptr += 4;
+ for (i = 0; (i < count) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(a, r, g, b);
+ dataptr++;
+ }
+ }
+ break;
+ case 24:
+ if (bufptr < (bufend - 3))
+ {
+ unsigned char r, g, b;
+
+ r = bufptr[2];
+ g = bufptr[1];
+ b = bufptr[0];
+ bufptr += 3;
+ for (i = 0; (i < count) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(0xff, r, g, b);
+ dataptr++;
+ }
+ }
+ break;
+ case 16:
+ if (bufptr < (bufend - 2))
+ {
+ unsigned char r, g, b, a;
+ unsigned short tmp;
+
+ tmp =
+ (((unsigned short)bufptr[1]) << 8) |
+ (((unsigned short)bufptr[0]));
+ r = (tmp >> 7) & 0xf8; r |= r >> 5;
+ g = (tmp >> 2) & 0xf8; g |= g >> 5;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ a = 0xff;
+ if ((hasa) && (tmp & 0x8000)) a = 0;
+ bufptr += 2;
+ for (i = 0; (i < count) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(a, r, g, b);
+ dataptr++;
+ }
+ }
+ break;
+ case 8:
+ if (bufptr < (bufend - 1))
+ {
+ unsigned char g;
+
+ g = bufptr[0];
+ bufptr += 1;
+ for (i = 0; (i < count) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(0xff, g, g, g);
+ dataptr++;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else // raw
+ {
+ switch (bpp)
+ {
+ case 32:
+ for (i = 0; (i < count) && (bufptr < (bufend - 4)) && (dataptr < dataend); i++)
+ {
+ if (hasa)
+// *dataptr = ARGB_JOIN(255 - bufptr[3], bufptr[2], bufptr[1], bufptr[0]);
+ *dataptr = ARGB_JOIN(bufptr[3], bufptr[2], bufptr[1], bufptr[0]);
+ else
+ *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
+ dataptr++;
+ bufptr += 4;
+ }
+ break;
+ case 24:
+ for (i = 0; (i < count) && (bufptr < (bufend - 3)) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]);
+ dataptr++;
+ bufptr += 3;
+ }
+ break;
+ case 16:
+ for (i = 0; (i < count) && (bufptr < (bufend - 2)) && (dataptr < dataend); i++)
+ {
+ unsigned char r, g, b, a;
+ unsigned short tmp;
+
+ tmp =
+ (((unsigned short)bufptr[1]) << 8) |
+ (((unsigned short)bufptr[0]));
+ r = (tmp >> 7) & 0xf8; r |= r >> 5;
+ g = (tmp >> 2) & 0xf8; g |= g >> 5;
+ b = (tmp << 3) & 0xf8; b |= b >> 5;
+ a = 0xff;
+ if ((hasa) && (tmp & 0x8000)) a = 0;
+ *dataptr = ARGB_JOIN(a, r, g, b);
+ dataptr++;
+ bufptr += 2;
+ }
+ break;
+ case 8:
+ for (i = 0; (i < count) && (bufptr < (bufend - 1)) && (dataptr < dataend); i++)
+ {
+ *dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]);
+ dataptr++;
+ bufptr += 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (vinverted)
+ {
+ unsigned int *adv, *adv2, tmp;
+
+ adv = surface;
+ adv2 = surface + (w * (h - 1));
+ for (y = 0; y < (h / 2); y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ tmp = adv[x];
+ adv[x] = adv2[x];
+ adv2[x] = tmp;
+ }
+ adv2 -= w;
+ adv += w;
+ }
+ }
+ }
+
+ evas_cserve2_image_premul(ilp);
+
+ eina_file_map_free(f, seg);
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+close_file:
+ if (seg != NULL) eina_file_map_free(f, seg);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "tga",
+ evas_image_load_file_head_tga,
+ evas_image_load_file_data_tga
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_tiff_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_TIFF
+#if !EVAS_STATIC_BUILD_TIFF
+
+pkgdir = $(libdir)/evas/cserve2/loaders/tiff/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_tiff.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_tiff_libs@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_tiff.la
+
+#libevas_loader_tiff_la_SOURCES = evas_image_load_tiff.c
+#libevas_loader_tiff_la_LIBADD = @evas_image_loader_tiff_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <tiffio.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+typedef struct TIFFRGBAImage_Extra TIFFRGBAImage_Extra;
+
+struct TIFFRGBAImage_Extra {
+ TIFFRGBAImage rgba;
+ char pper;
+ uint32 num_pixels;
+ uint32 py;
+};
+
+static Eina_Bool
+evas_image_load_file_head_tiff(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ char txt[1024];
+ TIFFRGBAImage tiff_image;
+ TIFF *tif = NULL;
+ FILE *ffile;
+ int fd;
+ uint16 magic_number;
+
+ ffile = fopen(file, "rb");
+ if (!ffile)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ if (fread(&magic_number, sizeof(uint16), 1, ffile) != 1)
+ {
+ fclose(ffile);
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+ /* Apparently rewind(f) isn't sufficient */
+ fseek(ffile, 0, SEEK_SET);
+
+ if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
+ && (magic_number != TIFF_LITTLEENDIAN))
+ {
+ fclose(ffile);
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ fd = fileno(ffile);
+ fd = dup(fd);
+ lseek(fd, (long)0, SEEK_SET);
+ fclose(ffile);
+
+ tif = TIFFFdOpen(fd, file, "r");
+ if (!tif)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
+ if (!TIFFRGBAImageOK(tif, txt))
+ {
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
+ if (!TIFFRGBAImageBegin(& tiff_image, tif, 1, txt))
+ {
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ if (tiff_image.alpha != EXTRASAMPLE_UNSPECIFIED)
+ ilp->alpha = 1;
+ if ((tiff_image.width < 1) || (tiff_image.height < 1) ||
+ (tiff_image.width > IMG_MAX_SIZE) || (tiff_image.height > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(tiff_image.width, tiff_image.height))
+ {
+ TIFFClose(tif);
+ if (IMG_TOO_BIG(tiff_image.width, tiff_image.height))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
+ }
+ ilp->w = tiff_image.width;
+ ilp->h = tiff_image.height;
+
+ TIFFRGBAImageEnd(&tiff_image);
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_tiff(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ char txt[1024];
+ TIFFRGBAImage_Extra rgba_image;
+ TIFF *tif = NULL;
+ FILE *ffile;
+ uint32 *rast = NULL;
+ uint32 num_pixels;
+ int fd, x, y;
+ uint16 magic_number;
+ unsigned int *surface;
+
+ ffile = fopen(file, "rb");
+ if (!ffile)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ if (fread(&magic_number, sizeof(uint16), 1, ffile) != 1)
+ {
+ fclose(ffile);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ /* Apparently rewind(f) isn't sufficient */
+ fseek(ffile, (long)0, SEEK_SET);
+
+ if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
+ && (magic_number != TIFF_LITTLEENDIAN))
+ {
+ fclose(ffile);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ fd = fileno(ffile);
+ fd = dup(fd);
+ lseek(fd, (long)0, SEEK_SET);
+ fclose(ffile);
+
+ tif = TIFFFdOpen(fd, file, "r");
+ if (!tif)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ strcpy(txt, "Evas Tiff loader: cannot be processed by libtiff");
+ if (!TIFFRGBAImageOK(tif, txt))
+ {
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ strcpy(txt, "Evas Tiff loader: cannot begin reading tiff");
+ if (!TIFFRGBAImageBegin((TIFFRGBAImage *) & rgba_image, tif, 0, txt))
+ {
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
+ ilp->alpha = 1;
+ if ((rgba_image.rgba.width != ilp->w) ||
+ (rgba_image.rgba.height != ilp->h))
+ {
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ surface = ilp->buffer;
+ if (!surface)
+ {
+ TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+
+ rgba_image.num_pixels = num_pixels = ilp->w * ilp->h;
+
+ rgba_image.pper = rgba_image.py = 0;
+ rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
+
+ if (!rast)
+ {
+ ERR("Evas Tiff loader: out of memory");
+
+ TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return EINA_FALSE;
+ }
+ if (rgba_image.rgba.bitspersample == 8)
+ {
+ if (!TIFFRGBAImageGet((TIFFRGBAImage *) &rgba_image, rast,
+ rgba_image.rgba.width, rgba_image.rgba.height))
+ {
+ _TIFFfree(rast);
+ TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
+ TIFFClose(tif);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+ }
+ /* process rast -> image rgba. really same as prior code anyway just simpler */
+ for (y = 0; y < (int)ilp->h; y++)
+ {
+ DATA32 *pix, *pd;
+ uint32 *ps, pixel;
+ unsigned int a, r, g, b;
+
+ pix = surface;
+ pd = pix + ((ilp->h - y - 1) * ilp->w);
+ ps = rast + (y * ilp->w);
+ for (x = 0; x < (int)ilp->w; x++)
+ {
+ pixel = *ps;
+ a = TIFFGetA(pixel);
+ r = TIFFGetR(pixel);
+ g = TIFFGetG(pixel);
+ b = TIFFGetB(pixel);
+ if (!ilp->alpha) a = 255;
+ if ((rgba_image.rgba.alpha == EXTRASAMPLE_UNASSALPHA) &&
+ (a < 255))
+ {
+ r = (r * (a + 1)) >> 8;
+ g = (g * (a + 1)) >> 8;
+ b = (b * (a + 1)) >> 8;
+ }
+ *pd = ARGB_JOIN(a, r, g, b);
+ ps++;
+ pd++;
+ }
+ }
+
+ _TIFFfree(rast);
+
+ TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image);
+
+ TIFFClose(tif);
+
+ evas_cserve2_image_alpha_sparse_set(ilp);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "tiff",
+ evas_image_load_file_head_tiff,
+ evas_image_load_file_data_tiff
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_WBMP
+#if !EVAS_STATIC_BUILD_WBMP
+
+pkgdir = $(libdir)/evas/cserve2/loaders/wbmp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_wbmp.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_wbmp.la
+#libevas_loader_wbmp_la_SOURCES = evas_image_load_wbmp.c
+#libevas_loader_wbmp_la_LIBADD =
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+static int
+read_mb(unsigned int *data, void *map, size_t length, size_t *position)
+{
+ int ac = 0, ct;
+ unsigned char buf;
+
+ for (ct = 0;;)
+ {
+ if ((ct++) == 5) return -1;
+ if (*position > length) return -1;
+ buf = ((unsigned char *) map)[(*position)++];
+ ac = (ac << 7) | (buf & 0x7f);
+ if ((buf & 0x80) == 0) break;
+ }
+ *data = ac;
+ return 0;
+}
+
+static Eina_Bool
+evas_image_load_file_head_wbmp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ size_t length;
+ unsigned int type, w, h;
+
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ f = eina_file_open(file, 0);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ length = eina_file_size_get(f);
+ if (length <= 4) goto bail;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto bail;
+
+ if (read_mb(&type, map, length, &position) < 0) goto bail;
+
+ if (type != 0)
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto bail;
+ }
+
+ position++; /* skipping one byte */
+ if (read_mb(&w, map, length, &position) < 0) goto bail;
+ if (read_mb(&h, map, length, &position) < 0) goto bail;
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto bail;
+ }
+
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+ ilp->w = w;
+ ilp->h = h;
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+bail:
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_wbmp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+ Eina_File *f;
+ void *map = NULL;
+ size_t position = 0;
+ size_t length;
+ unsigned int type, w, h;
+ unsigned int line_length;
+ unsigned char *line = NULL;
+ int cur = 0, x, y;
+ DATA32 *dst_data;
+
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ f = eina_file_open(file, EINA_FALSE);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ length = eina_file_size_get(f);
+ if (length <= 4) goto bail;
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map) goto bail;
+
+ if (read_mb(&type, map, length, &position) < 0) goto bail;
+ position++; /* skipping one byte */
+ if (read_mb(&w, map, length, &position) < 0) goto bail;
+ if (read_mb(&h, map, length, &position) < 0) goto bail;
+
+ if (type != 0)
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto bail;
+ }
+
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto bail;
+ }
+
+ ilp->w = w;
+ ilp->h = h;
+
+ dst_data = ilp->buffer;
+ if (!dst_data)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto bail;
+ }
+
+ line_length = (ilp->w + 7) >> 3;
+
+ for (y = 0; y < (int)ilp->h; y++)
+ {
+ if (position + line_length > length) goto bail;
+ line = ((unsigned char*) map) + position;
+ position += line_length;
+ for (x = 0; x < (int)ilp->w; x++)
+ {
+ int idx = x >> 3;
+ int offset = 1 << (0x07 - (x & 0x07));
+ if (line[idx] & offset) dst_data[cur] = 0xffffffff;
+ else dst_data[cur] = 0xff000000;
+ cur++;
+ }
+ }
+ eina_file_map_free(f, map);
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+bail:
+ if (map) eina_file_map_free(f, map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "wbmp",
+ evas_image_load_file_head_wbmp,
+ evas_image_load_file_data_wbmp
+};
+
+static Eina_Bool
+module_init(void)
+{
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_xpm_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_XPM
+#if !EVAS_STATIC_BUILD_XPM
+pkgdir = $(libdir)/evas/cserve2/loaders/xpm/$(MODULE_ARCH)
+
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_xpm.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_xpm_libs@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_xpm.la
+
+#libevas_loader_xpm_la_SOURCES = evas_image_load_xpm.c
+#libevas_loader_xpm_la_LIBADD = @evas_image_loader_xpm_libs@
+
+#endif
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+static Eina_File *rgb_txt;
+static void *rgb_txt_map;
+
+static void
+xpm_parse_color(char *color, int *r, int *g, int *b)
+{
+ char *tmp;
+ char *max;
+ char *endline;
+ char buf[4096];
+
+ /* is a #ff00ff like color */
+ if (color[0] == '#')
+ {
+ int len;
+ char val[32];
+
+ len = strlen(color) - 1;
+ if (len < 96)
+ {
+ int i;
+
+ len /= 3;
+ for (i = 0; i < len; i++)
+ val[i] = color[1 + i + (0 * len)];
+ val[i] = 0;
+ sscanf(val, "%x", r);
+ for (i = 0; i < len; i++)
+ val[i] = color[1 + i + (1 * len)];
+ val[i] = 0;
+ sscanf(val, "%x", g);
+ for (i = 0; i < len; i++)
+ val[i] = color[1 + i + (2 * len)];
+ val[i] = 0;
+ sscanf(val, "%x", b);
+ if (len == 1)
+ {
+ *r = (*r << 4) | *r;
+ *g = (*g << 4) | *g;
+ *b = (*b << 4) | *b;
+ }
+ else if (len > 2)
+ {
+ *r >>= (len - 2) * 4;
+ *g >>= (len - 2) * 4;
+ *b >>= (len - 2) * 4;
+ }
+ }
+ return;
+ }
+ /* look in rgb txt database */
+ if (!rgb_txt) return;
+ tmp = rgb_txt_map;
+ max = tmp + eina_file_size_get(rgb_txt);
+
+ while (tmp < max)
+ {
+ endline = memchr(tmp, '\n', max - tmp);
+ if (!endline) endline = max;
+ if ((*tmp != '!') && ((endline - tmp) < (int) (sizeof(buf) - 1)))
+ {
+ int rr, gg, bb;
+ char name[4096];
+
+ /* FIXME: not really efficient */
+ memcpy(buf, tmp, endline - tmp);
+ buf[endline - tmp + 1] = '\0';
+
+ if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4)
+ {
+ if (!strcasecmp(name, color))
+ {
+ *r = rr;
+ *g = gg;
+ *b = bb;
+ return;
+ }
+ }
+ }
+ tmp = endline + 1;
+ }
+}
+
+/** FIXME: clean this up and make more efficient **/
+static Eina_Bool
+evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int load_data, int *error)
+{
+ DATA32 *ptr, *end;
+ Eina_File *f;
+ const char *map;
+ size_t length;
+ size_t position;
+
+ int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
+ quote, context, len, done, r, g, b, backslash, lu1, lu2;
+ char *line = NULL;
+ char s[256], tok[128], col[256], *tl;
+ int lsz = 256;
+ struct _cmap {
+ char str[6];
+ unsigned char transp;
+ short r, g, b;
+ } *cmap = NULL;
+
+ short lookup[128 - 32][128 - 32];
+ int count, pixels;
+
+ done = 0;
+// transp = -1;
+ transp = 1;
+
+ /* if immediate_load is 1, then dont delay image laoding as below, or */
+ /* already data in this image - dont load it again */
+
+ f = eina_file_open(file, 0);
+ if (!f)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+ length = eina_file_size_get(f);
+ position = 0;
+ if (length < 9)
+ {
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+ if (!map)
+ {
+ eina_file_close(f);
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ return EINA_FALSE;
+ }
+
+ if (strncmp("/* XPM */", map, 9))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto on_error;
+ }
+
+ i = 0;
+ j = 0;
+ cmap = NULL;
+ w = 10;
+ h = 10;
+ ptr = NULL;
+ end = NULL;
+ c = ' ';
+ comment = 0;
+ quote = 0;
+ context = 0;
+ pixels = 0;
+ count = 0;
+ line = malloc(lsz);
+ if (!line)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+
+ backslash = 0;
+ memset(lookup, 0, sizeof(lookup));
+ while (!done)
+ {
+ pc = c;
+ if (position == length) break ;
+ c = (char) map[position++];
+ if (!quote)
+ {
+ if ((pc == '/') && (c == '*'))
+ comment = 1;
+ else if ((pc == '*') && (c == '/') && (comment))
+ comment = 0;
+ }
+ if (!comment)
+ {
+ if ((!quote) && (c == '"'))
+ {
+ quote = 1;
+ i = 0;
+ }
+ else if ((quote) && (c == '"'))
+ {
+ line[i] = 0;
+ quote = 0;
+ if (context == 0)
+ {
+ /* Header */
+ if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4)
+ {
+ *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+ goto on_error;
+ }
+ if ((ncolors > 32766) || (ncolors < 1))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto on_error;
+ }
+ if ((cpp > 5) || (cpp < 1))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto on_error;
+ }
+ if ((w > IMG_MAX_SIZE) || (w < 1))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto on_error;
+ }
+ if ((h > IMG_MAX_SIZE) || (h < 1))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto on_error;
+ }
+ if (IMG_TOO_BIG(w, h))
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+
+ if (!cmap)
+ {
+ cmap = malloc(sizeof(struct _cmap) * ncolors);
+ if (!cmap)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+ }
+ ilp->w = w;
+ ilp->h = h;
+
+ j = 0;
+ context++;
+ }
+ else if (context == 1)
+ {
+ /* Color Table */
+ if (j < ncolors)
+ {
+ int slen;
+ int hascolor, iscolor;
+
+ iscolor = 0;
+ hascolor = 0;
+ tok[0] = 0;
+ col[0] = 0;
+ s[0] = 0;
+ len = strlen(line);
+ strncpy(cmap[j].str, line, cpp);
+ cmap[j].str[cpp] = 0;
+ for (slen = 0; slen < cpp; slen++)
+ {
+ /* fix the ascii of the color string - if its < 32 - just limit to 32 */
+ if (cmap[j].str[slen] < 32) cmap[j].str[slen] = 0;
+ }
+ cmap[j].r = -1;
+ cmap[j].transp = 0;
+ for (k = cpp; k < len; k++)
+ {
+ if (line[k] != ' ')
+ {
+ s[0] = 0;
+ sscanf(&line[k], "%255s", s);
+ slen = strlen(s);
+ k += slen;
+ if (!strcmp(s, "c")) iscolor = 1;
+ if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
+ || (!strcmp(s, "g4")) || (!strcmp(s, "g"))
+ || (!strcmp(s, "c")) || (k >= len))
+ {
+ if (k >= len)
+ {
+ if (col[0])
+ {
+ if (strlen(col) < (sizeof(col) - 2))
+ strcat(col, " ");
+ else
+ done = 1;
+ }
+ if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
+ strcat(col, s);
+ }
+ if (col[0])
+ {
+ if (!strcasecmp(col, "none"))
+ {
+ transp = 1;
+ cmap[j].transp = 1;
+ cmap[j].r = 0;
+ cmap[j].g = 0;
+ cmap[j].b = 0;
+ }
+ else
+ {
+ if ((((cmap[j].r < 0) || (!strcmp(tok, "c"))) && (!hascolor)))
+ {
+ r = g = b = 0;
+ xpm_parse_color(col, &r, &g, &b);
+ cmap[j].r = r;
+ cmap[j].g = g;
+ cmap[j].b = b;
+ if (iscolor) hascolor = 1;
+ }
+ }
+ }
+ strcpy(tok, s);
+ col[0] = 0;
+ }
+ else
+ {
+ if (col[0])
+ {
+ if (strlen(col) < ( sizeof(col) - 2))
+ strcat(col, " ");
+ else
+ done = 1;
+ }
+ if ((strlen(col) + strlen(s)) < (sizeof(col) - 1))
+ strcat(col, s);
+ }
+ }
+ }
+ }
+ j++;
+ if (j >= ncolors)
+ {
+ if (cpp == 1)
+ {
+ for (i = 0; i < ncolors; i++)
+ lookup[(int)cmap[i].str[0] - 32][0] = i;
+ }
+ if (cpp == 2)
+ {
+ for (i = 0; i < ncolors; i++)
+ lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
+ }
+ context++;
+ }
+
+ if (transp) ilp->alpha = 1;
+
+ if (load_data)
+ {
+ ptr = ilp->buffer;
+ if (!ptr)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto on_error;
+ }
+ pixels = w * h;
+ end = ptr + pixels;
+ }
+ else
+ {
+ *error = EVAS_LOAD_ERROR_NONE;
+ goto on_success;
+ }
+ }
+ else
+ {
+ /* Image Data */
+ i = 0;
+ if (cpp == 0)
+ {
+ /* Chars per pixel = 0? well u never know */
+ }
+ /* it's xpm - don't care about speed too much. still faster
+ * that most xpm loaders anyway */
+ else if (cpp == 1)
+ {
+ if (transp)
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ lu1 = (int)line[i] - 32;
+ if (lu1 < 0) continue;
+ if (cmap[lookup[lu1][0]].transp)
+ {
+ r = (unsigned char)cmap[lookup[lu1][0]].r;
+ g = (unsigned char)cmap[lookup[lu1][0]].g;
+ b = (unsigned char)cmap[lookup[lu1][0]].b;
+ *ptr = RGB_JOIN(r, g, b);
+ ptr++;
+ count++;
+ }
+ else
+ {
+ r = (unsigned char)cmap[lookup[lu1][0]].r;
+ g = (unsigned char)cmap[lookup[lu1][0]].g;
+ b = (unsigned char)cmap[lookup[lu1][0]].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ lu1 = (int)line[i] - 32;
+ if (lu1 < 0) continue;
+ r = (unsigned char)cmap[lookup[lu1][0]].r;
+ g = (unsigned char)cmap[lookup[lu1][0]].g;
+ b = (unsigned char)cmap[lookup[lu1][0]].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ }
+ }
+ }
+ else if (cpp == 2)
+ {
+ if (transp)
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ lu1 = (int)line[i] - 32;
+ i++;
+ lu2 = (int)line[i] - 32;
+ if (lu1 < 0) continue;
+ if (lu2 < 0) continue;
+ if (cmap[lookup[lu1][lu2]].transp)
+ {
+ r = (unsigned char)cmap[lookup[lu1][lu2]].r;
+ g = (unsigned char)cmap[lookup[lu1][lu2]].g;
+ b = (unsigned char)cmap[lookup[lu1][lu2]].b;
+ *ptr = RGB_JOIN(r, g, b);
+ ptr++;
+ count++;
+ }
+ else
+ {
+ r = (unsigned char)cmap[lookup[lu1][lu2]].r;
+ g = (unsigned char)cmap[lookup[lu1][lu2]].g;
+ b = (unsigned char)cmap[lookup[lu1][lu2]].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ lu1 = (int)line[i] - 32;
+ i++;
+ lu2 = (int)line[i] - 32;
+ if (lu1 < 0) continue;
+ if (lu2 < 0) continue;
+ r = (unsigned char)cmap[lookup[lu1][lu2]].r;
+ g = (unsigned char)cmap[lookup[lu1][lu2]].g;
+ b = (unsigned char)cmap[lookup[lu1][lu2]].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ }
+ }
+ }
+ else
+ {
+ if (transp)
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ for (j = 0; j < cpp; j++, i++)
+ {
+ col[j] = line[i];
+ if (col[j] < 32) col[j] = 32;
+ }
+ col[j] = 0;
+ i--;
+ for (j = 0; j < ncolors; j++)
+ {
+ if (!strcmp(col, cmap[j].str))
+ {
+ if (cmap[j].transp)
+ {
+ r = (unsigned char)cmap[j].r;
+ g = (unsigned char)cmap[j].g;
+ b = (unsigned char)cmap[j].b;
+ *ptr = RGB_JOIN(r, g, b);
+ ptr++;
+ count++;
+ }
+ else
+ {
+ r = (unsigned char)cmap[j].r;
+ g = (unsigned char)cmap[j].g;
+ b = (unsigned char)cmap[j].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = 0;
+ ((i < 65536) && (ptr < end) && (line[i]));
+ i++)
+ {
+ for (j = 0; j < cpp; j++, i++)
+ {
+ col[j] = line[i];
+ }
+ col[j] = 0;
+ i--;
+ for (j = 0; j < ncolors; j++)
+ {
+ if (!strcmp(col, cmap[j].str))
+ {
+ r = (unsigned char)cmap[j].r;
+ g = (unsigned char)cmap[j].g;
+ b = (unsigned char)cmap[j].b;
+ *ptr = ARGB_JOIN(0xff, r, g, b);
+ ptr++;
+ count++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Scan in line from XPM file */
+ if ((!comment) && (quote) && (c != '"'))
+ {
+ if (c < 32) c = 32;
+ else if (c > 127) c = 127;
+ if (c =='\\')
+ {
+ if (++backslash < 2)
+ line[i++] = c;
+ else
+ backslash = 0;
+ }
+ else
+ {
+ backslash = 0;
+ line[i++] = c;
+ }
+ }
+ if (i >= lsz)
+ {
+ lsz += 256;
+ tl = realloc(line, lsz);
+ if (!tl) break;
+ line = tl;
+ }
+ if (((ptr) && ((ptr - (DATA32 *)ilp->buffer) >= (w * h * (int)sizeof(DATA32)))) ||
+ ((context > 1) && (count >= pixels)))
+ break;
+ }
+
+ on_success:
+ free(cmap);
+ free(line);
+
+ eina_file_map_free(f, (void*) map);
+ eina_file_close(f);
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+
+ on_error:
+ free(line);
+ eina_file_map_free(f, (void*) map);
+ eina_file_close(f);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+evas_image_load_file_head_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ return evas_image_load_file_xpm(ilp, file, key, 0, error);
+}
+
+static Eina_Bool
+evas_image_load_file_data_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
+{
+ return evas_image_load_file_xpm(ilp, file, key, 1, error);
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+ EVAS_CSERVE2_MODULE_API_VERSION,
+ "xpm",
+ evas_image_load_file_head_xpm,
+ evas_image_load_file_data_xpm
+};
+
+static Eina_Bool
+module_init(void)
+{
+ /* Shouldn't we make that PATH configurable ? */
+ rgb_txt = eina_file_open("/usr/lib/X11/rgb.txt", 0);
+ if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11/lib/X11/rgb.txt", 0);
+ if (!rgb_txt) rgb_txt = eina_file_open("/usr/X11R6/lib/X11/rgb.txt", 0);
+ if (!rgb_txt) rgb_txt = eina_file_open("/usr/openwin/lib/X11/rgb.txt", 0);
+ if (rgb_txt)
+ rgb_txt_map = eina_file_map_all(rgb_txt, EINA_FILE_SEQUENTIAL);
+ return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+ if (rgb_txt)
+ {
+ eina_file_map_free(rgb_txt, rgb_txt_map);
+ eina_file_close(rgb_txt);
+ rgb_txt = NULL;
+ }
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
evas_images2_SOURCES = evas-images2.c
evas_images2_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
+examples_PROGRAMS += evas_images3
+evas_images3_SOURCES = evas-images3.c
+evas_images3_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
+
examples_PROGRAMS += evas_text
evas_text_SOURCES = evas-text.c
evas_text_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
$(srcdir)/evas-init-shutdown.c \
$(srcdir)/evas-images.c \
$(srcdir)/evas-images2.c \
+ $(srcdir)/evas-images3.c \
$(srcdir)/evas-object-manipulation.c \
$(srcdir)/evas-events.c \
$(srcdir)/evas-aspect-hints.c \
$(srcdir)/evas-init-shutdown.c \
$(srcdir)/evas-images.c \
$(srcdir)/evas-images2.c \
+ $(srcdir)/evas-images3.c \
$(srcdir)/evas-object-manipulation.c \
$(srcdir)/evas-events.c \
$(srcdir)/evas-aspect-hints.c \
$(srcdir)/evas-text.c \
$(srcdir)/evas-smart-object.c \
$(srcdir)/evas-box.c \
+ $(srcdir)/evas-table.c \
$(srcdir)/enlightenment.png \
$(srcdir)/red.png \
$(srcdir)/im1.png \
--- /dev/null
+/**
+ * Simple Evas example illustrating some image objects functions
+ *
+ * You'll need at least one engine built for it (excluding the buffer
+ * one) and the png image loader/saver also built. See stdout/stderr
+ * for output.
+ *
+ * @verbatim
+ * gcc -o evas-images2 evas-images2.c `pkg-config --libs --cflags evas ecore ecore-evas`
+ * @endverbatim
+ */
+
+#ifdef HAVE_CONFIG_H
+
+#include "config.h"
+#else
+
+#define PACKAGE_EXAMPLES_DIR "."
+#define __UNUSED__
+
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define WIDTH (320)
+#define HEIGHT (240)
+
+static const char *img_path = PACKAGE_EXAMPLES_DIR "/enlightenment.png";
+static const char *commands = \
+ "commands are:\n"
+ "\tw - write new pixel data to image\n"
+ "\ti - print image info\n"
+ "\ta - save noise image to disk (/tmp dir)\n"
+ "\th - print help\n";
+
+const char *file_path = "/tmp/evas-images2-example.png";
+const char *quality_str = "quality=100";
+
+struct test_data
+{
+ Ecore_Evas *ee;
+ Evas *evas;
+ Evas_Object *bg;
+ Evas_Object *logo, *logo1;
+};
+
+static struct test_data d = {0};
+
+static void
+_on_destroy(Ecore_Evas *ee __UNUSED__)
+{
+ ecore_main_loop_quit();
+}
+
+/* here just to keep our example's window size and background image's
+ * size in synchrony */
+static void
+_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.logo, w / 2, h);
+ evas_object_move(d.logo1, w / 2, 0);
+ evas_object_resize(d.logo1, w / 2, h);
+}
+
+static void
+_on_keydown(void *data __UNUSED__,
+ Evas *evas __UNUSED__,
+ Evas_Object *o __UNUSED__,
+ void *einfo)
+{
+ Evas_Event_Key_Down *ev = einfo;
+
+ if (strcmp(ev->keyname, "h") == 0) /* print help */
+ {
+ fprintf(stdout, commands);
+ return;
+ }
+
+ if (strcmp(ev->keyname, "i") == 0) /* change proxy's source */
+ {
+ int stride = evas_object_image_stride_get(d.logo);
+ int w, h;
+
+ evas_object_image_size_get(d.logo, &w, &h);
+
+ printf("image size: %dx%d; stride: %d\n", w, h, stride);
+
+ return;
+ }
+
+ if (strcmp(ev->keyname, "w") == 0) /* save noise image to disk */
+ {
+ int i;
+ char *pixels = evas_object_image_data_get(d.logo, EINA_FALSE);
+ char *bufpixels;
+ int w, h;
+ int stride;
+ Eina_Bool equal = EINA_TRUE;
+
+ evas_object_image_size_get(d.logo, &w, &h);
+ stride = evas_object_image_stride_get(d.logo);
+
+ bufpixels = malloc(sizeof(char) * stride * h);
+ memcpy(bufpixels, pixels, sizeof(char) * stride * h);
+
+ pixels = evas_object_image_data_get(d.logo, EINA_TRUE);
+
+ for (i = 0; i < (stride * h); i++)
+ {
+ if (bufpixels[i] != pixels[i])
+ {
+ equal = EINA_FALSE;
+ break;
+ }
+ }
+
+ free(bufpixels);
+
+ if (!equal)
+ printf("write pixels different from readonly pixels.\n");
+
+ for (i = ((stride * h) / 4) ; i < ((stride * h) / 2) ; i++)
+ {
+ pixels[i] = 0;
+ }
+
+ // evas_object_image_data_set(d.logo, pixels);
+ evas_object_image_data_update_add(d.logo, 0, 0, w, h);
+ return;
+ }
+}
+
+int
+main(void)
+{
+ // unsigned int i;
+ // unsigned int pixels[(WIDTH / 4) * (HEIGHT / 4)];
+
+ 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, 10, 10, WIDTH, HEIGHT, NULL);
+ if (!d.ee)
+ goto error;
+
+ ecore_evas_callback_destroy_set(d.ee, _on_destroy);
+ ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
+ ecore_evas_show(d.ee);
+
+ /* the canvas pointer, de facto */
+ d.evas = ecore_evas_get(d.ee);
+
+ d.bg = evas_object_rectangle_add(d.evas);
+ evas_object_color_set(d.bg, 255, 255, 255, 255); /* white bg */
+ evas_object_move(d.bg, 0, 0); /* at canvas' origin */
+ evas_object_resize(d.bg, WIDTH, HEIGHT); /* covers full canvas */
+ evas_object_show(d.bg);
+
+ evas_object_focus_set(d.bg, EINA_TRUE);
+ evas_object_event_callback_add(
+ d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL);
+
+ d.logo = evas_object_image_filled_add(d.evas);
+
+ evas_object_image_file_set(d.logo, img_path, NULL);
+ evas_object_resize(d.logo, WIDTH / 2, HEIGHT);
+ evas_object_show(d.logo);
+
+ d.logo1 = evas_object_image_filled_add(d.evas);
+ evas_object_image_file_set(d.logo1, img_path, NULL);
+ evas_object_resize(d.logo1, WIDTH / 2, HEIGHT);
+ evas_object_move(d.logo1, WIDTH / 2, 0);
+ evas_object_show(d.logo1);
+
+ fprintf(stdout, commands);
+ ecore_main_loop_begin();
+
+ ecore_evas_free(d.ee);
+ ecore_evas_shutdown();
+ return 0;
+
+error:
+ fprintf(stderr, "you got to have at least one evas engine built and linked"
+ " up to ecore-evas for this example to run properly.\n");
+ ecore_evas_shutdown();
+ return -1;
+}
/**
-@mainpage Evas
-
-@version 1.1
-@date 2000-2012
-
-Please see the @ref authors page for contact details.
-@link Evas.h Evas API @endlink
-
-@link Evas.h Evas API @endlink
-
-@section toc Table of Contents
-
-@li @ref intro
-@li @ref work
-@li @ref compiling
-@li @ref install
-@li @ref next_steps
-@li @ref intro_example
-
-
-@section intro What is Evas?
-
-Evas is a clean display canvas API for several target display systems
-that can draw anti-aliased text, smooth super and sub-sampled scaled
-images, alpha-blend objects and much more.
-
-It abstracts any need to know much about what the characteristics of
-your display system are or what graphics calls are used to draw them
-and how. It deals on an object level where all you do is create and
-manipulate objects in a canvas, set their properties, and the rest is
-done for you.
-
-Evas optimises the rendering pipeline to minimise effort in redrawing
-changes made to the canvas and so takes this work out of the
-programmers hand, saving a lot of time and energy.
-
-It's small and lean, designed to work on embedded systems all the way
-to large and powerful multi-cpu workstations. It can be compiled to
-only have the features you need for your target platform if you so
-wish, thus keeping it small and lean. It has several display
-back-ends, letting it display on several display systems, making it
-portable for cross-device and cross-platform development.
-
-@subsection intro_not_evas What Evas is not?
-
-Evas is not a widget set or widget toolkit, however it is their
-base. See Elementary (http://docs.enlightenment.org/auto/elementary/)
-for a toolkit based on Evas, Edje, Ecore and other Enlightenment
-technologies.
-
-It is not dependent or aware of main loops, input or output
-systems. Input should be polled from various sources and fed to
-Evas. Similarly, it will not create windows or report windows updates
-to your system, rather just drawing the pixels and reporting to the
-user the areas that were changed. Of course these operations are quite
-common and thus they are ready to use in Ecore, particularly in
-Ecore_Evas (http://docs.enlightenment.org/auto/ecore/).
-
-
-@section work How does Evas work?
-
-Evas is a canvas display library. This is markedly different from most
-display and windowing systems as a canvas is structural and is also a
-state engine, whereas most display and windowing systems are immediate
-mode display targets. Evas handles the logic between a structural
-display via its state engine, and controls the target windowing system
-in order to produce rendered results of the current canvas' state on
-the display.
-
-Immediate mode display systems retain very little, or no state. A
-program will execute a series of commands, as in the pseudo code:
-
-@verbatim
-draw line from position (0, 0) to position (100, 200);
-
-draw rectangle from position (10, 30) to position (50, 500);
-
-bitmap_handle = create_bitmap();
-scale bitmap_handle to size 100 x 100;
-draw image bitmap_handle at position (10, 30);
-@endverbatim
-
-The series of commands is executed by the windowing system and the
-results are displayed on the screen (normally). Once the commands are
-executed the display system has little or no idea of how to reproduce
-this image again, and so has to be instructed by the application how
-to redraw sections of the screen whenever needed. Each successive
-command will be executed as instructed by the application and either
-emulated by software or sent to the graphics hardware on the device to
-be performed.
-
-The advantage of such a system is that it is simple, and gives a
-program tight control over how something looks and is drawn. Given the
-increasing complexity of displays and demands by users to have better
-looking interfaces, more and more work is needing to be done at this
-level by the internals of widget sets, custom display widgets and
-other programs. This means more and more logic and display rendering
-code needs to be written time and time again, each time the
-application needs to figure out how to minimise redraws so that
-display is fast and interactive, and keep track of redraw logic. The
-power comes at a high-price, lots of extra code and work. Programmers
-not very familiar with graphics programming will often make mistakes
-at this level and produce code that is sub optimal. Those familiar
-with this kind of programming will simply get bored by writing the
-same code again and again.
-
-For example, if in the above scene, the windowing system requires the
-application to redraw the area from 0, 0 to 50, 50 (also referred as
-"expose event"), then the programmer must calculate manually the
-updates and repaint it again:
-
-@verbatim
-Redraw from position (0, 0) to position (50, 50):
-
-// what was in area (0, 0, 50, 50)?
-
-// 1. intersection part of line (0, 0) to (100, 200)?
+ @mainpage Evas
+
+ @version 1.2
+ @date 2000-2012
+
+ Please see the @ref authors page for contact details.
+ @link Evas.h Evas API @endlink
+
+ @link Evas.h Evas API @endlink
+
+ @section toc Table of Contents
+
+ @li @ref intro
+ @li @ref work
+ @li @ref compiling
+ @li @ref install
+ @li @ref next_steps
+ @li @ref intro_example
+
+
+ @section intro What is Evas?
+
+ Evas is a clean display canvas API for several target display systems
+ that can draw anti-aliased text, smooth super and sub-sampled scaled
+ images, alpha-blend objects and much more.
+
+ It abstracts any need to know much about what the characteristics of
+ your display system are or what graphics calls are used to draw them
+ and how. It deals on an object level where all you do is create and
+ manipulate objects in a canvas, set their properties, and the rest is
+ done for you.
+
+ Evas optimises the rendering pipeline to minimise effort in redrawing
+ changes made to the canvas and so takes this work out of the
+ programmers hand, saving a lot of time and energy.
+
+ It's small and lean, designed to work on embedded systems all the way
+ to large and powerful multi-cpu workstations. It can be compiled to
+ only have the features you need for your target platform if you so
+ wish, thus keeping it small and lean. It has several display
+ back-ends, letting it display on several display systems, making it
+ portable for cross-device and cross-platform development.
+
+ @subsection intro_not_evas What Evas is not?
+
+ Evas is not a widget set or widget toolkit, however it is their
+ base. See Elementary (http://docs.enlightenment.org/auto/elementary/)
+ for a toolkit based on Evas, Edje, Ecore and other Enlightenment
+ technologies.
+
+ It is not dependent or aware of main loops, input or output
+ systems. Input should be polled from various sources and fed to
+ Evas. Similarly, it will not create windows or report windows updates
+ to your system, rather just drawing the pixels and reporting to the
+ user the areas that were changed. Of course these operations are quite
+ common and thus they are ready to use in Ecore, particularly in
+ Ecore_Evas (http://docs.enlightenment.org/auto/ecore/).
+
+
+ @section work How does Evas work?
+
+ Evas is a canvas display library. This is markedly different from most
+ display and windowing systems as a canvas is structural and is also a
+ state engine, whereas most display and windowing systems are immediate
+ mode display targets. Evas handles the logic between a structural
+ display via its state engine, and controls the target windowing system
+ in order to produce rendered results of the current canvas' state on
+ the display.
+
+ Immediate mode display systems retain very little, or no state. A
+ program will execute a series of commands, as in the pseudo code:
+
+ @verbatim
+ draw line from position (0, 0) to position (100, 200);
+
+ draw rectangle from position (10, 30) to position (50, 500);
+
+ bitmap_handle = create_bitmap();
+ scale bitmap_handle to size 100 x 100;
+ draw image bitmap_handle at position (10, 30);
+ @endverbatim
+
+ The series of commands is executed by the windowing system and the
+ results are displayed on the screen (normally). Once the commands are
+ executed the display system has little or no idea of how to reproduce
+ this image again, and so has to be instructed by the application how
+ to redraw sections of the screen whenever needed. Each successive
+ command will be executed as instructed by the application and either
+ emulated by software or sent to the graphics hardware on the device to
+ be performed.
+
+ The advantage of such a system is that it is simple, and gives a
+ program tight control over how something looks and is drawn. Given the
+ increasing complexity of displays and demands by users to have better
+ looking interfaces, more and more work is needing to be done at this
+ level by the internals of widget sets, custom display widgets and
+ other programs. This means more and more logic and display rendering
+ code needs to be written time and time again, each time the
+ application needs to figure out how to minimise redraws so that
+ display is fast and interactive, and keep track of redraw logic. The
+ power comes at a high-price, lots of extra code and work. Programmers
+ not very familiar with graphics programming will often make mistakes
+ at this level and produce code that is sub optimal. Those familiar
+ with this kind of programming will simply get bored by writing the
+ same code again and again.
+
+ For example, if in the above scene, the windowing system requires the
+ application to redraw the area from 0, 0 to 50, 50 (also referred as
+ "expose event"), then the programmer must calculate manually the
+ updates and repaint it again:
+
+ @verbatim
+ Redraw from position (0, 0) to position (50, 50):
+
+ // what was in area (0, 0, 50, 50)?
+
+ // 1. intersection part of line (0, 0) to (100, 200)?
draw line from position (0, 0) to position (25, 50);
-// 2. intersection part of rectangle (10, 30) to (50, 500)?
+ // 2. intersection part of rectangle (10, 30) to (50, 500)?
draw rectangle from position (10, 30) to position (50, 50)
-// 3. intersection part of image at (10, 30), size 100 x 100?
+ // 3. intersection part of image at (10, 30), size 100 x 100?
bitmap_subimage = subregion from position (0, 0) to position (40, 20)
draw image bitmap_subimage at position (10, 30);
-@endverbatim
-
-The clever reader might have noticed that, if all elements in the
-above scene are opaque, then the system is doing useless paints: part
-of the line is behind the rectangle, and part of the rectangle is
-behind the image. These useless paints tend to be very costly, as
-pixels tend to be 4 bytes in size, thus an overlapping region of 100 x
-100 pixels is around 40000 useless writes! The developer could write
-code to calculate the overlapping areas and avoid painting then, but
-then it should be mixed with the "expose event" handling mentioned
-above and quickly one realizes the initially simpler method became
-really complex.
-
-Evas is a structural system in which the programmer creates and
-manages display objects and their properties, and as a result of this
-higher level state management, the canvas is able to redraw the set of
-objects when needed to represent the current state of the canvas.
-
-For example, the pseudo code:
-
-@verbatim
-line_handle = create_line();
-set line_handle from position (0, 0) to position (100, 200);
-show line_handle;
-
-rectangle_handle = create_rectangle();
-move rectangle_handle to position (10, 30);
-resize rectangle_handle to size 40 x 470;
-show rectangle_handle;
-
-bitmap_handle = create_bitmap();
-scale bitmap_handle to size 100 x 100;
-move bitmap_handle to position (10, 30);
-show bitmap_handle;
-
-render scene;
-@endverbatim
-
-This may look longer, but when the display needs to be refreshed or
-updated, the programmer only moves, resizes, shows, hides etc. the
-objects that need to change. The programmer simply thinks at the
-object logic level, and the canvas software does the rest of the work
-for them, figuring out what actually changed in the canvas since it
-was last drawn, how to most efficiently redraw the canvas and its
-contents to reflect the current state, and then it can go off and do
-the actual drawing of the canvas.
-
-This lets the programmer think in a more natural way when dealing with
-a display, and saves time and effort of working out how to load and
-display images, render given the current display system etc. Since
-Evas also is portable across different display systems, this also
-gives the programmer the ability to have their code ported and
-displayed on different display systems with very little work.
-
-Evas can be seen as a display system that stands somewhere between a
-widget set and an immediate mode display system. It retains basic
-display logic, but does very little high-level logic such as
-scrollbars, sliders, push buttons etc.
-
-
-@section compiling How to compile using Evas ?
-
-Evas 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 evas`
-@endverbatim
-
-Linking object files into a binary executable:
-
-@verbatim
-gcc -o my_application main.o `pkg-config --libs evas`
-@endverbatim
-
-You simply have to make sure that @c pkg-config is in your shell's @c
-PATH (see the manual page for your appropriate shell) and @c evas.pc
-in @c /usr/lib/pkgconfig or its path in the @c PKG_CONFIG_PATH
-environment variable. It's that simple to link and use Evas once you
-have written your code to use it.
-
-Since the program is linked to Evas, it is now able to use any
-advertised API calls to display graphics in a canvas managed by it, as
-well as use the API calls provided to manage data.
-
-You should make sure you add any extra compile and link flags to your
-compile commands that your application may need as well. The above
-example is only guaranteed to make Evas add it's own requirements.
-
-
-@section install How is it installed?
-
-Simple:
-
-@verbatim
-./configure
-make
-su -
-...
-make install
-@endverbatim
-
-@section next_steps Next Steps
-
-After you understood what Evas is and installed it in your system you
-should proceed understanding the programming interface for all
-objects, then see the specific for the most used elements. We'd
-recommend you to take a while to learn Ecore
-(http://docs.enlightenment.org/auto/ecore/) and Edje
-(http://docs.enlightenment.org/auto/edje/) as they will likely save
-you tons of work compared to using just Evas directly.
+ @endverbatim
+
+ The clever reader might have noticed that, if all elements in the
+ above scene are opaque, then the system is doing useless paints: part
+ of the line is behind the rectangle, and part of the rectangle is
+ behind the image. These useless paints tend to be very costly, as
+ pixels tend to be 4 bytes in size, thus an overlapping region of 100 x
+ 100 pixels is around 40000 useless writes! The developer could write
+ code to calculate the overlapping areas and avoid painting then, but
+ then it should be mixed with the "expose event" handling mentioned
+ above and quickly one realizes the initially simpler method became
+ really complex.
+
+ Evas is a structural system in which the programmer creates and
+ manages display objects and their properties, and as a result of this
+ higher level state management, the canvas is able to redraw the set of
+ objects when needed to represent the current state of the canvas.
+
+ For example, the pseudo code:
+
+ @verbatim
+ line_handle = create_line();
+ set line_handle from position (0, 0) to position (100, 200);
+ show line_handle;
+
+ rectangle_handle = create_rectangle();
+ move rectangle_handle to position (10, 30);
+ resize rectangle_handle to size 40 x 470;
+ show rectangle_handle;
+
+ bitmap_handle = create_bitmap();
+ scale bitmap_handle to size 100 x 100;
+ move bitmap_handle to position (10, 30);
+ show bitmap_handle;
+
+ render scene;
+ @endverbatim
+
+ This may look longer, but when the display needs to be refreshed or
+ updated, the programmer only moves, resizes, shows, hides etc. the
+ objects that need to change. The programmer simply thinks at the
+ object logic level, and the canvas software does the rest of the work
+ for them, figuring out what actually changed in the canvas since it
+ was last drawn, how to most efficiently redraw the canvas and its
+ contents to reflect the current state, and then it can go off and do
+ the actual drawing of the canvas.
+
+ This lets the programmer think in a more natural way when dealing with
+ a display, and saves time and effort of working out how to load and
+ display images, render given the current display system etc. Since
+ Evas also is portable across different display systems, this also
+ gives the programmer the ability to have their code ported and
+ displayed on different display systems with very little work.
+
+ Evas can be seen as a display system that stands somewhere between a
+ widget set and an immediate mode display system. It retains basic
+ display logic, but does very little high-level logic such as
+ scrollbars, sliders, push buttons etc.
+
+
+ @section compiling How to compile using Evas ?
+
+ Evas 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 evas`
+ @endverbatim
+
+ Linking object files into a binary executable:
+
+ @verbatim
+ gcc -o my_application main.o `pkg-config --libs evas`
+ @endverbatim
+
+ You simply have to make sure that @c pkg-config is in your shell's @c
+ PATH (see the manual page for your appropriate shell) and @c evas.pc
+ in @c /usr/lib/pkgconfig or its path in the @c PKG_CONFIG_PATH
+ environment variable. It's that simple to link and use Evas once you
+ have written your code to use it.
+
+ Since the program is linked to Evas, it is now able to use any
+ advertised API calls to display graphics in a canvas managed by it, as
+ well as use the API calls provided to manage data.
+
+ You should make sure you add any extra compile and link flags to your
+ compile commands that your application may need as well. The above
+ example is only guaranteed to make Evas add it's own requirements.
+
+
+ @section install How is it installed?
+
+ Simple:
+
+ @verbatim
+ ./configure
+ make
+ su -
+ ...
+ make install
+ @endverbatim
+
+ @section next_steps Next Steps
+
+ After you understood what Evas is and installed it in your system you
+ should proceed understanding the programming interface for all
+ objects, then see the specific for the most used elements. We'd
+ recommend you to take a while to learn Ecore
+ (http://docs.enlightenment.org/auto/ecore/) and Edje
+ (http://docs.enlightenment.org/auto/edje/) as they will likely save
+ you tons of work compared to using just Evas directly.
-Recommended reading:
+ Recommended reading:
-@li @ref Evas_Object_Group, where you'll get how to basically
+ @li @ref Evas_Object_Group, where you'll get how to basically
manipulate generic objects lying on an Evas canvas, handle canvas
and object events, etc.
-@li @ref Evas_Object_Rectangle, to learn about the most basic object
+ @li @ref Evas_Object_Rectangle, to learn about the most basic object
type on Evas -- the rectangle.
-@li @ref Evas_Object_Polygon, to learn how to create polygon elements
+ @li @ref Evas_Object_Polygon, to learn how to create polygon elements
on the canvas.
-@li @ref Evas_Line_Group, to learn how to create line elements on the
+ @li @ref Evas_Line_Group, to learn how to create line elements on the
canvas.
-@li @ref Evas_Object_Image, to learn about image objects, over which
+ @li @ref Evas_Object_Image, to learn about image objects, over which
Evas can do a plethora of operations.
-@li @ref Evas_Object_Text, to learn how to create textual elements on
+ @li @ref Evas_Object_Text, to learn how to create textual elements on
the canvas.
-@li @ref Evas_Object_Textblock, to learn how to create multiline
+ @li @ref Evas_Object_Textblock, to learn how to create multiline
textual elements on the canvas.
-@li @ref Evas_Smart_Object_Group and @ref Evas_Smart_Group, to define
+ @li @ref Evas_Smart_Object_Group and @ref Evas_Smart_Group, to define
new objects that provide @b custom functions to handle clipping,
hiding, moving, resizing, color setting and more. These could
be as simple as a group of objects that move together (see @ref
ends to be a widget, providing some intelligence (thus the name)
to Evas objects -- like a button or check box, for example.
-@section intro_example Introductory Example
-
-@include evas-buffer-simple.c
-*/
-
-/**
-@page authors Authors
-@author Carsten Haitzler <raster@@rasterman.com>
-@author Till Adam <till@@adam-lilienthal.de>
-@author Steve Ireland <sireland@@pobox.com>
-@author Brett Nash <nash@@nash.id.au>
-@author Tilman Sauerbeck <tilman@@code-monkey.de>
-@author Corey Donohoe <atmos@@atmos.org>
-@author Yuri Hudobin <glassy_ape@@users.sourceforge.net>
-@author Nathan Ingersoll <ningerso@@d.umn.edu>
-@author Willem Monsuwe <willem@@stack.nl>
-@author Jose O Gonzalez <jose_ogp@@juno.com>
-@author Bernhard Nemec <Bernhard.Nemec@@viasyshc.com>
-@author Jorge Luis Zapata Muga <jorgeluis.zapata@@gmail.com>
-@author Cedric Bail <cedric.bail@@free.fr>
-@author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
-@author Vincent Torri <vtorri@@univ-evry.fr>
-@author Tim Horton <hortont424@@gmail.com>
-@author Tom Hacohen <tom@@stosb.com>
-@author Mathieu Taillefumier <mathieu.taillefumier@@free.fr>
-@author Iván Briano <ivan@@profusion.mobi>
-@author Gustavo Lima Chaves <glima@@profusion.mobi>
-@author Samsung Electronics
-@author Samsung SAIT
-@author Sung W. Park <sungwoo@@gmail.com>
-@author Jiyoun Park <jy0703.park@@samsung.com>
-@author Myoungwoon Roy Kim(roy_kim) <myoungwoon.kim@@samsung.com> <myoungwoon@@gmail.com>
-@author Thierry el Borgi <thierry@@substantiel.fr>
-@author ChunEon Park <hermet@@hermet.pe.kr>
-@author Christopher 'devilhorns' Michael <cpmichael1@comcast.net>
-@author Seungsoo Woo <om101.woo@samsung.com>
-
-Please contact <enlightenment-devel@lists.sourceforge.net> to get in
-contact with the developers and maintainers.
-*/
+ @section intro_example Introductory Example
+
+ @include evas-buffer-simple.c
+ */
+
+/**
+ @page authors Authors
+ @author Carsten Haitzler <raster@@rasterman.com>
+ @author Till Adam <till@@adam-lilienthal.de>
+ @author Steve Ireland <sireland@@pobox.com>
+ @author Brett Nash <nash@@nash.id.au>
+ @author Tilman Sauerbeck <tilman@@code-monkey.de>
+ @author Corey Donohoe <atmos@@atmos.org>
+ @author Yuri Hudobin <glassy_ape@@users.sourceforge.net>
+ @author Nathan Ingersoll <ningerso@@d.umn.edu>
+ @author Willem Monsuwe <willem@@stack.nl>
+ @author Jose O Gonzalez <jose_ogp@@juno.com>
+ @author Bernhard Nemec <Bernhard.Nemec@@viasyshc.com>
+ @author Jorge Luis Zapata Muga <jorgeluis.zapata@@gmail.com>
+ @author Cedric Bail <cedric.bail@@free.fr>
+ @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
+ @author Vincent Torri <vtorri@@univ-evry.fr>
+ @author Tim Horton <hortont424@@gmail.com>
+ @author Tom Hacohen <tom@@stosb.com>
+ @author Mathieu Taillefumier <mathieu.taillefumier@@free.fr>
+ @author Iván Briano <ivan@@profusion.mobi>
+ @author Gustavo Lima Chaves <glima@@profusion.mobi>
+ @author Samsung Electronics
+ @author Samsung SAIT
+ @author Sung W. Park <sungwoo@@gmail.com>
+ @author Jiyoun Park <jy0703.park@@samsung.com>
+ @author Myoungwoon Roy Kim(roy_kim) <myoungwoon.kim@@samsung.com> <myoungwoon@@gmail.com>
+ @author Thierry el Borgi <thierry@@substantiel.fr>
+ @author Shilpa Singh <shilpa.singh@@samsung.com> <shilpasingh.o@@gmail.com>
+ @author ChunEon Park <hermet@@hermet.pe.kr>
+ @author Christopher 'devilhorns' Michael <cpmichael1@@comcast.net>
+ @author Seungsoo Woo <om101.woo@@samsung.com>
+ @author Youness Alaoui <kakaroto@@kakaroto.homelinux.net>
+ @author Jim Kukunas <james.t.kukunas@@linux.intel.com>
+ @author Nicolas Aguirre <aguirre.nicolas@@gmail.com>
+ @author Rafal Krypa <r.krypa@@samsung.com>
+ @author Hyoyoung Chang <hyoyoung@@gmail.com>
+ @author Jérôme Pinot <ngc891@@gmail.com>
+ @author Rafael Antognolli <antognolli@@profusion.mobi>
+
+ Please contact <enlightenment-devel@lists.sourceforge.net> to get in
+ contact with the developers and maintainers.
+ */
#ifndef _EVAS_H
#define _EVAS_H
int revision;
} Evas_Version;
-EAPI extern Evas_Version *evas_version;
+EAPI extern Evas_Version * evas_version;
/**
* @file
*/
/* BiDi exposed stuff */
- /*FIXME: document */
+/*FIXME: document */
typedef enum _Evas_BiDi_Direction
{
EVAS_BIDI_DIRECTION_NATURAL,
EVAS_CALLBACK_RENDER_PRE, /**< Called just before rendering starts on the canvas target @since 1.2 */
EVAS_CALLBACK_RENDER_POST, /**< Called just after rendering stops on the canvas target @since 1.2 */
-
+
EVAS_CALLBACK_LAST /**< kept as last element/sentinel -- not really an event */
} Evas_Callback_Type; /**< The types of events triggering a callback */
* Slightly more prioritized than default.
* @since 1.1.0
*/
-#define EVAS_CALLBACK_PRIORITY_BEFORE -100
+#define EVAS_CALLBACK_PRIORITY_BEFORE -100
/**
* @def EVAS_CALLBACK_PRIORITY_DEFAULT
* Default callback priority level
* Slightly less prioritized than default.
* @since 1.1.0
*/
-#define EVAS_CALLBACK_PRIORITY_AFTER 100
+#define EVAS_CALLBACK_PRIORITY_AFTER 100
/**
* @typedef Evas_Callback_Priority
typedef enum _Evas_Colorspace
{
EVAS_COLORSPACE_ARGB8888, /**< ARGB 32 bits per pixel, high-byte is Alpha, accessed 1 32bit word at a time */
- /* these are not currently supported - but planned for the future */
+ /* these are not currently supported - but planned for the future */
EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
- EVAS_COLORSPACE_YCBCR422P709_PL,/**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
+ EVAS_COLORSPACE_YCBCR422P709_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_RGB565_A5P, /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
EVAS_COLORSPACE_GRY8, /**< 8bit grayscale */
EVAS_COLORSPACE_YCBCR422601_PL, /**< YCbCr 4:2:2, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
*/
typedef enum _Evas_Object_Table_Homogeneous_Mode
{
- EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE = 0,
- EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE = 1,
- EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM = 2
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE = 0,
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE = 1,
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM = 2
} Evas_Object_Table_Homogeneous_Mode; /**< Table cell pack mode. */
-typedef struct _Evas_Coord_Rectangle Evas_Coord_Rectangle; /**< A generic rectangle handle */
-typedef struct _Evas_Point Evas_Point; /**< integer point */
+typedef struct _Evas_Coord_Rectangle Evas_Coord_Rectangle; /**< A generic rectangle handle */
+typedef struct _Evas_Point Evas_Point; /**< integer point */
-typedef struct _Evas_Coord_Point Evas_Coord_Point; /**< Evas_Coord point */
-typedef struct _Evas_Coord_Precision_Point Evas_Coord_Precision_Point; /**< Evas_Coord point with sub-pixel precision */
+typedef struct _Evas_Coord_Point Evas_Coord_Point; /**< Evas_Coord point */
+typedef struct _Evas_Coord_Precision_Point Evas_Coord_Precision_Point; /**< Evas_Coord point with sub-pixel precision */
-typedef struct _Evas_Position Evas_Position; /**< associates given point in Canvas and Output */
-typedef struct _Evas_Precision_Position Evas_Precision_Position; /**< associates given point in Canvas and Output, with sub-pixel precision */
+typedef struct _Evas_Position Evas_Position; /**< associates given point in Canvas and Output */
+typedef struct _Evas_Precision_Position Evas_Precision_Position; /**< associates given point in Canvas and Output, with sub-pixel precision */
/**
* @typedef Evas_Smart_Class
*
* @ingroup Evas_Smart_Group
*/
-typedef struct _Evas_Smart_Class Evas_Smart_Class;
+typedef struct _Evas_Smart_Class Evas_Smart_Class;
/**
* @typedef Evas_Smart_Cb_Description
*
* @ingroup Evas_Smart_Group
*/
-typedef struct _Evas_Smart_Cb_Description Evas_Smart_Cb_Description;
+typedef struct _Evas_Smart_Cb_Description Evas_Smart_Cb_Description;
/**
* @typedef Evas_Map
*
* @ingroup Evas_Object_Group_Map
*/
-typedef struct _Evas_Map Evas_Map;
+typedef struct _Evas_Map Evas_Map;
/**
* @typedef Evas
*
* @ingroup Evas_Canvas
*/
-typedef struct _Evas Evas;
+typedef struct _Evas Evas;
/**
* @typedef Evas_Object
typedef struct _Evas_Smart Evas_Smart; /**< An Evas Smart Object handle */
typedef struct _Evas_Native_Surface Evas_Native_Surface; /**< A generic datatype for engine specific native surface information */
- /**
- * @typedef Evas_Video_Surface
- *
- * A generic datatype for video specific surface information
- * @see evas_object_image_video_surface_set
- * @see evas_object_image_video_surface_get
- * @since 1.1.0
- */
-typedef struct _Evas_Video_Surface Evas_Video_Surface;
+/**
+ * @typedef Evas_Video_Surface
+ *
+ * A generic datatype for video specific surface information
+ * @see evas_object_image_video_surface_set
+ * @see evas_object_image_video_surface_get
+ * @since 1.1.0
+ */
+typedef struct _Evas_Video_Surface Evas_Video_Surface;
-typedef unsigned long long Evas_Modifier_Mask; /**< An Evas modifier mask type */
+typedef unsigned long long Evas_Modifier_Mask; /**< An Evas modifier mask type */
-typedef int Evas_Coord;
-typedef int Evas_Font_Size;
-typedef int Evas_Angle;
+typedef int Evas_Coord;
+typedef int Evas_Font_Size;
+typedef int Evas_Angle;
struct _Evas_Coord_Rectangle /**< A rectangle in Evas_Coord */
{
struct _Evas_Coord_Precision_Point
{
Evas_Coord x, y;
- double xsub, ysub;
+ double xsub, ysub;
};
struct _Evas_Position
{
- Evas_Point output;
- Evas_Coord_Point canvas;
+ Evas_Point output;
+ Evas_Coord_Point canvas;
};
struct _Evas_Precision_Position
{
- Evas_Point output;
- Evas_Coord_Precision_Point canvas;
+ Evas_Point output;
+ Evas_Coord_Precision_Point canvas;
};
typedef enum _Evas_Aspect_Control
} Evas_Aspect_Control; /**< Aspect types/policies for scaling size hints, used for evas_object_size_hint_aspect_set() */
typedef struct _Evas_Pixel_Import_Source Evas_Pixel_Import_Source; /**< A source description of pixels for importing pixels */
-typedef struct _Evas_Engine_Info Evas_Engine_Info; /**< A generic Evas Engine information structure */
-typedef struct _Evas_Device Evas_Device; /**< A source device handle - where the event came from */
-typedef struct _Evas_Event_Mouse_Down Evas_Event_Mouse_Down; /**< Event structure for #EVAS_CALLBACK_MOUSE_DOWN event callbacks */
-typedef struct _Evas_Event_Mouse_Up Evas_Event_Mouse_Up; /**< Event structure for #EVAS_CALLBACK_MOUSE_UP event callbacks */
-typedef struct _Evas_Event_Mouse_In Evas_Event_Mouse_In; /**< Event structure for #EVAS_CALLBACK_MOUSE_IN event callbacks */
-typedef struct _Evas_Event_Mouse_Out Evas_Event_Mouse_Out; /**< Event structure for #EVAS_CALLBACK_MOUSE_OUT event callbacks */
-typedef struct _Evas_Event_Mouse_Move Evas_Event_Mouse_Move; /**< Event structure for #EVAS_CALLBACK_MOUSE_MOVE event callbacks */
-typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel; /**< Event structure for #EVAS_CALLBACK_MOUSE_WHEEL event callbacks */
-typedef struct _Evas_Event_Multi_Down Evas_Event_Multi_Down; /**< Event structure for #EVAS_CALLBACK_MULTI_DOWN event callbacks */
-typedef struct _Evas_Event_Multi_Up Evas_Event_Multi_Up; /**< Event structure for #EVAS_CALLBACK_MULTI_UP event callbacks */
-typedef struct _Evas_Event_Multi_Move Evas_Event_Multi_Move; /**< Event structure for #EVAS_CALLBACK_MULTI_MOVE event callbacks */
-typedef struct _Evas_Event_Key_Down Evas_Event_Key_Down; /**< Event structure for #EVAS_CALLBACK_KEY_DOWN event callbacks */
-typedef struct _Evas_Event_Key_Up Evas_Event_Key_Up; /**< Event structure for #EVAS_CALLBACK_KEY_UP event callbacks */
-typedef struct _Evas_Event_Hold Evas_Event_Hold; /**< Event structure for #EVAS_CALLBACK_HOLD event callbacks */
+typedef struct _Evas_Engine_Info Evas_Engine_Info; /**< A generic Evas Engine information structure */
+typedef struct _Evas_Device Evas_Device; /**< A source device handle - where the event came from */
+typedef struct _Evas_Event_Mouse_Down Evas_Event_Mouse_Down; /**< Event structure for #EVAS_CALLBACK_MOUSE_DOWN event callbacks */
+typedef struct _Evas_Event_Mouse_Up Evas_Event_Mouse_Up; /**< Event structure for #EVAS_CALLBACK_MOUSE_UP event callbacks */
+typedef struct _Evas_Event_Mouse_In Evas_Event_Mouse_In; /**< Event structure for #EVAS_CALLBACK_MOUSE_IN event callbacks */
+typedef struct _Evas_Event_Mouse_Out Evas_Event_Mouse_Out; /**< Event structure for #EVAS_CALLBACK_MOUSE_OUT event callbacks */
+typedef struct _Evas_Event_Mouse_Move Evas_Event_Mouse_Move; /**< Event structure for #EVAS_CALLBACK_MOUSE_MOVE event callbacks */
+typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel; /**< Event structure for #EVAS_CALLBACK_MOUSE_WHEEL event callbacks */
+typedef struct _Evas_Event_Multi_Down Evas_Event_Multi_Down; /**< Event structure for #EVAS_CALLBACK_MULTI_DOWN event callbacks */
+typedef struct _Evas_Event_Multi_Up Evas_Event_Multi_Up; /**< Event structure for #EVAS_CALLBACK_MULTI_UP event callbacks */
+typedef struct _Evas_Event_Multi_Move Evas_Event_Multi_Move; /**< Event structure for #EVAS_CALLBACK_MULTI_MOVE event callbacks */
+typedef struct _Evas_Event_Key_Down Evas_Event_Key_Down; /**< Event structure for #EVAS_CALLBACK_KEY_DOWN event callbacks */
+typedef struct _Evas_Event_Key_Up Evas_Event_Key_Up; /**< Event structure for #EVAS_CALLBACK_KEY_UP event callbacks */
+typedef struct _Evas_Event_Hold Evas_Event_Hold; /**< Event structure for #EVAS_CALLBACK_HOLD event callbacks */
typedef enum _Evas_Load_Error
{
EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */
} Evas_Load_Error; /**< Evas image load error codes one can get - see evas_load_error_str() too. */
-
typedef enum _Evas_Alloc_Error
{
EVAS_ALLOC_ERROR_NONE = 0, /**< No allocation error */
struct _Evas_Pixel_Import_Source
{
Evas_Pixel_Import_Pixel_Format format; /**< pixel format type ie ARGB32, YUV420P_601 etc. */
- int w, h; /**< width and height of source in pixels */
- void **rows; /**< an array of pointers (size depends on format) pointing to left edge of each scanline */
+ int w, h; /**< width and height of source in pixels */
+ void **rows; /**< an array of pointers (size depends on format) pointing to left edge of each scanline */
};
/* magic version number to know what the native surf struct looks like */
struct _Evas_Native_Surface
{
- int version;
- Evas_Native_Surface_Type type;
+ int version;
+ Evas_Native_Surface_Type type;
union {
- struct {
- void *visual; /**< visual of the pixmap to use (Visual) */
- unsigned long pixmap; /**< pixmap id to use (Pixmap) */
- } x11;
- struct {
- unsigned int texture_id; /**< opengl texture id to use from glGenTextures() */
- unsigned int framebuffer_id; /**< 0 if not a FBO, FBO id otherwise from glGenFramebuffers() */
- unsigned int internal_format; /**< same as 'internalFormat' for glTexImage2D() */
- unsigned int format; /**< same as 'format' for glTexImage2D() */
- unsigned int x, y, w, h; /**< region inside the texture to use (image size is assumed as texture size, with 0, 0 being the top-left and co-ordinates working down to the right and bottom being positive) */
- } opengl;
+ struct
+ {
+ void *visual; /**< visual of the pixmap to use (Visual) */
+ unsigned long pixmap; /**< pixmap id to use (Pixmap) */
+ } x11;
+ struct
+ {
+ unsigned int texture_id; /**< opengl texture id to use from glGenTextures() */
+ unsigned int framebuffer_id; /**< 0 if not a FBO, FBO id otherwise from glGenFramebuffers() */
+ unsigned int internal_format; /**< same as 'internalFormat' for glTexImage2D() */
+ unsigned int format; /**< same as 'format' for glTexImage2D() */
+ unsigned int x, y, w, h; /**< region inside the texture to use (image size is assumed as texture size, with 0, 0 being the top-left and co-ordinates working down to the right and bottom being positive) */
+ } opengl;
} data;
};
struct _Evas_Video_Surface
{
- int version;
+ int version;
Evas_Video_Coord_Cb move; /**< Move the video surface to this position */
Evas_Video_Coord_Cb resize; /**< Resize the video surface to that size */
- Evas_Video_Cb show; /**< Show the video overlay surface */
- Evas_Video_Cb hide; /**< Hide the video overlay surface */
- Evas_Video_Cb update_pixels; /**< Please update the Evas_Object_Image pixels when called */
+ Evas_Video_Cb show; /**< Show the video overlay surface */
+ Evas_Video_Cb hide; /**< Hide the video overlay surface */
+ Evas_Video_Cb update_pixels; /**< Please update the Evas_Object_Image pixels when called */
- Evas_Object *parent;
- void *data;
+ Evas_Object *parent;
+ void *data;
};
-#define EVAS_LAYER_MIN -32768 /**< bottom-most layer number */
-#define EVAS_LAYER_MAX 32767 /**< top-most layer number */
+#define EVAS_LAYER_MIN -32768 /**< bottom-most layer number */
+#define EVAS_LAYER_MAX 32767 /**< top-most layer number */
-#define EVAS_COLOR_SPACE_ARGB 0 /**< Not used for anything */
-#define EVAS_COLOR_SPACE_AHSV 1 /**< Not used for anything */
-#define EVAS_TEXT_INVALID -1 /**< Not used for anything */
-#define EVAS_TEXT_SPECIAL -2 /**< Not used for anything */
+#define EVAS_COLOR_SPACE_ARGB 0 /**< Not used for anything */
+#define EVAS_COLOR_SPACE_AHSV 1 /**< Not used for anything */
+#define EVAS_TEXT_INVALID -1 /**< Not used for anything */
+#define EVAS_TEXT_SPECIAL -2 /**< Not used for anything */
-#define EVAS_HINT_EXPAND 1.0 /**< Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hint_expand_set(), evas_object_size_hint_expand_get() */
-#define EVAS_HINT_FILL -1.0 /**< Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_fill_set(), evas_object_size_hint_fill_get() */
-#define evas_object_size_hint_fill_set evas_object_size_hint_align_set /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
-#define evas_object_size_hint_fill_get evas_object_size_hint_align_get /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
+#define EVAS_HINT_EXPAND 1.0 /**< Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hint_expand_set(), evas_object_size_hint_expand_get() */
+#define EVAS_HINT_FILL -1.0 /**< Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_fill_set(), evas_object_size_hint_fill_get() */
+#define evas_object_size_hint_fill_set evas_object_size_hint_align_set /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
+#define evas_object_size_hint_fill_get evas_object_size_hint_align_get /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
#define evas_object_size_hint_expand_set evas_object_size_hint_weight_set /**< Convenience macro to make it easier to understand that weight is also used for expand properties */
#define evas_object_size_hint_expand_get evas_object_size_hint_weight_get /**< Convenience macro to make it easier to understand that weight is also used for expand properties */
struct _Evas_Event_Mouse_Down /** Mouse button press event */
{
- int button; /**< Mouse button number that went down (1 - 32) */
+ int button; /**< Mouse button number that went down (1 - 32) */
- Evas_Point output; /**< The X/Y location of the cursor */
- Evas_Coord_Point canvas; /**< The X/Y location of the cursor */
+ Evas_Point output; /**< The X/Y location of the cursor */
+ Evas_Coord_Point canvas; /**< The X/Y location of the cursor */
- void *data;
- Evas_Modifier *modifiers; /**< modifier keys pressed during the event */
- Evas_Lock *locks;
+ void *data;
+ Evas_Modifier *modifiers; /**< modifier keys pressed during the event */
+ Evas_Lock *locks;
Evas_Button_Flags flags; /**< button flags set during the event */
unsigned int timestamp;
struct _Evas_Event_Mouse_Up /** Mouse button release event */
{
- int button; /**< Mouse button number that was raised (1 - 32) */
+ int button; /**< Mouse button number that was raised (1 - 32) */
- Evas_Point output;
- Evas_Coord_Point canvas;
+ Evas_Point output;
+ Evas_Coord_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
Evas_Button_Flags flags;
unsigned int timestamp;
struct _Evas_Event_Mouse_In /** Mouse enter event */
{
- int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
+ int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
- Evas_Point output;
+ Evas_Point output;
Evas_Coord_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Mouse_Out /** Mouse leave event */
{
- int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
-
+ int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
- Evas_Point output;
+ Evas_Point output;
Evas_Coord_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Mouse_Move /** Mouse button down event */
{
- int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
+ int buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
- Evas_Position cur, prev;
+ Evas_Position cur, prev;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Mouse_Wheel /** Wheel event */
{
- int direction; /* 0 = default up/down wheel FIXME: more wheel types */
- int z; /* ...,-2,-1 = down, 1,2,... = up */
+ int direction; /* 0 = default up/down wheel FIXME: more wheel types */
+ int z; /* ...,-2,-1 = down, 1,2,... = up */
- Evas_Point output;
+ Evas_Point output;
Evas_Coord_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Multi_Down /** Multi button press event */
{
- int device; /**< Multi device number that went down (1 or more for extra touches) */
- double radius, radius_x, radius_y;
- double pressure, angle;
+ int device; /**< Multi device number that went down (1 or more for extra touches) */
+ double radius, radius_x, radius_y;
+ double pressure, angle;
- Evas_Point output;
+ Evas_Point output;
Evas_Coord_Precision_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
- Evas_Button_Flags flags;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ Evas_Button_Flags flags;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Multi_Up /** Multi button release event */
{
- int device; /**< Multi device number that went up (1 or more for extra touches) */
- double radius, radius_x, radius_y;
- double pressure, angle;
+ int device; /**< Multi device number that went up (1 or more for extra touches) */
+ double radius, radius_x, radius_y;
+ double pressure, angle;
- Evas_Point output;
+ Evas_Point output;
Evas_Coord_Precision_Point canvas;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
- Evas_Button_Flags flags;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ Evas_Button_Flags flags;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Multi_Move /** Multi button down event */
{
- int device; /**< Multi device number that moved (1 or more for extra touches) */
- double radius, radius_x, radius_y;
- double pressure, angle;
+ int device; /**< Multi device number that moved (1 or more for extra touches) */
+ double radius, radius_x, radius_y;
+ double pressure, angle;
Evas_Precision_Position cur;
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Key_Down /** Key press event */
{
- char *keyname; /**< the name string of the key pressed */
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
-
- const char *key; /**< The logical key : (eg shift+1 == exclamation) */
- const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
- const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ char *keyname; /**< the name string of the key pressed */
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+
+ const char *key; /**< The logical key : (eg shift+1 == exclamation) */
+ const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
+ const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Key_Up /** Key release event */
{
- char *keyname; /**< the name string of the key released */
- void *data;
- Evas_Modifier *modifiers;
- Evas_Lock *locks;
-
- const char *key; /**< The logical key : (eg shift+1 == exclamation) */
- const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
- const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ char *keyname; /**< the name string of the key released */
+ void *data;
+ Evas_Modifier *modifiers;
+ Evas_Lock *locks;
+
+ const char *key; /**< The logical key : (eg shift+1 == exclamation) */
+ const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
+ const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
struct _Evas_Event_Hold /** Hold change event */
{
- int hold; /**< The hold flag */
- void *data;
+ int hold; /**< The hold flag */
+ void *data;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
- Evas_Device *dev;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+ Evas_Device *dev;
};
/**
EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN /**< useful on object with "repeat events" enabled, where mouse/touch up and down events WONT be repeated to objects and these objects wont be auto-grabbed. @since 1.2 */
} Evas_Object_Pointer_Mode; /**< How the mouse pointer should be handled by Evas. */
-typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info); /**< Evas smart objects' "smart callback" function signature */
-typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info); /**< Evas event callback function signature */
-typedef Eina_Bool (*Evas_Object_Event_Post_Cb) (void *data, Evas *e);
-typedef void (*Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info); /**< Evas object event callback function signature */
+typedef void (*Evas_Smart_Cb)(void *data, Evas_Object *obj, void *event_info); /**< Evas smart objects' "smart callback" function signature */
+typedef void (*Evas_Event_Cb)(void *data, Evas *e, void *event_info); /**< Evas event callback function signature */
+typedef Eina_Bool (*Evas_Object_Event_Post_Cb)(void *data, Evas *e);
+typedef void (*Evas_Object_Event_Cb)(void *data, Evas *e, Evas_Object *obj, void *event_info); /**< Evas object event callback function signature */
typedef void (*Evas_Async_Events_Put_Cb)(void *target, Evas_Callback_Type type, void *event_info);
/**
*
* @ingroup Evas_Group
*/
-EAPI int evas_init (void);
+EAPI int evas_init(void);
/**
* Shutdown Evas
*
* @ingroup Evas_Group
*/
-EAPI int evas_shutdown (void);
-
+EAPI int evas_shutdown(void);
/**
* Return if any allocation errors have occurred during the prior function
*
* @ingroup Evas_Group
*/
-EAPI Evas_Alloc_Error evas_alloc_error (void);
-
+EAPI Evas_Alloc_Error evas_alloc_error(void);
/**
* @brief Get evas' internal asynchronous events read file descriptor.
*
* @ingroup Evas_Group
*/
-EAPI int evas_async_events_fd_get (void) EINA_WARN_UNUSED_RESULT;
+EAPI int evas_async_events_fd_get(void) EINA_WARN_UNUSED_RESULT;
/**
* @brief Trigger the processing of all events waiting on the file
*
* @ingroup Evas_Group
*/
-EAPI int evas_async_events_process (void);
+EAPI int evas_async_events_process(void);
/**
-* Insert asynchronous events on the canvas.
+ * Insert asynchronous events on the canvas.
*
* @param target The target to be affected by the events.
* @param type The type of callback function.
*
* @ingroup Evas_Group
*/
-EAPI Eina_Bool evas_async_events_put (const void *target, Evas_Callback_Type type, void *event_info, Evas_Async_Events_Put_Cb func) EINA_ARG_NONNULL(1, 4);
+EAPI Eina_Bool evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, Evas_Async_Events_Put_Cb func) EINA_ARG_NONNULL(1, 4);
/**
* @defgroup Evas_Canvas Canvas Functions
* @return A new uninitialised Evas canvas on success. Otherwise, @c NULL.
* @ingroup Evas_Canvas
*/
-EAPI Evas *evas_new (void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+EAPI Evas *evas_new(void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
/**
* Frees the given evas and any objects created on it.
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_free (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_free(Evas *e) EINA_ARG_NONNULL(1);
/**
* Inform to the evas that it got the focus.
* @param e The evas to change information.
* @ingroup Evas_Canvas
*/
-EAPI void evas_focus_in (Evas *e);
+EAPI void evas_focus_in(Evas *e);
/**
* Inform to the evas that it lost the focus.
* @param e The evas to change information.
* @ingroup Evas_Canvas
*/
-EAPI void evas_focus_out (Evas *e);
+EAPI void evas_focus_out(Evas *e);
/**
* Get the focus state known by the given evas
* @param e The evas to query information.
* @ingroup Evas_Canvas
*/
-EAPI Eina_Bool evas_focus_state_get (const Evas *e);
+EAPI Eina_Bool evas_focus_state_get(const Evas *e);
/**
* Push the nochange flag up 1
* @param e The evas to change information.
* @ingroup Evas_Canvas
*/
-EAPI void evas_nochange_push (Evas *e);
+EAPI void evas_nochange_push(Evas *e);
/**
* Pop the nochange flag down 1
* @param e The evas to change information.
* @ingroup Evas_Canvas
*/
-EAPI void evas_nochange_pop (Evas *e);
-
+EAPI void evas_nochange_pop(Evas *e);
/**
* Attaches a specific pointer to the evas for fetching later
* @param data The pointer to attach
* @ingroup Evas_Canvas
*/
-EAPI void evas_data_attach_set (Evas *e, void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_data_attach_set(Evas *e, void *data) EINA_ARG_NONNULL(1);
/**
* Returns the pointer attached by evas_data_attach_set()
* @return The pointer attached
* @ingroup Evas_Canvas
*/
-EAPI void *evas_data_attach_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI void *evas_data_attach_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Add a damage rectangle.
* This is the function by which one tells evas that a part of the
* canvas has to be repainted.
*
+ * @note All newly created Evas rectangles get the default color values of 255 255 255 255 (opaque white).
+ *
* @ingroup Evas_Canvas
*/
-EAPI void evas_damage_rectangle_add (Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
/**
* Add an "obscured region" to an Evas canvas.
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_obscured_rectangle_add (Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
/**
* Remove all "obscured regions" from an Evas canvas.
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_obscured_clear (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_obscured_clear(Evas *e) EINA_ARG_NONNULL(1);
/**
* Force immediate renderization of the given Evas canvas.
*
* @ingroup Evas_Canvas
*/
-EAPI Eina_List *evas_render_updates (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_List *evas_render_updates(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Free the rectangles returned by evas_render_updates().
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_render_updates_free (Eina_List *updates);
+EAPI void evas_render_updates_free(Eina_List *updates);
/**
* Force renderization of the given canvas.
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_render (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_render(Evas *e) EINA_ARG_NONNULL(1);
/**
* Update the canvas internal objects but not triggering immediate
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_norender (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_norender(Evas *e) EINA_ARG_NONNULL(1);
/**
* Make the canvas discard internally cached data used for rendering.
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_render_idle_flush (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_render_idle_flush(Evas *e) EINA_ARG_NONNULL(1);
/**
* Make the canvas discard as much data as possible used by the engine at
*
* @ingroup Evas_Canvas
*/
-EAPI void evas_render_dump (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_render_dump(Evas *e) EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Output_Method Render Engine Functions
* evas_output_method_set(evas, engine_id);
* @endcode
*/
-EAPI int evas_render_method_lookup (const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_render_method_lookup(const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* List all the rendering engines compiled into the copy of the Evas library
* evas_render_method_list_free(engine_list);
* @endcode
*/
-EAPI Eina_List *evas_render_method_list (void) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_List *evas_render_method_list(void) EINA_WARN_UNUSED_RESULT;
/**
* This function should be called to free a list of engine names
* evas_render_method_list_free(engine_list);
* @endcode
*/
-EAPI void evas_render_method_list_free (Eina_List *list);
-
+EAPI void evas_render_method_list_free(Eina_List *list);
/**
* Sets the output engine for the given evas.
*
* @ingroup Evas_Output_Method
*/
-EAPI void evas_output_method_set (Evas *e, int render_method) EINA_ARG_NONNULL(1);
+EAPI void evas_output_method_set(Evas *e, int render_method) EINA_ARG_NONNULL(1);
/**
* Retrieves the number of the output engine used for the given evas.
* returned if there is an error.
* @ingroup Evas_Output_Method
*/
-EAPI int evas_output_method_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI int evas_output_method_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieves the current render engine info struct from the given evas.
* an engine has not yet been assigned.
* @ingroup Evas_Output_Method
*/
-EAPI Evas_Engine_Info *evas_engine_info_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Engine_Info *evas_engine_info_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Applies the engine settings for the given evas from the given @c
* @return @c EINA_TRUE if no error occurred, @c EINA_FALSE otherwise.
* @ingroup Evas_Output_Method
*/
-EAPI Eina_Bool evas_engine_info_set (Evas *e, Evas_Engine_Info *info) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_engine_info_set(Evas *e, Evas_Engine_Info *info) EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Output_Size Output and Viewport Resizing Functions
* @param h The height in output units, usually pixels.
* @ingroup Evas_Output_Size
*/
-EAPI void evas_output_size_set (Evas *e, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_output_size_set(Evas *e, int w, int h) EINA_ARG_NONNULL(1);
/**
* Retrieve the output size of the render engine of the given evas.
* @param h The pointer to an integer to store the height in.
* @ingroup Evas_Output_Size
*/
-EAPI void evas_output_size_get (const Evas *e, int *w, int *h) EINA_ARG_NONNULL(1);
+EAPI void evas_output_size_get(const Evas *e, int *w, int *h) EINA_ARG_NONNULL(1);
/**
* Sets the output viewport of the given evas in evas units.
* @param h The height of the viewport. Must be greater than 0.
* @ingroup Evas_Output_Size
*/
-EAPI void evas_output_viewport_set (Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_output_viewport_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Get the render engine's output viewport co-ordinates in canvas units.
* evas_output_viewport_get(evas, &x, &y, &w, &h);
* @endcode
*/
-EAPI void evas_output_viewport_get (const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_output_viewport_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the output framespace size of the render engine of the given evas.
*
- * The framespace size is used in the Wayland engines to denote space where
+ * The framespace size is used in the Wayland engines to denote space where
* the output is not drawn. This is mainly used in ecore_evas to draw borders
*
* The units used for @p w and @p h depend on the engine used by the
* @ingroup Evas_Output_Size
* @since 1.1.0
*/
-EAPI void evas_output_framespace_set (Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+EAPI void evas_output_framespace_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
/**
* Get the render engine's output framespace co-ordinates in canvas units.
- *
+ *
* @param e The pointer to the Evas Canvas
* @param x The pointer to a x variable to be filled in
* @param y The pointer to a y variable to be filled in
* @ingroup Evas_Output_Size
* @since 1.1.0
*/
-EAPI void evas_output_framespace_get (const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+EAPI void evas_output_framespace_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
/**
* @defgroup Evas_Coord_Mapping_Group Coordinate Mapping Functions
* canvas_x = evas_coord_screen_x_to_world(evas, screen_x);
* @endcode
*/
-EAPI Evas_Coord evas_coord_screen_x_to_world (const Evas *e, int x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_coord_screen_x_to_world(const Evas *e, int x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Convert/scale an ouput screen co-ordinate into canvas co-ordinates
* canvas_y = evas_coord_screen_y_to_world(evas, screen_y);
* @endcode
*/
-EAPI Evas_Coord evas_coord_screen_y_to_world (const Evas *e, int y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_coord_screen_y_to_world(const Evas *e, int y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Convert/scale a canvas co-ordinate into output screen co-ordinates
* screen_x = evas_coord_world_x_to_screen(evas, canvas_x);
* @endcode
*/
-EAPI int evas_coord_world_x_to_screen (const Evas *e, Evas_Coord x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_coord_world_x_to_screen(const Evas *e, Evas_Coord x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Convert/scale a canvas co-ordinate into output screen co-ordinates
* screen_y = evas_coord_world_y_to_screen(evas, canvas_y);
* @endcode
*/
-EAPI int evas_coord_world_y_to_screen (const Evas *e, Evas_Coord y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_coord_world_y_to_screen(const Evas *e, Evas_Coord y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Pointer_Group Pointer (Mouse) Functions
* printf("Mouse is at screen position %i, %i\n", mouse_x, mouse_y);
* @endcode
*/
-EAPI void evas_pointer_output_xy_get (const Evas *e, int *x, int *y) EINA_ARG_NONNULL(1);
+EAPI void evas_pointer_output_xy_get(const Evas *e, int *x, int *y) EINA_ARG_NONNULL(1);
/**
* This function returns the current known pointer co-ordinates
* printf("Mouse is at canvas position %f, %f\n", mouse_x, mouse_y);
* @endcode
*/
-EAPI void evas_pointer_canvas_xy_get (const Evas *e, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1);
+EAPI void evas_pointer_canvas_xy_get(const Evas *e, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1);
/**
* Returns a bitmask with the mouse buttons currently pressed, set to 1
* }
* @endcode
*/
-EAPI int evas_pointer_button_down_mask_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_pointer_button_down_mask_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Returns whether the mouse pointer is logically inside the canvas
* else printf("Mouse is out!\n");
* @endcode
*/
-EAPI Eina_Bool evas_pointer_inside_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI void evas_sync(Evas *e) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_pointer_inside_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI void evas_sync(Evas *e) EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Canvas_Events Canvas Events
* it more than once on the event, in this case). This would make
* sense if you passed different functions and/or callback data, only.
*/
-EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
+EAPI void evas_event_callback_add(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Add (register) a callback function to a given canvas event with a
* @see evas_event_callback_add
* @since 1.1.0
*/
-EAPI void evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
+EAPI void evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
/**
* Delete a callback function from the canvas.
* my_data = evas_event_callback_del(ebject, EVAS_CALLBACK_CANVAS_FOCUS_IN, focus_in_callback);
* @endcode
*/
-EAPI void *evas_event_callback_del (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
+EAPI void *evas_event_callback_del(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
/**
* Delete (unregister) a callback function registered to a given
* @note For deletion of canvas events callbacks filtering by just
* type and function pointer, user evas_event_callback_del().
*/
-EAPI void *evas_event_callback_del_full (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
+EAPI void *evas_event_callback_del_full(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Push a callback on the post-event callback stack
* actually does the action).
*
*/
-EAPI void evas_post_event_callback_push (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
+EAPI void evas_post_event_callback_push(Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
/**
* Remove a callback from the post-event callback stack
* the callback stack is removed from being executed when the stack is
* unwound. Further instances may still be run on unwind.
*/
-EAPI void evas_post_event_callback_remove (Evas *e, Evas_Object_Event_Post_Cb func);
+EAPI void evas_post_event_callback_remove(Evas *e, Evas_Object_Event_Post_Cb func);
/**
* Remove a callback from the post-event callback stack
* in the callback stack is removed from being executed when the stack is
* unwound. Further instances may still be run on unwind.
*/
-EAPI void evas_post_event_callback_remove_full (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
+EAPI void evas_post_event_callback_remove_full(Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
/**
* @defgroup Evas_Event_Freezing_Group Input Events Freezing Functions
/**
* Set the default set of flags an event begins with
- *
+ *
* @param e The canvas to set the default event flags of
* @param flags The default flags to use
- *
+ *
* Events in evas can have an event_flags member. This starts out with
* and initial value (no flags). this lets you set the default flags that
* an event begins with to be @p flags
- *
+ *
* @since 1.2
*/
-EAPI void evas_event_default_flags_set (Evas *e, Evas_Event_Flags flags) EINA_ARG_NONNULL(1);
+EAPI void evas_event_default_flags_set(Evas *e, Evas_Event_Flags flags) EINA_ARG_NONNULL(1);
/**
* Get the defaulty set of flags an event begins with
- *
+ *
* @param e The canvas to get the default event flags from
* @return The default event flags for that canvas
- *
+ *
* This gets the default event flags events are produced with when fed in.
- *
+ *
* @see evas_event_default_flags_set()
* @since 1.2
*/
-EAPI Evas_Event_Flags evas_event_default_flags_get (const Evas *e) EINA_ARG_NONNULL(1);
+EAPI Evas_Event_Flags evas_event_default_flags_get(const Evas *e) EINA_ARG_NONNULL(1);
/**
* Freeze all input events processing.
* realistic code we would be freezing while a toolkit or Edje was
* doing some UI changes, thawing it back afterwards.
*/
-EAPI void evas_event_freeze (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_event_freeze(Evas *e) EINA_ARG_NONNULL(1);
/**
* Thaw a canvas out after freezing (for input events).
*
* See evas_event_freeze() for an example.
*/
-EAPI void evas_event_thaw (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_event_thaw(Evas *e) EINA_ARG_NONNULL(1);
/**
* Return the freeze count on input events of a given canvas.
* @endcode
*
*/
-EAPI int evas_event_freeze_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_event_freeze_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* After thaw of a canvas, re-evaluate the state of objects and call callbacks
* containment and other states and thus also call callbacks for mouse in and
* out on new objects if the state change demands it.
*/
-EAPI void evas_event_thaw_eval (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_event_thaw_eval(Evas *e) EINA_ARG_NONNULL(1);
/**
* @}
*
* @since 1.2
*/
-EAPI int evas_event_down_count_get (const Evas *e) EINA_ARG_NONNULL(1);
+EAPI int evas_event_down_count_get(const Evas *e) EINA_ARG_NONNULL(1);
/**
* Mouse down event feed.
* by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_down (Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Mouse up event feed.
* by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_up (Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Mouse move event feed.
* to be treated by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_move (Evas *e, int x, int y, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Mouse in event feed.
* by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_in (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Mouse out event feed.
* by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_out (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
- EAPI void evas_event_feed_multi_down (Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
- EAPI void evas_event_feed_multi_up (Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
- EAPI void evas_event_feed_multi_move (Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data);
+EAPI void evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_multi_down(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+EAPI void evas_event_feed_multi_up(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+EAPI void evas_event_feed_multi_move(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data);
/**
* Mouse cancel event feed.
* mouse cancel event happens.
*
*/
-EAPI void evas_event_feed_mouse_cancel (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_cancel(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Mouse wheel event feed.
* be treated by the callback function.
*
*/
-EAPI void evas_event_feed_mouse_wheel (Evas *e, int direction, int z, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Key down event feed
* callback function.
*
*/
-EAPI void evas_event_feed_key_down (Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Key up event feed
* callback function.
*
*/
-EAPI void evas_event_feed_key_up (Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Hold event feed
* This function makes the object to stop sending events.
*
*/
-EAPI void evas_event_feed_hold (Evas *e, int hold, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
/**
* Re feed event.
* This function call evas_event_feed_* functions, so it can
* cause havoc if not used wisely. Please use it responsibly.
*/
-EAPI void evas_event_refeed_event (Evas *e, void *event_copy, Evas_Callback_Type event_type) EINA_ARG_NONNULL(1);
-
+EAPI void evas_event_refeed_event(Evas *e, void *event_copy, Evas_Callback_Type event_type) EINA_ARG_NONNULL(1);
/**
* @}
* This function flushes image cache of canvas.
*
*/
-EAPI void evas_image_cache_flush (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_image_cache_flush(Evas *e) EINA_ARG_NONNULL(1);
/**
* Reload the image cache
* This function reloads the image cache of canvas.
*
*/
-EAPI void evas_image_cache_reload (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_image_cache_reload(Evas *e) EINA_ARG_NONNULL(1);
/**
* Set the image cache.
* This function sets the image cache of canvas in bytes.
*
*/
-EAPI void evas_image_cache_set (Evas *e, int size) EINA_ARG_NONNULL(1);
+EAPI void evas_image_cache_set(Evas *e, int size) EINA_ARG_NONNULL(1);
/**
* Get the image cache
* This function returns the image cache size of canvas in bytes.
*
*/
-EAPI int evas_image_cache_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_image_cache_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the maximum image size evas can possibly handle
* @param maxh Pointer to hold the return value in pixels of the maximum height
*
* This function returns the larges image or surface size that evas can handle
- * in pixels, and if there is one, returns @c EINA_TRUE. It returns
+ * in pixels, and if there is one, returns @c EINA_TRUE. It returns
* @c EINA_FALSE if no extra constraint on maximum image size exists. You still
* should check the return values of @p maxw and @p maxh as there may still be
* a limit, just a much higher one.
*
* @since 1.1
*/
-EAPI Eina_Bool evas_image_max_size_get (const Evas *e, int *maxw, int *maxh) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_image_max_size_get(const Evas *e, int *maxw, int *maxh) EINA_ARG_NONNULL(1);
/**
* @}
* #EVAS_FONT_HINTING_AUTO, #EVAS_FONT_HINTING_BYTECODE.
* @ingroup Evas_Font_Group
*/
-EAPI void evas_font_hinting_set (Evas *e, Evas_Font_Hinting_Flags hinting) EINA_ARG_NONNULL(1);
+EAPI void evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting) EINA_ARG_NONNULL(1);
/**
* Retrieves the font hinting used by the given evas.
* #EVAS_FONT_HINTING_AUTO, #EVAS_FONT_HINTING_BYTECODE.
* @ingroup Evas_Font_Group
*/
-EAPI Evas_Font_Hinting_Flags evas_font_hinting_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Font_Hinting_Flags evas_font_hinting_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Checks if the font hinting is supported by the given evas.
* @return @c EINA_TRUE if it is supported, @c EINA_FALSE otherwise.
* @ingroup Evas_Font_Group
*/
-EAPI Eina_Bool evas_font_hinting_can_hint (const Evas *e, Evas_Font_Hinting_Flags hinting) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_font_hinting_can_hint(const Evas *e, Evas_Font_Hinting_Flags hinting) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Force the given evas and associated engine to flush its font cache.
* @param e The given evas to flush font cache.
* @ingroup Evas_Font_Group
*/
-EAPI void evas_font_cache_flush (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_font_cache_flush(Evas *e) EINA_ARG_NONNULL(1);
/**
* Changes the size of font cache of the given evas.
*
* @ingroup Evas_Font_Group
*/
-EAPI void evas_font_cache_set (Evas *e, int size) EINA_ARG_NONNULL(1);
+EAPI void evas_font_cache_set(Evas *e, int size) EINA_ARG_NONNULL(1);
/**
* Changes the size of font cache of the given evas.
*
* @ingroup Evas_Font_Group
*/
-EAPI int evas_font_cache_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI int evas_font_cache_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* List of available font descriptions known or found by this evas.
*
* @ingroup Evas_Font_Group
*/
-EAPI Eina_List *evas_font_available_list (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_List *evas_font_available_list(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Free list of font descriptions returned by evas_font_dir_available_list().
*
* @ingroup Evas_Font_Group
*/
-EAPI void evas_font_available_list_free(Evas *e, Eina_List *available) EINA_ARG_NONNULL(1);
+EAPI void evas_font_available_list_free(Evas *e, Eina_List *available) EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Font_Path_Group Font Path Functions
* @param e The given evas.
* @ingroup Evas_Font_Path_Group
*/
-EAPI void evas_font_path_clear (Evas *e) EINA_ARG_NONNULL(1);
+EAPI void evas_font_path_clear(Evas *e) EINA_ARG_NONNULL(1);
/**
* Appends a font path to the list of font paths used by the given evas.
* @param path The new font path.
* @ingroup Evas_Font_Path_Group
*/
-EAPI void evas_font_path_append (Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_font_path_append(Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
/**
* Prepends a font path to the list of font paths used by the given evas.
* @param path The new font path.
* @ingroup Evas_Font_Path_Group
*/
-EAPI void evas_font_path_prepend (Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_font_path_prepend(Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
/**
* Retrieves the list of font paths used by the given evas.
* @return The list of font paths used.
* @ingroup Evas_Font_Path_Group
*/
-EAPI const Eina_List *evas_font_path_list (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const Eina_List *evas_font_path_list(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Object_Group Generic Object Functions
*
* See the full @ref Example_Evas_Object_Manipulation "example".
*/
-EAPI void evas_object_clip_set (Evas_Object *obj, Evas_Object *clip) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_clip_set(Evas_Object *obj, Evas_Object *clip) EINA_ARG_NONNULL(1, 2);
/**
* Get the object clipping @p obj (if any).
*
* See the full @ref Example_Evas_Object_Manipulation "example".
*/
-EAPI Evas_Object *evas_object_clip_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_clip_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Disable/cease clipping on a clipped @p obj object.
* evas_object_clipees_get() and evas_object_clip_get().
*
*/
-EAPI void evas_object_clip_unset (Evas_Object *obj);
+EAPI void evas_object_clip_unset(Evas_Object *obj);
/**
* Return a list of objects currently clipped by @p obj.
* }
* @endcode
*/
-EAPI const Eina_List *evas_object_clipees_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI const Eina_List *evas_object_clipees_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets or unsets a given object as the currently focused one on its
*
* Changing focus only affects where (key) input events go. There can
* be only one object focused at any time. If @p focus is @c EINA_TRUE,
- * @p obj will be set as the currently focused object and it will
- * receive all keyboard events that are not exclusive key grabs on
+ * @p obj will be set as the currently focused object and it will
+ * receive all keyboard events that are not exclusive key grabs on
* other objects.
*
* Example:
* @see evas_object_key_grab
* @see evas_object_key_ungrab
*/
-EAPI void evas_object_focus_set (Evas_Object *obj, Eina_Bool focus) EINA_ARG_NONNULL(1);
+EAPI void evas_object_focus_set(Evas_Object *obj, Eina_Bool focus) EINA_ARG_NONNULL(1);
/**
* Retrieve whether an object has the focus.
* @see evas_object_key_grab
* @see evas_object_key_ungrab
*/
-EAPI Eina_Bool evas_object_focus_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_object_focus_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
- * Sets the layer of the its canvas that the given object will be part
- * of.
+ * Sets the layer of its canvas that the given object will be part of.
*
* @param obj The given Evas object.
* @param l The number of the layer to place the object on.
*
* @see evas_object_layer_get()
*/
-EAPI void evas_object_layer_set (Evas_Object *obj, short l) EINA_ARG_NONNULL(1);
+EAPI void evas_object_layer_set(Evas_Object *obj, short l) EINA_ARG_NONNULL(1);
/**
* Retrieves the layer of its canvas that the given object is part of.
*
* @param obj The given Evas object to query layer from
- * @return Number of the its layer
+ * @return Number of its layer
*
* @see evas_object_layer_set()
*/
-EAPI short evas_object_layer_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI short evas_object_layer_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the name of the given Evas object to the given name.
*
* See the full @ref Example_Evas_Events "example".
*/
-EAPI void evas_object_name_set (Evas_Object *obj, const char *name) EINA_ARG_NONNULL(1);
+EAPI void evas_object_name_set(Evas_Object *obj, const char *name) EINA_ARG_NONNULL(1);
/**
* Retrieves the name of the given Evas object.
*
* See the full @ref Example_Evas_Events "example".
*/
-EAPI const char *evas_object_name_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI const char *evas_object_name_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Increments object reference count to defer its deletion.
* @ingroup Evas_Object_Group_Basic
* @since 1.1.0
*/
-EAPI void evas_object_ref (Evas_Object *obj);
+EAPI void evas_object_ref(Evas_Object *obj);
/**
* Decrements object reference count.
* @ingroup Evas_Object_Group_Basic
* @since 1.1.0
*/
-EAPI void evas_object_unref (Evas_Object *obj);
+EAPI void evas_object_unref(Evas_Object *obj);
/**
* Get the object reference count.
* @ingroup Evas_Object_Group_Basic
* @since 1.2.0
*/
-EAPI int evas_object_ref_get (const Evas_Object *obj);
-
+EAPI int evas_object_ref_get(const Evas_Object *obj);
/**
* Marks the given Evas object for deletion (when Evas will free its
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_del (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_del(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Move the given Evas object to the given location inside its
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_move (Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
/**
* Changes the size of the given Evas object.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_resize (Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieves the position and (rectangular) size of the given Evas
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_geometry_get (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
-
+EAPI void evas_object_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Makes the given Evas object visible.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_show (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_show(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Makes the given Evas object invisible.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_hide (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Retrieves whether or not the given Evas object is visible.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI Eina_Bool evas_object_visible_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_object_visible_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the general/main color of the given Evas object to the given
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_color_set (Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
/**
* Retrieves the general/main color of the given Evas object.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI void evas_object_color_get (const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
-
+EAPI void evas_object_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
/**
* Retrieves the Evas canvas that the given object lives on.
*
* @ingroup Evas_Object_Group_Basic
*/
-EAPI Evas *evas_object_evas_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas *evas_object_evas_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieves the type of the given Evas object.
*
* See the full @ref Example_Evas_Object_Manipulation "example".
*/
-EAPI const char *evas_object_type_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_object_type_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Raise @p obj to the top of its layer.
* @see evas_object_stack_below()
* @see evas_object_lower()
*/
-EAPI void evas_object_raise (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_raise(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Lower @p obj to the bottom of its layer.
* @see evas_object_stack_below()
* @see evas_object_raise()
*/
-EAPI void evas_object_lower (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_lower(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Stack @p obj immediately above @p above
* @see evas_object_layer_set()
* @see evas_object_stack_below()
*/
-EAPI void evas_object_stack_above (Evas_Object *obj, Evas_Object *above) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_stack_above(Evas_Object *obj, Evas_Object *above) EINA_ARG_NONNULL(1, 2);
/**
* Stack @p obj immediately below @p below
* @see evas_object_layer_set()
* @see evas_object_stack_below()
*/
-EAPI void evas_object_stack_below (Evas_Object *obj, Evas_Object *below) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_stack_below(Evas_Object *obj, Evas_Object *below) EINA_ARG_NONNULL(1, 2);
/**
* Get the Evas object stacked right above @p obj
* @see evas_object_below_get()
*
*/
-EAPI Evas_Object *evas_object_above_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_above_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the Evas object stacked right below @p obj
* @see evas_object_layer_set()
* @see evas_object_below_get()
*/
-EAPI Evas_Object *evas_object_below_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_below_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @}
* See the full example @ref Example_Evas_Events "here".
*
*/
- EAPI void evas_object_event_callback_add (Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
+EAPI void evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Add (register) a callback function to a given Evas object event with a
* @see evas_object_event_callback_add
* @since 1.1.0
*/
-EAPI void evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
+EAPI void evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
/**
* Delete a callback function from an object
* my_data = evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP, up_callback);
* @endcode
*/
-EAPI void *evas_object_event_callback_del (Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func) EINA_ARG_NONNULL(1, 3);
+EAPI void *evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func) EINA_ARG_NONNULL(1, 3);
/**
* Delete (unregister) a callback function registered to a given
* my_data = evas_object_event_callback_del_full(object, EVAS_CALLBACK_MOUSE_UP, up_callback, data);
* @endcode
*/
-EAPI void *evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
-
+EAPI void *evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Set whether an Evas object is to pass (ignore) events.
* @see evas_object_propagate_events_set()
* @see evas_object_freeze_events_set()
*/
-EAPI void evas_object_pass_events_set (Evas_Object *obj, Eina_Bool pass) EINA_ARG_NONNULL(1);
+EAPI void evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass) EINA_ARG_NONNULL(1);
/**
* Determine whether an object is set to pass (ignore) events.
* @see evas_object_propagate_events_get()
* @see evas_object_freeze_events_get()
*/
-EAPI Eina_Bool evas_object_pass_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_pass_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set whether an Evas object is to repeat events.
* @see evas_object_propagate_events_set()
* @see evas_object_freeze_events_set()
*/
-EAPI void evas_object_repeat_events_set (Evas_Object *obj, Eina_Bool repeat) EINA_ARG_NONNULL(1);
+EAPI void evas_object_repeat_events_set(Evas_Object *obj, Eina_Bool repeat) EINA_ARG_NONNULL(1);
/**
* Determine whether an object is set to repeat events.
* @see evas_object_propagate_events_get()
* @see evas_object_freeze_events_get()
*/
-EAPI Eina_Bool evas_object_repeat_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_repeat_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set whether events on a smart object's member should get propagated
* @see evas_object_pass_events_set()
* @see evas_object_freeze_events_set()
*/
-EAPI void evas_object_propagate_events_set (Evas_Object *obj, Eina_Bool prop) EINA_ARG_NONNULL(1);
+EAPI void evas_object_propagate_events_set(Evas_Object *obj, Eina_Bool prop) EINA_ARG_NONNULL(1);
/**
* Retrieve whether an Evas object is set to propagate events.
* @see evas_object_pass_events_get()
* @see evas_object_freeze_events_get()
*/
-EAPI Eina_Bool evas_object_propagate_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_propagate_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set whether an Evas object is to freeze (discard) events.
*
* If @p freeze is @c EINA_TRUE, it will make events on @p obj to be @b
* discarded. Unlike evas_object_pass_events_set(), events will not be
- * passed to @b next lower object. This API can be used for blocking
- * events while @p obj is on transiting.
+ * passed to @b next lower object. This API can be used for blocking
+ * events while @p obj is on transiting.
*
* If @p freeze is @c EINA_FALSE, events will be processed on that
* object as normal.
* @see evas_object_propagate_events_set()
* @since 1.1.0
*/
-EAPI void evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze) EINA_ARG_NONNULL(1);
+EAPI void evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze) EINA_ARG_NONNULL(1);
/**
* Determine whether an object is set to freeze (discard) events.
* @see evas_object_propagate_events_get()
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @}
* @param obj object to enable the map on
* @param enabled enabled state
*/
-EAPI void evas_object_map_enable_set (Evas_Object *obj, Eina_Bool enabled);
+EAPI void evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled);
/**
* Get the map enabled state
* @param obj object to get the map enabled state from
* @return the map enabled state
*/
-EAPI Eina_Bool evas_object_map_enable_get (const Evas_Object *obj);
-
-/**
- * Set the map source object
- *
- * This sets the object from which the map is taken - can be any object that
- * has map enabled on it.
- *
- * Currently not implemented. for future use.
- *
- * @param obj object to set the map source of
- * @param src the source object from which the map is taken
- */
-EAPI void evas_object_map_source_set (Evas_Object *obj, Evas_Object *src);
-
-/**
- * Get the map source object
- *
- * @param obj object to set the map source of
- * @return the object set as the source
- *
- * @see evas_object_map_source_set()
- */
-EAPI Evas_Object *evas_object_map_source_get (const Evas_Object *obj);
+EAPI Eina_Bool evas_object_map_enable_get(const Evas_Object *obj);
/**
* Set current object transformation map.
*
* @see evas_map_new()
*/
-EAPI void evas_object_map_set (Evas_Object *obj, const Evas_Map *map);
+EAPI void evas_object_map_set(Evas_Object *obj, const Evas_Map *map);
/**
* Get current object transformation map.
*
* @see evas_object_map_set()
*/
-EAPI const Evas_Map *evas_object_map_get (const Evas_Object *obj);
-
+EAPI const Evas_Map *evas_object_map_get(const Evas_Object *obj);
/**
* Populate source and destination map points to match exactly object.
* @see evas_map_point_coord_set()
* @see evas_map_point_image_uv_set()
*/
-EAPI void evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *obj, Evas_Coord z);
+EAPI void evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *obj, Evas_Coord z);
/**
* Populate source and destination map points to match exactly object.
* @see evas_map_point_coord_set()
* @see evas_map_point_image_uv_set()
*/
-EAPI void evas_map_util_points_populate_from_object (Evas_Map *m, const Evas_Object *obj);
+EAPI void evas_map_util_points_populate_from_object(Evas_Map *m, const Evas_Object *obj);
/**
* Populate source and destination map points to match given geometry.
* @see evas_map_point_coord_set()
* @see evas_map_point_image_uv_set()
*/
-EAPI void evas_map_util_points_populate_from_geometry (Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z);
+EAPI void evas_map_util_points_populate_from_geometry(Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z);
/**
* Set color of all points to given color.
*
* @see evas_map_point_color_set()
*/
-EAPI void evas_map_util_points_color_set (Evas_Map *m, int r, int g, int b, int a);
+EAPI void evas_map_util_points_color_set(Evas_Map *m, int r, int g, int b, int a);
/**
* Change the map to apply the given rotation.
* @see evas_map_point_coord_set()
* @see evas_map_util_zoom()
*/
-EAPI void evas_map_util_rotate (Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy);
+EAPI void evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy);
/**
* Change the map to apply the given zooming.
* @see evas_map_point_coord_set()
* @see evas_map_util_rotate()
*/
-EAPI void evas_map_util_zoom (Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
+EAPI void evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
/**
* Rotate the map around 3 axes in 3D
* @param cy rotation's center vertical position.
* @param cz rotation's center vertical position.
*/
-EAPI void evas_map_util_3d_rotate (Evas_Map *m, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz);
+EAPI void evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz);
/**
* Perform lighting calculations on the given Map
* @param ag ambient color green value (0 - 255)
* @param ab ambient color blue value (0 - 255)
*/
-EAPI void evas_map_util_3d_lighting (Evas_Map *m, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab);
+EAPI void evas_map_util_3d_lighting(Evas_Map *m, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab);
/**
* Apply a perspective transform to the map
* @param z0 The "0" z plane value
* @param foc The focal distance
*/
-EAPI void evas_map_util_3d_perspective (Evas_Map *m, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc);
+EAPI void evas_map_util_3d_perspective(Evas_Map *m, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc);
/**
* Get the clockwise state of a map
* @param m map to query.
* @return 1 if clockwise, 0 otherwise
*/
-EAPI Eina_Bool evas_map_util_clockwise_get (Evas_Map *m);
-
+EAPI Eina_Bool evas_map_util_clockwise_get(Evas_Map *m);
/**
* Create map of transformation points to be later used with an Evas object.
*
* @see evas_object_map_set()
*/
-EAPI Evas_Map *evas_map_new (int count);
+EAPI Evas_Map *evas_map_new(int count);
/**
* Set the smoothing for map rendering
* @param m map to modify. Must not be NULL.
* @param enabled enable or disable smooth map rendering
*/
-EAPI void evas_map_smooth_set (Evas_Map *m, Eina_Bool enabled);
+EAPI void evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled);
/**
* get the smoothing for map rendering
*
* @param m map to get the smooth from. Must not be NULL.
*/
-EAPI Eina_Bool evas_map_smooth_get (const Evas_Map *m);
+EAPI Eina_Bool evas_map_smooth_get(const Evas_Map *m);
/**
* Set the alpha flag for map rendering
* @param m map to modify. Must not be NULL.
* @param enabled enable or disable alpha map rendering
*/
-EAPI void evas_map_alpha_set (Evas_Map *m, Eina_Bool enabled);
+EAPI void evas_map_alpha_set(Evas_Map *m, Eina_Bool enabled);
/**
* get the alpha flag for map rendering
*
* @param m map to get the alpha from. Must not be NULL.
*/
-EAPI Eina_Bool evas_map_alpha_get (const Evas_Map *m);
+EAPI Eina_Bool evas_map_alpha_get(const Evas_Map *m);
/**
* Copy a previously allocated map.
* @param m map to copy. Must not be NULL.
* @return newly allocated map with the same count and contents as @p m.
*/
-EAPI Evas_Map *evas_map_dup (const Evas_Map *m);
+EAPI Evas_Map *evas_map_dup(const Evas_Map *m);
/**
* Free a previously allocated map.
*
* @param m map to free.
*/
-EAPI void evas_map_free (Evas_Map *m);
+EAPI void evas_map_free(Evas_Map *m);
/**
* Get a maps size.
* @param m map to get size.
* @return -1 on error, points otherwise.
*/
-EAPI int evas_map_count_get (const Evas_Map *m) EINA_CONST;
+EAPI int evas_map_count_get(const Evas_Map *m) EINA_CONST;
/**
* Change the map point's coordinate.
* @see evas_map_util_points_populate_from_object_full()
* @see evas_map_util_points_populate_from_object()
*/
-EAPI void evas_map_point_coord_set (Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
+EAPI void evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
/**
* Get the map point's coordinate.
* @param y where to return the Y coordinate.
* @param z where to return the Z coordinate.
*/
-EAPI void evas_map_point_coord_get (const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
+EAPI void evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
/**
* Change the map point's U and V texture source point
* @see evas_map_util_points_populate_from_object_full()
* @see evas_map_util_points_populate_from_object()
*/
-EAPI void evas_map_point_image_uv_set (Evas_Map *m, int idx, double u, double v);
+EAPI void evas_map_point_image_uv_set(Evas_Map *m, int idx, double u, double v);
/**
* Get the map point's U and V texture source points
* @param u where to write the X coordinate within the image/texture source
* @param v where to write the Y coordinate within the image/texture source
*/
-EAPI void evas_map_point_image_uv_get (const Evas_Map *m, int idx, double *u, double *v);
+EAPI void evas_map_point_image_uv_get(const Evas_Map *m, int idx, double *u, double *v);
/**
* Set the color of a vertex in the map
* @see evas_map_point_coord_set()
* @see evas_object_map_set()
*/
-EAPI void evas_map_point_color_set (Evas_Map *m, int idx, int r, int g, int b, int a);
+EAPI void evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a);
/**
* Get the color set on a vertex in the map
* @see evas_map_point_coord_set()
* @see evas_object_map_set()
*/
-EAPI void evas_map_point_color_get (const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
+EAPI void evas_map_point_color_get(const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
/**
* @}
*/
*
* @see evas_object_size_hint_min_set() for an example
*/
-EAPI void evas_object_size_hint_min_get (const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_min_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's minimum size.
*
* @see evas_object_size_hint_min_get()
*/
-EAPI void evas_object_size_hint_min_set (Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_min_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for an object's maximum size.
*
* @see evas_object_size_hint_max_set()
*/
-EAPI void evas_object_size_hint_max_get (const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_max_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's maximum size.
*
* @see evas_object_size_hint_max_get()
*/
-EAPI void evas_object_size_hint_max_set (Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_max_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for an object's optimum size.
*
* @see evas_object_size_hint_request_set()
*/
-EAPI void evas_object_size_hint_request_get (const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_request_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's optimum size.
*
* @see evas_object_size_hint_request_get()
*/
-EAPI void evas_object_size_hint_request_set (Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_request_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for an object's aspect ratio.
*
* @see evas_object_size_hint_aspect_set()
*/
-EAPI void evas_object_size_hint_aspect_get (const Evas_Object *obj, Evas_Aspect_Control *aspect, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_aspect_get(const Evas_Object *obj, Evas_Aspect_Control *aspect, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's aspect ratio.
*
* @see evas_object_size_hint_aspect_get() for more information.
*/
-EAPI void evas_object_size_hint_aspect_set (Evas_Object *obj, Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_aspect_set(Evas_Object *obj, Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for on object's alignment.
*
* @note Use @c NULL pointers on the hint components you're not
* interested in: they'll be ignored by the function.
+ * @note If @c obj is invalid, then the hint components will be set with 0.5
*
* @see evas_object_size_hint_align_set() for more information
*/
-EAPI void evas_object_size_hint_align_get (const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_align_get(const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's alignment.
* @see evas_object_size_hint_max_set()
* @see evas_object_size_hint_padding_set()
*/
-EAPI void evas_object_size_hint_align_set (Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_align_set(Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for an object's weight.
*
* @note Use @c NULL pointers on the hint components you're not
* interested in: they'll be ignored by the function.
+ * @note If @c obj is invalid, then the hint components will be set with 0.0
*
* @see evas_object_size_hint_weight_set() for an example
*/
-EAPI void evas_object_size_hint_weight_get (const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_weight_get(const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's weight.
*
* @see evas_object_size_hint_weight_get() for more information
*/
-EAPI void evas_object_size_hint_weight_set (Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_weight_set(Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
/**
* Retrieves the hints for an object's padding space.
*
* @see evas_object_size_hint_padding_set()
*/
-EAPI void evas_object_size_hint_padding_get (const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_padding_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
/**
* Sets the hints for an object's padding space.
*
* @see evas_object_size_hint_padding_get() for more information
*/
-EAPI void evas_object_size_hint_padding_set (Evas_Object *obj, Evas_Coord l, Evas_Coord r, Evas_Coord t, Evas_Coord b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_size_hint_padding_set(Evas_Object *obj, Evas_Coord l, Evas_Coord r, Evas_Coord t, Evas_Coord b) EINA_ARG_NONNULL(1);
/**
* @}
* printf("The data that was attached was %p\n", evas_object_data_get(obj, "name_of_data"));
* @endcode
*/
-EAPI void evas_object_data_set (Evas_Object *obj, const char *key, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_data_set(Evas_Object *obj, const char *key, const void *data) EINA_ARG_NONNULL(1, 2);
/**
* Return an attached data pointer on an Evas object by its given
* else printf("No data was stored on the object\n");
* @endcode
*/
-EAPI void *evas_object_data_get (const Evas_Object *obj, const char *key) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_data_get(const Evas_Object *obj, const char *key) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Delete an attached data pointer from an object.
* my_data = evas_object_data_del(obj, "name_of_my_data");
* @endcode
*/
-EAPI void *evas_object_data_del (Evas_Object *obj, const char *key) EINA_ARG_NONNULL(1, 2);
-
+EAPI void *evas_object_data_del(Evas_Object *obj, const char *key) EINA_ARG_NONNULL(1, 2);
/**
* Set pointer behavior.
*
* @ingroup Evas_Object_Group_Extras
*/
-EAPI void evas_object_pointer_mode_set (Evas_Object *obj, Evas_Object_Pointer_Mode setting) EINA_ARG_NONNULL(1);
+EAPI void evas_object_pointer_mode_set(Evas_Object *obj, Evas_Object_Pointer_Mode setting) EINA_ARG_NONNULL(1);
/**
* Determine how pointer will behave.
* @return pointer behavior.
* @ingroup Evas_Object_Group_Extras
*/
-EAPI Evas_Object_Pointer_Mode evas_object_pointer_mode_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Evas_Object_Pointer_Mode evas_object_pointer_mode_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets whether or not the given Evas object is to be drawn anti-aliased.
* @param antialias 1 if the object is to be anti_aliased, 0 otherwise.
* @ingroup Evas_Object_Group_Extras
*/
-EAPI void evas_object_anti_alias_set (Evas_Object *obj, Eina_Bool antialias) EINA_ARG_NONNULL(1);
+EAPI void evas_object_anti_alias_set(Evas_Object *obj, Eina_Bool antialias) EINA_ARG_NONNULL(1);
/**
* Retrieves whether or not the given Evas object is to be drawn anti_aliased.
* @return @c 1 if the object is to be anti_aliased. @c 0 otherwise.
* @ingroup Evas_Object_Group_Extras
*/
-EAPI Eina_Bool evas_object_anti_alias_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_object_anti_alias_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the scaling factor for an Evas object. Does not affect all
*
* @ingroup Evas_Object_Group_Extras
*/
-EAPI void evas_object_scale_set (Evas_Object *obj, double scale) EINA_ARG_NONNULL(1);
+EAPI void evas_object_scale_set(Evas_Object *obj, double scale) EINA_ARG_NONNULL(1);
/**
* Retrieves the scaling factor for the given Evas object.
*
* @see evas_object_scale_set()
*/
-EAPI double evas_object_scale_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI double evas_object_scale_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the render_op to be used for rendering the Evas object.
* @param op one of the Evas_Render_Op values.
* @ingroup Evas_Object_Group_Extras
*/
-EAPI void evas_object_render_op_set (Evas_Object *obj, Evas_Render_Op op) EINA_ARG_NONNULL(1);
+EAPI void evas_object_render_op_set(Evas_Object *obj, Evas_Render_Op op) EINA_ARG_NONNULL(1);
/**
* Retrieves the current value of the operation used for rendering the Evas object.
* @return one of the enumerated values in Evas_Render_Op.
* @ingroup Evas_Object_Group_Extras
*/
-EAPI Evas_Render_Op evas_object_render_op_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Render_Op evas_object_render_op_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set whether to use precise (usually expensive) point collision
* @see evas_object_precise_is_inside_get()
* @ingroup Evas_Object_Group_Extras
*/
- EAPI void evas_object_precise_is_inside_set(Evas_Object *obj, Eina_Bool precise) EINA_ARG_NONNULL(1);
+EAPI void evas_object_precise_is_inside_set(Evas_Object *obj, Eina_Bool precise) EINA_ARG_NONNULL(1);
/**
* Determine whether an object is set to use precise point collision
*
* @ingroup Evas_Object_Group_Extras
*/
- EAPI Eina_Bool evas_object_precise_is_inside_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_precise_is_inside_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set a hint flag on the given Evas object that it's used as a "static
*
* This is a hint to Evas that this object is used as a big static
* clipper and shouldn't be moved with children and otherwise
- * considered specially. The default value for new objects is
+ * considered specially. The default value for new objects is
* @c EINA_FALSE.
*
* @see evas_object_static_clip_get()
*
* @ingroup Evas_Object_Group_Extras
*/
- EAPI void evas_object_static_clip_set (Evas_Object *obj, Eina_Bool is_static_clip) EINA_ARG_NONNULL(1);
+EAPI void evas_object_static_clip_set(Evas_Object *obj, Eina_Bool is_static_clip) EINA_ARG_NONNULL(1);
/**
* Get the "static clipper" hint flag for a given Evas object.
*
* @ingroup Evas_Object_Group_Extras
*/
- EAPI Eina_Bool evas_object_static_clip_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_static_clip_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @}
*
* @ingroup Evas_Object_Group_Find
*/
-EAPI Evas_Object *evas_focus_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_focus_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieves the object on the given evas with the given name.
* @param name The given name.
* @return If successful, the Evas object with the given name. Otherwise,
* @c NULL.
- *
+ *
* This looks for the evas object given a name by evas_object_name_set(). If
* the name is not unique canvas-wide, then which one of the many objects
* with that name is returned is undefined, so only use this if you can ensure
* the object name is unique.
- *
+ *
* @ingroup Evas_Object_Group_Find
*/
-EAPI Evas_Object *evas_object_name_find (const Evas *e, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_name_find(const Evas *e, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieves the object from children of the given object with the given name.
* @param recurse Set to the number of child levels to recurse (0 == don't recurse, 1 == only look at the children of @p obj or their immediate children, but no further etc.).
* @return If successful, the Evas object with the given name. Otherwise,
* @c NULL.
- *
+ *
* This looks for the evas object given a name by evas_object_name_set(), but
* it ONLY looks at the children of the object *p obj, and will only recurse
* into those children if @p recurse is greater than 0. If the name is not
* unique within immediate children (or the whole child tree) then it is not
* defined which child object will be returned. If @p recurse is set to -1 then
* it will recurse without limit.
- *
+ *
* @since 1.2
- *
+ *
* @ingroup Evas_Object_Group_Find
*/
-EAPI Evas_Object *evas_object_name_child_find (const Evas_Object *obj, const char *name, int recurse) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_name_child_find(const Evas_Object *obj, const char *name, int recurse) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve the Evas object stacked at the top of a given position in
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Evas_Object *evas_object_top_at_xy_get (const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_top_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve the Evas object stacked at the top at the position of the
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Evas_Object *evas_object_top_at_pointer_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_top_at_pointer_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve the Evas object stacked at the top of a given rectangular
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Evas_Object *evas_object_top_in_rectangle_get (const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_top_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve a list of Evas objects lying over a given position in
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Eina_List *evas_objects_at_xy_get (const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Eina_List *evas_objects_in_rectangle_get (const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_List *evas_objects_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_List *evas_objects_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the lowest (stacked) Evas object on the canvas @p e.
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Evas_Object *evas_object_bottom_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_bottom_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the highest (stacked) Evas object on the canvas @p e.
* objects, acting only on the ones at the "top level", with regard to
* object parenting.
*/
-EAPI Evas_Object *evas_object_top_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_top_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @}
* @{
*/
-typedef void (*Evas_Object_Intercept_Show_Cb) (void *data, Evas_Object *obj);
-typedef void (*Evas_Object_Intercept_Hide_Cb) (void *data, Evas_Object *obj);
-typedef void (*Evas_Object_Intercept_Move_Cb) (void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
-typedef void (*Evas_Object_Intercept_Resize_Cb) (void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h);
-typedef void (*Evas_Object_Intercept_Raise_Cb) (void *data, Evas_Object *obj);
-typedef void (*Evas_Object_Intercept_Lower_Cb) (void *data, Evas_Object *obj);
-typedef void (*Evas_Object_Intercept_Stack_Above_Cb) (void *data, Evas_Object *obj, Evas_Object *above);
-typedef void (*Evas_Object_Intercept_Stack_Below_Cb) (void *data, Evas_Object *obj, Evas_Object *above);
-typedef void (*Evas_Object_Intercept_Layer_Set_Cb) (void *data, Evas_Object *obj, int l);
-typedef void (*Evas_Object_Intercept_Color_Set_Cb) (void *data, Evas_Object *obj, int r, int g, int b, int a);
-typedef void (*Evas_Object_Intercept_Clip_Set_Cb) (void *data, Evas_Object *obj, Evas_Object *clip);
-typedef void (*Evas_Object_Intercept_Clip_Unset_Cb) (void *data, Evas_Object *obj);
+typedef void (*Evas_Object_Intercept_Show_Cb)(void *data, Evas_Object *obj);
+typedef void (*Evas_Object_Intercept_Hide_Cb)(void *data, Evas_Object *obj);
+typedef void (*Evas_Object_Intercept_Move_Cb)(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+typedef void (*Evas_Object_Intercept_Resize_Cb)(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+typedef void (*Evas_Object_Intercept_Raise_Cb)(void *data, Evas_Object *obj);
+typedef void (*Evas_Object_Intercept_Lower_Cb)(void *data, Evas_Object *obj);
+typedef void (*Evas_Object_Intercept_Stack_Above_Cb)(void *data, Evas_Object *obj, Evas_Object *above);
+typedef void (*Evas_Object_Intercept_Stack_Below_Cb)(void *data, Evas_Object *obj, Evas_Object *above);
+typedef void (*Evas_Object_Intercept_Layer_Set_Cb)(void *data, Evas_Object *obj, int l);
+typedef void (*Evas_Object_Intercept_Color_Set_Cb)(void *data, Evas_Object *obj, int r, int g, int b, int a);
+typedef void (*Evas_Object_Intercept_Clip_Set_Cb)(void *data, Evas_Object *obj, Evas_Object *clip);
+typedef void (*Evas_Object_Intercept_Clip_Unset_Cb)(void *data, Evas_Object *obj);
/**
* Set the callback function that intercepts a show event of a object.
* @see evas_object_intercept_show_callback_del().
*
*/
-EAPI void evas_object_intercept_show_callback_add (Evas_Object *obj, Evas_Object_Intercept_Show_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_show_callback_add(Evas_Object *obj, Evas_Object_Intercept_Show_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
/**
* Unset the callback function that intercepts a show event of a
* @see evas_object_intercept_show_callback_add().
*
*/
-EAPI void *evas_object_intercept_show_callback_del (Evas_Object *obj, Evas_Object_Intercept_Show_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_show_callback_del(Evas_Object *obj, Evas_Object_Intercept_Show_Cb func) EINA_ARG_NONNULL(1, 2);
/**
* Set the callback function that intercepts a hide event of a object.
* @see evas_object_intercept_hide_callback_del().
*
*/
-EAPI void evas_object_intercept_hide_callback_add (Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_hide_callback_add(Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
/**
* Unset the callback function that intercepts a hide event of a
* @see evas_object_intercept_hide_callback_add().
*
*/
-EAPI void *evas_object_intercept_hide_callback_del (Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_hide_callback_del(Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func) EINA_ARG_NONNULL(1, 2);
/**
* Set the callback function that intercepts a move event of a object.
* @see evas_object_intercept_move_callback_del().
*
*/
-EAPI void evas_object_intercept_move_callback_add (Evas_Object *obj, Evas_Object_Intercept_Move_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_move_callback_add(Evas_Object *obj, Evas_Object_Intercept_Move_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
/**
* Unset the callback function that intercepts a move event of a
* @see evas_object_intercept_move_callback_add().
*
*/
-EAPI void *evas_object_intercept_move_callback_del (Evas_Object *obj, Evas_Object_Intercept_Move_Cb func) EINA_ARG_NONNULL(1, 2);
-
- EAPI void evas_object_intercept_resize_callback_add (Evas_Object *obj, Evas_Object_Intercept_Resize_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_resize_callback_del (Evas_Object *obj, Evas_Object_Intercept_Resize_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_raise_callback_add (Evas_Object *obj, Evas_Object_Intercept_Raise_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_raise_callback_del (Evas_Object *obj, Evas_Object_Intercept_Raise_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_lower_callback_add (Evas_Object *obj, Evas_Object_Intercept_Lower_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_lower_callback_del (Evas_Object *obj, Evas_Object_Intercept_Lower_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_stack_above_callback_add (Evas_Object *obj, Evas_Object_Intercept_Stack_Above_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_stack_above_callback_del (Evas_Object *obj, Evas_Object_Intercept_Stack_Above_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_stack_below_callback_add (Evas_Object *obj, Evas_Object_Intercept_Stack_Below_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_stack_below_callback_del (Evas_Object *obj, Evas_Object_Intercept_Stack_Below_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_layer_set_callback_add (Evas_Object *obj, Evas_Object_Intercept_Layer_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_layer_set_callback_del (Evas_Object *obj, Evas_Object_Intercept_Layer_Set_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_color_set_callback_add (Evas_Object *obj, Evas_Object_Intercept_Color_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_color_set_callback_del (Evas_Object *obj, Evas_Object_Intercept_Color_Set_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_clip_set_callback_add (Evas_Object *obj, Evas_Object_Intercept_Clip_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_clip_set_callback_del (Evas_Object *obj, Evas_Object_Intercept_Clip_Set_Cb func) EINA_ARG_NONNULL(1, 2);
- EAPI void evas_object_intercept_clip_unset_callback_add (Evas_Object *obj, Evas_Object_Intercept_Clip_Unset_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
- EAPI void *evas_object_intercept_clip_unset_callback_del (Evas_Object *obj, Evas_Object_Intercept_Clip_Unset_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_move_callback_del(Evas_Object *obj, Evas_Object_Intercept_Move_Cb func) EINA_ARG_NONNULL(1, 2);
+
+EAPI void evas_object_intercept_resize_callback_add(Evas_Object *obj, Evas_Object_Intercept_Resize_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_resize_callback_del(Evas_Object *obj, Evas_Object_Intercept_Resize_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_raise_callback_add(Evas_Object *obj, Evas_Object_Intercept_Raise_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_raise_callback_del(Evas_Object *obj, Evas_Object_Intercept_Raise_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_lower_callback_add(Evas_Object *obj, Evas_Object_Intercept_Lower_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_lower_callback_del(Evas_Object *obj, Evas_Object_Intercept_Lower_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_stack_above_callback_add(Evas_Object *obj, Evas_Object_Intercept_Stack_Above_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_stack_above_callback_del(Evas_Object *obj, Evas_Object_Intercept_Stack_Above_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_stack_below_callback_add(Evas_Object *obj, Evas_Object_Intercept_Stack_Below_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_stack_below_callback_del(Evas_Object *obj, Evas_Object_Intercept_Stack_Below_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_layer_set_callback_add(Evas_Object *obj, Evas_Object_Intercept_Layer_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_layer_set_callback_del(Evas_Object *obj, Evas_Object_Intercept_Layer_Set_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_color_set_callback_add(Evas_Object *obj, Evas_Object_Intercept_Color_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_color_set_callback_del(Evas_Object *obj, Evas_Object_Intercept_Color_Set_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_clip_set_callback_add(Evas_Object *obj, Evas_Object_Intercept_Clip_Set_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_clip_set_callback_del(Evas_Object *obj, Evas_Object_Intercept_Clip_Set_Cb func) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_intercept_clip_unset_callback_add(Evas_Object *obj, Evas_Object_Intercept_Clip_Unset_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_Object_Intercept_Clip_Unset_Cb func) EINA_ARG_NONNULL(1, 2);
/**
* @}
* rectangle, however the rectangle is actually very useful and should be
* manipulated using the generic @ref Evas_Object_Group "evas object functions".
*
- * The evas rectangle server a number of key functions when working on evas
+ * The evas rectangle serves a number of key functions when working on evas
* programs:
* @li Background
* @li Debugging
* evas_object_show(clipper);
* @endcode
*
+ * @warning We don't guarantee any proper results if you create a Rectangle
+ * object without setting the evas engine.
+ *
* For an example that more fully exercise the use of an evas object rectangle
* see @ref Example_Evas_Object_Manipulation.
*
*
* @ingroup Evas_Object_Rectangle
*/
-EAPI Evas_Object *evas_object_rectangle_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* @defgroup Evas_Object_Image Image Object Functions
* - #EVAS_COLORSPACE_GRY8:
* The image is just a alpha mask (8 bit's per pixel). This is used
* for alpha masking.
- * .
+ *
+ * @warning We don't guarantee any proper results if you create a Image object
+ * without setting the evas engine.
+ *
* Some examples on this group of functions can be found @ref
* Example_Evas_Images "here".
*
* @{
*/
-typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
-
+typedef void (*Evas_Object_Image_Pixels_Get_Cb)(void *data, Evas_Object *o);
/**
* Creates a new image object on the given Evas @p e canvas.
* evas_object_image_file_set(img, "/path/to/img", NULL);
* @endcode
*/
-EAPI Evas_Object *evas_object_image_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_image_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Creates a new image object that @b automatically scales its bound
* @see evas_object_image_filled_set()
* @see evas_object_image_fill_set()
*/
-EAPI Evas_Object *evas_object_image_filled_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
-
+EAPI Evas_Object *evas_object_image_filled_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Sets the data for an image from memory to be loaded
* itself). The @p data at the address is copied and stored for future use, so
* no @p data needs to be kept after this call is made. It will be managed and
* freed for you when no longer needed. The @p size is limited to 2 gigabytes
- * in size, and must be greater than 0. A @c NULL @p data pointer is also
- * invalid. Set the filename to @c NULL to reset to empty state and have the
+ * in size, and must be greater than 0. A @c NULL @p data pointer is also
+ * invalid. Set the filename to @c NULL to reset to empty state and have the
* image file data freed from memory using evas_object_image_file_set().
*
* The @p format is optional (pass @c NULL if you don't need/use it). It is
* @param format The format of the file (optional), or @c NULL if not needed
* @param key The image key in file, or @c NULL.
*/
-EAPI void evas_object_image_memfile_set (Evas_Object *obj, void *data, int size, char *format, char *key) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key) EINA_ARG_NONNULL(1, 2);
/**
* Set the source file from where an image object must fetch the real
* }
* @endcode
*/
-EAPI void evas_object_image_file_set (Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
/**
* Retrieve the source file from where an image object is to fetch the
* @note Use @c NULL pointers on the file components you're not
* interested in: they'll be ignored by the function.
*/
-EAPI void evas_object_image_file_get (const Evas_Object *obj, const char **file, const char **key) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key) EINA_ARG_NONNULL(1, 2);
/**
* Set the dimensions for an image object's border, a region which @b
* @see evas_object_image_border_get()
* @see evas_object_image_border_center_fill_set()
*/
-EAPI void evas_object_image_border_set (Evas_Object *obj, int l, int r, int t, int b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b) EINA_ARG_NONNULL(1);
/**
* Retrieve the dimensions for an image object's border, a region
*
* See @ref evas_object_image_border_set() for more details.
*/
-EAPI void evas_object_image_border_get (const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
/**
* Sets @b how the center part of the given image object (not the
*
* @see evas_object_image_border_center_fill_get()
*/
-EAPI void evas_object_image_border_center_fill_set (Evas_Object *obj, Evas_Border_Fill_Mode fill) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill) EINA_ARG_NONNULL(1);
/**
* Retrieves @b how the center part of the given image object (not the
*
* See @ref evas_object_image_fill_set() for more details.
*/
-EAPI Evas_Border_Fill_Mode evas_object_image_border_center_fill_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Border_Fill_Mode evas_object_image_border_center_fill_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set whether the image object's fill property should track the
* @see evas_object_image_filled_add()
* @see evas_object_image_fill_get()
*/
-EAPI void evas_object_image_filled_set (Evas_Object *obj, Eina_Bool setting) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting) EINA_ARG_NONNULL(1);
/**
* Retrieve whether the image object's fill property should track the
*
* @see evas_object_image_filled_set() for more information
*/
-EAPI Eina_Bool evas_object_image_filled_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_filled_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the scaling factor (multiplier) for the borders of an image
* @see evas_object_image_border_set()
* @see evas_object_image_border_scale_get()
*/
-EAPI void evas_object_image_border_scale_set (Evas_Object *obj, double scale);
+EAPI void evas_object_image_border_scale_set(Evas_Object *obj, double scale);
/**
* Retrieves the scaling factor (multiplier) for the borders of an
* @see evas_object_image_border_set()
* @see evas_object_image_border_scale_set()
*/
-EAPI double evas_object_image_border_scale_get (const Evas_Object *obj);
+EAPI double evas_object_image_border_scale_get(const Evas_Object *obj);
/**
* Set how to fill an image object's drawing rectangle given the
* will @b override the values set here automatically, for you, in a
* given way.
*/
-EAPI void evas_object_image_fill_set (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
/**
* Retrieve how an image object is to fill its drawing rectangle,
*
* See @ref evas_object_image_fill_set() for more details.
*/
-EAPI void evas_object_image_fill_get (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Sets the tiling mode for the given evas image object's fill.
* @param spread One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
* EVAS_TEXTURE_RESTRICT, or EVAS_TEXTURE_PAD.
*/
-EAPI void evas_object_image_fill_spread_set (Evas_Object *obj, Evas_Fill_Spread spread) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread) EINA_ARG_NONNULL(1);
/**
* Retrieves the spread (tiling mode) for the given image object's
* @param obj The given evas image object.
* @return The current spread mode of the image object.
*/
-EAPI Evas_Fill_Spread evas_object_image_fill_spread_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Fill_Spread evas_object_image_fill_spread_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the size of the given image object.
* larger, then the image will be treated as if it were in the upper
* left hand corner of a larger image that is otherwise transparent.
*/
-EAPI void evas_object_image_size_set (Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_size_set(Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
/**
* Retrieves the size of the given image object.
*
* See @ref evas_object_image_size_set() for more details.
*/
-EAPI void evas_object_image_size_get (const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_size_get(const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
/**
* Retrieves the row stride of the given image object.
* The row stride is the number of bytes between the start of a row
* and the start of the next row for image data.
*/
-EAPI int evas_object_image_stride_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_object_image_stride_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieves a number representing any error that occurred during the
* one of the #Evas_Load_Error values. #EVAS_LOAD_ERROR_NONE
* is returned if there was no error.
*/
-EAPI Evas_Load_Error evas_object_image_load_error_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Load_Error evas_object_image_load_error_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the raw image data of the given image object.
*
* @see evas_object_image_data_get()
*/
-EAPI void evas_object_image_data_set (Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_data_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
/**
* Get a pointer to the raw image data of the given image object.
*
* @see evas_object_image_data_set()
*/
-EAPI void *evas_object_image_data_get (const Evas_Object *obj, Eina_Bool for_writing) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI void *evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Converts the raw image data of the given image object to the
* @param to_cspace The colorspace to which the image raw data will be converted.
* @return data A newly allocated data in the format specified by to_cspace.
*/
-EAPI void *evas_object_image_data_convert (Evas_Object *obj, Evas_Colorspace to_cspace) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI void *evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Replaces the raw image data of the given image object.
* See @ref evas_object_image_data_get() for more details.
*
*/
-EAPI void evas_object_image_data_copy_set (Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_data_copy_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
/**
* Mark a sub-region of the given image object to be redrawn.
* This function schedules a particular rectangular region of an image
* object to be updated (redrawn) at the next rendering cycle.
*/
-EAPI void evas_object_image_data_update_add (Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
/**
* Enable or disable alpha channel usage on the given image object.
*
* @see evas_object_image_alpha_get()
*/
-EAPI void evas_object_image_alpha_set (Evas_Object *obj, Eina_Bool has_alpha) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha) EINA_ARG_NONNULL(1);
/**
* Retrieve whether alpha channel data is being used on the given
*
* See @ref evas_object_image_alpha_set() for more details.
*/
-EAPI Eina_Bool evas_object_image_alpha_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_alpha_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets whether to use high-quality image scaling algorithm on the
*
* @see evas_object_image_smooth_scale_get()
*/
-EAPI void evas_object_image_smooth_scale_set (Evas_Object *obj, Eina_Bool smooth_scale) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale) EINA_ARG_NONNULL(1);
/**
* Retrieves whether the given image object is using high-quality
*
* See @ref evas_object_image_smooth_scale_set() for more details.
*/
-EAPI Eina_Bool evas_object_image_smooth_scale_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_smooth_scale_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Preload an image object's image data in the background
* then, that the user preload an image with it being @b hidden, just
* to be shown on the #EVAS_CALLBACK_IMAGE_PRELOADED event's callback.
*/
-EAPI void evas_object_image_preload (Evas_Object *obj, Eina_Bool cancel) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel) EINA_ARG_NONNULL(1);
/**
* Reload an image object's image data.
*
* This function reloads the image data bound to image object @p obj.
*/
-EAPI void evas_object_image_reload (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_reload(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Save the given image object's contents to an (image) file.
* acceptable flags are @c quality and @c compress. Eg.: @c
* "quality=100 compress=9"
*/
-EAPI Eina_Bool evas_object_image_save (const Evas_Object *obj, const char *file, const char *key, const char *flags) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags) EINA_ARG_NONNULL(1, 2);
/**
* Import pixels from given source to a given canvas image object.
* This function imports pixels from a given source to a given canvas image.
*
*/
-EAPI Eina_Bool evas_object_image_pixels_import (Evas_Object *obj, Evas_Pixel_Import_Source *pixels) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels) EINA_ARG_NONNULL(1, 2);
/**
* Set the callback function to get pixels from a canvas' image.
* pixes from a image of the canvas.
*
*/
-EAPI void evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Mark whether the given image object is dirty (needs to be redrawn).
* @param obj The given image object.
* @param dirty Whether the image is dirty.
*/
-EAPI void evas_object_image_pixels_dirty_set (Evas_Object *obj, Eina_Bool dirty) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty) EINA_ARG_NONNULL(1);
/**
* Retrieves whether the given image object is dirty (needs to be redrawn).
* @param obj The given image object.
* @return Whether the image is dirty.
*/
-EAPI Eina_Bool evas_object_image_pixels_dirty_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_pixels_dirty_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the DPI resolution of an image object's source image.
*
* @see evas_object_image_load_dpi_get()
*/
-EAPI void evas_object_image_load_dpi_set (Evas_Object *obj, double dpi) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_dpi_set(Evas_Object *obj, double dpi) EINA_ARG_NONNULL(1);
/**
* Get the DPI resolution of a loaded image object in the canvas.
*
* @see evas_object_image_load_dpi_set() for more details
*/
-EAPI double evas_object_image_load_dpi_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI double evas_object_image_load_dpi_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the size of a given image object's source image, when loading
*
* @see evas_object_image_load_size_get()
*/
-EAPI void evas_object_image_load_size_set (Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_size_set(Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
/**
* Get the size of a given image object's source image, when loading
*
* @see evas_object_image_load_size_set() for more details
*/
-EAPI void evas_object_image_load_size_get (const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
/**
* Set the scale down factor of a given image object's source image,
*
* @see evas_object_image_load_scale_down_get()
*/
-EAPI void evas_object_image_load_scale_down_set (Evas_Object *obj, int scale_down) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down) EINA_ARG_NONNULL(1);
/**
* get the scale down factor of a given image object's source image,
*
* @see evas_object_image_load_scale_down_set() for more details
*/
-EAPI int evas_object_image_load_scale_down_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_object_image_load_scale_down_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Inform a given image object to load a selective region of its
*
* @see evas_object_image_load_region_get()
*/
-EAPI void evas_object_image_load_region_set (Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
/**
* Retrieve the coordinates of a given image object's selective
*
* @see evas_object_image_load_region_get()
*/
-EAPI void evas_object_image_load_region_get (const Evas_Object *obj, int *x, int *y, int *w, int *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h) EINA_ARG_NONNULL(1);
/**
* Define if the orientation information in the image file should be honored.
* @param enable @c EINA_TRUE means that it should honor the orientation information
* @since 1.1
*/
-EAPI void evas_object_image_load_orientation_set (Evas_Object *obj, Eina_Bool enable) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable) EINA_ARG_NONNULL(1);
/**
* Get if the orientation information in the image file should be honored.
* @param obj The given image object pointer.
* @since 1.1
*/
-EAPI Eina_Bool evas_object_image_load_orientation_get (const Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_load_orientation_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Set the colorspace of a given image of the canvas.
* This function sets the colorspace of given canvas image.
*
*/
-EAPI void evas_object_image_colorspace_set (Evas_Object *obj, Evas_Colorspace cspace) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace) EINA_ARG_NONNULL(1);
/**
* Get the colorspace of a given image of the canvas.
* This function returns the colorspace of given canvas image.
*
*/
-EAPI Evas_Colorspace evas_object_image_colorspace_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Colorspace evas_object_image_colorspace_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the support state of a given image
*
* This function returns the state of the region support of given image
*/
-EAPI Eina_Bool evas_object_image_region_support_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_region_support_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the native surface of a given image of the canvas
* This function sets a native surface of a given canvas image.
*
*/
-EAPI void evas_object_image_native_surface_set (Evas_Object *obj, Evas_Native_Surface *surf) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf) EINA_ARG_NONNULL(1, 2);
/**
* Get the native surface of a given image of the canvas
* This function returns the native surface of a given canvas image.
*
*/
-EAPI Evas_Native_Surface *evas_object_image_native_surface_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Native_Surface *evas_object_image_native_surface_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the video surface linked to a given image of the canvas
* This function link a video surface to a given canvas image.
*
*/
-EAPI void evas_object_image_video_surface_set (Evas_Object *obj, Evas_Video_Surface *surf) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf) EINA_ARG_NONNULL(1);
/**
* Get the video surface linekd to a given image of the canvas
* This function returns the video surface linked to a given canvas image.
*
*/
-EAPI const Evas_Video_Surface *evas_object_image_video_surface_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const Evas_Video_Surface *evas_object_image_video_surface_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the scale hint of a given image of the canvas.
*
* @see evas_object_image_scale_hint_get()
*/
-EAPI void evas_object_image_scale_hint_set (Evas_Object *obj, Evas_Image_Scale_Hint hint) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint) EINA_ARG_NONNULL(1);
/**
* Get the scale hint of a given image of the canvas.
*
* @see evas_object_image_scale_hint_set() for more details.
*/
-EAPI Evas_Image_Scale_Hint evas_object_image_scale_hint_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Image_Scale_Hint evas_object_image_scale_hint_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the content hint setting of a given image object of the canvas.
*
* @see evas_object_image_content_hint_get()
*/
-EAPI void evas_object_image_content_hint_set (Evas_Object *obj, Evas_Image_Content_Hint hint) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint) EINA_ARG_NONNULL(1);
/**
* Get the content hint setting of a given image object of the canvas.
*
* @see evas_object_image_content_hint_set()
*/
-EAPI Evas_Image_Content_Hint evas_object_image_content_hint_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Evas_Image_Content_Hint evas_object_image_content_hint_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Enable an image to be used as an alpha mask.
* @param obj Object to use as an alpha mask.
* @param ismask Use image as alphamask, must be true.
*/
-EAPI void evas_object_image_alpha_mask_set (Evas_Object *obj, Eina_Bool ismask) EINA_ARG_NONNULL(1);
+EAPI void evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask) EINA_ARG_NONNULL(1);
/**
* Set the source object on an image object to used as a @b proxy.
* @see evas_object_image_source_get()
* @see evas_object_image_source_unset()
*/
-EAPI Eina_Bool evas_object_image_source_set (Evas_Object *obj, Evas_Object *src) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_source_set(Evas_Object *obj, Evas_Object *src) EINA_ARG_NONNULL(1);
/**
* Get the current source object of an image object.
*
* @see evas_object_image_source_set() for more details
*/
-EAPI Evas_Object *evas_object_image_source_get (const Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_image_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Clear the source object on a proxy image object.
* This is equivalent to calling evas_object_image_source_set() with a
* @c NULL source.
*/
-EAPI Eina_Bool evas_object_image_source_unset (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_image_source_unset(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Check if a file extension may be supported by @ref Evas_Object_Image.
*
* This functions is threadsafe.
*/
-EAPI Eina_Bool evas_object_image_extension_can_load_get(const char *file);
+EAPI Eina_Bool evas_object_image_extension_can_load_get(const char *file);
/**
* Check if a file extension may be supported by @ref Evas_Object_Image.
*
* This functions is threadsafe.
*/
-EAPI Eina_Bool evas_object_image_extension_can_load_fast_get(const char *file);
+EAPI Eina_Bool evas_object_image_extension_can_load_fast_get(const char *file);
/**
* Check if an image object can be animated (have multiple frames)
* This returns if the image file of an image object is capable of animation
* such as an animated gif file might. This is only useful to be called once
* the image object file has been set.
- *
+ *
* Example:
* @code
* extern Evas_Object *obj;
* frame_count = evas_object_image_animated_frame_count_get(obj);
* printf("This image has %d frames\n",frame_count);
*
- * duration = evas_object_image_animated_frame_duration_get(obj,1,0);
+ * duration = evas_object_image_animated_frame_duration_get(obj,1,0);
* printf("Frame 1's duration is %f. You had better set object's frame to 2 after this duration using timer\n");
- *
+ *
* loop_count = evas_object_image_animated_loop_count_get(obj);
* printf("loop count is %d. You had better run loop %d times\n",loop_count,loop_count);
*
* printf("You set image object's frame to 1. You can see frame 1\n");
* }
* @endcode
- *
+ *
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* @see evas_object_image_animated_frame_set()
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_image_animated_get(const Evas_Object *obj);
+EAPI Eina_Bool evas_object_image_animated_get(const Evas_Object *obj);
/**
* Get the total number of frames of the image object.
* @return The number of frames
*
* This returns total number of frames the image object supports (if animated)
- *
+ *
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* @see evas_object_image_animated_frame_set()
* @since 1.1.0
*/
-EAPI int evas_object_image_animated_frame_count_get(const Evas_Object *obj);
+EAPI int evas_object_image_animated_frame_count_get(const Evas_Object *obj);
/**
* Get the kind of looping the image object does.
* @return Loop type of the image object
*
* This returns the kind of looping the image object wants to do.
- *
+ *
* If it returns EVAS_IMAGE_ANIMATED_HINT_LOOP, you should display frames in a sequence like:
* 1->2->3->1->2->3->1...
* If it returns EVAS_IMAGE_ANIMATED_HINT_PINGPONG, it is better to
* display frames in a sequence like: 1->2->3->2->1->2->3->1...
- *
+ *
* The default type is EVAS_IMAGE_ANIMATED_HINT_LOOP.
*
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* This returns loop count of image. The loop count is the number of times
* the animation will play fully from first to last frame until the animation
* should stop (at the final frame).
- *
+ *
* If 0 is returned, then looping should happen indefinitely (no limit to
* the number of times it loops).
*
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* @see evas_object_image_animated_frame_set()
* @since 1.1.0
*/
-EAPI int evas_object_image_animated_loop_count_get(const Evas_Object *obj);
+EAPI int evas_object_image_animated_loop_count_get(const Evas_Object *obj);
/**
* Get the duration of a sequence of frames.
*
* This returns total duration that the specified sequence of frames should
* take in seconds.
- *
+ *
* If you set start_frame to 1 and frame_num 0, you get frame 1's duration
- * If you set start_frame to 1 and frame_num 1, you get frame 1's duration +
+ * If you set start_frame to 1 and frame_num 1, you get frame 1's duration +
* frame2's duration
*
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* @see evas_object_image_animated_frame_set()
* @since 1.1.0
*/
-EAPI double evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int fram_num);
+EAPI double evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int fram_num);
/**
* Set the frame to current frame of an image object
* frame.
*
* @see evas_object_image_animated_get()
- * @see evas_object_image_animated_frame_count_get()
+ * @see evas_object_image_animated_frame_count_get()
* @see evas_object_image_animated_loop_type_get()
* @see evas_object_image_animated_loop_count_get()
* @see evas_object_image_animated_frame_duration_get()
* @see evas_object_image_animated_frame_set()
* @since 1.1.0
*/
-EAPI void evas_object_image_animated_frame_set(Evas_Object *obj, int frame_num);
+EAPI void evas_object_image_animated_frame_set(Evas_Object *obj, int frame_num);
/**
* @}
*/
*
* See some @ref Example_Evas_Text "examples" on this group of functions.
*
+ * @warning We don't guarantee any proper results if you create a Text object
+ * without setting the evas engine.
+ *
* @ingroup Evas_Object_Specific
*/
* arguments, being 'x' your style variable.
*/
#define EVAS_TEXT_STYLE_BASIC_SET(x, s) \
- do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_BASIC) | (s); } while (0)
+ do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_BASIC) | (s); } while (0)
#define EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION (0x7 << 4)
* EVAS_TEXT_STYLE_SHADOW_DIRECTION_* values on 's', incrementally.
*/
#define EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(x, s) \
- do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION) | (s); } while (0)
-
- typedef enum _Evas_Text_Style_Type
- {
- EVAS_TEXT_STYLE_PLAIN, /**< plain, standard text */
- EVAS_TEXT_STYLE_SHADOW, /**< text with shadow underneath */
- EVAS_TEXT_STYLE_OUTLINE, /**< text with an outline */
- EVAS_TEXT_STYLE_SOFT_OUTLINE, /**< text with a soft outline */
- EVAS_TEXT_STYLE_GLOW, /**< text with a glow effect */
- EVAS_TEXT_STYLE_OUTLINE_SHADOW, /**< text with both outline and shadow effects */
- EVAS_TEXT_STYLE_FAR_SHADOW, /**< text with (far) shadow underneath */
- EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW, /**< text with outline and soft shadow effects combined */
- EVAS_TEXT_STYLE_SOFT_SHADOW, /**< text with (soft) shadow underneath */
- EVAS_TEXT_STYLE_FAR_SOFT_SHADOW, /**< text with (far soft) shadow underneath */
-
- /* OR these to modify shadow direction (3 bits needed) */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT = (0x0 << 4), /**< shadow growing to bottom right */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM = (0x1 << 4), /**< shadow growing to the bottom */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT = (0x2 << 4), /**< shadow growing to bottom left */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT = (0x3 << 4), /**< shadow growing to the left */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT = (0x4 << 4), /**< shadow growing to top left */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP = (0x5 << 4), /**< shadow growing to the top */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT = (0x6 << 4), /**< shadow growing to top right */
- EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT = (0x7 << 4) /**< shadow growing to the right */
- } Evas_Text_Style_Type; /**< Types of styles to be applied on text objects. The @c EVAS_TEXT_STYLE_SHADOW_DIRECTION_* ones are to be ORed together with others imposing shadow, to change shadow's direction */
+ do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION) | (s); } while (0)
+
+typedef enum _Evas_Text_Style_Type
+{
+ EVAS_TEXT_STYLE_PLAIN, /**< plain, standard text */
+ EVAS_TEXT_STYLE_SHADOW, /**< text with shadow underneath */
+ EVAS_TEXT_STYLE_OUTLINE, /**< text with an outline */
+ EVAS_TEXT_STYLE_SOFT_OUTLINE, /**< text with a soft outline */
+ EVAS_TEXT_STYLE_GLOW, /**< text with a glow effect */
+ EVAS_TEXT_STYLE_OUTLINE_SHADOW, /**< text with both outline and shadow effects */
+ EVAS_TEXT_STYLE_FAR_SHADOW, /**< text with (far) shadow underneath */
+ EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW, /**< text with outline and soft shadow effects combined */
+ EVAS_TEXT_STYLE_SOFT_SHADOW, /**< text with (soft) shadow underneath */
+ EVAS_TEXT_STYLE_FAR_SOFT_SHADOW, /**< text with (far soft) shadow underneath */
+
+ /* OR these to modify shadow direction (3 bits needed) */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT = (0x0 << 4), /**< shadow growing to bottom right */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM = (0x1 << 4), /**< shadow growing to the bottom */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT = (0x2 << 4), /**< shadow growing to bottom left */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT = (0x3 << 4), /**< shadow growing to the left */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT = (0x4 << 4), /**< shadow growing to top left */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP = (0x5 << 4), /**< shadow growing to the top */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT = (0x6 << 4), /**< shadow growing to top right */
+ EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT = (0x7 << 4) /**< shadow growing to the right */
+} Evas_Text_Style_Type; /**< Types of styles to be applied on text objects. The @c EVAS_TEXT_STYLE_SHADOW_DIRECTION_* ones are to be ORed together with others imposing shadow, to change shadow's direction */
/**
* Creates a new text object on the provided canvas.
* @see evas_object_text_font_set()
* @see evas_object_text_text_set()
*/
-EAPI Evas_Object *evas_object_text_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_text_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Set the font (source) file to be used on a given text object.
*
* @see evas_object_text_font_get()
*/
-EAPI void evas_object_text_font_source_set (Evas_Object *obj, const char *font) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_font_source_set(Evas_Object *obj, const char *font) EINA_ARG_NONNULL(1);
/**
* Get the font file's path which is being used on a given text
*
* @see evas_object_text_font_get() for more details
*/
-EAPI const char *evas_object_text_font_source_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_object_text_font_source_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the font family and size on a given text object.
* @see evas_object_text_font_get()
* @see evas_object_text_font_source_set()
*/
- EAPI void evas_object_text_font_set (Evas_Object *obj, const char *font, Evas_Font_Size size) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size size) EINA_ARG_NONNULL(1);
/**
* Retrieve the font family and size in use on a given text object.
*
* @see evas_object_text_font_set()
*/
-EAPI void evas_object_text_font_get (const Evas_Object *obj, const char **font, Evas_Font_Size *size) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_font_get(const Evas_Object *obj, const char **font, Evas_Font_Size *size) EINA_ARG_NONNULL(1);
/**
* Sets the text string to be displayed by the given text object.
*
* @see evas_object_text_text_get()
*/
-EAPI void evas_object_text_text_set (Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
/**
* Retrieves the text string currently being displayed by the given
*
* @see evas_object_text_text_set()
*/
-EAPI const char *evas_object_text_text_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_object_text_text_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Sets the BiDi delimiters used in the textblock.
* @param delim A null terminated string of delimiters, e.g ",|".
* @since 1.1.0
*/
-EAPI void evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim);
+EAPI void evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim);
/**
* @brief Gets the BiDi delimiters used in the textblock.
* @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
* @since 1.1.0
*/
-EAPI const char *evas_object_text_bidi_delimiters_get(const Evas_Object *obj);
+EAPI const char *evas_object_text_bidi_delimiters_get(const Evas_Object *obj);
- EAPI Evas_Coord evas_object_text_ascent_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_descent_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_max_ascent_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_max_descent_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_horiz_advance_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_vert_advance_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
- EAPI Evas_Coord evas_object_text_inset_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_ascent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_descent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_max_ascent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_max_descent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_horiz_advance_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_vert_advance_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Coord evas_object_text_inset_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve position and dimension information of a character within a text @c Evas_Object.
*
* @return @c EINA_FALSE on success, @c EINA_TRUE on error.
*/
-EAPI Eina_Bool evas_object_text_char_pos_get (const Evas_Object *obj, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
- EAPI int evas_object_text_char_coords_get (const Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI int evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Returns the logical position of the last char in the text
* up to the pos given. this is NOT the position of the last char
* because of the possibility of RTL in the text.
*/
-EAPI int evas_object_text_last_up_to_pos (const Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+EAPI int evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
/**
* Retrieves the style on use on the given text object.
*
* @see evas_object_text_style_set() for more details.
*/
-EAPI Evas_Text_Style_Type evas_object_text_style_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Text_Style_Type evas_object_text_style_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the style to apply on the given text object.
* @see evas_object_text_glow_color_set()
* @see evas_object_text_glow2_color_set()
*/
-EAPI void evas_object_text_style_set (Evas_Object *obj, Evas_Text_Style_Type type) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_style_set(Evas_Object *obj, Evas_Text_Style_Type type) EINA_ARG_NONNULL(1);
/**
* Sets the shadow color for the given text object.
*
* @see evas_object_text_shadow_color_get()
*/
-EAPI void evas_object_text_shadow_color_set (Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_shadow_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
/**
* Retrieves the shadow color for the given text object.
*
* @see evas_object_text_shadow_color_set() for more details.
*/
-EAPI void evas_object_text_shadow_color_get (const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_shadow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
/**
* Sets the glow color for the given text object.
*
* @see evas_object_text_glow_color_get()
*/
-EAPI void evas_object_text_glow_color_set (Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_glow_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
/**
* Retrieves the glow color for the given text object.
*
* @see evas_object_text_glow_color_set() for more details.
*/
-EAPI void evas_object_text_glow_color_get (const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_glow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
/**
* Sets the 'glow 2' color for the given text object.
*
* @see evas_object_text_glow2_color_get()
*/
-EAPI void evas_object_text_glow2_color_set (Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_glow2_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
/**
* Retrieves the 'glow 2' color for the given text object.
*
* @see evas_object_text_glow2_color_set() for more details.
*/
-EAPI void evas_object_text_glow2_color_get (const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_glow2_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
/**
* Sets the outline color for the given text object.
*
* @see evas_object_text_outline_color_get()
*/
-EAPI void evas_object_text_outline_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_outline_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
/**
* Retrieves the outline color for the given text object.
*
* @see evas_object_text_outline_color_set() for more details.
*/
-EAPI void evas_object_text_outline_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_outline_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
/**
* Gets the text style pad of a text object.
* @param b The bottom pad (or @c NULL).
*
*/
-EAPI void evas_object_text_style_pad_get (const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_text_style_pad_get(const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
/**
* Retrieves the direction of the text currently being displayed in the
* @param obj The given evas text object.
* @return the direction of the text
*/
-EAPI Evas_BiDi_Direction evas_object_text_direction_get (const Evas_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+EAPI Evas_BiDi_Direction evas_object_text_direction_get(const Evas_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
/**
* @}
* @li ellipsis - Value between 0.0-1.0 to indicate the type of ellipsis, or -1.0 to indicate ellipsis isn't wanted.
* @li password - "on" or "off". This is used to specifically turn replacing chars with the replacement char (i.e password mode) on and off.
*
+ * @warning We don't guarantee any proper results if you create a Textblock
+ * object
+ * without setting the evas engine.
*
* @todo put here some usage examples
*
* @{
*/
- typedef struct _Evas_Textblock_Style Evas_Textblock_Style;
- typedef struct _Evas_Textblock_Cursor Evas_Textblock_Cursor;
- /**
- * @typedef Evas_Object_Textblock_Node_Format
- * A format node.
- */
- typedef struct _Evas_Object_Textblock_Node_Format Evas_Object_Textblock_Node_Format;
- typedef struct _Evas_Textblock_Rectangle Evas_Textblock_Rectangle;
-
- struct _Evas_Textblock_Rectangle
- {
- Evas_Coord x, y, w, h;
- };
+typedef struct _Evas_Textblock_Style Evas_Textblock_Style;
+typedef struct _Evas_Textblock_Cursor Evas_Textblock_Cursor;
+/**
+ * @typedef Evas_Object_Textblock_Node_Format
+ * A format node.
+ */
+typedef struct _Evas_Object_Textblock_Node_Format Evas_Object_Textblock_Node_Format;
+typedef struct _Evas_Textblock_Rectangle Evas_Textblock_Rectangle;
- typedef enum _Evas_Textblock_Text_Type
- {
- EVAS_TEXTBLOCK_TEXT_RAW,
- EVAS_TEXTBLOCK_TEXT_PLAIN,
- EVAS_TEXTBLOCK_TEXT_MARKUP
- } Evas_Textblock_Text_Type;
+struct _Evas_Textblock_Rectangle
+{
+ Evas_Coord x, y, w, h;
+};
- typedef enum _Evas_Textblock_Cursor_Type
- {
- EVAS_TEXTBLOCK_CURSOR_UNDER,
- EVAS_TEXTBLOCK_CURSOR_BEFORE
- } Evas_Textblock_Cursor_Type;
+typedef enum _Evas_Textblock_Text_Type
+{
+ EVAS_TEXTBLOCK_TEXT_RAW,
+ EVAS_TEXTBLOCK_TEXT_PLAIN,
+ EVAS_TEXTBLOCK_TEXT_MARKUP
+} Evas_Textblock_Text_Type;
+typedef enum _Evas_Textblock_Cursor_Type
+{
+ EVAS_TEXTBLOCK_CURSOR_UNDER,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE
+} Evas_Textblock_Cursor_Type;
/**
* Adds a textblock to the given evas.
* @param e The given evas.
* @return The new textblock object.
*/
-EAPI Evas_Object *evas_object_textblock_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
-
+EAPI Evas_Object *evas_object_textblock_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Returns the unescaped version of escape.
* @param escape the string to be escaped
* @return the unescaped version of escape
*/
-EAPI const char *evas_textblock_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_textblock_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Returns the escaped version of the string.
* @param len_ret the len of the part of the string that was used.
* @return the escaped string.
*/
-EAPI const char *evas_textblock_string_escape_get(const char *string, int *len_ret) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_textblock_string_escape_get(const char *string, int *len_ret) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Return the unescaped version of the string between start and end.
* @param escape_end the end of the string.
* @return the unescaped version of the range
*/
-EAPI const char *evas_textblock_escape_string_range_get(const char *escape_start, const char *escape_end) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI const char *evas_textblock_escape_string_range_get(const char *escape_start, const char *escape_end) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Return the plain version of the markup.
* version of the text. i.e: <br> and <\n> will be replaced with \n, &...; with
* the actual char and etc.
*
- * @param obj The textblock object to work with. (if @c NULL, tries the
+ * @param obj The textblock object to work with. (if @c NULL, tries the
* default).
* @param text The markup text (if @c NULL, return @c NULL).
* @return An allocated plain text version of the markup.
* @since 1.2.0
*/
-EAPI char *evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+EAPI char *evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
/**
* Return the markup version of the plain text.
* @return An allocated plain text version of the markup.
* @since 1.2.0
*/
-EAPI char *evas_textblock_text_utf8_to_markup(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+EAPI char *evas_textblock_text_utf8_to_markup(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
/**
* Creates a new textblock style.
* @return The new textblock style.
*/
-EAPI Evas_Textblock_Style *evas_textblock_style_new(void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+EAPI Evas_Textblock_Style *evas_textblock_style_new(void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
/**
* Destroys a textblock style.
* @param ts The textblock style to free.
*/
-EAPI void evas_textblock_style_free(Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_style_free(Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
/**
* Sets the style ts to the style passed as text by text.
* @param text the text to parse - NOT NULL.
* @return Returns no value.
*/
-EAPI void evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) EINA_ARG_NONNULL(1);
/**
* Return the text of the style ts.
* @param ts the style to get it's text.
* @return the text of the style or null on error.
*/
-EAPI const char *evas_textblock_style_get(const Evas_Textblock_Style *ts) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI const char *evas_textblock_style_get(const Evas_Textblock_Style *ts) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the objects style to ts.
* @param ts the style to set.
* @return Returns no value.
*/
-EAPI void evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
/**
* Return the style of an object.
* @param obj the object to get the style from.
* @return the style of the object.
*/
-EAPI const Evas_Textblock_Style *evas_object_textblock_style_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const Evas_Textblock_Style *evas_object_textblock_style_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Push ts to the top of the user style stack.
* @see evas_object_textblock_style_set
* @since 1.2.0
*/
-EAPI void evas_object_textblock_style_user_push(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_style_user_push(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
/**
* Del the from the top of the user style stack.
* @see evas_object_textblock_style_get
* @since 1.2.0
*/
-EAPI void evas_object_textblock_style_user_pop(Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_style_user_pop(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Get (don't remove) the style at the top of the user style stack.
* @see evas_object_textblock_style_get
* @since 1.2.0
*/
-EAPI const Evas_Textblock_Style *evas_object_textblock_style_user_peek(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const Evas_Textblock_Style *evas_object_textblock_style_user_peek(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Set the "replacement character" to use for the given textblock object.
* @param obj The given textblock object.
* @param ch The charset name.
*/
-EAPI void evas_object_textblock_replace_char_set(Evas_Object *obj, const char *ch) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_replace_char_set(Evas_Object *obj, const char *ch) EINA_ARG_NONNULL(1);
/**
* @brief Get the "replacement character" for given textblock object. Returns
* @param obj The given textblock object
* @return Replacement character or @c NULL.
*/
-EAPI const char *evas_object_textblock_replace_char_get(Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_object_textblock_replace_char_get(Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Sets the vertical alignment of text within the textblock object
* @param align A value between @c 0.0 and @c 1.0.
* @since 1.1.0
*/
-EAPI void evas_object_textblock_valign_set(Evas_Object *obj, double align);
+EAPI void evas_object_textblock_valign_set(Evas_Object *obj, double align);
/**
* @brief Gets the vertical alignment of a textblock
* @return The alignment set for the object.
* @since 1.1.0
*/
-EAPI double evas_object_textblock_valign_get(const Evas_Object *obj);
+EAPI double evas_object_textblock_valign_get(const Evas_Object *obj);
/**
* @brief Sets the BiDi delimiters used in the textblock.
* @param delim A null terminated string of delimiters, e.g ",|".
* @since 1.1.0
*/
-EAPI void evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim);
+EAPI void evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim);
/**
* @brief Gets the BiDi delimiters used in the textblock.
* @c NULL.
* @since 1.1.0
*/
-EAPI const char *evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj);
+EAPI const char *evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj);
/**
* @brief Sets newline mode. When true, newline character will behave
* @param mode @c EINA_TRUE for legacy mode, @c EINA_FALSE otherwise.
* @since 1.1.0
*/
-EAPI void evas_object_textblock_legacy_newline_set(Evas_Object *obj, Eina_Bool mode) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_legacy_newline_set(Evas_Object *obj, Eina_Bool mode) EINA_ARG_NONNULL(1);
/**
* @brief Gets newline mode. When true, newline character behaves
* @return @c EINA_TRUE if in legacy mode, @c EINA_FALSE otherwise.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_textblock_legacy_newline_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_object_textblock_legacy_newline_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Sets the tetxblock's text to the markup text.
* @param text the markup text to use.
* @return Return no value.
*/
-EAPI void evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
/**
* Prepends markup to the cursor cur.
* @param text the markup text to prepend.
* @return Return no value.
*/
-EAPI void evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
/**
* Return the markup of the object.
* @param obj the Evas object.
* @return the markup text of the object.
*/
-EAPI const char *evas_object_textblock_text_markup_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
-
+EAPI const char *evas_object_textblock_text_markup_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Return the object's main cursor.
* @param obj the object.
* @return The @p obj's main cursor.
*/
-EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Create a new cursor, associate it to the obj and init it to point
* @param obj the object to associate to.
* @return the new cursor.
*/
-EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_new(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
-
+EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_new(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Free the cursor and unassociate it from the object.
* @param cur the cursor to free.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_free(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
-
+EAPI void evas_textblock_cursor_free(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Sets the cursor to the start of the first text node.
* @param cur the cursor to update.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_paragraph_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_paragraph_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* sets the cursor to the end of the last text node.
* @param cur the cursor to set.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_paragraph_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_paragraph_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Advances to the start of the next text node
* @return @c EINA_TRUE if it managed to advance a paragraph, @c EINA_FALSE
* otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_paragraph_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_paragraph_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Advances to the end of the previous text node
* @return @c EINA_TRUE if it managed to advance a paragraph, @c EINA_FALSE
* otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_paragraph_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_paragraph_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Returns the
* @param anchor the anchor name to get
* @return Returns the list format node corresponding to the anchor, may be null if there are none.
*/
-EAPI const Eina_List *evas_textblock_node_format_list_get(const Evas_Object *obj, const char *anchor) EINA_ARG_NONNULL(1, 2);
+EAPI const Eina_List *evas_textblock_node_format_list_get(const Evas_Object *obj, const char *anchor) EINA_ARG_NONNULL(1, 2);
/**
* Returns the first format node.
* @param obj the Evas object of the textblock - not null.
* @param n the current format node - not null.
*/
-EAPI void evas_textblock_node_format_remove_pair(Evas_Object *obj, Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_textblock_node_format_remove_pair(Evas_Object *obj, Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
/**
* Sets the cursor to point to the place where format points to.
* @param n the format node to update according.
* @deprecated duplicate of evas_textblock_cursor_at_format_set
*/
-EAPI void evas_textblock_cursor_set_at_format(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_textblock_cursor_set_at_format(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
/**
* Return the format node at the position pointed by cur.
* @param fnode the format node.
* @return the textual format of the format node.
*/
-EAPI const char *evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fnode) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fnode) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the cursor to point to the position of fmt.
* @param cur the cursor to update
* @param fmt the format to update according to.
*/
-EAPI void evas_textblock_cursor_at_format_set(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *fmt) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_textblock_cursor_at_format_set(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *fmt) EINA_ARG_NONNULL(1, 2);
/**
* Check if the current cursor position is a visible format. This way is more
* otherwise.
* @see evas_textblock_cursor_format_get()
*/
-EAPI Eina_Bool evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Advances to the next format node
* @param cur the cursor to be updated.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_format_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_format_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Advances to the previous format node.
* @param cur the cursor to update.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Returns true if the cursor points to a format.
* @return @c EINA_TRUE if a cursor points to a format @c EINA_FALSE
* otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_is_format(const Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_is_format(const Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Advances 1 char forward.
* @param cur the cursor to advance.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Advances 1 char backward.
* @param cur the cursor to advance.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Moves the cursor to the start of the word under the cursor.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
* @since 1.2.0
*/
-EAPI Eina_Bool evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Moves the cursor to the end of the word under the cursor.
* @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
* @since 1.2.0
*/
-EAPI Eina_Bool evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Go to the first char in the node the cursor is pointing on.
* @param cur the cursor to update.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Go to the last char in a text node.
* @param cur the cursor to update.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_paragraph_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_paragraph_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Go to the start of the current line
* @param cur the cursor to update.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Go to the end of the current line.
* @param cur the cursor to update.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_line_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_line_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Return the current cursor pos.
* @param cur the cursor to take the position from.
* @return the position or -1 on error
*/
-EAPI int evas_textblock_cursor_pos_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_pos_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set the cursor pos.
* @param cur the cursor to be set.
* @param pos the pos to set.
*/
-EAPI void evas_textblock_cursor_pos_set(Evas_Textblock_Cursor *cur, int pos) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_pos_set(Evas_Textblock_Cursor *cur, int pos) EINA_ARG_NONNULL(1);
/**
* Go to the start of the line passed
* @param line numer to set.
* @return @c EINA_TRUE on success, @c EINA_FALSE on error.
*/
-EAPI Eina_Bool evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line) EINA_ARG_NONNULL(1);
/**
* Compare two cursors.
* @param cur2 the second cursor.
* @return -1 if cur1 < cur2, 0 if cur1 == cur2 and 1 otherwise.
*/
-EAPI int evas_textblock_cursor_compare(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI int evas_textblock_cursor_compare(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Make cur_dest point to the same place as cur. Does not work if they don't
* @param cur_dest destination cursor.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_copy(const Evas_Textblock_Cursor *cur, Evas_Textblock_Cursor *cur_dest) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_textblock_cursor_copy(const Evas_Textblock_Cursor *cur, Evas_Textblock_Cursor *cur_dest) EINA_ARG_NONNULL(1, 2);
/**
* Adds text to the current cursor position and set the cursor to *before*
* @return Returns the len of the text added.
* @see evas_textblock_cursor_text_prepend()
*/
-EAPI int evas_textblock_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
+EAPI int evas_textblock_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
/**
* Adds text to the current cursor position and set the cursor to *after*
* @return Returns the len of the text added.
* @see evas_textblock_cursor_text_append()
*/
-EAPI int evas_textblock_cursor_text_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
-
+EAPI int evas_textblock_cursor_text_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
/**
* Adds format to the current cursor position. If the format being added is a
* @param cur the cursor to look at.
* @return @c EINA_TRUE if the cursor points to the terminating null, @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
/**
* Adds format to the current cursor position. If the format being added is a
* @return Returns true if a visible format was added, false otherwise.
* @see evas_textblock_cursor_format_prepend()
*/
-EAPI Eina_Bool evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
/**
* Delete the character at the location of the cursor. If there's a format
* @param cur the cursor pointing to the current location.
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+EAPI void evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Delete the range between cur1 and cur2.
* @param cur2 the second side of the range
* @return Returns no value.
*/
-EAPI void evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2) EINA_ARG_NONNULL(1, 2);
/**
* Return the text of the paragraph cur points to - returns the text in markup.
* @param cur the cursor pointing to the paragraph.
* @return the text on success, @c NULL otherwise.
*/
-EAPI const char *evas_textblock_cursor_paragraph_text_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_textblock_cursor_paragraph_text_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Return the length of the paragraph, cheaper the eina_unicode_strlen()
* @param cur the position of the paragraph.
* @return the length of the paragraph on success, -1 otehrwise.
*/
-EAPI int evas_textblock_cursor_paragraph_text_length_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_paragraph_text_length_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Return the currently visible range.
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textblock_Cursor *end) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textblock_Cursor *end) EINA_ARG_NONNULL(1, 2);
/**
* Return the format nodes in the range between cur1 and cur2.
* @return the foramt nodes in the range. You have to free it.
* @since 1.1.0
*/
-EAPI Eina_List * evas_textblock_cursor_range_formats_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_List *evas_textblock_cursor_range_formats_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Return the text in the range between cur1 and cur2
* @return the text in the range
* @see elm_entry_markup_to_utf8()
*/
-EAPI char *evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI char *evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Return the content of the cursor.
*
* Free the returned string pointer when done (if it is not NULL).
- *
+ *
* @param cur the cursor
* @return the text in the range, terminated by a nul byte (may be utf8).
*/
-EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
-
+EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Returns the geometry of the cursor. Depends on the type of cursor requested.
* @param ctype the type of the cursor.
* @return line number of the char on success, -1 on error.
*/
-EAPI int evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *dir, Evas_Textblock_Cursor_Type ctype) EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *dir, Evas_Textblock_Cursor_Type ctype) EINA_ARG_NONNULL(1);
/**
* Returns the geometry of the char at cur.
* @param ch the h of the char.
* @return line number of the char on success, -1 on error.
*/
-EAPI int evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Returns the geometry of the pen at cur.
* @param ch the h of the char.
* @return line number of the char on success, -1 on error.
*/
-EAPI int evas_textblock_cursor_pen_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cpen_x, Evas_Coord *cy, Evas_Coord *cadv, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_pen_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cpen_x, Evas_Coord *cy, Evas_Coord *cadv, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Returns the geometry of the line at cur.
* @param ch the height of the line.
* @return line number of the line on success, -1 on error.
*/
-EAPI int evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Set the position of the cursor according to the X and Y coordinates.
* @param y coord to set by.
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
/**
* Set the cursor position according to the y coord.
* @param y the coord to set by.
* @return the line number found, -1 on error.
*/
-EAPI int evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y) EINA_ARG_NONNULL(1);
+EAPI int evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y) EINA_ARG_NONNULL(1);
/**
* Get the geometry of a range.
* @param cur2 other side of the range.
* @return a list of Rectangles representing the geometry of the range.
*/
-EAPI Eina_List *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
- EAPI Eina_Bool evas_textblock_cursor_format_item_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
-
+EAPI Eina_List *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_textblock_cursor_format_item_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Checks if the cursor points to the end of the line.
* @param cur the cursor to check.
* @return @c EINA_TRUE if true, @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI Eina_Bool evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the geometry of a line number.
* @param ch h coord of the line.
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*/
-EAPI Eina_Bool evas_object_textblock_line_number_geometry_get(const Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_textblock_line_number_geometry_get(const Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
/**
* Clear the textblock object.
* @param obj the object to clear.
* @return nothing.
*/
-EAPI void evas_object_textblock_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Get the formatted width and height. This calculates the actual size after restricting
* @return Returns no value.
* @see evas_object_textblock_size_native_get
*/
-EAPI void evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
/**
* Get the native width and height. This calculates the actual size without taking account
* @param h the height returned
* @return Returns no value.
*/
-EAPI void evas_object_textblock_size_native_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
- EAPI void evas_object_textblock_style_insets_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_size_native_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_textblock_style_insets_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Evas_Object_Textgrid Textgrid Object Functions
+ *
+ * @todo put here some usage examples
+ *
+ * @since 1.3
+ *
+ * @ingroup Evas_Object_Specific
+ *
+ * @{
+ */
+
+/**
+ * @typedef Evas_Textgrid_Palette
+ *
+ * The palette to use for the forgraound and background colors.
+ *
+ * @since 1.3
+ */
+typedef enum
+{
+ EVAS_TEXTGRID_PALETTE_NONE, /**< No palette is used */
+ EVAS_TEXTGRID_PALETTE_STANDARD, /**< standard palette (around 16 colors) */
+ EVAS_TEXTGRID_PALETTE_EXTENDED, /**< extended palette (at max 256 colors) */
+ EVAS_TEXTGRID_PALETTE_LAST /**< ignore it */
+} Evas_Textgrid_Palette;
+
+/**
+ * @typedef Evas_Textgrid_Font_Style
+ *
+ * The style to give to each character of the grid.
+ *
+ * @since 1.3
+ */
+typedef enum
+{
+ EVAS_TEXTGRID_FONT_STYLE_NORMAL = (1 << 0), /**< Normal style */
+ EVAS_TEXTGRID_FONT_STYLE_BOLD = (1 << 1), /**< Bold style */
+ EVAS_TEXTGRID_FONT_STYLE_ITALIC = (1 << 2) /**< Oblique style */
+} Evas_Textgrid_Font_Style;
+
+/**
+ * @typedef Evas_Textgrid_Cell
+ *
+ * The values that describes each cell.
+ *
+ * @since 1.3
+ */
+typedef struct _Evas_Textgrid_Cell Evas_Textgrid_Cell;
+
+/**
+ * @struct _Evas_Textgrid_Cell
+ *
+ * The values that describes each cell.
+ *
+ * @since 1.3
+ */
+struct _Evas_Textgrid_Cell
+{
+ Eina_Unicode codepoint; /**< the UNICODE value of the character */
+ unsigned char fg; /**< the index of the palette for the foreground color */
+ unsigned char bg; /**< the index of the palette for the background color */
+ unsigned short bold : 1; /**< whether the character is bold */
+ unsigned short italic : 1; /**< whether the character is oblique */
+ unsigned short underline : 1; /**< whether the character is underlined */
+ unsigned short strikethrough : 1; /**< whether the character is strikethrough'ed */
+ unsigned short fg_extended : 1; /**< whether the extended palette is used for the foreground color */
+ unsigned short bg_extended : 1; /**< whether the extended palette is used for the background color */
+};
+
+/**
+ * @brief Add a textgrid to the given Evas.
+ *
+ * @param e The given evas.
+ * @return The new textgrid object.
+ *
+ * This function adds a new textgrid object to the Evas @p e and returns the object.
+ *
+ * @since 1.3
+ */
+EAPI Evas_Object *evas_object_textgrid_add(Evas *e);
+
+/**
+ * @brief Set the size of the textgrid object.
+ *
+ * @param obj The textgrid object.
+ * @param w The number of columns (width in cells) of the grid.
+ * @param h The number of rows (height in cells) of the grid.
+ *
+ * This function sets the number of lines @p h and the number
+ * of columns @p w to the textgrid object @p obj. If
+ * @p w or @p h are less or equal than 0, this
+ * functiond does nothing.
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_size_set(Evas_Object *obj, int w, int h);
+
+/**
+ * @brief Get the size of the textgrid object.
+ *
+ * @param obj The textgrid object.
+ * @param w The number of columns of the grid.
+ * @param h The number of rows of the grid.
+ *
+ * This function retrieves the number of lines in the buffer @p
+ * h and the number of columns in the buffer @p w of
+ * the textgrid object @p obj. @p w or @p h can be
+ * @c NULL. On error, their value is 0.
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_size_get(const Evas_Object *obj, int *w, int *h);
+
+/**
+ * @brief Set the font (source) file to be used on a given textgrid object.
+ *
+ * @param obj The textgrid object to set font for.
+ * @param font_source The font file's path.
+ *
+ * This function allows the font file @p font_source to be explicitly
+ * set for the textgrid object @p obj, overriding system lookup, which
+ * will first occur in the given file's contents. If @font_source is
+ * @c NULL or is an empty string, or the same font_source has already
+ * been set, or on error, this function does nothing.
+ *
+ * @see evas_object_textgrid_font_get()
+ * @see evas_object_textgrid_font_set()
+ * @see evas_object_textgrid_font_source_get()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_font_source_set(Evas_Object *obj, const char *font_source);
+
+/**
+ * @brief Get the font file's path which is being used on a given textgrid object.
+ *
+ * @param obj The textgrid object to set font for.
+ * @return The font file's path.
+ *
+ * This function returns the font source path of the textgrid object
+ * @p obj. If the font source path has not been set, or on error,
+ * @c NULL is returned.
+ *
+ * @see evas_object_textgrid_font_get()
+ * @see evas_object_textgrid_font_set()
+ * @see evas_object_textgrid_font_source_set()
+ *
+ * @since 1.3
+ */
+EAPI const char *evas_object_textgrid_font_source_get(const Evas_Object *obj);
+
+/**
+ * @brief Set the font family and size on a given textgrid object.
+ *
+ * @param obj The textgrid object to set font for.
+ * @param font_name The font (family) name.
+ * @param font_size The font size, in points.
+ *
+ * This function allows the font name @p font_name and size
+ * @p font_size of the textgrid object @p obj to be set. The @p font_name
+ * string has to follow fontconfig's convention on naming fonts, as
+ * it's the underlying library used to query system fonts by Evas (see
+ * the @c fc-list command's output, on your system, to get an
+ * idea). It also has to be a monospace font. If @p font_name is
+ * @c NULL, or if it is an empty string, or if @p font_size is less or
+ * equal than 0, or on error, this function does nothing.
+ *
+ * @see evas_object_textgrid_font_get()
+ * @see evas_object_textgrid_font_source_set()
+ * @see evas_object_textgrid_font_source_get()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font_Size font_size);
+
+/**
+ * @brief Retrieve the font family and size in use on a given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param font_name A pointer to the location to store the font name in.
+ * @param font_size A pointer to the location to store the font size in.
+ *
+ * This function allows the font name and size of a textgrid object
+ * @p obj to be queried and stored respectively in the buffers
+ * @p font_name and @p font_size. Be aware that the font name string is
+ * still owned by Evas and should @b not have free() called on it by
+ * the caller of the function. On error, the font name is the empty
+ * string and the font size is 0. @p font_name and @p font_source can
+ * be @c NULL.
+ *
+ * @see evas_object_textgrid_font_set()
+ * @see evas_object_textgrid_font_source_set()
+ * @see evas_object_textgrid_font_source_get()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_font_get(const Evas_Object *obj, const char **font_name, Evas_Font_Size *font_size);
+
+/**
+ * @brief Retrieve the size of a cell of the given textgrid object in pixels.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param width A pointer to the location to store the width in pixels of a cell.
+ * @param height A pointer to the location to store the height in
+ * pixels of a cell.
+ *
+ * This functions retrieves the width and height, in pixels, of a cell
+ * of the textgrid object @p obj and store them respectively in the
+ * buffers @p width and @p height. Their value depends on the
+ * monospace font used for the textgrid object, as well as the
+ * style. @p width and @p height can be @c NULL. On error, they are
+ * set to 0.
+ *
+ * @see evas_object_textgrid_font_set()
+ * @see evas_object_textgrid_supported_font_styles_set()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_cell_size_get(const Evas_Object *obj, int *width, int *height);
+
+/**
+ * @brief The set color to the given palette at the given index of the given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param pal The type of the palette to set the color.
+ * @param idx The index of the paletter to wich the color is stored.
+ * @param r The red component of the color.
+ * @param g The green component of the color.
+ * @param b The blue component of the color.
+ * @param a The alpha component of the color.
+ *
+ * This function sets the color for the palette of type @p pal at the
+ * index @p idx of the textgrid object @p obj. The ARGB components are
+ * given by @p r, @p g, @p b and @p a. This color can be used when
+ * setting the #Evas_Textgrid_Cell structure. The components must set
+ * a pre-multiplied color. If pal is #EVAS_TEXTGRID_PALETTE_NONE or
+ * #EVAS_TEXTGRID_PALETTE_LAST, or if @p idx is not between 0 and 255,
+ * or on error, this function does nothing. The color components are
+ * clamped between 0 and 255. If @p idx is greater than the latest set
+ * color, the colors between this last index and @p idx - 1 are set to
+ * black (0, 0, 0, 0).
+ *
+ * @see evas_object_textgrid_palette_get()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_palette_set(Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int r, int g, int b, int a);
+
+/**
+ * @brief The retrieve color to the given palette at the given index of the given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param pal The type of the palette to set the color.
+ * @param idx The index of the paletter to wich the color is stored.
+ * @param r A pointer to the red component of the color.
+ * @param g A pointer to the green component of the color.
+ * @param b A pointer to the blue component of the color.
+ * @param a A pointer to the alpha component of the color.
+ *
+ * This function retrieves the color for the palette of type @p pal at the
+ * index @p idx of the textgrid object @p obj. The ARGB components are
+ * stored in the buffers @p r, @p g, @p b and @p a. If @p idx is not
+ * between 0 and the index of the latest set color, or if @p pal is
+ * #EVAS_TEXTGRID_PALETTE_NONE or #EVAS_TEXTGRID_PALETTE_LAST, the
+ * values of the components are 0. @p r, @p g, @pb and @p a can be
+ * @c NULL.
+ *
+ * @see evas_object_textgrid_palette_set()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_palette_get(const Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int *r, int *g, int *b, int *a);
+
+EAPI void evas_object_textgrid_supported_font_styles_set(Evas_Object *obj, Evas_Textgrid_Font_Style styles);
+EAPI Evas_Textgrid_Font_Style evas_object_textgrid_supported_font_styles_get(const Evas_Object *obj);
+
+/**
+ * @brief Set the string at the given row of the given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param y The row index of the grid.
+ * @param The string as a sequence of #Evas_Textgrid_Cell.
+ *
+ * This function returns cells to the textgrid taken by
+ * evas_object_textgrid_cellrow_get(). The row pointer @p row should be the
+ * same row pointer returned by evas_object_textgrid_cellrow_get() for the
+ * same row @p y.
+ *
+ * @see evas_object_textgrid_cellrow_get()
+ * @see evas_object_textgrid_size_set()
+ * @see evas_object_textgrid_update_add()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_cellrow_set(Evas_Object *obj, int y, const Evas_Textgrid_Cell *row);
+
+/**
+ * @brief Get the string at the given row of the given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param y The row index of the grid.
+ * @return A pointer to the first cell of the given row.
+ *
+ * This function returns a pointer to the first cell of the line @p y
+ * of the textgrid object @p obj. If @p y is not between 0 and the
+ * number of lines of the grid - 1, or on error, this function return @c NULL.
+ *
+ * @see evas_object_textgrid_cellrow_set()
+ * @see evas_object_textgrid_size_set()
+ * @see evas_object_textgrid_update_add()
+ *
+ * @since 1.3
+ */
+EAPI Evas_Textgrid_Cell *evas_object_textgrid_cellrow_get(const Evas_Object *obj, int y);
+
+/**
+ * @brief Get the string at the given row of the given textgrid object.
+ *
+ * @param obj The textgrid object to query for font information.
+ * @param x The rect region of cells top-left x (column)
+ * @param y The rect region of cells top-left y (row)
+ * @param w The rect region size in number of cells (columns)
+ * @param h The rect region size in number of cells (rows)
+ *
+ * This function delcares to evas that a region of cells was updated by
+ * code and needs refreshing. An application should modify cells like this
+ * as an example:
+ *
+ * @code
+ * Evas_Textgrid_Cell *cells;
+ * int i;
+ *
+ * cells = evas_object_textgrid_cellrow_get(obj, row);
+ * for (i = 0; i < width; i++) cells[i].codepoint = 'E';
+ * evas_object_textgrid_cellrow_set(obj, row, cells);
+ * evas_object_textgrid_update_add(obj, 0, row, width, 1);
+ * @endcode
+ *
+ * @see evas_object_textgrid_cellrow_set()
+ * @see evas_object_textgrid_cellrow_get()
+ * @see evas_object_textgrid_size_set()
+ *
+ * @since 1.3
+ */
+EAPI void evas_object_textgrid_update_add(Evas_Object *obj, int x, int y, int w, int h);
+
/**
* @}
*/
*
* Functions used to deal with evas line objects.
*
+ * @warning We don't guarantee any proper results if you create a Line object
+ * without setting the evas engine.
+ *
* @ingroup Evas_Object_Specific
*
* @{
* @param e The given evas.
* @return The new evas line object.
*/
-EAPI Evas_Object *evas_object_line_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_line_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Sets the coordinates of the end points of the given evas line object.
* @param x2 The X coordinate of the second point.
* @param y2 The Y coordinate of the second point.
*/
-EAPI void evas_object_line_xy_set (Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2);
+EAPI void evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2);
/**
* Retrieves the coordinates of the end points of the given evas line object.
* @param y2 Pointer to an integer in which to store the Y coordinate of the
* second end point.
*/
-EAPI void evas_object_line_xy_get (const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2);
+EAPI void evas_object_line_xy_get(const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2);
/**
* @}
*/
* Hint: as evas does not provide ellipse, smooth paths or circle, one
* can calculate points and convert these to a polygon.
*
+ * @warning We don't guarantee any proper results if you create a Polygon
+ * object without setting the evas engine.
+ *
* @ingroup Evas_Object_Specific
*
* @{
* @param e The given evas.
* @return A new evas polygon object.
*/
-EAPI Evas_Object *evas_object_polygon_add (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_polygon_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Adds the given point to the given evas polygon object.
* @param y The Y coordinate of the given point.
* @ingroup Evas_Polygon_Group
*/
-EAPI void evas_object_polygon_point_add (Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+EAPI void evas_object_polygon_point_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
/**
* Removes all of the points from the given evas polygon object.
* @param obj The given polygon object.
*/
-EAPI void evas_object_polygon_points_clear (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_polygon_points_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* @}
*/
/* @since 1.2.0 */
-EAPI void evas_object_is_frame_object_set(Evas_Object *obj, Eina_Bool is_frame);
+EAPI void evas_object_is_frame_object_set(Evas_Object *obj, Eina_Bool is_frame);
/* @since 1.2.0 */
-EAPI Eina_Bool evas_object_is_frame_object_get(Evas_Object *obj);
+EAPI Eina_Bool evas_object_is_frame_object_get(Evas_Object *obj);
/**
* @defgroup Evas_Smart_Group Smart Functions
*/
struct _Evas_Smart_Class
{
- const char *name; /**< the name string of the class */
- int version;
- void (*add) (Evas_Object *o); /**< code to be run when adding object to a canvas */
- void (*del) (Evas_Object *o); /**< code to be run when removing object to a canvas */
- void (*move) (Evas_Object *o, Evas_Coord x, Evas_Coord y); /**< code to be run when moving object on a canvas */
- void (*resize) (Evas_Object *o, Evas_Coord w, Evas_Coord h); /**< code to be run when resizing object on a canvas */
- void (*show) (Evas_Object *o); /**< code to be run when showing object on a canvas */
- void (*hide) (Evas_Object *o); /**< code to be run when hiding object on a canvas */
- void (*color_set) (Evas_Object *o, int r, int g, int b, int a); /**< code to be run when setting color of object on a canvas */
- void (*clip_set) (Evas_Object *o, Evas_Object *clip); /**< code to be run when setting clipper of object on a canvas */
- void (*clip_unset) (Evas_Object *o); /**< code to be run when unsetting clipper of object on a canvas */
- void (*calculate) (Evas_Object *o); /**< code to be run when object has rendering updates on a canvas */
- void (*member_add) (Evas_Object *o, Evas_Object *child); /**< code to be run when child member is added to object */
- void (*member_del) (Evas_Object *o, Evas_Object *child); /**< code to be run when child member is removed from object */
+ const char *name; /**< the name string of the class */
+ int version;
+ void (*add)(Evas_Object *o); /**< code to be run when adding object to a canvas */
+ void (*del)(Evas_Object *o); /**< code to be run when removing object from a canvas */
+ void (*move)(Evas_Object *o, Evas_Coord x, Evas_Coord y); /**< code to be run when moving object on a canvas. @a x and @a y will be new coordinates one applied to the object. use evas_object_geometry_get() if you need the old values, during this call. after that, the old values will be lost. */
+ void (*resize)(Evas_Object *o, Evas_Coord w, Evas_Coord h); /**< code to be run when resizing object on a canvas. @a w and @a h will be new dimensions one applied to the object. use evas_object_geometry_get() if you need the old values, during this call. after that, the old values will be lost. */
+ void (*show)(Evas_Object *o); /**< code to be run when showing object on a canvas */
+ void (*hide)(Evas_Object *o); /**< code to be run when hiding object on a canvas */
+ void (*color_set)(Evas_Object *o, int r, int g, int b, int a); /**< code to be run when setting color of object on a canvas. @a r, @a g, @a b and @a y will be new color components one applied to the object. use evas_object_color_get() if you need the old values, during this call. after that, the old values will be lost. */
+ void (*clip_set)(Evas_Object *o, Evas_Object *clip); /**< code to be run when setting clipper of object on a canvas. @a clip will be new clipper one applied to the object. use evas_object_clip_get() if you need the old one, during this call. after that, the old (object pointer) value will be lost. */
+ void (*clip_unset)(Evas_Object *o); /**< code to be run when unsetting clipper of object on a canvas. if you need the pointer to a previous set clipper, during this call, use evas_object_clip_get(). after that, the old (object pointer) value will be lost. */
+ void (*calculate)(Evas_Object *o); /**< code to be run when object has rendering updates on a canvas */
+ void (*member_add)(Evas_Object *o, Evas_Object *child); /**< code to be run when a child member is added to object */
+ void (*member_del)(Evas_Object *o, Evas_Object *child); /**< code to be run when a child member is removed from object */
const Evas_Smart_Class *parent; /**< this class inherits from this parent */
const Evas_Smart_Cb_Description *callbacks; /**< callbacks at this level, @c NULL terminated */
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
* @ingroup Evas_Smart_Group
*/
-#define EVAS_SMART_CLASS_INIT_NULL {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+#define EVAS_SMART_CLASS_INIT_NULL {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/**
* @def EVAS_SMART_CLASS_INIT_VERSION
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
* @ingroup Evas_Smart_Group
*/
-#define EVAS_SMART_CLASS_INIT_NAME_VERSION(name) {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+#define EVAS_SMART_CLASS_INIT_NAME_VERSION(name) {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/**
* @def EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
* @ingroup Evas_Smart_Group
*/
-#define EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT(name, parent) {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, parent, NULL, NULL}
+#define EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT(name, parent) {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, parent, NULL, NULL}
/**
* @def EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
* @ingroup Evas_Smart_Group
*/
#define EVAS_SMART_SUBCLASS_NEW(smart_name, prefix, api_type, parent_type, parent_func, cb_desc) \
- static const parent_type * prefix##_parent_sc = NULL; \
- static void prefix##_smart_set_user(api_type *api); \
- static void prefix##_smart_set(api_type *api) \
- { \
- Evas_Smart_Class *sc; \
- if (!(sc = (Evas_Smart_Class *)api)) \
- return; \
- if (!prefix##_parent_sc) \
- prefix##_parent_sc = parent_func(); \
- evas_smart_class_inherit(sc, prefix##_parent_sc); \
- prefix##_smart_set_user(api); \
- } \
- static Evas_Smart * prefix##_smart_class_new(void) \
- { \
- static Evas_Smart *smart = NULL; \
- static api_type api; \
- if (!smart) \
- { \
- Evas_Smart_Class *sc = (Evas_Smart_Class *)&api; \
- memset(&api, 0, sizeof(api_type)); \
- sc->version = EVAS_SMART_CLASS_VERSION; \
- sc->name = smart_name; \
- sc->callbacks = cb_desc; \
- prefix##_smart_set(&api); \
- smart = evas_smart_class_new(sc); \
- } \
- return smart; \
+ static const parent_type * prefix##_parent_sc = NULL; \
+ static void prefix##_smart_set_user(api_type * api); \
+ static void prefix##_smart_set(api_type * api) \
+ { \
+ Evas_Smart_Class *sc; \
+ if (!(sc = (Evas_Smart_Class *)api)) \
+ return; \
+ if (!prefix##_parent_sc) \
+ prefix##_parent_sc = parent_func(); \
+ evas_smart_class_inherit(sc, prefix##_parent_sc); \
+ prefix##_smart_set_user(api); \
+ } \
+ static Evas_Smart *prefix##_smart_class_new(void) \
+ { \
+ static Evas_Smart *smart = NULL; \
+ static api_type api; \
+ if (!smart) \
+ { \
+ Evas_Smart_Class *sc = (Evas_Smart_Class *)&api; \
+ memset(&api, 0, sizeof(api_type)); \
+ sc->version = EVAS_SMART_CLASS_VERSION; \
+ sc->name = smart_name; \
+ sc->callbacks = cb_desc; \
+ prefix##_smart_set(&api); \
+ smart = evas_smart_class_new(sc); \
+ } \
+ return smart; \
}
/**
*
* @ingroup Evas_Smart_Group
*/
-#define EVAS_SMART_DATA_ALLOC(o, priv_type) \
- priv_type *priv; \
- priv = evas_object_smart_data_get(o); \
- if (!priv) { \
- priv = (priv_type *)calloc(1, sizeof(priv_type)); \
- if (!priv) return; \
- evas_object_smart_data_set(o, priv); \
- }
-
+#define EVAS_SMART_DATA_ALLOC(o, priv_type) \
+ priv_type * priv; \
+ priv = evas_object_smart_data_get(o); \
+ if (!priv) { \
+ priv = (priv_type *)calloc(1, sizeof(priv_type)); \
+ if (!priv) return; \
+ evas_object_smart_data_set(o, priv); \
+ }
/**
* Free an #Evas_Smart struct
* when they are not referenced anymore. Thus, this function is of no use
* for Evas users, most probably.
*/
-EAPI void evas_smart_free (Evas_Smart *s) EINA_ARG_NONNULL(1);
+EAPI void evas_smart_free(Evas_Smart *s) EINA_ARG_NONNULL(1);
/**
* Creates a new #Evas_Smart from a given #Evas_Smart_Class struct
* construct yours, consider using the #EVAS_SMART_SUBCLASS_NEW macro,
* which will make use of this function automatically for you.
*/
-EAPI Evas_Smart *evas_smart_class_new (const Evas_Smart_Class *sc) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Smart *evas_smart_class_new(const Evas_Smart_Class *sc) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the #Evas_Smart_Class handle of an #Evas_Smart struct
* @param s a valid #Evas_Smart pointer
* @return the #Evas_Smart_Class in it
*/
-EAPI const Evas_Smart_Class *evas_smart_class_get (const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI const Evas_Smart_Class *evas_smart_class_get(const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @brief Get the data pointer set on an #Evas_Smart struct
* This data pointer is set as the data field in the #Evas_Smart_Class
* passed in to evas_smart_class_new().
*/
-EAPI void *evas_smart_data_get (const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI void *evas_smart_data_get(const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the smart callbacks known by this #Evas_Smart handle's smart
*/
EAPI const Evas_Smart_Cb_Description **evas_smart_callbacks_descriptions_get(const Evas_Smart *s, unsigned int *count) EINA_ARG_NONNULL(1, 1);
-
/**
* Find a callback description for the callback named @a name.
*
*
* @see evas_smart_callbacks_descriptions_get()
*/
-EAPI const Evas_Smart_Cb_Description *evas_smart_callback_description_find(const Evas_Smart *s, const char *name) EINA_ARG_NONNULL(1, 2);
-
+EAPI const Evas_Smart_Cb_Description *evas_smart_callback_description_find(const Evas_Smart *s, const char *name) EINA_ARG_NONNULL(1, 2);
/**
* Sets one class to inherit from the other.
* this size. Everything after @c Evas_Smart_Class size is copied
* using regular memcpy().
*/
-EAPI Eina_Bool evas_smart_class_inherit_full (Evas_Smart_Class *sc, const Evas_Smart_Class *parent_sc, unsigned int parent_sc_size) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_smart_class_inherit_full(Evas_Smart_Class *sc, const Evas_Smart_Class *parent_sc, unsigned int parent_sc_size) EINA_ARG_NONNULL(1, 2);
/**
* Get the number of users of the smart instance
* Evas_Smart_Class data from memory (have it be a constant structure and
* data), or use this API call and be very careful.
*/
-EAPI int evas_smart_usage_get(const Evas_Smart *s);
-
- /**
- * @def evas_smart_class_inherit
- * Easy to use version of evas_smart_class_inherit_full().
- *
- * This version will use sizeof(parent_sc), copying everything.
- *
- * @param sc child class, will have methods copied from @a parent_sc
- * @param parent_sc parent class, will provide contents to be copied.
- * @return 1 on success, 0 on failure.
- * @ingroup Evas_Smart_Group
- */
+EAPI int evas_smart_usage_get(const Evas_Smart *s);
+
+/**
+ * @def evas_smart_class_inherit
+ * Easy to use version of evas_smart_class_inherit_full().
+ *
+ * This version will use sizeof(parent_sc), copying everything.
+ *
+ * @param sc child class, will have methods copied from @a parent_sc
+ * @param parent_sc parent class, will provide contents to be copied.
+ * @return 1 on success, 0 on failure.
+ * @ingroup Evas_Smart_Group
+ */
#define evas_smart_class_inherit(sc, parent_sc) evas_smart_class_inherit_full(sc, (Evas_Smart_Class *)parent_sc, sizeof(*parent_sc))
/**
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Evas_Object *evas_object_smart_add (Evas *e, Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_MALLOC;
+EAPI Evas_Object *evas_object_smart_add(Evas *e, Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_MALLOC;
/**
* Set an Evas object as a member of a given smart object.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_member_add (Evas_Object *obj, Evas_Object *smart_obj) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj) EINA_ARG_NONNULL(1, 2);
/**
* Removes a member object from a given smart object.
* @see evas_object_smart_member_add() for more details
* @see evas_object_smart_members_get()
*/
-EAPI void evas_object_smart_member_del (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_member_del(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Retrieves the list of the member objects of a given Evas smart
* The returned list should be freed with @c eina_list_free() when you
* no longer need it.
*
+ * @since 1.3 This function will return @c NULL when a non-smart object is passed.
+ *
* @see evas_object_smart_member_add()
* @see evas_object_smart_member_del()
-*/
-EAPI Eina_List *evas_object_smart_members_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+ */
+EAPI Eina_List *evas_object_smart_members_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Gets the parent smart object of a given Evas object, if it has one.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Evas_Object *evas_object_smart_parent_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_smart_parent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Checks whether a given smart object or any of its smart object
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Eina_Bool evas_object_smart_type_check (const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_smart_type_check(const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Checks whether a given smart object or any of its smart object
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Eina_Bool evas_object_smart_type_check_ptr (const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_smart_type_check_ptr(const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Get the #Evas_Smart from which @p obj smart object was created.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Evas_Smart *evas_object_smart_smart_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Smart *evas_object_smart_smart_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Retrieve user data stored on a given smart object.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void *evas_object_smart_data_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI void *evas_object_smart_data_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Store a pointer to user data for a given smart object.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_data_set (Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_data_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
/**
* Add (register) a callback function to the smart event specified by
* @see evas_object_smart_callback_del()
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_callback_add (Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
+EAPI void evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
/**
* Add (register) a callback function to the smart event specified by
* @since 1.1.0
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data);
+EAPI void evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data);
/**
* Delete (unregister) a callback function from the smart event
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void *evas_object_smart_callback_del (Evas_Object *obj, const char *event, Evas_Smart_Cb func) EINA_ARG_NONNULL(1, 2, 3);
+EAPI void *evas_object_smart_callback_del(Evas_Object *obj, const char *event, Evas_Smart_Cb func) EINA_ARG_NONNULL(1, 2, 3);
/**
* Delete (unregister) a callback function from the smart event
* @note To delete all smart event callbacks which match @p type and @p func,
* use evas_object_smart_callback_del().
*/
-EAPI void *evas_object_smart_callback_del_full(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
+EAPI void *evas_object_smart_callback_del_full(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
/**
* Call a given smart callback on the smart object @p obj.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_callback_call (Evas_Object *obj, const char *event, void *event_info) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event_info) EINA_ARG_NONNULL(1, 2);
/**
* Set an smart object @b instance's smart callbacks descriptions.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Eina_Bool evas_object_smart_callbacks_descriptions_set(Evas_Object *obj, const Evas_Smart_Cb_Description *descriptions) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_smart_callbacks_descriptions_set(Evas_Object *obj, const Evas_Smart_Cb_Description *descriptions) EINA_ARG_NONNULL(1);
/**
* Retrieve an smart object's know smart callback descriptions (both
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_callbacks_descriptions_get(const Evas_Object *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_callbacks_descriptions_get(const Evas_Object *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count) EINA_ARG_NONNULL(1);
/**
* Find callback description for callback called @a name.
* will be done on instance descriptions.
* @return reference to description if found, @c NULL if not found.
*/
-EAPI void evas_object_smart_callback_description_find(const Evas_Object *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_object_smart_callback_description_find(const Evas_Object *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description) EINA_ARG_NONNULL(1, 2);
/**
* Mark smart object as changed, dirty.
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_changed (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_changed(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Set or unset the flag signalling that a given smart object needs to
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) EINA_ARG_NONNULL(1);
/**
* Get the value of the flag signalling that a given smart object needs to
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI Eina_Bool evas_object_smart_need_recalculate_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_smart_need_recalculate_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Call the @b calculate() smart function immediately on a given smart
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_object_smart_calculate (Evas_Object *obj) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_calculate(Evas_Object *obj) EINA_ARG_NONNULL(1);
/**
* Call user-provided @c calculate() smart functions and unset the
*
* @ingroup Evas_Smart_Object_Group
*/
-EAPI void evas_smart_objects_calculate (Evas *e);
+EAPI void evas_smart_objects_calculate(Evas *e);
/**
* This gets the internal counter that counts the number of smart calculations
- *
+ *
* @param e The canvas to get the calculate counter from
- *
+ *
* Whenever evas performs smart object calculations on the whole canvas
* it increments a counter by 1. This is the smart object calculate counter
* that this function returns the value of. It starts at the value of 0 and
* 1 every time objects are calculated. You can use this counter to ensure
* you don't re-do calculations withint the same calculation generation/run
* if the calculations maybe cause self-feeding effects.
- *
+ *
* @ingroup Evas_Smart_Object_Group
* @since 1.1
*/
-EAPI int evas_smart_objects_calculate_count_get (const Evas *e);
-
+EAPI int evas_smart_objects_calculate_count_get(const Evas *e);
+
/**
* Moves all children objects of a given smart object relative to a
* given offset.
* @note Clipped smart objects already make use of this function on
* their @c move() smart function definition.
*/
-EAPI void evas_object_smart_move_children_relative(Evas_Object *obj, Evas_Coord dx, Evas_Coord dy) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_move_children_relative(Evas_Object *obj, Evas_Coord dx, Evas_Coord dy) EINA_ARG_NONNULL(1);
/**
* @}
* Every subclass should provide this at the beginning of their own
* data set with evas_object_smart_data_set().
*/
- typedef struct _Evas_Object_Smart_Clipped_Data Evas_Object_Smart_Clipped_Data;
- struct _Evas_Object_Smart_Clipped_Data
- {
- Evas_Object *clipper;
- Evas *evas;
- };
-
+typedef struct _Evas_Object_Smart_Clipped_Data Evas_Object_Smart_Clipped_Data;
+struct _Evas_Object_Smart_Clipped_Data
+{
+ Evas_Object *clipper;
+ Evas *evas;
+};
/**
* Get the clipper object for the given clipped smart object.
*
* @see evas_object_smart_clipped_smart_add()
*/
-EAPI Evas_Object *evas_object_smart_clipped_clipper_get (Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_smart_clipped_clipper_get(Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set a given smart class' callbacks so it implements the <b>clipped smart
* clipped smart object are:
* - @c add: creates a hidden clipper with "infinite" size, to clip
* any incoming members;
- * - @c del: delete all children objects;
- * - @c move: move all objects relative relatively;
- * - @c resize: <b>not defined</b>;
- * - @c show: if there are children objects, show clipper;
- * - @c hide: hides clipper;
- * - @c color_set: set the color of clipper;
- * - @c clip_set: set clipper of clipper;
- * - @c clip_unset: unset the clipper of clipper;
+ * - @c del: delete all children objects;
+ * - @c move: move all objects relative relatively;
+ * - @c resize: <b>not defined</b>;
+ * - @c show: if there are children objects, show clipper;
+ * - @c hide: hides clipper;
+ * - @c color_set: set the color of clipper;
+ * - @c clip_set: set clipper of clipper;
+ * - @c clip_unset: unset the clipper of clipper;
*
* @note There are other means of assigning parent smart classes to
* child ones, like the #EVAS_SMART_SUBCLASS_NEW macro or the
* evas_smart_class_inherit_full() function.
*/
-EAPI void evas_object_smart_clipped_smart_set (Evas_Smart_Class *sc) EINA_ARG_NONNULL(1);
+EAPI void evas_object_smart_clipped_smart_set(Evas_Smart_Class *sc) EINA_ARG_NONNULL(1);
/**
* Get a pointer to the <b>clipped smart object's</b> class, to use
* @see #Evas_Smart_Object_Clipped for more information on this smart
* class
*/
-EAPI const Evas_Smart_Class *evas_object_smart_clipped_class_get (void) EINA_CONST;
+EAPI const Evas_Smart_Class *evas_object_smart_clipped_class_get(void) EINA_CONST;
/**
* @}
*
* @ingroup Evas_Object_Box
*/
- typedef struct _Evas_Object_Box_Api Evas_Object_Box_Api;
+typedef struct _Evas_Object_Box_Api Evas_Object_Box_Api;
/**
* @typedef Evas_Object_Box_Data
*
* @ingroup Evas_Object_Box
*/
- typedef struct _Evas_Object_Box_Data Evas_Object_Box_Data;
+typedef struct _Evas_Object_Box_Data Evas_Object_Box_Data;
/**
* @typedef Evas_Object_Box_Option
*
* @ingroup Evas_Object_Box
*/
- typedef struct _Evas_Object_Box_Option Evas_Object_Box_Option;
+typedef struct _Evas_Object_Box_Option Evas_Object_Box_Option;
/**
* @typedef Evas_Object_Box_Layout
*
* @ingroup Evas_Object_Box
*/
- typedef void (*Evas_Object_Box_Layout) (Evas_Object *o, Evas_Object_Box_Data *priv, void *user_data);
+typedef void (*Evas_Object_Box_Layout)(Evas_Object *o, Evas_Object_Box_Data *priv, void *user_data);
/**
* @def EVAS_OBJECT_BOX_API_VERSION
* @extends Evas_Smart_Class
* @ingroup Evas_Object_Box
*/
- struct _Evas_Object_Box_Api
- {
- Evas_Smart_Class base; /**< Base smart class struct, need for all smart objects */
- int version; /**< Version of this smart class definition */
- Evas_Object_Box_Option *(*append) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child); /**< Smart function to append child elements in boxes */
- Evas_Object_Box_Option *(*prepend) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child); /**< Smart function to prepend child elements in boxes */
- Evas_Object_Box_Option *(*insert_before) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, const Evas_Object *reference); /**< Smart function to insert a child element before another in boxes */
- Evas_Object_Box_Option *(*insert_after) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, const Evas_Object *reference); /**< Smart function to insert a child element after another in boxes */
- Evas_Object_Box_Option *(*insert_at) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child, unsigned int pos); /**< Smart function to insert a child element at a given position on boxes */
- Evas_Object *(*remove) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child); /**< Smart function to remove a child element from boxes */
- Evas_Object *(*remove_at) (Evas_Object *o, Evas_Object_Box_Data *priv, unsigned int pos); /**< Smart function to remove a child element from boxes, by its position */
- Eina_Bool (*property_set) (Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args); /**< Smart function to set a custom property on a box child */
- Eina_Bool (*property_get) (Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args); /**< Smart function to retrieve a custom property from a box child */
- const char *(*property_name_get)(Evas_Object *o, int property); /**< Smart function to get the name of a custom property of box children */
- int (*property_id_get) (Evas_Object *o, const char *name); /**< Smart function to get the numerical ID of a custom property of box children */
- Evas_Object_Box_Option *(*option_new) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object *child); /**< Smart function to create a new box option struct */
- void (*option_free) (Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object_Box_Option *opt); /**< Smart function to delete a box option struct */
- };
+struct _Evas_Object_Box_Api
+{
+ Evas_Smart_Class base; /**< Base smart class struct, need for all smart objects */
+ int version; /**< Version of this smart class definition */
+ Evas_Object_Box_Option *(*append)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child); /**< Smart function to append child elements in boxes */
+ Evas_Object_Box_Option *(*prepend)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child); /**< Smart function to prepend child elements in boxes */
+ Evas_Object_Box_Option *(*insert_before)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child, const Evas_Object * reference); /**< Smart function to insert a child element before another in boxes */
+ Evas_Object_Box_Option *(*insert_after)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child, const Evas_Object * reference); /**< Smart function to insert a child element after another in boxes */
+ Evas_Object_Box_Option *(*insert_at)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child, unsigned int pos); /**< Smart function to insert a child element at a given position on boxes */
+ Evas_Object *(*remove)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child); /**< Smart function to remove a child element from boxes */
+ Evas_Object *(*remove_at)(Evas_Object * o, Evas_Object_Box_Data * priv, unsigned int pos); /**< Smart function to remove a child element from boxes, by its position */
+ Eina_Bool (*property_set)(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args); /**< Smart function to set a custom property on a box child */
+ Eina_Bool (*property_get)(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args); /**< Smart function to retrieve a custom property from a box child */
+ const char *(*property_name_get)(const Evas_Object * o, int property); /**< Smart function to get the name of a custom property of box children */
+ int (*property_id_get)(const Evas_Object *o, const char *name); /**< Smart function to get the numerical ID of a custom property of box children */
+ Evas_Object_Box_Option *(*option_new)(Evas_Object * o, Evas_Object_Box_Data * priv, Evas_Object * child); /**< Smart function to create a new box option struct */
+ void (*option_free)(Evas_Object *o, Evas_Object_Box_Data *priv, Evas_Object_Box_Option *opt); /**< Smart function to delete a box option struct */
+};
/**
* @def EVAS_OBJECT_BOX_API_INIT
* @see EVAS_OBJECT_BOX_API_INIT
* @ingroup Evas_Object_Box
*/
-#define EVAS_OBJECT_BOX_API_INIT_NULL EVAS_OBJECT_BOX_API_INIT(EVAS_SMART_CLASS_INIT_NULL)
+#define EVAS_OBJECT_BOX_API_INIT_NULL EVAS_OBJECT_BOX_API_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def EVAS_OBJECT_BOX_API_INIT_VERSION
* @extends Evas_Object_Smart_Clipped_Data
* @ingroup Evas_Object_Box
*/
- struct _Evas_Object_Box_Data
+struct _Evas_Object_Box_Data
+{
+ Evas_Object_Smart_Clipped_Data base;
+ const Evas_Object_Box_Api *api;
+ struct
{
- Evas_Object_Smart_Clipped_Data base;
- const Evas_Object_Box_Api *api;
- struct {
- double h, v;
- } align;
- struct {
- Evas_Coord h, v;
- } pad;
- Eina_List *children;
- struct {
- Evas_Object_Box_Layout cb;
- void *data;
- void (*free_data)(void *data);
- } layout;
- Eina_Bool layouting : 1;
- Eina_Bool children_changed : 1;
- };
-
- struct _Evas_Object_Box_Option
+ double h, v;
+ } align;
+ struct
{
- Evas_Object *obj; /**< Pointer to the box child object, itself */
- Eina_Bool max_reached:1;
- Eina_Bool min_reached:1;
- Evas_Coord alloc_size;
- }; /**< #Evas_Object_Box_Option struct fields */
+ Evas_Coord h, v;
+ } pad;
+ Eina_List *children;
+ struct
+ {
+ Evas_Object_Box_Layout cb;
+ void *data;
+ void (*free_data)(void *data);
+ } layout;
+ Eina_Bool layouting : 1;
+ Eina_Bool children_changed : 1;
+};
+
+struct _Evas_Object_Box_Option
+{
+ Evas_Object *obj; /**< Pointer to the box child object, itself */
+ Eina_Bool max_reached : 1;
+ Eina_Bool min_reached : 1;
+ Evas_Coord alloc_size;
+}; /**< #Evas_Object_Box_Option struct fields */
/**
* Set the default box @a api struct (Evas_Object_Box_Api)
* @param api The box API struct to set back, most probably with
* overridden fields (on class extensions scenarios)
*/
-EAPI void evas_object_box_smart_set (Evas_Object_Box_Api *api) EINA_ARG_NONNULL(1);
+EAPI void evas_object_box_smart_set(Evas_Object_Box_Api *api) EINA_ARG_NONNULL(1);
/**
* Get the Evas box smart class, for inheritance purposes.
* The returned value is @b not to be modified, just use it as your
* parent class.
*/
-EAPI const Evas_Object_Box_Api *evas_object_box_smart_class_get (void) EINA_CONST;
+EAPI const Evas_Object_Box_Api *evas_object_box_smart_class_get(void) EINA_CONST;
/**
* Set a new layouting function to a given box object
* @note A box layouting function will be triggered by the @c
* 'calculate' smart callback of the box's smart class.
*/
-EAPI void evas_object_box_layout_set (Evas_Object *o, Evas_Object_Box_Layout cb, const void *data, void (*free_data)(void *data)) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_set(Evas_Object *o, Evas_Object_Box_Layout cb, const void *data, void (*free_data)(void *data)) EINA_ARG_NONNULL(1, 2);
/**
* Add a new box object on the provided canvas.
* properties of the box must be set/retrieved via
* <c>evas_object_box_{h,v}_{align,padding}_{get,set)()</c>.
*/
-EAPI Evas_Object *evas_object_box_add (Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_box_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Add a new box as a @b child of a given smart object.
*
* @see evas_object_box_add()
*/
-EAPI Evas_Object *evas_object_box_add_to (Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_box_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Layout function which sets the box @a o to a (basic) horizontal box
* be set, by the <c>evas_object_size_hint_{min,max}_set()</c>
* functions.
*/
-EAPI void evas_object_box_layout_horizontal (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a (basic) vertical box
* evas_object_box_layout_horizontal(). The description of its
* behaviour can be derived from that function's documentation.
*/
-EAPI void evas_object_box_layout_vertical (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a @b homogeneous
* evas_object_box_layout_homogeneous_horizontal(). The description
* of its behaviour can be derived from that function's documentation.
*/
-EAPI void evas_object_box_layout_homogeneous_vertical (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a @b homogeneous
* try to resize this child element to the exact height of its parent
* (respecting the maximum size hint on the child's height).
*/
-EAPI void evas_object_box_layout_homogeneous_horizontal (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a <b>maximum size,
* description of its behaviour can be derived from that function's
* documentation.
*/
-EAPI void evas_object_box_layout_homogeneous_max_size_vertical (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_homogeneous_max_size_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a @b flow horizontal
* @c align_y dictates positioning relative to the <b>largest
* height</b> required by a child object in the actual row.
*/
-EAPI void evas_object_box_layout_flow_horizontal (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a @b flow vertical box.
* evas_object_box_layout_flow_horizontal(). The description of its
* behaviour can be derived from that function's documentation.
*/
-EAPI void evas_object_box_layout_flow_vertical (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Layout function which sets the box @a o to a @b stacking box
* width and accounting for its horizontal padding properties). The
* same applies to the vertical axis.
*/
-EAPI void evas_object_box_layout_stack (Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_box_layout_stack(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
/**
* Set the alignment of the whole bounding box of contents, for a
*
* @see evas_object_box_align_get()
*/
-EAPI void evas_object_box_align_set (Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_box_align_set(Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
/**
* Get the alignment of the whole bounding box of contents, for a
*
* @see evas_object_box_align_set() for more information
*/
-EAPI void evas_object_box_align_get (const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_box_align_get(const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
/**
* Set the (space) padding between cells set for a given box object.
*
* @see evas_object_box_padding_get()
*/
-EAPI void evas_object_box_padding_set (Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_box_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
/**
* Get the (space) padding between cells set for a given box object.
*
* @see evas_object_box_padding_set()
*/
-EAPI void evas_object_box_padding_get (const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_box_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
/**
* Append a new @a child object to the given box object @a o.
* @note This call will trigger the box's _Evas_Object_Box_Api::append
* smart function.
*/
-EAPI Evas_Object_Box_Option *evas_object_box_append (Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
+EAPI Evas_Object_Box_Option *evas_object_box_append(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
/**
* Prepend a new @a child object to the given box object @a o.
* @note This call will trigger the box's
* _Evas_Object_Box_Api::prepend smart function.
*/
-EAPI Evas_Object_Box_Option *evas_object_box_prepend (Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
+EAPI Evas_Object_Box_Option *evas_object_box_prepend(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
/**
* Insert a new @a child object <b>before another existing one</b>, in
* @note This call will trigger the box's
* _Evas_Object_Box_Api::insert_before smart function.
*/
-EAPI Evas_Object_Box_Option *evas_object_box_insert_before (Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
+EAPI Evas_Object_Box_Option *evas_object_box_insert_before(Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
/**
* Insert a new @a child object <b>after another existing one</b>, in
* @note This call will trigger the box's
* _Evas_Object_Box_Api::insert_after smart function.
*/
-EAPI Evas_Object_Box_Option *evas_object_box_insert_after (Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
+EAPI Evas_Object_Box_Option *evas_object_box_insert_after(Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
/**
* Insert a new @a child object <b>at a given position</b>, in a given
* @note This call will trigger the box's
* _Evas_Object_Box_Api::insert_at smart function.
*/
-EAPI Evas_Object_Box_Option *evas_object_box_insert_at (Evas_Object *o, Evas_Object *child, unsigned int pos) EINA_ARG_NONNULL(1, 2);
+EAPI Evas_Object_Box_Option *evas_object_box_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos) EINA_ARG_NONNULL(1, 2);
/**
* Remove a given object from a box object, unparenting it again.
* @note This call will trigger the box's _Evas_Object_Box_Api::remove
* smart function.
*/
-EAPI Eina_Bool evas_object_box_remove (Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_box_remove(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
/**
* Remove an object, <b>bound to a given position</b> in a box object,
* @note This call will trigger the box's
* _Evas_Object_Box_Api::remove_at smart function.
*/
-EAPI Eina_Bool evas_object_box_remove_at (Evas_Object *o, unsigned int pos) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_box_remove_at(Evas_Object *o, unsigned int pos) EINA_ARG_NONNULL(1);
/**
* Remove @b all child objects from a box object, unparenting them
* each of @p o's child objects, in sequence. If, and only if, all
* those calls succeed, so does this one.
*/
-EAPI Eina_Bool evas_object_box_remove_all (Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_box_remove_all(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
/**
* Get an iterator to walk the list of children of a given box object.
*
* @note Do @b not remove or delete objects while walking the list.
*/
-EAPI Eina_Iterator *evas_object_box_iterator_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Iterator *evas_object_box_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get an accessor (a structure providing random items access) to the
*
* @note Do not remove or delete objects while walking the list.
*/
-EAPI Eina_Accessor *evas_object_box_accessor_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Accessor *evas_object_box_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the list of children objects in a given box object.
* It's possible to remove objects from the box when walking
* this list, but these removals won't be reflected on it.
*/
-EAPI Eina_List *evas_object_box_children_get (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_List *evas_object_box_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the name of the property of the child elements of the box @a o
* _Evas_Object_Box_Api::property_name_get smart class function of the
* box, which is originally set to @c NULL.
*/
-EAPI const char *evas_object_box_option_property_name_get (Evas_Object *o, int property) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const char *evas_object_box_option_property_name_get(const Evas_Object *o, int property) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Get the numerical identifier of the property of the child elements
* _Evas_Object_Box_Api::property_id_get smart class function of the
* box, which is originally set to @c NULL.
*/
-EAPI int evas_object_box_option_property_id_get (Evas_Object *o, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI int evas_object_box_option_property_id_get(const Evas_Object *o, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Set a property value (by its given numerical identifier), on a
* evas_object_box_option_property_vset() with this list and the same
* previous arguments.
*/
-EAPI Eina_Bool evas_object_box_option_property_set (Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_box_option_property_set(Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
/**
* Set a property value (by its given numerical identifier), on a
* evas_object_box_option_property_set(). See its documentation for
* more details.
*/
-EAPI Eina_Bool evas_object_box_option_property_vset (Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_box_option_property_vset(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
/**
* Get a property's value (by its given numerical identifier), on a
* evas_object_box_option_property_vget() with this list and the same
* previous arguments.
*/
-EAPI Eina_Bool evas_object_box_option_property_get (Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_box_option_property_get(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
/**
* Get a property's value (by its given numerical identifier), on a
* evas_object_box_option_property_get(). See its documentation for
* more details.
*/
-EAPI Eina_Bool evas_object_box_option_property_vget (Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_box_option_property_vget(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
/**
* @}
*
* @param evas Canvas in which table will be added.
*/
-EAPI Evas_Object *evas_object_table_add (Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_table_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* @brief Create a table that is child of a given element @a parent.
*
* @see evas_object_table_add()
*/
-EAPI Evas_Object *evas_object_table_add_to (Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_table_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* @brief Set how this table should layout children.
* no minimum size is provided at all then the table will fallback to
* expand mode as well.
*/
-EAPI void evas_object_table_homogeneous_set (Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_homogeneous_set(Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous) EINA_ARG_NONNULL(1);
/**
* Get the current layout homogeneous mode.
*
* @see evas_object_table_homogeneous_set()
*/
-EAPI Evas_Object_Table_Homogeneous_Mode evas_object_table_homogeneous_get (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI Evas_Object_Table_Homogeneous_Mode evas_object_table_homogeneous_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Set padding between cells.
*/
-EAPI void evas_object_table_padding_set (Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
/**
* Get padding between cells.
*/
-EAPI void evas_object_table_padding_get (const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
/**
* Set the alignment of the whole bounding box of contents.
*/
-EAPI void evas_object_table_align_set (Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_align_set(Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
/**
* Get alignment of the whole bounding box of contents.
*/
-EAPI void evas_object_table_align_get (const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_align_get(const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
/**
* Sets the mirrored mode of the table. In mirrored mode the table items go
* @param mirrored the mirrored mode to set
* @since 1.1.0
*/
-EAPI void evas_object_table_mirrored_set (Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_mirrored_set(Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
/**
* Gets the mirrored mode of the table.
* @since 1.1.0
* @see evas_object_table_mirrored_set()
*/
-EAPI Eina_Bool evas_object_table_mirrored_get (const Evas_Object *o) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_table_mirrored_get(const Evas_Object *o) EINA_ARG_NONNULL(1);
/**
* Get packing location of a child of table
* @return 1 on success, 0 on failure.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_table_pack_get(Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan);
+EAPI Eina_Bool evas_object_table_pack_get(const Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan);
/**
* Add a new child to a table object or set its current packing.
*
* @return 1 on success, 0 on failure.
*/
-EAPI Eina_Bool evas_object_table_pack (Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) EINA_ARG_NONNULL(1, 2);
/**
* Remove child from table.
*
* @return 1 on success, 0 on failure.
*/
-EAPI Eina_Bool evas_object_table_unpack (Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_table_unpack(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
/**
* Faster way to remove all child objects from a table object.
* @param o The given table object.
* @param clear if true, it will delete just removed children.
*/
-EAPI void evas_object_table_clear (Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_clear(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
/**
* Get the number of columns and rows this table takes.
* difference for a single cell table is that paddings will be
* accounted proportionally.
*/
-EAPI void evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows) EINA_ARG_NONNULL(1);
+EAPI void evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows) EINA_ARG_NONNULL(1);
/**
* Get an iterator to walk the list of children for the table.
*
* @note Do not remove or delete objects while walking the list.
*/
-EAPI Eina_Iterator *evas_object_table_iterator_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Iterator *evas_object_table_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get an accessor to get random access to the list of children for the table.
*
* @note Do not remove or delete objects while walking the list.
*/
-EAPI Eina_Accessor *evas_object_table_accessor_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Accessor *evas_object_table_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the list of children for the table.
* It's possible to remove objects from the table when walking this
* list, but these removals won't be reflected on it.
*/
-EAPI Eina_List *evas_object_table_children_get (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_List *evas_object_table_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the child of the table at the given coordinates
*
* @note This does not take into account col/row spanning
*/
-EAPI Evas_Object *evas_object_table_child_get (const Evas_Object *o, unsigned short col, unsigned short row) EINA_ARG_NONNULL(1);
+EAPI Evas_Object *evas_object_table_child_get(const Evas_Object *o, unsigned short col, unsigned short row) EINA_ARG_NONNULL(1);
/**
* @}
*/
* evas_object_grid_pack().
* @since 1.1.0
*/
-EAPI Evas_Object *evas_object_grid_add (Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_grid_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Create a grid that is child of a given element @a parent.
* @see evas_object_grid_add()
* @since 1.1.0
*/
-EAPI Evas_Object *evas_object_grid_add_to (Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Evas_Object *evas_object_grid_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Set the virtual resolution for the grid
* @param h The virtual vertical size (resolution) in integer units
* @since 1.1.0
*/
-EAPI void evas_object_grid_size_set (Evas_Object *o, int w, int h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_grid_size_set(Evas_Object *o, int w, int h) EINA_ARG_NONNULL(1);
/**
* Get the current virtual resolution
* @see evas_object_grid_size_set()
* @since 1.1.0
*/
-EAPI void evas_object_grid_size_get (const Evas_Object *o, int *w, int *h) EINA_ARG_NONNULL(1);
+EAPI void evas_object_grid_size_get(const Evas_Object *o, int *w, int *h) EINA_ARG_NONNULL(1);
/**
* Sets the mirrored mode of the grid. In mirrored mode the grid items go
* @param mirrored the mirrored mode to set
* @since 1.1.0
*/
-EAPI void evas_object_grid_mirrored_set (Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
+EAPI void evas_object_grid_mirrored_set(Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
/**
* Gets the mirrored mode of the grid.
* @see evas_object_grid_mirrored_set()
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_grid_mirrored_get (const Evas_Object *o) EINA_ARG_NONNULL(1);
+EAPI Eina_Bool evas_object_grid_mirrored_get(const Evas_Object *o) EINA_ARG_NONNULL(1);
/**
* Add a new child to a grid object.
* @return 1 on success, 0 on failure.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_grid_pack (Evas_Object *o, Evas_Object *child, int x, int y, int w, int h) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_grid_pack(Evas_Object *o, Evas_Object *child, int x, int y, int w, int h) EINA_ARG_NONNULL(1, 2);
/**
* Remove child from grid.
* @return 1 on success, 0 on failure.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_grid_unpack (Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_grid_unpack(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
/**
* Faster way to remove all child objects from a grid object.
* @param clear if true, it will delete just removed children.
* @since 1.1.0
*/
-EAPI void evas_object_grid_clear (Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
+EAPI void evas_object_grid_clear(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
/**
* Get the pack options for a grid child
* @return 1 on success, 0 on failure.
* @since 1.1.0
*/
-EAPI Eina_Bool evas_object_grid_pack_get (Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h);
+EAPI Eina_Bool evas_object_grid_pack_get(const Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h);
/**
* Get an iterator to walk the list of children for the grid.
* @note Do not remove or delete objects while walking the list.
* @since 1.1.0
*/
-EAPI Eina_Iterator *evas_object_grid_iterator_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Iterator *evas_object_grid_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get an accessor to get random access to the list of children for the grid.
* @note Do not remove or delete objects while walking the list.
* @since 1.1.0
*/
-EAPI Eina_Accessor *evas_object_grid_accessor_new (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_Accessor *evas_object_grid_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* Get the list of children for the grid.
* list, but these removals won't be reflected on it.
* @since 1.1.0
*/
-EAPI Eina_List *evas_object_grid_children_get (const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
+EAPI Eina_List *evas_object_grid_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/**
* @}
* Be warned that it @b doesn't work when <b>threaded image
* preloading</b> is enabled for Evas, though.
*/
- typedef struct _Evas_Cserve_Stats Evas_Cserve_Stats;
- typedef struct _Evas_Cserve_Image_Cache Evas_Cserve_Image_Cache;
- typedef struct _Evas_Cserve_Image Evas_Cserve_Image;
- typedef struct _Evas_Cserve_Config Evas_Cserve_Config;
+typedef struct _Evas_Cserve_Stats Evas_Cserve_Stats;
+typedef struct _Evas_Cserve_Image_Cache Evas_Cserve_Image_Cache;
+typedef struct _Evas_Cserve_Image Evas_Cserve_Image;
+typedef struct _Evas_Cserve_Config Evas_Cserve_Config;
/**
* Statistics about the server that shares cached bitmaps.
* @ingroup Evas_Cserve
*/
- struct _Evas_Cserve_Stats
- {
- int saved_memory; /**< current amount of saved memory, in bytes */
- int wasted_memory; /**< current amount of wasted memory, in bytes */
- int saved_memory_peak; /**< peak amount of saved memory, in bytes */
- int wasted_memory_peak; /**< peak amount of wasted memory, in bytes */
- double saved_time_image_header_load; /**< time, in seconds, saved in header loads by sharing cached loads instead */
- double saved_time_image_data_load; /**< time, in seconds, saved in data loads by sharing cached loads instead */
- };
+struct _Evas_Cserve_Stats
+{
+ int saved_memory; /**< current amount of saved memory, in bytes */
+ int wasted_memory; /**< current amount of wasted memory, in bytes */
+ int saved_memory_peak; /**< peak amount of saved memory, in bytes */
+ int wasted_memory_peak; /**< peak amount of wasted memory, in bytes */
+ double saved_time_image_header_load; /**< time, in seconds, saved in header loads by sharing cached loads instead */
+ double saved_time_image_data_load; /**< time, in seconds, saved in data loads by sharing cached loads instead */
+};
/**
* A handle of a cache of images shared by a server.
* @ingroup Evas_Cserve
*/
- struct _Evas_Cserve_Image_Cache
- {
- struct {
- int mem_total;
- int count;
- } active, cached;
- Eina_List *images;
- };
+struct _Evas_Cserve_Image_Cache
+{
+ struct
+ {
+ int mem_total;
+ int count;
+ } active, cached;
+ Eina_List *images;
+};
/**
* A handle to an image shared by a server.
* @ingroup Evas_Cserve
*/
- struct _Evas_Cserve_Image
- {
- const char *file, *key;
- int w, h;
- time_t file_mod_time;
- time_t file_checked_time;
- time_t cached_time;
- int refcount;
- int data_refcount;
- int memory_footprint;
- double head_load_time;
- double data_load_time;
- Eina_Bool alpha : 1;
- Eina_Bool data_loaded : 1;
- Eina_Bool active : 1;
- Eina_Bool dead : 1;
- Eina_Bool useless : 1;
- };
+struct _Evas_Cserve_Image
+{
+ const char *file, *key;
+ int w, h;
+ time_t file_mod_time;
+ time_t file_checked_time;
+ time_t cached_time;
+ int refcount;
+ int data_refcount;
+ int memory_footprint;
+ double head_load_time;
+ double data_load_time;
+ Eina_Bool alpha : 1;
+ Eina_Bool data_loaded : 1;
+ Eina_Bool active : 1;
+ Eina_Bool dead : 1;
+ Eina_Bool useless : 1;
+};
/**
* Configuration that controls the server that shares cached bitmaps.
* @ingroup Evas_Cserve
*/
- struct _Evas_Cserve_Config
- {
- int cache_max_usage;
- int cache_item_timeout;
- int cache_item_timeout_check;
- };
-
+struct _Evas_Cserve_Config
+{
+ int cache_max_usage;
+ int cache_item_timeout;
+ int cache_item_timeout_check;
+};
/**
* Retrieves if the system wants to share bitmaps using the server.
* @return @c EINA_TRUE if it wants, @c EINA_FALSE otherwise.
* @ingroup Evas_Cserve
*/
-EAPI Eina_Bool evas_cserve_want_get (void) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Bool evas_cserve_want_get(void) EINA_WARN_UNUSED_RESULT;
/**
* Retrieves if the system is connected to the server used to share
* @return @c EINA_TRUE if it's connected, @c EINA_FALSE otherwise.
* @ingroup Evas_Cserve
*/
-EAPI Eina_Bool evas_cserve_connected_get (void) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Bool evas_cserve_connected_get(void) EINA_WARN_UNUSED_RESULT;
/**
* Retrieves statistics from a running bitmap sharing server.
* @c EINA_FALSE otherwise (when @p stats is untouched)
* @ingroup Evas_Cserve
*/
-EAPI Eina_Bool evas_cserve_stats_get (Evas_Cserve_Stats *stats) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Bool evas_cserve_stats_get(Evas_Cserve_Stats *stats) EINA_WARN_UNUSED_RESULT;
/**
* Completely discard/clean a given images cache, thus re-setting it.
*
* @param cache A handle to the given images cache.
*/
-EAPI void evas_cserve_image_cache_contents_clean (Evas_Cserve_Image_Cache *cache);
+EAPI void evas_cserve_image_cache_contents_clean(Evas_Cserve_Image_Cache *cache);
/**
* Retrieves the current configuration of the Evas image caching
*
* @ingroup Evas_Cserve
*/
-EAPI Eina_Bool evas_cserve_config_get (Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Bool evas_cserve_config_get(Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
/**
* Changes the configurations of the Evas image caching server.
*
* @ingroup Evas_Cserve
*/
-EAPI Eina_Bool evas_cserve_config_set (const Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Bool evas_cserve_config_set(const Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
/**
* Force the system to disconnect from the bitmap caching server.
*
* @ingroup Evas_Cserve
*/
-EAPI void evas_cserve_disconnect (void);
+EAPI void evas_cserve_disconnect(void);
/**
* @defgroup Evas_Utils General Utilities
*
* @ingroup Evas_Utils
*/
-EAPI const char *evas_load_error_str (Evas_Load_Error error);
+EAPI const char *evas_load_error_str(Evas_Load_Error error);
/* Evas utility routines for color space conversions */
/* hsv color space has h in the range 0.0 to 360.0, and s,v in the range 0.0 to 1.0 */
*
* @ingroup Evas_Utils
**/
-EAPI void evas_color_hsv_to_rgb (float h, float s, float v, int *r, int *g, int *b);
+EAPI void evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b);
/**
* Convert a given color from RGB to HSV format.
*
* @ingroup Evas_Utils
**/
-EAPI void evas_color_rgb_to_hsv (int r, int g, int b, float *h, float *s, float *v);
+EAPI void evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v);
/* argb color space has a,r,g,b in the range 0 to 255 */
*
* @ingroup Evas_Utils
**/
-EAPI void evas_color_argb_premul (int a, int *r, int *g, int *b);
+EAPI void evas_color_argb_premul(int a, int *r, int *g, int *b);
/**
* Undo pre-multiplication of a rgb triplet by an alpha factor.
*
* @ingroup Evas_Utils
**/
-EAPI void evas_color_argb_unpremul (int a, int *r, int *g, int *b);
-
+EAPI void evas_color_argb_unpremul(int a, int *r, int *g, int *b);
/**
* Pre-multiplies data by an alpha factor.
*
* @ingroup Evas_Utils
**/
-EAPI void evas_data_argb_premul (unsigned int *data, unsigned int len);
+EAPI void evas_data_argb_premul(unsigned int *data, unsigned int len);
/**
* Undo pre-multiplication data by an alpha factor.
*
* @ingroup Evas_Utils
**/
-EAPI void evas_data_argb_unpremul (unsigned int *data, unsigned int len);
+EAPI void evas_data_argb_unpremul(unsigned int *data, unsigned int len);
/* string and font handling */
*
* @ingroup Evas_Utils
*/
-EAPI int evas_string_char_next_get (const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
+EAPI int evas_string_char_next_get(const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
/**
* Gets the previous character in the string
*
* @ingroup Evas_Utils
*/
-EAPI int evas_string_char_prev_get (const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
+EAPI int evas_string_char_prev_get(const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
/**
* Get the length in characters of the string.
* @return The length in characters (not bytes)
* @ingroup Evas_Utils
*/
-EAPI int evas_string_char_len_get (const char *str) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI int evas_string_char_len_get(const char *str) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Keys Key Input Functions
* @return An ::Evas_Modifier handle to query Evas' keys subsystem
* with evas_key_modifier_is_set(), or @c NULL on error.
*/
-EAPI const Evas_Modifier *evas_key_modifier_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+EAPI const Evas_Modifier *evas_key_modifier_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Returns a handle to the list of lock keys registered in the canvas
* @return An ::Evas_Lock handle to query Evas' keys subsystem with
* evas_key_lock_is_set(), or @c NULL on error.
*/
-EAPI const Evas_Lock *evas_key_lock_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
-
+EAPI const Evas_Lock *evas_key_lock_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
* Checks the state of a given modifier key, at the time of the
* @see evas_key_modifier_on
* @see evas_key_modifier_off
*/
-EAPI Eina_Bool evas_key_modifier_is_set (const Evas_Modifier *m, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
-
+EAPI Eina_Bool evas_key_modifier_is_set(const Evas_Modifier *m, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Checks the state of a given lock key, at the time of the call. If
* @see evas_key_lock_on
* @see evas_key_lock_off
*/
-EAPI Eina_Bool evas_key_lock_is_set (const Evas_Lock *l, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
-
+EAPI Eina_Bool evas_key_lock_is_set(const Evas_Lock *l, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Adds the @p keyname key to the current list of modifier keys.
* care of registering on it all standard modifiers: "Shift",
* "Control", "Alt", "Meta", "Hyper", "Super".
*/
-EAPI void evas_key_modifier_add (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_modifier_add(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Removes the @p keyname key from the current list of modifier keys
* @see evas_key_modifier_off
* @see evas_key_modifier_is_set
*/
-EAPI void evas_key_modifier_del (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_modifier_del(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Adds the @p keyname key to the current list of lock keys.
* care of registering on it all standard lock keys: "Caps_Lock",
* "Num_Lock", "Scroll_Lock".
*/
-EAPI void evas_key_lock_add (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_lock_add(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Removes the @p keyname key from the current list of lock keys on
* @see evas_key_lock_on
* @see evas_key_lock_off
*/
-EAPI void evas_key_lock_del (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_key_lock_del(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Enables or turns on programmatically the modifier key with name @p
* @see evas_key_modifier_off
* @see evas_key_modifier_is_set
*/
-EAPI void evas_key_modifier_on (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_modifier_on(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Disables or turns off programmatically the modifier key with name
* @see evas_key_modifier_on
* @see evas_key_modifier_is_set
*/
-EAPI void evas_key_modifier_off (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_modifier_off(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Enables or turns on programmatically the lock key with name @p
* @see evas_key_lock_del
* @see evas_key_lock_off
*/
-EAPI void evas_key_lock_on (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_key_lock_on(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Disables or turns off programmatically the lock key with name @p
* @see evas_key_lock_del
* @see evas_key_lock_on
*/
-EAPI void evas_key_lock_off (Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
-
+EAPI void evas_key_lock_off(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
/**
* Creates a bit mask from the @p keyname @b modifier key. Values
* @see evas_object_key_grab
* @see evas_object_key_ungrab
*/
-EAPI Evas_Modifier_Mask evas_key_modifier_mask_get (const Evas *e, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
-
+EAPI Evas_Modifier_Mask evas_key_modifier_mask_get(const Evas *e, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Requests @p keyname key events be directed to @p obj.
*
* See the full example @ref Example_Evas_Events "here".
*
+ * @warning Providing impossible modifier sets creates undefined behavior
+ *
* @see evas_object_key_ungrab
* @see evas_object_focus_set
* @see evas_object_focus_get
* @see evas_focus_get
* @see evas_key_modifier_add
*/
-EAPI Eina_Bool evas_object_key_grab (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Bool evas_object_key_grab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
/**
* Removes the grab on @p keyname key events by @p obj.
* @see evas_object_focus_get
* @see evas_focus_get
*/
-EAPI void evas_object_key_ungrab (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers) EINA_ARG_NONNULL(1, 2);
+EAPI void evas_object_key_ungrab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers) EINA_ARG_NONNULL(1, 2);
/**
* @}
extern "C" {
#endif
-typedef struct _Evas_GL Evas_GL;
-typedef struct _Evas_GL_Surface Evas_GL_Surface;
-typedef struct _Evas_GL_Context Evas_GL_Context;
-typedef struct _Evas_GL_Config Evas_GL_Config;
-typedef struct _Evas_GL_API Evas_GL_API;
-typedef void *Evas_GL_Func;
-typedef void *EvasGLImage;
-
-typedef enum _Evas_GL_Color_Format
-{
- EVAS_GL_RGB_888 = 0,
- EVAS_GL_RGB_8 = EVAS_GL_RGB_888,
- EVAS_GL_RGBA_8888 = 1,
- EVAS_GL_RGBA_8 = EVAS_GL_RGBA_8888,
-} Evas_GL_Color_Format;
-
-typedef enum _Evas_GL_Depth_Bits
-{
- EVAS_GL_DEPTH_NONE = 0,
- EVAS_GL_DEPTH_BIT_8 = 1,
- EVAS_GL_DEPTH_BIT_16 = 2,
- EVAS_GL_DEPTH_BIT_24 = 3,
- EVAS_GL_DEPTH_BIT_32 = 4
-} Evas_GL_Depth_Bits;
-
-typedef enum _Evas_GL_Stencil_Bits
-{
- EVAS_GL_STENCIL_NONE = 0,
- EVAS_GL_STENCIL_BIT_1 = 1,
- EVAS_GL_STENCIL_BIT_2 = 2,
- EVAS_GL_STENCIL_BIT_4 = 3,
- EVAS_GL_STENCIL_BIT_8 = 4,
- EVAS_GL_STENCIL_BIT_16 = 5
-} Evas_GL_Stencil_Bits;
-
-typedef enum _Evas_GL_Options_Bits
-{
- EVAS_GL_OPTIONS_NONE = 0,
- EVAS_GL_OPTIONS_DIRECT = (1<<0)
-} Evas_GL_Options_Bits;
-
-typedef enum _Evas_GL_Multisample_Bits
-{
- EVAS_GL_MULTISAMPLE_NONE = 0,
- EVAS_GL_MULTISAMPLE_LOW = 1,
- EVAS_GL_MULTISAMPLE_MED = 2,
- EVAS_GL_MULTISAMPLE_HIGH = 3
-} Evas_GL_Multisample_Bits;
-
-struct _Evas_GL_Config
-{
- Evas_GL_Color_Format color_format;
- Evas_GL_Depth_Bits depth_bits;
- Evas_GL_Stencil_Bits stencil_bits;
- Evas_GL_Options_Bits options_bits;
- Evas_GL_Multisample_Bits multisample_bits;
-};
-
-#define EVAS_GL_EXTENSIONS 1
-
-
/**
* @defgroup Evas_GL Rendering GL on Evas
*
*/
/**
+ * @typedef Evas_GL
+ *
+ * Evas GL Object for rendering gl in Evas.
+ */
+typedef struct _Evas_GL Evas_GL;
+
+/**
+ * @typedef Evas_GL_Surface
+ *
+ * Evas GL Surface object, a GL rendering target in Evas GL.
+ */
+typedef struct _Evas_GL_Surface Evas_GL_Surface;
+
+/**
+ * @typedef Evas_GL_Context
+ *
+ * Evas GL Context object, a GL rendering context in Evas GL.
+ */
+typedef struct _Evas_GL_Context Evas_GL_Context;
+
+/**
+ * @typedef Evas_GL_Config
+ *
+ * Evas GL Surface configuration object for surface creation.
+ */
+typedef struct _Evas_GL_Config Evas_GL_Config;
+
+/**
+ * @typedef Evas_GL_API
+ *
+ * Evas GL API object that contains the GL APIs to be used in Evas GL.
+ */
+typedef struct _Evas_GL_API Evas_GL_API;
+
+/**
+ * @typedef Evas_GL_Func
+ *
+ * Evas GL Function Object used as a function pointer.
+ */
+typedef void *Evas_GL_Func;
+
+/**
+ * @typedef EvasGLImage
+ *
+ * Evas GL Image Object used in Evas GL Image extension.
+ */
+typedef void *EvasGLImage;
+
+/**
+ * Surface Color Format
+ */
+typedef enum _Evas_GL_Color_Format
+{
+ EVAS_GL_RGB_888 = 0,
+ EVAS_GL_RGBA_8888 = 1
+} Evas_GL_Color_Format;
+
+/**
+ * Surface Depth Format
+ */
+typedef enum _Evas_GL_Depth_Bits
+{
+ EVAS_GL_DEPTH_NONE = 0,
+ EVAS_GL_DEPTH_BIT_8 = 1,
+ EVAS_GL_DEPTH_BIT_16 = 2,
+ EVAS_GL_DEPTH_BIT_24 = 3,
+ EVAS_GL_DEPTH_BIT_32 = 4
+} Evas_GL_Depth_Bits;
+
+/**
+ * Surface Stencil Format
+ */
+typedef enum _Evas_GL_Stencil_Bits
+{
+ EVAS_GL_STENCIL_NONE = 0,
+ EVAS_GL_STENCIL_BIT_1 = 1,
+ EVAS_GL_STENCIL_BIT_2 = 2,
+ EVAS_GL_STENCIL_BIT_4 = 3,
+ EVAS_GL_STENCIL_BIT_8 = 4,
+ EVAS_GL_STENCIL_BIT_16 = 5
+} Evas_GL_Stencil_Bits;
+
+/**
+ * Configuration Options.
+ *
+ * @since 1.1.0
+ */
+typedef enum _Evas_GL_Options_Bits
+{
+ EVAS_GL_OPTIONS_NONE = 0, /**< No extra options */
+ EVAS_GL_OPTIONS_DIRECT = (1<<0) /**< Optional hint to allow rendering directly to evas' window when possible */
+} Evas_GL_Options_Bits;
+
+/**
+ * Configuration Option for Multisample Anti-aliased (MSAA) rendering surface.
+ * Only works in supported device.
+ *
+ * @since 1.2.0
+ */
+typedef enum _Evas_GL_Multisample_Bits
+{
+ EVAS_GL_MULTISAMPLE_NONE = 0, /**< No multisample rendering */
+ EVAS_GL_MULTISAMPLE_LOW = 1, /**< MSAA with mininum number of samples */
+ EVAS_GL_MULTISAMPLE_MED = 2, /**< MSAA with half the number of max samples */
+ EVAS_GL_MULTISAMPLE_HIGH = 3 /**< MSAA with maximum allowed samples */
+} Evas_GL_Multisample_Bits;
+
+/**
+ * @struct _Evas_GL_Config
+ *
+ * Evas GL Surface configuration
+ */
+struct _Evas_GL_Config
+{
+ Evas_GL_Color_Format color_format; /**< Surface Color Format */
+ Evas_GL_Depth_Bits depth_bits; /**< Surface Depth Bits */
+ Evas_GL_Stencil_Bits stencil_bits; /**< Surface Stencil Bits */
+ Evas_GL_Options_Bits options_bits; /**< Extra Surface Options */
+ Evas_GL_Multisample_Bits multisample_bits; /**< Optional Surface MSAA Bits */
+};
+
+#define EVAS_GL_EXTENSIONS 1
+
+
+/**
* Creates a new Evas_GL object and returns a handle for gl rendering on efl.
*
* @param e The given evas canvas OpenGL is to be used on.
* As long as the Evas creates a config object for the user, it takes care
* of the backward compatibility issue.
*/
-EAPI Evas_GL_Config *evas_gl_config_new ();
+EAPI Evas_GL_Config *evas_gl_config_new (void);
/**
* Frees a config object created from evas_gl_config_new.
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#else
+# ifndef EVAS_GL_NO_GL_H_CHECK
+# error "You may only include either Evas_GL.h OR use your native OpenGL's headers. If you use Evas to do GL, then you cannot use the native gl headers."
+# endif
+#endif
+
+
+#if !defined(__glext_h_) && !defined(__gl2ext_h_)
+# define __glext_h_
+# define __gl2ext_h_
+
//---------------------------//
// GLES extension defines
#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+/* GL_IMG_multisampled_render_to_texture */
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+
/*------------------------------------------------------------------------*
* NV extension tokens
*------------------------------------------------------------------------*/
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = canvas cache cserve file engines include
+SUBDIRS = canvas cache cache2 cserve cserve2 file engines include
EVAS_STATIC_MODULE =
EVAS_STATIC_LIBADD =
endif
+if EVAS_CSERVE2
+
+libevas_cserve2_la = cserve2/libevas_cserve2.la
+
+endif
+
libevas_la_LIBADD = \
canvas/libevas_canvas.la \
file/libevas_file.la \
cache/libevas_cache.la \
$(libevas_cserve_la) \
+$(libevas_cserve2_la) \
engines/common/libevas_engine_common.la \
@FREETYPE_LIBS@ \
@FRIBIDI_LIBS@ \
file/libevas_file.la \
cache/libevas_cache.la \
$(libevas_cserve_la) \
+$(libevas_cserve2_la) \
engines/common/libevas_engine_common.la \
$(EVAS_STATIC_MODULE)
+if EVAS_CSERVE2
+
+libevas_la_LIBADD += \
+cache2/libevas_cache2.la
+
+libevas_la_DEPENDENCIES += \
+cache2/libevas_cache2.la
+
+endif
+
if BUILD_ENGINE_SOFTWARE_16
libevas_la_LIBADD += engines/common_16/libevas_engine_common_16.la
### Evas_GL we are still using it in our code, so just don't install it.
EXTRA_DIST=Evas_GL.h
-DIST_SUBDIRS = canvas cache cserve file engines include
+DIST_SUBDIRS = canvas cache cache2 cserve cserve2 file engines include
MAINTAINERCLEANFILES = Makefile.in
-AM_CPPFLAGS = -I. \
- -I$(top_srcdir)/src/lib \
- -I$(top_srcdir)/src/lib/include \
- -DPACKAGE_BIN_DIR=\"$(bindir)\" \
- -DPACKAGE_LIB_DIR=\"$(libdir)\" \
- -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
- @EVIL_CFLAGS@ \
- @FREETYPE_CFLAGS@ \
- @PIXMAN_CFLAGS@ \
- @EINA_CFLAGS@ \
- @PIXMAN_CFLAGS@
+AM_CPPFLAGS = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EVIL_CFLAGS@ \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@EINA_CFLAGS@
noinst_LTLIBRARIES = libevas_cache.la
libevas_cache_la_SOURCES = \
int usage;
unsigned int limit;
int references;
-#ifdef EVAS_FRAME_QUEUING
- LK(lock);
-#endif
};
struct _Evas_Cache_Engine_Image_Func
//#define CACHEDUMP 1
-#ifdef EVAS_CSERVE
+#ifdef EVAS_CSERVE2
// FIXME: cache server and threaded preload clash badly atm - disable
-//#undef BUILD_ASYNC_PRELOAD
+#undef BUILD_ASYNC_PRELOAD
#endif
#ifdef BUILD_ASYNC_PRELOAD
_evas_cache_image_lru_nodata_del(im);
im->flags.dirty = 1;
im->flags.cached = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
im->cache->dirty = eina_inlist_prepend(im->cache->dirty, EINA_INLIST_GET(im));
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
if (im->cache_key)
{
eina_stringshare_del(im->cache_key);
if (!im->flags.dirty) return;
im->flags.dirty = 0;
im->flags.cached = 0;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im));
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
if (!im->cache_key) return;
im->flags.activ = 1;
im->flags.cached = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
eina_hash_direct_add(im->cache->activ, im->cache_key, im);
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
if (!im->cache_key) return;
im->flags.activ = 0;
im->flags.cached = 0;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
eina_hash_del(im->cache->activ, im->cache_key, im);
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
if (!im->cache_key) return;
im->flags.lru = 1;
im->flags.cached = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage += im->cache->func.mem_size_get(im);
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
if (!im->cache_key) return;
im->flags.lru = 0;
im->flags.cached = 0;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
eina_hash_del(im->cache->inactiv, im->cache_key, im);
im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage -= im->cache->func.mem_size_get(im);
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
_evas_cache_image_lru_del(im);
im->flags.lru = 1;
im->flags.cached = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im));
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
if (!im->flags.lru_nodata) return;
im->flags.lru = 0;
im->flags.cached = 0;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->cache->lock);
-#endif
im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im));
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->cache->lock);
-#endif
}
static void
LKD(ie->lock);
LKD(ie->lock_cancel);
#endif
-#ifdef EVAS_FRAME_QUEUING
- LKD(ie->lock_references);
-#endif
cache->func.dealloc(ie);
}
if (tstamp) ie->tstamp = *tstamp;
else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
-#ifdef EVAS_FRAME_QUEUING
- LKI(ie->lock_references);
-#endif
#ifdef BUILD_ASYNC_PRELOAD
LKI(ie->lock);
LKI(ie->lock_cancel);
return;
}
if (ie->flags.loaded) _evas_cache_image_async_end(ie);
-#ifdef EVAS_FRAME_QUEUING
- LKL(ie->lock_references);
-#endif
if (ie->references == 0)
{
_evas_cache_image_lru_add(ie);
cache = ie->cache;
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(ie->lock_references);
-#endif
if (cache) evas_cache_image_flush(cache);
}
EAPI void
evas_cache_image_set(Evas_Cache_Image *cache, unsigned int limit)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(cache->lock);
-#endif
if (cache->limit == limit)
{
-#ifdef EVAS_FRAME_QUEUING
- LKU(cache->lock);
-#endif
return;
}
cache->limit = limit;
-#ifdef EVAS_FRAME_QUEUING
- LKU(cache->lock);
-#endif
evas_cache_image_flush(cache);
}
cache->inactiv = eina_hash_string_superfast_new(NULL);
cache->activ = eina_hash_string_superfast_new(NULL);
cache->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKI(cache->lock);
-#endif
return cache;
}
Eina_List *delete_list;
Image_Entry *im;
-#ifdef EVAS_FRAME_QUEUING
- LKL(cache->lock);
-#endif
cache->references--;
if (cache->references != 0)
{
-#ifdef EVAS_FRAME_QUEUING
- LKU(cache->lock);
-#endif
return;
}
-#ifdef EVAS_FRAME_QUEUING
- /* Release and destroy lock early ! */
- LKU(cache->lock);
- LKD(cache->lock);
-#endif
#ifdef BUILD_ASYNC_PRELOAD
EINA_LIST_FREE(cache->preload, im)
hkey[size] = '\0';
/* find image by key in active hash */
-#ifdef EVAS_FRAME_QUEUING
- LKL(cache->lock);
-#endif
im = eina_hash_find(cache->activ, hkey);
-#ifdef EVAS_FRAME_QUEUING
- LKU(cache->lock);
-#endif
if (im)
{
int ok = 1;
}
/* find image by key in inactive/lru hash */
-#ifdef EVAS_FRAME_QUEUING
- LKL(cache->lock);
-#endif
im = eina_hash_find(cache->inactiv, hkey);
-#ifdef EVAS_FRAME_QUEUING
- LKU(cache->lock);
-#endif
if (im)
{
int ok = 1;
on_ok:
*error = EVAS_LOAD_ERROR_NONE;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
im->references++;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
return im;
on_stat_error:
Evas_Cache_Image *cache;
int references;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
im->references--;
if (im->references < 0) im->references = 0;
references = im->references;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
cache = im->cache;
if (references == 0)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->ref_fq_add);
- LKL(im->ref_fq_del);
- if (im->ref_fq[0] != im->ref_fq[1])
- {
- LKU(im->ref_fq_add);
- LKU(im->ref_fq_del);
- return;
- }
- LKU(im->ref_fq_add);
- LKU(im->ref_fq_del);
-#endif
-
#ifdef BUILD_ASYNC_PRELOAD
if (im->preload)
{
{
int references;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
references = im->references;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
if (references > 1) return;
if ((im->flags.dirty) || (!im->flags.need_data)) return;
_evas_cache_image_lru_nodata_add(im);
{
#ifndef EVAS_CSERVE
int references;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
references = im->references;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
// if ref 1 also copy if using shared cache as its read-only
if (references == 1) im_dirty = im;
else
if (cache->func.debug) cache->func.debug("dirty-src", im);
cache->func.dirty(im_dirty, im);
if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
-#ifdef EVAS_FRAME_QUEUING
- LKL(im_dirty->lock_references);
-#endif
im_dirty->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im_dirty->lock_references);
-#endif
evas_cache_image_drop(im);
}
_evas_cache_image_dirty_add(im_dirty);
int references;
cache = im->cache;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
references = im->references;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
if (references <= 1)
{
if (cache->func.debug) cache->func.debug("dirty-src", im);
cache->func.dirty(im_dirty, im);
if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
-#ifdef EVAS_FRAME_QUEUING
- LKL(im_dirty->lock_references);
-#endif
im_dirty->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im_dirty->lock_references);
-#endif
evas_cache_image_drop(im);
}
return im_dirty;
_evas_cache_image_entry_delete(cache, im);
return NULL;
}
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
im->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
if (cache->func.debug) cache->func.debug("copied-data", im);
return im;
}
_evas_cache_image_entry_delete(cache, im);
return NULL;
}
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
im->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
if (cache->func.debug) cache->func.debug("data", im);
return im;
}
_evas_cache_image_entry_surface_alloc(cache, im2, w, h);
error = cache->func.size_set(im2, im, w, h);
if (error != 0) goto on_error;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im2->lock_references);
-#endif
im2->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im2->lock_references);
-#endif
evas_cache_image_drop(im);
if (cache->func.debug) cache->func.debug("size_set", im2);
return im2;
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
if (!im) return NULL;
-#ifdef EVAS_FRAME_QUEUING
- LKL(im->lock_references);
-#endif
im->references = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKU(im->lock_references);
-#endif
return im;
}
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = -I. \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib/include \
+ -I$(top_srcdir)/src/lib/cserve2 \
+ -DPACKAGE_BIN_DIR=\"$(bindir)\" \
+ -DPACKAGE_LIB_DIR=\"$(libdir)\" \
+ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+ @EVIL_CFLAGS@ \
+ @FREETYPE_CFLAGS@ \
+ @PIXMAN_CFLAGS@ \
+ @EINA_CFLAGS@ \
+ @PIXMAN_CFLAGS@
+
+if EVAS_CSERVE2
+
+noinst_LTLIBRARIES = libevas_cache2.la
+libevas_cache2_la_SOURCES = \
+evas_cache2.c
+
+noinst_HEADERS = evas_cache2.h
+
+libevas_cache2_la_LIBAD = @EVIL_LIBS@
+
+libevas_cache2_la_DEPENDENCIES = $(top_builddir)/config.h
+
+endif
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_common.h"
+#include "evas_private.h"
+#include "evas_cache2.h"
+#include "evas_cs2.h"
+#include "evas_cs2_private.h"
+
+#define FREESTRC(Var) \
+ if (Var) \
+{ \
+ eina_stringshare_del(Var); \
+ Var = NULL; \
+}
+
+static void _evas_cache_image_dirty_add(Image_Entry *im);
+static void _evas_cache_image_dirty_del(Image_Entry *im);
+static void _evas_cache_image_activ_add(Image_Entry *im);
+static void _evas_cache_image_activ_del(Image_Entry *im);
+static void _evas_cache_image_lru_add(Image_Entry *im);
+static void _evas_cache_image_lru_del(Image_Entry *im);
+static void _evas_cache2_image_entry_preload_remove(Image_Entry *ie, const void *target);
+// static void _evas_cache_image_lru_nodata_add(Image_Entry *im);
+// static void _evas_cache_image_lru_nodata_del(Image_Entry *im);
+
+static void
+_evas_cache_image_dirty_add(Image_Entry *im)
+{
+ if (im->flags.dirty) return;
+ _evas_cache_image_activ_del(im);
+ _evas_cache_image_lru_del(im);
+ // _evas_cache_image_lru_nodata_del(im);
+ im->flags.dirty = 1;
+ im->flags.cached = 1;
+ im->cache2->dirty = eina_inlist_prepend(im->cache2->dirty, EINA_INLIST_GET(im));
+ if (im->cache_key)
+ {
+ eina_stringshare_del(im->cache_key);
+ im->cache_key = NULL;
+ }
+}
+
+static void
+_evas_cache_image_dirty_del(Image_Entry *im)
+{
+ if (!im->flags.dirty) return;
+ if (!im->cache2) return;
+ im->flags.dirty = 0;
+ im->flags.cached = 0;
+ im->cache2->dirty = eina_inlist_remove(im->cache2->dirty, EINA_INLIST_GET(im));
+}
+
+static void
+_evas_cache_image_activ_add(Image_Entry *im)
+{
+ if (im->flags.activ) return;
+ _evas_cache_image_dirty_del(im);
+ _evas_cache_image_lru_del(im);
+ // _evas_cache_image_lru_nodata_del(im);
+ if (!im->cache_key) return;
+ im->flags.activ = 1;
+ im->flags.cached = 1;
+ eina_hash_direct_add(im->cache2->activ, im->cache_key, im);
+}
+
+static void
+_evas_cache_image_activ_del(Image_Entry *im)
+{
+ if (!im->flags.activ) return;
+ if (!im->cache_key) return;
+ im->flags.activ = 0;
+ im->flags.cached = 0;
+ eina_hash_del(im->cache2->activ, im->cache_key, im);
+}
+
+static void
+_evas_cache_image_lru_add(Image_Entry *im)
+{
+ if (im->flags.lru) return;
+ _evas_cache_image_dirty_del(im);
+ _evas_cache_image_activ_del(im);
+ // _evas_cache_image_lru_nodata_del(im);
+ if (!im->cache_key) return;
+ im->flags.lru = 1;
+ im->flags.cached = 1;
+ eina_hash_direct_add(im->cache2->inactiv, im->cache_key, im);
+ im->cache2->lru = eina_inlist_prepend(im->cache2->lru, EINA_INLIST_GET(im));
+ im->cache2->usage += im->cache2->func.mem_size_get(im);
+}
+
+static void
+_evas_cache_image_lru_del(Image_Entry *im)
+{
+ if (!im->flags.lru) return;
+ if (!im->cache_key) return;
+ im->flags.lru = 0;
+ im->flags.cached = 0;
+ eina_hash_del(im->cache2->inactiv, im->cache_key, im);
+ im->cache2->lru = eina_inlist_remove(im->cache2->lru, EINA_INLIST_GET(im));
+ im->cache2->usage -= im->cache2->func.mem_size_get(im);
+}
+
+/*
+static void
+_evas_cache_image_lru_nodata_add(Image_Entry *im)
+{
+ if (im->flags.lru_nodata) return;
+ _evas_cache_image_dirty_del(im);
+ _evas_cache_image_activ_del(im);
+ _evas_cache_image_lru_del(im);
+ im->flags.lru = 1;
+ im->flags.cached = 1;
+ im->cache2->lru_nodata = eina_inlist_prepend(im->cache2->lru_nodata, EINA_INLIST_GET(im));
+}
+
+static void
+_evas_cache_image_lru_nodata_del(Image_Entry *im)
+{
+ if (!im->flags.lru_nodata) return;
+ im->flags.lru = 0;
+ im->flags.cached = 0;
+ im->cache2->lru_nodata = eina_inlist_remove(im->cache2->lru_nodata, EINA_INLIST_GET(im));
+}
+*/
+
+static Eina_Bool
+_timestamp_compare(Image_Timestamp *tstamp, struct stat *st)
+{
+ if (tstamp->mtime != st->st_mtime) return EINA_FALSE;
+ if (tstamp->size != st->st_size) return EINA_FALSE;
+ if (tstamp->ino != st->st_ino) return EINA_FALSE;
+#ifdef _STAT_VER_LINUX
+#if (defined __USE_MISC && defined st_mtime)
+ if (tstamp->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec)
+ return EINA_FALSE;
+#else
+ if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec)
+ return EINA_FALSE;
+#endif
+#endif
+ return EINA_TRUE;
+}
+
+static void
+_timestamp_build(Image_Timestamp *tstamp, struct stat *st)
+{
+ tstamp->mtime = st->st_mtime;
+ tstamp->size = st->st_size;
+ tstamp->ino = st->st_ino;
+#ifdef _STAT_VER_LINUX
+#if (defined __USE_MISC && defined st_mtime)
+ tstamp->mtime_nsec = (unsigned long int)st->st_mtim.tv_nsec;
+#else
+ tstamp->mtime_nsec = (unsigned long int)st->st_mtimensec;
+#endif
+#endif
+}
+
+static void
+_evas_cache_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
+{
+ if (!ie) return;
+
+ if (ie->flags.delete_me == 1)
+ return;
+
+ if (ie->preload_rid)
+ {
+ ie->flags.delete_me = 1;
+ _evas_cache2_image_entry_preload_remove(ie, NULL);
+ return;
+ }
+
+ _evas_cache_image_dirty_del(ie);
+ _evas_cache_image_activ_del(ie);
+ _evas_cache_image_lru_del(ie);
+ // _evas_cache_image_lru_nodata_del(ie);
+
+
+ if (ie->data1)
+ {
+ evas_cserve2_image_unload(ie);
+ evas_cache2_image_unload_data(ie);
+ evas_cserve2_image_free(ie);
+ }
+ else
+ {
+ if (cache)
+ cache->func.surface_delete(ie);
+ }
+
+ FREESTRC(ie->cache_key);
+ FREESTRC(ie->file);
+ FREESTRC(ie->key);
+ ie->cache2 = NULL;
+
+ evas_common_rgba_image_scalecache_shutdown(ie);
+
+ free(ie);
+}
+
+static Image_Entry *
+_evas_cache_image_entry_new(Evas_Cache2 *cache,
+ const char *hkey,
+ Image_Timestamp *tstamp,
+ const char *file,
+ const char *key,
+ RGBA_Image_Loadopts *lo,
+ int *error)
+{
+ Image_Entry *ie;
+ RGBA_Image *im;
+
+ // ie = cache->func.alloc();
+ im = calloc(1, sizeof(RGBA_Image));
+ if (!im)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return NULL;
+ }
+
+ im->flags = RGBA_IMAGE_NOTHING;
+ im->ref = 1;
+ evas_common_rgba_image_scalecache_init(&im->cache_entry);
+
+ ie = &im->cache_entry;
+
+ ie->cache2 = cache;
+ if (hkey) ie->cache_key = eina_stringshare_add(hkey);
+ ie->flags.need_data = 1;
+ ie->space = EVAS_COLORSPACE_ARGB8888;
+ ie->w = -1;
+ ie->h = -1;
+ ie->scale = 1;
+ if (file) ie->file = eina_stringshare_add(file);
+ if (key) ie->key = eina_stringshare_add(key);
+ if (tstamp) ie->tstamp = *tstamp;
+ else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
+
+ if (lo) ie->load_opts = *lo;
+ if (ie->file)
+ {
+ if (!evas_cserve2_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
+ {
+ ERR("couldn't load '%s' '%s' with cserve2!",
+ ie->file, ie->key ? ie->key : "");
+ _evas_cache_image_entry_delete(cache, ie);
+ return NULL;
+ }
+ }
+
+ if (ie->cache_key) _evas_cache_image_activ_add(ie);
+ else _evas_cache_image_dirty_add(ie);
+ return ie;
+}
+
+EAPI void
+evas_cache2_image_surface_alloc(Image_Entry *ie, int w, int h)
+{
+ Evas_Cache2 *cache = ie->cache2;
+ int wmin = w > 0 ? w : 1;
+ int hmin = h > 0 ? h : 1;
+
+ if (cache->func.surface_alloc(ie, wmin, hmin))
+ {
+ wmin = 0;
+ hmin = 0;
+ }
+
+ ie->w = wmin;
+ ie->h = hmin;
+ ie->allocated.w = wmin;
+ ie->allocated.h = hmin;
+ ie->flags.loaded = EINA_TRUE;
+}
+
+static void
+_evas_cache2_image_preloaded_cb(void *data, Eina_Bool success)
+{
+ Image_Entry *ie = data;
+ Evas_Cache_Target *tmp;
+
+ ie->cache2->preload = eina_list_remove(ie->cache2->preload, ie);
+ ie->flags.preload_done = success;
+
+ while ((tmp = ie->targets))
+ {
+ ie->targets = (Evas_Cache_Target *)
+ eina_inlist_remove(EINA_INLIST_GET(ie->targets),
+ EINA_INLIST_GET(ie->targets));
+ if (!ie->flags.delete_me)
+ evas_object_inform_call_image_preloaded((Evas_Object *) tmp->target);
+ free(tmp);
+ }
+
+ if (ie->flags.delete_me)
+ _evas_cache_image_entry_delete(ie->cache2, ie);
+}
+
+static Eina_Bool
+_evas_cache2_image_entry_preload_add(Image_Entry *ie, const void *target)
+{
+ Evas_Cache_Target *tg;
+
+ if (ie->flags.preload_done)
+ return EINA_FALSE;
+
+ tg = malloc(sizeof(Evas_Cache_Target));
+ if (!tg)
+ return EINA_TRUE;
+
+ tg->target = target;
+ ie->targets = (Evas_Cache_Target *)
+ eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
+
+ if (!ie->preload_rid)
+ {
+ ie->cache2->preload = eina_list_append(ie->cache2->preload, ie);
+ evas_cserve2_image_preload(ie, _evas_cache2_image_preloaded_cb);
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_evas_cache2_image_entry_preload_remove(Image_Entry *ie, const void *target)
+{
+ if (target)
+ {
+ Evas_Cache_Target *tg;
+
+ EINA_INLIST_FOREACH(ie->targets, tg)
+ {
+ if (tg->target == target)
+ {
+ ie->targets = (Evas_Cache_Target *)
+ eina_inlist_remove(EINA_INLIST_GET(ie->targets),
+ EINA_INLIST_GET(tg));
+ free(tg);
+ break;
+ }
+ }
+ }
+ else
+ {
+ Evas_Cache_Target *tg;
+
+ while (ie->targets)
+ {
+ tg = ie->targets;
+ ie->targets = (Evas_Cache_Target *)
+ eina_inlist_remove(EINA_INLIST_GET(ie->targets),
+ EINA_INLIST_GET(tg));
+ free(tg);
+ }
+ }
+
+ // FIXME: Should also send message to the server to cancel the request.
+}
+
+EAPI Image_Entry *
+evas_cache2_image_copied_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
+{
+ Image_Entry *im;
+
+ if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
+ (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
+ (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
+ w &= ~0x1;
+
+ im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (!im)
+ return NULL;
+
+ im->space = cspace;
+ im->flags.alpha = alpha;
+ evas_cache2_image_surface_alloc(im, w, h);
+ if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
+ {
+ _evas_cache_image_entry_delete(cache, im);
+ return NULL;
+ }
+
+ im->references = 1;
+ im->flags.loaded = EINA_TRUE;
+ if (cache->func.debug) cache->func.debug("copied-data", im);
+
+ return im;
+}
+
+EAPI Image_Entry *
+evas_cache2_image_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
+{
+ Image_Entry *im;
+
+ if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
+ (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
+ (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
+ w &= ~0x1;
+
+ im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (!im) return NULL;
+ im->w = w;
+ im->h = h;
+ im->flags.alpha = alpha;
+ im->flags.loaded = 1;
+ if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
+ {
+ _evas_cache_image_entry_delete(cache, im);
+ return NULL;
+ }
+ im->references = 1;
+ if (cache->func.debug) cache->func.debug("data", im);
+ return im;
+}
+
+EAPI Image_Entry *
+evas_cache2_image_empty(Evas_Cache2 *cache)
+{
+ Image_Entry *im;
+
+ im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (!im)
+ return NULL;
+
+ im->references = 1;
+ return im;
+}
+
+EAPI Image_Entry *
+evas_cache2_image_size_set(Image_Entry *im, unsigned int w, unsigned h)
+{
+ Evas_Cache2 *cache;
+ Image_Entry *im2 = NULL;
+ int error;
+
+ if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
+ (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
+ (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
+ w &= ~0x1;
+
+ if ((im->w == w) && (im->h == h)) return im;
+
+ cache = im->cache2;
+ im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ if (!im2) goto on_error;
+
+ im2->flags.alpha = im->flags.alpha;
+ im2->space = im->space;
+ im2->load_opts = im->load_opts;
+ evas_cache2_image_surface_alloc(im2, w, h);
+ error = cache->func.size_set(im2, im, w, h);
+ if (error != 0) goto on_error;
+
+ im2->references = 1;
+
+ evas_cache2_image_close(im);
+ return im2;
+
+on_error:
+ if (im2)
+ _evas_cache_image_entry_delete(cache, im2);
+ return NULL;
+}
+
+EAPI Evas_Cache2 *
+evas_cache2_init(const Evas_Cache2_Image_Func *cb)
+{
+ Evas_Cache2 *cache = calloc(1, sizeof(Evas_Cache2));
+
+ cache->func = *cb;
+ cache->activ = eina_hash_string_superfast_new(NULL);
+ cache->inactiv = eina_hash_string_superfast_new(NULL);
+
+ return cache;
+}
+
+static Eina_Bool
+_evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
+{
+ Eina_List **delete_list = fdata;
+ *delete_list = eina_list_prepend(*delete_list, data);
+ return EINA_TRUE;
+}
+
+EAPI void
+evas_cache2_shutdown(Evas_Cache2 *cache)
+{
+ Eina_List *delete_list;
+ Image_Entry *im;
+
+ while (cache->lru)
+ {
+ im = (Image_Entry *)cache->lru;
+ _evas_cache_image_entry_delete(cache, im);
+ }
+ /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
+ while (cache->dirty)
+ {
+ im = (Image_Entry *)cache->dirty;
+ _evas_cache_image_entry_delete(cache, im);
+ }
+
+ delete_list = NULL;
+ eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
+ while (delete_list)
+ {
+ _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
+ delete_list = eina_list_remove_list(delete_list, delete_list);
+ }
+
+ eina_hash_free(cache->activ);
+ eina_hash_free(cache->inactiv);
+
+ free(cache);
+}
+
+static void
+_create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, RGBA_Image_Loadopts *lo)
+{
+ const char *ckey = "(null)";
+ size_t size;
+
+ /* generate hkey from file+key+load opts */
+ memcpy(hkey, path, pathlen);
+ size = pathlen;
+ memcpy(hkey + size, "//://", 5);
+ size += 5;
+ if (key) ckey = key;
+ memcpy(hkey + size, ckey, keylen);
+ size += keylen;
+ if (lo)
+ {
+ memcpy(hkey + size, "//@/", 4);
+ size += 4;
+ size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
+ hkey[size] = '/';
+ size += 1;
+ size += eina_convert_dtoa(lo->dpi, hkey + size);
+ hkey[size] = '/';
+ size += 1;
+ size += eina_convert_xtoa(lo->w, hkey + size);
+ hkey[size] = 'x';
+ size += 1;
+ size += eina_convert_xtoa(lo->h, hkey + size);
+ hkey[size] = '/';
+ size += 1;
+ size += eina_convert_xtoa(lo->region.x, hkey + size);
+ hkey[size] = '+';
+ size += 1;
+ size += eina_convert_xtoa(lo->region.y, hkey + size);
+ hkey[size] = '.';
+ size += 1;
+ size += eina_convert_xtoa(lo->region.w, hkey + size);
+ hkey[size] = 'x';
+ size += 1;
+ size += eina_convert_xtoa(lo->region.h, hkey + size);
+
+ if (lo->orientation)
+ {
+ hkey[size] = '/';
+ size += 1;
+ hkey[size] = 'o';
+ size += 1;
+ }
+ }
+ hkey[size] = '\0';
+}
+
+EAPI Image_Entry *
+evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error)
+{
+ size_t size;
+ size_t pathlen;
+ size_t keylen;
+ char *hkey;
+ Image_Entry *im;
+ int stat_done = 0, stat_failed = 0;
+ struct stat st;
+ Image_Timestamp tstamp;
+ Evas_Image_Load_Opts prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 }, EINA_FALSE };
+
+ if ((!path) || ((!path) && (!key)))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return NULL;
+ }
+
+ pathlen = strlen(path);
+ keylen = key ? strlen(key) : 6;
+ size = pathlen + keylen + 132;
+ hkey = alloca(sizeof(char) * size);
+
+ _create_hash_key(hkey, path, pathlen, key, keylen, lo);
+ DBG("Looking at the hash for key '%s'", hkey);
+
+ /* use local var to copy default load options to the image entry */
+ if ((!lo) ||
+ (lo &&
+ (lo->scale_down_by == 0) &&
+ (lo->dpi == 0.0) &&
+ ((lo->w == 0) || (lo->h == 0)) &&
+ ((lo->region.w == 0) || (lo->region.h == 0)) &&
+ (lo->orientation == 0)
+ ))
+ {
+ lo = &prevent;
+ }
+
+ im = eina_hash_find(cache->activ, hkey);
+
+ if (im)
+ {
+ int ok = 1;
+ DBG("Found entry on active hash for key: '%s'", hkey);
+
+ stat_done = 1;
+ if (stat(path, &st) < 0)
+ {
+ stat_failed = 1;
+ ok = 0;
+ }
+ else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
+ if (ok) goto on_ok;
+ /* image we found doesn't match what's on disk (stat info wise)
+ * so dirty the active cache entry so we never find it again. this
+ * also implicitly guarantees that we only have 1 active copy
+ * of an image at a given key. we wither find it and keep re-reffing
+ * it or we dirty it and get it out */
+ DBG("Entry on inactive hash was invalid (file changed or deleted).");
+ _evas_cache_image_dirty_add(im);
+ im = NULL;
+ }
+
+ im = eina_hash_find(cache->inactiv, hkey);
+
+ if (im)
+ {
+ int ok = 1;
+ DBG("Found entry on inactive hash for key: '%s'", hkey);
+
+ if (!stat_done)
+ {
+ stat_done = 1;
+ if (stat(path, &st) < 0)
+ {
+ stat_failed = 1;
+ ok = 0;
+ }
+ else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
+ }
+ else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
+
+ if (ok)
+ {
+ /* remove from lru and make it active again */
+ _evas_cache_image_lru_del(im);
+ _evas_cache_image_activ_add(im);
+ goto on_ok;
+ }
+ DBG("Entry on inactive hash was invalid (file changed or deleted).");
+ /* as avtive cache find - if we match in lru and its invalid, dirty */
+ _evas_cache_image_dirty_add(im);
+ /* this image never used, so it have to be deleted */
+ _evas_cache_image_entry_delete(cache, im);
+ im = NULL;
+ }
+ if (stat_failed) goto on_stat_error;
+
+ if (!stat_done)
+ {
+ if (stat(path, &st) < 0) goto on_stat_error;
+ }
+ _timestamp_build(&tstamp, &st);
+ DBG("Creating a new entry for key '%s'.", hkey);
+ im = _evas_cache_image_entry_new(cache, hkey, &tstamp, path, key,
+ lo, error);
+ if (!im) goto on_stat_error;
+
+on_ok:
+ *error = EVAS_LOAD_ERROR_NONE;
+ DBG("Using entry on hash for key '%s'", hkey);
+
+ im->references++;
+
+ return im;
+
+on_stat_error:
+#ifndef _WIN32
+ if ((errno == ENOENT) || (errno == ENOTDIR) ||
+ (errno == ENAMETOOLONG) || (errno == ELOOP))
+#else
+ if (errno == ENOENT)
+#endif
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+#ifndef _WIN32
+ else if ((errno == ENOMEM) || (errno == EOVERFLOW))
+#else
+ else if (errno == ENOMEM)
+#endif
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else if (errno == EACCES)
+ *error = EVAS_LOAD_ERROR_PERMISSION_DENIED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+
+ if (im) _evas_cache_image_entry_delete(cache, im);
+ return NULL;
+}
+
+EAPI int
+evas_cache2_image_open_wait(Image_Entry *im)
+{
+ DBG("Wait for open image '%s' '%s'", im->file, im->key);
+ if (evas_cserve2_image_load_wait(im) != CSERVE2_NONE)
+ return EVAS_LOAD_ERROR_GENERIC;
+
+ return EVAS_LOAD_ERROR_NONE;
+}
+
+EAPI void
+evas_cache2_image_close(Image_Entry *im)
+{
+ Evas_Cache2 *cache;
+ int references;
+
+ im->references--;
+ if (im->references < 0)
+ {
+ ERR("image with negative references: %d", im->references);
+ im->references = 0;
+ }
+
+ references = im->references;
+ cache = im->cache2;
+
+ if (references > 0)
+ return;
+
+ if (im->flags.dirty)
+ {
+ _evas_cache_image_entry_delete(cache, im);
+ return;
+ }
+
+ _evas_cache_image_lru_add(im);
+ if (cache)
+ evas_cache2_flush(cache);
+}
+
+EAPI int
+evas_cache2_image_load_data(Image_Entry *ie)
+{
+ int error = EVAS_LOAD_ERROR_NONE;
+
+ if ((ie->flags.loaded) && (!ie->flags.animated))
+ return error;
+
+ ie->flags.in_progress = EINA_TRUE;
+
+ DBG("try cserve2 image data '%s' '%s'",
+ ie->file, ie->key ? ie->key : "");
+ if (evas_cserve2_image_data_load(ie))
+ {
+ evas_cserve2_image_load_data_wait(ie);
+ RGBA_Image *im = (RGBA_Image *)ie;
+ im->image.data = evas_cserve2_image_data_get(ie);
+ DBG("try cserve2 image data '%s' '%s' loaded!",
+ ie->file, ie->key ? ie->key : "");
+ if (im->image.data)
+ {
+ im->image.no_free = 1;
+ error = EVAS_LOAD_ERROR_NONE;
+ }
+ else
+ {
+ ERR("Failed to load data for image '%s' '%s'.",
+ ie->file, ie->key ? ie->key : "");
+ error = EVAS_LOAD_ERROR_GENERIC;
+ }
+ }
+ else
+ {
+ ERR("Couldn't send LOAD message to cserve2.");
+ error = EVAS_LOAD_ERROR_GENERIC;
+ }
+
+ ie->flags.in_progress = EINA_FALSE;
+ ie->flags.loaded = 1;
+
+ if (error != EVAS_LOAD_ERROR_NONE)
+ ie->flags.loaded = 0;
+
+ return error;
+}
+
+EAPI void
+evas_cache2_image_unload_data(Image_Entry *im)
+{
+ // FIXME: This function seems pretty useless, since we always have
+ // to send an UNLOAD message to the server when closing an image,
+ // even if we didn't send a LOAD message before, because the SETOPTS
+ // message increases the image refcount.
+ if (im->flags.in_progress)
+ return;
+
+ if ((!im->file))
+ return;
+
+ if (!im->flags.loaded)
+ return;
+
+// if (im->data2)
+ im->flags.loaded = 0;
+}
+
+EAPI void
+evas_cache2_image_preload_data(Image_Entry *im, const void *target)
+{
+ RGBA_Image *img = (RGBA_Image *)im;
+
+ if ((im->flags.loaded) && (img->image.data))
+ {
+ evas_object_inform_call_image_preloaded((Evas_Object *)target);
+ return;
+ }
+
+ if (!_evas_cache2_image_entry_preload_add(im, target))
+ evas_object_inform_call_image_preloaded((Evas_Object *)target);
+}
+
+EAPI void
+evas_cache2_image_preload_cancel(Image_Entry *im, const void *target)
+{
+ if (!target)
+ return;
+
+ _evas_cache2_image_entry_preload_remove(im, target);
+}
+
+EAPI DATA32 *
+evas_cache2_image_pixels(Image_Entry *im)
+{
+ return im->cache2->func.surface_pixels(im);
+}
+
+EAPI Image_Entry *
+evas_cache2_image_writable(Image_Entry *im)
+{
+ Evas_Cache2 *cache = im->cache2;
+ Image_Entry *im2 = NULL;
+
+ if (!im->cache_key)
+ {
+ if (!im->flags.dirty)
+ _evas_cache_image_dirty_add(im);
+ return im;
+ }
+
+ im2 = evas_cache2_image_copied_data(cache, im->w, im->h,
+ evas_cache2_image_pixels(im),
+ im->flags.alpha, im->space);
+ if (!im2)
+ goto on_error;
+
+ evas_cache2_image_close(im);
+ return im2;
+
+on_error:
+ if (im2)
+ _evas_cache_image_entry_delete(cache, im2);
+ return NULL;
+}
+
+EAPI Image_Entry *
+evas_cache2_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
+{
+ Evas_Cache2 *cache = im->cache2;
+ Image_Entry *im2 = NULL;
+
+ if (!im->cache_key)
+ {
+ if (!im->flags.dirty)
+ _evas_cache_image_dirty_add(im);
+ im2 = im;
+ }
+ else
+ {
+ im2 = evas_cache2_image_copied_data(cache, im->w, im->h,
+ evas_cache2_image_pixels(im),
+ im->flags.alpha, im->space);
+ if (!im2)
+ goto on_error;
+
+ evas_cache2_image_close(im);
+ }
+
+ if (cache->func.dirty_region)
+ cache->func.dirty_region(im2, x, y, w, h);
+
+ return im2;
+
+on_error:
+ if (im2)
+ _evas_cache_image_entry_delete(cache, im2);
+ evas_cache2_image_close(im);
+ return NULL;
+}
+
+EAPI int
+evas_cache2_flush(Evas_Cache2 *cache)
+{
+ if (cache->limit == -1) return -1;
+
+ while ((cache->lru) && (cache->limit < cache->usage))
+ {
+ Image_Entry *im;
+
+ im = (Image_Entry *)cache->lru->last;
+ DBG("Remove unused entry from cache.");
+ _evas_cache_image_entry_delete(cache, im);
+ }
+
+ return cache->usage;
+}
+
+EAPI void
+evas_cache2_limit_set(Evas_Cache2 *cache, int limit)
+{
+ if (cache->limit == limit)
+ return;
+
+ DBG("Cache2 limit set to %d", limit);
+
+ cache->limit = limit;
+
+ evas_cache2_flush(cache);
+}
+
+EAPI int
+evas_cache2_limit_get(Evas_Cache2 *cache)
+{
+ return cache->limit;
+}
+
+EAPI int
+evas_cache2_usage_get(Evas_Cache2 *cache)
+{
+ return cache->usage;
+}
--- /dev/null
+#ifndef _EVAS_CACHE2_H
+#define _EVAS_CACHE2_H
+
+typedef struct _Evas_Cache2_Image_Func Evas_Cache2_Image_Func;
+typedef struct _Evas_Cache2 Evas_Cache2;
+
+struct _Evas_Cache2_Image_Func
+{
+ // Image_Entry *(*alloc)(void);
+ // void (*dealloc)(Image_Entry *im);
+
+ /* The cache provide some helpers for surface manipulation. */
+ int (*surface_alloc)(Image_Entry *im, unsigned int w, unsigned int h);
+ void (*surface_delete)(Image_Entry *im);
+ DATA32 *(*surface_pixels)(Image_Entry *im);
+
+ /* The cache is doing the allocation and deallocation, you must just do the rest. */
+ // int (*constructor)(Image_Entry *im); /**< return is EVAS_LOAD_ERROR_* or EVAS_LOAD_ERROR_NONE! */
+ // void (*destructor)(Image_Entry *im);
+
+ void (*dirty_region)(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
+ /* Only called when references > 0. Need to provide a fresh copie of im. */
+ /* The destination surface does have a surface, but no allocated pixel data. */
+ int (*dirty)(Image_Entry *dst, const Image_Entry *src);
+ /* Only called when references == 1. We will call drop on `im'. */
+ /* The destination surface does not have any surface. */
+ int (*size_set)(Image_Entry *dst, const Image_Entry *src, unsigned int w, unsigned int h);
+
+ /* The destination surface does not have any surface. */
+ int (*copied_data)(Image_Entry *dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
+ /* The destination surface does not have any surface. */
+ int (*data)(Image_Entry *dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
+ int (*color_space)(Image_Entry *dst, int cspace);
+
+ /* This function need to update im->w and im->h. */
+ // int (*load)(Image_Entry *im); /**< return is EVAS_LOAD_ERROR_* or EVAS_LOAD_ERROR_NONE! */
+ int (*mem_size_get)(Image_Entry *im);
+ void (*debug)(const char *context, Image_Entry *im);
+};
+
+struct _Evas_Cache2
+{
+ Evas_Cache2_Image_Func func;
+
+ Eina_List *preload;
+
+ Eina_Hash *inactiv;
+ Eina_Hash *activ;
+ Eina_Inlist *dirty;
+ Eina_Inlist *lru;
+ int usage;
+ int limit;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EAPI Evas_Cache2* evas_cache2_init(const Evas_Cache2_Image_Func *cb);
+EAPI void evas_cache2_shutdown(Evas_Cache2 *cache);
+EAPI Image_Entry * evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error);
+EAPI int evas_cache2_image_open_wait(Image_Entry *im);
+EAPI void evas_cache2_image_close(Image_Entry *im);
+EAPI int evas_cache2_image_load_data(Image_Entry *ie);
+EAPI void evas_cache2_image_unload_data(Image_Entry *im);
+EAPI void evas_cache2_image_preload_data(Image_Entry *im, const void *target);
+
+EAPI DATA32 * evas_cache2_image_pixels(Image_Entry *im);
+EAPI Image_Entry * evas_cache2_image_writable(Image_Entry *im);
+EAPI Image_Entry * evas_cache2_image_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
+EAPI Image_Entry * evas_cache2_image_copied_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
+EAPI Image_Entry * evas_cache2_image_size_set(Image_Entry *im, unsigned int w, unsigned h);
+EAPI Image_Entry * evas_cache2_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
+EAPI Image_Entry * evas_cache2_image_empty(Evas_Cache2 *cache);
+EAPI void evas_cache2_image_surface_alloc(Image_Entry *ie, int w, int h);
+
+EAPI int evas_cache2_flush(Evas_Cache2 *cache);
+EAPI void evas_cache2_limit_set(Evas_Cache2 *cache, int limit);
+EAPI int evas_cache2_limit_get(Evas_Cache2 *cache);
+EAPI int evas_cache2_usage_get(Evas_Cache2 *cache);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _EVAS_CACHE2_H */
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
-I$(top_srcdir)/src/lib/cserve \
+-I$(top_srcdir)/src/lib/cserve2 \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EVAS_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@ \
-@PIXMAN_CFLAGS@
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@
noinst_LTLIBRARIES = libevas_canvas.la
libevas_canvas_la_SOURCES = \
evas_object_table.c \
evas_object_text.c \
evas_object_textblock.c \
+evas_object_textgrid.c \
evas_object_grid.c \
evas_font_dir.c \
evas_rectangle.c \
{
EVAS_MEMPOOL_FREE(_mp_pc, pc);
}
- _evas_unwalk(e);
}
void
if (!obj->callbacks)
{
- EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 512, );
+ EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 64, );
obj->callbacks = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Callbacks);
if (!obj->callbacks) return;
EVAS_MEMPOOL_PREP(_mp_cb, obj->callbacks, Evas_Callbacks);
}
- EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 2048, );
+ EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 128, );
fn = EVAS_MEMPOOL_ALLOC(_mp_fn, Evas_Func_Node);
if (!fn) return;
EVAS_MEMPOOL_PREP(_mp_fn, fn, Evas_Func_Node);
if (!e->callbacks)
{
- EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 512, );
+ EVAS_MEMPOOL_INIT(_mp_cb, "evas_callbacks", Evas_Callbacks, 64, );
e->callbacks = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Callbacks);
if (!e->callbacks) return;
EVAS_MEMPOOL_PREP(_mp_cb, e->callbacks, Evas_Callbacks);
}
- EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 2048, );
+ EVAS_MEMPOOL_INIT(_mp_fn, "evas_func_node", Evas_Func_Node, 128, );
fn = EVAS_MEMPOOL_ALLOC(_mp_fn, Evas_Func_Node);
if (!fn) return;
EVAS_MEMPOOL_PREP(_mp_fn, fn, Evas_Func_Node);
}
obj->cur.clipper = clip;
clip->clip.clipees = eina_list_append(clip->clip.clipees, obj);
- if (clip->clip.clipees) clip->cur.have_clipees = 1;
+ if (clip->clip.clipees)
+ {
+ clip->cur.have_clipees = 1;
+ if (clip->changed)
+ evas_object_update_bounding_box(clip);
+ }
/* If it's NOT a rectangle set the mask bits too */
/* FIXME: Optmz ths chck */
int inside;
if (!list) return in;
- for (obj = _EINA_INLIST_CONTAINER(obj, list);
- obj;
+ for (obj = _EINA_INLIST_CONTAINER(obj, list);
+ obj;
obj = _EINA_INLIST_CONTAINER(obj, EINA_INLIST_GET(obj)->prev))
{
if (obj == stop)
}
else
{
- in = _evas_event_object_list_in_get
- (e, in, evas_object_smart_members_get_direct(obj),
- stop, x, y, &norep);
+ if (!obj->child_has_map)
+ evas_object_smart_bouding_box_update(obj);
+ if (obj->child_has_map ||
+ (obj->cur.bounding_box.x <= x &&
+ obj->cur.bounding_box.x + obj->cur.bounding_box.w >= x &&
+ obj->cur.bounding_box.y <= y &&
+ obj->cur.bounding_box.y + obj->cur.bounding_box.h >= y) ||
+ (obj->cur.geometry.x <= x &&
+ obj->cur.geometry.y + obj->cur.geometry.w >= x &&
+ obj->cur.geometry.y <= y &&
+ obj->cur.geometry.y + obj->cur.geometry.h >= y))
+ in = _evas_event_object_list_in_get
+ (e, in, evas_object_smart_members_get_direct(obj),
+ stop, x, y, &norep);
}
if (norep)
{
{
inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
- if ((obj->cur.usemap) && (obj->cur.map) &&
- (obj->cur.map->count == 4))
+ if (inside)
{
- if ((inside) &&
- (!evas_map_coords_get(obj->cur.map, x, y,
- &(obj->cur.map->mx),
- &(obj->cur.map->my), 0)))
+ if ((obj->cur.usemap) && (obj->cur.map) &&
+ (obj->cur.map->count == 4))
{
- inside = 0;
+ if (!evas_map_coords_get(obj->cur.map, x, y,
+ &(obj->cur.map->mx),
+ &(obj->cur.map->my), 0))
+ {
+ inside = 0;
+ }
}
}
-
if (inside && ((!obj->precise_is_inside) ||
(evas_object_is_inside(obj, x, y))))
{
int x, int y, int *no_rep)
{
if (!list) return NULL;
- return _evas_event_object_list_raw_in_get(e, in, list->last, stop,
- x, y, no_rep);
+ return _evas_event_object_list_raw_in_get(e, in, list->last, stop, x, y,
+ no_rep);
}
Eina_List *
if ((!e->layers) || (e->events_frozen > 0)) return NULL;
EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
{
- int norep = 0;
+ int no_rep = 0;
in = _evas_event_object_list_in_get(e, in,
EINA_INLIST_GET(lay->objects),
- stop, x, y, &norep);
- if (norep) return in;
+ stop, x, y, &no_rep);
+ if (no_rep) return in;
}
return in;
}
EAPI void
evas_event_refeed_event(Evas *e, void *event_copy, Evas_Callback_Type event_type)
{
+ if (!event_copy) return;
+
switch (event_type)
{
case EVAS_CALLBACK_MOUSE_IN:
#include "evas_common.h"
#include "evas_private.h"
#include "evas_cs.h"
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
#ifdef LKDEBUG
EAPI Eina_Bool lockdebug = EINA_FALSE;
#ifdef EVAS_CSERVE
if (getenv("EVAS_CSERVE")) evas_cserve_init();
#endif
+#ifdef EVAS_CSERVE2
+ if (getenv("EVAS_CSERVE2")) evas_cserve2_init();
+#endif
#ifdef BUILD_ASYNC_PRELOAD
_evas_preload_thread_init();
#endif
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_init();
-#endif
return _evas_init_count;
EAPI int
evas_shutdown(void)
{
+ if (_evas_init_count <= 0)
+ {
+ EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
+ return 0;
+ }
if (--_evas_init_count != 0)
return _evas_init_count;
-#ifdef EVAS_FRAME_QUEUING
- if (evas_common_frameq_enabled())
- {
- evas_common_frameq_finish();
- evas_common_frameq_destroy();
- }
-#endif
#ifdef BUILD_ASYNC_EVENTS
_evas_preload_thread_shutdown();
#endif
return;
MAGIC_CHECK_END();
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush();
-#endif
-
- if (e->walking_list == 0) evas_render_idle_flush(e);
-
if (e->walking_list > 0) return;
+ evas_render_idle_flush(e);
- if (e->callbacks)
- {
- if (e->callbacks->deletions_waiting) return;
-
- e->callbacks->deletions_waiting = 0;
- evas_event_callback_list_post_free(&e->callbacks->callbacks);
- if (!e->callbacks->callbacks)
- {
- free(e->callbacks);
- e->callbacks = NULL;
- }
-
- _evas_post_event_callback_free(e);
- }
+ _evas_post_event_callback_free(e);
del = 1;
e->walking_list++;
if (w < 1) w = 1;
if (h < 1) h = 1;
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush();
-#endif
-
e->output.w = w;
e->output.h = h;
e->output.changed = 1;
if (m->surface)
obj->layer->evas->engine.func->image_map_surface_free
(obj->layer->evas->engine.data.output, m->surface);
+ if (obj->spans)
+ {
+ // FIXME: destroy engine side spans
+ free(obj->spans);
+ obj->spans = NULL;
+ }
}
m->magic = 0;
free(m);
return evas_map_coords_get(m, x, y, NULL, NULL, 0);
}
+static Eina_Bool
+_evas_object_map_parent_check(Evas_Object *parent)
+{
+ const Eina_Inlist *list;
+ const Evas_Object *o;
+
+ if (!parent) return EINA_FALSE;
+
+ list = evas_object_smart_members_get_direct(parent->smart.parent);
+ EINA_INLIST_FOREACH(list, o)
+ if (o->cur.usemap) break ;
+ if (o) return EINA_FALSE; /* Still some child have a map enable */
+ parent->child_has_map = EINA_FALSE;
+ _evas_object_map_parent_check(parent->smart.parent);
+ return EINA_TRUE;
+}
+
EAPI void
evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled)
{
+ Evas_Object *parents;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
evas_object_change(obj);
if (!obj->changed_pchange) obj->changed_pchange = pchange;
obj->changed_map = EINA_TRUE;
+
+ if (enabled)
+ {
+ for (parents = obj->smart.parent; parents; parents = parents->smart.parent)
+ parents->child_has_map = EINA_TRUE;
+ }
+ else
+ {
+ if (_evas_object_map_parent_check(obj->smart.parent))
+ evas_object_update_bounding_box(obj);
+ }
}
EAPI Eina_Bool
return obj->cur.usemap;
}
-
-EAPI void
-evas_object_map_source_set(Evas_Object *obj, Evas_Object *src)
-{
- MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
- return;
- MAGIC_CHECK_END();
- (void)src; /* method still needs to be implemented. */
-}
-
-EAPI Evas_Object *
-evas_object_map_source_get(const Evas_Object *obj)
-{
- MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
- return NULL;
- MAGIC_CHECK_END();
- return NULL;
-}
-
EAPI void
evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
{
// We do have the same exact count of point in this map, so just copy it
if ((obj->cur.map) && (obj->cur.map->count == map->count))
- {
- Evas_Map *omap = obj->cur.map;
- obj->cur.map = _evas_map_new(map->count);
- memcpy(obj->cur.map, omap, sizeof(Evas_Map) + (map->count * sizeof(Evas_Map_Point)));
- _evas_map_copy(obj->cur.map, map);
- free(omap);
- }
+ _evas_map_copy(obj->cur.map, map);
else
{
if (obj->cur.map) evas_map_free(obj->cur.map);
if (count > 0) return EINA_TRUE;
return EINA_FALSE;
}
+
+void
+evas_object_map_update(Evas_Object *obj,
+ int x, int y,
+ int imagew, int imageh,
+ int uvw, int uvh)
+{
+ const Evas_Map_Point *p, *p_end;
+ RGBA_Map_Point *pts, *pt;
+
+ if (obj->spans)
+ {
+ if (obj->spans->x != x || obj->spans->y != y ||
+ obj->spans->image.w != imagew || obj->spans->image.h != imageh ||
+ obj->spans->uv.w != uvw || obj->spans->uv.h != uvh)
+ obj->changed_map = EINA_TRUE;
+ }
+
+ if (!obj->changed_map) return ;
+
+ if (obj->cur.map && obj->spans && obj->cur.map->count != obj->spans->count)
+ {
+ if (obj->spans)
+ {
+ // Destroy engine side spans
+ free(obj->spans);
+ }
+ obj->spans = NULL;
+ }
+
+ if (!((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap)))
+ return ;
+
+ if (!obj->spans)
+ obj->spans = calloc(1, sizeof (RGBA_Map) +
+ sizeof (RGBA_Map_Point) * (obj->cur.map->count - 1));
+
+ if (!obj->spans) return ;
+
+ obj->spans->count = obj->cur.map->count;
+ obj->spans->x = x;
+ obj->spans->y = y;
+ obj->spans->uv.w = uvw;
+ obj->spans->uv.h = uvh;
+ obj->spans->image.w = imagew;
+ obj->spans->image.h = imageh;
+
+ pts = obj->spans->pts;
+
+ p = obj->cur.map->points;
+ p_end = p + obj->cur.map->count;
+ pt = pts;
+
+ pts[0].px = obj->cur.map->persp.px << FP;
+ pts[0].py = obj->cur.map->persp.py << FP;
+ pts[0].foc = obj->cur.map->persp.foc << FP;
+ pts[0].z0 = obj->cur.map->persp.z0 << FP;
+ // draw geom +x +y
+ for (; p < p_end; p++, pt++)
+ {
+ pt->x = (lround(p->x) + x) * FP1;
+ pt->y = (lround(p->y) + y) * FP1;
+ pt->z = (lround(p->z) ) * FP1;
+ pt->fx = p->px;
+ pt->fy = p->py;
+ pt->fz = p->z;
+ pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
+ pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
+ if (pt->u < 0) pt->u = 0;
+ else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
+ if (pt->v < 0) pt->v = 0;
+ else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
+ pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
+ }
+ if (obj->cur.map->count & 0x1)
+ {
+ pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
+ }
+
+ // Request engine to update it's point
+}
#define SIG_CHILD_ADDED "child,added"
#define SIG_CHILD_REMOVED "child,removed"
-static const Evas_Smart_Cb_Description _signals[] =
+static const Evas_Smart_Cb_Description _signals[] =
{
{SIG_CHILD_ADDED, ""},
{SIG_CHILD_REMOVED, ""},
static void _sizing_eval(Evas_Object *obj);
-#define EVAS_OBJECT_BOX_DATA_GET(o, ptr) \
- Evas_Object_Box_Data *ptr = evas_object_smart_data_get(o)
-
-#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, ptr) \
- EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
- if (!ptr) \
- { \
- CRIT("no widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- fflush(stderr); \
- abort(); \
- return; \
-}
-
-#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
- EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
- if (!ptr) \
- { \
- CRIT("no widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- fflush(stderr); \
- abort(); \
- return val; \
- }
+#define EVAS_OBJECT_BOX_DATA_GET(o, ptr) \
+ Evas_Object_Box_Data *ptr = evas_object_smart_data_get(o)
+
+#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, ptr) \
+ EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
+if (!ptr) \
+{ \
+ CRIT("no widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ fflush(stderr); \
+ return; \
+}
+
+#define EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+ EVAS_OBJECT_BOX_DATA_GET(o, ptr); \
+if (!ptr) \
+{ \
+ CRIT("no widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ fflush(stderr); \
+ return val; \
+}
EVAS_SMART_SUBCLASS_NEW(_evas_object_box_type, _evas_object_box,
- Evas_Object_Box_Api, Evas_Smart_Class,
- evas_object_smart_clipped_class_get, NULL)
+ Evas_Object_Box_Api, Evas_Smart_Class,
+ evas_object_smart_clipped_class_get, NULL)
static Eina_Bool
_evas_object_box_iterator_next(Evas_Object_Box_Iterator *it, void **data)
if ((!api) || (!api->remove))
{
- ERR("no api->remove");
- return;
+ ERR("no api->remove");
+ return;
}
if (!api->remove(box, priv, o))
api = priv->api;
if ((!api) || (!api->option_new))
{
- ERR("no api->option_new");
- return NULL;
+ ERR("no api->option_new");
+ return NULL;
}
opt = api->option_new(o, priv, child);
if (!opt)
{
- ERR("option_new failed");
- return NULL;
+ ERR("option_new failed");
+ return NULL;
}
return opt;
EINA_LIST_FOREACH(priv->children, l, opt)
{
if (opt->obj == reference)
- {
- Evas_Object_Box_Option *new_opt;
+ {
+ Evas_Object_Box_Option *new_opt;
- new_opt = _evas_object_box_option_new(o, priv, child);
- if (!new_opt)
- return NULL;
+ new_opt = _evas_object_box_option_new(o, priv, child);
+ if (!new_opt)
+ return NULL;
- priv->children = eina_list_prepend_relative
- (priv->children, new_opt, opt);
+ priv->children = eina_list_prepend_relative
+ (priv->children, new_opt, opt);
priv->children_changed = EINA_TRUE;
evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
- return new_opt;
- }
+ return new_opt;
+ }
}
return NULL;
EINA_LIST_FOREACH(priv->children, l, opt)
{
- if (opt->obj == reference)
- {
- Evas_Object_Box_Option *new_opt;
+ if (opt->obj == reference)
+ {
+ Evas_Object_Box_Option *new_opt;
- new_opt = _evas_object_box_option_new(o, priv, child);
- if (!new_opt)
- return NULL;
+ new_opt = _evas_object_box_option_new(o, priv, child);
+ if (!new_opt)
+ return NULL;
- priv->children = eina_list_append_relative
- (priv->children, new_opt, opt);
+ priv->children = eina_list_append_relative
+ (priv->children, new_opt, opt);
priv->children_changed = EINA_TRUE;
evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
- return new_opt;
- }
+ return new_opt;
+ }
}
return NULL;
new_opt = _evas_object_box_option_new(o, priv, child);
if (!new_opt)
- return NULL;
+ return NULL;
priv->children = eina_list_prepend(priv->children, new_opt);
priv->children_changed = EINA_TRUE;
for (l = priv->children, i = 0; l; l = l->next, i++)
{
- Evas_Object_Box_Option *opt = l->data;
+ Evas_Object_Box_Option *opt = l->data;
if (i == pos)
- {
- Evas_Object_Box_Option *new_opt;
+ {
+ Evas_Object_Box_Option *new_opt;
- new_opt = _evas_object_box_option_new(o, priv, child);
- if (!new_opt)
- return NULL;
+ new_opt = _evas_object_box_option_new(o, priv, child);
+ if (!new_opt)
+ return NULL;
- priv->children = eina_list_prepend_relative
- (priv->children, new_opt, opt);
+ priv->children = eina_list_prepend_relative
+ (priv->children, new_opt, opt);
priv->children_changed = EINA_TRUE;
evas_object_smart_callback_call(o, SIG_CHILD_ADDED, new_opt);
- return new_opt;
- }
+ return new_opt;
+ }
}
return NULL;
if ((!api) || (!api->option_free))
{
- ERR("api->option_free not set (may cause memory leaks, segfaults)");
- return NULL;
+ ERR("api->option_free not set (may cause memory leaks, segfaults)");
+ return NULL;
}
EINA_LIST_FOREACH(priv->children, l, opt)
Evas_Object *obj = opt->obj;
if (obj == child)
- {
- priv->children = eina_list_remove(priv->children, opt);
- api->option_free(o, priv, opt);
+ {
+ priv->children = eina_list_remove(priv->children, opt);
+ api->option_free(o, priv, opt);
priv->children_changed = EINA_TRUE;
evas_object_smart_callback_call(o, SIG_CHILD_REMOVED, obj);
- return obj;
- }
+ return obj;
+ }
}
return NULL;
if ((!api) || (!api->option_free))
{
- WRN("api->option_free not set (may cause memory leaks, segfaults)");
+ WRN("api->option_free not set (may cause memory leaks, segfaults)");
return NULL;
}
node = eina_list_nth_list(priv->children, pos);
if (!node)
{
- ERR("No item to be removed at position %d", pos);
- return NULL;
+ ERR("No item to be removed at position %d", pos);
+ return NULL;
}
opt = node->data;
const Evas_Smart *smart;
const Evas_Smart_Class *sc;
- priv = (Evas_Object_Box_Data *)calloc(1, sizeof(*priv));
- if (!priv)
- {
- ERR("Could not allocate object private data.");
- return;
- }
+ priv = (Evas_Object_Box_Data *)calloc(1, sizeof(*priv));
+ if (!priv)
+ {
+ ERR("Could not allocate object private data.");
+ return;
+ }
smart = evas_object_smart_smart_get(o);
sc = evas_smart_class_get(smart);
priv->api = (const Evas_Object_Box_Api *)sc;
- evas_object_smart_data_set(o, priv);
+ evas_object_smart_data_set(o, priv);
}
_evas_object_box_parent_sc->add(o);
api = priv->api;
if ((!api) || (!api->option_free))
{
- WRN("api->option_free not set (may cause memory leaks, segfaults)");
+ WRN("api->option_free not set (may cause memory leaks, segfaults)");
return;
}
l = priv->children;
while (l)
{
- Evas_Object_Box_Option *opt = l->data;
+ Evas_Object_Box_Option *opt = l->data;
- _evas_object_box_child_callbacks_unregister(opt->obj);
- api->option_free(o, priv, opt);
- l = eina_list_remove_list(l, l);
+ _evas_object_box_child_callbacks_unregister(opt->obj);
+ api->option_free(o, priv, opt);
+ l = eina_list_remove_list(l, l);
}
if (priv->layout.data && priv->layout.free_data)
EAPI const Evas_Object_Box_Api *
evas_object_box_smart_class_get(void)
{
- static Evas_Object_Box_Api _sc =
+ static Evas_Object_Box_Api _sc =
EVAS_OBJECT_BOX_API_INIT_NAME_VERSION(_evas_object_box_type);
static const Evas_Object_Box_Api *class = NULL;
{
EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
- if ((priv->layout.cb == cb) && (priv->layout.data == data) &&
+ if ((priv->layout.cb == cb) && (priv->layout.data == data) &&
(priv->layout.free_data == free_data))
return;
{
if (dim > cell_sz)
{
- if ((min_d != 0) && (cell_sz < min_d))
- *new_dim = min_d;
- else
- *new_dim = cell_sz;
+ if ((min_d != 0) && (cell_sz < min_d))
+ *new_dim = min_d;
+ else
+ *new_dim = cell_sz;
}
else
{
- if ((max_d != -1) && (cell_sz > max_d))
- *new_dim = max_d;
- else
- *new_dim = cell_sz;
+ if ((max_d != -1) && (cell_sz > max_d))
+ *new_dim = max_d;
+ else
+ *new_dim = cell_sz;
}
}
{
if (align >= 0.0)
{
- *new_dim = dim;
- *offset = (space_sz - (dim + pad_before + pad_after)) * align
- + pad_before;
+ *new_dim = dim;
+ *offset = (space_sz - (dim + pad_before + pad_after)) * align
+ + pad_before;
}
else
{
- if ((max_dim != -1) && (space_sz > max_dim))
- {
- *new_dim = max_dim;
- *offset = (space_sz - (max_dim + pad_before + pad_after)) * 0.5
- + pad_before;
- }
- else
- {
- *new_dim = space_sz;
- *offset = 0;
- }
+ if ((max_dim != -1) && (space_sz > max_dim))
+ {
+ *new_dim = max_dim;
+ *offset = (space_sz - (max_dim + pad_before + pad_after)) * 0.5
+ + pad_before;
+ }
+ else
+ {
+ *new_dim = space_sz;
+ *offset = 0;
+ }
}
}
{
if (align >= 0.0)
{
- *new_dim = dim;
- *offset =
- (cell_sz - (dim + pad_before + pad_after)) * align + pad_before;
+ *new_dim = dim;
+ *offset =
+ (cell_sz - (dim + pad_before + pad_after)) * align + pad_before;
}
else
{
*offset = pad_before;
_layout_dimension_change_min_max_cell_bound
- (dim, new_dim, min_dim, max_dim, cell_sz - pad_before - pad_after);
+ (dim, new_dim, min_dim, max_dim, cell_sz - pad_before - pad_after);
}
}
evas_object_geometry_get(o, NULL, NULL, NULL, &h);
if (remaining <= 0)
- {
- int min_w;
-
- evas_object_size_hint_min_get(o, &min_w, NULL);
- evas_object_resize(o, min_w, h);
- }
- else
- {
- double normal_weight, weight_x;
- int target_size;
- int max_w;
-
- evas_object_size_hint_weight_get(o, &weight_x, NULL);
- normal_weight = weight_x / weight_total;
- target_size = (int)((double)remaining * normal_weight);
-
- evas_object_size_hint_max_get(o, &max_w, NULL);
- if ((max_w != -1) && (target_size > max_w))
- {
- evas_object_resize(o, max_w, h);
- rem_diff += max_w;
- objects[i] = objects[n_objects - 1];
- weight_total -= weight_x;
- n_objects--;
- return _evas_object_box_layout_horizontal_weight_apply
- (priv, objects, n_objects, remaining - rem_diff,
- weight_total);
- }
- else
- {
- evas_object_resize(o, target_size, h);
- rem_diff += target_size;
- }
- }
+ {
+ int min_w;
+
+ evas_object_size_hint_min_get(o, &min_w, NULL);
+ evas_object_resize(o, min_w, h);
+ }
+ else
+ {
+ double normal_weight, weight_x;
+ int target_size;
+ int max_w;
+
+ evas_object_size_hint_weight_get(o, &weight_x, NULL);
+ normal_weight = weight_x / weight_total;
+ target_size = (int)((double)remaining * normal_weight);
+
+ evas_object_size_hint_max_get(o, &max_w, NULL);
+ if ((max_w != -1) && (target_size > max_w))
+ {
+ evas_object_resize(o, max_w, h);
+ rem_diff += max_w;
+ objects[i] = objects[n_objects - 1];
+ weight_total -= weight_x;
+ n_objects--;
+ return _evas_object_box_layout_horizontal_weight_apply
+ (priv, objects, n_objects, remaining - rem_diff,
+ weight_total);
+ }
+ else
+ {
+ evas_object_resize(o, target_size, h);
+ rem_diff += target_size;
+ }
+ }
}
return remaining - rem_diff;
int padding_l, padding_r;
double weight_x;
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_size_hint_weight_get(opt->obj, &weight_x, NULL);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, NULL, NULL);
+ (opt->obj, &padding_l, &padding_r, NULL, NULL);
req_w += padding_l + padding_r;
if (!weight_x)
- {
- int child_w;
-
- evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, NULL);
- req_w += child_w;
- }
- else
- {
- objects[weight_use] = opt;
- weight_use++;
- weight_total += weight_x;
- }
+ {
+ int child_w;
+
+ evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, NULL);
+ req_w += child_w;
+ }
+ else
+ {
+ objects[weight_use] = opt;
+ weight_use++;
+ weight_total += weight_x;
+ }
}
remaining = w - req_w;
evas_object_size_hint_align_get(opt->obj, NULL, &align_y);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, NULL, &max_h);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
if (new_h > top_h) top_h = new_h;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
+ (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
- if (new_h != child_h)
- evas_object_resize(opt->obj, child_w, new_h);
+ if (new_h != child_h)
+ evas_object_resize(opt->obj, child_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
x += child_w + padding_l + padding_r + global_pad;
sub_pixel += pad_inc;
if (sub_pixel >= 1 << 16)
- {
- x++;
- sub_pixel -= 1 << 16;
- }
+ {
+ x++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, req_w, top_h);
evas_object_geometry_get(o, NULL, NULL, &w, NULL);
if (remaining <= 0)
- {
- int min_h;
-
- evas_object_size_hint_min_get(o, NULL, &min_h);
- evas_object_resize(o, w, min_h);
- }
- else
- {
- double normal_weight, weight_y;
- int target_size;
- int max_h;
-
- evas_object_size_hint_weight_get(o, NULL, &weight_y);
- normal_weight = weight_y / weight_total;
- target_size = (int)((double)remaining * normal_weight);
-
- evas_object_size_hint_max_get(o, NULL, &max_h);
- if ((max_h != -1) && (target_size > max_h))
- {
- evas_object_resize(o, w, max_h);
- rem_diff += max_h;
- objects[i] = objects[n_objects - 1];
- weight_total -= weight_y;
- n_objects--;
- return _evas_object_box_layout_vertical_weight_apply
- (priv, objects, n_objects, remaining - rem_diff,
- weight_total);
- }
- else
- {
- evas_object_resize(o, w, target_size);
- rem_diff += target_size;
- }
- }
+ {
+ int min_h;
+
+ evas_object_size_hint_min_get(o, NULL, &min_h);
+ evas_object_resize(o, w, min_h);
+ }
+ else
+ {
+ double normal_weight, weight_y;
+ int target_size;
+ int max_h;
+
+ evas_object_size_hint_weight_get(o, NULL, &weight_y);
+ normal_weight = weight_y / weight_total;
+ target_size = (int)((double)remaining * normal_weight);
+
+ evas_object_size_hint_max_get(o, NULL, &max_h);
+ if ((max_h != -1) && (target_size > max_h))
+ {
+ evas_object_resize(o, w, max_h);
+ rem_diff += max_h;
+ objects[i] = objects[n_objects - 1];
+ weight_total -= weight_y;
+ n_objects--;
+ return _evas_object_box_layout_vertical_weight_apply
+ (priv, objects, n_objects, remaining - rem_diff,
+ weight_total);
+ }
+ else
+ {
+ evas_object_resize(o, w, target_size);
+ rem_diff += target_size;
+ }
+ }
}
return remaining - rem_diff;
int padding_t, padding_b;
double weight_y;
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_size_hint_weight_get(opt->obj, NULL, &weight_y);
evas_object_size_hint_padding_get
- (opt->obj, NULL, NULL, &padding_t, &padding_b);
+ (opt->obj, NULL, NULL, &padding_t, &padding_b);
req_h += padding_t + padding_b;
if (!weight_y)
- {
- int child_h;
-
- evas_object_geometry_get(opt->obj, NULL, NULL, NULL, &child_h);
- req_h += child_h;
- }
- else
- {
- objects[weight_use] = opt;
- weight_use++;
- weight_total += weight_y;
- }
+ {
+ int child_h;
+
+ evas_object_geometry_get(opt->obj, NULL, NULL, NULL, &child_h);
+ req_h += child_h;
+ }
+ else
+ {
+ objects[weight_use] = opt;
+ weight_use++;
+ weight_total += weight_y;
+ }
}
remaining = h - req_h;
y += remaining / 2;
else
{ /* justified */
- _fixed_point_divide_and_decompose_integer
- (remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->pad.v;
+ _fixed_point_divide_and_decompose_integer
+ (remaining, n_children - 1, &global_pad, &pad_inc);
+ global_pad += priv->pad.v;
}
EINA_LIST_FOREACH(priv->children, l, opt)
evas_object_size_hint_align_get(opt->obj, &align_x, NULL);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, &max_w, NULL);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
new_w = child_w;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
+ (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
if (new_w > top_w) top_w = new_w;
- if (new_w != child_w)
- evas_object_resize(opt->obj, new_w, child_h);
+ if (new_w != child_w)
+ evas_object_resize(opt->obj, new_w, child_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
y += child_h + padding_t + padding_b + global_pad;
sub_pixel += pad_inc;
if (sub_pixel >= 1 << 16)
- {
- y++;
- sub_pixel -= 1 << 16;
- }
+ {
+ y++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, top_w, req_h);
evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
evas_object_size_hint_min_get(opt->obj, &min_w, NULL);
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
new_w = child_w;
new_h = child_h;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
+ (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
- padding_l, padding_r);
+ (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
+ padding_l, padding_r);
- if ((new_w != child_w) || (new_h != child_h))
- evas_object_resize(opt->obj, new_w, new_h);
+ if ((new_w != child_w) || (new_h != child_h))
+ evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
x += cell_sz + priv->pad.h;
sub_pixel += inc;
if (sub_pixel >= 1 << 16)
- {
- x++;
- sub_pixel -= 1 << 16;
- }
+ {
+ x++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, w, h);
evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
evas_object_size_hint_min_get(opt->obj, NULL, &min_h);
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
new_w = child_w;
new_h = child_h;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
+ (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
- padding_t, padding_b);
+ (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
+ padding_t, padding_b);
- if ((new_w != child_w) || (new_h != child_h))
- evas_object_resize(opt->obj, new_w, new_h);
+ if ((new_w != child_w) || (new_h != child_h))
+ evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
y += cell_sz + priv->pad.v;
sub_pixel += inc;
if (sub_pixel >= 1 << 16)
- {
- y++;
- sub_pixel -= 1 << 16;
- }
+ {
+ y++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, w, h);
{
int child_w, padding_l, padding_r;
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, NULL, NULL);
+ (opt->obj, &padding_l, &padding_r, NULL, NULL);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, NULL);
if (child_w + padding_l + padding_r > cell_sz)
- cell_sz = child_w + padding_l + padding_r;
+ cell_sz = child_w + padding_l + padding_r;
}
global_pad = priv->pad.h;
else
{ /* justified */
_fixed_point_divide_and_decompose_integer
- (remaining, n_children - 1, &global_pad, &pad_inc);
+ (remaining, n_children - 1, &global_pad, &pad_inc);
global_pad += priv->pad.h;
}
evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
evas_object_size_hint_min_get(opt->obj, &min_w, NULL);
if (new_h > top_h) top_h = new_h;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
+ (child_h, &new_h, h, max_h, &off_y, align_y, padding_t, padding_b);
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
- padding_l, padding_r);
+ (child_w, &new_w, min_w, max_w, cell_sz, &off_x, align_x,
+ padding_l, padding_r);
- if ((new_w != child_w) || (new_h != child_h))
- evas_object_resize(opt->obj, new_w, new_h);
+ if ((new_w != child_w) || (new_h != child_h))
+ evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
x += cell_sz + global_pad;
sub_pixel += pad_inc;
if (sub_pixel >= 1 << 16)
- {
- x++;
- sub_pixel -= 1 << 16;
- }
+ {
+ x++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, x, top_h);
{
int child_h, padding_t, padding_b;
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_size_hint_padding_get
- (opt->obj, NULL, NULL, &padding_t, &padding_b);
+ (opt->obj, NULL, NULL, &padding_t, &padding_b);
evas_object_geometry_get(opt->obj, NULL, NULL, NULL, &child_h);
if (child_h + padding_t + padding_b > cell_sz)
- cell_sz = child_h + padding_t + padding_b;
+ cell_sz = child_h + padding_t + padding_b;
}
global_pad = priv->pad.v;
y += remaining / 2;
else
{ /* justified */
- _fixed_point_divide_and_decompose_integer
- (remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->pad.v;
+ _fixed_point_divide_and_decompose_integer
+ (remaining, n_children - 1, &global_pad, &pad_inc);
+ global_pad += priv->pad.v;
}
EINA_LIST_FOREACH(priv->children, l, opt)
evas_object_size_hint_align_get(opt->obj, &align_x, &align_y);
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
evas_object_size_hint_max_get(opt->obj, &max_w, &max_h);
evas_object_size_hint_min_get(opt->obj, NULL, &min_h);
if (new_w > top_w) top_w = new_w;
_layout_set_offset_and_expand_dimension_space_max_bounded
- (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
+ (child_w, &new_w, w, max_w, &off_x, align_x, padding_l, padding_r);
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
- padding_t, padding_b);
+ (child_h, &new_h, min_h, max_h, cell_sz, &off_y, align_y,
+ padding_t, padding_b);
- if ((new_w != child_w) || (new_h != child_h))
- evas_object_resize(opt->obj, new_w, new_h);
+ if ((new_w != child_w) || (new_h != child_h))
+ evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
y += cell_sz + global_pad;
sub_pixel += pad_inc;
if (sub_pixel >= 1 << 16)
- {
- y++;
- sub_pixel -= 1 << 16;
- }
+ {
+ y++;
+ sub_pixel -= 1 << 16;
+ }
}
evas_object_size_hint_min_set(o, top_w, y);
int child_w, child_h, off_x = 0;
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
- _sizing_eval(opt->obj);
- evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
+ _sizing_eval(opt->obj);
+ evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
child_w += padding_l + padding_r + priv->pad.h;
child_h += padding_t + padding_b;
remain_w -= child_w;
if (remain_w + priv->pad.h >= 0)
- { /* continue "line" */
- if (child_h > max_h)
- max_h = child_h;
-
- off_x += child_w;
- row_width[n_rows] += child_w;
- }
- else
- { /* break line */
- if (i == start_i)
- { /* obj goes to actual line */
- max_h = child_h;
- row_width[n_rows] = child_w;
- }
- else
- { /* obj goes to next line */
- row_max_h[n_rows] = max_h;
- row_break[n_rows] = i - 1;
- n_rows++;
-
- off_x = child_w;
- off_y += max_h;
- max_h = child_h;
-
- row_width[n_rows] = child_w;
- start_i = i;
-
- remain_w = box_w - off_x;
- }
- }
+ { /* continue "line" */
+ if (child_h > max_h)
+ max_h = child_h;
+
+ off_x += child_w;
+ row_width[n_rows] += child_w;
+ }
+ else
+ { /* break line */
+ if (i == start_i)
+ { /* obj goes to actual line */
+ max_h = child_h;
+ row_width[n_rows] = child_w;
+ }
+ else
+ { /* obj goes to next line */
+ row_max_h[n_rows] = max_h;
+ row_break[n_rows] = i - 1;
+ n_rows++;
+
+ off_x = child_w;
+ off_y += max_h;
+ max_h = child_h;
+
+ row_width[n_rows] = child_w;
+ start_i = i;
+
+ remain_w = box_w - off_x;
+ }
+ }
}
row_break[n_rows] = i - 1;
if (remain_y > 0)
{
- if (priv->align.v >= 0.0)
- inc_y = priv->align.v * remain_y;
- else if (row_count == 0)
- y += remain_y / 2;
- else /* y-justified */
- inc_y = remain_y / row_count;
+ if (priv->align.v >= 0.0)
+ inc_y = priv->align.v * remain_y;
+ else if (row_count == 0)
+ y += remain_y / 2;
+ else /* y-justified */
+ inc_y = remain_y / row_count;
}
inc_y += priv->pad.v;
remain_x = (w - row_width[r]);
if (priv->align.h < 0.0)
- {
- if (row_size == 0)
- x += remain_x / 2;
- else
- _fixed_point_divide_and_decompose_integer
- (remain_x, row_size, &row_justify, &just_inc);
- }
+ {
+ if (row_size == 0)
+ x += remain_x / 2;
+ else
+ _fixed_point_divide_and_decompose_integer
+ (remain_x, row_size, &row_justify, &just_inc);
+ }
row_justify += priv->pad.h;
for (; i <= row_break[r]; i++, l = l->next)
- {
- Evas_Object_Box_Option *opt = l->data;
- int off_x, off_y, y_remain;
- int padding_l, padding_r;
- int child_w, child_h;
- double align_y;
+ {
+ Evas_Object_Box_Option *opt = l->data;
+ int off_x, off_y, y_remain;
+ int padding_l, padding_r;
+ int child_w, child_h;
+ double align_y;
- evas_object_size_hint_align_get(opt->obj, NULL, &align_y);
- evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, NULL, NULL);
+ evas_object_size_hint_align_get(opt->obj, NULL, &align_y);
+ evas_object_size_hint_padding_get
+ (opt->obj, &padding_l, &padding_r, NULL, NULL);
- evas_object_geometry_get
- (opt->obj, NULL, NULL, &child_w, &child_h);
+ evas_object_geometry_get
+ (opt->obj, NULL, NULL, &child_w, &child_h);
- y_remain = row_max_h[r] - child_h;
+ y_remain = row_max_h[r] - child_h;
- off_x = padding_l;
- if (priv->align.h >= 0.0)
- off_x += remain_x * priv->align.h;
- off_y = y_remain * align_y;
+ off_x = padding_l;
+ if (priv->align.h >= 0.0)
+ off_x += remain_x * priv->align.h;
+ off_y = y_remain * align_y;
- evas_object_move(opt->obj, x + off_x, y + off_y);
+ evas_object_move(opt->obj, x + off_x, y + off_y);
- x += child_w + padding_l + padding_r + row_justify;
+ x += child_w + padding_l + padding_r + row_justify;
- sub_pixel += just_inc;
- if (sub_pixel >= 1 << 16)
- {
- x++;
- sub_pixel -= 1 << 16;
- }
- }
+ sub_pixel += just_inc;
+ if (sub_pixel >= 1 << 16)
+ {
+ x++;
+ sub_pixel -= 1 << 16;
+ }
+ }
evas_object_geometry_get(o, &x, NULL, NULL, NULL);
if (min_w < row_width[r])
int child_w, child_h, off_y = 0;
evas_object_size_hint_padding_get
- (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
+ (opt->obj, &padding_l, &padding_r, &padding_t, &padding_b);
- _sizing_eval(opt->obj);
+ _sizing_eval(opt->obj);
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
child_w += padding_l + padding_r;
remain_h -= child_h;
if (remain_h + priv->pad.v >= 0)
- { /* continue "col" */
- if (child_w > max_w)
- max_w = child_w;
-
- off_y += child_h;
- col_height[n_cols] += child_h;
- }
- else
- {
- /* break col */
- if (i == start_i)
- { /* obj goes to actual col */
- max_w = child_w;
- col_height[n_cols] = child_h;
- }
- else
- { /* obj goes to next col */
- col_max_w[n_cols] = max_w;
- col_break[n_cols] = i - 1;
- n_cols++;
-
- off_x += max_w;
- off_y = child_h;
- max_w = child_w;
-
- col_height[n_cols] = child_h;
- start_i = i;
-
- remain_h = box_h - off_y;
- }
- }
+ { /* continue "col" */
+ if (child_w > max_w)
+ max_w = child_w;
+
+ off_y += child_h;
+ col_height[n_cols] += child_h;
+ }
+ else
+ {
+ /* break col */
+ if (i == start_i)
+ { /* obj goes to actual col */
+ max_w = child_w;
+ col_height[n_cols] = child_h;
+ }
+ else
+ { /* obj goes to next col */
+ col_max_w[n_cols] = max_w;
+ col_break[n_cols] = i - 1;
+ n_cols++;
+
+ off_x += max_w;
+ off_y = child_h;
+ max_w = child_w;
+
+ col_height[n_cols] = child_h;
+ start_i = i;
+
+ remain_h = box_h - off_y;
+ }
+ }
}
col_break[n_cols] = i - 1;
if (remain_x > 0)
{
- if (priv->align.h >= 0)
- inc_x = priv->align.h * remain_x;
- else if (col_count == 0)
- x += remain_x / 2;
- else /* x-justified */
- inc_x = remain_x / col_count;
+ if (priv->align.h >= 0)
+ inc_x = priv->align.h * remain_x;
+ else if (col_count == 0)
+ x += remain_x / 2;
+ else /* x-justified */
+ inc_x = remain_x / col_count;
}
inc_x += priv->pad.h;
remain_y = (h - col_height[c]);
if (priv->align.v < 0.0)
- {
- if (col_size == 0)
- y += remain_y / 2;
- else
- _fixed_point_divide_and_decompose_integer
- (remain_y, col_size, &col_justify, &just_inc);
- }
+ {
+ if (col_size == 0)
+ y += remain_y / 2;
+ else
+ _fixed_point_divide_and_decompose_integer
+ (remain_y, col_size, &col_justify, &just_inc);
+ }
col_justify += priv->pad.v;
for (; i <= col_break[c]; i++, l = l->next)
- {
- Evas_Object_Box_Option *opt = l->data;
- int off_x, off_y, x_remain;
- int padding_t, padding_b;
- int child_w, child_h;
- double align_x;
+ {
+ Evas_Object_Box_Option *opt = l->data;
+ int off_x, off_y, x_remain;
+ int padding_t, padding_b;
+ int child_w, child_h;
+ double align_x;
- evas_object_size_hint_align_get(opt->obj, &align_x, NULL);
- evas_object_size_hint_padding_get
- (opt->obj, NULL, NULL, &padding_t, &padding_b);
+ evas_object_size_hint_align_get(opt->obj, &align_x, NULL);
+ evas_object_size_hint_padding_get
+ (opt->obj, NULL, NULL, &padding_t, &padding_b);
- evas_object_geometry_get
- (opt->obj, NULL, NULL, &child_w, &child_h);
+ evas_object_geometry_get
+ (opt->obj, NULL, NULL, &child_w, &child_h);
- x_remain = col_max_w[c] - child_w;
+ x_remain = col_max_w[c] - child_w;
- off_x = x_remain * align_x;
- off_y = padding_t;
- if (priv->align.v >= 0.0)
- off_y += remain_y * priv->align.v;
+ off_x = x_remain * align_x;
+ off_y = padding_t;
+ if (priv->align.v >= 0.0)
+ off_y += remain_y * priv->align.v;
- evas_object_move(opt->obj, x + off_x, y + off_y);
+ evas_object_move(opt->obj, x + off_x, y + off_y);
- y += child_h + padding_t + padding_b + col_justify;
+ y += child_h + padding_t + padding_b + col_justify;
- sub_pixel += just_inc;
- if (sub_pixel >= 1 << 16)
- {
- y++;
- sub_pixel -= 1 << 16;
- }
- }
+ sub_pixel += just_inc;
+ if (sub_pixel >= 1 << 16)
+ {
+ y++;
+ sub_pixel -= 1 << 16;
+ }
+ }
evas_object_geometry_get(o, NULL, &y, NULL, NULL);
min_w += col_max_w[c];
{
Evas_Object *child = opt->obj;
Evas_Coord max_w, max_h, min_w, min_h, pad_l, pad_r, pad_t, pad_b,
- child_w, child_h, new_w, new_h, off_x, off_y;
+ child_w, child_h, new_w, new_h, off_x, off_y;
double align_x, align_y;
evas_object_size_hint_align_get(child, &align_x, &align_y);
evas_object_size_hint_padding_get
- (child, &pad_l, &pad_r, &pad_t, &pad_b);
+ (child, &pad_l, &pad_r, &pad_t, &pad_b);
evas_object_size_hint_max_get(child, &max_w, &max_h);
evas_object_size_hint_min_get(child, &min_w, &min_h);
- _sizing_eval(opt->obj);
- evas_object_geometry_get(child, NULL, NULL, &child_w, &child_h);
+ _sizing_eval(opt->obj);
+ evas_object_geometry_get(child, NULL, NULL, &child_w, &child_h);
new_w = child_w;
new_h = child_h;
if (new_w > top_w) top_w = new_w;
if (new_h > top_h) top_h = new_h;
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_w, &new_w, min_w, max_w, ow, &off_x, align_x, pad_l, pad_r);
+ (child_w, &new_w, min_w, max_w, ow, &off_x, align_x, pad_l, pad_r);
_layout_set_offset_and_change_dimension_min_max_cell_bounded
- (child_h, &new_h, min_h, max_h, oh, &off_y, align_y, pad_t, pad_b);
+ (child_h, &new_h, min_h, max_h, oh, &off_y, align_y, pad_t, pad_b);
- if ((new_w != child_w) || (new_h != child_h))
- evas_object_resize(child, new_w, new_h);
+ if ((new_w != child_w) || (new_h != child_h))
+ evas_object_resize(child, new_w, new_h);
evas_object_move(child, ox + off_x, oy + off_y);
if (old_child)
- evas_object_stack_above(child, old_child);
+ evas_object_stack_above(child, old_child);
old_child = child;
}
EVAS_OBJECT_BOX_DATA_GET(o, priv);
if (priv)
{
- if (horizontal) *horizontal = priv->align.h;
- if (vertical) *vertical = priv->align.v;
+ if (horizontal) *horizontal = priv->align.h;
+ if (vertical) *vertical = priv->align.v;
}
else
{
- if (horizontal) *horizontal = 0.5;
- if (vertical) *vertical = 0.5;
+ if (horizontal) *horizontal = 0.5;
+ if (vertical) *vertical = 0.5;
}
}
EVAS_OBJECT_BOX_DATA_GET(o, priv);
if (priv)
{
- if (horizontal) *horizontal = priv->pad.h;
- if (vertical) *vertical = priv->pad.v;
+ if (horizontal) *horizontal = priv->pad.h;
+ if (vertical) *vertical = priv->pad.v;
}
else
{
- if (horizontal) *horizontal = 0;
- if (vertical) *vertical = 0;
+ if (horizontal) *horizontal = 0;
+ if (vertical) *vertical = 0;
}
}
if (opt)
{
- evas_object_smart_member_add(child, o);
- evas_object_smart_changed(o);
- return _evas_object_box_option_callbacks_register(o, priv, opt);
+ evas_object_smart_member_add(child, o);
+ evas_object_smart_changed(o);
+ return _evas_object_box_option_callbacks_register(o, priv, opt);
}
return NULL;
}
EAPI const char *
-evas_object_box_option_property_name_get(Evas_Object *o, int property)
+evas_object_box_option_property_name_get(const Evas_Object *o, int property)
{
const Evas_Object_Box_Api *api;
}
EAPI int
-evas_object_box_option_property_id_get(Evas_Object *o, const char *name)
+evas_object_box_option_property_id_get(const Evas_Object *o, const char *name)
{
const Evas_Object_Box_Api *api;
}
EAPI Eina_Bool
-evas_object_box_option_property_get(Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...)
+evas_object_box_option_property_get(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...)
{
Eina_Bool ret;
va_list args;
}
EAPI Eina_Bool
-evas_object_box_option_property_vget(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args)
+evas_object_box_option_property_vget(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args)
{
const Evas_Object_Box_Api *api;
}
EAPI Eina_Bool
-evas_object_grid_pack_get(Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h)
+evas_object_grid_pack_get(const Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h)
{
Evas_Object_Grid_Option *opt;
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return NULL;
MAGIC_CHECK_END();
+ EINA_SAFETY_ON_NULL_RETURN_VAL(e->engine.func, NULL);
obj = evas_object_new(e);
evas_object_image_init(obj);
evas_object_inject(obj, e);
{
#ifdef HAVE_SYS_MMAN_H
Evas_Object_Image *o;
- char buf[4096];
+ char buf[PATH_MAX];
void *dst;
int fd = -1;
#endif
if (fd < 0)
{
- snprintf(buf, sizeof(buf), "/tmp/.evas-tmpf-%i-%p-%i-XXXXXX",
- (int)getpid(), data, (int)size);
+ const char *tmpdir = getenv("TMPDIR");
+
+ if (!tmpdir)
+ {
+ tmpdir = getenv("TMP");
+ if (!tmpdir)
+ {
+ tmpdir = getenv("TEMP");
+ if (!tmpdir) tmpdir = "/tmp";
+ }
+ }
+ snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX",
+ tmpdir, (int)getpid(), data, (int)size);
fd = mkstemp(buf);
+ if (fd < 0) return;
}
- if (fd < 0) return;
if (ftruncate(fd, size) < 0)
{
unlink(buf);
close(fd);
return;
}
+#ifdef __linux__
unlink(buf);
+#endif
eina_mmap_safety_enabled_set(EINA_TRUE);
return;
MAGIC_CHECK_END();
_evas_object_image_cleanup(obj, o);
-#ifdef EVAS_FRAME_QUEUING
- if (o->engine_data)
- evas_common_pipe_op_image_flush(o->engine_data);
-#endif
p_data = o->engine_data;
if (data)
{
return NULL;
MAGIC_CHECK_END();
if (!o->engine_data) return NULL;
-#ifdef EVAS_FRAME_QUEUING
- evas_common_pipe_op_image_flush(o->engine_data);
-#endif
data = NULL;
if (obj->layer->evas->engine.func->image_scale_hint_set)
{
int stride = 0;
-#ifdef EVAS_FRAME_QUEUING
- evas_common_pipe_op_image_flush(o->engine_data);
-#endif
o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
o->engine_data,
o->cur.has_alpha);
MAGIC_CHECK_END();
_evas_object_image_cleanup(obj, o);
-#ifdef EVAS_FRAME_QUEUING
- if ((Evas_Colorspace)o->cur.cspace != cspace)
- {
- if (o->engine_data)
- evas_common_pipe_op_image_flush(o->engine_data);
- }
-#endif
o->cur.cspace = cspace;
if (o->engine_data)
return;
MAGIC_CHECK_END();
if (o->scale_hint == hint) return;
-#ifdef EVAS_FRAME_QUEUING
- if (o->engine_data)
- evas_common_pipe_op_image_flush(o->engine_data);
-#endif
o->scale_hint = hint;
if (o->engine_data)
{
return;
MAGIC_CHECK_END();
if (o->content_hint == hint) return;
-#ifdef EVAS_FRAME_QUEUING
- if (o->engine_data)
- evas_common_pipe_op_image_flush(o->engine_data);
-#endif
o->content_hint = hint;
if (o->engine_data)
{
Evas_Object_Image *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 256, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 16, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
}
if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
{
- const Evas_Map_Point *p, *p_end;
- RGBA_Map_Point pts[obj->cur.map->count], *pt;
+ RGBA_Map_Point *pts;
- p = obj->cur.map->points;
- p_end = p + obj->cur.map->count;
- pt = pts;
-
- pts[0].px = obj->cur.map->persp.px << FP;
- pts[0].py = obj->cur.map->persp.py << FP;
- pts[0].foc = obj->cur.map->persp.foc << FP;
- pts[0].z0 = obj->cur.map->persp.z0 << FP;
- // draw geom +x +y
- for (; p < p_end; p++, pt++)
- {
- pt->x = (lround(p->x) + x) * FP1;
- pt->y = (lround(p->y) + y) * FP1;
- pt->z = (lround(p->z) ) * FP1;
- pt->fx = p->px;
- pt->fy = p->py;
- pt->fz = p->z;
- pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
- pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
- if (pt->u < 0) pt->u = 0;
- else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
- if (pt->v < 0) pt->v = 0;
- else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
- pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
- }
- if (obj->cur.map->count & 0x1)
- {
- pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
- }
+ evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
+ pts = obj->spans->pts;
obj->layer->evas->engine.func->image_map_draw
(output, context, surface, pixels, obj->cur.map->count,
DATA32 magic;
struct {
struct {
- int x1, y1, x2, y2;
+ Evas_Coord x1, y1, x2, y2;
struct {
Evas_Coord w, h;
} object;
} cache;
- Evas_Coord x1, y1, x2, y2;
+ Evas_Coord x1, y1, x2, y2;
} cur, prev;
void *engine_data;
-
- char changed : 1;
+ Eina_Bool changed : 1;
};
/* private methods for line objects */
{
/* methods (compulsory) */
evas_object_line_free,
- evas_object_line_render,
- evas_object_line_render_pre,
- evas_object_line_render_post,
- evas_object_line_id_get,
- evas_object_line_visual_id_get,
- evas_object_line_engine_data_get,
+ evas_object_line_render,
+ evas_object_line_render_pre,
+ evas_object_line_render_post,
+ evas_object_line_id_get,
+ evas_object_line_visual_id_get,
+ evas_object_line_engine_data_get,
/* these are optional. NULL = nothing */
- NULL,
- NULL,
- NULL,
- NULL,
- evas_object_line_is_opaque,
- evas_object_line_was_opaque,
- evas_object_line_is_inside,
- evas_object_line_was_inside,
- evas_object_line_coords_recalc,
- NULL,
- NULL,
- NULL,
- NULL
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ evas_object_line_is_opaque,
+ evas_object_line_was_opaque,
+ evas_object_line_is_inside,
+ evas_object_line_was_inside,
+ evas_object_line_coords_recalc,
+ NULL,
+ NULL,
+ NULL,
+ NULL
};
/* the actual api call to add a rect */
o->cur.y1 = y1 - min_y;
o->cur.x2 = x2 - min_x;
o->cur.y2 = y2 - min_y;
- o->changed = 1;
+ o->changed = EINA_TRUE;
evas_object_change(obj);
evas_object_coords_recalc(obj);
evas_object_clip_dirty(obj);
obj->cur.geometry.w = 0;
obj->cur.geometry.h = 0;
obj->cur.layer = 0;
- obj->cur.anti_alias = 1;
+ obj->cur.anti_alias = EINA_TRUE;
obj->cur.render_op = EVAS_RENDER_BLEND;
/* set up object-specific settings */
obj->prev = obj->cur;
Evas_Object_Line *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_line", Evas_Object_Line, 16, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_line", Evas_Object_Line, 4, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Line);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Line);
/* render object to surface with context, and offxet by x,y */
o = (Evas_Object_Line *)(obj->object_data);
obj->layer->evas->engine.func->context_color_set(output,
- context,
- obj->cur.cache.clip.r,
- obj->cur.cache.clip.g,
- obj->cur.cache.clip.b,
- obj->cur.cache.clip.a);
+ context,
+ obj->cur.cache.clip.r,
+ obj->cur.cache.clip.g,
+ obj->cur.cache.clip.b,
+ obj->cur.cache.clip.a);
obj->layer->evas->engine.func->context_multiplier_unset(output,
- context);
+ context);
obj->layer->evas->engine.func->context_anti_alias_set(output, context,
- obj->cur.anti_alias);
+ obj->cur.anti_alias);
obj->layer->evas->engine.func->context_render_op_set(output, context,
- obj->cur.render_op);
+ obj->cur.render_op);
obj->layer->evas->engine.func->line_draw(output,
- context,
- surface,
- o->cur.cache.x1 + x,
- o->cur.cache.y1 + y,
- o->cur.cache.x2 + x,
- o->cur.cache.y2 + y);
+ context,
+ surface,
+ o->cur.cache.x1 + x,
+ o->cur.cache.y1 + y,
+ o->cur.cache.x2 + x,
+ o->cur.cache.y2 + y);
}
static void
{
Evas_Object_Line *o;
int is_v, was_v;
+ Eina_Bool changed_color = EINA_FALSE;
/* dont pre-render the obj twice! */
if (obj->pre_render_done) return;
- obj->pre_render_done = 1;
+ obj->pre_render_done = EINA_TRUE;
/* pre-render phase. this does anything an object needs to do just before */
/* rendering. this could mean loading the image data, retrieving it from */
/* elsewhere, decoding video etc. */
/* if someone is clipping this obj - go calculate the clipper */
if (obj->cur.clipper)
{
- if (obj->cur.cache.clip.dirty)
- evas_object_clip_recalc(obj->cur.clipper);
- obj->cur.clipper->func->render_pre(obj->cur.clipper);
+ if (obj->cur.cache.clip.dirty)
+ evas_object_clip_recalc(obj->cur.clipper);
+ obj->cur.clipper->func->render_pre(obj->cur.clipper);
}
/* now figure what changed and add draw rects */
/* if it just became visible or invisible */
was_v = evas_object_was_visible(obj);
if (is_v != was_v)
{
- evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
- goto done;
+ evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes,
+ obj, is_v, was_v);
+ goto done;
}
if (obj->changed_map)
{
if (!is_v) goto done;
/* clipper changed this is in addition to anything else for obj */
evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj);
- /* if we restacked (layer or just within a layer) */
- if (obj->restack)
- {
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
- }
- /* if it changed anti_alias */
- if (obj->cur.anti_alias != obj->prev.anti_alias)
- {
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
- }
- /* if it changed render op */
- if (obj->cur.render_op != obj->prev.render_op)
- {
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
- }
- /* if it changed color */
+
if ((obj->cur.color.r != obj->prev.color.r) ||
(obj->cur.color.g != obj->prev.color.g) ||
(obj->cur.color.b != obj->prev.color.b) ||
(obj->cur.color.a != obj->prev.color.a))
+ changed_color = EINA_TRUE;
+
+ /* if we restacked (layer or just within a layer) */
+ /* or if it changed anti_alias */
+ /* or if ii changed render op */
+ /* or if it changed color */
+ if ((obj->restack) ||
+ (obj->cur.anti_alias != obj->prev.anti_alias) ||
+ (obj->cur.render_op != obj->prev.render_op) ||
+ (changed_color)
+ )
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ obj);
+ goto done;
}
+
/* if it changed geometry - and obviously not visibility or color */
/* calculate differences since we have a constant color fill */
/* we really only need to update the differences */
(obj->cur.geometry.w != obj->prev.geometry.w) ||
(obj->cur.geometry.h != obj->prev.geometry.h) ||
((o->changed) &&
- ((o->cur.x1 != o->prev.x1) ||
- (o->cur.y1 != o->prev.y1) ||
- (o->cur.x2 != o->prev.x2) ||
- (o->cur.y2 != o->prev.y2)))
- )
+ ((o->cur.x1 != o->prev.x1) ||
+ (o->cur.y1 != o->prev.y1) ||
+ (o->cur.x2 != o->prev.x2) ||
+ (o->cur.y2 != o->prev.y2)))
+ )
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ obj);
+ goto done;
}
- done:
- evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v);
+
+done:
+ evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj,
+ is_v, was_v);
}
static void
/* move cur to prev safely for object data */
obj->prev = obj->cur;
o->prev = o->cur;
- o->changed = 0;
+ o->changed = EINA_FALSE;
}
static unsigned int evas_object_line_id_get(Evas_Object *obj)
{
Evas_Object *obj;
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object", Evas_Object, 512, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object", Evas_Object, 32, NULL);
obj = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object);
if (!obj) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, obj, Evas_Object);
obj->del_ref = EINA_TRUE;
return;
}
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush();
-#endif
evas_object_hide(obj);
if (obj->focused)
while (obj->proxy.proxies)
evas_object_image_source_unset(obj->proxy.proxies->data);
if (obj->cur.clipper) evas_object_clip_unset(obj);
- if (obj->smart.smart) evas_object_smart_del(obj);
evas_object_map_set(obj, NULL);
+ if (obj->smart.smart) evas_object_smart_del(obj);
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL, _evas_event_counter);
_evas_post_event_callback_call(obj->layer->evas);
evas_object_change(obj);
}
+void
+evas_object_update_bounding_box(Evas_Object *obj)
+{
+ Eina_Bool propagate = EINA_FALSE;
+ Eina_Bool computeminmax = EINA_FALSE;
+ Evas_Coord x, y, w, h;
+ Evas_Coord px, py, pw, ph;
+ Eina_Bool noclip;
+
+ if (!obj->smart.parent) return ;
+ if (obj->child_has_map) return ; /* Disable bounding box computation for this object and its parent */
+ /* We could also remove object that are not visible from the bounding box, use the clipping information
+ to reduce the bounding of the object they are clipping, but for the moment this will do it's jobs */
+ noclip = !(obj->clip.clipees || obj->is_static_clip);
+
+ if (obj->smart.smart)
+ {
+ x = obj->cur.bounding_box.x;
+ y = obj->cur.bounding_box.y;
+ w = obj->cur.bounding_box.w;
+ h = obj->cur.bounding_box.h;
+ px = obj->prev.bounding_box.x;
+ py = obj->prev.bounding_box.y;
+ pw = obj->prev.bounding_box.w;
+ ph = obj->prev.bounding_box.h;
+ }
+ else
+ {
+ x = obj->cur.geometry.x;
+ y = obj->cur.geometry.y;
+ w = obj->cur.geometry.w;
+ h = obj->cur.geometry.h;
+ px = obj->prev.geometry.x;
+ py = obj->prev.geometry.y;
+ pw = obj->prev.geometry.w;
+ ph = obj->prev.geometry.h;
+ }
+
+ /* We are not yet trying to find the smallest bounding box, but we want to find a good approximation quickly.
+ * That's why we initialiaze min and max search to geometry of the parent object.
+ */
+
+ if (obj->smart.parent->cur.valid_bounding_box)
+ {
+ /* Update left limit */
+ if (noclip && x < obj->smart.parent->cur.bounding_box.x)
+ {
+ obj->smart.parent->cur.bounding_box.w += obj->smart.parent->cur.bounding_box.x - x;
+ obj->smart.parent->cur.bounding_box.x = x;
+ propagate = EINA_TRUE;
+ }
+ else if ((px == obj->smart.parent->prev.bounding_box.x && x > obj->smart.parent->cur.bounding_box.x)
+ || (!noclip && x == obj->smart.parent->cur.bounding_box.x))
+ {
+ computeminmax = EINA_TRUE;
+ }
+
+ /* Update top limit */
+ if (noclip && y < obj->smart.parent->cur.bounding_box.y)
+ {
+ obj->smart.parent->cur.bounding_box.h += obj->smart.parent->cur.bounding_box.x - x;
+ obj->smart.parent->cur.bounding_box.y = y;
+ propagate = EINA_TRUE;
+ }
+ else if ((py == obj->smart.parent->prev.bounding_box.y && y > obj->smart.parent->cur.bounding_box.y)
+ || (!noclip && y == obj->smart.parent->cur.bounding_box.y))
+ {
+ computeminmax = EINA_TRUE;
+ }
+
+ /* Update right limit */
+ if (noclip && x + w > obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
+ {
+ obj->smart.parent->cur.bounding_box.w = x + w - obj->smart.parent->cur.bounding_box.x;
+ propagate = EINA_TRUE;
+ }
+ else if ((px + pw == obj->smart.parent->prev.bounding_box.x + obj->smart.parent->prev.bounding_box.w &&
+ x + w < obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w)
+ || (!noclip && x + w == obj->smart.parent->cur.bounding_box.x + obj->smart.parent->cur.bounding_box.w))
+ {
+ computeminmax = EINA_TRUE;
+ }
+
+ /* Update bottom limit */
+ if (noclip && y + h > obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h)
+ {
+ obj->smart.parent->cur.bounding_box.h = y + h - obj->smart.parent->cur.bounding_box.y;
+ propagate = EINA_TRUE;
+ }
+ else if ((py + ph == obj->smart.parent->prev.bounding_box.y + obj->smart.parent->prev.bounding_box.h &&
+ y + h < obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h) ||
+ (!noclip && y + h == obj->smart.parent->cur.bounding_box.y + obj->smart.parent->cur.bounding_box.h))
+ {
+ computeminmax = EINA_TRUE;
+ }
+
+ if (computeminmax)
+ {
+ evas_object_smart_need_bounding_box_update(obj->smart.parent);
+ }
+ }
+ else
+ {
+ if (noclip)
+ {
+ obj->smart.parent->cur.bounding_box.x = x;
+ obj->smart.parent->cur.bounding_box.y = y;
+ obj->smart.parent->cur.bounding_box.w = w;
+ obj->smart.parent->cur.bounding_box.h = h;
+ obj->smart.parent->cur.valid_bounding_box = EINA_TRUE;
+ propagate = EINA_TRUE;
+ }
+ }
+
+ if (propagate)
+ evas_object_update_bounding_box(obj->smart.parent);
+}
+
EAPI void
evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
obj->cur.geometry.x = nx;
obj->cur.geometry.y = ny;
+ evas_object_update_bounding_box(obj);
+
//// obj->cur.cache.geometry.validity = 0;
obj->changed_move = EINA_TRUE;
evas_object_change(obj);
obj->cur.geometry.w = nw;
obj->cur.geometry.h = nh;
+ evas_object_update_bounding_box(obj);
+
//// obj->cur.cache.geometry.validity = 0;
evas_object_change(obj);
evas_object_clip_dirty(obj);
{
if (obj->size_hints) return;
- EVAS_MEMPOOL_INIT(_mp_sh, "evas_size_hints", Evas_Size_Hints, 512, );
+ EVAS_MEMPOOL_INIT(_mp_sh, "evas_size_hints", Evas_Size_Hints, 32, );
obj->size_hints = EVAS_MEMPOOL_ALLOC(_mp_sh, Evas_Size_Hints);
if (!obj->size_hints) return;
EVAS_MEMPOOL_PREP(_mp_sh, obj->size_hints, Evas_Size_Hints);
Evas_Object_Polygon *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_polygon", Evas_Object_Polygon, 32, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_polygon", Evas_Object_Polygon, 4, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Polygon);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Polygon);
Evas_Object_Rectangle *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_rectangle", Evas_Object_Rectangle, 256, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_rectangle", Evas_Object_Rectangle, 16, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Rectangle);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Rectangle);
Eina_Inlist *contained;
Evas_Smart_Cb_Description_Array callbacks_descriptions;
int walking_list;
+ int member_count;
Eina_Bool deletions_waiting : 1;
Eina_Bool need_recalculate : 1;
+ Eina_Bool update_boundingbox_needed : 1;
};
struct _Evas_Smart_Callback
MAGIC_CHECK_END();
o = (Evas_Object_Smart *)(obj->object_data);
if (!o) return NULL;
+ if (o->magic != MAGIC_OBJ_SMART) return NULL;
return o->data;
}
if (obj->smart.parent) evas_object_smart_member_del(obj);
+ o->member_count++;
evas_object_release(obj, 1);
obj->layer = smart_obj->layer;
obj->cur.layer = obj->layer->layer;
evas_object_mapped_clip_across_mark(obj);
if (smart_obj->smart.smart->smart_class->member_add)
smart_obj->smart.smart->smart_class->member_add(smart_obj, obj);
+ evas_object_update_bounding_box(obj);
}
EAPI void
o = (Evas_Object_Smart *)(obj->smart.parent->object_data);
o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(obj));
+ o->member_count--;
obj->smart.parent = NULL;
evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
obj->layer->usage--;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return NULL;
MAGIC_CHECK_END();
+ if (!obj->smart.smart) return NULL;
o = (Evas_Object_Smart *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
return NULL;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return NULL;
MAGIC_CHECK_END();
+ if (!obj->smart.smart) return NULL;
o = (Evas_Object_Smart *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
return NULL;
_evas_object_smart_members_all_del(Evas_Object *obj)
{
Evas_Object_Smart *o = (Evas_Object_Smart *)(obj->object_data);
- while (o->contained)
- evas_object_del((Evas_Object *)(o->contained));
+ Evas_Object *memobj;
+ Eina_Inlist *itrn;
+ EINA_INLIST_FOREACH_SAFE(o->contained, itrn, memobj)
+ {
+ evas_object_del((Evas_Object *) memobj);
+ }
}
EAPI Evas_Object *
MAGIC_CHECK_END();
if (!event) return;
if (!func) return;
- EVAS_MEMPOOL_INIT(_mp_cb, "evas_smart_callback", Evas_Smart_Callback, 512, );
+ EVAS_MEMPOOL_INIT(_mp_cb, "evas_smart_callback", Evas_Smart_Callback, 32, );
cb = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Smart_Callback);
if (!cb) return;
EVAS_MEMPOOL_PREP(_mp_cb, cb, Evas_Smart_Callback);
o->contained = eina_inlist_prepend_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
}
+void
+evas_object_smart_need_bounding_box_update(Evas_Object *obj)
+{
+ Evas_Object_Smart *o;
+
+ o = (Evas_Object_Smart *)(obj->object_data);
+
+ if (o->update_boundingbox_needed) return ;
+ o->update_boundingbox_needed = EINA_TRUE;
+
+ if (obj->smart.parent) evas_object_smart_need_bounding_box_update(obj->smart.parent);
+}
+
+void
+evas_object_smart_bouding_box_update(Evas_Object *obj)
+{
+ Eina_Inlist *list;
+ Evas_Object *o;
+ Evas_Object_Smart *os;
+ Evas_Coord minx;
+ Evas_Coord miny;
+ Evas_Coord maxw = 0;
+ Evas_Coord maxh = 0;
+
+ os = (Evas_Object_Smart *)(obj->object_data);
+
+ if (!os->update_boundingbox_needed) return ;
+ os->update_boundingbox_needed = EINA_FALSE;
+
+ minx = obj->layer->evas->output.w;
+ miny = obj->layer->evas->output.h;
+
+ list = os->contained;
+ EINA_INLIST_FOREACH(list, o)
+ {
+ Evas_Coord tx;
+ Evas_Coord ty;
+ Evas_Coord tw;
+ Evas_Coord th;
+
+ if (o == obj) continue ;
+ if (o->clip.clipees || o->is_static_clip) continue ;
+
+ if (o->smart.smart)
+ {
+ evas_object_smart_bouding_box_update(o);
+
+ tx = o->cur.bounding_box.x;
+ ty = o->cur.bounding_box.y;
+ tw = o->cur.bounding_box.x + o->cur.bounding_box.w;
+ th = o->cur.bounding_box.y + o->cur.bounding_box.h;
+ }
+ else
+ {
+ tx = o->cur.geometry.x;
+ ty = o->cur.geometry.y;
+ tw = o->cur.geometry.x + o->cur.geometry.w;
+ th = o->cur.geometry.y + o->cur.geometry.h;
+ }
+
+ if (tx < minx) minx = tx;
+ if (ty < miny) miny = ty;
+ if (tw > maxw) maxw = tw;
+ if (th > maxh) maxh = th;
+ }
+
+ if (minx != obj->cur.bounding_box.x)
+ {
+ obj->cur.bounding_box.w += obj->cur.bounding_box.x - minx;
+ obj->cur.bounding_box.x = minx;
+ }
+
+ if (miny != obj->cur.bounding_box.y)
+ {
+ obj->cur.bounding_box.h += obj->cur.bounding_box.y - miny;
+ obj->cur.bounding_box.y = miny;
+ }
+
+ if (maxw != obj->cur.bounding_box.x + obj->cur.bounding_box.w)
+ {
+ obj->cur.bounding_box.w = maxw - obj->cur.bounding_box.x;
+ }
+
+ if (maxh != obj->cur.bounding_box.y + obj->cur.bounding_box.h)
+ {
+ obj->cur.bounding_box.h = maxh - obj->cur.bounding_box.y;
+ }
+}
+
/* all nice and private */
static void
evas_object_smart_init(Evas_Object *obj)
Evas_Object_Smart *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_smart", Evas_Object_Smart, 256, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_smart", Evas_Object_Smart, 32, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Smart);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Smart);
evas_object_smart_render_pre(Evas_Object *obj)
{
if (obj->pre_render_done) return;
+ if (!obj->child_has_map)
+ {
+#if 0
+ Evas_Object_Smart *o;
+
+ o = (Evas_Object_Smart *)(obj->object_data);
+ if (o->member_count > 1 &&
+ obj->cur.bounding_box.w == obj->prev.bounding_box.w &&
+ obj->cur.bounding_box.h == obj->prev.bounding_box.h &&
+ (obj->cur.bounding_box.x != obj->prev.bounding_box.x ||
+ obj->cur.bounding_box.y != obj->prev.bounding_box.y))
+ {
+ fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p < %p)\n", evas_object_type_get(obj), obj, obj->smart.parent);
+ }
+#endif
+ }
if (obj->changed_map)
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
#include "evas_common.h"
#include "evas_private.h"
-#define CSO_DATA_GET_OR_RETURN(obj, ptr) \
+#define CSO_DATA_GET_OR_RETURN(obj, ptr) \
Evas_Object_Smart_Clipped_Data *ptr = evas_object_smart_data_get(obj); \
if (!ptr) return;
lst = evas_object_smart_members_get_direct(obj);
EINA_INLIST_FOREACH(lst, child)
{
- Evas_Coord orig_x, orig_y;
+ Evas_Coord orig_x, orig_y;
-// shortcut as we are in evas
-// evas_object_geometry_get(child, &orig_x, &orig_y, NULL, NULL);
+ // shortcut as we are in evas
+ // evas_object_geometry_get(child, &orig_x, &orig_y, NULL, NULL);
if (child->delete_me) continue;
if (child->is_static_clip) continue;
orig_x = child->cur.geometry.x;
orig_y = child->cur.geometry.y;
- evas_object_move(child, orig_x + dx, orig_y + dy);
+ evas_object_move(child, orig_x + dx, orig_y + dy);
}
}
if (cso->clipper)
{
- Evas_Object *clipper = cso->clipper;
- cso->clipper = NULL;
- evas_object_del(clipper);
+ Evas_Object *clipper = cso->clipper;
+ cso->clipper = NULL;
+ evas_object_del(clipper);
}
_evas_object_smart_members_all_del(obj);
double h, v;
} weights;
struct {
- int h, v;
+ int h, v;
} expands;
struct {
- Evas_Coord w, h;
+ Evas_Coord w, h;
} min;
} total;
struct {
const Evas_Object *table;
};
-#define EVAS_OBJECT_TABLE_DATA_GET(o, ptr) \
- Evas_Object_Table_Data *ptr = evas_object_smart_data_get(o)
-
-#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, ptr) \
- EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
- if (!ptr) \
- { \
- CRIT("no widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- abort(); \
- return; \
+#define EVAS_OBJECT_TABLE_DATA_GET(o, ptr) \
+ Evas_Object_Table_Data *ptr = evas_object_smart_data_get(o)
+
+#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, ptr) \
+ EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
+if (!ptr) \
+{ \
+ CRIT("no widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return; \
}
-#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
- EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
- if (!ptr) \
- { \
- CRIT("No widget data for object %p (%s)", \
- o, evas_object_type_get(o)); \
- abort(); \
- return val; \
- }
+#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+ EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
+if (!ptr) \
+{ \
+ CRIT("No widget data for object %p (%s)", \
+ o, evas_object_type_get(o)); \
+ return val; \
+}
static const char EVAS_OBJECT_TABLE_OPTION_KEY[] = "|EvTb";
int size;
size = sizeof(Evas_Object_Table_Cache) +
- ((cols + rows) *
+ ((cols + rows) *
(sizeof(double) + sizeof(Evas_Coord) + sizeof(Eina_Bool)));
cache = malloc(size);
if (!cache)
{
- ERR("Could not allocate table cache %dx%d (%d bytes): %s",
- cols, rows, size, strerror(errno));
- return NULL;
+ ERR("Could not allocate table cache %dx%d (%d bytes): %s",
+ cols, rows, size, strerror(errno));
+ return NULL;
}
cache->weights.h = (double *)(cache + 1);
c->total.min.h = 0;
size = ((priv->size.rows + priv->size.cols) *
- (sizeof(double) + sizeof(Evas_Coord) + sizeof(Eina_Bool)));
+ (sizeof(double) + sizeof(Evas_Coord) + sizeof(Eina_Bool)));
memset(c + 1, 0, size);
}
priv->hints_changed = 1;
if (priv->cache)
{
- _evas_object_table_cache_free(priv->cache);
- priv->cache = NULL;
+ _evas_object_table_cache_free(priv->cache);
+ priv->cache = NULL;
}
}
*x += opt->pad.l;
if (cw != *w)
{
- *x += (*w - cw) * opt->align.h;
- *w = cw;
+ *x += (*w - cw) * opt->align.h;
+ *w = cw;
}
*y += opt->pad.t;
if (ch != *h)
{
- *y += (*h - ch) * opt->align.v;
- *h = ch;
+ *y += (*h - ch) * opt->align.v;
+ *h = ch;
}
}
EINA_LIST_FOREACH(priv->children, l, opt)
{
- Evas_Object *child = opt->obj;
- Evas_Coord child_minw, child_minh, cell_minw, cell_minh;
- double weightw, weighth;
-
- evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
- evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
- evas_object_size_hint_padding_get
- (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
- evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
- evas_object_size_hint_weight_get(child, &weightw, &weighth);
-
- child_minw = opt->min.w + opt->pad.l + opt->pad.r;
- child_minh = opt->min.h + opt->pad.t + opt->pad.b;
-
- cell_minw = (child_minw + opt->colspan - 1) / opt->colspan;
- cell_minh = (child_minh + opt->rowspan - 1) / opt->rowspan;
-
- opt->expand_h = 0;
- if ((weightw > 0.0) &&
- ((opt->max.w < 0) ||
- ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
- {
- opt->expand_h = 1;
- expand_h = 1;
- }
-
- opt->expand_v = 0;
- if ((weighth > 0.0) &&
- ((opt->max.h < 0) ||
- ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
- {
- opt->expand_v = 1;
- expand_v = 1;
- }
-
- opt->fill_h = 0;
- if (opt->align.h < 0.0)
- {
- opt->align.h = 0.5;
- opt->fill_h = 1;
- }
- opt->fill_v = 0;
- if (opt->align.v < 0.0)
- {
- opt->align.v = 0.5;
- opt->fill_v = 1;
- }
-
- /* greatest mininum values, with paddings */
- if (minw < cell_minw)
- minw = cell_minw;
- if (minh < cell_minh)
- minh = cell_minh;
- /* greatest mininum values, without paddings */
- if (o_minw < opt->min.w)
- o_minw = opt->min.w;
- if (o_minh < opt->min.h)
- o_minh = opt->min.h;
+ Evas_Object *child = opt->obj;
+ Evas_Coord child_minw, child_minh, cell_minw, cell_minh;
+ double weightw, weighth;
+
+ evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
+ evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
+ evas_object_size_hint_padding_get
+ (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
+ evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
+ evas_object_size_hint_weight_get(child, &weightw, &weighth);
+
+ child_minw = opt->min.w + opt->pad.l + opt->pad.r;
+ child_minh = opt->min.h + opt->pad.t + opt->pad.b;
+
+ cell_minw = (child_minw + opt->colspan - 1) / opt->colspan;
+ cell_minh = (child_minh + opt->rowspan - 1) / opt->rowspan;
+
+ opt->expand_h = 0;
+ if ((weightw > 0.0) &&
+ ((opt->max.w < 0) ||
+ ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
+ {
+ opt->expand_h = 1;
+ expand_h = 1;
+ }
+
+ opt->expand_v = 0;
+ if ((weighth > 0.0) &&
+ ((opt->max.h < 0) ||
+ ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
+ {
+ opt->expand_v = 1;
+ expand_v = 1;
+ }
+
+ opt->fill_h = 0;
+ if (opt->align.h < 0.0)
+ {
+ opt->align.h = 0.5;
+ opt->fill_h = 1;
+ }
+ opt->fill_v = 0;
+ if (opt->align.v < 0.0)
+ {
+ opt->align.v = 0.5;
+ opt->fill_v = 1;
+ }
+
+ /* greatest mininum values, with paddings */
+ if (minw < cell_minw)
+ minw = cell_minw;
+ if (minh < cell_minh)
+ minh = cell_minh;
+ /* greatest mininum values, without paddings */
+ if (o_minw < opt->min.w)
+ o_minw = opt->min.w;
+ if (o_minh < opt->min.h)
+ o_minh = opt->min.h;
}
if (priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM)
{
- if (o_minw < 1)
- {
- ERR("homogeneous table based on item size but no "
- "horizontal mininum size specified! Using expand.");
- expand_h = 1;
- }
- if (o_minh < 1)
- {
- ERR("homogeneous table based on item size but no "
- "vertical mininum size specified! Using expand.");
- expand_v = 1;
- }
+ if (o_minw < 1)
+ {
+ ERR("homogeneous table based on item size but no "
+ "horizontal mininum size specified! Using expand.");
+ expand_h = 1;
+ }
+ if (o_minh < 1)
+ {
+ ERR("homogeneous table based on item size but no "
+ "vertical mininum size specified! Using expand.");
+ expand_v = 1;
+ }
}
minw = priv->size.cols * (minw + priv->pad.h) - priv->pad.h;
expand_h = 0;
if (!expand_h)
{
- *x += (*w - minw) * priv->align.h;
- *w = minw;
+ *x += (*w - minw) * priv->align.h;
+ *w = minw;
}
if (*h < minh)
expand_v = 0;
if (!expand_v)
{
- *y += (*h - minh) * priv->align.v;
- *h = minh;
+ *y += (*h - minh) * priv->align.v;
+ *h = minh;
}
}
Evas_Coord x = 0, y = 0, w = 0, h = 0, ww, hh, cellw = 0, cellh = 0;
Eina_List *l;
Evas_Object_Table_Option *opt;
-
+
_evas_object_table_calculate_layout_homogeneous_sizes
- (o, priv, &x, &y, &w, &h, &cellw, &cellh);
-
+ (o, priv, &x, &y, &w, &h, &cellw, &cellh);
+
ww = w - ((priv->size.cols - 1) * priv->pad.h);
hh = h - ((priv->size.rows - 1) * priv->pad.v);
-
+
if (ww < 0) ww = 0;
if (ww < 0) ww = 0;
-
+
EINA_LIST_FOREACH(priv->children, l, opt)
{
- Evas_Object *child = opt->obj;
- Evas_Coord cx, cy, cw, ch, cox, coy, cow, coh;
+ Evas_Object *child = opt->obj;
+ Evas_Coord cx, cy, cw, ch, cox, coy, cow, coh;
- cx = x + ((opt->col * ww) / priv->size.cols);
+ cx = x + ((opt->col * ww) / priv->size.cols);
cw = x + (((opt->col + opt->colspan) * ww) / priv->size.cols) - cx;
- cy = y + ((opt->row * hh) / priv->size.rows);
+ cy = y + ((opt->row * hh) / priv->size.rows);
ch = y + (((opt->row + opt->rowspan) * hh) / priv->size.rows) - cy;
cx += (opt->col) * priv->pad.h;
cy += (opt->row) * priv->pad.v;
-
+
cox = cx;
coy = cy;
cow = cw;
coh = ch;
- _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
+ _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
if (cw > cow)
{
cx = cox;
{
evas_object_move(child, cx, cy);
}
- evas_object_resize(child, cw, ch);
+ evas_object_resize(child, cw, ch);
}
}
const Eina_Bool *itr_expand = expands + start;
Evas_Coord step = 0, last_space = 0;
int total = 0, i = start;
-
+
/* XXX move to fixed point math and spread errors among cells */
if (weighttot > 0.0)
{
Eina_List *l;
double totweightw = 0.0, totweighth = 0.0;
int i;
-
+
if (!priv->cache)
{
- priv->cache = _evas_object_table_cache_alloc
- (priv->size.cols, priv->size.rows);
- if (!priv->cache)
- return;
+ priv->cache = _evas_object_table_cache_alloc
+ (priv->size.cols, priv->size.rows);
+ if (!priv->cache)
+ return;
}
c = priv->cache;
_evas_object_table_cache_reset(priv);
memset(c->weights.v, 0, priv->size.rows);
EINA_LIST_FOREACH(priv->children, l, opt)
{
- Evas_Object *child = opt->obj;
- double weightw, weighth;
-
- evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
- evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
- evas_object_size_hint_padding_get
- (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
- evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
- evas_object_size_hint_weight_get(child, &weightw, &weighth);
-
- opt->expand_h = 0;
- if ((weightw > 0.0) &&
- ((opt->max.w < 0) ||
- ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
- opt->expand_h = 1;
-
- opt->expand_v = 0;
- if ((weighth > 0.0) &&
- ((opt->max.h < 0) ||
- ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
- opt->expand_v = 1;
-
- opt->fill_h = 0;
- if (opt->align.h < 0.0)
- {
- opt->align.h = 0.5;
- opt->fill_h = 1;
- }
- opt->fill_v = 0;
- if (opt->align.v < 0.0)
- {
- opt->align.v = 0.5;
- opt->fill_v = 1;
- }
-
- if (!opt->expand_h)
- memset(c->expands.h + opt->col, 0, opt->colspan);
+ Evas_Object *child = opt->obj;
+ double weightw, weighth;
+
+ evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
+ evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
+ evas_object_size_hint_padding_get
+ (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
+ evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
+ evas_object_size_hint_weight_get(child, &weightw, &weighth);
+
+ opt->expand_h = 0;
+ if ((weightw > 0.0) &&
+ ((opt->max.w < 0) ||
+ ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
+ opt->expand_h = 1;
+
+ opt->expand_v = 0;
+ if ((weighth > 0.0) &&
+ ((opt->max.h < 0) ||
+ ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
+ opt->expand_v = 1;
+
+ opt->fill_h = 0;
+ if (opt->align.h < 0.0)
+ {
+ opt->align.h = 0.5;
+ opt->fill_h = 1;
+ }
+ opt->fill_v = 0;
+ if (opt->align.v < 0.0)
+ {
+ opt->align.v = 0.5;
+ opt->fill_v = 1;
+ }
+
+ if (!opt->expand_h)
+ memset(c->expands.h + opt->col, 0, opt->colspan);
else
{
for (i = opt->col; i < opt->col + opt->colspan; i++)
- c->weights.h[i] += (weightw / (double)opt->colspan);
+ c->weights.h[i] += (weightw / (double)opt->colspan);
}
- if (!opt->expand_v)
- memset(c->expands.v + opt->row, 0, opt->rowspan);
+ if (!opt->expand_v)
+ memset(c->expands.v + opt->row, 0, opt->rowspan);
else
{
for (i = opt->row; i < opt->row + opt->rowspan; i++)
/* calculate sizes for each row and column */
EINA_LIST_FOREACH(priv->children, l, opt)
{
- Evas_Coord tot, need;
-
- /* handle horizontal */
- tot = _evas_object_table_sum_sizes(c->sizes.h, opt->col, opt->end_col);
- need = opt->min.w + opt->pad.l + opt->pad.r;
- if (tot < need)
- {
- Evas_Coord space = need - tot;
- int count;
-
- count = _evas_object_table_count_expands
- (c->expands.h, opt->col, opt->end_col);
-
- if (count > 0)
- _evas_object_table_sizes_calc_expand
- (c->sizes.h, opt->col, opt->end_col, space,
- c->expands.h, count, c->weights.h, totweightw);
- else
- _evas_object_table_sizes_calc_noexpand
- (c->sizes.h, opt->col, opt->end_col, space);
- }
-
- /* handle vertical */
- tot = _evas_object_table_sum_sizes(c->sizes.v, opt->row, opt->end_row);
- need = opt->min.h + opt->pad.t + opt->pad.b;
- if (tot < opt->min.h)
- {
- Evas_Coord space = need - tot;
- int count;
-
- count = _evas_object_table_count_expands
- (c->expands.v, opt->row, opt->end_row);
-
- if (count > 0)
- _evas_object_table_sizes_calc_expand
- (c->sizes.v, opt->row, opt->end_row, space,
- c->expands.v, count, c->weights.v, totweighth);
- else
- _evas_object_table_sizes_calc_noexpand
- (c->sizes.v, opt->row, opt->end_row, space);
- }
+ Evas_Coord tot, need;
+
+ /* handle horizontal */
+ tot = _evas_object_table_sum_sizes(c->sizes.h, opt->col, opt->end_col);
+ need = opt->min.w + opt->pad.l + opt->pad.r;
+ if (tot < need)
+ {
+ Evas_Coord space = need - tot;
+ int count;
+
+ count = _evas_object_table_count_expands
+ (c->expands.h, opt->col, opt->end_col);
+
+ if (count > 0)
+ _evas_object_table_sizes_calc_expand
+ (c->sizes.h, opt->col, opt->end_col, space,
+ c->expands.h, count, c->weights.h, totweightw);
+ else
+ _evas_object_table_sizes_calc_noexpand
+ (c->sizes.h, opt->col, opt->end_col, space);
+ }
+
+ /* handle vertical */
+ tot = _evas_object_table_sum_sizes(c->sizes.v, opt->row, opt->end_row);
+ need = opt->min.h + opt->pad.t + opt->pad.b;
+ if (tot < opt->min.h)
+ {
+ Evas_Coord space = need - tot;
+ int count;
+
+ count = _evas_object_table_count_expands
+ (c->expands.v, opt->row, opt->end_row);
+
+ if (count > 0)
+ _evas_object_table_sizes_calc_expand
+ (c->sizes.v, opt->row, opt->end_row, space,
+ c->expands.v, count, c->weights.v, totweighth);
+ else
+ _evas_object_table_sizes_calc_noexpand
+ (c->sizes.v, opt->row, opt->end_row, space);
+ }
}
c->total.weights.h = totweightw;
c->total.weights.v = totweighth;
-
+
c->total.expands.h = _evas_object_table_count_expands
- (c->expands.h, 0, priv->size.cols);
+ (c->expands.h, 0, priv->size.cols);
c->total.expands.v = _evas_object_table_count_expands
(c->expands.v, 0, priv->size.rows);
/* handle horizontal */
if ((c->total.expands.h <= 0) || (c->total.min.w >= w))
{
- x += (w - c->total.min.w) * priv->align.h;
- w = c->total.min.w;
- cols = c->sizes.h;
+ x += (w - c->total.min.w) * priv->align.h;
+ w = c->total.min.w;
+ cols = c->sizes.h;
}
else
{
- int size = priv->size.cols * sizeof(Evas_Coord);
- cols = malloc(size);
- if (!cols)
- {
- ERR("Could not allocate temp columns (%d bytes): %s",
+ int size = priv->size.cols * sizeof(Evas_Coord);
+ cols = malloc(size);
+ if (!cols)
+ {
+ ERR("Could not allocate temp columns (%d bytes): %s",
size, strerror(errno));
goto end;
- }
- memcpy(cols, c->sizes.h, size);
- _evas_object_table_sizes_calc_expand
- (cols, 0, priv->size.cols, w - c->total.min.w,
- c->expands.h, c->total.expands.h, c->weights.h, c->total.weights.h);
+ }
+ memcpy(cols, c->sizes.h, size);
+ _evas_object_table_sizes_calc_expand
+ (cols, 0, priv->size.cols, w - c->total.min.w,
+ c->expands.h, c->total.expands.h, c->weights.h, c->total.weights.h);
}
/* handle vertical */
if ((c->total.expands.v <= 0) || (c->total.min.h >= h))
{
- y += (h - c->total.min.h) * priv->align.v;
- h = c->total.min.h;
- rows = c->sizes.v;
+ y += (h - c->total.min.h) * priv->align.v;
+ h = c->total.min.h;
+ rows = c->sizes.v;
}
else
{
- int size = priv->size.rows * sizeof(Evas_Coord);
- rows = malloc(size);
- if (!rows)
- {
- ERR("could not allocate temp rows (%d bytes): %s",
+ int size = priv->size.rows * sizeof(Evas_Coord);
+ rows = malloc(size);
+ if (!rows)
+ {
+ ERR("could not allocate temp rows (%d bytes): %s",
size, strerror(errno));
- goto end;
- }
- memcpy(rows, c->sizes.v, size);
- _evas_object_table_sizes_calc_expand
- (rows, 0, priv->size.rows, h - c->total.min.h,
- c->expands.v, c->total.expands.v, c->weights.v, c->total.weights.v);
+ goto end;
+ }
+ memcpy(rows, c->sizes.v, size);
+ _evas_object_table_sizes_calc_expand
+ (rows, 0, priv->size.rows, h - c->total.min.h,
+ c->expands.v, c->total.expands.v, c->weights.v, c->total.weights.v);
}
EINA_LIST_FOREACH(priv->children, l, opt)
{
- Evas_Object *child = opt->obj;
- Evas_Coord cx, cy, cw, ch;
+ Evas_Object *child = opt->obj;
+ Evas_Coord cx, cy, cw, ch;
- cx = x + opt->col * (priv->pad.h);
- cx += _evas_object_table_sum_sizes(cols, 0, opt->col);
- cw = _evas_object_table_sum_sizes(cols, opt->col, opt->end_col);
+ cx = x + opt->col * (priv->pad.h);
+ cx += _evas_object_table_sum_sizes(cols, 0, opt->col);
+ cw = _evas_object_table_sum_sizes(cols, opt->col, opt->end_col);
- cy = y + opt->row * (priv->pad.v);
- cy += _evas_object_table_sum_sizes(rows, 0, opt->row);
- ch = _evas_object_table_sum_sizes(rows, opt->row, opt->end_row);
+ cy = y + opt->row * (priv->pad.v);
+ cy += _evas_object_table_sum_sizes(rows, 0, opt->row);
+ ch = _evas_object_table_sum_sizes(rows, opt->row, opt->end_row);
- _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
+ _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
if (priv->is_mirrored)
{
{
evas_object_move(child, cx, cy);
}
- evas_object_resize(child, cw, ch);
+ evas_object_resize(child, cw, ch);
}
end:
}
EVAS_SMART_SUBCLASS_NEW("Evas_Object_Table", _evas_object_table,
- Evas_Smart_Class, Evas_Smart_Class,
- evas_object_smart_clipped_class_get, NULL)
+ Evas_Smart_Class, Evas_Smart_Class,
+ evas_object_smart_clipped_class_get, NULL)
static void
_evas_object_table_smart_add(Evas_Object *o)
l = priv->children;
while (l)
{
- Evas_Object_Table_Option *opt = l->data;
- _evas_object_table_child_disconnect(o, opt->obj);
- _evas_object_table_option_del(opt->obj);
- free(opt);
- l = eina_list_remove_list(l, l);
+ Evas_Object_Table_Option *opt = l->data;
+ _evas_object_table_child_disconnect(o, opt->obj);
+ _evas_object_table_option_del(opt->obj);
+ free(opt);
+ l = eina_list_remove_list(l, l);
}
if (priv->cache)
if ((priv->size.cols < 1) || (priv->size.rows < 1))
{
- DBG("Nothing to do: cols=%d, rows=%d",
- priv->size.cols, priv->size.rows);
- return;
+ DBG("Nothing to do: cols=%d, rows=%d",
+ priv->size.cols, priv->size.rows);
+ return;
}
if (priv->homogeneous)
EVAS_OBJECT_TABLE_DATA_GET(o, priv);
if (priv)
{
- if (horizontal) *horizontal = priv->align.h;
- if (vertical) *vertical = priv->align.v;
+ if (horizontal) *horizontal = priv->align.h;
+ if (vertical) *vertical = priv->align.v;
}
else
{
- if (horizontal) *horizontal = 0.5;
- if (vertical) *vertical = 0.5;
+ if (horizontal) *horizontal = 0.5;
+ if (vertical) *vertical = 0.5;
}
}
EVAS_OBJECT_TABLE_DATA_GET(o, priv);
if (priv)
{
- if (horizontal) *horizontal = priv->pad.h;
- if (vertical) *vertical = priv->pad.v;
+ if (horizontal) *horizontal = priv->pad.h;
+ if (vertical) *vertical = priv->pad.v;
}
else
{
- if (horizontal) *horizontal = 0;
- if (vertical) *vertical = 0;
+ if (horizontal) *horizontal = 0;
+ if (vertical) *vertical = 0;
}
}
EAPI Eina_Bool
-evas_object_table_pack_get(Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan)
+evas_object_table_pack_get(const Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan)
{
Evas_Object_Table_Option *opt;
if (rowspan < 1)
{
- ERR("rowspan < 1");
- return EINA_FALSE;
+ ERR("rowspan < 1");
+ return EINA_FALSE;
}
if (colspan < 1)
{
- ERR("colspan < 1");
- return EINA_FALSE;
+ ERR("colspan < 1");
+ return EINA_FALSE;
}
opt = _evas_object_table_option_get(child);
opt->rowspan = rowspan;
opt->end_col = col + colspan;
opt->end_row = row + rowspan;
-
+
if (evas_object_smart_parent_get(child) == o)
{
Eina_Bool need_shrink = EINA_FALSE;
-
+
if (priv->size.cols < opt->end_col)
- priv->size.cols = opt->end_col;
+ priv->size.cols = opt->end_col;
else
- need_shrink = EINA_TRUE;
+ need_shrink = EINA_TRUE;
if (priv->size.rows < opt->end_row)
- priv->size.rows = opt->end_row;
+ priv->size.rows = opt->end_row;
else
need_shrink = EINA_TRUE;
Eina_List *l;
Evas_Object_Table_Option *opt2;
int max_row = 0, max_col = 0;
-
+
EINA_LIST_FOREACH(priv->children, l, opt2)
{
if (max_col < opt2->end_col) max_col = opt2->end_col;
opt->expand_v = 0;
priv->children = eina_list_append(priv->children, opt);
-
+
if (priv->size.cols < opt->end_col)
- priv->size.cols = opt->end_col;
+ priv->size.cols = opt->end_col;
if (priv->size.rows < opt->end_row)
- priv->size.rows = opt->end_row;
-
+ priv->size.rows = opt->end_row;
+
_evas_object_table_option_set(child, opt);
evas_object_smart_member_add(child, o);
_evas_object_table_child_connect(o, child);
l = priv->children;
while (l)
{
- Evas_Object_Table_Option *cur_opt = l->data;
-
- if (cur_opt != opt)
- {
- if (max_col < cur_opt->end_col)
- max_col = cur_opt->end_col;
- if (max_row < cur_opt->end_row)
- max_row = cur_opt->end_row;
-
- l = l->next;
- }
- else
- {
- Eina_List *tmp = l->next;
- priv->children = eina_list_remove_list(priv->children, l);
-
- if ((priv->size.cols > opt->end_col) &&
- (priv->size.rows > opt->end_row))
- break;
- else
- {
- was_greatest = 1;
- l = tmp;
- }
- }
+ Evas_Object_Table_Option *cur_opt = l->data;
+
+ if (cur_opt != opt)
+ {
+ if (max_col < cur_opt->end_col)
+ max_col = cur_opt->end_col;
+ if (max_row < cur_opt->end_row)
+ max_row = cur_opt->end_row;
+
+ l = l->next;
+ }
+ else
+ {
+ Eina_List *tmp = l->next;
+ priv->children = eina_list_remove_list(priv->children, l);
+
+ if ((priv->size.cols > opt->end_col) &&
+ (priv->size.rows > opt->end_row))
+ break;
+ else
+ {
+ was_greatest = 1;
+ l = tmp;
+ }
+ }
}
if (was_greatest)
{
- priv->size.cols = max_col;
- priv->size.rows = max_row;
+ priv->size.cols = max_col;
+ priv->size.rows = max_row;
}
}
if (o != evas_object_smart_parent_get(child))
{
- ERR("cannot unpack child from incorrect table!");
- return EINA_FALSE;
+ ERR("cannot unpack child from incorrect table!");
+ return EINA_FALSE;
}
opt = _evas_object_table_option_del(child);
if (!opt)
{
- ERR("cannot unpack child with no packing option!");
- return EINA_FALSE;
+ ERR("cannot unpack child with no packing option!");
+ return EINA_FALSE;
}
_evas_object_table_child_disconnect(o, child);
EINA_LIST_FREE(priv->children, opt)
{
- _evas_object_table_child_disconnect(o, opt->obj);
- _evas_object_table_option_del(opt->obj);
- evas_object_smart_member_del(opt->obj);
- if (clear)
- evas_object_del(opt->obj);
- free(opt);
+ _evas_object_table_child_disconnect(o, opt->obj);
+ _evas_object_table_option_del(opt->obj);
+ evas_object_smart_member_del(opt->obj);
+ if (clear)
+ evas_object_del(opt->obj);
+ free(opt);
}
priv->size.cols = 0;
priv->size.rows = 0;
EVAS_OBJECT_TABLE_DATA_GET(o, priv);
if (priv)
{
- if (cols) *cols = priv->size.cols;
- if (rows) *rows = priv->size.rows;
+ if (cols) *cols = priv->size.cols;
+ if (rows) *rows = priv->size.rows;
}
else
{
- if (cols) *cols = -1;
- if (rows) *rows = -1;
+ if (cols) *cols = -1;
+ if (rows) *rows = -1;
}
}
_evas_object_text_horiz_advance_get(const Evas_Object *obj,
const Evas_Object_Text *o)
{
- Evas_Object_Text_Item *it;
+ Evas_Object_Text_Item *it, *last_it = NULL;
Evas_Coord adv;
(void) obj;
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
{
adv += it->adv;
+ last_it = it;
}
+
+ if (last_it && (last_it->w > last_it->adv))
+ adv += last_it->w - last_it->adv;
return adv;
}
obj->layer->evas->pointer.y, 1, 1);
}
-#ifdef EVAS_FRAME_QUEUING
- if (o->font)
- evas_common_pipe_op_text_flush((RGBA_Font *) o->font);
-#endif
-
/* DO IT */
if (o->font)
{
{
ENFN->font_text_props_info_create(ENDT,
fi, str + pos, &it->text_props,
- o->bidi_par_props, it->text_pos, len);
+ o->bidi_par_props, it->text_pos, len, EVAS_TEXT_PROPS_MODE_SHAPE);
ENFN->font_string_size_get(ENDT,
o->font,
Evas_Object_Text *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_text", Evas_Object_Text, 128, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_text", Evas_Object_Text, 8, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Text);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Text);
obj->cur.geometry.x + x + sl + ox + it->x, \
obj->cur.geometry.y + y + st + oy + \
(int) \
- (((o->max_ascent * obj->cur.geometry.h) / obj->cur.geometry.h) - 0.5), \
+ (((o->max_ascent * obj->cur.geometry.h) / obj->cur.geometry.h)), \
obj->cur.geometry.w, \
obj->cur.geometry.h, \
obj->cur.geometry.w, \
o = (Evas_Object_Text *)(obj->object_data);
if (!o->font) return;
-#ifdef EVAS_FRAME_QUEUING
- evas_common_pipe_op_text_flush((RGBA_Font *) o->font);
-#endif
evas_font_load_hinting_set(obj->layer->evas, o->font,
obj->layer->evas->hinting);
was = evas_object_is_in_output_rect(obj,
((ch) == _TAB) || \
((ch) == _PARAGRAPH_SEPARATOR))
+#ifdef CRITICAL
+#undef CRITICAL
+#endif
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#define TB_NULL_CHECK(null_check, ...) \
+ do \
+ { \
+ if (!null_check) \
+ { \
+ ERR("%s is NULL while it shouldn't be, please notify developers.", #null_check); \
+ return __VA_ARGS__; \
+ } \
+ } \
+ while(0)
+
/* private struct for textblock object internal data */
/**
* @internal
static Eina_Bool _evas_textblock_cursor_is_at_the_end(const Evas_Textblock_Cursor *cur);
static void _evas_textblock_node_text_remove(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *n);
-static void _evas_textblock_node_text_remove_formats_between(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *n, int start, int end);
static Evas_Object_Textblock_Node_Format *_evas_textblock_cursor_node_format_before_or_at_pos_get(const Evas_Textblock_Cursor *cur);
static size_t _evas_textblock_node_format_pos_get(const Evas_Object_Textblock_Node_Format *fmt);
static void _evas_textblock_node_format_remove(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Format *n, int visual_adjustment);
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
dx = 1;
+ break;
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP:
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
default:
{
c->ENFN->font_text_props_info_create(c->ENDT,
cur_fi, str, &ti->text_props, c->par->bidi_props,
- ti->parent.text_pos, run_len);
+ ti->parent.text_pos, run_len, EVAS_TEXT_PROPS_MODE_SHAPE);
}
str += run_len;
script_len -= run_len;
c->ENFN->font_text_props_info_create(c->ENDT,
cur_fi, _ellip_str, &ellip_ti->text_props,
- c->par->bidi_props, ellip_ti->parent.text_pos, len);
+ c->par->bidi_props, ellip_ti->parent.text_pos, len, EVAS_TEXT_PROPS_MODE_SHAPE);
}
_text_item_update_sizes(c, ellip_ti);
evas_textblock_escape_string_get(const char *escape)
{
/* & -> & */
+ if (!escape) return NULL;
return _escaped_char_get(escape, escape + strlen(escape));
}
EAPI const char *
evas_textblock_escape_string_range_get(const char *escape_start, const char *escape_end)
{
+ if ((!escape_start) || (!escape_end)) return NULL;
return _escaped_char_get(escape_start, escape_end);
}
EAPI const char *
evas_textblock_string_escape_get(const char *string, int *len_ret)
{
+ if ((!string) || (!len_ret)) return NULL;
/* & -> & */
return _escaped_char_match(string, len_ret);
}
EAPI void
evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text)
{
+ if (!cur) return;
Evas_Object *obj = cur->obj;
TB_HEAD();
if (text)
Evas_Object_Textblock_Node_Format *fnode;
Eina_Unicode *text_base, *text;
int off;
+ int len;
/* For each text node to thorugh all of it's format nodes
* append text from the start to the offset of the next format
* this is the core algorithm of the layout mechanism.
* Skip the unicode replacement chars when there are because
* we don't want to print them. */
+ len = (int) eina_ustrbuf_length_get(n->unicode);
text_base = text =
- eina_unicode_strndup(eina_ustrbuf_string_get(n->unicode),
- eina_ustrbuf_length_get(n->unicode));
+ eina_unicode_strndup(eina_ustrbuf_string_get(n->unicode), len);
fnode = n->format_node;
off = 0;
while (fnode && (fnode->text_node == n))
{
Eina_Unicode tmp_ch;
off += fnode->offset;
+
+ if (off > len) break;
/* No need to skip on the first run */
tmp_ch = text[off];
text[off] = 0; /* Null terminate the part of the string */
Evas_Object_Textblock_Node_Format *itr;
int position = 0;
- if (!cur->node) return NULL;
+ TB_NULL_CHECK(cur->node, NULL);
node = cur->node->format_node;
if (!node) return NULL;
Evas_Object_Textblock_Node_Format *itr;
size_t position = 0;
- if (!cur->node) return NULL;
+ TB_NULL_CHECK(cur->node, NULL);
node = cur->node->format_node;
if (!node) return NULL;
EAPI const Evas_Object_Textblock_Node_Format *
evas_textblock_node_format_next_get(const Evas_Object_Textblock_Node_Format *n)
{
+ if (!n) return NULL;
return _NODE_FORMAT(EINA_INLIST_GET(n)->next);
}
EAPI const Evas_Object_Textblock_Node_Format *
evas_textblock_node_format_prev_get(const Evas_Object_Textblock_Node_Format *n)
{
+ if (!n) return NULL;
return _NODE_FORMAT(EINA_INLIST_GET(n)->prev);
}
evas_textblock_cursor_paragraph_next(Evas_Textblock_Cursor *cur)
{
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
/* If there is a current text node, return the next text node (if exists)
* otherwise, just return False. */
if (cur->node)
{
Evas_Object_Textblock_Node_Text *node;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
/* If the current node is a text node, just get the prev if any,
* if it's a format, get the current text node out of the format and return
* the prev text node if any. */
Evas_Object_Textblock_Node_Format *node;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
/* If the current node is a format node, just get the next if any,
* if it's a text, get the current format node out of the text and return
* the next format node if any. */
{
const Evas_Object_Textblock_Node_Format *node;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
node = evas_textblock_cursor_format_get(cur);
if (!node)
{
#endif
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
text = eina_ustrbuf_string_get(cur->node->unicode);
#endif
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
text = eina_ustrbuf_string_get(cur->node->unicode);
const Eina_Unicode *text;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
ind = cur->pos;
text = eina_ustrbuf_string_get(cur->node->unicode);
evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
{
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
if (cur->pos != 0)
{
int ind;
if (!cur) return;
- if (!cur->node) return;
+ TB_NULL_CHECK(cur->node);
ind = eina_ustrbuf_length_get(cur->node->unicode);
/* If it's not the last paragraph, go back one, because we want to point
* to the PS, not the NULL */
Evas_Object_Textblock_Item *it = NULL;
if (!cur) return;
- if (!cur->node) return;
+ TB_NULL_CHECK(cur->node);
o = (Evas_Object_Textblock *)(cur->obj->object_data);
if (!o->formatted.valid) _relayout(cur->obj);
Evas_Object_Textblock_Item *it = NULL;
if (!cur) return;
- if (!cur->node) return;
+ TB_NULL_CHECK(cur->node);
o = (Evas_Object_Textblock *)(cur->obj->object_data);
if (!o->formatted.valid) _relayout(cur->obj);
int use_end = 1;
int delta = 0;
int first = 1;
- int update_format_node;
size_t pos = 0;
int orig_end;
return EINA_FALSE;
}
- update_format_node = ((itr == n->format_node) && (new_node != n));
delta = orig_end - pos;
itr->offset -= pos - start;
}
last_node->text_node = new_node;
- if (update_format_node)
- {
- n->format_node = last_node;
- }
}
return EINA_FALSE;
/**
* @internal
- * Removes all the format nodes between start and end in the text node n.
- * This function updates the offset of the next format node and the
- * text nodes pointing to it. if end == -1 end means the end of the string.
- *
- * @param o the textblock object.
- * @param n the text node the positinos refer to.
- * @param start the start of where to delete from.
- * @param end the end of the section to delete, if end == -1 it means the end of the string.
- */
-static void
-_evas_textblock_node_text_remove_formats_between(Evas_Object_Textblock *o,
- Evas_Object_Textblock_Node_Text *n, int start, int end)
-{
- Evas_Object_Textblock_Node_Format *itr;
- int use_end = 1;
- int offset = end - start;
- itr = n->format_node;
-
- if (itr)
- start -= itr->offset;
- if (offset < 0) offset = 0;
- if (end < 0) use_end = 0;
- while (itr && (itr->text_node == n))
- {
- Evas_Object_Textblock_Node_Format *nnode;
- int tmp_offset = 0;
-
- /* start is negative when this gets relevant */
- if ((offset + start < 0) && use_end)
- {
- break;
- }
- nnode = _NODE_FORMAT(EINA_INLIST_GET(itr)->next);
- if (nnode)
- {
- tmp_offset = nnode->offset;
- }
- if (start <= 0)
- {
- /* Don't do visible adjustments because we are removing the visual
- * chars anyway and taking those into account */
- _evas_textblock_node_format_remove(o, itr, 0);
- }
- start -= tmp_offset;
- itr = nnode;
- }
-}
-
-/**
- * @internal
* Returns the first format in the range between start and end in the textblock
* n.
*
size_t npos = 0;
if (!cur) return -1;
- if (!cur->node) return 0;
+ TB_NULL_CHECK(cur->node, 0);
o = (Evas_Object_Textblock *)(cur->obj->object_data);
n = o->text_nodes;
while (n != cur->node)
int len;
/*append is essentially prepend without advancing */
len = evas_textblock_cursor_text_append(cur, _text);
+ if (len == 0) return 0;
cur->pos += len; /*Advance */
return len;
}
const Eina_Unicode *text;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
text = eina_ustrbuf_string_get(cur->node->unicode);
+ if ((cur->pos - 1) > eina_ustrbuf_length_get(cur->node->unicode)) return EINA_FALSE;
return ((text[cur->pos] == 0) && (!EINA_INLIST_GET(cur->node)->next)) ?
EINA_TRUE : EINA_FALSE;
}
if (n1 == n2)
{
+ Evas_Object_Textblock_Node_Format *remove_format = NULL;
+ Evas_Object_Textblock_Node_Text *merge_node = NULL;
if ((cur1->pos == 0) &&
(cur2->pos == eina_ustrbuf_length_get(n1->unicode)))
{
- _evas_textblock_node_text_remove_formats_between(o, n1, 0, -1);
+ /* Remove the whole node. */
+ Evas_Object_Textblock_Node_Text *n =
+ _NODE_TEXT(EINA_INLIST_GET(n1)->next);
+ if (n)
+ {
+ should_merge = EINA_TRUE;
+ }
+ else
+ {
+ n = _NODE_TEXT(EINA_INLIST_GET(n1)->prev);
+ if (n)
+ {
+ merge_node = n;
+ remove_format = merge_node->format_node;
+ }
+ else
+ {
+ /* Clear the whole textblock - do it nicer. */
+ evas_object_textblock_text_markup_set(cur1->obj, "");
+ return;
+ }
+ }
}
else
{
}
eina_ustrbuf_remove(n1->unicode, cur1->pos, cur2->pos);
_evas_textblock_cursors_update_offset(cur1, cur1->node, cur1->pos, - (cur2->pos - cur1->pos));
+ if (merge_node)
+ {
+ _evas_textblock_node_text_adjust_offsets_to_start(o, n1,
+ 0, -1);
+ _evas_textblock_nodes_merge(o, merge_node);
+ evas_textblock_cursor_set_at_format(cur1, remove_format);
+ }
}
else
{
Evas_Object_Textblock_Node_Text *nnode;
nnode = _NODE_TEXT(EINA_INLIST_GET(n)->next);
- _evas_textblock_cursors_set_node(o, n, n1);
- _evas_textblock_node_text_remove(o, n);
+ _evas_textblock_node_text_adjust_offsets_to_start(o, n, 0, -1);
+ _evas_textblock_nodes_merge(o, n1);
n = nnode;
}
should_merge = _evas_textblock_node_text_adjust_offsets_to_start(o, n2,
eina_ustrbuf_remove(n2->unicode, 0, cur2->pos);
/* Merge the nodes because we removed the PS */
_evas_textblock_cursors_update_offset(cur1, cur1->node, cur1->pos,
- - cur1->pos);
- _evas_textblock_cursors_update_offset(cur2, cur2->node, 0, - cur2->pos);
+ -cur1->pos);
+ _evas_textblock_cursors_update_offset(cur2, cur2->node, 0, -cur2->pos);
+ cur2->pos = 0;
_evas_textblock_nodes_merge(o, n1);
}
fnode = _evas_textblock_cursor_node_format_at_pos_get(cur1);
+ n1 = cur1->node;
+ n2 = cur2->node;
n1->dirty = n2->dirty = EINA_TRUE;
+
if (should_merge)
{
/* We call this function instead of the cursor one because we already
EAPI Eina_List *
evas_textblock_cursor_range_formats_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
{
- Evas_Object *obj = cur1->obj;
+ Evas_Object *obj;
Eina_List *ret = NULL;
Evas_Object_Textblock_Node_Text *n1, *n2;
Evas_Object_Textblock_Node_Format *first, *last;
- TB_HEAD_RETURN(NULL);
if (!cur1 || !cur1->node) return NULL;
if (!cur2 || !cur2->node) return NULL;
if (cur1->obj != cur2->obj) return NULL;
+
+ obj = cur1->obj;
+ TB_HEAD_RETURN(NULL);
+
if (evas_textblock_cursor_compare(cur1, cur2) > 0)
{
const Evas_Textblock_Cursor *tc;
{
Evas_Textblock_Cursor cur1, cur2;
if (!cur) return NULL;
- if (!cur->node) return NULL;
+ TB_NULL_CHECK(cur->node, NULL);
if (cur->node->utf8)
{
free(cur->node->utf8);
{
int len;
if (!cur) return -1;
- if (!cur->node) return -1;
+ TB_NULL_CHECK(cur->node, -1);
len = eina_ustrbuf_length_get(cur->node->unicode);
if (EINA_INLIST_GET(cur->node)->next)
evas_textblock_cursor_format_get(const Evas_Textblock_Cursor *cur)
{
if (!cur) return NULL;
- if (!cur->node) return NULL;
+ TB_NULL_CHECK(cur->node, NULL);
return _evas_textblock_cursor_node_format_at_pos_get(cur);
}
const Eina_Unicode *text;
if (!cur) return EINA_FALSE;
- if (!cur->node) return EINA_FALSE;
+ TB_NULL_CHECK(cur->node, EINA_FALSE);
if (!evas_textblock_cursor_is_format(cur)) return EINA_FALSE;
text = eina_ustrbuf_string_get(cur->node->unicode);
return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]);
const Evas_Textblock_Cursor *dir_cur;
Evas_Textblock_Cursor cur2;
Evas_Object_Textblock *o;
+ if (!cur) return -1;
o = (Evas_Object_Textblock *)(cur->obj->object_data);
if (!o->formatted.valid) _relayout(cur->obj);
EAPI int
evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
{
+ if (!cur) return -1;
return _evas_textblock_cursor_char_pen_geometry_common_get(
cur->ENFN->font_char_coords_get, cur, cx, cy, cw, ch);
}
EAPI int
evas_textblock_cursor_pen_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
{
+ if (!cur) return -1;
return _evas_textblock_cursor_char_pen_geometry_common_get(
cur->ENFN->font_pen_coords_get, cur, cx, cy, cw, ch);
}
Evas_Object_Textblock *o;
/* alloc obj private data */
- EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_textblock", Evas_Object_Textblock, 64, NULL);
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_textblock", Evas_Object_Textblock, 8, NULL);
o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Textblock);
if (!o) return NULL;
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Textblock);
Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
if (ti->parent.format->font.font)
{
-#ifdef EVAS_FRAME_QUEUING
- evas_common_pipe_op_text_flush((RGBA_Font *) ti->parent.format->font.font);
-#endif
evas_font_load_hinting_set(obj->layer->evas,
ti->parent.format->font.font,
obj->layer->evas->hinting);
--- /dev/null
+#include "evas_common.h" /* Includes evas_bidi_utils stuff. */
+#include "evas_private.h"
+
+/* save typing */
+#define ENFN obj->layer->evas->engine.func
+#define ENDT obj->layer->evas->engine.data.output
+
+/* private magic number for text objects */
+static const char o_type[] = "textgrid";
+
+/* private struct for line object internal data */
+typedef struct _Evas_Object_Textgrid Evas_Object_Textgrid;
+typedef struct _Evas_Object_Textgrid_Cell Evas_Object_Textgrid_Cell;
+typedef struct _Evas_Object_Textgrid_Color Evas_Object_Textgrid_Color;
+
+typedef struct _Evas_Object_Textgrid_Row Evas_Object_Textgrid_Row;
+typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect;
+typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text;
+typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line;
+
+struct _Evas_Object_Textgrid
+{
+ DATA32 magic;
+
+ struct {
+ int w, h;
+ int char_width;
+ int char_height;
+ Evas_Object_Textgrid_Row *rows;
+ Evas_Textgrid_Cell *cells;
+
+ const char *font_source;
+ const char *font_name;
+ Evas_Font_Size font_size;
+ Evas_Font_Description *font_description;
+
+ Eina_Array *palette_standard;
+ Eina_Array *palette_extended;
+ } cur, prev;
+
+ int max_ascent;
+
+ Evas_Font_Set *font;
+
+ unsigned int changed : 1;
+ unsigned int core_change : 1;
+ unsigned int row_change : 1;
+ unsigned int pal_change : 1;
+};
+
+struct _Evas_Object_Textgrid_Color
+{
+ unsigned char r, g, b, a;
+};
+
+struct _Evas_Object_Textgrid_Row
+{
+ int ch1, ch2; // change region, -1 == none
+ int rects_num, texts_num, lines_num;
+ int rects_alloc, texts_alloc, lines_alloc;
+ Evas_Object_Textgrid_Rect *rects; // rects + colors
+ Evas_Object_Textgrid_Text *texts; // text
+ Evas_Object_Textgrid_Line *lines; // underlines, strikethroughs
+};
+
+struct _Evas_Object_Textgrid_Rect
+{
+ unsigned char r, g, b, a;
+ int x, w;
+};
+
+struct _Evas_Object_Textgrid_Text
+{
+ unsigned char r, g, b, a;
+ int x;
+ Evas_Text_Props text_props;
+};
+
+struct _Evas_Object_Textgrid_Line
+{
+ unsigned char r, g, b, a;
+ int x, w, y;
+};
+
+/* private methods for textgrid objects */
+static void evas_object_textgrid_init(Evas_Object *obj);
+static void *evas_object_textgrid_new(void);
+static void evas_object_textgrid_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
+static void evas_object_textgrid_free(Evas_Object *obj);
+static void evas_object_textgrid_render_pre(Evas_Object *obj);
+static void evas_object_textgrid_render_post(Evas_Object *obj);
+
+static unsigned int evas_object_textgrid_id_get(Evas_Object *obj);
+static unsigned int evas_object_textgrid_visual_id_get(Evas_Object *obj);
+static void *evas_object_textgrid_engine_data_get(Evas_Object *obj);
+
+static int evas_object_textgrid_is_opaque(Evas_Object *obj);
+static int evas_object_textgrid_was_opaque(Evas_Object *obj);
+
+static void evas_object_textgrid_scale_update(Evas_Object *obj);
+
+static const Evas_Object_Func object_func =
+{
+ /* methods (compulsory) */
+ evas_object_textgrid_free,
+ evas_object_textgrid_render,
+ evas_object_textgrid_render_pre,
+ evas_object_textgrid_render_post,
+ evas_object_textgrid_id_get,
+ evas_object_textgrid_visual_id_get,
+ evas_object_textgrid_engine_data_get,
+ /* these are optional. NULL = nothing */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ evas_object_textgrid_is_opaque,
+ evas_object_textgrid_was_opaque,
+ NULL,
+ NULL,
+ NULL,
+ evas_object_textgrid_scale_update,
+ NULL,
+ NULL,
+ NULL
+};
+
+EVAS_MEMPOOL(_mp_obj);
+
+/* all nice and private */
+static void
+evas_object_textgrid_init(Evas_Object *obj)
+{
+ /* alloc textgrid ob, setup methods and default values */
+ obj->object_data = evas_object_textgrid_new();
+ /* set up default settings for this kind of object */
+ obj->cur.color.r = 255;
+ obj->cur.color.g = 255;
+ obj->cur.color.b = 255;
+ obj->cur.color.a = 255;
+ obj->cur.geometry.x = 0;
+ obj->cur.geometry.y = 0;
+ obj->cur.geometry.w = 0;
+ obj->cur.geometry.h = 0;
+ obj->cur.layer = 0;
+ /* set up object-specific settings */
+ obj->prev = obj->cur;
+ /* set up methods (compulsory) */
+ obj->func = &object_func;
+ obj->type = o_type;
+}
+
+static void *
+evas_object_textgrid_new(void)
+{
+ Evas_Object_Textgrid *o;
+
+ /* FIXME: using evas mempool like text ? */
+ EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_textgrid", Evas_Object_Textgrid, 4, NULL);
+ o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Textgrid);
+ EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Textgrid);
+ o->magic = MAGIC_OBJ_TEXTGRID;
+ o->prev = o->cur;
+ o->cur.palette_standard = eina_array_new(16);
+ o->cur.palette_extended = eina_array_new(16);
+ return o;
+}
+
+static void
+evas_object_textgrid_row_clear(Evas_Object_Textgrid_Row *r)
+{
+ int i;
+
+ if (r->rects)
+ {
+ free(r->rects);
+ r->rects = NULL;
+ r->rects_num = 0;
+ r->rects_alloc = 0;
+ }
+ if (r->texts)
+ {
+ for (i = 0; i < r->texts_num; i++)
+ evas_common_text_props_content_unref(&(r->texts[i].text_props));
+ free(r->texts);
+ r->texts = NULL;
+ r->texts_num = 0;
+ r->texts_alloc = 0;
+ }
+ if (r->lines)
+ {
+ free(r->lines);
+ r->lines = NULL;
+ r->lines_num = 0;
+ r->lines_alloc = 0;
+ }
+}
+
+static void
+evas_object_textgrid_rows_clear(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+ int i;
+
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ if (!o->cur.rows) return;
+ for (i = 0; i < o->cur.h; i++)
+ {
+ evas_object_textgrid_row_clear(&(o->cur.rows[i]));
+ o->cur.rows[i].ch1 = 0;
+ o->cur.rows[i].ch2 = o->cur.w - 1;
+ }
+}
+
+static void
+evas_object_textgrid_free(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+ unsigned int i;
+
+ /* frees private object data. very simple here */
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ /* free obj */
+ evas_object_textgrid_rows_clear(obj);
+ if (o->cur.rows) free(o->cur.rows);
+ if (o->cur.font_name) eina_stringshare_del(o->cur.font_name);
+ if (o->cur.font_source) eina_stringshare_del(o->cur.font_source);
+ if (o->cur.font_description) evas_font_desc_unref(o->cur.font_description);
+ if (o->font) evas_font_free(obj->layer->evas, o->font);
+ if (o->cur.cells) free(o->cur.cells);
+ for (i = 0; i < eina_array_count(o->cur.palette_standard); i++)
+ free(eina_array_data_get(o->cur.palette_standard, i));
+ eina_array_free(o->cur.palette_standard);
+ for (i = 0; i < eina_array_count(o->cur.palette_extended); i++)
+ free(eina_array_data_get(o->cur.palette_extended, i));
+ eina_array_free(o->cur.palette_extended);
+ o->magic = 0;
+ /* FIXME: using evas mempool like text ? */
+ EVAS_MEMPOOL_FREE(_mp_obj, o);
+}
+
+
+static void
+evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w, int r, int g, int b, int a)
+{
+ row->rects_num++;
+ if (row->rects_num > row->rects_alloc)
+ {
+ Evas_Object_Textgrid_Rect *t;
+
+ row->rects_alloc += 8; // dont expect many rects per line
+ t = realloc(row->rects, sizeof(Evas_Object_Textgrid_Rect) * row->rects_alloc);
+ if (!t)
+ {
+ row->rects_num--;
+ return;
+ }
+ row->rects = t;
+ }
+ row->rects[row->rects_num - 1].x = x;
+ row->rects[row->rects_num - 1].w = w;
+ row->rects[row->rects_num - 1].r = r;
+ row->rects[row->rects_num - 1].g = g;
+ row->rects[row->rects_num - 1].b = b;
+ row->rects[row->rects_num - 1].a = a;
+}
+
+static void
+evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *obj, Evas_Object_Textgrid *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a)
+{
+ Evas_Script_Type script;
+ Evas_Font_Instance *script_fi = NULL;
+ Evas_Font_Instance *cur_fi = NULL;
+
+ row->texts_num++;
+ if (row->texts_num > row->texts_alloc)
+ {
+ Evas_Object_Textgrid_Text *t;
+
+ row->texts_alloc += 32; // expect more text per line
+ t = realloc(row->texts, sizeof(Evas_Object_Textgrid_Text) * row->texts_alloc);
+ if (!t)
+ {
+ row->texts_num--;
+ return;
+ }
+ row->texts = t;
+ }
+
+ script = evas_common_language_script_type_get(&codepoint, 1);
+ ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+ script, &codepoint, 1);
+ memset(&(row->texts[row->texts_num - 1].text_props), 0,
+ sizeof(Evas_Text_Props));
+ evas_common_text_props_script_set
+ (&(row->texts[row->texts_num - 1].text_props), script);
+ ENFN->font_text_props_info_create
+ (ENDT, script_fi, &codepoint,
+ &(row->texts[row->texts_num - 1].text_props), NULL, 0, 1,
+ EVAS_TEXT_PROPS_MODE_NONE);
+ row->texts[row->texts_num - 1].x = x;
+ row->texts[row->texts_num - 1].r = r;
+ row->texts[row->texts_num - 1].g = g;
+ row->texts[row->texts_num - 1].b = b;
+ row->texts[row->texts_num - 1].a = a;
+}
+
+static void
+evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w, int y, int r, int g, int b, int a)
+{
+ row->lines_num++;
+ if (row->lines_num > row->lines_alloc)
+ {
+ Evas_Object_Textgrid_Line *t;
+
+ row->lines_alloc += 8; // dont expect many lines per line
+ t = realloc(row->lines, sizeof(Evas_Object_Textgrid_Line) * row->lines_alloc);
+ if (!t)
+ {
+ row->lines_num--;
+ return;
+ }
+ row->lines = t;
+ }
+ row->lines[row->lines_num - 1].x = x;
+ row->lines[row->lines_num - 1].w = w;
+ row->lines[row->lines_num - 1].y = y;
+ row->lines[row->lines_num - 1].r = r;
+ row->lines[row->lines_num - 1].g = g;
+ row->lines[row->lines_num - 1].b = b;
+ row->lines[row->lines_num - 1].a = a;
+}
+
+static void
+evas_object_textgrid_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
+{
+ Evas_Object_Textgrid *o;
+ Evas_Textgrid_Cell *cells;
+ Evas_Object_Textgrid_Color *c;
+ Eina_Array *palette;
+ int xx, yy, xp, yp, w, h, ww, hh;
+ int rr = 0, rg = 0, rb = 0, ra = 0, rx = 0, rw = 0, run;
+
+ /* render object to surface with context, and offxet by x,y */
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ ENFN->context_multiplier_unset(output, context);
+ ENFN->context_render_op_set(output, context, obj->cur.render_op);
+
+ if (!(o->font) || (!o->cur.cells)) return;
+
+ w = o->cur.char_width;
+ h = o->cur.char_height;
+ ww = obj->cur.geometry.w;
+ hh = obj->cur.geometry.h;
+
+ // generate row data from cells (and only deal with rows that updated)
+ for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
+ {
+ Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
+
+ if (row->ch1 < 0)
+ {
+ cells += o->cur.w;
+ continue;
+ }
+ row->ch1 = -1;
+ row->ch2 = 0;
+ run = 0;
+ xp = obj->cur.geometry.x;
+ for (xx = 0; xx < o->cur.w; xx++, cells++)
+ {
+ if (cells->bg_extended) palette = o->cur.palette_extended;
+ else palette = o->cur.palette_standard;
+ c = eina_array_data_get(palette, cells->bg);
+ if ((c) && (c->a > 0))
+ {
+ if (!run)
+ {
+ run = 1;
+ rr = c->r;
+ rg = c->g;
+ rb = c->b;
+ ra = c->a;
+ rx = xp;
+ rw = w;
+ }
+ else if ((c->r != rr) || (c->g != rg) ||
+ (c->b != rb) || (c->a != ra))
+ {
+ evas_object_textgrid_row_rect_append(row, rx, rw,
+ rr, rg, rb, ra);
+ rr = c->r;
+ rg = c->g;
+ rb = c->b;
+ ra = c->a;
+ rx = xp;
+ rw = w;
+ }
+ else rw += w;
+ }
+ else if (run)
+ {
+ run = 0;
+ evas_object_textgrid_row_rect_append(row, rx, rw,
+ rr, rg, rb, ra);
+ }
+ if (cells->codepoint > 0)
+ {
+ if (cells->fg_extended) palette = o->cur.palette_extended;
+ else palette = o->cur.palette_standard;
+ c = eina_array_data_get(palette, cells->fg);
+ if ((c) && (c->a > 0))
+ {
+ evas_object_textgrid_row_text_append(row, obj, o, xp,
+ cells->codepoint,
+ c->r, c->g, c->b, c->a);
+ // XXX: underlines and strikethroughs dont get
+ // merghed into horizontal runs like bg rects above
+ if (cells->underline)
+ evas_object_textgrid_row_line_append(row, rx, rw,
+ o->max_ascent + 1,
+ rr, rg, rb, ra);
+ if (cells->strikethrough)
+ evas_object_textgrid_row_line_append(row, rx, rw,
+ ((3 * o->max_ascent) / 4),
+ rr, rg, rb, ra);
+ }
+ }
+ xp += w;
+ }
+ if (run)
+ {
+ run = 0;
+ evas_object_textgrid_row_rect_append(row, rx, rw,
+ rr, rg, rb, ra);
+ }
+ }
+ yp = obj->cur.geometry.y + y;
+ // draw the row data that is generated from the cell array
+ for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
+ {
+ Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
+
+ xp = obj->cur.geometry.x + x;
+ for (xx = 0; xx < row->rects_num; xx++)
+ {
+ ENFN->context_color_set(output, context,
+ row->rects[xx].r, row->rects[xx].g,
+ row->rects[xx].b, row->rects[xx].a);
+ ENFN->rectangle_draw(output, context, surface,
+ xp + row->rects[xx].x, yp,
+ row->rects[xx].w, h);
+ }
+ for (xx = 0; xx < row->texts_num; xx++)
+ {
+ ENFN->context_color_set(output, context,
+ row->texts[xx].r, row->texts[xx].g,
+ row->texts[xx].b, row->texts[xx].a);
+ ENFN->font_draw(output, context, surface, o->font,
+ xp + row->texts[xx].x, yp + o->max_ascent,
+ ww, hh, ww, hh, &(row->texts[xx].text_props));
+ }
+ for (xx = 0; xx < row->lines_num; xx++)
+ {
+ ENFN->context_color_set(output, context,
+ row->lines[xx].r, row->lines[xx].g,
+ row->lines[xx].b, row->lines[xx].a);
+ ENFN->rectangle_draw(output, context, surface,
+ xp + row->lines[xx].x, yp + row->lines[xx].y,
+ row->lines[xx].w, h);
+ }
+ yp += h;
+ }
+}
+
+static void
+evas_object_textgrid_render_pre(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+ int is_v, was_v;
+
+ /* dont pre-render the obj twice! */
+ if (obj->pre_render_done) return;
+ obj->pre_render_done = 1;
+ /* pre-render phase. this does anything an object needs to do just before */
+ /* rendering. this could mean loading the image data, retrieving it from */
+ /* elsewhere, decoding video etc. */
+ /* then when this is done the object needs to figure if it changed and */
+ /* if so what and where and add thr appropriate redraw rectangles */
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ /* if someone is clipping this obj - go calculate the clipper */
+ if (obj->cur.clipper)
+ {
+ if (obj->cur.cache.clip.dirty)
+ evas_object_clip_recalc(obj->cur.clipper);
+ obj->cur.clipper->func->render_pre(obj->cur.clipper);
+ }
+ /* now figure what changed and add draw rects */
+ /* if it just became visible or invisible */
+ is_v = evas_object_is_visible(obj);
+ was_v = evas_object_was_visible(obj);
+ if (is_v != was_v)
+ {
+ evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
+ goto done;
+ }
+ if (obj->changed_map)
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ obj);
+ goto done;
+ }
+ /* its not visible - we accounted for it appearing or not so just abort */
+ if (!is_v) goto done;
+ /* clipper changed this is in addition to anything else for obj */
+ evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj);
+ /* if we restacked (layer or just within a layer) and dont clip anyone */
+ if (obj->restack)
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ /* if it changed color */
+ if ((obj->cur.color.r != obj->prev.color.r) ||
+ (obj->cur.color.g != obj->prev.color.g) ||
+ (obj->cur.color.b != obj->prev.color.b) ||
+ (obj->cur.color.a != obj->prev.color.a))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ /* if it changed geometry - and obviously not visibility or color */
+ /* calculate differences since we have a constant color fill */
+ /* we really only need to update the differences */
+ if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
+ (obj->cur.geometry.y != obj->prev.geometry.y) ||
+ (obj->cur.geometry.w != obj->prev.geometry.w) ||
+ (obj->cur.geometry.h != obj->prev.geometry.h))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ if (obj->cur.render_op != obj->prev.render_op)
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ if (obj->cur.scale != obj->prev.scale)
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+
+ if (o->changed)
+ {
+ if (o->core_change)
+ {
+ if ((o->cur.h != o->prev.h) ||
+ (o->cur.w != o->prev.w) ||
+ (o->cur.font_size != o->prev.font_size) ||
+ ((o->cur.font_name) && (o->prev.font_name) &&
+ (strcmp(o->cur.font_name, o->prev.font_name))) ||
+ ((o->cur.font_name) && (!o->prev.font_name)) ||
+ ((!o->cur.font_name) && (o->prev.font_name)))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ obj);
+ goto done;
+ }
+ }
+ if (o->pal_change)
+ {
+ unsigned int i;
+
+ if (eina_array_count(o->cur.palette_standard) != eina_array_count(o->prev.palette_standard))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ for (i = 0; i < eina_array_count(o->cur.palette_standard); i++)
+ {
+ Evas_Object_Textgrid_Color *c_cur;
+ Evas_Object_Textgrid_Color *c_prev;
+
+ c_cur = eina_array_data_get(o->cur.palette_standard, i);
+ c_prev = eina_array_data_get(o->prev.palette_standard, i);
+ if ((c_cur->a != c_prev->a) ||
+ (c_cur->r != c_prev->r) ||
+ (c_cur->g != c_prev->g) ||
+ (c_cur->b != c_prev->b))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ }
+ if (eina_array_count(o->cur.palette_extended) != eina_array_count(o->prev.palette_extended))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ for (i = 0; i < eina_array_count(o->cur.palette_extended); i++)
+ {
+ Evas_Object_Textgrid_Color *c_cur;
+ Evas_Object_Textgrid_Color *c_prev;
+
+ c_cur = eina_array_data_get(o->cur.palette_extended, i);
+ c_prev = eina_array_data_get(o->prev.palette_extended, i);
+ if ((c_cur->a != c_prev->a) ||
+ (c_cur->r != c_prev->r) ||
+ (c_cur->g != c_prev->g) ||
+ (c_cur->b != c_prev->b))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ }
+ }
+ if (o->row_change)
+ {
+ int i;
+
+ for (i = 0; i < o->cur.h; i++)
+ {
+ Evas_Object_Textgrid_Row *r = &(o->cur.rows[i]);
+ if (r->ch1 >= 0)
+ evas_add_rect(&obj->layer->evas->clip_changes,
+ obj->cur.geometry.x +
+ (r->ch1 * o->cur.char_width),
+ obj->cur.geometry.y +
+ (i * o->cur.char_height),
+ (r->ch2 - r->ch1 + 1) * o->cur.char_width,
+ o->cur.char_height);
+ }
+ }
+ }
+
+ done:
+ o->core_change = 0;
+ o->row_change = 0;
+ o->pal_change = 0;
+ evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v);
+}
+
+static void
+evas_object_textgrid_render_post(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ /* this moves the current data to the previous state parts of the object */
+ /* in whatever way is safest for the object. also if we don't need object */
+ /* data anymore we can free it if the object deems this is a good idea */
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ /* remove those pesky changes */
+ evas_object_clip_changes_clean(obj);
+ /* move cur to prev safely for object data */
+ obj->prev = obj->cur;
+ o->prev = o->cur;
+ o->changed = 0;
+}
+
+static unsigned int
+evas_object_textgrid_id_get(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ if (!o) return 0;
+ return MAGIC_OBJ_TEXTGRID;
+}
+
+static unsigned int
+evas_object_textgrid_visual_id_get(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ if (!o) return 0;
+ return MAGIC_OBJ_SHAPE;
+}
+
+static void *
+evas_object_textgrid_engine_data_get(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ if (!o) return NULL;
+ return o->font;
+}
+
+static int
+evas_object_textgrid_is_opaque(Evas_Object *obj __UNUSED__)
+{
+ /* this returns 1 if the internal object data implies that the object is
+ currently fully opaque over the entire gradient it occupies */
+ return 0;
+}
+
+static int
+evas_object_textgrid_was_opaque(Evas_Object *obj __UNUSED__)
+{
+ /* this returns 1 if the internal object data implies that the object was
+ currently fully opaque over the entire gradient it occupies */
+ return 0;
+}
+
+static void
+evas_object_textgrid_scale_update(Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+ int font_size;
+ const char *font_name;
+
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ font_name = eina_stringshare_add(o->cur.font_name);
+ font_size = o->cur.font_size;
+ if (o->cur.font_name) eina_stringshare_del(o->cur.font_name);
+ o->cur.font_name = NULL;
+ o->prev.font_name = NULL;
+ o->cur.font_size = 0;
+ o->prev.font_size = 0;
+ evas_object_textgrid_font_set(obj, font_name, font_size);
+}
+
+/********************* LOCAL *********************/
+
+/********************* API *********************/
+
+EAPI Evas_Object *
+evas_object_textgrid_add(Evas *e)
+{
+ Evas_Object *obj;
+
+ MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+ return NULL;
+ MAGIC_CHECK_END();
+
+ obj = evas_object_new(e);
+ evas_object_textgrid_init(obj);
+ evas_object_inject(obj, e);
+ return obj;
+}
+
+EAPI void
+evas_object_textgrid_size_set(Evas_Object *obj, int w, int h)
+{
+ Evas_Object_Textgrid *o;
+ int i;
+
+ if ((h <= 0) || (w <= 0)) return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ if ((o->cur.w == w) && (o->cur.h == h)) return;
+
+ evas_object_textgrid_rows_clear(obj);
+ if (o->cur.rows)
+ {
+ free(o->cur.rows);
+ o->cur.rows = NULL;
+ }
+ if (o->cur.cells)
+ {
+ free(o->cur.cells);
+ o->cur.cells = NULL;
+ }
+ o->cur.cells = calloc(w * h, sizeof(Evas_Textgrid_Cell));
+ if (!o->cur.cells) return;
+ o->cur.rows = calloc(h, sizeof(Evas_Object_Textgrid_Row));
+ if (!o->cur.rows)
+ {
+ free(o->cur.cells);
+ o->cur.cells = NULL;
+ return;
+ }
+ for (i = 0; i < h; i++)
+ {
+ o->cur.rows[i].ch1 = 0;
+ o->cur.rows[i].ch2 = w - 1;
+ }
+ o->cur.w = w;
+ o->cur.h = h;
+ o->changed = 1;
+ o->core_change = 1;
+ evas_object_change(obj);
+}
+
+EAPI void
+evas_object_textgrid_size_get(const Evas_Object *obj, int *w, int *h)
+{
+ Evas_Object_Textgrid *o;
+
+ if (h) *h = 0;
+ if (w) *w = 0;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ if (w) *w = o->cur.w;
+ if (h) *h = o->cur.h;
+}
+
+EAPI void
+evas_object_textgrid_font_source_set(Evas_Object *obj, const char *font_source)
+{
+ Evas_Object_Textgrid *o;
+
+ if ((!font_source) || (!*font_source))
+ return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ if ((o->cur.font_source) && (font_source) &&
+ (!strcmp(o->cur.font_source, font_source))) return;
+
+ eina_stringshare_replace(&o->cur.font_source, font_source);
+ o->changed = 1;
+ o->core_change = 1;
+ evas_object_change(obj);
+}
+
+EAPI const char *
+evas_object_textgrid_font_source_get(const Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return NULL;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return NULL;
+ MAGIC_CHECK_END();
+
+ return o->cur.font_source;
+}
+
+EAPI void
+evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font_Size font_size)
+{
+ Evas_Object_Textgrid *o;
+ int is, was = 0, pass = 0, freeze = 0;
+ Evas_Font_Description *font_description;
+
+ if ((!font_name) || (!*font_name) || (font_size <= 0))
+ return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ font_description = evas_font_desc_new();
+ evas_font_name_parse(font_description, font_name);
+ if (o->cur.font_description &&
+ !evas_font_desc_cmp(font_description, o->cur.font_description) &&
+ (font_size == o->cur.font_size))
+ {
+ evas_font_desc_unref(font_description);
+ return;
+ }
+
+ if (o->cur.font_description) evas_font_desc_unref(o->cur.font_description);
+ o->cur.font_description = font_description;
+
+ o->cur.font_size = font_size;
+ eina_stringshare_replace(&o->cur.font_name, font_name);
+ o->prev.font_name = NULL;
+
+ if (obj->layer->evas->events_frozen <= 0)
+ {
+ pass = evas_event_passes_through(obj);
+ freeze = evas_event_freezes_through(obj);
+ if ((!pass) && (!freeze))
+ was = evas_object_is_in_output_rect(obj,
+ obj->layer->evas->pointer.x,
+ obj->layer->evas->pointer.y,
+ 1, 1);
+ }
+
+ /* DO IT */
+ if (o->font)
+ {
+ evas_font_free(obj->layer->evas, o->font);
+ o->font = NULL;
+ }
+
+ o->font = evas_font_load(obj->layer->evas, o->cur.font_description,
+ o->cur.font_source,
+ (int)(((double) o->cur.font_size) *
+ obj->cur.scale));
+ if (o->font)
+ {
+ Eina_Unicode W[2] = { 'W', 0 };
+ Evas_Font_Instance *script_fi = NULL;
+ Evas_Font_Instance *cur_fi = NULL;
+ Evas_Text_Props text_props;
+ Evas_Script_Type script;
+
+ script = evas_common_language_script_type_get(W, 1);
+ ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+ script, W, 1);
+ memset(&text_props, 0, sizeof(Evas_Text_Props));
+ evas_common_text_props_script_set(&text_props, script);
+ ENFN->font_text_props_info_create(ENDT, script_fi, W, &text_props,
+ NULL, 0, 1,
+ EVAS_TEXT_PROPS_MODE_NONE);
+ ENFN->font_string_size_get(ENDT, o->font, &text_props,
+ &o->cur.char_width, &o->cur.char_height);
+ o->max_ascent = ENFN->font_max_ascent_get(ENDT, o->font);
+ evas_common_text_props_content_unref(&text_props);
+ }
+ else
+ {
+ obj->cur.geometry.w = 0;
+ obj->cur.geometry.h = 0;
+ o->max_ascent = 0;
+ }
+
+ o->changed = 1;
+ evas_object_change(obj);
+ evas_object_clip_dirty(obj);
+ evas_object_coords_recalc(obj);
+ if (obj->layer->evas->events_frozen <= 0)
+ {
+ if ((!pass) && (!freeze))
+ {
+ is = evas_object_is_in_output_rect(obj,
+ obj->layer->evas->pointer.x,
+ obj->layer->evas->pointer.y,
+ 1, 1);
+ if ((is ^ was) && obj->cur.visible)
+ evas_event_feed_mouse_move(obj->layer->evas,
+ obj->layer->evas->pointer.x,
+ obj->layer->evas->pointer.y,
+ obj->layer->evas->last_timestamp,
+ NULL);
+ }
+ }
+ evas_object_inform_call_resize(obj);
+ o->changed = 1;
+ o->core_change = 1;
+ evas_object_textgrid_rows_clear(obj);
+ evas_object_change(obj);
+}
+
+EAPI void
+evas_object_textgrid_font_get(const Evas_Object *obj, const char **font_name, Evas_Font_Size *font_size)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ if (font_name) *font_name = "";
+ if (font_size) *font_size = 0;
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ if (font_name) *font_name = "";
+ if (font_size) *font_size = 0;
+ return;
+ MAGIC_CHECK_END();
+
+ if (font_name) *font_name = o->cur.font_name;
+ if (font_size) *font_size = o->cur.font_size;
+}
+
+EAPI void
+evas_object_textgrid_cell_size_get(const Evas_Object *obj, int *width, int *height)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ if (width) *width = 0;
+ if (height) *height = 0;
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ if (width) *width = 0;
+ if (height) *height = 0;
+ return;
+ MAGIC_CHECK_END();
+
+ if (width) *width = o->cur.char_width;
+ if (height) *height = o->cur.char_height;
+}
+
+EAPI void
+evas_object_textgrid_palette_set(Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int r, int g, int b, int a)
+{
+ Evas_Object_Textgrid *o;
+ Eina_Array *palette;
+ Evas_Object_Textgrid_Color *color, *c;
+ int count, i;
+
+ if ((idx < 0) || (idx > 255)) return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ if (a > 255) a = 255; if (a < 0) a = 0;
+ if (r > 255) r = 255; if (r < 0) r = 0;
+ if (g > 255) g = 255; if (g < 0) g = 0;
+ if (b > 255) b = 255; if (b < 0) b = 0;
+ if (r > a)
+ {
+ r = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+ if (g > a)
+ {
+ g = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+ if (b > a)
+ {
+ b = a;
+ ERR("Evas only handles pre multiplied colors!");
+ }
+
+ switch (pal)
+ {
+ case EVAS_TEXTGRID_PALETTE_STANDARD:
+ palette = o->cur.palette_standard;
+ break;
+ case EVAS_TEXTGRID_PALETTE_EXTENDED:
+ palette = o->cur.palette_extended;
+ break;
+ default:
+ return;
+ }
+
+ color = malloc(sizeof(Evas_Object_Textgrid_Color));
+ if (!color) return;
+
+ color->a = a;
+ color->r = r;
+ color->g = g;
+ color->b = b;
+
+ count = eina_array_count(palette);
+ if (idx < count) eina_array_data_set(palette, idx, color);
+ else if (idx == count) eina_array_push(palette, color);
+ else
+ {
+ for (i = count; i < idx; i++)
+ {
+ c = calloc(1, sizeof(Evas_Object_Textgrid_Color));
+ if (!c)
+ {
+ ERR("Evas can not allocate memory");
+ return;
+ }
+ eina_array_push(palette, c);
+ }
+ eina_array_push(palette, color);
+ }
+ o->changed = 1;
+ o->pal_change = 1;
+ evas_object_textgrid_rows_clear(obj);
+ evas_object_change(obj);
+}
+
+EAPI void
+evas_object_textgrid_palette_get(const Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int *r, int *g, int *b, int *a)
+{
+ Evas_Object_Textgrid *o;
+ Eina_Array *palette;
+ Evas_Object_Textgrid_Color *color;
+
+ if (idx < 0) return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ if (a) *a = 0;
+ if (r) *r = 0;
+ if (g) *g = 0;
+ if (b) *b = 0;
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ if (a) *a = 0;
+ if (r) *r = 0;
+ if (g) *g = 0;
+ if (b) *b = 0;
+ return;
+ MAGIC_CHECK_END();
+
+ switch (pal)
+ {
+ case EVAS_TEXTGRID_PALETTE_STANDARD:
+ palette = o->cur.palette_standard;
+ break;
+ case EVAS_TEXTGRID_PALETTE_EXTENDED:
+ palette = o->cur.palette_extended;
+ break;
+ default:
+ return;
+ }
+
+ if (idx >= (int)eina_array_count(palette)) return;
+ color = eina_array_data_get(palette, idx);
+ if (!color) return;
+
+ if (a) *a = color->a;
+ if (r) *r = color->r;
+ if (g) *g = color->g;
+ if (b) *b = color->b;
+}
+
+
+EAPI void
+evas_object_textgrid_supported_font_styles_set(Evas_Object *obj, Evas_Textgrid_Font_Style styles)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ /* FIXME: to do */
+ if (styles)
+ {
+ o->changed = 1;
+ evas_object_change(obj);
+ }
+}
+
+EAPI Evas_Textgrid_Font_Style
+evas_object_textgrid_supported_font_styles_get(const Evas_Object *obj)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return EVAS_TEXTGRID_FONT_STYLE_NORMAL;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return EVAS_TEXTGRID_FONT_STYLE_NORMAL;
+ MAGIC_CHECK_END();
+
+ /* FIXME: to do */
+ return 0;
+}
+
+EAPI void
+evas_object_textgrid_cellrow_set(Evas_Object *obj, int y, const Evas_Textgrid_Cell *row)
+{
+ Evas_Object_Textgrid *o;
+
+ if (!row) return;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ if ((y < 0) || (y >= o->cur.h)) return;
+}
+
+EAPI Evas_Textgrid_Cell *
+evas_object_textgrid_cellrow_get(const Evas_Object *obj, int y)
+{
+ Evas_Object_Textgrid *o;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return NULL;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return NULL;
+ MAGIC_CHECK_END();
+
+ if ((y < 0) || (y >= o->cur.h)) return NULL;
+
+ return o->cur.cells + (y * o->cur.w);
+}
+
+EAPI void
+evas_object_textgrid_update_add(Evas_Object *obj, int x, int y, int w, int h)
+{
+ Evas_Object_Textgrid *o;
+ int i, x2;
+
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+ o = (Evas_Object_Textgrid *)(obj->object_data);
+ MAGIC_CHECK(o, Evas_Object_Textgrid, MAGIC_OBJ_TEXTGRID);
+ return;
+ MAGIC_CHECK_END();
+
+ RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.w, o->cur.h);
+ if ((w <= 0) || (h <= 0)) return;
+
+ x2 = x + w - 1;
+ for (i = 0; i < h; i++)
+ {
+ Evas_Object_Textgrid_Row *r = &(o->cur.rows[y + i]);
+
+ if (r->ch1 < 0)
+ {
+ evas_object_textgrid_row_clear(r);
+ r->ch1 = x;
+ r->ch2 = x2;
+ }
+ else
+ {
+ if (x < r->ch1) r->ch1 = x;
+ if (x2 > r->ch2) r->ch2 = x2;
+ }
+ }
+ o->row_change = 1;
+ o->changed = 1;
+ evas_object_change(obj);
+}
#include "evas_common.h"
#include "evas_private.h"
#include <math.h>
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
// debug rendering
/* #define REND_DGB 1 */
}
static Eina_Bool
-_evas_render_has_map(Evas_Object *obj)
-{
- return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
- ((obj->cur.map) && (obj->cur.usemap)));
- // return ((obj->cur.map) && (obj->cur.usemap));
-}
-
-static Eina_Bool
_evas_render_had_map(Evas_Object *obj)
{
return ((obj->prev.map) && (obj->prev.usemap));
obj->rect_del = EINA_FALSE;
obj->render_pre = EINA_FALSE;
-#ifndef EVAS_FRAME_QUEUING
- /* because of clip objects - delete 2 cycles later */
if (obj->delete_me == 2)
-#else
- if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2)
-#endif
- eina_array_push(delete_objects, obj);
- else if (obj->delete_me != 0) obj->delete_me++;
+ eina_array_push(delete_objects, obj);
+ else if (obj->delete_me != 0) obj->delete_me++;
/* If the object will be removed, we should not cache anything during this run. */
if (obj->delete_me != 0) clean_them = EINA_TRUE;
for (i = 0; i < pending_objects->count; ++i)
{
- Evas_Object *obj, *parent;
+ Evas_Object *obj;
int is_active;
Eina_Bool ok = EINA_FALSE;
obj = eina_array_data_get(pending_objects, i);
if (!obj->layer) goto clean_stuff;
- parent = evas_object_smart_parent_get(obj);
- if (parent && _evas_render_has_map(parent))
- goto clean_stuff;
+ //If the children are in active objects, They should be cleaned up.
+ if (obj->changed_map && _evas_render_has_map(obj))
+ goto clean_stuff;
evas_object_clip_recalc(obj);
is_active = evas_object_is_active(obj);
/* This doesn't cover the area of the video object, so don't bother with that object */
if (!eina_rectangles_intersect(&zone, &self))
- continue ;
+ continue;
xc1 = current->cur.cache.clip.x;
yc1 = current->cur.cache.clip.y;
_evas_render_has_map(obj));
if (_evas_render_has_map(obj))
{
- const Evas_Map_Point *p, *p_end;
- RGBA_Map_Point pts[4], *pt;
+ RGBA_Map_Point *pts;
int sw, sh;
Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
return clean_them;
}
- pts[0].px = obj->cur.map->persp.px << FP;
- pts[0].py = obj->cur.map->persp.py << FP;
- pts[0].foc = obj->cur.map->persp.foc << FP;
- pts[0].z0 = obj->cur.map->persp.z0 << FP;
-
- p = obj->cur.map->points;
- p_end = p + obj->cur.map->count;
- pt = pts;
- for (; p < p_end; p++, pt++)
- {
- pt->x = (lround(p->x) + off_x) * FP1;
- pt->y = (lround(p->y) + off_y) * FP1;
- pt->z = (lround(p->z) ) * FP1;
- pt->fx = p->px;
- pt->fy = p->py;
- pt->fz = p->z;
- pt->u = lround(p->u) * FP1;
- pt->v = lround(p->v) * FP1;
- if (pt->u < 0) pt->u = 0;
- else if (pt->u > (sw * FP1)) pt->u = (sw * FP1);
- if (pt->v < 0) pt->v = 0;
- else if (pt->v > (sh * FP1)) pt->v = (sh * FP1);
- pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
- }
- /* Copy last for software engine */
- if (obj->cur.map->count & 0x1)
- {
- pts[obj->cur.map->count] = pts[obj->cur.map->count - 1];
- }
-
+ evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
+ pts = obj->spans->pts;
if (obj->cur.map->surface)
{
}
else
{
+ if (0 && obj->cur.cached_surface)
+ fprintf(stderr, "We should cache '%s' [%i, %i, %i, %i]\n",
+ evas_object_type_get(obj),
+ obj->cur.bounding_box.x, obj->cur.bounding_box.x,
+ obj->cur.bounding_box.w, obj->cur.bounding_box.h);
if (mapped)
{
RDI(level);
MAGIC_CHECK_END();
if (!e->changed) return NULL;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cserve2_dispatch();
+#endif
evas_call_smarts_calculate(e);
RD("[--- RENDER EVAS (size: %ix%i)\n", e->viewport.w, e->viewport.h);
}
/* phase 4. framespace, output & viewport changes */
- if (e->framespace.changed)
- {
- int fx, fy, fw, fh;
-
- fx = e->viewport.x - e->framespace.x;
- fy = e->viewport.y - e->framespace.y;
- fw = e->viewport.w + e->framespace.w;
- fh = e->viewport.h + e->framespace.h;
- e->engine.func->output_redraws_rect_add(e->engine.data.output,
- fx, fy, fw, fh);
- }
-
if (e->viewport.changed)
{
e->engine.func->output_redraws_rect_add(e->engine.data.output,
{
ERR("viewport size != output size!");
}
- if (redraw_all)
+
+ if (e->framespace.changed)
{
+ int fx, fy, fw, fh;
+
+ fx = e->viewport.x - e->framespace.x;
+ fy = e->viewport.y - e->framespace.y;
+ fw = e->viewport.w + e->framespace.w;
+ fh = e->viewport.h + e->framespace.h;
e->engine.func->output_redraws_rect_add(e->engine.data.output,
- 0, 0,
+ fx, fy, fw, fh);
+ }
+
+ /* phase 4.5: check if object is not in framespace. if not, we need to clip
+ * it to the 'master' clip.
+ *
+ * NB: This is for the wayland engine(s). If we do not do this, then
+ * objects will draw outside the viewport and potentially onto the frame
+ * itself */
+ if (!strncmp(e->engine.module->definition->name, "wayland", 7))
+ {
+ Eina_Rectangle clip_rect;
+
+ /* see if the master clip has been added yet, if not, then create */
+ if (!e->framespace.clip)
+ {
+ e->framespace.clip = evas_object_rectangle_add(e);
+ evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
+ evas_object_move(e->framespace.clip,
+ e->framespace.x, e->viewport.y);
+ evas_object_resize(e->framespace.clip,
+ e->viewport.w - e->framespace.w, e->viewport.h);
+ evas_object_show(e->framespace.clip);
+ }
+ else
+ {
+ /* master clip is already present. check for size changes in the
+ * viewport, and update master clip size if needed */
+ if ((e->viewport.changed) || (e->output.changed))
+ evas_object_resize(e->framespace.clip,
+ e->viewport.w - e->framespace.w,
+ e->viewport.h);
+ }
+
+ EINA_RECTANGLE_SET(&clip_rect,
+ e->framespace.clip->cur.geometry.x,
+ e->framespace.clip->cur.geometry.y,
+ e->framespace.clip->cur.geometry.w,
+ e->framespace.clip->cur.geometry.h)
+
+ /* With the master clip all setup, we need to loop the objects on this
+ * canvas and determine if the object is in the viewport space. If it
+ * is in the viewport space (and not in framespace), then we need to
+ * clip the object to the master clip so that it does not draw on top
+ * of the frame (eg: elm 3d test) */
+ for (i = 0; i < e->render_objects.count; ++i)
+ {
+ Eina_Rectangle obj_rect;
+ Evas_Object *pclip;
+
+ obj = eina_array_data_get(&e->render_objects, i);
+ if (evas_object_is_frame_object_get(obj))
+ continue;
+
+ EINA_RECTANGLE_SET(&obj_rect,
+ obj->cur.geometry.x, obj->cur.geometry.y,
+ obj->cur.geometry.w, obj->cur.geometry.h);
+
+ /* if the object does not intersect our clip rect, ignore it */
+ if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
+ continue;
+
+ if (!(pclip = evas_object_clip_get(obj)))
+ {
+ /* clip this object so it does not draw on the window frame */
+ evas_object_clip_set(obj, e->framespace.clip);
+ }
+ }
+ }
+
+ if (redraw_all)
+ {
+ e->engine.func->output_redraws_rect_add(e->engine.data.output, 0, 0,
e->output.w, e->output.h);
}
return NULL;
MAGIC_CHECK_END();
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush_ready ();
-#endif
-
if (!e->changed) return NULL;
return evas_render_updates_internal(e, 1, 1);
}
return;
MAGIC_CHECK_END();
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush_ready ();
-#endif
-
if (!e->changed) return;
evas_render_updates_internal(e, 0, 1);
}
EAPI void
evas_sync(Evas *e)
{
-#ifdef EVAS_FRAME_QUEUING
- MAGIC_CHECK(e, Evas, MAGIC_EVAS);
- return;
- MAGIC_CHECK_END();
-
- evas_common_frameq_flush();
-#else
- (void) e;
-#endif
+ (void) e;
}
static void
return;
MAGIC_CHECK_END();
-#ifndef EVAS_FRAME_QUEUING
if ((!obj->changed) && (obj->delete_me < 2))
-#else
- if ((!obj->changed))
-#endif
- {
- Evas *e;
+ {
+ Evas *e;
- e = obj->layer->evas;
- if ((!e) || (e->cleanup)) return;
-#ifdef EVAS_FRAME_QUEUING
- if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return;
-#endif
- eina_array_push(&e->pending_objects, obj);
- obj->changed = EINA_TRUE;
- }
+ e = obj->layer->evas;
+ if ((!e) || (e->cleanup)) return;
+ eina_array_push(&e->pending_objects, obj);
+ obj->changed = EINA_TRUE;
+ }
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+@EINA_CFLAGS@ \
+@FREETYPE_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@EET_CFLAGS@ \
+@FONTCONFIG_CFLAGS@ \
+@pthread_cflags@ \
+@PIXMAN_CFLAGS@
+
+if EVAS_CSERVE2
+
+noinst_LTLIBRARIES = libevas_cserve2.la
+
+libevas_cserve2_la_SOURCES = \
+evas_cs2.h \
+evas_cs2_private.h \
+evas_cs2_image_data.c \
+evas_cs2_client.c
+
+libevas_cserve2_la_LIBADD = @EINA_LIBS@
+
+endif
--- /dev/null
+#ifndef EVAS_CS2_H
+#define EVAS_CS2_H 1
+
+#include <Eina.h>
+
+#ifdef EVAS_CSERVE2
+
+typedef enum {
+ CSERVE2_OPEN = 1,
+ CSERVE2_OPENED,
+ CSERVE2_SETOPTS,
+ CSERVE2_SETOPTSED,
+ CSERVE2_LOAD,
+ CSERVE2_LOADED,
+ CSERVE2_PRELOAD,
+ CSERVE2_PRELOADED,
+ CSERVE2_UNLOAD,
+ CSERVE2_CLOSE,
+ CSERVE2_FONT_LOAD,
+ CSERVE2_FONT_LOADED,
+ CSERVE2_FONT_UNLOAD,
+ CSERVE2_FONT_GLYPHS_LOAD,
+ CSERVE2_FONT_GLYPHS_LOADED,
+ CSERVE2_FONT_GLYPHS_USED,
+ CSERVE2_ERROR
+} Message_Type;
+
+typedef enum {
+ CSERVE2_NONE,
+ CSERVE2_GENERIC,
+ CSERVE2_DOES_NOT_EXIST,
+ CSERVE2_PERMISSION_DENIED,
+ CSERVE2_RESOURCE_ALLOCATION_FAILED,
+ CSERVE2_CORRUPT_FILE,
+ CSERVE2_UNKNOWN_FORMAT,
+ CSERVE2_INVALID_COMMAND,
+ CSERVE2_LOADER_DIED,
+ CSERVE2_LOADER_EXEC_ERR,
+ CSERVE2_INVALID_CACHE, // invalid cserve cache entry
+ CSERVE2_FILE_CHANGED,
+ CSERVE2_REQUEST_CANCEL
+} Error_Type;
+
+struct _Msg_Base {
+ int type;
+ unsigned int rid;
+};
+
+typedef struct _Msg_Base Msg_Base;
+
+struct _Msg_Open {
+ Msg_Base base;
+ unsigned int file_id;
+ int path_offset;
+ int key_offset;
+};
+
+struct _Msg_Opened {
+ Msg_Base base;
+ struct {
+ int w, h;
+ int frame_count;
+ int loop_count;
+ int loop_hint; /* include Evas.h? Copy the enum around? */
+ Eina_Bool alpha : 1;
+ } image;
+};
+
+struct _Msg_Setopts {
+ Msg_Base base;
+ unsigned int file_id;
+ unsigned int image_id;
+ struct {
+ double dpi;
+ int w, h;
+ int scale_down;
+ int rx, ry, rw, rh;
+ Eina_Bool orientation;
+ } opts;
+};
+
+struct _Msg_Setoptsed {
+ Msg_Base base;
+};
+
+struct _Msg_Load {
+ Msg_Base base;
+ unsigned int image_id;
+};
+
+struct _Msg_Loaded {
+ Msg_Base base;
+ struct {
+ int mmap_offset;
+ int use_offset;
+ int mmap_size;
+ int image_size;
+ } shm;
+ Eina_Bool alpha_sparse : 1;
+};
+
+struct _Msg_Preload {
+ Msg_Base base;
+ unsigned int image_id;
+};
+
+struct _Msg_Preloaded {
+ Msg_Base base;
+};
+
+struct _Msg_Unload {
+ Msg_Base base;
+ unsigned int image_id;
+};
+
+struct _Msg_Close {
+ Msg_Base base;
+ unsigned int file_id;
+};
+
+/**
+ * @struct _Msg_Font_Load
+ *
+ * Message from client to request load or unload of a font.
+ *
+ * The path strings follow the struct inside the message.
+ */
+struct _Msg_Font_Load {
+ Msg_Base base;
+ unsigned int pathlen; // font id
+ unsigned int rend_flags; // font id
+ unsigned int hint; // font id
+ unsigned int size; // font id
+ unsigned int dpi; // font id
+};
+
+/**
+ * @struct _Msg_Font_Loaded
+ *
+ * Message from server to inform that a font was loaded.
+ */
+struct _Msg_Font_Loaded {
+ Msg_Base base;
+};
+
+/**
+ * @struct _Msg_Font_Glyphs_Request
+ *
+ * Message from client to request load of glyphs, of inform usage of them.
+ *
+ * The path strings follow the struct inside the message, as well as
+ * the list of glyphs to be loaded.
+ */
+struct _Msg_Font_Glyphs_Request {
+ Msg_Base base;
+ unsigned int pathlen; // font id
+ unsigned int rend_flags; // font id
+ unsigned int hint; // font id
+ unsigned int size; // font id
+ unsigned int dpi; // font id
+ unsigned int nglyphs;
+};
+
+/**
+ * @struct _Msg_Font_Glyphs_Loaded
+ *
+ * Message from server to inform that some glyphs were loaded.
+ *
+ * This message is quite complex: it contains the font id, representing for
+ * which font these glyphs should be loaded, and the number of caches on which
+ * the loaded glyphs are stored. Each cache is a SHM segment. The information
+ * about each SHM comes serialized just after this struct, and can be read in
+ * order as follows:
+ *
+ * shm name:
+ * - unsigned int size;
+ * - char name[];
+ * glyphs:
+ * - unsigned int nglyphs;
+ * - struct {
+ * unsigned int index;
+ * unsigned int offset;
+ * } glarray[];
+ */
+struct _Msg_Font_Glyphs_Loaded {
+ Msg_Base base;
+ unsigned int ncaches;
+};
+
+struct _Msg_Error {
+ Msg_Base base;
+ int error;
+};
+
+typedef struct _Msg_Open Msg_Open;
+typedef struct _Msg_Opened Msg_Opened;
+typedef struct _Msg_Setopts Msg_Setopts;
+typedef struct _Msg_Setoptsed Msg_Setoptsed;
+typedef struct _Msg_Load Msg_Load;
+typedef struct _Msg_Loaded Msg_Loaded;
+typedef struct _Msg_Preload Msg_Preload;
+typedef struct _Msg_Preloaded Msg_Preloaded;
+typedef struct _Msg_Unload Msg_Unload;
+typedef struct _Msg_Close Msg_Close;
+typedef struct _Msg_Font_Load Msg_Font_Load;
+typedef struct _Msg_Font_Loaded Msg_Font_Loaded;
+typedef struct _Msg_Font_Glyphs_Request Msg_Font_Glyphs_Request;
+typedef struct _Msg_Font_Glyphs_Loaded Msg_Font_Glyphs_Loaded;
+typedef struct _Msg_Error Msg_Error;
+
+#endif
+#endif
--- /dev/null
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <Eina.h>
+
+#include "evas_cs2.h"
+#include "evas_cs2_private.h"
+
+#ifdef EVAS_CSERVE2
+
+typedef void (*Op_Callback)(void *data, const void *msg);
+
+struct _File_Entry {
+ unsigned int file_id;
+};
+
+struct _Client_Request {
+ Message_Type type;
+ unsigned int rid;
+ Op_Callback cb;
+ void *data;
+};
+
+typedef struct _File_Entry File_Entry;
+typedef struct _Client_Request Client_Request;
+
+static int cserve2_init = 0;
+static int socketfd = -1;
+
+static unsigned int _rid_count = 0;
+static unsigned int _file_id = 0;
+static unsigned int _data_id = 0;
+
+static Eina_List *_requests = NULL;
+
+static struct sockaddr_un socksize;
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(socksize.sun_path)
+#endif
+
+static void
+_socket_path_set(char *path)
+{
+ char *env;
+ char buf[UNIX_PATH_MAX];
+
+ env = getenv("EVAS_CSERVE2_SOCKET");
+ if (env && env[0])
+ {
+ strncpy(path, env, UNIX_PATH_MAX - 1);
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
+ /* FIXME: check we can actually create this socket */
+ strcpy(path, buf);
+#if 0
+ env = getenv("XDG_RUNTIME_DIR");
+ if (!env || !env[0])
+ {
+ env = getenv("HOME");
+ if (!env || !env[0])
+ {
+ env = getenv("TMPDIR");
+ if (!env || !env[0])
+ env = "/tmp";
+ }
+ }
+
+ snprintf(buf, sizeof(buf), "%s/evas-cserve2-%x.socket", env, getuid());
+ /* FIXME: check we can actually create this socket */
+ strcpy(path, buf);
+#endif
+}
+
+static Eina_Bool
+_server_connect(void)
+{
+ int s, len;
+ struct sockaddr_un remote;
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ ERR("socket");
+ return EINA_FALSE;
+ }
+
+ remote.sun_family = AF_UNIX;
+ _socket_path_set(remote.sun_path);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ if (connect(s, (struct sockaddr *)&remote, len) == -1)
+ {
+ ERR("connect");
+ return EINA_FALSE;
+ }
+
+ fcntl(s, F_SETFL, O_NONBLOCK);
+
+ socketfd = s;
+
+ DBG("connected to cserve2 server.");
+ return EINA_TRUE;
+}
+
+static void
+_server_disconnect(void)
+{
+ close(socketfd);
+ socketfd = -1;
+}
+
+static void
+_request_answer_add(Message_Type type, unsigned int rid, Op_Callback cb, void *data)
+{
+ Client_Request *cr = calloc(1, sizeof(*cr));
+
+ cr->type = type;
+ cr->rid = rid;
+ cr->cb = cb;
+ cr->data = data;
+
+ _requests = eina_list_append(_requests, cr);
+}
+
+static Eina_Bool
+_server_send(const void *buf, int size, Op_Callback cb, void *data)
+{
+ const Msg_Base *msg;
+ if (send(socketfd, &size, sizeof(size), MSG_NOSIGNAL) == -1)
+ {
+ ERR("Couldn't send message size to server.");
+ return EINA_FALSE;
+ }
+ if (send(socketfd, buf, size, MSG_NOSIGNAL) == -1)
+ {
+ ERR("Couldn't send message body to server.");
+ return EINA_FALSE;
+ }
+
+ msg = buf;
+ switch (msg->type)
+ {
+ case CSERVE2_OPEN:
+ case CSERVE2_SETOPTS:
+ case CSERVE2_LOAD:
+ case CSERVE2_PRELOAD:
+ _request_answer_add(msg->type, msg->rid, cb, data);
+ break;
+ default:
+ break;
+ }
+
+ return EINA_TRUE;
+}
+
+static int sr_size = 0;
+static int sr_got = 0;
+static char *sr_buf = NULL;
+
+static void *
+_server_read(int *size)
+{
+ int n;
+ void *ret;
+
+ if (sr_size)
+ goto get_data;
+
+ n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
+ if (n < 0)
+ return NULL;
+
+ sr_buf = malloc(sr_size);
+
+get_data:
+ n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
+ if (n < 0)
+ return NULL;
+
+ sr_got += n;
+ if (sr_got < sr_size)
+ return NULL;
+
+ *size = sr_size;
+ sr_size = 0;
+ sr_got = 0;
+ ret = sr_buf;
+ sr_buf = NULL;
+
+ return ret;
+}
+
+int
+evas_cserve2_init(void)
+{
+ if (cserve2_init++)
+ return cserve2_init;
+
+ DBG("Connecting to cserve2.");
+ if (!_server_connect())
+ {
+ cserve2_init = 0;
+ return 0;
+ }
+
+ return cserve2_init;
+}
+
+int
+evas_cserve2_shutdown(void)
+{
+ if ((--cserve2_init) > 0)
+ return cserve2_init;
+
+ DBG("Disconnecting from cserve2.");
+ _server_disconnect();
+
+ return cserve2_init;
+}
+
+int
+evas_cserve2_use_get(void)
+{
+ return cserve2_init;
+}
+
+static unsigned int
+_next_rid(void)
+{
+ if (!_rid_count)
+ _rid_count++;
+
+ return _rid_count++;
+}
+
+static unsigned int
+_server_dispatch(void)
+{
+ int size;
+ unsigned int rid;
+ Eina_List *l, *l_next;
+ Client_Request *cr;
+ Msg_Base *msg;
+
+ msg = _server_read(&size);
+ if (!msg)
+ return 0;
+
+ EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr)
+ {
+ if (cr->rid != msg->rid) // dispatch this answer
+ continue;
+
+ _requests = eina_list_remove_list(_requests, l);
+ if (cr->cb)
+ cr->cb(cr->data, msg);
+ free(cr);
+ }
+
+ rid = msg->rid;
+ free(msg);
+
+ return rid;
+}
+
+static void
+_server_dispatch_until(unsigned int rid)
+{
+ Eina_Bool done = EINA_FALSE;
+
+ while (!done)
+ {
+ if (_server_dispatch() == rid)
+ done = EINA_TRUE;
+ }
+}
+
+static void
+_image_opened_cb(void *data, const void *msg_received)
+{
+ const Msg_Base *answer = msg_received;
+ const Msg_Opened *msg = msg_received;
+ Image_Entry *ie = data;
+
+ ie->open_rid = 0;
+
+ if (answer->type == CSERVE2_ERROR)
+ {
+ const Msg_Error *msg_error = msg_received;
+ ERR("Couldn't open image: '%s':'%s'; error: %d",
+ ie->file, ie->key, msg_error->error);
+ free(ie->data1);
+ ie->data1 = NULL;
+ return;
+ }
+
+ ie->w = msg->image.w;
+ ie->h = msg->image.h;
+ ie->flags.alpha = msg->image.alpha;
+ ie->loop_hint = msg->image.loop_hint;
+ ie->loop_count = msg->image.loop_count;
+ ie->frame_count = msg->image.frame_count;
+}
+
+static void
+_image_loaded_cb(void *data, const void *msg_received)
+{
+ const Msg_Base *answer = msg_received;
+ const Msg_Loaded *msg = msg_received;
+ Image_Entry *ie = data;
+ Data_Entry *dentry = ie->data2;
+ const char *shmpath;
+
+ ie->load_rid = 0;
+
+ if (!ie->data2)
+ return;
+
+ if (answer->type == CSERVE2_ERROR)
+ {
+ const Msg_Error *msg_error = msg_received;
+ ERR("Couldn't load image: '%s':'%s'; error: %d",
+ ie->file, ie->key, msg_error->error);
+ free(ie->data2);
+ ie->data2 = NULL;
+ return;
+ }
+
+ shmpath = ((const char *)msg) + sizeof(*msg);
+
+ // dentry->shm.path = strdup(shmpath);
+ dentry->shm.mmap_offset = msg->shm.mmap_offset;
+ dentry->shm.use_offset = msg->shm.use_offset;
+ dentry->shm.mmap_size = msg->shm.mmap_size;
+ dentry->shm.image_size = msg->shm.image_size;
+
+ dentry->shm.f = eina_file_open(shmpath, EINA_TRUE);
+ if (!dentry->shm.f)
+ {
+ free(dentry);
+ ie->data2 = NULL;
+ return;
+ }
+
+ dentry->shm.data = eina_file_map_new(dentry->shm.f, EINA_FILE_WILLNEED,
+ dentry->shm.mmap_offset,
+ dentry->shm.mmap_size);
+
+ if (!dentry->shm.data)
+ {
+ eina_file_close(dentry->shm.f);
+ free(dentry);
+ ie->data2 = NULL;
+ }
+
+ if (ie->data2)
+ {
+ ie->flags.loaded = EINA_TRUE;
+ ie->flags.alpha_sparse = msg->alpha_sparse;
+ }
+}
+
+static void
+_image_preloaded_cb(void *data, const void *msg_received)
+{
+ const Msg_Base *answer = msg_received;
+ Image_Entry *ie = data;
+ Data_Entry *dentry = ie->data2;
+
+ DBG("Received PRELOADED for RID: %d", answer->rid);
+ ie->preload_rid = 0;
+
+ if (answer->type == CSERVE2_ERROR)
+ {
+ const Msg_Error *msg_error = msg_received;
+ ERR("Couldn't preload image: '%s':'%s'; error: %d",
+ ie->file, ie->key, msg_error->error);
+ dentry->preloaded_cb(data, EINA_FALSE);
+ dentry->preloaded_cb = NULL;
+ return;
+ }
+
+ if (dentry && (dentry->preloaded_cb))
+ {
+ dentry->preloaded_cb(data, EINA_TRUE);
+ dentry->preloaded_cb = NULL;
+ }
+}
+
+static const char *
+_build_absolute_path(const char *path, char buf[], int size)
+{
+ char *p;
+ int len;
+
+ if (!path)
+ return NULL;
+
+ p = buf;
+
+ if (path[0] == '/')
+ strncpy(p, path, size);
+ else if (path[0] == '~')
+ {
+ const char *home = getenv("HOME");
+ if (!home)
+ return NULL;
+ strncpy(p, home, size);
+ len = strlen(p);
+ size -= len + 1;
+ p += len;
+ p[0] = '/';
+ p++;
+ strncpy(p, path + 2, size);
+ }
+ else
+ {
+ if (!getcwd(p, size))
+ return NULL;
+ len = strlen(p);
+ size -= len + 1;
+ p += len;
+ p[0] = '/';
+ p++;
+ strncpy(p, path, size);
+ }
+
+ return buf;
+}
+
+static unsigned int
+_image_open_server_send(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt __UNUSED__)
+{
+ int flen, klen;
+ int size;
+ char *buf;
+ char filebuf[PATH_MAX];
+ Msg_Open msg_open;
+ File_Entry *fentry;
+
+ if (cserve2_init == 0)
+ {
+ ERR("Server not initialized.");
+ return 0;
+ }
+
+ if (!key) key = "";
+
+ _build_absolute_path(file, filebuf, sizeof(filebuf));
+
+ fentry = calloc(1, sizeof(*fentry));
+
+ memset(&msg_open, 0, sizeof(msg_open));
+
+ fentry->file_id = ++_file_id;
+ if (fentry->file_id == 0)
+ fentry->file_id = ++_file_id;
+
+ flen = strlen(filebuf) + 1;
+ klen = strlen(key) + 1;
+
+ msg_open.base.rid = _next_rid();
+ msg_open.base.type = CSERVE2_OPEN;
+ msg_open.file_id = fentry->file_id;
+ msg_open.path_offset = 0;
+ msg_open.key_offset = flen;
+
+ size = sizeof(msg_open) + flen + klen;
+ buf = malloc(size);
+ if (!buf) return EINA_FALSE;
+ memcpy(buf, &msg_open, sizeof(msg_open));
+ memcpy(buf + sizeof(msg_open), filebuf, flen);
+ memcpy(buf + sizeof(msg_open) + flen, key, klen);
+
+ if (!_server_send(buf, size, _image_opened_cb, ie))
+ {
+ ERR("Couldn't send message to server.");
+ free(buf);
+ return 0;
+ }
+
+ free(buf);
+ ie->data1 = fentry;
+
+ return msg_open.base.rid;
+}
+
+unsigned int
+_image_setopts_server_send(Image_Entry *ie)
+{
+ File_Entry *fentry;
+ Data_Entry *dentry;
+ Msg_Setopts msg;
+
+ if (cserve2_init == 0)
+ return 0;
+
+ fentry = ie->data1;
+
+ dentry = calloc(1, sizeof(*dentry));
+
+ memset(&msg, 0, sizeof(msg));
+ dentry->image_id = ++_data_id;
+ if (dentry->image_id == 0)
+ dentry->image_id = ++_data_id;
+
+ msg.base.rid = _next_rid();
+ msg.base.type = CSERVE2_SETOPTS;
+ msg.file_id = fentry->file_id;
+ msg.image_id = dentry->image_id;
+
+ if (!_server_send(&msg, sizeof(msg), 0, NULL))
+ return 0;
+
+ ie->data2 = dentry;
+
+ return msg.base.rid;
+}
+
+unsigned int
+_image_load_server_send(Image_Entry *ie)
+{
+ Data_Entry *dentry;
+ Msg_Load msg;
+
+ if (cserve2_init == 0)
+ return 0;
+
+ if (!ie->data1)
+ {
+ ERR("No data for opened file.");
+ return 0;
+ }
+
+ dentry = ie->data2;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.base.rid = _next_rid();
+ msg.base.type = CSERVE2_LOAD;
+ msg.image_id = dentry->image_id;
+
+ if (!_server_send(&msg, sizeof(msg), _image_loaded_cb, ie))
+ return 0;
+
+ return msg.base.rid;
+}
+
+unsigned int
+_image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success))
+{
+ Data_Entry *dentry;
+ Msg_Preload msg;
+
+ if (cserve2_init == 0)
+ return 0;
+
+ dentry = ie->data2;
+ dentry->preloaded_cb = preloaded_cb;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.base.rid = _next_rid();
+ msg.base.type = CSERVE2_PRELOAD;
+ msg.image_id = dentry->image_id;
+
+ if (!_server_send(&msg, sizeof(msg), _image_preloaded_cb, ie))
+ return 0;
+
+ return msg.base.rid;
+}
+
+unsigned int
+_image_close_server_send(Image_Entry *ie)
+{
+ Msg_Close msg;
+ File_Entry *fentry;
+
+ if (cserve2_init == 0)
+ return 0;
+
+ if (!ie->data1)
+ return 0;
+
+ fentry = ie->data1;
+
+ if (ie->data2)
+ {
+ Data_Entry *dentry = ie->data2;
+ if (dentry->shm.data)
+ eina_file_map_free(dentry->shm.f, dentry->shm.data);
+ if (dentry->shm.f)
+ eina_file_close(dentry->shm.f);
+ free(ie->data2);
+ ie->data2 = NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = _next_rid();
+ msg.base.type = CSERVE2_CLOSE;
+ msg.file_id = fentry->file_id;
+
+ free(fentry);
+ ie->data1 = NULL;
+
+ if (!_server_send(&msg, sizeof(msg), NULL, NULL))
+ return 0;
+
+ return msg.base.rid;
+}
+
+unsigned int
+_image_unload_server_send(Image_Entry *ie)
+{
+ Msg_Unload msg;
+ Data_Entry *dentry;
+
+ if (cserve2_init == 0)
+ return 0;
+
+ if (!ie->data2)
+ return 0;
+
+ dentry = ie->data2;
+
+ if (dentry->shm.data)
+ eina_file_map_free(dentry->shm.f, dentry->shm.data);
+ if (dentry->shm.f)
+ eina_file_close(dentry->shm.f);
+
+ // if (dentry->shm.path)
+ // free(dentry->shm.path);
+ memset(&msg, 0, sizeof(msg));
+ msg.base.rid = _next_rid();
+ msg.base.type = CSERVE2_UNLOAD;
+ msg.image_id = dentry->image_id;
+
+ free(dentry);
+ ie->data2 = NULL;
+
+ if (!_server_send(&msg, sizeof(msg), NULL, NULL))
+ return 0;
+
+ return msg.base.rid;
+}
+
+Eina_Bool
+evas_cserve2_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt)
+{
+ unsigned int rid;
+
+ rid = _image_open_server_send(ie, file, key, lopt);
+ if (!rid)
+ return EINA_FALSE;
+
+ ie->open_rid = rid;
+
+ _image_setopts_server_send(ie);
+
+ // _server_dispatch_until(rid);
+
+ if (ie->data1)
+ return EINA_TRUE;
+ else
+ return EINA_FALSE;
+}
+
+int
+evas_cserve2_image_load_wait(Image_Entry *ie)
+{
+ if (ie->open_rid)
+ {
+ _server_dispatch_until(ie->open_rid);
+ if (!ie->data1)
+ return CSERVE2_GENERIC;
+ return CSERVE2_NONE;
+ }
+ else
+ return CSERVE2_GENERIC;
+}
+
+Eina_Bool
+evas_cserve2_image_data_load(Image_Entry *ie)
+{
+ unsigned int rid;
+
+ rid = _image_load_server_send(ie);
+ if (!rid)
+ return EINA_FALSE;
+
+ ie->load_rid = rid;
+
+ if (ie->data2)
+ return EINA_TRUE;
+ else
+ return EINA_FALSE;
+}
+
+void
+evas_cserve2_image_load_data_wait(Image_Entry *ie)
+{
+ if (ie->load_rid)
+ _server_dispatch_until(ie->load_rid);
+}
+
+Eina_Bool
+evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success))
+{
+ unsigned int rid;
+
+ if (!ie->data1)
+ return EINA_FALSE;
+
+ rid = _image_preload_server_send(ie, preloaded_cb);
+ if (!rid)
+ return EINA_FALSE;
+
+ ie->preload_rid = rid;
+
+ return EINA_FALSE;
+}
+
+void
+evas_cserve2_image_free(Image_Entry *ie)
+{
+ if (!ie->data1)
+ return;
+
+ if (!_image_close_server_send(ie))
+ WRN("Couldn't send close message to cserve2.");
+}
+
+void
+evas_cserve2_image_unload(Image_Entry *ie)
+{
+ if (!ie->data2)
+ return;
+
+ if (!_image_unload_server_send(ie))
+ WRN("Couldn't send unload message to cserve2.");
+}
+
+void
+evas_cserve2_dispatch(void)
+{
+ _server_dispatch_until(0);
+}
+#endif
--- /dev/null
+#include "config.h"
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "evas_cs2.h"
+#include "evas_cs2_private.h"
+
+#ifdef EVAS_CSERVE2
+
+void *
+evas_cserve2_image_data_get(Image_Entry *ie)
+{
+ Data_Entry *dentry = ie->data2;
+
+ if (!dentry)
+ return NULL;
+
+ return dentry->shm.data;
+}
+
+#endif
--- /dev/null
+#ifndef EVAS_CS2_PRIVATE_H
+#define EVAS_CS2_PRIVATE_H 1
+
+#include "evas_common.h"
+
+struct _Data_Entry {
+ unsigned int image_id;
+ void (*preloaded_cb)(void *, Eina_Bool);
+ struct {
+ const char *path;
+ int mmap_offset;
+ int use_offset;
+ int mmap_size;
+ int image_size;
+ Eina_File *f;
+ void *data;
+ } shm;
+};
+
+typedef struct _Data_Entry Data_Entry;
+
+int evas_cserve2_init(void);
+int evas_cserve2_shutdown(void);
+EAPI int evas_cserve2_use_get(void);
+Eina_Bool evas_cserve2_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt);
+int evas_cserve2_image_load_wait(Image_Entry *ie);
+Eina_Bool evas_cserve2_image_data_load(Image_Entry *ie);
+void evas_cserve2_image_load_data_wait(Image_Entry *ie);
+void evas_cserve2_image_free(Image_Entry *ie);
+void evas_cserve2_image_unload(Image_Entry *ie);
+Eina_Bool evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success));
+void evas_cserve2_dispatch(void);
+
+void *evas_cserve2_image_data_get(Image_Entry *ie);
+#endif
AM_CPPFLAGS = -I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/cserve \
+ -I$(top_srcdir)/src/lib/cserve2 \
-I$(top_srcdir)/src/lib/include \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
#define _EVAS_FONT_H
#include "evas_text_utils.h"
-
+/* The tangent of the slant angle we do on runtime. */
+#define _EVAS_FONT_SLANT_TAN 0.221694663
/* main */
EAPI void evas_common_font_init (void);
/* draw */
-EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Evas_Text_Props *intl_props);
+EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *intl_props);
EAPI int evas_common_font_glyph_search (RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl);
EAPI RGBA_Font_Glyph *evas_common_font_int_cache_glyph_get (RGBA_Font_Int *fi, FT_UInt index);
+EAPI Eina_Bool evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg);
EAPI FT_UInt evas_common_get_char_index (RGBA_Font_Int* fi, Eina_Unicode gl);
EAPI void evas_common_font_draw_init (void);
+EAPI void evas_common_font_draw_prepare (Evas_Text_Props *text_props);
/* load */
EAPI void evas_common_font_dpi_set (int dpi);
EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y);
EAPI int evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi, RGBA_Font_Int **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
-#ifdef EVAS_FRAME_QUEUING
-EAPI void evas_common_font_draw_finish(void);
-#endif
-
void evas_common_font_load_init(void);
void evas_common_font_load_shutdown(void);
(text_props->start > 0)) ? \
text_props->info->glyph[text_props->start - 1].pen_after : 0 ; \
size_t char_index; \
+ (void) _pen_x; /* Sometimes it won't be used */ \
(void) _pen_y; /* Sometimes it won't be used */
/* Visual walk helper macros */
#include "evas_font_ot.h"
-/* Forcibly disable the broken word/metric caching. */
-#ifdef METRIC_CACHE
-# undef METRIC_CACHE
-#endif
-
-#ifdef WORD_CACHE
-# undef WORD_CACHE
-#endif
-
-#define WORD_CACHE_MAXLEN 50
-/* How many to cache */
-#define WORD_CACHE_NWORDS 40
-
-static int max_cached_words = WORD_CACHE_NWORDS;
-
struct prword
{
EINA_INLIST;
} bm;
};
-
-#if defined(METRIC_CACHE) || defined(WORD_CACHE)
-LK(lock_words); // for word cache call
-static Eina_Inlist *words = NULL;
-static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Evas_Text_Props *text_props);
-#endif
-
-EAPI void
-evas_common_font_draw_init(void)
+typedef struct _Evas_Glyph Evas_Glyph;
+struct _Evas_Glyph
{
- char *p;
- int tmp;
-
- if ((p = getenv("EVAS_WORD_CACHE_MAX_WORDS")))
- {
- tmp = strtol(p,NULL,10);
- /* 0 to disable of course */
- if (tmp > -1 && tmp < 500){
- max_cached_words = tmp;
- }
- }
-}
+ RGBA_Font_Glyph *fg;
+ void *data;
+ Eina_Rectangle coord;
+ FT_UInt idx;
+ int j;
+};
-#ifdef EVAS_FRAME_QUEUING
EAPI void
-evas_common_font_draw_finish(void)
+evas_common_font_draw_init(void)
{
}
-#endif
/*
* BiDi handling: We receive the shaped string + other props from text_props,
* is on the right, and not on the left).
*/
static void
-evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn __UNUSED__, int x, int y,
+evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
const Evas_Text_Props *text_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w,
int ext_h, int im_w, int im_h __UNUSED__)
{
DATA32 *im;
- RGBA_Font_Int *fi;
- EVAS_FONT_WALK_TEXT_INIT();
-
- fi = text_props->font_instance;
- if (!fi) return;
-
- evas_common_font_int_reload(fi);
-
- if (fi->src->current_size != fi->size)
- {
- FTLOCK();
- FT_Activate_Size(fi->ft.size);
- FTUNLOCK();
- fi->src->current_size = fi->size;
- }
-
-
-#if defined(METRIC_CACHE) || defined(WORD_CACHE)
- unsigned int len;
-
- len = text_props->len;
-
- if (len > 2 && (len < WORD_CACHE_MAXLEN))
- {
- struct prword *word;
-
- word =
- evas_font_word_prerender(dc, text_props);
- if (word)
- {
- int j, rowstart, rowend, xstart, xrun;
-
- im = dst->image.data;
- xrun = word->width;
- y -= word->baseline;
- xstart = 0;
- rowstart = 0;
- rowend = word->height;
- /* Clip to extent */
- if (x + xrun > ext_x + ext_w)
- {
- xrun -= x + xrun - ext_x - ext_w;
- }
- if (x < ext_x)
- {
- int excess = ext_x - x;
- xstart = excess - 1;
- xrun -= excess;
- x = ext_x;
- }
- if (y + rowend > ext_y + ext_h)
- {
- rowend -= (y - ext_y + rowend - ext_h);
- }
- if (y < ext_y)
- {
- int excess = ext_y - y;
- rowstart += excess;
- //rowend -= excess;
- // y = ext_y;
- }
-
- if (xrun < 1) return;
-/* For some reason, metric and word chache are exactly the same except for
- * this piece of code that makes metric go nuts. ATM, we'll just go the
- * WORD_CACHE path. */
-#if defined(METRIC_CACHE) || defined(WORD_CACHE)
- if (word->im)
- {
- for (j = rowstart ; j < rowend ; j ++)
- {
- func(NULL, word->im + (word->roww * j) + xstart, dc->col.col,
- im + ((y + j) * im_w) + x, xrun);
- }
- return;
- }
-# elif defined(METRIC_CACHE)
- unsigned int ind;
-
- y += word->baseline;
- for (ind = 0 ; ind < len ; ind ++)
- {
- // FIXME Do we need to draw?
- struct cinfo *ci = word->cinfo + ind;
- for (j = rowstart ; j < rowend ; j ++)
- {
- if ((ci->fg->ext_dat) && (dc->font_ext.func.gl_draw))
- {
- /* ext glyph draw */
- dc->font_ext.func.gl_draw(dc->font_ext.data,
- (void *)dst,
- dc, ci->fg,
- x + ci->pos.x,
- y - ci->bm.h + j);
- }
- else
- {
- func(NULL, word->im + (word->roww * j) + xstart,
- dc->col.col, im + ((y + j) * im_w) + x, xrun);
- }
- }
- }
- return;
-# endif
- }
- }
-#endif
+ Evas_Glyph *glyphs;
+ unsigned int length;
+ unsigned int it;
im = dst->image.data;
- EVAS_FONT_WALK_TEXT_START()
+ if (!text_props->bin) return ;
+
+ glyphs = (void*) eina_binbuf_string_get(text_props->bin);
+ length = eina_binbuf_length_get(text_props->bin) / sizeof (Evas_Glyph);
+ for (it = 0; it < length; ++it)
{
FT_UInt idx;
RGBA_Font_Glyph *fg;
int chr_x, chr_y;
- if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
-
- idx = EVAS_FONT_WALK_INDEX;
-
- LKL(fi->ft_mutex);
- fg = evas_common_font_int_cache_glyph_get(fi, idx);
- if (!fg)
- {
- LKU(fi->ft_mutex);
- continue;
- }
-
- LKU(fi->ft_mutex);
+ fg = glyphs[it].fg;
+ idx = glyphs[it].idx;
if (dc->font_ext.func.gl_new)
{
fg->ext_dat_free = dc->font_ext.func.gl_free;
}
- chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
- chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
+ chr_x = x + glyphs[it].coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
+ chr_y = y + glyphs[it].coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
if (chr_x < (ext_x + ext_w))
{
DATA8 *data;
int i, j, w, h;
- data = fg->glyph_out->bitmap.buffer;
- j = fg->glyph_out->bitmap.pitch;
- w = fg->glyph_out->bitmap.width;
+ data = glyphs[it].data;
+ j = glyphs[it].j;
+ w = glyphs[it].coord.w;
if (j < w) j = w;
- h = fg->glyph_out->bitmap.rows;
+ h = glyphs[it].coord.h;
/*
if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
&& (fg->glyph_out->bitmap.num_grays == 256)
in_w = 0;
dx = chr_x;
dy = y - (chr_y - i - y);
-#ifdef EVAS_SLI
- if (((dy) % dc->sli.h) == dc->sli.y)
-#endif
- {
- if ((dx < (ext_x + ext_w)) &&
- (dy >= (ext_y)) &&
- (dy < (ext_y + ext_h)))
- {
- if (dx + w > (ext_x + ext_w))
- in_w += (dx + w) - (ext_x + ext_w);
- if (dx < ext_x)
- {
- in_w += ext_x - dx;
- in_x = ext_x - dx;
- dx = ext_x;
- }
- if (in_w < w)
- {
- func(NULL, data + (i * j) + in_x, dc->col.col,
- im + (dy * im_w) + dx, w - in_w);
- }
- }
- }
+
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
+ {
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, data + (i * j) + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
+ }
}
}
}
in_w = 0;
dx = chr_x;
dy = y - (chr_y - i - y);
-#ifdef EVAS_SLI
- if (((dy) % dc->sli.h) == dc->sli.y)
-#endif
- {
- tp = tmpbuf;
- dp = data + (i * fg->glyph_out->bitmap.pitch);
- for (bi = 0; bi < w; bi += 8)
- {
- bits = *dp;
- if ((w - bi) < 8) end = w - bi;
- else end = 8;
- for (bj = 0; bj < end; bj++)
- {
- *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
- tp++;
- }
- dp++;
- }
- if ((dx < (ext_x + ext_w)) &&
- (dy >= (ext_y)) &&
- (dy < (ext_y + ext_h)))
- {
- if (dx + w > (ext_x + ext_w))
- in_w += (dx + w) - (ext_x + ext_w);
- if (dx < ext_x)
- {
- in_w += ext_x - dx;
- in_x = ext_x - dx;
- dx = ext_x;
- }
- if (in_w < w)
- {
- func(NULL, tmpbuf + in_x, dc->col.col,
- im + (dy * im_w) + dx, w - in_w);
- }
- }
+
+ tp = tmpbuf;
+ dp = data + (i * fg->glyph_out->bitmap.pitch);
+ for (bi = 0; bi < w; bi += 8)
+ {
+ bits = *dp;
+ if ((w - bi) < 8) end = w - bi;
+ else end = 8;
+ for (bj = 0; bj < end; bj++)
+ {
+ *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
+ tp++;
+ }
+ dp++;
+ }
+ if ((dx < (ext_x + ext_w)) &&
+ (dy >= (ext_y)) &&
+ (dy < (ext_y + ext_h)))
+ {
+ if (dx + w > (ext_x + ext_w))
+ in_w += (dx + w) - (ext_x + ext_w);
+ if (dx < ext_x)
+ {
+ in_w += ext_x - dx;
+ in_x = ext_x - dx;
+ dx = ext_x;
+ }
+ if (in_w < w)
+ {
+ func(NULL, tmpbuf + in_x, dc->col.col,
+ im + (dy * im_w) + dx, w - in_w);
+ }
}
}
}
else
break;
}
+}
+
+EAPI void
+evas_common_font_draw_prepare(Evas_Text_Props *text_props)
+{
+ RGBA_Font_Int *fi;
+ EVAS_FONT_WALK_TEXT_INIT();
+
+ fi = text_props->font_instance;
+ if (!fi) return;
+
+ if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
+ return ;
+
+ if (!text_props->bin) text_props->bin = eina_binbuf_new();
+ else eina_binbuf_reset(text_props->bin);
+
+ evas_common_font_int_reload(fi);
+
+ if (fi->src->current_size != fi->size)
+ {
+ evas_common_font_source_reload(fi->src);
+ FTLOCK();
+ FT_Activate_Size(fi->ft.size);
+ FTUNLOCK();
+ fi->src->current_size = fi->size;
+ }
+
+ EVAS_FONT_WALK_TEXT_START()
+ {
+ Evas_Glyph glyph;
+ RGBA_Font_Glyph *fg;
+ FT_UInt idx;
+
+ if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
+ idx = EVAS_FONT_WALK_INDEX;
+
+ fg = evas_common_font_int_cache_glyph_get(fi, idx);
+ if (!fg) continue;
+ if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
+
+ glyph.fg = fg;
+ glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
+ glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
+ glyph.coord.w = fg->glyph_out->bitmap.width;
+ glyph.coord.h = fg->glyph_out->bitmap.rows;
+ glyph.j = fg->glyph_out->bitmap.pitch;
+ glyph.idx = idx;
+ glyph.data = fg->glyph_out->bitmap.buffer;
+
+ eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph));
+ }
EVAS_FONT_WALK_TEXT_END();
- evas_common_font_int_use_trim();
+
+ text_props->generation = fi->generation;
}
EAPI void
-evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Evas_Text_Props *text_props)
+evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props)
{
int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h;
if (ext_w <= 0) return;
if (ext_h <= 0) return;
-#ifdef EVAS_FRAME_QUEUING
- LKL(fn->lock);
-#endif
// evas_common_font_size_use(fn);
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
if (!dc->cutout.rects)
{
- evas_common_font_draw_internal(dst, dc, fn, x, y, text_props,
+ evas_common_font_draw_internal(dst, dc, x, y, text_props,
func, ext_x, ext_y, ext_w, ext_h,
im_w, im_h);
}
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
- evas_common_font_draw_internal(dst, dc, fn, x, y, text_props,
+ evas_common_font_draw_internal(dst, dc, x, y, text_props,
func, r->x, r->y, r->w, r->h,
im_w, im_h);
}
}
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(fn->lock);
-#endif
}
-
-/* Only used if cache is on */
-#if defined(METRIC_CACHE) || defined(WORD_CACHE)
-
-static Eina_Bool
-_evas_font_word_prerender_text_props_equal(const Evas_Text_Props *_a, const Evas_Text_Props *_b)
-{
- Evas_Font_Glyph_Info *gl1, *gl2;
- size_t i;
-
- if ((_a->len != _b->len) ||
- (_a->font_instance != _b->font_instance))
- return EINA_FALSE;
-
- gl1 = _a->info->glyph + _a->start;
- gl2 = _b->info->glyph + _b->start;
- i = _a->len;
- for ( ; (i > 0) && (gl1->index == gl2->index) ; i--, gl1++, gl2++)
- ;
-
- return (i == 0);
-}
-
-static struct prword *
-evas_font_word_prerender(RGBA_Draw_Context *dc, const Evas_Text_Props *text_props)
-{
- struct cinfo *metrics;
- unsigned char *im;
- int width;
- int height, above, below, baseline, descent;
- unsigned int i,j;
- struct prword *w;
- int last_delta = 0;
- Eina_Unicode gl;
- struct cinfo *ci;
- unsigned int len = text_props->len;
- RGBA_Font_Int *fi = (RGBA_Font_Int *) text_props->font_instance;
- EVAS_FONT_WALK_TEXT_INIT();
-
-# ifndef METRIC_CACHE
- gl = dc->font_ext.func.gl_new ? 1: 0;
- if (gl) return NULL;
-# endif
-
- LKL(lock_words);
- EINA_INLIST_FOREACH(words,w)
- {
- if (_evas_font_word_prerender_text_props_equal(&w->text_props,
- text_props))
- {
- words = eina_inlist_promote(words, EINA_INLIST_GET(w));
- LKU(lock_words);
- return w;
- }
- }
- LKU(lock_words);
-
- gl = dc->font_ext.func.gl_new ? 1: 0;
-
- above = 0; below = 0; baseline = 0; height = 0; descent = 0;
-
- /* First pass: Work out how big and populate */
- metrics = malloc(sizeof(struct cinfo) * len);
- ci = metrics;
- EVAS_FONT_WALK_TEXT_START()
- {
- FT_UInt index;
- RGBA_Font_Glyph *fg;
- index = EVAS_FONT_WALK_INDEX;
- LKL(fi->ft_mutex);
- fg = evas_common_font_int_cache_glyph_get(fi, index);
- if (!fg)
- {
- LKU(fi->ft_mutex);
- continue;
- }
-
- LKU(fi->ft_mutex);
- EVAS_FONT_WALK_TEXT_WORK();
- /* Currently broken with invisible chars if (!EVAS_FONT_WALK_IS_VISIBLE) continue; */
- ci->index = index;
- ci->fg = fg;
-
- if (gl)
- {
- ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
- ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
- }
- ci->bm.data = ci->fg->glyph_out->bitmap.buffer;
- ci->bm.w = MAX(ci->fg->glyph_out->bitmap.pitch,
- ci->fg->glyph_out->bitmap.width);
- ci->bm.rows = ci->fg->glyph_out->bitmap.rows;
- ci->bm.h = ci->fg->glyph_out->top;
- above = ci->bm.rows - (ci->bm.rows - ci->bm.h);
- below = ci->bm.rows - ci->bm.h;
- if (below > descent) descent = below;
- if (above > baseline) baseline = above;
- ci->pos.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
- ci->pos.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
- last_delta = EVAS_FONT_WALK_X_ADV -
- (ci->bm.w + ci->fg->glyph_out->left);
- ci++;
- }
- EVAS_FONT_WALK_TEXT_END();
-
- /* First loop done */
- width = EVAS_FONT_WALK_PEN_X;
- if (last_delta < 0)
- width -= last_delta;
- width = (width & 0x7) ? width + (8 - (width & 0x7)) : width;
-
- height = baseline + descent;
- if (!gl)
- {
- im = calloc(height, width);
- for (i = 0 ; i < len ; i ++)
- {
- struct cinfo *cin = metrics + i;
-
- for (j = 0 ; j < cin->bm.rows ; j ++)
- {
- int correction; /* Used to remove negative inset and such */
- if (cin->pos.x < 0)
- correction = -cin->pos.x;
- else
- correction = 0;
-
- memcpy(im + cin->pos.x + (j + baseline - cin->bm.h) * width +
- correction,
- cin->bm.data + j * cin->bm.w + correction,
- cin->bm.w - correction);
- }
- }
- }
- else
- {
- im = NULL;
- }
-
- /* Save it */
- struct prword *save;
-
- save = malloc(sizeof(struct prword));
- save->cinfo = metrics;
- evas_common_text_props_content_copy_and_ref(&save->text_props, text_props);
- save->im = im;
- save->width = EVAS_FONT_WALK_PEN_X;
- if (last_delta < 0)
- save->width += last_delta;
- save->roww = width;
- save->height = height;
- save->baseline = baseline;
- LKL(lock_words);
- words = eina_inlist_prepend(words, EINA_INLIST_GET(save));
-
- /* Clean up if too long */
- if (eina_inlist_count(words) > max_cached_words)
- {
- struct prword *last = (struct prword *)(words->last);
-
- if (last)
- {
- if (last->im) free(last->im);
- if (last->cinfo) free(last->cinfo);
- evas_common_text_props_content_unref(&last->text_props);
- words = eina_inlist_remove(words, EINA_INLIST_GET(last));
- free(last);
- }
- }
- LKU(lock_words);
-
- return save;
-}
-#endif
fi->real_size = fi->size * 64;
error = FT_Set_Char_Size(fi->src->ft.face, 0, fi->real_size, font_dpi, font_dpi);
if (error)
- {
- fi->real_size = fi->size;
- error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size);
- }
+ error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size);
FTUNLOCK();
if (error)
{
- int i;
+ int i, maxd = 0x7fffffff;
int chosen_size = 0;
- int chosen_width = 0;
+ int chosen_size2 = 0;
for (i = 0; i < fi->src->ft.face->num_fixed_sizes; i++)
{
- int s;
- int d, cd;
-
- s = fi->src->ft.face->available_sizes[i].height;
- cd = chosen_size - fi->size;
+ int s, cd;
+
+ s = fi->src->ft.face->available_sizes[i].size;
+ cd = chosen_size - fi->real_size;
if (cd < 0) cd = -cd;
- d = s - fi->size;
- if (d < 0) d = -d;
- if (d < cd)
- {
- chosen_width = fi->src->ft.face->available_sizes[i].width;
+ if (cd < maxd)
+ {
+ maxd = cd;
chosen_size = s;
+ chosen_size2 = fi->src->ft.face->available_sizes[i].y_ppem;
+ if (maxd == 0) break;
}
- if (d == 0) break;
}
fi->real_size = chosen_size;
FTLOCK();
- error = FT_Set_Pixel_Sizes(fi->src->ft.face, chosen_width, fi->real_size);
+ error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size);
FTUNLOCK();
if (error)
{
- /* couldn't choose the size anyway... what now? */
+ error = FT_Set_Char_Size(fi->src->ft.face, 0, fi->real_size, font_dpi, font_dpi);
+ if (error)
+ {
+ /* hack around broken fonts */
+ fi->real_size = (chosen_size2 / 64) * 60;
+ error = FT_Set_Char_Size(fi->src->ft.face, 0, fi->real_size, font_dpi, font_dpi);
+ if (error)
+ {
+ /* couldn't choose the size anyway... what now? */
+ }
+ }
}
}
fi->src->current_size = 0;
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
}
- else ret = val;
+ else
+ {
+ if ((fi->src->ft.face->bbox.yMax == 0) &&
+ (fi->src->ft.face->bbox.yMin == 0))
+ ret = (int)fi->ft.size->metrics.ascender / 64;
+ else
+ ret = val;
+ }
fi->max_h += ret;
val = -(int)fi->src->ft.face->bbox.yMin;
if (fi->src->ft.face->units_per_EM != 0)
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
}
- else ret = val;
+ else
+ {
+ if ((fi->src->ft.face->bbox.yMax == 0) &&
+ (fi->src->ft.face->bbox.yMin == 0))
+ ret = -(int)fi->ft.size->metrics.descender / 64;
+ else
+ ret = val;
+ }
fi->max_h += ret;
/* If the loaded font doesn't match with wanted_rend value requested by
fi->hinting = fn->hinting;
fn->references = 1;
LKI(fn->lock);
-#ifdef EVAS_FRAME_QUEUING
- LKI(fn->ref_fq_add);
- LKI(fn->ref_fq_del);
- eina_condition_new(&(fn->cond_fq_del), &(fn->ref_fq_del));
-#endif
if (fi->inuse) evas_common_font_int_promote(fi);
else
{
fi->hinting = fn->hinting;
fn->references = 1;
LKI(fn->lock);
-#ifdef EVAS_FRAME_QUEUING
- LKI(fn->ref_fq_add);
- LKI(fn->ref_fq_del);
- eina_condition_new(&(fn->cond_fq_del), &(fn->ref_fq_del));
-#endif
if (fi->inuse) evas_common_font_int_promote(fi);
else
{
if (!fn) return;
fn->references--;
if (fn->references > 0) return;
-#ifdef EVAS_FRAME_QUEUING
- LKL(fn->ref_fq_add);
- LKL(fn->ref_fq_del);
- if (fn->ref_fq[0] != fn->ref_fq[1])
- {
- LKU(fn->ref_fq_add);
- LKU(fn->ref_fq_del);
- return;
- }
- LKU(fn->ref_fq_add);
- LKU(fn->ref_fq_del);
-#endif
EINA_LIST_FOREACH(fn->fonts, l, fi)
{
fi->references--;
eina_list_free(fn->fonts);
if (fn->fash) fn->fash->freeme(fn->fash);
LKD(fn->lock);
-#ifdef EVAS_FRAME_QUEUING
- LKD(fn->ref_fq_add);
- LKD(fn->ref_fq_del);
- eina_condition_free(&(fn->cond_fq_del));
-#endif
free(fn);
}
_evas_common_font_int_clear(RGBA_Font_Int *fi)
{
int i, j, k;
-
+
LKL(fi->ft_mutex);
if (!fi->fash)
{
}
if (fi->inuse) fonts_use_usage -= fi->usage;
fi->usage = 0;
+ fi->generation++;
LKU(fi->ft_mutex);
}
#include "evas_font_private.h"
+#include <assert.h>
+
#include FT_OUTLINE_H
FT_Library evas_ft_lib = 0;
initialised--;
if (initialised != 0) return;
- LKD(lock_font_draw);
- LKD(lock_bidi);
- LKD(lock_ot);
-
evas_common_font_load_shutdown();
evas_common_font_cache_set(0);
evas_common_font_flush();
FT_Done_FreeType(evas_ft_lib);
-#ifdef EVAS_FRAME_QUEUING
- evas_common_font_draw_finish();
-#endif
evas_ft_lib = 0;
+
+ LKD(lock_font_draw);
+ LKD(lock_bidi);
+ LKD(lock_ot);
}
EAPI void
FTUNLOCK();
fi->src->current_size = fi->size;
}
- val = (int)fi->src->ft.face->bbox.yMax;
+ if ((fi->src->ft.face->bbox.yMax == 0) &&
+ (fi->src->ft.face->bbox.yMin == 0) &&
+ (fi->src->ft.face->units_per_EM == 0))
+ val = (int)fi->src->ft.face->size->metrics.ascender / 64;
+ else
+ val = (int)fi->src->ft.face->bbox.yMax;
if (fi->src->ft.face->units_per_EM == 0)
return val;
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
FTUNLOCK();
fi->src->current_size = fi->size;
}
- val = -(int)fi->src->ft.face->bbox.yMin;
+ if ((fi->src->ft.face->bbox.yMax == 0) &&
+ (fi->src->ft.face->bbox.yMin == 0) &&
+ (fi->src->ft.face->units_per_EM == 0))
+ val = -(int)fi->src->ft.face->size->metrics.descender / 64;
+ else
+ val = -(int)fi->src->ft.face->bbox.yMin;
if (fi->src->ft.face->units_per_EM == 0)
return val;
dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx)
{
RGBA_Font_Glyph *fg;
- FT_UInt hindex;
FT_Error error;
- int size;
const FT_Int32 hintflags[3] =
{ FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
- static FT_Matrix transform = {0x10000, 0x05000, 0x0000, 0x10000}; // about 12 degree.
+ static FT_Matrix transform = {0x10000, _EVAS_FONT_SLANT_TAN * 0x10000,
+ 0x00000, 0x10000};
evas_common_font_int_promote(fi);
if (fi->fash)
else if (fg) return fg;
}
- hindex = idx + (fi->hinting * 500000000);
-
// fg = eina_hash_find(fi->glyphs, &hindex);
// if (fg) return fg;
return NULL;
}
+ {
+ FT_BBox outbox;
+ FT_Glyph_Get_CBox(fg->glyph, FT_GLYPH_BBOX_UNSCALED,
+ &outbox);
+ fg->width = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMax - outbox.xMin);
+ fg->x_bear = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMin);
+ }
+
+ fg->index = idx;
+ fg->fi = fi;
+
+ if (!fi->fash) fi->fash = _fash_gl_new();
+ if (fi->fash) _fash_gl_add(fi->fash, idx, fg);
+
+// eina_hash_direct_add(fi->glyphs, &fg->index, fg);
+ return fg;
+}
+
+EAPI Eina_Bool
+evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg)
+{
+ int size;
+ FT_Error error;
+ RGBA_Font_Int *fi = fg->fi;
FTLOCK();
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
if (error)
FTUNLOCK();
free(fg);
if (!fi->fash) fi->fash = _fash_gl_new();
- if (fi->fash) _fash_gl_add(fi->fash, idx, (void *)(-1));
- return NULL;
+ if (fi->fash) _fash_gl_add(fi->fash, fg->index, (void *)(-1));
+ return EINA_FALSE;
}
FTUNLOCK();
fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
- fg->index = hindex;
- fg->fi = fi;
-
- if (!fi->fash) fi->fash = _fash_gl_new();
- if (fi->fash) _fash_gl_add(fi->fash, idx, fg);
/* This '+ 200' is just an estimation of how much memory freetype will use
* on it's size. This value is not really used anywhere in code - it's
* only for statistics. */
fi->usage += size;
if (fi->inuse) evas_common_font_int_use_increase(size);
-// eina_hash_direct_add(fi->glyphs, &fg->index, fg);
- return fg;
+ return EINA_TRUE;
}
typedef struct _Font_Char_Index Font_Char_Index;
}
static void
-_evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Int *fi)
+_evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Int *fi, Evas_Text_Props_Mode mode)
{
/* Create hb_font if not previously created */
if (!fi->ft.hb_font)
_evas_common_font_ot_font_funcs_get(), fi, NULL);
}
- hb_shape(fi->ft.hb_font, buffer, NULL, 0);
+ if (mode == EVAS_TEXT_PROPS_MODE_SHAPE)
+ {
+ hb_shape(fi->ft.hb_font, buffer, NULL, 0);
+ }
+ else
+ {
+ const char *shaper_list[] = { "fallback", NULL };
+ hb_shape_full(fi->ft.hb_font, buffer, NULL, 0, shaper_list);
+ }
}
EAPI Eina_Bool
evas_common_font_ot_populate_text_props(const Eina_Unicode *text,
- Evas_Text_Props *props, int len)
+ Evas_Text_Props *props, int len, Evas_Text_Props_Mode mode)
{
RGBA_Font_Int *fi;
hb_buffer_t *buffer;
/* FIXME: add run-time conversions if needed, which is very unlikely */
hb_buffer_add_utf32(buffer, (const uint32_t *) text, slen, 0, slen);
- _evas_common_font_ot_shape(buffer, fi);
+ _evas_common_font_ot_shape(buffer, fi, mode);
props->len = hb_buffer_get_length(buffer);
props->info->ot = calloc(props->len,
EAPI Eina_Bool
evas_common_font_ot_populate_text_props(const Eina_Unicode *text,
- Evas_Text_Props *props, int len);
+ Evas_Text_Props *props, int len, Evas_Text_Props_Mode mode);
#endif
extern LK(lock_font_draw); // for freetype2 API calls
extern LK(lock_bidi); // for fribidi API calls
extern LK(lock_ot); // for harfbuzz calls
-#endif
-
-# if defined(EVAS_FRAME_QUEUING) || defined(BUILD_PIPE_RENDER)
-# define FTLOCK() LKL(lock_font_draw)
+# define FTLOCK() LKL(lock_font_draw)
# define FTUNLOCK() LKU(lock_font_draw)
-# define BIDILOCK() LKL(lock_bidi)
+# define BIDILOCK() LKL(lock_bidi)
# define BIDIUNLOCK() LKU(lock_bidi)
-# define OTLOCK() LKL(lock_ot)
+/* Macros for text walking */
+# define OTLOCK() LKL(lock_ot)
# define OTUNLOCK() LKU(lock_ot)
-# else
-# define FTLOCK(x)
-# define FTUNLOCK(x)
+#else
+# define FTLOCK()
+# define FTUNLOCK()
# define BIDILOCK()
# define BIDIUNLOCK()
/* Macros for text walking */
# define OTLOCK()
# define OTUNLOCK()
-# endif
+#endif
void evas_common_font_source_unload(RGBA_Font_Source *fs);
void evas_common_font_source_reload(RGBA_Font_Source *fs);
Evas_Coord ret_adv = 0;
if (text_props->len > 0)
{
+ RGBA_Font_Int *fi = text_props->font_instance;
const Evas_Font_Glyph_Info *glyph = text_props->info->glyph +
text_props->start;
- ret_adv = glyph[text_props->len - 1].pen_after;
+ const Evas_Font_Glyph_Info *last_glyph = glyph + text_props->len - 1;
+ ret_adv = last_glyph->pen_after;
if (text_props->start > 0)
ret_adv -= glyph[-1].pen_after;
+
+#if 0
+ /* Runtime slant adjustment. */
+ if (fi->runtime_rend & FONT_REND_SLANT)
+ {
+ RGBA_Font_Glyph *fg =
+ evas_common_font_int_cache_glyph_get(fi, last_glyph->index);
+ if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
+ ret_adv += fg->glyph_out->bitmap.rows * _EVAS_FONT_SLANT_TAN;
+ }
+#endif
}
if (h_adv) *h_adv = ret_adv;
/* EAPI RGBA_Image *evas_common_image_create (int w, int h); */
EAPI RGBA_Image *evas_common_image_new (unsigned int w, unsigned int h, unsigned int alpha);
EAPI Evas_Cache_Image *evas_common_image_cache_get (void);
+#ifdef EVAS_CSERVE2
+EAPI Evas_Cache2 *evas_common_image_cache2_get (void);
+#endif
EAPI void evas_common_image_set_cache (unsigned int size);
EAPI int evas_common_image_get_cache (void);
EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error);
EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+EAPI void evas_common_rgba_image_scalecache_init(Image_Entry *ie);
+EAPI void evas_common_rgba_image_scalecache_shutdown(Image_Entry *ie);
EAPI void evas_common_rgba_image_scalecache_size_set(unsigned int size);
EAPI unsigned int evas_common_rgba_image_scalecache_size_get(void);
EAPI void evas_common_rgba_image_scalecache_flush(void);
#include "evas_common.h"
#include "evas_private.h"
#include "evas_cs.h"
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
struct ext_loader_s
{
}
}
#endif
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ ERR("This function shouldn't be called anymore!");
+ // DBG("try cserve2 '%s' '%s'", ie->file, ie->key ? ie->key : "");
+ // if (evas_cserve2_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
+ // {
+ // DBG("try cserve2 '%s' '%s' loaded!",
+ // ie->file, ie->key ? ie->key : "");
+ // return EVAS_LOAD_ERROR_NONE;
+ // }
+ }
+#endif
if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode))
{
DBG("trying to open directory '%s' !", ie->file);
}
#endif
+#ifdef EVAS_CSERVE2
+ if (ie->data1)
+ {
+ ERR("This function shouldn't be called anymore!");
+ // DBG("try cserve2 image data '%s' '%s'",
+ // ie->file, ie->key ? ie->key : "");
+ // if (evas_cserve2_image_data_load(ie))
+ // {
+ // RGBA_Image *im = (RGBA_Image *)ie;
+ // im->image.data = evas_cserve2_image_data_get(ie);
+ // DBG("try cserve2 image data '%s' '%s' loaded!",
+ // ie->file, ie->key ? ie->key : "");
+ // if (im->image.data)
+ // {
+ // im->image.no_free = 1;
+ // return EVAS_LOAD_ERROR_NONE;
+ // }
+ // }
+ // return EVAS_LOAD_ERROR_GENERIC;
+ }
+#endif
+
if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC;
// printf("load data [%p] %s %s\n", ie, ie->file, ie->key);
//#define SURFDBG 1
static Evas_Cache_Image * eci = NULL;
+#ifdef EVAS_CSERVE2
+static Evas_Cache2 * eci2 = NULL;
+#endif
static int reference = 0;
/* static RGBA_Image *evas_rgba_line_buffer = NULL; */
NULL
};
+#ifdef EVAS_CSERVE2
+static const Evas_Cache2_Image_Func _evas_common_image_func2 =
+{
+ // _evas_common_rgba_image_new,
+ // _evas_common_rgba_image_delete,
+ _evas_common_rgba_image_surface_alloc,
+ _evas_common_rgba_image_surface_delete,
+ _evas_common_rgba_image_surface_pixels,
+ // evas_common_load_rgba_image_module_from_file,
+ // _evas_common_rgba_image_unload,
+ NULL, // _evas_common_rgba_image_dirty_region,
+ NULL, // _evas_common_rgba_image_dirty,
+ evas_common_rgba_image_size_set,
+ evas_common_rgba_image_from_copied_data,
+ evas_common_rgba_image_from_data,
+ NULL, // evas_common_rgba_image_colorspace_set,
+ // evas_common_load_rgba_image_data_from_file,
+ _evas_common_rgba_image_ram_usage,
+/* _evas_common_rgba_image_debug */
+ NULL
+};
+#endif
+
EAPI void
evas_common_image_init(void)
{
if (!eci)
eci = evas_cache_image_init(&_evas_common_image_func);
+#ifdef EVAS_CSERVE2
+ if (!eci2)
+ eci2 = evas_cache2_init(&_evas_common_image_func2);
+#endif
reference++;
//// ERR("REF++=%i", reference);
// ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
evas_cache_image_shutdown(eci);
eci = NULL;
+#ifdef EVAS_CSERVE2
+ evas_cache2_shutdown(eci2);
+ eci2 = NULL;
+#endif
}
#ifdef BUILD_LOADER_EET
if (!im) return NULL;
im->flags = RGBA_IMAGE_NOTHING;
im->ref = 1;
-#ifdef EVAS_FRAME_QUEUING
- LKI(im->cache_entry.ref_fq_add);
- LKI(im->cache_entry.ref_fq_del);
- eina_condition_new(&(im->cache_entry.cond_fq_del),
- &(im->cache_entry.ref_fq_del));
-#endif
evas_common_rgba_image_scalecache_init(&im->cache_entry);
#ifdef BUILD_PIPE_RENDER
evas_common_pipe_free(im);
-# ifdef EVAS_FRAME_QUEUING
- LKD(im->cache_entry.ref_fq_add);
- LKD(im->cache_entry.ref_fq_del);
- eina_condition_free(&(im->cache_entry.cond_fq_del));
-# endif
#endif
evas_common_rgba_image_scalecache_shutdown(&im->cache_entry);
if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module);
#ifdef EVAS_CSERVE
if (ie->data1) evas_cserve_image_free(ie);
#endif
+#ifdef EVAS_CSERVE2
+ if (ie->data1)
+ ERR("Shouldn't reach this point since we are using cache2: '%s' '%s'",
+ ie->file, ie->key);
+ // if (ie->data1) evas_cserve2_image_free(ie);
+#endif
/*
* FIXME: This doesn't seem to be needed... But I'm not sure why.
* -- nash
}
#endif
+#ifdef EVAS_CSERVE2
+ if (ie->data1)
+ {
+ ERR("Shouldn't reach this point since we are using cache2.");
+// evas_cserve2_image_unload(ie);
+// im->image.data = NULL;
+// ie->allocated.w = 0;
+// ie->allocated.h = 0;
+// ie->flags.loaded = 0;
+#ifdef BUILD_ASYNC_PRELOAD
+ ie->flags.preload_done = 0;
+#endif
+ return;
+ }
+#endif
+
if (im->image.data && !im->image.no_free)
{
free(im->image.data);
#ifdef EVAS_CSERVE
if (ie->data1) return 0;
#endif
+#ifdef EVAS_CSERVE2
+ if (ie->data1) return 0;
+#endif
if (im->image.no_free) return 0;
if (im->flags & RGBA_IMAGE_ALPHA_ONLY)
else if (ie->data1)
evas_cserve_image_free(ie);
#endif
+// #ifdef EVAS_CSERVE2
+// else if (ie->data1)
+// ERR("Shouldn't reach this point since we are using cache2.");
+// // evas_cserve2_image_free(ie);
+// #endif
im->image.data = NULL;
ie->allocated.w = 0;
#ifdef EVAS_CSERVE
if (ie->data1) evas_cserve_image_free(ie);
#endif
+#ifdef EVAS_CSERVE2
+ // if (ie->data1) evas_cserve2_image_free(ie);
+ if (ie->data1) ERR("Shouldn't reach this point since we are using cache2.");
+#endif
im->flags |= RGBA_IMAGE_IS_DIRTY;
evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
}
#ifdef EVAS_CSERVE
if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
#endif
+#ifdef EVAS_CSERVE2
+ // if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
+ if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
+#endif
return 1;
}
#ifdef EVAS_CSERVE
if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
#endif
+#ifdef EVAS_CSERVE2
+ // if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
+ if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
+#endif
evas_common_image_colorspace_normalize(src);
evas_common_image_colorspace_normalize(dst);
/* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
if (im->image.data)
{
-#ifdef EVAS_CSERVE
+#if defined(EVAS_CSERVE)
+ if ((!im->image.no_free) || (ie->data1))
+#elif defined(EVAS_CSERVE2)
if ((!im->image.no_free) || (ie->data1))
#else
if ((!im->image.no_free))
#ifdef EVAS_CSERVE
if (((Image_Entry *)im)->data1) evas_cserve_image_free(&im->cache_entry);
#endif
+#ifdef EVAS_CSERVE2
+ // if (((Image_Entry *)im)->data1) evas_cserve2_image_free(&im->cache_entry);
+ if (((Image_Entry *)im)->data1) ERR("Shouldn't reach this point since we are using cache2.");
+#endif
if (!im->image.no_free)
{
free(im->image.data);
{
im->cs.dirty = 1;
evas_common_rgba_image_scalecache_dirty(&im->cache_entry);
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_IMAGE
+ if (im->pixman.im)
+ {
+ pixman_image_unref(im->pixman.im);
+ im->pixman.im = NULL;
+ }
+ _evas_common_rgba_image_post_surface((Image_Entry *)im);
+# endif
+#endif
}
EAPI void
{
if (eci)
evas_cache_image_set(eci, size);
+#ifdef EVAS_CSERVE2
+ if (eci2)
+ evas_cache2_limit_set(eci2, size);
+#endif
}
EAPI int
return eci;
}
+#ifdef EVAS_CSERVE2
+EAPI Evas_Cache2*
+evas_common_image_cache2_get(void)
+{
+ return eci2;
+}
+#endif
+
EAPI RGBA_Image *
evas_common_image_line_buffer_obtain(int len)
{
void evas_common_scalecache_init(void);
void evas_common_scalecache_shutdown(void);
-void evas_common_rgba_image_scalecache_init(Image_Entry *ie);
-void evas_common_rgba_image_scalecache_shutdown(Image_Entry *ie);
void evas_common_rgba_image_scalecache_dirty(Image_Entry *ie);
void evas_common_rgba_image_scalecache_orig_use(Image_Entry *ie);
int evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie);
#include <assert.h>
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
#include "evas_common.h"
#include "evas_private.h"
#include "evas_image_private.h"
unsigned int dst_w, dst_h;
unsigned int flop;
unsigned int size_adjust;
-#ifdef EVAS_FRAME_QUEUING
- RWLK(lock);
-#endif
Eina_Bool forced_unload : 1;
Eina_Bool smooth : 1;
Eina_Bool populate_me : 1;
{
Scaleitem *sci;
sci = im->cache.list->data;
-#ifdef EVAS_FRAME_QUEUING
- WRLKL(sci->lock);
-#endif
im->cache.list = eina_list_remove(im->cache.list, sci);
if (sci->im)
{
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
LKU(cache_lock);
}
-#ifdef EVAS_FRAME_QUEUING
- RWLKU(sci->lock);
- RWLKD(sci->lock);
-#endif
free(sci);
}
LKU(im->cache.lock);
{
l = eina_list_last(im->cache.list);
sci = l->data;
-#ifdef EVAS_FRAME_QUEUING
- WRLKL(sci->lock);
-#endif
im->cache.list = eina_list_remove_list(im->cache.list, l);
if ((sci->usage == im->cache.newest_usage) ||
(sci->usage_count == im->cache.newest_usage_count))
// INF(" 1- %i", sci->dst_w * sci->dst_h * 4);
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
}
-#ifdef EVAS_FRAME_QUEUING
- RWLKU(sci->lock);
-#endif
if (max_scale_items < 1) return NULL;
}
else
return NULL;
sci = calloc(1, sizeof(Scaleitem));
sci->parent_im = im;
-#ifdef EVAS_FRAME_QUEUING
- RWLKI(sci->lock);
-#endif
}
sci->usage = 0;
sci->usage_count = 0;
if (!sci) return;
}
if (sci == notsci) return;
-#ifdef EVAS_FRAME_QUEUING
- WRLKL(sci->lock);
-#endif
if (sci->im)
{
evas_common_rgba_image_free(&sci->im->cache_entry);
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
memset(sci, 0, sizeof(Eina_Inlist));
}
-#ifdef EVAS_FRAME_QUEUING
- RWLKU(sci->lock);
-#endif
-
// INF("FLUSH %i > %i", cache_size, max_cache_size);
}
}
LKL(im->cache.lock);
if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
{
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
+ if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
#endif
- {
- if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
- evas_common_image_colorspace_normalize(im);
- }
+ }
+ evas_common_image_colorspace_normalize(im);
+
// noscales++;
LKU(im->cache.lock);
if (im->image.data)
LKU(cache_lock);
if (!sci)
{
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
-#endif
+ if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
{
- if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&im->cache_entry);
- evas_common_image_colorspace_normalize(im);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&im->cache_entry);
}
+ evas_common_image_colorspace_normalize(im);
+
// misses++;
LKU(im->cache.lock);
if (im->image.data)
evas_common_draw_context_set_render_op(ct, _EVAS_RENDER_COPY);
}
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&im->cache_entry);
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&im->cache_entry);
+ }
evas_common_image_colorspace_normalize(im);
if (im->image.data)
{
if (sci->flop >= FLOP_DEL) sci->flop -= FLOP_DEL;
}
// INF("use cached!");
-#ifdef EVAS_FRAME_QUEUING
- RDLKL(sci->lock);
-#endif
LKU(im->cache.lock);
evas_common_scale_rgba_in_to_out_clip_sample
(sci->im, dst, dc,
dst_region_w, dst_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
-#ifdef EVAS_FRAME_QUEUING
- RWLKU(sci->lock);
-#endif
// hits++;
// INF("check %p %i < %i",
// im,
// (int)im->cache.orig_usage,
// (int)im->cache.newest_usage);
-#ifndef EVAS_FRAME_QUEUING
/* while framequeuing is applied,
* original image data is loaded by the main thread
* just before enqueuing the rendering op into the pipe.
#ifdef EVAS_CSERVE
|| (ie->data1)
#endif
+#ifdef EVAS_CSERVE2
+ || (ie->data1)
+#endif
) &&
(im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)))
{
(im->cache.newest_usage / 20)))
{
//FIXME: imagedataunload - inform owners
- evas_common_rgba_image_unload(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_unload_data(&im->cache_entry);
+ else
+#endif
+ evas_common_rgba_image_unload(&im->cache_entry);
}
}
}
-#endif
}
else
{
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
-#endif
+ if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
{
- if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&im->cache_entry);
- evas_common_image_colorspace_normalize(im);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&im->cache_entry);
}
+ evas_common_image_colorspace_normalize(im);
// misses++;
LKU(im->cache.lock);
if (im->image.data)
}
#else
RGBA_Image *im = (RGBA_Image *)ie;
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
-#endif
+ if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
{
- if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&im->cache_entry);
- evas_common_image_colorspace_normalize(im);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&im->cache_entry);
}
+ evas_common_image_colorspace_normalize(im);
if (im->image.data)
{
if (smooth)
pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
if (dc->render_op == _EVAS_RENDER_BLEND)
op = PIXMAN_OP_OVER;
-# endif
+# endif
#endif
dstw = dst->cache_entry.w;
if (dy == 0)
{
-#ifdef EVAS_SLI
- if (((y0) % dc->sli.h) == dc->sli.y)
-#endif
- {
- if ((y0 >= ty) && (y0 <= by))
- {
- if (dx < 0)
- {
- int tmp = x1;
+ if ((y0 >= ty) && (y0 <= by))
+ {
+ if (dx < 0)
+ {
+ int tmp = x1;
- x1 = x0;
- x0 = tmp;
- }
+ x1 = x0;
+ x0 = tmp;
+ }
- if (x0 < lx) x0 = lx;
- if (x1 > rx) x1 = rx;
+ if (x0 < lx) x0 = lx;
+ if (x1 > rx) x1 = rx;
- len = x1 - x0 + 1;
- p = dst->image.data + (dstw * y0) + x0;
+ len = x1 - x0 + 1;
+ p = dst->image.data + (dstw * y0) + x0;
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
- if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (!dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- NULL, dst->pixman.im,
- x0, y0, 0, 0, x0, y0, len, 1);
- else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- dc->mask.mask->pixman.im,
- dst->pixman.im,
- x0, y0, 0, 0, x0, y0, len, 1);
- else
-# endif
+ if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (!dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ NULL, dst->pixman.im,
+ x0, y0, 0, 0, x0, y0, len, 1);
+ else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ dc->mask.mask->pixman.im,
+ dst->pixman.im,
+ x0, y0, 0, 0, x0, y0, len, 1);
+ else
+# endif
#endif
- {
- sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, dc->render_op);
- if (sfunc)
- sfunc(NULL, NULL, color, p, len);
- }
+ {
+ sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, dc->render_op);
+ if (sfunc)
+ sfunc(NULL, NULL, color, p, len);
}
}
return;
if (dx == 0)
{
- if ((x0 >= lx) && (x0 <= rx))
- {
- if (y0 < ty) y0 = ty;
- if (y1 > by) y1 = by;
+ if ((x0 >= lx) && (x0 <= rx))
+ {
+ if (y0 < ty) y0 = ty;
+ if (y1 > by) y1 = by;
- len = y1 - y0 + 1;
- p = dst->image.data + (dstw * y0) + x0;
+ len = y1 - y0 + 1;
+ p = dst->image.data + (dstw * y0) + x0;
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
dc->mask.mask->pixman.im, dst->pixman.im,
x0, y0, 0, 0, x0, y0, 1, len);
else
-# endif
+# endif
#endif
{
while (len--)
{
-#ifdef EVAS_SLI
- if (((y1 + 1 - len) % dc->sli.h) == dc->sli.y)
-#endif
- {
- pfunc(0, 255, color, p);
- }
+ pfunc(0, 255, color, p);
p += dstw;
}
}
}
- return;
+ return;
}
if ((dy == dx) || (dy == -dx))
{
- int p0_in, p1_in;
+ int p0_in, p1_in;
- p0_in = (IN_RECT(x0, y0, clx, cly, clw, clh) ? 1 : 0);
- p1_in = (IN_RECT(x1, y1, clx, cly, clw, clh) ? 1 : 0);
+ p0_in = (IN_RECT(x0, y0, clx, cly, clw, clh) ? 1 : 0);
+ p1_in = (IN_RECT(x1, y1, clx, cly, clw, clh) ? 1 : 0);
- if (dy > 0)
- {
- if (!p0_in)
- {
- x0 = x0 + (ty - y0);
- y0 = ty;
- if (x0 > rx) return;
- if (x0 < lx)
- {
- y0 = y0 + (lx - x0);
- x0 = lx;
- if ((y0 < ty) || (y0 > by)) return;
- }
- }
- if (!p1_in)
- {
- x1 = x0 + (by - y0);
- y1 = by;
- if (x1 < lx) return;
- if (x1 > rx)
- {
- y1 = y0 + (rx - x0);
- x1 = rx;
- if ((y1 < ty) || (y1 > by)) return;
- }
- }
- }
- else
- {
- if (!p0_in)
- {
- x0 = x0 - (by - y0);
- y0 = by;
- if (x0 > rx) return;
- if (x0 < lx)
- {
- y0 = y0 - (lx - x0);
- x0 = lx;
- if ((y0 < ty) || (y0 > by)) return;
- }
- }
- if (!p1_in)
- {
- x1 = x0 - (ty - y0);
- y1 = ty;
- if (x1 < lx) return;
- if (x1 > rx)
- {
- y1 = y0 - (rx - x0);
- x1 = rx;
- if ((y1 < ty) || (y1 > by)) return;
- }
- }
- }
- if (y1 > y0)
- {
- p = dst->image.data + (dstw * y0) + x0;
- len = y1 - y0 + 1;
- if (dx > 0) dstw++;
- else dstw--;
- }
- else
- {
- len = y0 - y1 + 1;
- p = dst->image.data + (dstw * y1) + x1;
- if (dx > 0) dstw--;
- else dstw++;
- }
+ if (dy > 0)
+ {
+ if (!p0_in)
+ {
+ x0 = x0 + (ty - y0);
+ y0 = ty;
+ if (x0 > rx) return;
+ if (x0 < lx)
+ {
+ y0 = y0 + (lx - x0);
+ x0 = lx;
+ if ((y0 < ty) || (y0 > by)) return;
+ }
+ }
+ if (!p1_in)
+ {
+ x1 = x0 + (by - y0);
+ y1 = by;
+ if (x1 < lx) return;
+ if (x1 > rx)
+ {
+ y1 = y0 + (rx - x0);
+ x1 = rx;
+ if ((y1 < ty) || (y1 > by)) return;
+ }
+ }
+ }
+ else
+ {
+ if (!p0_in)
+ {
+ x0 = x0 - (by - y0);
+ y0 = by;
+ if (x0 > rx) return;
+ if (x0 < lx)
+ {
+ y0 = y0 - (lx - x0);
+ x0 = lx;
+ if ((y0 < ty) || (y0 > by)) return;
+ }
+ }
+ if (!p1_in)
+ {
+ x1 = x0 - (ty - y0);
+ y1 = ty;
+ if (x1 < lx) return;
+ if (x1 > rx)
+ {
+ y1 = y0 - (rx - x0);
+ x1 = rx;
+ if ((y1 < ty) || (y1 > by)) return;
+ }
+ }
+ }
+ if (y1 > y0)
+ {
+ p = dst->image.data + (dstw * y0) + x0;
+ len = y1 - y0 + 1;
+ if (dx > 0) dstw++;
+ else dstw--;
+ }
+ else
+ {
+ len = y0 - y1 + 1;
+ p = dst->image.data + (dstw * y1) + x1;
+ if (dx > 0) dstw--;
+ else dstw++;
+ }
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
int pixman_x_position = x0;
int pixman_y_position = y0;
int x_unit = dstw - dst->cache_entry.w;
-# endif
-#endif
-
-
- while (len--)
- {
-#ifdef EVAS_SLI
- if (((y1 + 1 - len) % dc->sli.h) == dc->sli.y)
+# endif
#endif
- {
+ while (len--)
+ {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
- if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (!dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- NULL, dst->pixman.im,
- pixman_x_position,
- pixman_y_position,
- 0, 0, pixman_x_position,
- pixman_y_position, 1, 1);
- else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- dc->mask.mask->pixman.im,
- dst->pixman.im,
- pixman_x_position,
- pixman_y_position, 0, 0,
- pixman_x_position,
- pixman_y_position, 1, 1);
- else
-# endif
+ if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (!dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ NULL, dst->pixman.im,
+ pixman_x_position,
+ pixman_y_position,
+ 0, 0, pixman_x_position,
+ pixman_y_position, 1, 1);
+ else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ dc->mask.mask->pixman.im,
+ dst->pixman.im,
+ pixman_x_position,
+ pixman_y_position, 0, 0,
+ pixman_x_position,
+ pixman_y_position, 1, 1);
+ else
+# endif
#endif
- pfunc(0, 255, color, p);
- }
+ pfunc(0, 255, color, p);
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
pixman_x_position += x_unit;
pixman_y_position += 1;
-# endif
+# endif
#endif
p += dstw;
- }
+ }
}
}
-
#define SETUP_LINE_SHALLOW \
if (x0 > x1) \
{ \
{
if (py < 0) goto next_x;
}
-#ifdef EVAS_SLI
- if (((py) % dc->sli.h) == dc->sli.y)
-#endif
- {
- if (IN_RANGE(px, py, clw, clh))
- {
+ if (IN_RANGE(px, py, clw, clh))
+ {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
- if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (!dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- NULL, dst->pixman.im,
- pix_x, pix_y, 0, 0,
- pix_x, pix_y, 1, 1);
- else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- dc->mask.mask->pixman.im,
- dst->pixman.im,
- pix_x, pix_y, 0, 0,
- pix_x, pix_y, 1, 1);
- else
+ if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (!dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ NULL, dst->pixman.im,
+ pix_x, pix_y, 0, 0,
+ pix_x, pix_y, 1, 1);
+ else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ dc->mask.mask->pixman.im,
+ dst->pixman.im,
+ pix_x, pix_y, 0, 0,
+ pix_x, pix_y, 1, 1);
+ else
# endif
#endif
- pfunc(0, 255, color, p);
- }
- }
+ pfunc(0, 255, color, p);
+ }
+
next_x:
- yy += dyy;
- px++;
- p++;
+ yy += dyy;
+ px++;
+ p++;
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
- pix_x += pix_x_unit;
+ pix_x += pix_x_unit;
# endif
#endif
}
{
if (px < 0) goto next_y;
}
-#ifdef EVAS_SLI
- if (((py) % dc->sli.h) == dc->sli.y)
-#endif
- {
- if (IN_RANGE(px, py, clw, clh))
- {
+ if (IN_RANGE(px, py, clw, clh))
+ {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_LINE
- if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (!dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- NULL, dst->pixman.im,
- pix_x, pix_y, 0, 0,
- pix_x, pix_y, 1, 1);
- else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- dc->mask.mask->pixman.im,
- dst->pixman.im,
- pix_x, pix_y, 0, 0,
- pix_x, pix_y, 1, 1);
- else
+ if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (!dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ NULL, dst->pixman.im,
+ pix_x, pix_y, 0, 0,
+ pix_x, pix_y, 1, 1);
+ else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ dc->mask.mask->pixman.im,
+ dst->pixman.im,
+ pix_x, pix_y, 0, 0,
+ pix_x, pix_y, 1, 1);
+ else
# endif
#endif
- pfunc(0, 255, color, p);
- }
+ pfunc(0, 255, color, p);
}
next_y:
xx += dxx;
pix_y += pix_y_unit;
# endif
#endif
-
}
}
#include "evas_common.h"
#include "evas_blend_private.h"
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
#ifdef BUILD_SCALE_SMOOTH
# ifdef BUILD_MMX
int i;
if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&src->cache_entry);
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&src->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&src->cache_entry);
+ }
evas_common_image_colorspace_normalize(src);
if (!src->image.data) return;
#ifdef BUILD_MMX
#include <unistd.h>
#ifdef BUILD_PIPE_RENDER
-
-#ifdef EVAS_FRAME_QUEUING
-#define SCALECACHE
-static Evas_FrameQ gframeq; // global frameQ
-
-static Evas_Surface *
-evas_common_surface_alloc(void *surface, int x, int y, int w, int h)
-{
- Evas_Surface *e_surface;
-
- e_surface = calloc(1, sizeof(Evas_Surface));
- e_surface->im = surface;
- LKL(e_surface->im->cache_entry.ref_fq_add);
- e_surface->im->cache_entry.ref_fq[0]++;
- LKU(e_surface->im->cache_entry.ref_fq_add);
- e_surface->x = x;
- e_surface->y = y;
- e_surface->w = w;
- e_surface->h = h;
-
- return e_surface;
-}
-
-static void
-evas_common_surface_dealloc(Evas_Surface *surface)
-{
- Evas_Surface *d_surface;
-
- while (surface)
- {
- d_surface = surface;
- surface = (Evas_Surface *)eina_inlist_remove(EINA_INLIST_GET(surface), EINA_INLIST_GET(d_surface));
- LKL(d_surface->im->cache_entry.ref_fq_del);
- d_surface->im->cache_entry.ref_fq[1]++;
- LKU(d_surface->im->cache_entry.ref_fq_del);
- free(d_surface);
- }
-}
-
-static void
-evas_common_surface_add(Evas_Frame *frame, Evas_Surface *surface)
-{
- frame->surfaces = (Evas_Surface *)eina_inlist_append(EINA_INLIST_GET(frame->surfaces), EINA_INLIST_GET(surface));
-}
-
-static Evas_Frame *
-evas_common_frame_alloc(void)
-{
- Evas_Frame *frame;
-
- frame = calloc(1, sizeof(Evas_Frame));
- frame->surfaces = NULL;
- return frame;
-}
-
-static void
-evas_common_frame_dealloc(Evas_Frame *frame)
-{
- evas_common_surface_dealloc(frame->surfaces);
- free(frame);
-}
-
-static void
-evas_common_frame_add(Evas_FrameQ *frameq, Evas_Frame *frame)
-{
- Evas_Frame *temp_frame;
-
- LKL(frameq->mutex);
- while ((int)eina_inlist_count(EINA_INLIST_GET(frameq->frames)) >= frameq->frameq_sz)
- {
- /* wait a worker thread finish previous frame */
- eina_condition_wait(&(frameq->cond_done));
- }
- frameq->frames = (Evas_Frame *) eina_inlist_append(EINA_INLIST_GET(frameq->frames), EINA_INLIST_GET(frame));
-
- // this frame need not to be scheduled for flushing time
- EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), temp_frame)
- {
- if (!temp_frame->ready)
- {
- break;
- }
- }
- if (temp_frame && temp_frame == frame)
- frame->dont_schedule = 1;
-
- LKU(frameq->mutex);
-
- eina_condition_signal(&(frameq->cond_new));
-}
-
-EAPI Evas_Surface *
-evas_common_frameq_new_surface(void *surface, int x, int y, int w, int h)
-{
- return evas_common_surface_alloc(surface, x, y, w, h);
-}
-
-EAPI void
-evas_common_frameq_add_surface(Evas_Surface *surface)
-{
- evas_common_surface_add(gframeq.cur_frame, surface);
-}
-
-EAPI void
-evas_common_frameq_set_frame_data(void *data,
- void (*fn_output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h),
- void (*fn_output_flush) (void *data),
- void (*fn_output_set_priv)(void *data, void *cur, void *prev))
-{
- if (gframeq.cur_frame)
- {
- gframeq.cur_frame->data = data;
- gframeq.cur_frame->output_redraws_next_update_push = fn_output_redraws_next_update_push;
- gframeq.cur_frame->output_flush = fn_output_flush;
- gframeq.cur_frame->output_set_priv = fn_output_set_priv;
- }
-}
-
-EAPI void
-evas_common_frameq_prepare_frame(void)
-{
- if (!gframeq.cur_frame )
- {
- gframeq.cur_frame = evas_common_frame_alloc();
- }
-}
-
-EAPI void
-evas_common_frameq_ready_frame(void)
-{
- if (gframeq.cur_frame)
- {
- evas_common_frame_add(&gframeq, gframeq.cur_frame);
- gframeq.cur_frame = NULL; // create a new frame for the next frame later
- }
-}
-
-
-EAPI void
-evas_common_frameq_init(void)
-{
- gframeq.frames = NULL;
- LKI(gframeq.mutex);
- eina_condition_new(&(gframeq.cond_new), &(gframeq.mutex));
- eina_condition_new(&(gframeq.cond_ready), &(gframeq.mutex));
- eina_condition_new(&(gframeq.cond_done), &(gframeq.mutex));
- gframeq.initialised = 0; // worker thread are not created yet
- gframeq.frameq_sz = 1; // this value ensures the first frame can be enqueued.
-}
-
-EAPI void
-evas_common_frameq_destroy(void)
-{
-#if 0 // let them destroyed indirectly with program exit
- LKL(gframeq.mutex);
- eina_condition_free(&(gframeq.cond_new));
- eina_condition_free(&(gframeq.cond_ready));
- eina_condition_free(&(gframeq.cond_done));
- LKU(gframeq.mutex);
-#endif
- LKD(gframeq.mutex);
-
- gframeq.frames = NULL;
- gframeq.initialised = 0;
-}
-
-EAPI void
-evas_common_frameq_flush(void)
-{
- if (! evas_common_frameq_enabled())
- return;
-
- LKL(gframeq.mutex);
- while(eina_inlist_count(EINA_INLIST_GET(gframeq.frames)) > 0)
- {
- /* wait a worker thread finish previous frame */
- eina_condition_wait(&(gframeq.cond_done));
- }
- LKU(gframeq.mutex);
-}
-
-
-EAPI void
-evas_common_frameq_flush_ready(void)
-{
- return;
-}
-
-EAPI int
-evas_common_frameq_get_frameq_sz(void)
-{
- return gframeq.frameq_sz;
-}
-
-EAPI int
-evas_common_frameq_enabled(void)
-{
- return gframeq.initialised;
-}
-#endif
-
static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op);
static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op);
static void evas_common_pipe_op_free(RGBA_Pipe_Op *op);
thinfo = data;
for (;;)
{
- RGBA_Pipe_Thread_Info *info;
+ const RGBA_Pipe_Thread_Info *info;
RGBA_Pipe *p;
/* wait for start signal */
// INF(" TH %i START...", thinfo->thread_num);
pthread_barrier_wait(&(thinfo->barrier[0]));
- info = thinfo->info;
-// if (info)
-// {
-// thinfo->info = NULL;
-// INF(" TH %i GO", thinfo->thread_num);
- EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
- {
- int i;
-
- for (i = 0; i < p->op_num; i++)
- {
- if (p->op[i].op_func)
- p->op[i].op_func(info->im, &(p->op[i]), info);
- }
- }
- free(info);
-// }
-// INF(" TH %i DONE", thinfo->thread_num);
- /* send finished signal */
- pthread_barrier_wait(&(thinfo->barrier[1]));
- }
- return NULL;
-}
-
-#ifdef EVAS_FRAME_QUEUING
-static void
-evas_common_frameq_release(void *data)
-{
- Evas_FrameQ *frameq;
- Evas_Frameq_Thread_Info *fq_info;
- Thinfo *thinfo;
-
- thinfo = data;
- fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info);
- frameq = fq_info->frameq;
- /* This thread may or may not own the mutex.
- * But there's no way to determine the ownership of the mutex, so release it anyway
- */
- LKU(frameq->mutex);
-}
-
-static void *
-evas_common_frameq_thread(void *data)
-{
- Evas_FrameQ *frameq;
- Evas_Frame *frame;
- Evas_Surface *surface;
- RGBA_Pipe *p;
- Thinfo *thinfo;
- Evas_Frameq_Thread_Info *fq_info;
- RGBA_Pipe_Thread_Info p_info;
-
- thinfo = data;
- fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info);
- frameq = fq_info->frameq;
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- /* install thread cancelation cleanup handler */
- pthread_cleanup_push(evas_common_frameq_release, data);
-
- for (;;)
- {
- frame = NULL;
-
- /* 1. pick a frame to draw */
- LKL(frameq->mutex);
- while(!frame)
- {
- EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), frame)
- {
- if (!frame->in_process)
- {
- frame->in_process = 1;
- break;
- }
- }
- if (frame)
- {
- break;
- }
- pthread_testcancel();
- eina_condition_wait(&(frameq->cond_new));
- }
- LKU(frameq->mutex);
-
- /* 2. draw selected frame */
- EINA_INLIST_FOREACH(EINA_INLIST_GET(frame->surfaces), surface)
+ EINA_INLIST_FOREACH(thinfo->tasks, info)
{
- p_info.im = surface->im;
- p_info.x = 0;
- p_info.y = 0;
- p_info.w = surface->im->cache_entry.w;
- p_info.h = surface->im->cache_entry.h;
-
- EINA_INLIST_FOREACH(EINA_INLIST_GET(p_info.im->cache_entry.pipe), p)
+ EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
{
int i;
for (i = 0; i < p->op_num; i++)
{
if (p->op[i].op_func)
- {
- p->op[i].op_func(p_info.im, &(p->op[i]), &p_info);
- }
- }
- }
-
- /* push surface out */
- if (! surface->dontpush)
- {
- frame->output_redraws_next_update_push(frame->data,
- surface->im, surface->x, surface->y, surface->w, surface->h);
- }
- }
-
- // record frame ready time, will be used in post worker thread, evas_common_frameq_thread_post()
- gettimeofday(&frame->ready_time, NULL);
-
- LKL(frameq->mutex);
- frame->ready = 1;
- eina_condition_signal(&(frameq->cond_ready));
- LKU(frameq->mutex);
- }
-
- // Remove cleanup handler
- pthread_cleanup_pop(0);
- return NULL;
-}
-
-
-#define INTERVAL_QSIZE 17 // Actual size is 'INTERVAL_QSIZE - 1' because of not using index
-#define SATISFACTION_THRESHOLD 4 // 4 ms --> 250 FPS
-#define RESET_RATIO 4 // RESET_RATIO * [Average Ready Gap | get_max_interval()] --> Reset Threshold
-#define DOUBLE_RESET_TIME_INTERVAL_THRESHOLD 16000 // make it double in case of less 16ms
-#define RESET_ABSOLUTE_INTERVAL 600000 // 600 msec
-
-struct iq_node
-{
- long long rt;
- long long ri;
-};
-
-static struct iq_node _IQ[INTERVAL_QSIZE];
-static int _IQ_head = 0, _IQ_tail = 0;
-static int _IQ_length = 0;
-static long long min_ready, max_ready;
-static long long average_interval;
-
-static int
-_IQ_next_index(int i)
-{
- return (i + 1) % INTERVAL_QSIZE;
-}
-
-static int
-_IQ_previous_index(int i)
-{
- if (--i < 0) i += INTERVAL_QSIZE;
- return i;
-}
-
-static void
-_IQ_init(void)
-{
- _IQ_length = _IQ_head = _IQ_tail = 0;
- min_ready = LLONG_MAX, max_ready = LLONG_MIN;
- average_interval = 0;
-}
-
-static int
-_IQ_empty(void)
-{
- return (_IQ_head == _IQ_tail) ? 1 : 0;
-}
-
-static int
-_IQ_full(void)
-{
- return (_IQ_head == ((_IQ_tail + 1) % INTERVAL_QSIZE)) ? 1 : 0;
-}
-
-static void
-_IQ_insert(long long ready_time, long long last_interval)
-{
- if (_IQ_full()) return;
-
- if (_IQ_empty())
- {
- if (last_interval < 0)
- {
- last_interval = -last_interval;
- }
- _IQ[_IQ_tail].rt = ready_time;
- _IQ[_IQ_tail].ri = last_interval;
- min_ready = ready_time - last_interval;
- max_ready = ready_time;
- _IQ_tail = _IQ_next_index(_IQ_tail);
- _IQ_length++;
- }
- else
- {
- if (max_ready < ready_time)
- {
- _IQ[_IQ_tail].rt = ready_time;
- _IQ[_IQ_tail].ri = ready_time - max_ready;
- _IQ_tail = _IQ_next_index(_IQ_tail);
- _IQ_length++;
- max_ready = ready_time;
- }
- else if (ready_time < min_ready)
- {
- last_interval = _IQ[_IQ_head].ri;
- _IQ[_IQ_head].ri = _IQ[_IQ_head].rt - ready_time;
- _IQ_head = _IQ_previous_index(_IQ_head);
- _IQ[_IQ_head].rt = ready_time;
- _IQ[_IQ_head].ri = last_interval;
- min_ready = ready_time;
- _IQ_length++;
- }
- else
- {
- int i, j, k, l = 0;
- for (i = _IQ_head; i != _IQ_tail; i = j)
- {
- j = _IQ_next_index(i);
- if (_IQ[j].rt < ready_time)
- {
- continue;
- }
- break;
- }
- for (k = _IQ_tail; k != j; k = l)
- {
- l = _IQ_previous_index(k);
- _IQ[k] = _IQ[l];
- }
- i = _IQ_next_index(j);
- _IQ[j].ri -= (_IQ[j].rt - ready_time);
- _IQ[j].rt = ready_time;
- _IQ[i].ri = _IQ[i].rt - ready_time;
- _IQ_tail = _IQ_next_index(_IQ_tail);
- _IQ_length++;
- }
- }
- average_interval = (max_ready - min_ready) / _IQ_length;
-}
-
-static long long
-_IQ_delete(void)
-{
- struct iq_node oldest;
-
- if (_IQ_empty()) return 0;
- oldest = _IQ[_IQ_head];
- _IQ_head = (_IQ_head + 1) % INTERVAL_QSIZE;
- if ((--_IQ_length) == 0)
- {
- _IQ_init();
- }
- else
- {
- min_ready = _IQ[_IQ_head].rt;
- average_interval = (max_ready - min_ready) / _IQ_length;
- }
-
- return oldest.ri;
-}
-
-static long long
-get_max_interval(void)
-{
- int i;
- long long max = LLONG_MIN;
-
- for ( i= _IQ_head ; i != _IQ_tail ; i = _IQ_next_index(i))
- {
- if (_IQ[i].ri > max)
- {
- max = _IQ[i].ri;
- }
- }
-
- return max;
-}
-
-static long long
-tv_to_long_long(struct timeval *tv)
-{
- if (!tv)
- {
- return 0;
- }
-
- return tv->tv_sec * 1000000LL + tv->tv_usec;
-}
-
-static long long
-evas_common_frameq_schedule_flush_time(int frameq_sz, int thread_no,
- long long last_ready_time, long long current_ready_time,
- long long last_flush_time, int ready_frames_num,
- int dont_schedule)
-{
- // to get each time and to do others
- long long current_time = 0LL;
- long long current_ready_interval = 0LL;
- long long theshold_time = SATISFACTION_THRESHOLD * 1000LL; // ms -> usec
- long long reset_time_interval = 0LL;
- long long sleep_time = 0LL;
- long long saved_ready_time, saved_ready_interval;
- long long time_slept = 0LL;
- static long long time_lag = 0;
- struct timeval now;
- int frameq_full_threshold =0;
- int need_reset = 0;
- int need_schedule = 0;
-
- frameq_full_threshold = frameq_sz -thread_no; // Qsize - threads#
-
- /* 1.5 defer flush time of current frame if need */
- // in case of the first time, just keep ready time only
- if (last_ready_time == 0LL)
- {
- last_ready_time = current_ready_time;
- }
- else
- {
- /* 1.5.1 get current ready time & interval */
- saved_ready_time = current_ready_time;
- saved_ready_interval = current_ready_interval = current_ready_time - last_ready_time;
- // compensate a case which current ready time is older than previous one,
- // doesn't work on the interval queue
- if (current_ready_interval < 0)
- {
- current_ready_time = last_ready_time;
- current_ready_interval = 0;
- }
-
- /* 1.5.2 get the reset time interval before keeping a new one */
- if (!_IQ_empty())
- {
- reset_time_interval = RESET_RATIO * average_interval;
- if (average_interval < DOUBLE_RESET_TIME_INTERVAL_THRESHOLD)
- {
- reset_time_interval *= 2;
- }
- }
-
- /* 1.5.3 reset - if too late, discard all saved interval and start from here */
- if (current_ready_interval > RESET_ABSOLUTE_INTERVAL)
- {
- need_reset = 1;
- }
- else if (_IQ_length >= thread_no * 2 && current_ready_interval > reset_time_interval)
- {
- need_reset = 1;
- }
- else if (_IQ_length >= thread_no && _IQ_length < thread_no * 2
- && current_ready_interval > get_max_interval() * RESET_RATIO)
- {
- need_reset = 1;
- }
-
- if (need_reset)
- {
- _IQ_init();
- }
- else
- {
- /* 1.5.4 enqueue - keep a new interval for next average interval */
- if (_IQ_full())
- {
- _IQ_delete();
- }
- _IQ_insert(saved_ready_time, saved_ready_interval);
-
- /* 1.5.5 schedule - if faster than average interval, figure out sleep time to meet it */
- if (!dont_schedule)
- {
- need_schedule = 0;
- sleep_time = 0;
- if (_IQ_length >= thread_no * 2 && average_interval > theshold_time)
- {
- need_schedule = 1;
- }
- // compensate the case that postworker blocks the workers from getting a new fresh frame
- // It's actually occurred when during the wait time of postworker, the frame queue is full
- // Consequently check the number of currently ready frames and apply some time drop to average time according to the number
- if (ready_frames_num >= frameq_full_threshold)
- {
- need_schedule = 0;
+ p->op[i].op_func(info->im, &(p->op[i]), info);
}
- if (need_schedule)
- {
- gettimeofday(&now, NULL);
- current_time = tv_to_long_long(&now);
- time_lag += (current_time - last_flush_time);
- sleep_time = (average_interval < time_lag) ? 0 : (average_interval - time_lag);
- }
- }
-
- /* 1.5.6 sleep - actually sleep and get over-slept time (time_lag) for next frame */
- if (sleep_time > 0)
- {
- sleep_time = sleep_time * 9 / 10;
- usleep((unsigned int)sleep_time);
- gettimeofday(&now, NULL);
- time_slept = tv_to_long_long(&now) - current_time;
- time_lag = time_slept - sleep_time;
- }
- else
- {
- time_lag = 0;
}
}
- last_ready_time = current_ready_time;
- }
-
- return last_ready_time;
-}
-
-static void *
-evas_common_frameq_thread_post(void *data)
-{
- Evas_FrameQ *frameq;
- Evas_Frame *frame;
- Evas_Surface *surface;
- Thinfo *thinfo;
- Evas_Frameq_Thread_Info *fq_info;
- Eina_List *pending_writes = NULL;
- Eina_List *prev_pending_writes = NULL;
-
- long long last_ready_time = 0LL;
- long long current_ready_time;
- Evas_Frame *temp_frame = NULL;
- int ready_frames_num;
- long long last_flush_time = 0LL;
- struct timeval now;
- int dont_schedule = 0;
-
- thinfo = data;
- fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info);
- frameq = fq_info->frameq;
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
- /* install thread cancelation cleanup handler */
- pthread_cleanup_push(evas_common_frameq_release, data);
- _IQ_init();
+ thinfo->tasks = NULL;
- for (;;)
- {
- /* 1. wait the first frame being done */
- LKL(frameq->mutex);
- while(!frameq->frames || !frameq->frames->ready)
- {
- eina_condition_wait(&(frameq->cond_ready));
- }
- frame = frameq->frames;
-
- /* 1.5. prepare to schedule flush time */
- current_ready_time = tv_to_long_long(&frame->ready_time);
- ready_frames_num = 0;
- EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), temp_frame)
- {
- if (temp_frame->ready == 1)
- {
- ready_frames_num++;
- }
- }
- dont_schedule = (frame->dont_schedule)?1:0;
- LKU(frameq->mutex);
-
- /* 2. generate pending_writes */
- EINA_INLIST_FOREACH(EINA_INLIST_GET(frame->surfaces), surface)
- {
- evas_common_pipe_flush(surface->im);
- if (! surface->dontpush)
- {
- pending_writes = eina_list_append(pending_writes, surface->im);
- }
- }
-
- /* 2.5. schedule flush time */
- last_ready_time = evas_common_frameq_schedule_flush_time(
- frameq->frameq_sz, frameq->thread_num,
- last_ready_time, current_ready_time,
- last_flush_time, ready_frames_num, dont_schedule);
-
- /* 3. flush redraws */
- frame->output_set_priv(frame->data, pending_writes, prev_pending_writes);
- frame->output_flush(frame->data);
- gettimeofday(&now, NULL);
- // keep as the last flush time
- last_flush_time = now.tv_sec * 1000000LL + now.tv_usec;
-
- prev_pending_writes = pending_writes;
- pending_writes = NULL;
-
- /* 4. remove this frame from the frame queue */
- LKL(frameq->mutex);
- frameq->frames =
- (Evas_Frame *)eina_inlist_remove(EINA_INLIST_GET(frameq->frames),
- EINA_INLIST_GET(frame));
-
- LKU(frameq->mutex);
- eina_condition_broadcast(&frameq->cond_done);
- evas_common_frame_dealloc(frame);
+ pthread_barrier_wait(&(thinfo->barrier[1]));
}
-
- // Remove cleanup handler
- pthread_cleanup_pop(0);
return NULL;
}
-
-#endif /* EVAS_FRAME_QUEUING */
#endif
#ifdef BUILD_PTHREAD
static int thread_num = 0;
static Thinfo thinfo[TH_MAX];
static pthread_barrier_t thbarrier[2];
+
+static RGBA_Pipe_Thread_Info *buf = NULL;
+static unsigned int buf_size = 0;
#endif
static void
evas_common_pipe_begin(RGBA_Image *im)
{
+#define SZ 128
#ifdef BUILD_PTHREAD
- int i, y, h;
-
-#ifdef EVAS_FRAME_QUEUING
- return;
-#endif
+ unsigned int x, y, cpu;
+ RGBA_Pipe_Thread_Info *info;
+ unsigned int estimatex, estimatey;
+ unsigned int needed_size;
if (!im->cache_entry.pipe) return;
if (thread_num == 1) return;
- y = 0;
- h = im->cache_entry.h / thread_num;
- if (h < 1) h = 1;
- for (i = 0; i < thread_num; i++)
- {
- RGBA_Pipe_Thread_Info *info;
-
-// if (y >= im->cache_entry.h) break;
- info = calloc(1, sizeof(RGBA_Pipe_Thread_Info));
- info->im = im;
-#ifdef EVAS_SLI
- info->x = 0;
- info->w = im->cache_entry.w;
- info->y = i;
- info->h = thread_num;
-#else
- info->x = 0;
- info->y = y;
- info->w = im->cache_entry.w;
- if (i == (thread_num - 1))
- {
- info->h = im->cache_entry.h - y;
- }
- else
- {
- info->h = h;
- }
- y += info->h;
-#endif
- thinfo[i].info = info;
- }
- /* tell worker threads to start */
- pthread_barrier_wait(&(thbarrier[0]));
-#endif
-}
-#ifdef EVAS_FRAME_QUEUING
-EAPI void
-evas_common_frameq_begin(void)
-{
-#ifdef BUILD_PTHREAD
- int i;
- Evas_Frameq_Thread_Info *fp_info;
- pthread_attr_t attr;
- cpu_set_t cpu;
-
- if (!gframeq.initialised)
+ if (im->cache_entry.w * im->cache_entry.h / thread_num < SZ * SZ)
{
- int cpunum, set_cpu_affinity = 0;
-
- cpunum = eina_cpu_count();
- gframeq.thread_num = cpunum;
- gframeq.frameq_sz = cpunum * FRAMEQ_SZ_PER_THREAD;
-
- eina_threads_init();
-
- for (i = 0; i < gframeq.thread_num; i++)
- {
-
- fp_info = calloc(1, sizeof(Evas_Frameq_Thread_Info));
- fp_info->frameq = &gframeq;
-
- gframeq.thinfo[i].thread_num = i;
- gframeq.thinfo[i].fq_info = fp_info;
-
- pthread_attr_init(&attr);
- if (set_cpu_affinity)
- {
- CPU_ZERO(&cpu);
- CPU_SET((i+1) % cpunum, &cpu);
- pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
- }
-
- pthread_create(&(gframeq.thinfo[i].thread_id), &attr,
- evas_common_frameq_thread, &(gframeq.thinfo[i]));
-
- pthread_attr_destroy(&attr);
- pthread_detach(gframeq.thinfo[i].thread_id);
- }
-
- {
- fp_info = calloc(1, sizeof(Evas_Frameq_Thread_Info));
- fp_info->frameq = &gframeq;
-
- gframeq.thinfo[i].thread_num = i;
- gframeq.thinfo[i].fq_info = fp_info;
-
- pthread_attr_init(&attr);
- if (set_cpu_affinity)
- {
- CPU_ZERO(&cpu);
- CPU_SET((i+1) % cpunum, &cpu);
- pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
- }
-
- pthread_create(&(gframeq.thinfo[i].thread_id), &attr,
- evas_common_frameq_thread_post, &(gframeq.thinfo[i]));
- pthread_attr_destroy(&attr);
- pthread_detach(gframeq.thinfo[i].thread_id);
- }
- gframeq.initialised = 1; // now worker threads are created.
-
- INF("initialised");
- DBG("%d cpus, set_cpu_affinity=%d, frameq_sz=%d",
- cpunum, set_cpu_affinity, gframeq.frameq_sz);
+ estimatex = im->cache_entry.w;
+ estimatey = im->cache_entry.h / thread_num;
+ if (estimatey == 0) estimatey = 1;
}
-#endif /* BUILD_PTHREAD */
-}
-
-EAPI void
-evas_common_frameq_finish(void)
-{
- int i;
-
- /* 1. cancel all worker threads */
- for (i = 0; i < gframeq.thread_num; i++)
+ else
{
- pthread_cancel(gframeq.thinfo[i].thread_id);
+ estimatex = SZ;
+ estimatey = SZ;
}
- // cancel post-worker thread
- pthread_cancel(gframeq.thinfo[i].thread_id);
- /* 2. send signal to worker threads so that they enter to the thread cancelation cleanup handler */
- for (i = 0; i < gframeq.thread_num; i++)
+ needed_size = ((im->cache_entry.w / estimatex) + 1 ) * ((im->cache_entry.h / estimatey) + 1);
+ if (buf_size < needed_size)
{
- eina_condition_signal(&(gframeq.cond_new));
+ buf = realloc(buf, sizeof (RGBA_Pipe_Thread_Info) * needed_size);
+ buf_size = needed_size;
}
- // send signal to post-worker thread
- eina_condition_signal(&(gframeq.cond_ready));
- /* all the workers were created and detached before
- * so don't need to join them here.
- */
+ info = buf;
+ cpu = 0;
+ for (y = 0; y < im->cache_entry.h; y += estimatey)
+ for (x = 0; x < im->cache_entry.w; x += estimatex)
+ {
+ info->im = im;
+ info->x = x;
+ info->y = y;
+ info->w = (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex;
+ info->h = (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey;
-}
+ thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info));
+ cpu++;
+ if (cpu >= (unsigned int) thread_num) cpu = 0;
-#endif /* EVAS_FRAME_QUEUING */
+ info++;
+ }
+
+ /* tell worker threads to start */
+ pthread_barrier_wait(&(thbarrier[0]));
+#endif
+}
EAPI void
evas_common_pipe_flush(RGBA_Image *im)
{
if (!im->cache_entry.pipe) return;
-#ifndef EVAS_FRAME_QUEUING
#ifdef BUILD_PTHREAD
if (thread_num > 1)
{
- /* sync worker threads */
- pthread_barrier_wait(&(thbarrier[1]));
+ /* sync worker threads */
+ pthread_barrier_wait(&(thbarrier[1]));
}
else
#endif
{
- RGBA_Pipe *p;
- int i;
+ RGBA_Pipe_Thread_Info info;
+ RGBA_Pipe *p;
+ int i;
+
+ info.im = im;
+ info.x = 0;
+ info.y = 0;
+ info.w = im->cache_entry.w;
+ info.h = im->cache_entry.h;
/* process pipe - 1 thead */
for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
{
if (p->op[i].op_func)
{
- p->op[i].op_func(im, &(p->op[i]), NULL);
+ p->op[i].op_func(im, &(p->op[i]), &info);
}
}
}
}
-#endif /* !EVAS_FRAME_QUEUING */
+
evas_common_cpu_end_opt();
evas_common_pipe_free(im);
}
/* draw ops */
/**************** RECT ******************/
static void
-evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
- evas_common_rectangle_draw(dst, &(context),
- op->op.rect.x, op->op.rect.y,
- op->op.rect.w, op->op.rect.h);
- }
- else
- {
- evas_common_rectangle_draw(dst, &(op->context),
- op->op.rect.x, op->op.rect.y,
- op->op.rect.w, op->op.rect.h);
- }
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+ evas_common_rectangle_draw(dst, &(context),
+ op->op.rect.x, op->op.rect.y,
+ op->op.rect.w, op->op.rect.h);
}
EAPI void
/**************** LINE ******************/
static void
-evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
- evas_common_line_draw(dst, &(context),
- op->op.line.x0, op->op.line.y0,
- op->op.line.x1, op->op.line.y1);
- }
- else
- {
- evas_common_line_draw(dst, &(op->context),
- op->op.line.x0, op->op.line.y0,
- op->op.line.x1, op->op.line.y1);
- }
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+ evas_common_line_draw(dst, &(context),
+ op->op.line.x0, op->op.line.y0,
+ op->op.line.x1, op->op.line.y1);
}
EAPI void
}
static void
-evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
- evas_common_polygon_draw(dst, &(context),
- op->op.poly.points, 0, 0);
- }
- else
- {
- evas_common_polygon_draw(dst, &(op->context),
- op->op.poly.points, 0, 0);
- }
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+ evas_common_polygon_draw(dst, &(context),
+ op->op.poly.points, 0, 0);
}
EAPI void
static void
evas_common_pipe_op_text_free(RGBA_Pipe_Op *op)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(op->op.text.font->ref_fq_del);
- op->op.text.font->ref_fq[1]++;
- LKU(op->op.text.font->ref_fq_del);
- eina_condition_signal(&(op->op.text.font->cond_fq_del));
-#else
- evas_common_font_free(op->op.text.font);
-#endif
- evas_common_text_props_content_unref(&(op->op.text.intl_props));
+ evas_common_text_props_content_unref(op->op.text.intl_props);
evas_common_pipe_op_free(op);
}
-#ifdef EVAS_FRAME_QUEUING
-/* flush all op using @fn */
-EAPI void
-evas_common_pipe_op_text_flush(RGBA_Font *fn)
-{
- if (! evas_common_frameq_enabled())
- return;
-
- LKL(fn->ref_fq_add);
- LKL(fn->ref_fq_del);
-
- while (fn->ref_fq[0] != fn->ref_fq[1])
- eina_condition_wait(&(fn->cond_fq_del));
-
- LKU(fn->ref_fq_del);
- LKU(fn->ref_fq_add);
-}
-#endif
-
static void
-evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
- evas_common_font_draw(dst, &(context),
- op->op.text.font, op->op.text.x, op->op.text.y,
- &op->op.text.intl_props);
- }
- else
- {
- evas_common_font_draw(dst, &(op->context),
- op->op.text.font, op->op.text.x, op->op.text.y,
- &op->op.text.intl_props);
- }
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
+ evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
}
EAPI void
evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
- RGBA_Font *fn, int x, int y, const Evas_Text_Props *intl_props)
+ int x, int y, Evas_Text_Props *intl_props)
{
RGBA_Pipe_Op *op;
- if (!fn) return;
dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
if (!dst->cache_entry.pipe) return;
op->op.text.x = x;
op->op.text.y = y;
- evas_common_text_props_content_copy_and_ref(&(op->op.text.intl_props),
- intl_props);
-#ifdef EVAS_FRAME_QUEUING
- LKL(fn->ref_fq_add);
- fn->ref_fq[0]++;
- LKU(fn->ref_fq_add);
-#else
- fn->references++;
-#endif
- op->op.text.font = fn;
+ op->op.text.intl_props = intl_props;
+ evas_common_text_props_content_ref(intl_props);
op->op_func = evas_common_pipe_text_draw_do;
op->free_func = evas_common_pipe_op_text_free;
evas_common_pipe_draw_context_copy(dc, op);
+ evas_common_pipe_text_prepare(intl_props);
}
/**************** IMAGE *****************/
static void
evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(op->op.image.src->cache_entry.ref_fq_del);
- op->op.image.src->cache_entry.ref_fq[1]++;
- LKU(op->op.image.src->cache_entry.ref_fq_del);
- eina_condition_signal(&(op->op.image.src->cache_entry.cond_fq_del));
-#else
op->op.image.src->ref--;
if (op->op.image.src->ref == 0)
{
evas_cache_image_drop(&op->op.image.src->cache_entry);
}
-#endif
evas_common_pipe_op_free(op);
}
-#ifdef EVAS_FRAME_QUEUING
-EAPI void
-evas_common_pipe_op_image_flush(RGBA_Image *im)
-{
- if (! evas_common_frameq_enabled())
- return;
-
- LKL(im->cache_entry.ref_fq_add);
- LKL(im->cache_entry.ref_fq_del);
-
- while (im->cache_entry.ref_fq[0] != im->cache_entry.ref_fq[1])
- eina_condition_wait(&(im->cache_entry.cond_fq_del));
-
- LKU(im->cache_entry.ref_fq_del);
- LKU(im->cache_entry.ref_fq_add);
-}
-#endif
-
static void
-evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
#ifdef SCALECACHE
- evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
- dst, &(context),
- op->op.image.smooth,
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
+ evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
+ dst, &(context),
+ op->op.image.smooth,
+ op->op.image.sx,
+ op->op.image.sy,
+ op->op.image.sw,
+ op->op.image.sh,
+ op->op.image.dx,
+ op->op.image.dy,
+ op->op.image.dw,
+ op->op.image.dh);
#else
- if (op->op.image.smooth)
- {
- evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
- dst, &(context),
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
- }
- else
- {
- evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
- dst, &(context),
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
- }
-#endif
+ if (op->op.image.smooth)
+ {
+ evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
+ dst, &(context),
+ op->op.image.sx,
+ op->op.image.sy,
+ op->op.image.sw,
+ op->op.image.sh,
+ op->op.image.dx,
+ op->op.image.dy,
+ op->op.image.dw,
+ op->op.image.dh);
}
else
{
-#ifdef SCALECACHE
- evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
- dst, &(op->context),
- op->op.image.smooth,
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
-#else
- if (op->op.image.smooth)
- {
- evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
- dst, &(op->context),
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
- }
- else
- {
- evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
- dst, &(op->context),
- op->op.image.sx,
- op->op.image.sy,
- op->op.image.sw,
- op->op.image.sh,
- op->op.image.dx,
- op->op.image.dy,
- op->op.image.dw,
- op->op.image.dh);
- }
-#endif
+ evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
+ dst, &(context),
+ op->op.image.sx,
+ op->op.image.sy,
+ op->op.image.sw,
+ op->op.image.sh,
+ op->op.image.dx,
+ op->op.image.dy,
+ op->op.image.dw,
+ op->op.image.dh);
}
+#endif
}
EAPI void
op->op.image.dy = dst_region_y;
op->op.image.dw = dst_region_w;
op->op.image.dh = dst_region_h;
-#ifdef EVAS_FRAME_QUEUING
- LKL(src->cache_entry.ref_fq_add);
- src->cache_entry.ref_fq[0]++;
- LKU(src->cache_entry.ref_fq_add);
-#else
src->ref++;
-#endif
op->op.image.src = src;
op->op_func = evas_common_pipe_image_draw_do;
op->free_func = evas_common_pipe_op_image_free;
evas_common_pipe_draw_context_copy(dc, op);
-#ifdef EVAS_FRAME_QUEUING
- /* laod every src image here.
- * frameq utilize all cpu cores already by worker threads
- * so another threads and barrier waiting can't be of any benefit.
- * therefore, not instantiate loader threads.
- */
- if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&src->cache_entry);
- evas_common_image_colorspace_normalize(src);
-#else
evas_common_pipe_image_load(src);
-#endif
}
static void
evas_common_pipe_op_map_free(RGBA_Pipe_Op *op)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(op->op.image.src->cache_entry.ref_fq_del);
- op->op.image.src->cache_entry.ref_fq[1]++;
- LKU(op->op.image.src->cache_entry.ref_fq_del);
-#else
op->op.map.src->ref--;
if (op->op.map.src->ref == 0)
evas_cache_image_drop(&op->op.map.src->cache_entry);
-#endif
free(op->op.map.p);
evas_common_pipe_op_free(op);
}
static void
-evas_common_pipe_map_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
+evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
- if (info)
- {
- RGBA_Draw_Context context;
+ RGBA_Draw_Context context;
- memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
-#ifdef EVAS_SLI
- evas_common_draw_context_set_sli(&(context), info->y, info->h);
-#else
- evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
-#endif
+ memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
+ evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
- evas_common_map_rgba(op->op.map.src, dst,
- &context, op->op.map.npoints, op->op.map.p,
- op->op.map.smooth, op->op.map.level);
- }
- else
- {
- evas_common_map_rgba(op->op.map.src, dst,
- &(op->context), op->op.map.npoints, op->op.map.p,
- op->op.map.smooth, op->op.map.level);
- }
+ evas_common_map_rgba(op->op.map.src, dst,
+ &context, op->op.map.npoints, op->op.map.p,
+ op->op.map.smooth, op->op.map.level);
}
EAPI void
op->op.map.npoints = npoints;
op->op.map.smooth = smooth;
op->op.map.level = level;
-#ifdef EVAS_FRAME_QUEUING
- LKL(src->cache_entry.ref_fq_add);
- src->cache_entry.ref_fq[0]++;
- LKU(src->cache_entry.ref_fq_add);
-#else
src->ref++;
-#endif
op->op.map.src = src;
op->op.map.p = pts_copy;
op->op_func = evas_common_pipe_map_draw_do;
op->free_func = evas_common_pipe_op_map_free;
evas_common_pipe_draw_context_copy(dc, op);
-#ifdef EVAS_FRAME_QUEUING
- /* laod every src image here.
- * frameq utilize all cpu cores already by worker threads
- * so another threads and barrier waiting can't be of any benefit.
- * therefore, not instantiate loader threads.
- */
- if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
- evas_cache_image_load_data(&src->cache_entry);
- evas_common_image_colorspace_normalize(src);
-#else
evas_common_pipe_image_load(src);
-#endif
}
static void
/* Map imply that we need to process them recursively first. */
for (p = root->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
{
- for (i = 0; i < p->op_num; i++)
+ for (i = 0; i < p->op_num; i++)
{
if (p->op[i].op_func == evas_common_pipe_map_draw_do)
{
}
#ifdef BUILD_PTHREAD
-static Eina_List *task = NULL;
+static Eina_List *im_task = NULL;
+static Eina_List *text_task = NULL;
static Thinfo task_thinfo[TH_MAX];
static pthread_barrier_t task_thbarrier[2];
-static LK(task_mutext);
+static LK(im_task_mutex);
+static LK(text_task_mutex);
#endif
#ifdef BUILD_PTHREAD
/* wait for start signal */
pthread_barrier_wait(&(tinfo->barrier[0]));
- while (task)
+ while (im_task)
{
RGBA_Image *im = NULL;
- LKL(task_mutext);
- im = eina_list_data_get(task);
- task = eina_list_remove_list(task, task);
- LKU(task_mutext);
+ LKL(im_task_mutex);
+ im = eina_list_data_get(im_task);
+ im_task = eina_list_remove_list(im_task, im_task);
+ LKU(im_task_mutex);
if (im)
{
}
}
- /* send finished signal */
+ while (text_task)
+ {
+ Evas_Text_Props *text_props;
+ RGBA_Font_Int *fi;
+
+ LKL(text_task_mutex);
+ fi = eina_list_data_get(text_task);
+ text_task = eina_list_remove_list(text_task, text_task);
+ LKU(text_task_mutex);
+
+ if (fi)
+ {
+ LKL(fi->ft_mutex);
+ EINA_LIST_FREE(fi->task, text_props)
+ {
+ evas_common_font_draw_prepare(text_props);
+ text_props->changed = EINA_FALSE;
+ text_props->prepare = EINA_FALSE;
+ }
+ LKU(fi->ft_mutex);
+ }
+ }
+
+ /* send finished signal */
pthread_barrier_wait(&(tinfo->barrier[1]));
}
static volatile int bval = 0;
static void
-evas_common_pipe_image_load_do(void)
+evas_common_pipe_load_do(void)
{
#ifdef BUILD_PTHREAD
+ if (!im_task && !text_task) return ;
+
/* Notify worker thread. */
pthread_barrier_wait(&(task_thbarrier[0]));
eina_threads_init();
- LKI(task_mutext);
+ LKI(im_task_mutex);
+ LKI(text_task_mutex);
pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1);
pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1);
CPU_SET(i % cpunum, &cpu);
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
thinfo[i].thread_num = i;
- thinfo[i].info = NULL;
+ thinfo[i].tasks = NULL;
thinfo[i].barrier = thbarrier;
/* setup initial locks */
pthread_create(&(thinfo[i].thread_id), &attr,
CPU_SET(i % cpunum, &cpu);
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
task_thinfo[i].thread_num = i;
- task_thinfo[i].info = NULL;
+ task_thinfo[i].tasks = NULL;
task_thinfo[i].barrier = task_thbarrier;
/* setup initial locks */
pthread_create(&(task_thinfo[i].thread_id), &attr,
&& !evas_cache_image_is_loaded(&(im->cache_entry)))
goto add_task;
- if ((!im->cs.data) || ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY))))
+ if (!((!im->cs.data) || ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY)))))
goto add_task;
return ;
add_task:
- task = eina_list_append(task, im);
+ LKL(im_task_mutex);
+ im_task = eina_list_append(im_task, im);
+ LKU(im_task_mutex);
im->flags |= RGBA_IMAGE_TODO_LOAD;
}
EAPI void
+evas_common_pipe_text_prepare(Evas_Text_Props *text_props)
+{
+ RGBA_Font_Int *fi;
+
+ fi = text_props->font_instance;
+ if (!fi) return ;
+
+ if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
+ return ;
+
+ LKL(fi->ft_mutex);
+
+ if (!fi->task)
+ {
+ LKL(text_task_mutex);
+ text_task = eina_list_append(text_task, fi);
+ LKU(text_task_mutex);
+ }
+
+ if (text_props->prepare) goto end;
+ text_props->prepare = EINA_TRUE;
+ fi->task = eina_list_append(fi->task, text_props);
+
+ end:
+ LKU(fi->ft_mutex);
+}
+
+EAPI void
evas_common_pipe_map_begin(RGBA_Image *root)
{
if (!evas_common_pipe_init())
{
RGBA_Image *im;
- EINA_LIST_FREE(task, im)
+ EINA_LIST_FREE(im_task, im)
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
-
+
im->flags &= ~RGBA_IMAGE_TODO_LOAD;
}
}
- evas_common_pipe_image_load_do();
+ evas_common_pipe_load_do();
evas_common_pipe_map_render(root);
}
int thread_num;
pthread_t thread_id;
pthread_barrier_t *barrier;
- RGBA_Pipe_Thread_Info *info;
-# ifdef EVAS_FRAME_QUEUING
- void *fq_info;
-#endif
+ const Eina_Inlist *tasks;
} Thinfo;
#endif
-#ifdef EVAS_FRAME_QUEUING
-struct _Evas_Surface
-{
- EINA_INLIST;
- RGBA_Image *im;
- int x, y, w, h;
- int dontpush; // dont push the surface out after drawing done
-};
-typedef struct _Evas_Surface Evas_Surface;
-
-struct _Evas_Frame
-{
- EINA_INLIST;
- Evas_Surface *surfaces;
- void *data;
- int in_process;
- int ready;
- int dont_schedule;
- struct timeval ready_time;
-
- void (*output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h);
- void (*output_flush) (void *data);
- void (*output_set_priv)(void *data, void *cur, void *prev);
-};
-typedef struct _Evas_Frame Evas_Frame;
-
-
-struct _Evas_FrameQ
-{
- int initialised;
- Evas_Frame *frames;
- Eina_Condition cond_new;
- Eina_Condition cond_ready;
- Eina_Condition cond_done;
- LK(mutex);
-
- int thread_num;
- Thinfo thinfo[TH_MAX];
- int frameq_sz;
-
- Evas_Frame *cur_frame;
-};
-typedef struct _Evas_FrameQ Evas_FrameQ;
-#define FRAMEQ_SZ_PER_THREAD 2
-
-struct _Evas_Frameq_Thread_Info
-{
- Evas_FrameQ *frameq;
-};
-typedef struct _Evas_Frameq_Thread_Info Evas_Frameq_Thread_Info;
-
-EAPI Evas_Surface *evas_common_frameq_new_surface(void *surface, int x, int y, int w, int h);
-EAPI void evas_common_frameq_add_surface(Evas_Surface *surface);
-EAPI void evas_common_frameq_set_frame_data(void *data,
- void (*fn_output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h),
- void (*fn_output_flush) (void *data),
- void (*fn_output_set_priv)(void *data, void *cur, void *prev));
-EAPI void evas_common_frameq_prepare_frame(void);
-EAPI void evas_common_frameq_ready_frame(void);
-EAPI void evas_common_frameq_init(void);
-EAPI void evas_common_frameq_destroy(void);
-EAPI void evas_common_frameq_flush(void);
-EAPI void evas_common_frameq_flush_ready(void);
-EAPI int evas_common_frameq_get_frameq_sz(void);
-EAPI int evas_common_frameq_enabled(void);
-EAPI void evas_common_frameq_begin(void);
-EAPI void evas_common_frameq_finish(void);
-#endif
-
/* image rendering pipelines... new optional system - non-immediate and
* threadable
*/
EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y);
-EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Evas_Text_Props *intl_props);
+EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Text_Props *intl_props);
+EAPI void evas_common_pipe_text_prepare(Evas_Text_Props *text_props);
EAPI void evas_common_pipe_image_load(RGBA_Image *im);
EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
EAPI void evas_common_pipe_map_begin(RGBA_Image *root);
int smooth, int level);
EAPI void evas_common_pipe_flush(RGBA_Image *im);
-#ifdef EVAS_FRAME_QUEUING
-EAPI void evas_common_pipe_op_text_flush(RGBA_Font *fn);
-EAPI void evas_common_pipe_op_image_flush(RGBA_Image *im);
-#endif
-
#endif /* _EVAS_PIPE_H */
{
DATA32 *ptr;
-#ifdef EVAS_SLI
- if (((span->y) % dc->sli.h) == dc->sli.y)
-#endif
- {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_POLY
- if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (!dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- NULL, dst->pixman.im,
- span->x, span->y, 0, 0,
- span->x, span->y, span->w, 1);
- else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
- (dc->mask.mask))
- pixman_image_composite(op, dc->col.pixman_color_image,
- dc->mask.mask->pixman.im,
- dst->pixman.im,
- span->x, span->y, 0, 0,
- span->x, span->y, span->w, 1);
- else
+ if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (!dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ NULL, dst->pixman.im,
+ span->x, span->y, 0, 0,
+ span->x, span->y, span->w, 1);
+ else if ((dst->pixman.im) && (dc->col.pixman_color_image) &&
+ (dc->mask.mask))
+ pixman_image_composite(op, dc->col.pixman_color_image,
+ dc->mask.mask->pixman.im,
+ dst->pixman.im,
+ span->x, span->y, 0, 0,
+ span->x, span->y, span->w, 1);
+ else
# endif
#endif
- {
- ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
- func(NULL, NULL, dc->col.col, ptr, span->w);
- }
- }
+ {
+ ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
+ func(NULL, NULL, dc->col.col, ptr, span->w);
+ }
}
while (spans)
{
ptr = dst->image.data + (y * dst->cache_entry.w) + x;
for (yy = 0; yy < h; yy++)
{
-#ifdef EVAS_SLI
- if (((yy + y) % dc->sli.h) == dc->sli.y)
-#endif
- {
- func(NULL, NULL, dc->col.col, ptr, w);
- }
- ptr += dst->cache_entry.w;
+ func(NULL, NULL, dc->col.col, ptr, w);
+
+ ptr += dst->cache_entry.w;
}
}
}
}
for (y = 0; y < dst_clip_h; y++)
{
- /* * blend here [clip_w *] ptr -> dst_ptr * */
-#ifdef EVAS_SLI
- if (((y + dst_clip_y) % dc->sli.h) == dc->sli.y)
-#endif
- {
- func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
- }
- ptr += src_w;
- dst_ptr += dst_w;
- if (mask) mask += maskobj->cache_entry.w;
+ /* * blend here [clip_w *] ptr -> dst_ptr * */
+ func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
+
+ ptr += src_w;
+ dst_ptr += dst_w;
+ if (mask) mask += maskobj->cache_entry.w;
}
}
}
{
for (y = 0; y < dst_clip_h; y++)
{
-# ifdef EVAS_SLI
- if (((y + dst_clip_y) % dc->sli.h) == dc->sli.y)
-# endif
- {
- dst_ptr = dptr;
- for (x = 0; x < dst_clip_w; x++)
- {
- ptr = row_ptr[y] + lin_ptr[x];
- *dst_ptr = *ptr;
- dst_ptr++;
- }
- }
- dptr += dst_w;
+
+ dst_ptr = dptr;
+ for (x = 0; x < dst_clip_w; x++)
+ {
+ ptr = row_ptr[y] + lin_ptr[x];
+ *dst_ptr = *ptr;
+ dst_ptr++;
+ }
+
+ dptr += dst_w;
}
}
else
buf = alloca(dst_clip_w * sizeof(DATA32));
for (y = 0; y < dst_clip_h; y++)
{
-#ifdef EVAS_SLI
- if (((y + dst_clip_y) % dc->sli.h) == dc->sli.y)
-#endif
- {
- dst_ptr = buf;
- for (x = 0; x < dst_clip_w; x++)
- {
- ptr = row_ptr[y] + lin_ptr[x];
- *dst_ptr = *ptr;
- dst_ptr++;
- }
- /* * blend here [clip_w *] buf -> dptr * */
- func(buf, NULL, dc->mul.col, dptr, dst_clip_w);
- }
- dptr += dst_w;
+ dst_ptr = buf;
+ for (x = 0; x < dst_clip_w; x++)
+ {
+ ptr = row_ptr[y] + lin_ptr[x];
+ *dst_ptr = *ptr;
+ dst_ptr++;
+ }
+ /* * blend here [clip_w *] buf -> dptr * */
+ func(buf, NULL, dc->mul.col, dptr, dst_clip_w);
+
+ dptr += dst_w;
}
}
}
int *xp, xap, yap, pos;
//int dyy, dxx;
int w = dst_clip_w;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
dptr = dst_ptr;
pos = (src_region_y * src_w) + src_region_x;
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
- pix = *yp + *xp + pos;
+ while (dst_clip_w--)
+ {
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
+ pix = *yp + *xp + pos;
- a = (A_VAL(pix) * xap) >> 10;
- r = (R_VAL(pix) * xap) >> 10;
- g = (G_VAL(pix) * xap) >> 10;
- b = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- a += (A_VAL(pix) * Cx) >> 10;
- r += (R_VAL(pix) * Cx) >> 10;
- g += (G_VAL(pix) * Cx) >> 10;
- b += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- a += (A_VAL(pix) * j) >> 10;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((yap = *yapp) > 0)
- {
- pix = *yp + *xp + src_w + pos;
- aa = (A_VAL(pix) * xap) >> 10;
- rr = (R_VAL(pix) * xap) >> 10;
- gg = (G_VAL(pix) * xap) >> 10;
- bb = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- aa += (A_VAL(pix) * Cx) >> 10;
- rr += (R_VAL(pix) * Cx) >> 10;
- gg += (G_VAL(pix) * Cx) >> 10;
- bb += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- aa += (A_VAL(pix) * j) >> 10;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- a += ((aa - a) * yap) >> 8;
- r += ((rr - r) * yap) >> 8;
- g += ((gg - g) * yap) >> 8;
- b += ((bb - b) * yap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(((a + (1 << 3)) >> 4),
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
+ a = (A_VAL(pix) * xap) >> 10;
+ r = (R_VAL(pix) * xap) >> 10;
+ g = (G_VAL(pix) * xap) >> 10;
+ b = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ a += (A_VAL(pix) * Cx) >> 10;
+ r += (R_VAL(pix) * Cx) >> 10;
+ g += (G_VAL(pix) * Cx) >> 10;
+ b += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ a += (A_VAL(pix) * j) >> 10;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((yap = *yapp) > 0)
+ {
+ pix = *yp + *xp + src_w + pos;
+ aa = (A_VAL(pix) * xap) >> 10;
+ rr = (R_VAL(pix) * xap) >> 10;
+ gg = (G_VAL(pix) * xap) >> 10;
+ bb = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ aa += (A_VAL(pix) * Cx) >> 10;
+ rr += (R_VAL(pix) * Cx) >> 10;
+ gg += (G_VAL(pix) * Cx) >> 10;
+ bb += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ aa += (A_VAL(pix) * j) >> 10;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ a += ((aa - a) * yap) >> 8;
+ r += ((rr - r) * yap) >> 8;
+ g += ((gg - g) * yap) >> 8;
+ b += ((bb - b) * yap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(((a + (1 << 3)) >> 4),
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
+ }
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- yp++; yapp++;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
+ func(buf, NULL, dc->mul.col, dptr, w);
+
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ yp++; yapp++;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
}
}
else
while (dst_clip_h--)
{
pbuf = dptr;
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
+
+ while (dst_clip_w--)
{
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
- pix = *yp + *xp + pos;
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
+ pix = *yp + *xp + pos;
- r = (R_VAL(pix) * xap) >> 10;
- g = (G_VAL(pix) * xap) >> 10;
- b = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- r += (R_VAL(pix) * Cx) >> 10;
- g += (G_VAL(pix) * Cx) >> 10;
- b += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((yap = *yapp) > 0)
- {
- pix = *yp + *xp + src_w + pos;
- rr = (R_VAL(pix) * xap) >> 10;
- gg = (G_VAL(pix) * xap) >> 10;
- bb = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- rr += (R_VAL(pix) * Cx) >> 10;
- gg += (G_VAL(pix) * Cx) >> 10;
- bb += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- r += ((rr - r) * yap) >> 8;
- g += ((gg - g) * yap) >> 8;
- b += ((bb - b) * yap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
+ r = (R_VAL(pix) * xap) >> 10;
+ g = (G_VAL(pix) * xap) >> 10;
+ b = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ r += (R_VAL(pix) * Cx) >> 10;
+ g += (G_VAL(pix) * Cx) >> 10;
+ b += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((yap = *yapp) > 0)
+ {
+ pix = *yp + *xp + src_w + pos;
+ rr = (R_VAL(pix) * xap) >> 10;
+ gg = (G_VAL(pix) * xap) >> 10;
+ bb = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ rr += (R_VAL(pix) * Cx) >> 10;
+ gg += (G_VAL(pix) * Cx) >> 10;
+ bb += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r += ((rr - r) * yap) >> 8;
+ g += ((gg - g) * yap) >> 8;
+ b += ((bb - b) * yap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
}
-#ifdef EVAS_SLI
- ysli++;
-#endif
-
+
dptr += dst_w; dst_clip_w = w;
yp++; yapp++;
xp = xpoints;// + dxx;
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
- pix = *yp + *xp + pos;
+ while (dst_clip_w--)
+ {
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
+ pix = *yp + *xp + pos;
- r = (R_VAL(pix) * xap) >> 10;
- g = (G_VAL(pix) * xap) >> 10;
- b = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- r += (R_VAL(pix) * Cx) >> 10;
- g += (G_VAL(pix) * Cx) >> 10;
- b += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((yap = *yapp) > 0)
- {
- pix = *yp + *xp + src_w + pos;
- rr = (R_VAL(pix) * xap) >> 10;
- gg = (G_VAL(pix) * xap) >> 10;
- bb = (B_VAL(pix) * xap) >> 10;
- for (j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- pix++;
- rr += (R_VAL(pix) * Cx) >> 10;
- gg += (G_VAL(pix) * Cx) >> 10;
- bb += (B_VAL(pix) * Cx) >> 10;
- }
- if (j > 0)
- {
- pix++;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- r += ((rr - r) * yap) >> 8;
- g += ((gg - g) * yap) >> 8;
- b += ((bb - b) * yap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
+ r = (R_VAL(pix) * xap) >> 10;
+ g = (G_VAL(pix) * xap) >> 10;
+ b = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ r += (R_VAL(pix) * Cx) >> 10;
+ g += (G_VAL(pix) * Cx) >> 10;
+ b += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((yap = *yapp) > 0)
+ {
+ pix = *yp + *xp + src_w + pos;
+ rr = (R_VAL(pix) * xap) >> 10;
+ gg = (G_VAL(pix) * xap) >> 10;
+ bb = (B_VAL(pix) * xap) >> 10;
+ for (j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ pix++;
+ rr += (R_VAL(pix) * Cx) >> 10;
+ gg += (G_VAL(pix) * Cx) >> 10;
+ bb += (B_VAL(pix) * Cx) >> 10;
+ }
+ if (j > 0)
+ {
+ pix++;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r += ((rr - r) * yap) >> 8;
+ g += ((gg - g) * yap) >> 8;
+ b += ((bb - b) * yap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
+ }
+
+ func(buf, NULL, dc->mul.col, dptr, w);
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
-
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- yp++; yapp++;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ yp++; yapp++;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
}
}
}
int a, r, g, b, rx, gx, bx, ax;
int xap, yap, pos;
//int dyy, dxx;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
DATA32 **yp;
int *xp;
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
+ while (dst_clip_w--)
+ {
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
- sptr = *yp + *xp + pos;
- pix = sptr;
- sptr += src_w;
+ sptr = *yp + *xp + pos;
+ pix = sptr;
+ sptr += src_w;
- ax = (A_VAL(pix) * xap) >> 9;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- ax += (A_VAL(pix) * Cx) >> 9;
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- ax += (A_VAL(pix) * i) >> 9;
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
+ ax = (A_VAL(pix) * xap) >> 9;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ ax += (A_VAL(pix) * Cx) >> 9;
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ ax += (A_VAL(pix) * i) >> 9;
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
- a = (ax * yap) >> 14;
- r = (rx * yap) >> 14;
- g = (gx * yap) >> 14;
- b = (bx * yap) >> 14;
+ a = (ax * yap) >> 14;
+ r = (rx * yap) >> 14;
+ g = (gx * yap) >> 14;
+ b = (bx * yap) >> 14;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix = sptr;
- sptr += src_w;
- ax = (A_VAL(pix) * xap) >> 9;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- ax += (A_VAL(pix) * Cx) >> 9;
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- ax += (A_VAL(pix) * i) >> 9;
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- a += (ax * Cy) >> 14;
- r += (rx * Cy) >> 14;
- g += (gx * Cy) >> 14;
- b += (bx * Cy) >> 14;
- }
- if (j > 0)
- {
- pix = sptr;
- sptr += src_w;
- ax = (A_VAL(pix) * xap) >> 9;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- ax += (A_VAL(pix) * Cx) >> 9;
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- ax += (A_VAL(pix) * i) >> 9;
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- a += (ax * j) >> 14;
- r += (rx * j) >> 14;
- g += (gx * j) >> 14;
- b += (bx * j) >> 14;
- }
- *pbuf++ = ARGB_JOIN(((a + (1 << 4)) >> 5),
- ((r + (1 << 4)) >> 5),
- ((g + (1 << 4)) >> 5),
- ((b + (1 << 4)) >> 5));
- xp++; xapp++;
- }
-
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
- yp++; yapp++;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix = sptr;
+ sptr += src_w;
+ ax = (A_VAL(pix) * xap) >> 9;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ ax += (A_VAL(pix) * Cx) >> 9;
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ ax += (A_VAL(pix) * i) >> 9;
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ a += (ax * Cy) >> 14;
+ r += (rx * Cy) >> 14;
+ g += (gx * Cy) >> 14;
+ b += (bx * Cy) >> 14;
+ }
+ if (j > 0)
+ {
+ pix = sptr;
+ sptr += src_w;
+ ax = (A_VAL(pix) * xap) >> 9;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ ax += (A_VAL(pix) * Cx) >> 9;
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ ax += (A_VAL(pix) * i) >> 9;
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ a += (ax * j) >> 14;
+ r += (rx * j) >> 14;
+ g += (gx * j) >> 14;
+ b += (bx * j) >> 14;
+ }
+ *pbuf++ = ARGB_JOIN(((a + (1 << 4)) >> 5),
+ ((r + (1 << 4)) >> 5),
+ ((g + (1 << 4)) >> 5),
+ ((b + (1 << 4)) >> 5));
+ xp++; xapp++;
+ }
+
+ func(buf, NULL, dc->mul.col, dptr, w);
+
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
+ yp++; yapp++;
}
}
else
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- pbuf = dptr;
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
-
- sptr = *yp + *xp + pos;
- pix = sptr;
- sptr += src_w;
-
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- r = (rx * yap) >> 14;
- g = (gx * yap) >> 14;
- b = (bx * yap) >> 14;
+ pbuf = dptr;
+ while (dst_clip_w--)
+ {
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
+
+ sptr = *yp + *xp + pos;
+ pix = sptr;
+ sptr += src_w;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix = sptr;
- sptr += src_w;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- r += (rx * Cy) >> 14;
- g += (gx * Cy) >> 14;
- b += (bx * Cy) >> 14;
- }
- if (j > 0)
- {
- pix = sptr;
- sptr += src_w;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- r += (rx * j) >> 14;
- g += (gx * j) >> 14;
- b += (bx * j) >> 14;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 4)) >> 5),
- ((g + (1 << 4)) >> 5),
- ((b + (1 << 4)) >> 5));
- xp++; xapp++;
- }
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- dptr += dst_w; dst_clip_w = w;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
- yp++; yapp++;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r = (rx * yap) >> 14;
+ g = (gx * yap) >> 14;
+ b = (bx * yap) >> 14;
+
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix = sptr;
+ sptr += src_w;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * Cy) >> 14;
+ g += (gx * Cy) >> 14;
+ b += (bx * Cy) >> 14;
+ }
+ if (j > 0)
+ {
+ pix = sptr;
+ sptr += src_w;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * j) >> 14;
+ g += (gx * j) >> 14;
+ b += (bx * j) >> 14;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 4)) >> 5),
+ ((g + (1 << 4)) >> 5),
+ ((b + (1 << 4)) >> 5));
+ xp++; xapp++;
+ }
+
+ dptr += dst_w; dst_clip_w = w;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
+ yp++; yapp++;
}
}
else
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- while (dst_clip_w--)
- {
- Cx = *xapp >> 16;
- xap = *xapp & 0xffff;
-
- sptr = *yp + *xp + pos;
- pix = sptr;
- sptr += src_w;
+ while (dst_clip_w--)
+ {
+ Cx = *xapp >> 16;
+ xap = *xapp & 0xffff;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
+ sptr = *yp + *xp + pos;
+ pix = sptr;
+ sptr += src_w;
- r = (rx * yap) >> 14;
- g = (gx * yap) >> 14;
- b = (bx * yap) >> 14;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r = (rx * yap) >> 14;
+ g = (gx * yap) >> 14;
+ b = (bx * yap) >> 14;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix = sptr;
- sptr += src_w;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- r += (rx * Cy) >> 14;
- g += (gx * Cy) >> 14;
- b += (bx * Cy) >> 14;
- }
- if (j > 0)
- {
- pix = sptr;
- sptr += src_w;
- rx = (R_VAL(pix) * xap) >> 9;
- gx = (G_VAL(pix) * xap) >> 9;
- bx = (B_VAL(pix) * xap) >> 9;
- pix++;
- for (i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- rx += (R_VAL(pix) * Cx) >> 9;
- gx += (G_VAL(pix) * Cx) >> 9;
- bx += (B_VAL(pix) * Cx) >> 9;
- pix++;
- }
- if (i > 0)
- {
- rx += (R_VAL(pix) * i) >> 9;
- gx += (G_VAL(pix) * i) >> 9;
- bx += (B_VAL(pix) * i) >> 9;
- }
-
- r += (rx * j) >> 14;
- g += (gx * j) >> 14;
- b += (bx * j) >> 14;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 4)) >> 5),
- ((g + (1 << 4)) >> 5),
- ((b + (1 << 4)) >> 5));
- xp++; xapp++;
- }
-
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
- yp++; yapp++;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix = sptr;
+ sptr += src_w;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * Cy) >> 14;
+ g += (gx * Cy) >> 14;
+ b += (bx * Cy) >> 14;
+ }
+ if (j > 0)
+ {
+ pix = sptr;
+ sptr += src_w;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for (i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if (i > 0)
+ {
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * j) >> 14;
+ g += (gx * j) >> 14;
+ b += (bx * j) >> 14;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 4)) >> 5),
+ ((g + (1 << 4)) >> 5),
+ ((b + (1 << 4)) >> 5));
+ xp++; xapp++;
+ }
+
+ func(buf, NULL, dc->mul.col, dptr, w);
+
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
+ yp++; yapp++;
}
}
}
int *xp, xap, yap, pos;
//int dyy, dxx;
int w = dst_clip_w;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
dptr = dst_ptr;
pos = (src_region_y * src_w) + src_region_x;
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- while (dst_clip_w--)
- {
- pix = *yp + *xp + pos;
+ while (dst_clip_w--)
+ {
+ pix = *yp + *xp + pos;
- a = (A_VAL(pix) * yap) >> 10;
- r = (R_VAL(pix) * yap) >> 10;
- g = (G_VAL(pix) * yap) >> 10;
- b = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- a += (A_VAL(pix) * Cy) >> 10;
- r += (R_VAL(pix) * Cy) >> 10;
- g += (G_VAL(pix) * Cy) >> 10;
- b += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- a += (A_VAL(pix) * j) >> 10;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((xap = *xapp) > 0)
- {
- pix = *yp + *xp + 1 + pos;
- aa = (A_VAL(pix) * yap) >> 10;
- rr = (R_VAL(pix) * yap) >> 10;
- gg = (G_VAL(pix) * yap) >> 10;
- bb = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- aa += (A_VAL(pix) * Cy) >> 10;
- rr += (R_VAL(pix) * Cy) >> 10;
- gg += (G_VAL(pix) * Cy) >> 10;
- bb += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- aa += (A_VAL(pix) * j) >> 10;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- a += ((aa - a) * xap) >> 8;
- r += ((rr - r) * xap) >> 8;
- g += ((gg - g) * xap) >> 8;
- b += ((bb - b) * xap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(((a + (1 << 3)) >> 4),
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
+ a = (A_VAL(pix) * yap) >> 10;
+ r = (R_VAL(pix) * yap) >> 10;
+ g = (G_VAL(pix) * yap) >> 10;
+ b = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ a += (A_VAL(pix) * Cy) >> 10;
+ r += (R_VAL(pix) * Cy) >> 10;
+ g += (G_VAL(pix) * Cy) >> 10;
+ b += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ a += (A_VAL(pix) * j) >> 10;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((xap = *xapp) > 0)
+ {
+ pix = *yp + *xp + 1 + pos;
+ aa = (A_VAL(pix) * yap) >> 10;
+ rr = (R_VAL(pix) * yap) >> 10;
+ gg = (G_VAL(pix) * yap) >> 10;
+ bb = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ aa += (A_VAL(pix) * Cy) >> 10;
+ rr += (R_VAL(pix) * Cy) >> 10;
+ gg += (G_VAL(pix) * Cy) >> 10;
+ bb += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ aa += (A_VAL(pix) * j) >> 10;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ a += ((aa - a) * xap) >> 8;
+ r += ((rr - r) * xap) >> 8;
+ g += ((gg - g) * xap) >> 8;
+ b += ((bb - b) * xap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(((a + (1 << 3)) >> 4),
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
+ }
+
+ func(buf, NULL, dc->mul.col, dptr, w);
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- yp++; yapp++;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ yp++; yapp++;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
}
}
else
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- pbuf = dptr;
- while (dst_clip_w--)
- {
- pix = *yp + *xp + pos;
+ pbuf = dptr;
+ while (dst_clip_w--)
+ {
+ pix = *yp + *xp + pos;
- r = (R_VAL(pix) * yap) >> 10;
- g = (G_VAL(pix) * yap) >> 10;
- b = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- r += (R_VAL(pix) * Cy) >> 10;
- g += (G_VAL(pix) * Cy) >> 10;
- b += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((xap = *xapp) > 0)
- {
- pix = *yp + *xp + 1 + pos;
- rr = (R_VAL(pix) * yap) >> 10;
- gg = (G_VAL(pix) * yap) >> 10;
- bb = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- rr += (R_VAL(pix) * Cy) >> 10;
- gg += (G_VAL(pix) * Cy) >> 10;
- bb += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- r += ((rr - r) * xap) >> 8;
- g += ((gg - g) * xap) >> 8;
- b += ((bb - b) * xap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- dptr += dst_w; dst_clip_w = w;
- yp++; yapp++;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
+ r = (R_VAL(pix) * yap) >> 10;
+ g = (G_VAL(pix) * yap) >> 10;
+ b = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ r += (R_VAL(pix) * Cy) >> 10;
+ g += (G_VAL(pix) * Cy) >> 10;
+ b += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((xap = *xapp) > 0)
+ {
+ pix = *yp + *xp + 1 + pos;
+ rr = (R_VAL(pix) * yap) >> 10;
+ gg = (G_VAL(pix) * yap) >> 10;
+ bb = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ rr += (R_VAL(pix) * Cy) >> 10;
+ gg += (G_VAL(pix) * Cy) >> 10;
+ bb += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r += ((rr - r) * xap) >> 8;
+ g += ((gg - g) * xap) >> 8;
+ b += ((bb - b) * xap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
+ }
+
+ dptr += dst_w; dst_clip_w = w;
+ yp++; yapp++;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
}
}
else
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- Cy = *yapp >> 16;
- yap = *yapp & 0xffff;
+ Cy = *yapp >> 16;
+ yap = *yapp & 0xffff;
- while (dst_clip_w--)
- {
- pix = *yp + *xp + pos;
+ while (dst_clip_w--)
+ {
+ pix = *yp + *xp + pos;
- r = (R_VAL(pix) * yap) >> 10;
- g = (G_VAL(pix) * yap) >> 10;
- b = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- r += (R_VAL(pix) * Cy) >> 10;
- g += (G_VAL(pix) * Cy) >> 10;
- b += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- r += (R_VAL(pix) * j) >> 10;
- g += (G_VAL(pix) * j) >> 10;
- b += (B_VAL(pix) * j) >> 10;
- }
- if ((xap = *xapp) > 0)
- {
- pix = *yp + *xp + 1 + pos;
- rr = (R_VAL(pix) * yap) >> 10;
- gg = (G_VAL(pix) * yap) >> 10;
- bb = (B_VAL(pix) * yap) >> 10;
- for (j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix += src_w;
- rr += (R_VAL(pix) * Cy) >> 10;
- gg += (G_VAL(pix) * Cy) >> 10;
- bb += (B_VAL(pix) * Cy) >> 10;
- }
- if (j > 0)
- {
- pix += src_w;
- rr += (R_VAL(pix) * j) >> 10;
- gg += (G_VAL(pix) * j) >> 10;
- bb += (B_VAL(pix) * j) >> 10;
- }
- r += ((rr - r) * xap) >> 8;
- g += ((gg - g) * xap) >> 8;
- b += ((bb - b) * xap) >> 8;
- }
- *pbuf++ = ARGB_JOIN(0xff,
- ((r + (1 << 3)) >> 4),
- ((g + (1 << 3)) >> 4),
- ((b + (1 << 3)) >> 4));
- xp++; xapp++;
- }
+ r = (R_VAL(pix) * yap) >> 10;
+ g = (G_VAL(pix) * yap) >> 10;
+ b = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ r += (R_VAL(pix) * Cy) >> 10;
+ g += (G_VAL(pix) * Cy) >> 10;
+ b += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if ((xap = *xapp) > 0)
+ {
+ pix = *yp + *xp + 1 + pos;
+ rr = (R_VAL(pix) * yap) >> 10;
+ gg = (G_VAL(pix) * yap) >> 10;
+ bb = (B_VAL(pix) * yap) >> 10;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix += src_w;
+ rr += (R_VAL(pix) * Cy) >> 10;
+ gg += (G_VAL(pix) * Cy) >> 10;
+ bb += (B_VAL(pix) * Cy) >> 10;
+ }
+ if (j > 0)
+ {
+ pix += src_w;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r += ((rr - r) * xap) >> 8;
+ g += ((gg - g) * xap) >> 8;
+ b += ((bb - b) * xap) >> 8;
+ }
+ *pbuf++ = ARGB_JOIN(0xff,
+ ((r + (1 << 3)) >> 4),
+ ((g + (1 << 3)) >> 4),
+ ((b + (1 << 3)) >> 4));
+ xp++; xapp++;
+ }
+
+ func(buf, NULL, dc->mul.col, dptr, w);
- func(buf, NULL, dc->mul.col, dptr, w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pbuf = buf;
- dptr += dst_w; dst_clip_w = w;
- yp++; yapp++;
- xp = xpoints;// + dxx;
- xapp = xapoints;// + dxx;
+ pbuf = buf;
+ dptr += dst_w; dst_clip_w = w;
+ yp++; yapp++;
+ xp = xpoints;// + dxx;
+ xapp = xapoints;// + dxx;
}
}
}
RGBA_Gfx_Func func;
RGBA_Image *maskobj;
DATA8 *mask = NULL;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
ptr = src->image.data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;
if (dc->mask.mask)
// mask += (dst_clip_y - dc->mask.y) * maskobj->cache_entry.w;
while (dst_clip_h--)
{
+ func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- ptr += src_w;
- dst_ptr += dst_w;
- mask += maskobj->cache_entry.w;
+ ptr += src_w;
+ dst_ptr += dst_w;
+ mask += maskobj->cache_entry.w;
}
}
else
{
while (dst_clip_h--)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- ptr += src_w;
- dst_ptr += dst_w;
+ func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);
+
+ ptr += src_w;
+ dst_ptr += dst_w;
}
}
}
if (drh == srh)
{
int sxx0 = sxx;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
psrc = src->image.data + (src_w * (sry + cy)) + srx;
while (pdst < pdst_end)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- pbuf = buf; pbuf_end = buf + dst_clip_w;
- sxx = sxx0;
+ pbuf = buf; pbuf_end = buf + dst_clip_w;
+ sxx = sxx0;
#ifdef SCALE_USING_MMX
- pxor_r2r(mm0, mm0);
- MOV_A2R(ALPHA_255, mm5)
+ pxor_r2r(mm0, mm0);
+ MOV_A2R(ALPHA_255, mm5)
#endif
- while (pbuf < pbuf_end)
- {
- DATA32 p0, p1;
- int ax;
-
- sx = (sxx >> 16);
- ax = 1 + ((sxx - (sx << 16)) >> 8);
- p0 = p1 = *(psrc + sx);
- if ((sx + 1) < srw)
- p1 = *(psrc + sx + 1);
+ while (pbuf < pbuf_end)
+ {
+ DATA32 p0, p1;
+ int ax;
+
+ sx = (sxx >> 16);
+ ax = 1 + ((sxx - (sx << 16)) >> 8);
+ p0 = p1 = *(psrc + sx);
+ if ((sx + 1) < srw)
+ p1 = *(psrc + sx + 1);
#ifdef SCALE_USING_MMX
- MOV_P2R(p0, mm1, mm0)
- if (p0 | p1)
- {
- MOV_A2R(ax, mm3)
- MOV_P2R(p1, mm2, mm0)
- INTERP_256_R2R(mm3, mm2, mm1, mm5)
- }
- MOV_R2P(mm1, *pbuf, mm0)
- pbuf++;
+ MOV_P2R(p0, mm1, mm0)
+ if (p0 | p1)
+ {
+ MOV_A2R(ax, mm3)
+ MOV_P2R(p1, mm2, mm0)
+ INTERP_256_R2R(mm3, mm2, mm1, mm5)
+ }
+ MOV_R2P(mm1, *pbuf, mm0)
+ pbuf++;
#else
- if (p0 | p1)
- p0 = INTERP_256(ax, p1, p0);
- *pbuf++ = p0;
+ if (p0 | p1)
+ p0 = INTERP_256(ax, p1, p0);
+ *pbuf++ = p0;
#endif
- sxx += dsxx;
- }
- /* * blend here [clip_w *] buf -> dptr * */
- if (!direct_scale)
- func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pdst += dst_w;
- psrc += src_w;
- buf += buf_step;
+ sxx += dsxx;
+ }
+ /* * blend here [clip_w *] buf -> dptr * */
+ if (!direct_scale)
+ func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+
+ pdst += dst_w;
+ psrc += src_w;
+ buf += buf_step;
}
goto done_scale_up;
else if (drw == srw)
{
DATA32 *ps = src->image.data + (src_w * sry) + srx + cx;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
while (pdst < pdst_end)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- int ay;
+ int ay;
- sy = syy >> 16;
- psrc = ps + (sy * src_w);
- ay = 1 + ((syy - (sy << 16)) >> 8);
+ sy = syy >> 16;
+ psrc = ps + (sy * src_w);
+ ay = 1 + ((syy - (sy << 16)) >> 8);
#ifdef SCALE_USING_MMX
- pxor_r2r(mm0, mm0);
- MOV_A2R(ALPHA_255, mm5)
- MOV_A2R(ay, mm4)
+ pxor_r2r(mm0, mm0);
+ MOV_A2R(ALPHA_255, mm5)
+ MOV_A2R(ay, mm4)
#endif
- pbuf = buf; pbuf_end = buf + dst_clip_w;
- while (pbuf < pbuf_end)
- {
- DATA32 p0 = *psrc, p2 = p0;
+ pbuf = buf; pbuf_end = buf + dst_clip_w;
+ while (pbuf < pbuf_end)
+ {
+ DATA32 p0 = *psrc, p2 = p0;
- if ((sy + 1) < srh)
- p2 = *(psrc + src_w);
+ if ((sy + 1) < srh)
+ p2 = *(psrc + src_w);
#ifdef SCALE_USING_MMX
- MOV_P2R(p0, mm1, mm0)
- if (p0 | p2)
- {
- MOV_P2R(p2, mm2, mm0)
- INTERP_256_R2R(mm4, mm2, mm1, mm5)
- }
- MOV_R2P(mm1, *pbuf, mm0)
- pbuf++;
+ MOV_P2R(p0, mm1, mm0)
+ if (p0 | p2)
+ {
+ MOV_P2R(p2, mm2, mm0)
+ INTERP_256_R2R(mm4, mm2, mm1, mm5)
+ }
+ MOV_R2P(mm1, *pbuf, mm0)
+ pbuf++;
#else
- if (p0 | p2)
- p0 = INTERP_256(ay, p2, p0);
- *pbuf++ = p0;
-#endif
- psrc++;
- }
- /* * blend here [clip_w *] buf -> dptr * */
- if (!direct_scale)
- func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
- }
-#ifdef EVAS_SLI
- ysli++;
+ if (p0 | p2)
+ p0 = INTERP_256(ay, p2, p0);
+ *pbuf++ = p0;
#endif
+ psrc++;
+ }
+ /* * blend here [clip_w *] buf -> dptr * */
+ if (!direct_scale)
+ func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
pdst += dst_w;
syy += dsyy;
buf += buf_step;
{
DATA32 *ps = src->image.data + (src_w * sry) + srx;
int sxx0 = sxx;
-#ifdef EVAS_SLI
- int ysli = dst_clip_y;
-#endif
while (pdst < pdst_end)
{
-#ifdef EVAS_SLI
- if (((ysli) % dc->sli.h) == dc->sli.y)
-#endif
- {
- int ay;
+ int ay;
- sy = syy >> 16;
- psrc = ps + (sy * src_w);
- ay = 1 + ((syy - (sy << 16)) >> 8);
+ sy = syy >> 16;
+ psrc = ps + (sy * src_w);
+ ay = 1 + ((syy - (sy << 16)) >> 8);
#ifdef SCALE_USING_MMX
- MOV_A2R(ay, mm4)
- pxor_r2r(mm0, mm0);
- MOV_A2R(ALPHA_255, mm5)
+ MOV_A2R(ay, mm4)
+ pxor_r2r(mm0, mm0);
+ MOV_A2R(ALPHA_255, mm5)
#endif
- pbuf = buf; pbuf_end = buf + dst_clip_w;
- sxx = sxx0;
- while (pbuf < pbuf_end)
- {
- int ax;
- DATA32 *p, *q;
- DATA32 p0, p1, p2, p3;
-
- sx = sxx >> 16;
- ax = 1 + ((sxx - (sx << 16)) >> 8);
- p = psrc + sx; q = p + src_w;
- p0 = p1 = p2 = p3 = *p;
- if ((sx + 1) < srw)
- p1 = *(p + 1);
- if ((sy + 1) < srh)
- {
- p2 = *q; p3 = p2;
- if ((sx + 1) < srw)
- p3 = *(q + 1);
- }
+ pbuf = buf; pbuf_end = buf + dst_clip_w;
+ sxx = sxx0;
+ while (pbuf < pbuf_end)
+ {
+ int ax;
+ DATA32 *p, *q;
+ DATA32 p0, p1, p2, p3;
+
+ sx = sxx >> 16;
+ ax = 1 + ((sxx - (sx << 16)) >> 8);
+ p = psrc + sx; q = p + src_w;
+ p0 = p1 = p2 = p3 = *p;
+ if ((sx + 1) < srw)
+ p1 = *(p + 1);
+ if ((sy + 1) < srh)
+ {
+ p2 = *q; p3 = p2;
+ if ((sx + 1) < srw)
+ p3 = *(q + 1);
+ }
#ifdef SCALE_USING_MMX
- MOV_A2R(ax, mm6)
- MOV_P2R(p0, mm1, mm0)
- if (p0 | p1)
- {
- MOV_P2R(p1, mm2, mm0)
- INTERP_256_R2R(mm6, mm2, mm1, mm5)
- }
- MOV_P2R(p2, mm2, mm0)
- if (p2 | p3)
- {
- MOV_P2R(p3, mm3, mm0)
- INTERP_256_R2R(mm6, mm3, mm2, mm5)
- }
- INTERP_256_R2R(mm4, mm2, mm1, mm5)
- MOV_R2P(mm1, *pbuf, mm0)
- pbuf++;
+ MOV_A2R(ax, mm6)
+ MOV_P2R(p0, mm1, mm0)
+ if (p0 | p1)
+ {
+ MOV_P2R(p1, mm2, mm0)
+ INTERP_256_R2R(mm6, mm2, mm1, mm5)
+ }
+ MOV_P2R(p2, mm2, mm0)
+ if (p2 | p3)
+ {
+ MOV_P2R(p3, mm3, mm0)
+ INTERP_256_R2R(mm6, mm3, mm2, mm5)
+ }
+ INTERP_256_R2R(mm4, mm2, mm1, mm5)
+ MOV_R2P(mm1, *pbuf, mm0)
+ pbuf++;
#else
- if (p0 | p1)
- p0 = INTERP_256(ax, p1, p0);
- if (p2 | p3)
- p2 = INTERP_256(ax, p3, p2);
- if (p0 | p2)
- p0 = INTERP_256(ay, p2, p0);
- *pbuf++ = p0;
+ if (p0 | p1)
+ p0 = INTERP_256(ax, p1, p0);
+ if (p2 | p3)
+ p2 = INTERP_256(ax, p3, p2);
+ if (p0 | p2)
+ p0 = INTERP_256(ay, p2, p0);
+ *pbuf++ = p0;
#endif
- sxx += dsxx;
- }
- /* * blend here [clip_w *] buf -> dptr * */
- if (!direct_scale)
- func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
- }
-#ifdef EVAS_SLI
- ysli++;
-#endif
- pdst += dst_w;
- syy += dsyy;
- buf += buf_step;
+ sxx += dsxx;
+ }
+ /* * blend here [clip_w *] buf -> dptr * */
+ if (!direct_scale)
+ func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+
+ pdst += dst_w;
+ syy += dsyy;
+ buf += buf_step;
}
}
done_scale_up:
#include "language/evas_language_utils.h"
#include "evas_font_ot.h"
+#define PROPS_CHANGE(Props) Props->changed = EINA_TRUE;
+
void
evas_common_text_props_bidi_set(Evas_Text_Props *props,
Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start)
(void) bidi_par_props;
props->bidi.dir = EVAS_BIDI_DIRECTION_LTR;
#endif
+ PROPS_CHANGE(props);
}
void
evas_common_text_props_script_set(Evas_Text_Props *props, Evas_Script_Type scr)
{
props->script = scr;
+ PROPS_CHANGE(props);
}
void
if (--(props->info->refcount) == 0)
{
+ if (props->bin)
+ {
+ eina_binbuf_free(props->bin);
+ props->bin = NULL;
+ }
+
if (props->info->glyph)
free(props->info->glyph);
#ifdef OT_SUPPORT
}
ext->text_len = base->text_len - (ext->text_offset - base->text_offset);
base->text_len = (ext->text_offset - base->text_offset);
+ PROPS_CHANGE(base);
+ PROPS_CHANGE(ext);
}
/* Won't work in the middle of ligatures */
item1->len += item2->len;
item1->text_len += item2->text_len;
+ PROPS_CHANGE(item1);
}
-EAPI Eina_Bool
-evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
- Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props,
- size_t par_pos, int len)
-{
- RGBA_Font_Int *fi = (RGBA_Font_Int *) _fi;
-
- if (text_props->info)
- {
- evas_common_text_props_content_unref(text_props);
- }
- if (len == 0)
- {
- text_props->info = NULL;
- text_props->start = text_props->len = text_props->text_offset = 0;
- }
- text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
-
- text_props->font_instance = fi;
-
- evas_common_font_int_reload(fi);
- if (fi->src->current_size != fi->size)
- {
- FTLOCK();
- FT_Activate_Size(fi->ft.size);
- FTUNLOCK();
- fi->src->current_size = fi->size;
- }
-
#ifdef OT_SUPPORT
+static inline void
+_content_create_ot(RGBA_Font_Int *fi, const Eina_Unicode *text,
+ Evas_Text_Props *text_props, int len, Evas_Text_Props_Mode mode)
+{
size_t char_index;
Evas_Font_Glyph_Info *gl_itr;
Evas_Coord pen_x = 0, adjust_x = 0;
- (void) par_props;
- (void) par_pos;
- evas_common_font_ot_populate_text_props(text, text_props, len);
+ evas_common_font_ot_populate_text_props(text, text_props, len, mode);
gl_itr = text_props->info->glyph;
for (char_index = 0 ; char_index < text_props->len ; char_index++)
}
LKU(fi->ft_mutex);
- gl_itr->x_bear = fg->glyph_out->left;
- gl_itr->width = fg->glyph_out->bitmap.width;
+ gl_itr->x_bear = fg->x_bear;
+ gl_itr->width = fg->width;
/* text_props->info->glyph[char_index].advance =
* text_props->info->glyph[char_index].index =
* already done by the ot function */
fi = text_props->font_instance;
gl_itr++;
}
-#else
+}
+#endif
+
+static inline void
+_content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text,
+ Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props,
+ size_t par_pos, int len, Evas_Text_Props_Mode mode)
+{
/* We are walking the string in visual ordering */
Evas_Font_Glyph_Info *gl_itr;
Eina_Bool use_kerning;
int adv_d, i;
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
Eina_Unicode *base_str = NULL;
- if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+ if (mode == EVAS_TEXT_PROPS_MODE_SHAPE)
{
- text = base_str = eina_unicode_strndup(text, len);
- evas_bidi_shape_string(base_str, par_props, par_pos, len);
+ if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+ {
+ text = base_str = eina_unicode_strndup(text, len);
+ evas_bidi_shape_string(base_str, par_props, par_pos, len);
+ }
}
#else
+ (void) mode;
(void) par_props;
(void) par_pos;
#endif
idx = evas_common_get_char_index(fi, REPLACEMENT_CHAR);
}
- LKL(fi->ft_mutex);
fg = evas_common_font_int_cache_glyph_get(fi, idx);
- if (!fg)
- {
- LKU(fi->ft_mutex);
- continue;
- }
+ if (!fg) continue;
kern = 0;
if ((use_kerning) && (prev_index) && (idx) &&
}
pface = fi->src->ft.face;
- LKU(fi->ft_mutex);
gl_itr->index = idx;
- gl_itr->x_bear = fg->glyph_out->left;
+ gl_itr->x_bear = fg->x_bear;
adv = fg->glyph->advance.x >> 10;
- gl_itr->width = fg->glyph_out->bitmap.width;
+ gl_itr->width = fg->width;
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
{
if (base_str)
free(base_str);
# endif
+}
+
+EAPI Eina_Bool
+evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
+ Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props,
+ size_t par_pos, int len, Evas_Text_Props_Mode mode)
+{
+ RGBA_Font_Int *fi = (RGBA_Font_Int *) _fi;
+
+ if (text_props->info)
+ {
+ evas_common_text_props_content_unref(text_props);
+ }
+ if (len == 0)
+ {
+ text_props->info = NULL;
+ text_props->start = text_props->len = text_props->text_offset = 0;
+ }
+ text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
+
+ text_props->font_instance = fi;
+
+ evas_common_font_int_reload(fi);
+ if (fi->src->current_size != fi->size)
+ {
+ evas_common_font_source_reload(fi->src);
+ FTLOCK();
+ FT_Activate_Size(fi->ft.size);
+ FTUNLOCK();
+ fi->src->current_size = fi->size;
+ }
+
+ text_props->changed = EINA_TRUE;
+
+#ifdef OT_SUPPORT
+ (void) par_props;
+ (void) par_pos;
+ _content_create_ot(fi, text, text_props, len, mode);
+#else
+ _content_create_regular(fi, text, text_props, par_props, par_pos, len, mode);
#endif
+
text_props->text_len = len;
text_props->info->refcount = 1;
return EINA_TRUE;
}
+
typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
+typedef enum
+{
+ EVAS_TEXT_PROPS_MODE_NONE = 0,
+ EVAS_TEXT_PROPS_MODE_SHAPE
+} Evas_Text_Props_Mode;
+
# include "evas_font_ot.h"
# include "language/evas_bidi_utils.h"
# include "language/evas_language_utils.h"
Evas_Script_Type script;
Evas_Text_Props_Info *info;
void *font_instance;
+
+ Eina_Binbuf *bin;
+
+ int generation;
+ Eina_Bool changed : 1;
+ Eina_Bool prepare : 1;
};
struct _Evas_Text_Props_Info
Evas_Coord pen_after;
};
-
void
evas_common_text_props_bidi_set(Evas_Text_Props *props,
Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start);
EAPI Eina_Bool
evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props,
- size_t par_pos, int len);
+ size_t par_pos, int len, Evas_Text_Props_Mode mode);
void
evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
@FREETYPE_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@PIXMAN_CFLAGS@
noinst_LTLIBRARIES = libevas_file.la
# define THI(x) int x
# define TH_MAX 8
-// even though in theory having every Nth rendered line done by a different
-// thread might even out load across threads - it actually slows things down.
-//#define EVAS_SLI 1
-
#else
# define TH(x)
# define THI(x)
typedef struct _RGBA_Draw_Context RGBA_Draw_Context;
typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point;
typedef struct _RGBA_Map_Point RGBA_Map_Point;
+typedef struct _RGBA_Map RGBA_Map;
typedef struct _RGBA_Font RGBA_Font;
typedef struct _RGBA_Font_Int RGBA_Font_Int;
typedef struct _RGBA_Font_Source RGBA_Font_Source;
typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal);
#include "../cache/evas_cache.h"
+#ifdef EVAS_CSERVE2
+#include "../cache2/evas_cache2.h"
+#endif
/*****************************************************************************/
EINA_INLIST;
Evas_Cache_Image *cache;
+#ifdef EVAS_CSERVE2
+ Evas_Cache2 *cache2;
+#endif
const char *cache_key;
Image_Timestamp tstamp;
int references;
-#ifdef EVAS_FRAME_QUEUING
- LK(lock_references); // needed for accessing references
-#endif
#ifdef BUILD_PIPE_RENDER
RGBA_Pipe *pipe;
-#ifdef EVAS_FRAME_QUEUING
- LK(ref_fq_add);
- LK(ref_fq_del);
- Eina_Condition cond_fq_del;
- int ref_fq[2]; // ref_fq[0] is for addition, ref_fq[1] is for deletion
-#endif
#endif
unsigned char scale;
Image_Entry_Flags flags;
Evas_Image_Scale_Hint scale_hint;
void *data1, *data2;
+#ifdef EVAS_CSERVE2
+ unsigned int open_rid, load_rid, preload_rid;
+#endif
int server_id;
int connect_num;
int channel;
struct _RGBA_Pipe_Op
{
RGBA_Draw_Context context;
- void (*op_func) (RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info);
+ void (*op_func) (RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info);
void (*free_func) (RGBA_Pipe_Op *op);
union {
RGBA_Polygon_Point *points;
} poly;
struct {
- RGBA_Font *font;
int x, y;
- Evas_Text_Props intl_props;
+ Evas_Text_Props *intl_props;
} text;
struct {
RGBA_Image *src;
struct _RGBA_Pipe_Thread_Info
{
+ EINA_INLIST;
RGBA_Image *im;
int x, y, w, h;
};
FPc px, py, z0, foc;
};
+struct _RGBA_Map
+{
+ void *engine_data;
+
+ struct {
+ int w, h;
+ } image, uv;
+
+ int x, y;
+ int count;
+
+ RGBA_Map_Point pts[1];
+};
+
#if 0 // filtering disabled
struct _Filtered_Image
{
Fash_Int *fash;
Font_Hint_Flags hinting;
int references;
-#ifdef EVAS_FRAME_QUEUING
- int ref_fq[2]; //ref_fq[0] is for addition, ref_fq[1] is for deletion
- Eina_Condition cond_fq_del;
- LK(ref_fq_add);
- LK(ref_fq_del);
-#endif
LK(lock);
unsigned char sizeok : 1;
};
Font_Rend_Flags wanted_rend; /* The wanted rendering style */
Font_Rend_Flags runtime_rend; /* The rendering we need to do on runtime
in order to comply with the wanted_rend. */
+
+ Eina_List *task;
+
+ int generation;
+
unsigned char sizeok : 1;
unsigned char inuse : 1;
};
struct _RGBA_Font_Glyph
{
FT_UInt index;
+ Evas_Coord width;
+ Evas_Coord x_bear;
FT_Glyph glyph;
FT_BitmapGlyph glyph_out;
/* this is a problem - only 1 engine at a time can extend such a font... grrr */
#ifndef EVAS_INLINE_H
#define EVAS_INLINE_H
+static inline Eina_Bool
+_evas_render_has_map(Evas_Object *obj)
+{
+ return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
+ ((obj->cur.map) && (obj->cur.usemap)));
+ // return ((obj->cur.map) && (obj->cur.usemap));
+}
+
static inline void
_evas_object_event_new(void)
{
#define MAGIC_OBJ_TEXT 0x71777776
#define MAGIC_OBJ_SMART 0x71777777
#define MAGIC_OBJ_TEXTBLOCK 0x71777778
+#define MAGIC_OBJ_TEXTGRID 0x7177777A
#define MAGIC_SMART 0x72777770
#define MAGIC_OBJ_SHAPE 0x72777773
#define MAGIC_OBJ_CONTAINER 0x72777774
{
Evas_Coord x, y, w, h;
Eina_Bool changed : 1;
+ Evas_Object *clip;
} framespace;
Eina_List *damages;
Evas_Object *map_parent;
double scale;
Evas_Coord_Rectangle geometry;
+ Evas_Coord_Rectangle bounding_box;
struct {
struct {
Evas_Coord x, y, w, h;
Eina_Bool have_clipees : 1;
Eina_Bool anti_alias : 1;
Evas_Render_Op render_op : 4;
+
+ Eina_Bool valid_bounding_box : 1;
+ Eina_Bool cached_surface : 1;
+ Eina_Bool parent_cached_surface : 1;
} cur, prev;
char *name;
Evas_Size_Hints *size_hints;
+ RGBA_Map *spans;
+
int last_mouse_down_counter;
int last_mouse_up_counter;
int mouse_grabbed;
Eina_Bool del_ref : 1;
Eina_Bool is_frame : 1;
+ Eina_Bool child_has_map : 1;
};
struct _Evas_Func_Node
int (*font_v_advance_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props);
int (*font_char_coords_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
int (*font_char_at_coords_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
- void (*font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, const Evas_Text_Props *intl_props);
+ void (*font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Text_Props *intl_props);
void (*font_cache_flush) (void *data);
void (*font_cache_set) (void *data, int bytes);
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);
int (*font_pen_coords_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
- Eina_Bool (*font_text_props_info_create) (void *data __UNUSED__, Evas_Font_Instance *fi, const Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
+ Eina_Bool (*font_text_props_info_create) (void *data __UNUSED__, Evas_Font_Instance *fi, const Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len, Evas_Text_Props_Mode mode);
int (*font_right_inset_get) (void *data, Evas_Font_Set *font, const Evas_Text_Props *text_props);
#if 0 // filtering disabled
Evas_Object *evas_object_new(Evas *e);
void evas_object_change_reset(Evas_Object *obj);
void evas_object_free(Evas_Object *obj, int clean_layer);
+void evas_object_update_bounding_box(Evas_Object *obj);
void evas_object_inject(Evas_Object *obj, Evas *e);
void evas_object_release(Evas_Object *obj, int clean_layer);
void evas_object_change(Evas_Object *obj);
const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
void _evas_object_smart_members_all_del(Evas_Object *obj);
void evas_call_smarts_calculate(Evas *e);
+void evas_object_smart_bouding_box_update(Evas_Object *obj);
+void evas_object_smart_need_bounding_box_update(Evas_Object *obj);
void *evas_mem_calloc(int size);
void _evas_post_event_callback_call(Evas *e);
void _evas_post_event_callback_free(Evas *e);
Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y);
Eina_Bool evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord *mx, Evas_Coord *my, int grab);
+void evas_object_map_update(Evas_Object *obj, int x, int y, int imagew, int imageh, int uvw, int uvh);
Eina_List *evas_module_engine_list(void);
int _evas_alloc_error = 0;
static int _evas_debug_init = 0;
-static int _evas_debug_show = 0;
+static enum {
+ _EVAS_DEBUG_DEFAULT,
+ _EVAS_DEBUG_HIDE,
+ _EVAS_DEBUG_SHOW
+} _evas_debug_show = _EVAS_DEBUG_DEFAULT;
static int _evas_debug_abort = 0;
EAPI Evas_Alloc_Error
return NULL;
}
+static void
+_evas_debug_init_from_env()
+{
+ const char *tmp = getenv("EVAS_DEBUG_SHOW");
+ if (tmp)
+ {
+ int dbgshow = atoi(tmp);
+ _evas_debug_show = (dbgshow) ? _EVAS_DEBUG_SHOW : _EVAS_DEBUG_HIDE;
+ }
+ if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
+ _evas_debug_init = 1;
+}
+
void
evas_debug_error(void)
{
if (!_evas_debug_init)
{
- if (getenv("EVAS_DEBUG_SHOW")) _evas_debug_show = 1;
- if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
- _evas_debug_init = 1;
+ _evas_debug_init_from_env();
}
- if (_evas_debug_show)
+ if (_evas_debug_show == _EVAS_DEBUG_SHOW)
CRIT("Evas Magic Check Failed!!!");
}
{
if (!_evas_debug_init)
{
- if (getenv("EVAS_DEBUG_SHOW")) _evas_debug_show = 1;
- if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
- _evas_debug_init = 1;
+ _evas_debug_init_from_env();
}
- if (_evas_debug_show)
+ if (_evas_debug_show == _EVAS_DEBUG_SHOW)
CRIT("Input object pointer is NULL!");
if (_evas_debug_abort) abort();
}
{
if (!_evas_debug_init)
{
- if (getenv("EVAS_DEBUG_SHOW")) _evas_debug_show = 1;
- if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
- _evas_debug_init = 1;
+ _evas_debug_init_from_env();
}
- if (_evas_debug_show)
+ if ((_evas_debug_show == _EVAS_DEBUG_SHOW) ||
+ (_evas_debug_show == _EVAS_DEBUG_DEFAULT))
CRIT("Input object is zero'ed out (maybe a freed object or zero-filled RAM)!");
if (_evas_debug_abort) abort();
}
{
if (!_evas_debug_init)
{
- if (getenv("EVAS_DEBUG_SHOW")) _evas_debug_show = 1;
- if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
- _evas_debug_init = 1;
+ _evas_debug_init_from_env();
}
- if (_evas_debug_show)
+ if ((_evas_debug_show == _EVAS_DEBUG_SHOW) ||
+ (_evas_debug_show == _EVAS_DEBUG_DEFAULT))
CRIT("Input object is wrong type\n"
" Expected: %08x - %s\n"
" Supplied: %08x - %s",
{
if (!_evas_debug_init)
{
- if (getenv("EVAS_DEBUG_SHOW")) _evas_debug_show = 1;
- if (getenv("EVAS_DEBUG_ABORT")) _evas_debug_abort = 1;
- _evas_debug_init = 1;
+ _evas_debug_init_from_env();
}
- if (_evas_debug_show)
+ if ((_evas_debug_show == _EVAS_DEBUG_SHOW) ||
+ (_evas_debug_show == _EVAS_DEBUG_DEFAULT))
CRIT("%s", str);
if (_evas_debug_abort) abort();
}
-I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
-I$(top_srcdir)/src/modules/engines \
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@
if BUILD_ENGINE_BUFFER
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
+
#include "evas_common.h"
#include "evas_engine.h"
{
if (buf->priv.back_buf)
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&buf->priv.back_buf->cache_entry);
+ else
+#endif
evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
}
free(buf);
(buf->dest) && (buf->dest_row_bytes == (buf->w * sizeof(DATA32))))
{
memset(buf->dest, 0, h * buf->dest_row_bytes);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ buf->priv.back_buf = (RGBA_Image *) evas_cache2_image_data(evas_common_image_cache2_get(),
+ w, h,
+ buf->dest,
+ 1, EVAS_COLORSPACE_ARGB8888);
+ else
+#endif
buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
w, h,
buf->dest,
else if ((buf->depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) &&
(buf->dest) && (buf->dest_row_bytes == (buf->w * sizeof(DATA32))))
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ buf->priv.back_buf = (RGBA_Image *) evas_cache2_image_data(evas_common_image_cache2_get(),
+ w, h,
+ buf->dest,
+ 0, EVAS_COLORSPACE_ARGB8888);
+ else
+#endif
buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
w, h,
buf->dest,
else
{
*cx = 0; *cy = 0; *cw = w; *ch = h;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
+ else
+#endif
im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
if (im)
{
((buf->depth == OUTBUF_DEPTH_BGRA_32BPP_8888_8888)))
{
im->cache_entry.flags.alpha = 1;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_size_set(&im->cache_entry, w, h);
+ else
+#endif
im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
}
}
void
evas_buffer_outbuf_buf_free_region_for_update(Outbuf *buf, RGBA_Image *update)
{
- if (update != buf->priv.back_buf) evas_cache_image_drop(&update->cache_entry);
+ if (update != buf->priv.back_buf)
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&update->cache_entry);
+ else
+#endif
+ evas_cache_image_drop(&update->cache_entry);
+ }
}
void
buf->dest = buf->func.switch_buffer(buf->switch_data, buf->dest);
if (buf->priv.back_buf)
{
- evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
- buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
- buf->w, buf->h,
- buf->dest,
- buf->depth == OUTBUF_DEPTH_ARGB_32BPP_8888_8888 ? 1 : 0,
- EVAS_COLORSPACE_ARGB8888);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&buf->priv.back_buf->cache_entry);
+ buf->priv.back_buf = (RGBA_Image *) evas_cache2_image_data(evas_common_image_cache2_get(),
+ buf->w, buf->h,
+ buf->dest,
+ buf->depth == OUTBUF_DEPTH_ARGB_32BPP_8888_8888 ? 1 : 0,
+ EVAS_COLORSPACE_ARGB8888);
+ }
+ else
+#endif
+ {
+ evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
+ buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
+ buf->w, buf->h,
+ buf->dest,
+ buf->depth == OUTBUF_DEPTH_ARGB_32BPP_8888_8888 ? 1 : 0,
+ EVAS_COLORSPACE_ARGB8888);
+ }
}
}
}
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_direct3d_cflags@
if BUILD_ENGINE_DIRECT3D
}
static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, const Evas_Text_Props *intl_props)
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Text_Props *intl_props)
{
Render_Engine *re = (Render_Engine *)data;
RGBA_Image im;
evas_direct3d_font_texture_new,
evas_direct3d_font_texture_free,
evas_direct3d_font_texture_draw);
- evas_common_font_draw(&im, context, (RGBA_Font *) font, x, y, intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(&im, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
}
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_directfb_cflags@
if BUILD_ENGINE_DIRECTFB
* memory.
*/
static void
-evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
DirectFB_Engine_Image_Entry *eim = surface;
IDirectFBSurface *screen;
if (!_dfb_lock_and_sync_image(screen, im, DSLF_READ | DSLF_WRITE))
return;
- evas_common_font_draw(im, context, font, x, y, intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(im, context, x, y, intl_props);
evas_common_cpu_end_opt();
im->image.data = NULL;
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_fb_cflags@
if BUILD_ENGINE_FB
@EINA_CFLAGS@ \
@GL_EET_CFLAGS@ \
@FREETYPE_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_gl_cocoa_cflags@
if BUILD_ENGINE_GL_COCOA
}
static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
Render_Engine *re;
evas_gl_font_texture_new,
evas_gl_font_texture_free,
evas_gl_font_texture_draw);
- evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
- intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(im, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@GL_EET_CFLAGS@ \
-@EINA_CFLAGS@
+@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@
if BUILD_ENGINE_GL_COMMON
nw = ((w + 3) / 4) * 4;
ndata = alloca(nw *h);
if (!ndata) return NULL;
- if (fg->glyph_out->bitmap.num_grays == 256)
+ if ((fg->glyph_out->bitmap.num_grays == 256) &&
+ (fg->glyph_out->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY))
{
int x, y;
DATA8 *p1, *p2;
}
}
}
- else if (fg->glyph_out->bitmap.num_grays == 0)
+ else
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
b = (dc->col.col ) & 0xff;
}
- glFlush();
-
c = gc->dc->clip.use;
cx = gc->dc->clip.x; cy = gc->dc->clip.y;
cw = gc->dc->clip.w; ch = gc->dc->clip.h;
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
@GL_EET_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_gl_sdl_cflags@
if BUILD_ENGINE_GL_SDL
}
static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
Render_Engine *re;
evas_gl_font_texture_new,
evas_gl_font_texture_free,
evas_gl_font_texture_draw);
- evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
- intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(im, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
@GL_EET_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_gl_xlib_cflags@
if BUILD_ENGINE_GL_X11
//----------- GLES 2.0 Extensions ------------//
// If the symbol's not found, they get set to NULL
// If one of the functions in the extension exists, the extension in supported
+
/* GL_OES_get_program_binary */
FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinary", glsym_func_void);
FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryEXT", glsym_func_void);
}
static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
Render_Engine *re;
evas_gl_font_texture_new,
evas_gl_font_texture_free,
evas_gl_font_texture_draw);
- evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
- intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(im, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
}
#endif
+
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &re->gl_cap.max_rb_size);
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
{
sfc->direct_fb_opt = 1;
- fprintf(stderr, "########################################################\n");
- fprintf(stderr, "######### [Evas] Direct option bit is enabled ##########\n");
- fprintf(stderr, "########################################################\n");
+ DBG("########################################################");
+ DBG("######### [Evas] Direct option bit is enabled ##########");
+ DBG("########################################################");
}
// Add other options here...
}
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, curr_tex);
- // Attach texture to FBO
if (sfc->rt_msaa_samples)
glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
if (getenv("EVAS_GL_DIRECT_OVERRIDE"))
{
gl_direct_override = 1;
- fprintf(stderr, "########################################################\n");
- fprintf(stderr, "######### [Evas] Direct overriding is enabled ##########\n");
- fprintf(stderr, "########################################################\n");
+ DBG("########################################################");
+ DBG("######### [Evas] Direct overriding is enabled ##########");
+ DBG("########################################################");
}
/* store it for later use */
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_psl1ght_cflags@
if BUILD_ENGINE_PSL1GHT
}
static void
-eng_font_draw(void *data __UNUSED__, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *text_props)
+eng_font_draw(void *data __UNUSED__, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *text_props)
{
static RGBA_Image *im = NULL;
Soft16_Image *dst = surface;
evas_common_soft16_font_glyph_new,
evas_common_soft16_font_glyph_free,
evas_common_soft16_font_glyph_draw);
- evas_common_font_draw(im, context, (RGBA_Font *) font, x, y, text_props);
+ evas_common_font_draw_prepare(text_props);
+ evas_common_font_draw(im, context, x, y, text_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_16_ddraw_cflags@
if BUILD_ENGINE_SOFTWARE_16_DDRAW
MAINTAINERCLEANFILES = Makefile.in
-INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include @FREETYPE_CFLAGS@ @PIXMAN_CFLAGS@ @SDL_CFLAGS@ @EINA_CFLAGS@
+INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@SDL_CFLAGS@ \
+@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@
if BUILD_ENGINE_SOFTWARE_16_SDL
}
static void
-evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
static RGBA_Image *im = NULL;
SDL_Engine_Image_Entry *eim = surface;
evas_common_soft16_font_glyph_new,
evas_common_soft16_font_glyph_free,
evas_common_soft16_font_glyph_draw);
- evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, font, x, y, intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_16_wince_cflags@
if BUILD_ENGINE_SOFTWARE_16_WINCE
@FREETYPE_CFLAGS@ \
@EINA_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_16_x11_cflags@
if BUILD_ENGINE_SOFTWARE_16_X11
Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__,
int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *text_props)
{
- evas_common_font_draw(surface, context, (RGBA_Font *) font, x, y,
- text_props);
+ evas_common_font_draw_prepare(text_props);
+ evas_common_font_draw(surface, context, x, y, text_props);
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
}
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
-@evas_engine_software_8_x11_cflags@ \
--I/usr/include/pixman-1
+@FRIBIDI_CFLAGS@ \
+@evas_engine_software_8_x11_cflags@
if BUILD_ENGINE_SOFTWARE_8_X11
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_ddraw_cflags@
if BUILD_ENGINE_SOFTWARE_DDRAW
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_gdi_cflags@
if BUILD_ENGINE_SOFTWARE_GDI
gdipool = eina_list_prepend(gdipool, gdiob);
gdisize += gdiob->psize * (gdiob->depth >> 3);
while ((gdisize > (gdimemlimit)) ||
- (eina_list_count(gdipool) > gdicountlimit))
+ ((int)eina_list_count(gdipool) > gdicountlimit))
{
Eina_List *xl;
RECT rect;
POINT pt = { 0, 0 };
HRGN region;
- int *tmp;
+ DATA32 *tmp;
int i;
int j;
int ww;
-I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
-I$(top_srcdir)/src/modules/engines \
@EINA_CFLAGS@ \
@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@
SOFTWARE_GENERIC_SOURCES = evas_engine.c
#include "evas_common.h" /* Also includes international specific stuff */
#include "evas_private.h"
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
#ifdef HAVE_DLSYM
# include <dlfcn.h> /* dlopen,dlclose,etc */
eng_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h)
{
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
-#ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-#endif
- )
+ if ((cpunum > 1))
evas_common_pipe_rectangle_draw(surface, context, x, y, w, h);
else
#endif
eng_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2)
{
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
- #ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-#endif
- )
+ if ((cpunum > 1))
evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2);
else
#endif
eng_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y)
{
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
-#ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-#endif
- )
+ if ((cpunum > 1))
evas_common_pipe_poly_draw(surface, context, polygon, x, y);
else
#endif
return im;
}
im = (RGBA_Image *) evas_cache_image_alone(&im->cache_entry);
- evas_common_image_colorspace_dirty(im);
-
im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
+ evas_common_image_colorspace_dirty(im);
return im;
}
eng_image_load(void *data __UNUSED__, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
{
*error = EVAS_LOAD_ERROR_NONE;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ Image_Entry *ie;
+ ie = evas_cache2_image_open(evas_common_image_cache2_get(),
+ file, key, lo, error);
+ if (ie)
+ evas_cache2_image_open_wait(ie);
+
+ return ie;
+ }
+#endif
return evas_common_load_image_from_file(file, key, lo, error);
}
static void *
eng_image_new_from_data(void *data __UNUSED__, int w, int h, DATA32 *image_data, int alpha, int cspace)
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ Evas_Cache2 *cache = evas_common_image_cache2_get();
+ return evas_cache2_image_data(cache, w, h, image_data, alpha, cspace);
+ }
+#endif
return evas_cache_image_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace);
}
static void *
eng_image_new_from_copied_data(void *data __UNUSED__, int w, int h, DATA32 *image_data, int alpha, int cspace)
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ Evas_Cache2 *cache = evas_common_image_cache2_get();
+ return evas_cache2_image_copied_data(cache, w, h, image_data, alpha,
+ cspace);
+ }
+#endif
return evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace);
}
static void
eng_image_free(void *data __UNUSED__, void *image)
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(image);
+ return;
+ }
+#endif
evas_cache_image_drop(image);
}
{
Image_Entry *im = image;
if (!im) return NULL;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ return evas_cache2_image_size_set(im, w, h);
+#endif
return evas_cache_image_size_set(im, w, h);
}
{
Image_Entry *im = image;
if (!im) return NULL;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ return evas_cache2_image_dirty(im, x, y, w, h);
+#endif
return evas_cache_image_dirty(im, x, y, w, h);
}
eng_image_data_get(void *data __UNUSED__, void *image, int to_write, DATA32 **image_data, int *err)
{
RGBA_Image *im;
- int error;
+ int error = EVAS_LOAD_ERROR_NONE;
if (!image)
{
return NULL;
}
im = image;
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ error = evas_cache2_image_load_data(&im->cache_entry);
+ if (err) *err = error;
+
+ if (to_write)
+ im = (RGBA_Image *)evas_cache2_image_writable(&im->cache_entry);
+
+ *image_data = im->image.data;
+ return im;
+ }
+#endif
+
error = evas_cache_image_load_data(&im->cache_entry);
switch (im->cache_entry.space)
{
im2 = eng_image_new_from_data(data, w, h, image_data,
eng_image_alpha_get(data, image),
eng_image_colorspace_get(data, image));
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ im = im2;
+ break;
+ }
+#endif
evas_cache_image_drop(&im->cache_entry);
im = im2;
}
eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
{
RGBA_Image *im = image;
-
if (!im) return ;
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_preload_data(&im->cache_entry, target);
+ return;
+ }
+#endif
evas_cache_image_preload_data(&im->cache_entry, target);
}
eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
{
RGBA_Image *im = image;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ return;
+#endif
if (!im) return ;
evas_cache_image_preload_cancel(&im->cache_entry, target);
if (!image) return;
im = image;
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
-#ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-#endif
- )
+ if ((cpunum > 1))
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+#endif
evas_common_rgba_image_scalecache_prepare((Image_Entry *)(im),
surface, context, smooth,
src_x, src_y, src_w, src_h,
else
#endif
{
-// if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
-// evas_cache_image_load_data(&im->cache_entry);
-// evas_common_image_colorspace_normalize(im);
+#if 0
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_load_data(&im->cache_entry);
+ goto image_loaded;
+ }
+#endif
+ if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
+ evas_cache_image_load_data(&im->cache_entry);
+ evas_common_image_colorspace_normalize(im);
+
+image_loaded:
+#endif
evas_common_rgba_image_scalecache_prepare(&im->cache_entry, surface, context, smooth,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h);
else
{
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
-# ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-# endif
- )
+ if ((cpunum > 1))
evas_common_pipe_map_draw(im, surface, context, npoints, p, smooth, level);
else
#endif
eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha)
{
void *surface;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ surface = evas_cache2_image_copied_data(evas_common_image_cache2_get(),
+ w, h, NULL, alpha,
+ EVAS_COLORSPACE_ARGB8888);
+ evas_cache2_image_pixels(surface);
+ return surface;
+ }
+#endif
surface = evas_cache_image_copied_data(evas_common_image_cache_get(),
w, h, NULL, alpha,
EVAS_COLORSPACE_ARGB8888);
static void
eng_image_map_surface_free(void *data __UNUSED__, void *surface)
{
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_unload_data(surface);
+ return;
+ }
+#endif
evas_cache_image_drop(surface);
}
}
static Eina_Bool
-eng_font_text_props_info_create(void *data __UNUSED__, Evas_Font_Instance *fi, const Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t par_pos, size_t len)
+eng_font_text_props_info_create(void *data __UNUSED__, Evas_Font_Instance *fi, const Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t par_pos, size_t len, Evas_Text_Props_Mode mode)
{
return evas_common_text_props_content_create((RGBA_Font_Int *) fi, text,
- text_props, par_props, par_pos, len);
+ text_props, par_props, par_pos, len, mode);
}
static int
}
static void
-eng_font_draw(void *data __UNUSED__, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *text_props)
+eng_font_draw(void *data __UNUSED__, void *context, void *surface, Evas_Font_Set *font __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *text_props)
{
#ifdef BUILD_PIPE_RENDER
- if ((cpunum > 1)
-#ifdef EVAS_FRAME_QUEUING
- && evas_common_frameq_enabled()
-#endif
- )
- evas_common_pipe_text_draw(surface, context, (RGBA_Font *) font, x, y,
- text_props);
+ if ((cpunum > 1))
+ evas_common_pipe_text_draw(surface, context, x, y, text_props);
else
#endif
{
- evas_common_font_draw(surface, context, (RGBA_Font *) font, x, y,
- text_props);
+ evas_common_font_draw_prepare(text_props);
+ evas_common_font_draw(surface, context, x, y, text_props);
evas_common_cpu_end_opt();
}
}
-I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
-I$(top_srcdir)/src/modules/engines \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_software_xlib_cflags@
SOFTWARE_X11_SOURCES += \
int dpi;
} xr;
*/
-#ifdef EVAS_FRAME_QUEUING
- Evas_Engine_Render_Mode render_mode;
-#endif
-
void (*outbuf_free)(Outbuf *ob);
void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
int (*outbuf_get_rot)(Outbuf *ob);
void (*outbuf_flush)(Outbuf *ob);
void (*outbuf_idle_flush)(Outbuf *ob);
Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
-#ifdef EVAS_FRAME_QUEUING
- void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev);
-#endif
};
/* prototypes we will use here */
re->outbuf_flush = evas_software_xlib_outbuf_flush;
re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
-# ifdef EVAS_FRAME_QUEUING
- re->outbuf_set_priv = evas_software_xlib_outbuf_set_priv;
- re->render_mode = info->render_mode;
-# endif
}
#endif
re->outbuf_flush = evas_software_xcb_outbuf_flush;
re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
-# ifdef EVAS_FRAME_QUEUING
- re->outbuf_set_priv = evas_software_xcb_outbuf_priv_set;
- re->render_mode = info->render_mode;
-# endif
}
#endif
{
int ponebuf = 0;
-#ifdef EVAS_FRAME_QUEUING
- evas_common_frameq_flush();
-#endif
re = e->engine.data.output;
ponebuf = re->ob->onebuf;
info->info.destination_alpha);
evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
-# ifdef EVAS_FRAME_QUEUING
- re->render_mode = info->render_mode;
-# endif
}
#endif
info->info.destination_alpha);
evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
-#ifdef EVAS_FRAME_QUEUING
- re->render_mode = info->render_mode;
-#endif
}
#endif
re->ob->onebuf = ponebuf;
eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
{
Render_Engine *re;
-#ifdef EVAS_FRAME_QUEUING
- Evas_Surface *e_surface;
-#endif
re = (Render_Engine *)data;
-#if defined(BUILD_PIPE_RENDER) && !defined(EVAS_FRAME_QUEUING)
+#if defined(BUILD_PIPE_RENDER)
evas_common_pipe_map_begin(surface);
-#endif /* BUILD_PIPE_RENDER && !EVAS_FRAME_QUEUING*/
-
-#ifdef EVAS_FRAME_QUEUING
- if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
- {
- /* create a new frame if this is the first surface of this frame */
- evas_common_frameq_prepare_frame();
- /* add surface into the frame */
- e_surface = evas_common_frameq_new_surface(surface, x, y, w, h);
- evas_common_frameq_add_surface(e_surface);
- return;
- }
-#endif
-
- re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
- re->outbuf_free_region_for_update(re->ob, surface);
- evas_common_cpu_end_opt();
-}
-
-#ifdef EVAS_FRAME_QUEUING
-static void *
-eng_image_map_surface_new(void *data , int w, int h, int alpha)
-{
- void *surface;
- DATA32 *pixels;
- Render_Engine *re;
- Evas_Surface *e_surface;
-
- re = (Render_Engine *)data;
-
- surface =
- evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, NULL,
- alpha, EVAS_COLORSPACE_ARGB8888);
- pixels = evas_cache_image_pixels(surface);
-
- if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
- {
- /* create a new frame if this is the first surface of this frame */
- evas_common_frameq_prepare_frame();
-
- /* add surface into the frame */
- e_surface = evas_common_frameq_new_surface(surface, 0, 0, w, h);
-
- /* this surface is not going to be pushed to screen */
- e_surface->dontpush = 1;
- evas_common_frameq_add_surface(e_surface);
- }
- return surface;
-}
+#endif /* BUILD_PIPE_RENDER */
-static void
-eng_output_frameq_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
-{
- Render_Engine *re;
-
- re = (Render_Engine *)data;
re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
re->outbuf_free_region_for_update(re->ob, surface);
evas_common_cpu_end_opt();
}
static void
-eng_output_frameq_flush(void *data)
-{
- Render_Engine *re;
-
- re = (Render_Engine *)data;
- re->outbuf_flush(re->ob);
-}
-
-static void
-eng_output_frameq_set_priv(void *data, void *cur, void *prev)
-{
- Render_Engine *re;
-
- re = (Render_Engine *)data;
- re->outbuf_set_priv(re->ob, cur, prev);
-}
-#endif
-
-static void
eng_output_flush(void *data)
{
Render_Engine *re;
re = (Render_Engine *)data;
-#ifdef EVAS_FRAME_QUEUING
- if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
- {
- evas_common_frameq_set_frame_data(data,
- eng_output_frameq_redraws_next_update_push,
- eng_output_frameq_flush,
- eng_output_frameq_set_priv);
- evas_common_frameq_ready_frame();
- evas_common_frameq_begin();
- }
- else
-#endif
- re->outbuf_flush(re->ob);
+ re->outbuf_flush(re->ob);
}
static void
ORD(output_redraws_next_update_push);
ORD(output_flush);
ORD(output_idle_flush);
-#ifdef EVAS_FRAME_QUEUING
- ORD(image_map_surface_new);
-#endif
/* now advertise out own api */
em->functions = (void *)(&func);
/* a list of previous frame pending regions to write to the target */
Eina_List *prev_pending_writes;
-# ifdef EVAS_FRAME_QUEUING
- /* protecting prev_pending_writes */
- LK(lock);
-# endif
-
unsigned char mask_dither : 1;
unsigned char destination_alpha : 1;
unsigned char debug : 1;
/* Sync only needed for testing */
if (try_shm == 2) _xcbob_sync(conn);
-#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
+#if defined(LIBXEXT_VERSION_LOW)
if (evas_common_frameq_enabled())
xcb_grab_server(conn);
#endif
xcb_shm_attach(conn, xcbob->shm_info->shmseg,
xcbob->shm_info->shmid, 0);
-#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
+#if defined(LIBXEXT_VERSION_LOW)
if (evas_common_frameq_enabled())
xcb_ungrab_server(conn);
#endif
static int _shmlimit = (10 * 1024 * 1024);
static const unsigned int _shmcountlimit = 32;
-#ifdef EVAS_FRAME_QUEUING
-static LK(lock_shmpool);
-# define SHMPOOL_LOCK() LKL(lock_shmpool);
-# define SHMPOOL_UNLOCK() LKU(lock_shmpool);
-#else
-# define SHMPOOL_LOCK()
-# define SHMPOOL_UNLOCK()
-#endif
+#define SHMPOOL_LOCK()
+#define SHMPOOL_UNLOCK()
void
evas_software_xcb_outbuf_init(void)
{
-#ifdef EVAS_FRAME_QUEUING
- LKI(lock_shmpool);
-#endif
}
void
evas_software_xcb_outbuf_free(Outbuf *buf)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-#endif
while (buf->priv.pending_writes)
{
RGBA_Image *im = NULL;
if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
free(obr);
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-#endif
evas_software_xcb_outbuf_idle_flush(buf);
evas_software_xcb_outbuf_flush(buf);
if (buf->priv.x11.xcb.gc)
buf->priv.x11.xcb.cmap,
buf->priv.x11.xcb.visual,
buf->priv.pal);
-#ifdef EVAS_FRAME_QUEUING
- LKD(buf->priv.lock);
-#endif
free(buf);
_clear_xcbob(EINA_FALSE);
}
evas_software_xcb_outbuf_drawable_set(buf, draw);
evas_software_xcb_outbuf_mask_set(buf, mask);
-#ifdef EVAS_FRAME_QUEUING
- LKI(buf->priv.lock);
-#endif
-
return buf;
}
// memset(im->image.data, 0, (w * h * sizeof(DATA32)));
}
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
-#endif
- buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
+ buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
return im;
}
buf->priv.x11.xcb.gcm,
obr->x, obr->y, 0);
}
-# ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-# endif
while (buf->priv.prev_pending_writes)
{
im = buf->priv.prev_pending_writes->data;
free(obr);
}
buf->priv.prev_pending_writes = buf->priv.pending_writes;
-# ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-# endif
buf->priv.pending_writes = NULL;
xcb_flush(buf->priv.x11.xcb.conn);
#else
}
else
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-#endif
if (buf->priv.prev_pending_writes)
_xcbob_sync(buf->priv.x11.xcb.conn);
while (buf->priv.prev_pending_writes)
if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
free(obr);
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-#endif
_clear_xcbob(EINA_FALSE);
}
}
}
}
-#ifdef EVAS_FRAME_QUEUING
-void
-evas_software_xcb_outbuf_priv_set(Outbuf *buf, void *cur, void *prev __UNUSED__)
-{
- buf->priv.pending_writes = (Eina_List *)cur;
-}
-#endif
/* local functions */
static Xcb_Output_Buffer *
void evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug);
void evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h);
-# ifdef EVAS_FRAME_QUEUING
-void evas_software_xcb_outbuf_priv_set(Outbuf *buf, void *cur, void *prev);
-# endif
-
#endif
ph = XSetErrorHandler((XErrorHandler)
x_output_tmp_x_err);
}
-#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
+#if defined(LIBXEXT_VERSION_LOW)
/* workaround for libXext of lower then 1.1.1 */
if (evas_common_frameq_enabled())
XLockDisplay(d);
#endif
XShmAttach(d, xob->shm_info);
-#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
+#if defined(LIBXEXT_VERSION_LOW)
/* workaround for libXext of lower then 1.1.1 */
if (evas_common_frameq_enabled())
XUnlockDisplay(d);
#include <sys/time.h>
#include <sys/utsname.h>
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
#include "evas_common.h"
#include "evas_macros.h"
#include "evas_xlib_outbuf.h"
static int shmmemlimit = 10 * 1024 * 1024;
static const unsigned int shmcountlimit = 32;
-#ifdef EVAS_FRAME_QUEUING
-static LK(lock_shmpool);
-#define SHMPOOL_LOCK() LKL(lock_shmpool)
-#define SHMPOOL_UNLOCK() LKU(lock_shmpool)
-#else
#define SHMPOOL_LOCK()
#define SHMPOOL_UNLOCK()
-#endif
static X_Output_Buffer *
_find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
void
evas_software_xlib_outbuf_init(void)
{
-#ifdef EVAS_FRAME_QUEUING
- LKI(lock_shmpool);
-#endif
}
void
evas_software_xlib_outbuf_free(Outbuf *buf)
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-#endif
while (buf->priv.pending_writes)
{
RGBA_Image *im;
im = buf->priv.pending_writes->data;
buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
obr = im->extended_info;
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
if (obr->xob) _unfind_xob(obr->xob, 0);
if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr);
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-#endif
evas_software_xlib_outbuf_idle_flush(buf);
evas_software_xlib_outbuf_flush(buf);
if (buf->priv.x11.xlib.gc)
if (buf->priv.pal)
evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
buf->priv.x11.xlib.vis, buf->priv.pal);
-#ifdef EVAS_FRAME_QUEUING
- LKD(buf->priv.lock);
-#endif
free(buf);
_clear_xob(0);
}
evas_software_xlib_outbuf_drawable_set(buf, draw);
evas_software_xlib_outbuf_mask_set(buf, mask);
}
-#ifdef EVAS_FRAME_QUEUING
- LKI(buf->priv.lock);
-#endif
return buf;
}
free(obr);
return NULL;
}
- im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
- buf->w, buf->h,
- (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
- alpha, EVAS_COLORSPACE_ARGB8888);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ im = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
+ buf->w, buf->h,
+ (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
+ alpha, EVAS_COLORSPACE_ARGB8888);
+ }
+ else
+#endif
+ im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
+ buf->w, buf->h,
+ (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
+ alpha, EVAS_COLORSPACE_ARGB8888);
if (!im)
{
evas_software_xlib_x_output_buffer_free(obr->xob, 0);
}
else
{
- im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
+ else
+#endif
+ im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
if (!im)
{
free(obr);
return NULL;
}
im->cache_entry.flags.alpha |= alpha ? 1 : 0;
- evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
+ else
+#endif
+ evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
im->extended_info = obr;
if ((buf->rot == 0) || (buf->rot == 180))
{
NULL);
if (!obr->xob)
{
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
free(obr);
return NULL;
}
NULL);
if (!obr->xob)
{
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
free(obr);
return NULL;
}
free(obr);
return NULL;
}
- im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
- w, h,
- (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
- alpha, EVAS_COLORSPACE_ARGB8888);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ im = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
+ w, h,
+ (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
+ alpha, EVAS_COLORSPACE_ARGB8888);
+ else
+#endif
+ im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
+ w, h,
+ (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
+ alpha, EVAS_COLORSPACE_ARGB8888);
if (!im)
{
_unfind_xob(obr->xob, 0);
}
else
{
- im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
+ else
+#endif
+ im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
if (!im)
{
free(obr);
im->cache_entry.w = w;
im->cache_entry.h = h;
im->cache_entry.flags.alpha |= alpha ? 1 : 0;
- evas_cache_image_surface_alloc(&im->cache_entry, w, h);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
+ else
+#endif
+ evas_cache_image_surface_alloc(&im->cache_entry, w, h);
im->extended_info = obr;
if ((buf->rot == 0) || (buf->rot == 180))
{
NULL);
if (!obr->xob)
{
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
free(obr);
return NULL;
}
NULL);
if (!obr->xob)
{
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
free(obr);
return NULL;
}
// memset(im->image.data, 0, w * h * sizeof(DATA32));
}
-#ifdef EVAS_FRAME_QUEUING
- if (!evas_common_frameq_enabled())
-#endif
- buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
+ buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
return im;
}
buf->priv.x11.xlib.gcm,
obr->x, obr->y, 0);
}
-#ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-#endif
while (buf->priv.prev_pending_writes)
{
im = buf->priv.prev_pending_writes->data;
eina_list_remove_list(buf->priv.prev_pending_writes,
buf->priv.prev_pending_writes);
obr = im->extended_info;
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
if (obr->xob) _unfind_xob(obr->xob, 0);
if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr);
}
buf->priv.prev_pending_writes = buf->priv.pending_writes;
-#ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-#endif
buf->priv.pending_writes = NULL;
XFlush(buf->priv.x11.xlib.disp);
#else
im = eina_list_data_get(buf->priv.pending_writes);
buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
obr = im->extended_info;
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
if (obr->xob) _unfind_xob(obr->xob, 0);
if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr);
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
}
#endif
}
if (obr->xob) evas_software_xlib_x_output_buffer_free(obr->xob, 0);
if (obr->mxob) evas_software_xlib_x_output_buffer_free(obr->mxob, 0);
free(obr);
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
}
else
{
-#ifdef EVAS_FRAME_QUEUING
- LKL(buf->priv.lock);
-#endif
if (buf->priv.prev_pending_writes) XSync(buf->priv.x11.xlib.disp, False);
while (buf->priv.prev_pending_writes)
{
eina_list_remove_list(buf->priv.prev_pending_writes,
buf->priv.prev_pending_writes);
obr = im->extended_info;
- evas_cache_image_drop(&im->cache_entry);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ evas_cache2_image_close(&im->cache_entry);
+ }
+ else
+#endif
+ evas_cache_image_drop(&im->cache_entry);
if (obr->xob) _unfind_xob(obr->xob, 0);
if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr);
}
-#ifdef EVAS_FRAME_QUEUING
- LKU(buf->priv.lock);
-#endif
_clear_xob(0);
}
}
return buf->priv.x11.xlib.mask;
}
-#ifdef EVAS_FRAME_QUEUING
-void
-evas_software_xlib_outbuf_set_priv(Outbuf *buf, void *cur, void *prev __UNUSED__)
-{
- buf->priv.pending_writes = (Eina_List *)cur;
-}
-#endif
int h);
Eina_Bool evas_software_xlib_outbuf_alpha_get (Outbuf *buf);
-#ifdef EVAS_FRAME_QUEUING
-void evas_software_xlib_outbuf_set_priv (Outbuf *buf,
- void *cur,
- void *prev);
-#endif
#endif
#ifndef _EVAS_ENGINE_WAYLAND_EGL_H
#define _EVAS_ENGINE_WAYLAND_EGL_H
+/*
+ * Wayland supoprt is considered experimental as wayland itself is still
+ * unstable and liable to change core protocol. If you use this api, it is
+ * possible it will break in future, until this notice is removed.
+ */
+
#include <wayland-client.h>
typedef struct _Evas_Engine_Info_Wayland_Egl Evas_Engine_Info_Wayland_Egl;
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
@GL_EET_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_wayland_egl_cflags@
if BUILD_ENGINE_WAYLAND_EGL
}
static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
{
Render_Engine *re;
evas_gl_font_texture_new,
evas_gl_font_texture_free,
evas_gl_font_texture_draw);
- evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
- intl_props);
+ evas_common_font_draw_prepare(intl_props);
+ evas_common_font_draw(im, context, x, y, intl_props);
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
}
}
if (_evas_engine_wl_egl_log_dom < 0)
{
_evas_engine_wl_egl_log_dom =
- eina_log_domain_register("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
+ eina_log_domain_register("evas-wayland_egl", EVAS_DEFAULT_LOG_COLOR);
}
if (_evas_engine_wl_egl_log_dom < 0)
EVAS_MODULE_API_VERSION, "wayland_egl", "none", {module_open, module_close}
};
-EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, wayland_egl);
-#ifndef EVAS_STATIC_BUILD_GL_XLIB
-EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
+#ifndef EVAS_STATIC_BUILD_WAYLAND_EGL
+EVAS_EINA_MODULE_DEFINE(engine, wayland_egl);
#endif
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
NULL);
if (gw->egl_surface[0] == EGL_NO_SURFACE)
{
- ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
- (unsigned int)gw->win, eglGetError());
+ ERR("eglCreateWindowSurface() fail for %p. code=%#x",
+ gw->win, eglGetError());
eng_window_free(gw);
return NULL;
}
if (gw->egl_surface[0] == EGL_NO_SURFACE)
{
- ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
- (unsigned int)gw->win, eglGetError());
+ ERR("eglCreateWindowSurface() fail for %p. code=%#x",
+ gw->win, eglGetError());
return;
}
if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
#ifndef _EVAS_ENGINE_WAYLAND_SHM_H
# define _EVAS_ENGINE_WAYLAND_SHM_H
+/*
+ * Wayland supoprt is considered experimental as wayland itself is still
+ * unstable and liable to change core protocol. If you use this api, it is
+ * possible it will break in future, until this notice is removed.
+ */
+
typedef struct _Evas_Engine_Info_Wayland_Shm Evas_Engine_Info_Wayland_Shm;
struct _Evas_Engine_Info_Wayland_Shm
{
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_engine_wayland_shm_cflags@
if BUILD_ENGINE_WAYLAND_SHM
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_edb_cflags@ \
@EINA_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_eet_cflags@ \
@EINA_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_generic_cflags@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_gif_cflags@ \
@EINA_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_jpeg_cflags@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_pmaps_cflags@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_png_cflags@ \
@EVIL_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_svg_cflags@
if BUILD_LOADER_SVG
pkgdir = $(libdir)/evas/modules/loaders/svg/$(MODULE_ARCH)
pkg_LTLIBRARIES = module.la
-module_la_SOURCES = evas_image_load_svg.c
+module_la_SOURCES = evas_image_load_esvg.c
module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_svg_libs@ $(top_builddir)/src/lib/libevas.la
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
else
noinst_LTLIBRARIES = libevas_loader_svg.la
-libevas_loader_svg_la_SOURCES = evas_image_load_svg.c
+libevas_loader_svg_la_SOURCES = evas_image_load_esvg.c
libevas_loader_svg_la_LIBADD = @evas_image_loader_svg_libs@
endif
--- /dev/null
+#include <math.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+#include <Esvg.h>
+
+static inline Eina_Bool evas_image_load_file_is_svg(const char *file) EINA_ARG_NONNULL(1) EINA_PURE;
+static Eina_Bool evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+Evas_Image_Load_Func evas_image_load_svg_func =
+{
+ EINA_FALSE,
+ evas_image_load_file_head_svg,
+ evas_image_load_file_data_svg,
+ NULL,
+ EINA_FALSE
+};
+
+static Eina_Bool esvg_initialized = EINA_FALSE;
+
+
+static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
+{
+ int i, len = strlen(file);
+ Eina_Bool is_gz = EINA_FALSE;
+
+ for (i = len - 1; i > 0; i--)
+ {
+ if (file[i] == '.')
+ {
+ if (is_gz)
+ break;
+ else if (strcasecmp(file + i + 1, "gz") == 0)
+ is_gz = EINA_TRUE;
+ else
+ break;
+ }
+ }
+
+ if (i < 1) return EINA_FALSE;
+ i++;
+ if (i >= len) return EINA_FALSE;
+ if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
+ i += 3;
+ if (is_gz)
+ {
+ if (file[i] == '.') return EINA_TRUE;
+ else return EINA_FALSE;
+ }
+ else
+ {
+ if (file[i] == '\0') return EINA_TRUE;
+ else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
+ else return EINA_FALSE;
+ }
+}
+
+static Eina_Bool
+evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+ Ender_Element *e;
+ int w, h;
+ double sw, sh;
+
+ /* ignore all files not called .svg or .svg.gz - because rsvg has a leak
+ * where closing the handle doesn't free mem */
+ if (!evas_image_load_file_is_svg(file))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ e = esvg_parser_load(file, NULL, NULL);
+ if (!e)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ esvg_renderable_x_dpi_set(e, 75.0);
+ esvg_renderable_y_dpi_set(e, 75.0);
+ esvg_svg_actual_width_get(e, &sw);
+ esvg_svg_actual_height_get(e, &sh);
+ esvg_element_setup(e, NULL);
+ w = (int)ceil(sw);
+ h = (int)ceil(sh);
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ ender_element_delete(e);
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
+ }
+ if (ie->load_opts.scale_down_by > 1)
+ {
+ w /= ie->load_opts.scale_down_by;
+ h /= ie->load_opts.scale_down_by;
+ }
+ else if (ie->load_opts.dpi > 0.0)
+ {
+ w = (w * ie->load_opts.dpi) / 75.0;
+ h = (h * ie->load_opts.dpi) / 75.0;
+ }
+ else if ((ie->load_opts.w > 0) &&
+ (ie->load_opts.h > 0))
+ {
+ unsigned int w2, h2;
+
+ w2 = ie->load_opts.w;
+ h2 = (ie->load_opts.w * h) / w;
+ if (h2 > ie->load_opts.h)
+ {
+ h2 = ie->load_opts.h;
+ w2 = (ie->load_opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ie->w = w;
+ ie->h = h;
+ ie->flags.alpha = 1;
+
+ ender_element_delete(e);
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+/** FIXME: All evas loaders need to be tightened up **/
+static Eina_Bool
+evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+ DATA32 *pixels;
+ Ender_Element *e;
+ Enesim_Error *err = NULL;
+ Enesim_Surface *s;
+ void *data;
+ size_t stride;
+ int w, h;
+ double sw, sh;
+
+ if (!evas_image_load_file_is_svg(file))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ e = esvg_parser_load(file, NULL, NULL);
+ if (!e)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ esvg_renderable_x_dpi_set(e, 75.0);
+ esvg_renderable_y_dpi_set(e, 75.0);
+ esvg_svg_actual_width_get(e, &sw);
+ esvg_svg_actual_height_get(e, &sh);
+ w = (int)ceil(sw);
+ h = (int)ceil(sh);
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
+ {
+ ender_element_delete(e);
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_renderer;
+ }
+ if (ie->load_opts.scale_down_by > 1)
+ {
+ w /= ie->load_opts.scale_down_by;
+ h /= ie->load_opts.scale_down_by;
+ }
+ else if (ie->load_opts.dpi > 0.0)
+ {
+ w = (w * ie->load_opts.dpi) / 75.0;
+ h = (h * ie->load_opts.dpi) / 75.0;
+ }
+ else if ((ie->load_opts.w > 0) &&
+ (ie->load_opts.h > 0))
+ {
+ unsigned int w2, h2;
+
+ w2 = ie->load_opts.w;
+ h2 = (ie->load_opts.w * h) / w;
+ if (h2 > ie->load_opts.h)
+ {
+ h2 = ie->load_opts.h;
+ w2 = (ie->load_opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((w != (int)ie->w) || (h != (int)ie->h))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_renderer;
+ }
+ ie->flags.alpha = 1;
+ evas_cache_image_surface_alloc(ie, w, h);
+ pixels = evas_cache_image_pixels(ie);
+ if (!pixels)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto unref_renderer;
+ }
+
+ memset(pixels, 0, w * h * sizeof(DATA32));
+
+ s = enesim_surface_new(ENESIM_FORMAT_ARGB8888, w, h);
+ if (!s)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto unref_renderer;
+ }
+
+ esvg_element_setup(e, NULL);
+
+ if (!esvg_renderable_draw(e, s, NULL, 0, 0, &err))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ enesim_error_dump(err);
+ goto unref_surface;
+ }
+
+ if (!enesim_surface_data_get(s, &data, &stride))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_surface;
+ }
+
+/* printf("test : %d %d\n", w * h * sizeof(int), h * stride); */
+/* if ((w * h * sizeof(int)) != (h * stride)) */
+/* { */
+/* *error = EVAS_LOAD_ERROR_GENERIC; */
+/* goto unref_surface; */
+/* } */
+
+ /* FIXME: scale to (double)ie->w / dim.em, (double)ie->h / dim.ex */
+
+ memcpy (pixels, data, h * stride);
+
+ enesim_surface_unref(s);
+ ender_element_delete(e);
+
+ evas_common_image_set_alpha_sparse(ie);
+
+ return EINA_TRUE;
+
+ unref_surface:
+ enesim_surface_unref(s);
+ unref_renderer:
+ ender_element_delete(e);
+
+ return EINA_FALSE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+ if (!em) return 0;
+ em->functions = (void *)(&evas_image_load_svg_func);
+ if (!esvg_initialized) esvg_init();
+ esvg_initialized = EINA_TRUE;
+ return 1;
+}
+
+static void
+module_close(Evas_Module *em __UNUSED__)
+{
+ if (!esvg_initialized) return;
+ esvg_shutdown();
+ esvg_initialized = EINA_FALSE;
+}
+
+static Evas_Module_Api evas_modapi =
+{
+ EVAS_MODULE_API_VERSION,
+ "svg",
+ "none",
+ {
+ module_open,
+ module_close
+ }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, svg);
+
+#ifndef EVAS_STATIC_BUILD_SVG
+EVAS_EINA_MODULE_DEFINE(image_loader, svg);
+#endif
+++ /dev/null
-#include "evas_common.h"
-#include "evas_private.h"
-
-#include <librsvg/rsvg.h>
-#include <librsvg/rsvg-cairo.h>
-
-static inline Eina_Bool evas_image_load_file_is_svg(const char *file) EINA_ARG_NONNULL(1) EINA_PURE;
-static Eina_Bool evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
-static Eina_Bool evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
-
-Evas_Image_Load_Func evas_image_load_svg_func =
-{
- EINA_FALSE,
- evas_image_load_file_head_svg,
- evas_image_load_file_data_svg,
- NULL,
- EINA_FALSE
-};
-
-static int rsvg_initialized = 0;
-
-
-static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
-{
- int i, len = strlen(file);
- Eina_Bool is_gz = EINA_FALSE;
-
- for (i = len - 1; i > 0; i--)
- {
- if (file[i] == '.')
- {
- if (is_gz)
- break;
- else if (strcasecmp(file + i + 1, "gz") == 0)
- is_gz = EINA_TRUE;
- else
- break;
- }
- }
-
- if (i < 1) return EINA_FALSE;
- i++;
- if (i >= len) return EINA_FALSE;
- if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
- i += 3;
- if (is_gz)
- {
- if (file[i] == '.') return EINA_TRUE;
- else return EINA_FALSE;
- }
- else
- {
- if (file[i] == '\0') return EINA_TRUE;
- else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
- else return EINA_FALSE;
- }
-}
-
-static Eina_Bool
-evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
-{
- RsvgHandle *rsvg;
- RsvgDimensionData dim;
- int w, h;
-
- /* ignore all files not called .svg or .svg.gz - because rsvg has a leak
- * where closing the handle doesn't free mem */
- if (!evas_image_load_file_is_svg(file))
- {
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;
- }
-
- rsvg = rsvg_handle_new_from_file(file, NULL);
- if (!rsvg)
- {
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
- return EINA_FALSE;
- }
-
- rsvg_handle_set_dpi(rsvg, 75.0);
- rsvg_handle_get_dimensions(rsvg, &dim);
- w = dim.width;
- h = dim.height;
- if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
- IMG_TOO_BIG(w, h))
- {
- rsvg_handle_close(rsvg, NULL);
- g_object_unref(rsvg);
- if (IMG_TOO_BIG(w, h))
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- else
- *error = EVAS_LOAD_ERROR_GENERIC;
- return EINA_FALSE;
- }
- if (ie->load_opts.scale_down_by > 1)
- {
- w /= ie->load_opts.scale_down_by;
- h /= ie->load_opts.scale_down_by;
- }
- else if (ie->load_opts.dpi > 0.0)
- {
- w = (w * ie->load_opts.dpi) / 75.0;
- h = (h * ie->load_opts.dpi) / 75.0;
- }
- else if ((ie->load_opts.w > 0) &&
- (ie->load_opts.h > 0))
- {
- unsigned int w2, h2;
-
- w2 = ie->load_opts.w;
- h2 = (ie->load_opts.w * h) / w;
- if (h2 > ie->load_opts.h)
- {
- h2 = ie->load_opts.h;
- w2 = (ie->load_opts.h * w) / h;
- }
- w = w2;
- h = h2;
- }
- if (w < 1) w = 1;
- if (h < 1) h = 1;
- ie->w = w;
- ie->h = h;
- ie->flags.alpha = 1;
- rsvg_handle_close(rsvg, NULL);
- g_object_unref(rsvg);
-
- *error = EVAS_LOAD_ERROR_NONE;
- return EINA_TRUE;
-}
-
-/** FIXME: All evas loaders need to be tightened up **/
-static Eina_Bool
-evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
-{
- DATA32 *pixels;
- RsvgHandle *rsvg;
- RsvgDimensionData dim;
- int w, h;
- cairo_surface_t *surface;
- cairo_t *cr;
-
- /* ignore all files not called .svg or .svg.gz - because rsvg has a leak
- * where closing the handle doesn't free mem */
- if (!evas_image_load_file_is_svg(file))
- {
- *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
- return EINA_FALSE;
- }
-
- rsvg = rsvg_handle_new_from_file(file, NULL);
- if (!rsvg)
- {
- *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
- return EINA_FALSE;
- }
-
- rsvg_handle_set_dpi(rsvg, 75.0);
- rsvg_handle_get_dimensions(rsvg, &dim);
- w = dim.width;
- h = dim.height;
- if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
- {
- rsvg_handle_close(rsvg, NULL);
- g_object_unref(rsvg);
- if (IMG_TOO_BIG(w, h))
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- else
- *error = EVAS_LOAD_ERROR_GENERIC;
- return EINA_FALSE;
- }
- if (ie->load_opts.scale_down_by > 1)
- {
- w /= ie->load_opts.scale_down_by;
- h /= ie->load_opts.scale_down_by;
- }
- else if (ie->load_opts.dpi > 0.0)
- {
- w = (w * ie->load_opts.dpi) / 75.0;
- h = (h * ie->load_opts.dpi) / 75.0;
- }
- else if ((ie->load_opts.w > 0) &&
- (ie->load_opts.h > 0))
- {
- unsigned int w2, h2;
-
- w2 = ie->load_opts.w;
- h2 = (ie->load_opts.w * h) / w;
- if (h2 > ie->load_opts.h)
- {
- h2 = ie->load_opts.h;
- w2 = (ie->load_opts.h * w) / h;
- }
- w = w2;
- h = h2;
- }
- if (w < 1) w = 1;
- if (h < 1) h = 1;
- if ((w != (int)ie->w) || (h != (int)ie->h))
- {
- *error = EVAS_LOAD_ERROR_GENERIC;
- goto error;
- }
- ie->flags.alpha = 1;
- evas_cache_image_surface_alloc(ie, w, h);
- pixels = evas_cache_image_pixels(ie);
- if (!pixels)
- {
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- goto error;
- }
-
- memset(pixels, 0, w * h * sizeof(DATA32));
- surface = cairo_image_surface_create_for_data((unsigned char *)pixels, CAIRO_FORMAT_ARGB32,
- w, h, w * sizeof(DATA32));
- if (!surface)
- {
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- goto error;
- }
- cr = cairo_create(surface);
- if (!cr)
- {
- cairo_surface_destroy(surface);
- *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
- goto error;
- }
-
- cairo_scale(cr,
- (double)ie->w / dim.em,
- (double)ie->h / dim.ex);
- rsvg_handle_render_cairo(rsvg, cr);
- cairo_surface_destroy(surface);
- /* need to check if this is required... */
- cairo_destroy(cr);
- rsvg_handle_close(rsvg, NULL);
- g_object_unref(rsvg);
- evas_common_image_set_alpha_sparse(ie);
- return EINA_TRUE;
-
- error:
- rsvg_handle_close(rsvg, NULL);
- g_object_unref(rsvg);
- return EINA_FALSE;
-}
-
-static int
-module_open(Evas_Module *em)
-{
- if (!em) return 0;
- em->functions = (void *)(&evas_image_load_svg_func);
- if (!rsvg_initialized) rsvg_init();
- rsvg_initialized = 1;
- return 1;
-}
-
-static void
-module_close(Evas_Module *em __UNUSED__)
-{
- if (!rsvg_initialized) return;
- //rsvg_term();
- //rsvg_initialized = 0;
-}
-
-static Evas_Module_Api evas_modapi =
-{
- EVAS_MODULE_API_VERSION,
- "svg",
- "none",
- {
- module_open,
- module_close
- }
-};
-
-EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, svg);
-
-#ifndef EVAS_STATIC_BUILD_SVG
-EVAS_EINA_MODULE_DEFINE(image_loader, svg);
-#endif
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_tiff_cflags@ \
@EVIL_CFLAGS@
-I$(top_srcdir)/src/lib/include \
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@EINA_CFLAGS@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_xpm_cflags@ \
@EVIL_CFLAGS@
f = eina_file_open(file, 0);
if (!f)
{
- ERR("XPM ERROR: file failed to open");
+ if (load_data)
+ ERR("XPM ERROR: file failed to open");
*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
return EINA_FALSE;
}
position = 0;
if (length < 9)
{
- ERR("XPM ERROR: file size, %zd, is to small", length);
+ if (load_data)
+ ERR("XPM ERROR: file size, %zd, is to small", length);
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!map)
{
- ERR("XPM ERROR: file failed to mmap");
+ if (load_data)
+ ERR("XPM ERROR: file failed to mmap");
eina_file_close(f);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
MAINTAINERCLEANFILES = Makefile.in
-AM_CPPFLAGS = -I. \
- -I$(top_srcdir)/src/lib \
- -I$(top_srcdir)/src/lib/include \
- @FREETYPE_CFLAGS@ @PIXMAN_CFLAGS@ @evas_image_loader_edb_cflags@ \
- @EINA_CFLAGS@
+AM_CPPFLAGS = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@evas_image_loader_edb_cflags@ \
+@EINA_CFLAGS@
if BUILD_LOADER_EDB
if !EVAS_STATIC_BUILD_EDB
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_eet_cflags@
if BUILD_LOADER_EET
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_jpeg_cflags@
if BUILD_SAVER_JPEG
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_png_cflags@ \
@EVIL_CFLAGS@
@FREETYPE_CFLAGS@ \
@PIXMAN_CFLAGS@ \
@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
@evas_image_loader_tiff_cflags@
if BUILD_LOADER_TIFF
fnode = evas_textblock_node_format_next_get(fnode);
fail_if (fnode);
+ /* Range deletion across paragraph - a bug found in elm. */
+ evas_object_textblock_text_markup_set(tb,
+ "This is an entry widget in this window that<ps/>"
+ "uses markup <b>like this</> for styling and<ps/>"
+ "formatting <em>like this</>, as well as<ps/>"
+ "<a href=X><link>links in the text</></a>, so enter text<ps/>"
+ "in here to edit it. By the way, links are<ps/>"
+ "called <a href=anc-02>Anchors</a> so you will need<ps/>"
+ "to refer to them this way.<ps/>"
+ "<ps/>"
+
+ "Also you can stick in items with (relsize + ascent): "
+ "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
+ " (full) "
+ "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
+ " (to the left)<ps/>"
+
+ "Also (size + ascent): "
+ "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
+ " (full) "
+ "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
+ " (before this)<ps/>"
+
+ "And as well (absize + ascent): "
+ "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
+ " (full) "
+ "<item absize=64x64 vsize=full href=emoticon/not-impressed></item>"
+ " or even paths to image files on disk too like: "
+ "<item absize=96x128 vsize=full href=file://bla/images/sky_01.jpg></item>"
+ " ... end.");
+ evas_textblock_cursor_paragraph_first(cur);
+ evas_textblock_cursor_paragraph_last(main_cur);
+ evas_textblock_cursor_range_delete(cur, main_cur);
+ fnode = evas_textblock_node_format_first_get(tb);
+ fail_if(fnode);
+
/* Two formats in the same place. */
evas_object_textblock_text_markup_set(tb, "a<b><a>b</a></b>b");
evas_textblock_cursor_pos_set(cur, 1);