diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index 18b469d13a..13a8c198c1 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -511,6 +511,60 @@ else AM_CONDITIONAL(BUILD_ENGINE_CAIRO_COMMON, false) fi +####################################### +## Check if we should build the xrender_x11 engine +have_evas_xrender_x11="no"; +ENGINE_XRENDER_X11_PRG=""; +## Automatic check... +AC_CHECK_HEADER(X11/X.h, + [ have_evas_xrender_x11="yes" ], + [ have_evas_xrender_x11="no" ] +) +## Manual override +AC_MSG_CHECKING(whether xrender x11 backend is to be built) +AC_ARG_ENABLE(xrender-x11, [ --enable-xrender-x11 enable the XRender X11 rendering backend], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_evas_xrender_x11="yes" + else + AC_MSG_RESULT(no) + have_evas_xrender_x11="no" + fi + ], [ + AC_MSG_RESULT($have_evas_xrender_x11) + ] +) +if test "x$have_evas_xrender_x11" = "xyes"; then + AC_PATH_XTRA + AC_CHECK_HEADER(X11/X.h, + [ + AC_CHECK_HEADER(X11/extensions/Xrender.h, + [ + AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, true) + AC_DEFINE(BUILD_ENGINE_XRENDER_X11, 1, [XRender X11 Rendering Backend]) + x_dir=${x_dir:-/usr/X11R6} + x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} + x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext -lXrender" + ENGINE_XRENDER_X11_PRG="evas_xrender_x11_test" + ], + [ + AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false) + AC_MSG_RESULT(disabling xrender X11 engine) + have_evas_xrender_x11="no" + ] + ) + ], + [ + AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false) + AC_MSG_RESULT(disabling xrender X11 engine) + have_evas_xrender_x11="no" + ] + ) +else + AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false) +fi + + ##################################################################### ## Image loaders @@ -1543,6 +1597,7 @@ AC_SUBST(ENGINE_BUFFER_PRG) AC_SUBST(ENGINE_SOFTWARE_QTOPIA_PRG) AC_SUBST(ENGINE_GL_X11_PRG) AC_SUBST(ENGINE_CAIRO_X11_PRG) +AC_SUBST(ENGINE_XRENDER_X11_PRG) AC_SUBST(altivec_cflags) @@ -1574,6 +1629,7 @@ src/lib/engines/gl_common/Makefile src/lib/engines/gl_x11/Makefile src/lib/engines/cairo_common/Makefile src/lib/engines/cairo_x11/Makefile +src/lib/engines/xrender_x11/Makefile src/lib/include/Makefile proj/Makefile proj/win32_gdi/Makefile @@ -1610,7 +1666,8 @@ echo " Software Qtopia.........: $have_evas_qtopia" echo " Software Memory Buffer..: $have_evas_buffer" echo " DirectFB................: $have_evas_directfb" echo " OpenGL X11..............: $have_evas_gl_x11" -echo " Cairo X11..............: $have_evas_cairo_x11" +echo " Cairo X11...............: $have_evas_cairo_x11" +echo " XRender X11.............: $have_evas_xrender_x11" # FIXME: opengl engine needs to be fixed and tested lots for all drivers # FIXME: xrender engine to be written echo diff --git a/legacy/evas/data/test_pattern.png b/legacy/evas/data/test_pattern.png index 6b1f7210bc..f47249d99a 100644 Binary files a/legacy/evas/data/test_pattern.png and b/legacy/evas/data/test_pattern.png differ diff --git a/legacy/evas/src/bin/Makefile.am b/legacy/evas/src/bin/Makefile.am index fb72dafe08..34ebdd31be 100644 --- a/legacy/evas/src/bin/Makefile.am +++ b/legacy/evas/src/bin/Makefile.am @@ -12,7 +12,8 @@ bin_PROGRAMS = \ @ENGINE_BUFFER_PRG@ \ @ENGINE_SOFTWARE_QTOPIA_PRG@ \ @ENGINE_GL_X11_PRG@ \ -@ENGINE_CAIRO_X11_PRG@ +@ENGINE_CAIRO_X11_PRG@ \ +@ENGINE_XRENDER_X11_PRG@ EXTRA_PROGRAMS = \ evas_software_x11_test \ @@ -27,7 +28,8 @@ evas_fb_test \ evas_buffer_test \ evas_software_qtopia_test \ evas_gl_x11_test \ -evas_cairo_x11_test +evas_cairo_x11_test \ +evas_xrender_x11_test SUBDIRS = evas_software_win32 @@ -102,4 +104,9 @@ evas_cairo_x11_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_libs@ @CAI evas_cairo_x11_test_CFLAGS = $(CFLAGS) @x_cflags@ @CAIRO_CFLAGS@ evas_cairo_x11_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la +evas_xrender_x11_test_SOURCES = evas_test_main.h evas_test_main.c evas_xrender_x11_main.c +evas_xrender_x11_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_libs@ +evas_xrender_x11_test_CFLAGS = $(CFLAGS) @x_cflags@ +evas_xrender_x11_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la + EXTRA_DIST = evas_software_qtopia_main.h evas_software_qtopia_main.cpp moc_evas_software_qtopia_main.cpp diff --git a/legacy/evas/src/bin/evas_test_main.c b/legacy/evas/src/bin/evas_test_main.c index 5aea911dc5..38f5514abf 100644 --- a/legacy/evas/src/bin/evas_test_main.c +++ b/legacy/evas/src/bin/evas_test_main.c @@ -342,7 +342,7 @@ loop(void) printf("# EVAS BENCH: %3.3f\n", ((double)frames / (t - time_start)) / 60.0); printf("#\n"); printf("####################################################\n"); - exit(0); +// exit(0); for (i = 0; i < 16; i++) evas_object_del(p_s[i]); for (i = 0; i < 2; i++) evas_object_del(p_i[i]); for (i = 0; i < 16; i++) evas_object_del(p_t[i]); diff --git a/legacy/evas/src/bin/evas_xrender_x11_main.c b/legacy/evas/src/bin/evas_xrender_x11_main.c new file mode 100644 index 0000000000..038a46314f --- /dev/null +++ b/legacy/evas/src/bin/evas_xrender_x11_main.c @@ -0,0 +1,132 @@ +#include "evas_test_main.h" + +#include +#include +#include + +#include "Evas.h" +#include "Evas_Engine_XRender_X11.h" + +int +main(int argc, char **argv) +{ + int pause_me = 0; + Display *disp; + Window win; + XSetWindowAttributes attr; + XClassHint chint; + + disp = XOpenDisplay(NULL); + if (!disp) + { + printf("Error: cannot open display.\n"); + exit(-1); + } + attr.backing_store = NotUseful; + attr.colormap = DefaultColormap(disp, DefaultScreen(disp)); + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.event_mask = + ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + StructureNotifyMask; + attr.bit_gravity = ForgetGravity; + win = XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, win_w, win_h, 0, + DefaultDepth(disp, DefaultScreen(disp)), InputOutput, + DefaultVisual(disp, DefaultScreen(disp)), + CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask, &attr); + XStoreName(disp, win, "Evas XRender X11 Test"); + chint.res_name = "Evas_XRender_X11_Test"; + chint.res_class = "Main"; + XSetClassHint(disp, win, &chint); +#if 0 + szhints.flags = PMinSize | PMaxSize | PSize | USSize; + szhints.min_width = szhints.max_width = win_w; + szhints.min_height = szhints.max_height = win_h; + XSetWMNormalHints(disp, win, &szhints); +#endif + XMapWindow(disp, win); + XSync(disp, False); + + /* test evas_free.... :) */ + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("xrender_x11")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_XRender_X11 *einfo; + + einfo = (Evas_Engine_Info_XRender_X11 *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.display = disp; + einfo->info.visual = DefaultVisual(disp, DefaultScreen(disp)); + einfo->info.drawable = win; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + setup(); + + orig_start_time = start_time = get_time(); + for (;;) + { + XEvent ev; + + while (XCheckMaskEvent(disp, + ExposureMask | + StructureNotifyMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | PointerMotionMask, &ev)) + { + switch (ev.type) + { + case ButtonPress: + if (ev.xbutton.button == 3) + exit(0); +#if 0 + if (!pause_me) + pause_me = 1; + else if (pause_me == 1) + pause_me = 2; + else + pause_me = 1; +#endif + evas_event_feed_mouse_move(evas, ev.xbutton.x, ev.xbutton.y, 0, NULL); + evas_event_feed_mouse_down(evas, ev.xbutton.button, EVAS_BUTTON_NONE, 0, NULL); + break; + case ButtonRelease: + evas_event_feed_mouse_move(evas, ev.xbutton.x, ev.xbutton.y, 0, NULL); + evas_event_feed_mouse_up(evas, ev.xbutton.button, EVAS_BUTTON_NONE, 0, NULL); + break; + case MotionNotify: + evas_event_feed_mouse_move(evas, ev.xmotion.x, ev.xmotion.y, 0, NULL); + break; + case Expose: + evas_damage_rectangle_add(evas, + ev.xexpose.x, + ev.xexpose.y, + ev.xexpose.width, + ev.xexpose.height); + break; + case ConfigureNotify: + evas_output_size_set(evas, + ev.xconfigure.width, + ev.xconfigure.height); + break; + default: + break; + } + } + if (!(pause_me == 1)) + { + loop(); + evas_render(evas); + XFlush(disp); + } + if (pause_me == 2) + usleep(100000); + } + return 0; +} diff --git a/legacy/evas/src/bin/evas_xrender_x11_test b/legacy/evas/src/bin/evas_xrender_x11_test new file mode 100644 index 0000000000..df1f1c38dd --- /dev/null +++ b/legacy/evas/src/bin/evas_xrender_x11_test @@ -0,0 +1,117 @@ +#! /bin/sh + +# evas_xrender_x11_test - temporary wrapper script for .libs/evas_xrender_x11_test +# Generated by ltmain.sh - GNU libtool 1.5.6 (1.1220.2.95 2004/04/11 05:50:42) Debian: 224 $ +# +# The evas_xrender_x11_test program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='/bin/sed -e 1s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=:; export CDPATH; fi + +relink_command="(cd /home/raster/C/evas/src/bin; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; PATH=\"/home/raster/bin:/home/raster/s:/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/games:/sbin:/usr/sbin:/usr/X11R6/lib/xscreensaver:/opt/arm/3.3.2-vfp/bin:/opt/bitkeeper:/opt/java.sun/java.current/bin:.:\"; export PATH; ccache gcc -g3 -O0 -ggdb -o \$progdir/\$file evas_test_main.o evas_xrender_x11_main.o ../../src/lib/.libs/libevas.so -lm -L/usr/X11R6/lib -lX11 -lXext /usr/lib/libXrender.so -Wl,--rpath -Wl,/home/raster/C/evas/src/lib/.libs)" + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variable: + notinst_deplibs=' ../../src/lib/libevas.la' +else + # When we are sourced in execute mode, $file and $echo are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + echo="echo" + file="$0" + # Make sure echo works. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : + else + # Restart under the correct shell, and then maybe $echo will work. + exec /bin/sh "$0" --no-reexec ${1+"$@"} + fi + fi + + # Find the directory that this script lives in. + thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'` + done + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'evas_xrender_x11_test' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || \ + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if relink_command_output=`eval $relink_command 2>&1`; then : + else + echo "$relink_command_output" >&2 + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + + exec $progdir/$program ${1+"$@"} + + $echo "$0: cannot exec $program ${1+"$@"}" + exit 1 + fi + else + # The program doesn't exist. + $echo "$0: error: $progdir/$program does not exist" 1>&2 + $echo "This script is just a wrapper for $program." 1>&2 + echo "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 627f936812..6731942a05 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -309,6 +309,7 @@ extern "C" { EAPI Evas_Hash *evas_hash_add (Evas_Hash *hash, const char *key, const void*data); EAPI Evas_Hash *evas_hash_del (Evas_Hash *hash, const char *key, const void*data); EAPI void *evas_hash_find (Evas_Hash *hash, const char *key); + EAPI void *evas_hash_modify (Evas_Hash *hash, const char *key, const void*data); EAPI int evas_hash_size (Evas_Hash *hash); EAPI void evas_hash_free (Evas_Hash *hash); EAPI void evas_hash_foreach (Evas_Hash *hash, Evas_Bool (*func) (Evas_Hash *hash, const char *key, void *data, void *fdata), const void *fdata); diff --git a/legacy/evas/src/lib/Evas_Engine_XRender_X11.h b/legacy/evas/src/lib/Evas_Engine_XRender_X11.h new file mode 100644 index 0000000000..eaa4844bc9 --- /dev/null +++ b/legacy/evas/src/lib/Evas_Engine_XRender_X11.h @@ -0,0 +1,31 @@ +#ifndef _EVAS_ENGINE_XRENDER_X11_H +#define _EVAS_ENGINE_XRENDER_X11_H + +#include + +typedef struct _Evas_Engine_Info_XRender_X11 Evas_Engine_Info_XRender_X11; + +struct _Evas_Engine_Info_XRender_X11 +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + /* engine specific data & parameters it needs to set up */ + struct { + Display *display; + Drawable drawable; + Pixmap mask; + Visual *visual; + } info; + /* engine specific function calls to query stuff about the destination */ + /* engine (what visual & colormap & depth to use, performance info etc. */ + struct { + Visual * (*best_visual_get) (Display *disp, int screen); + Colormap (*best_colormap_get) (Display *disp, int screen); + int (*best_depth_get) (Display *disp, int screen); + } func; +}; +#endif + + diff --git a/legacy/evas/src/lib/Makefile.am b/legacy/evas/src/lib/Makefile.am index 7159784922..58a4ee1d36 100644 --- a/legacy/evas/src/lib/Makefile.am +++ b/legacy/evas/src/lib/Makefile.am @@ -20,7 +20,8 @@ Evas_Engine_Buffer.h \ Evas_Engine_Software_Win32_GDI.h \ Evas_Engine_Software_Qtopia.h \ Evas_Engine_GL_X11.h \ -Evas_Engine_Cairo_X11.h +Evas_Engine_Cairo_X11.h \ +Evas_Engine_XRender_X11.h if BUILD_ENGINE_SOFTWARE_X11 ENGINE_SOFTWARE_X11 = engines/software_x11/libevas_engine_software_x11.la @@ -102,6 +103,14 @@ ENGINE_CAIRO_X11 = ENGINE_CAIRO_X11_INC = endif +if BUILD_ENGINE_XRENDER_X11 +ENGINE_XRENDER_X11 = engines/xrender_x11/libevas_engine_xrender_x11.la +ENGINE_XRENDER_X11_INC = Evas_Engine_XRender_X11.h +else +ENGINE_XRENDER_X11 = +ENGINE_XRENDER_X11_INC = +endif + include_HEADERS = \ Evas.h \ $(ENGINE_SOFTWARE_X11_INC) \ @@ -113,7 +122,8 @@ $(ENGINE_SOFTWARE_QTOPIA_INC) \ $(ENGINE_GL_COMMON_INC) \ $(ENGINE_GL_X11_INC) \ $(ENGINE_CAIRO_COMMON_INC) \ -$(ENGINE_CAIRO_X11_INC) +$(ENGINE_CAIRO_X11_INC) \ +$(ENGINE_XRENDER_X11_INC) libevas_la_SOURCES = \ main.c @@ -136,7 +146,8 @@ libevas_la_LIBADD = \ $(ENGINE_GL_COMMON) \ $(ENGINE_GL_X11) \ $(ENGINE_CAIRO_COMMON) \ - $(ENGINE_CAIRO_X11) + $(ENGINE_CAIRO_X11) \ + $(ENGINE_XRENDER_X11) libevas_la_DEPENDENCIES = \ @@ -155,6 +166,7 @@ libevas_la_DEPENDENCIES = \ $(ENGINE_GL_COMMON) \ $(ENGINE_GL_X11) \ $(ENGINE_CAIRO_COMMON) \ - $(ENGINE_CAIRO_X11) + $(ENGINE_CAIRO_X11) \ + $(ENGINE_XRENDER_X11) libevas_la_LDFLAGS = -version-info 1:0:0 diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index 0f3b03f5e6..4d162490b5 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -27,6 +27,9 @@ #ifdef BUILD_ENGINE_CAIRO_X11 #include "evas_engine_api_cairo_x11.h" #endif +#ifdef BUILD_ENGINE_XRENDER_X11 +#include "evas_engine_api_xrender_x11.h" +#endif static int initcount = 0; @@ -226,6 +229,11 @@ evas_output_method_set(Evas *e, int render_method) e->engine.func = &evas_engine_software_x11_func; else #endif +#ifdef BUILD_ENGINE_XRENDER_X11 + if (e->output.render_method == RENDER_METHOD_XRENDER_X11) + e->engine.func = &evas_engine_xrender_x11_func; + else +#endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (e->output.render_method == RENDER_METHOD_SOFTWARE_XCB) e->engine.func = &evas_engine_software_xcb_func; @@ -676,6 +684,9 @@ evas_render_method_lookup(const char *name) #ifdef BUILD_ENGINE_SOFTWARE_X11 if (!strcmp(name, "software_x11")) return RENDER_METHOD_SOFTWARE_X11; #endif +#ifdef BUILD_ENGINE_XRENDER_X11 + if (!strcmp(name, "xrender_x11")) return RENDER_METHOD_XRENDER_X11; +#endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (!strcmp(name, "software_xcb")) return RENDER_METHOD_SOFTWARE_XCB; #endif @@ -746,6 +757,9 @@ evas_render_method_list(void) #ifdef BUILD_ENGINE_SOFTWARE_X11 methods = evas_list_append(methods, strdup("software_x11")); #endif +#ifdef BUILD_ENGINE_XRENDER_X11 + methods = evas_list_append(methods, strdup("xrender_x11")); +#endif #ifdef BUILD_ENGINE_SOFTWARE_XCB methods = evas_list_append(methods, strdup("software_xcb")); #endif diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index 49d0320482..5fdef93325 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -831,7 +831,7 @@ evas_object_image_reload(Evas_Object *obj) if ((!o->cur.file) || (o->pixels_checked_out > 0)) return; if (o->engine_data) - o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, 1, 1); + o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h); evas_object_image_unload(obj); /* evas_image_cache_flush(obj->layer->evas);*/ evas_object_image_load(obj); @@ -1615,6 +1615,8 @@ evas_object_image_render_pre(Evas_Object *obj) rr = o->pixel_updates->data; o->pixel_updates = evas_list_remove(o->pixel_updates, rr); + obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h); + idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw); idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh); @@ -1662,6 +1664,7 @@ evas_object_image_render_pre(Evas_Object *obj) o->pixel_updates = evas_list_remove(o->pixel_updates, r); free(r); } + obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h); updates = evas_object_render_pre_prev_cur_add(updates, obj); goto done; } diff --git a/legacy/evas/src/lib/data/evas_hash.c b/legacy/evas/src/lib/data/evas_hash.c index df85d674c3..dd9ab8a9bd 100644 --- a/legacy/evas/src/lib/data/evas_hash.c +++ b/legacy/evas/src/lib/data/evas_hash.c @@ -208,14 +208,8 @@ evas_hash_find(Evas_Hash *hash, const char *key) { if (l != hash->buckets[hash_num]) { - /* FIXME: move to front of list without alloc */ hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el); hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el); - if (evas_list_alloc_error()) - { - _evas_hash_alloc_error = 1; - return el->data; - } } return el->data; } @@ -223,6 +217,47 @@ evas_hash_find(Evas_Hash *hash, const char *key) return NULL; } +/** + * Modifies the entry pointer at the specified key and returns the old entry + * @param hash The given hash table. + * @param key The key string of the entry to modify. + * @param data The data to replace the old entry, if it exists. + * @return The data pointer for the old stored entry, or @c NULL if not + * found. If an existing entry is not found, nothing is added to the + * hash. + * @ingroup Evas_Hash_Data + */ +void * +evas_hash_modify(Evas_Hash *hash, const char *key, const void *data) +{ + int hash_num; + Evas_Hash_El *el; + Evas_Object_List *l; + + _evas_hash_alloc_error = 0; + if (!hash) return NULL; + hash_num = evas_hash_gen(key); + for (l = hash->buckets[hash_num]; l; l = l->next) + { + el = (Evas_Hash_El *)l; + if (((el->key) && (key) && (!strcmp(el->key, key))) || + ((!el->key) && (!key))) + { + void *old_data; + + if (l != hash->buckets[hash_num]) + { + hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el); + hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el); + } + old_data = el->data; + el->data = data; + return old_data; + } + } + return NULL; +} + /** * @defgroup Evas_Hash_General_Group Hash General Functions * diff --git a/legacy/evas/src/lib/engines/Makefile.am b/legacy/evas/src/lib/engines/Makefile.am index 84ba4839de..36ecbbf48c 100644 --- a/legacy/evas/src/lib/engines/Makefile.am +++ b/legacy/evas/src/lib/engines/Makefile.am @@ -12,4 +12,5 @@ directfb \ gl_common \ gl_x11 \ cairo_common \ -cairo_x11 +cairo_x11 \ +xrender_x11 diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index 936de4a6f9..10a7bcfff1 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -147,7 +147,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int fg = evas_common_font_int_cache_glyph_get(fi, index); if (!fg) continue; - if ((dc->font_ext.func.gl_new) && (!fg->ext_dat)) + if (dc->font_ext.func.gl_new) { /* extension calls */ fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg); @@ -179,7 +179,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int { /* ext glyph draw */ dc->font_ext.func.gl_draw(dc->font_ext.data, - (void *)c, + (void *)dst, dc, fg, chr_x, y - (chr_y - y) diff --git a/legacy/evas/src/lib/engines/gl_common/evas_gl_font.c b/legacy/evas/src/lib/engines/gl_common/evas_gl_font.c index 3c23d134a8..ac68514618 100644 --- a/legacy/evas/src/lib/engines/gl_common/evas_gl_font.c +++ b/legacy/evas/src/lib/engines/gl_common/evas_gl_font.c @@ -153,6 +153,7 @@ evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg) void evas_gl_font_texture_free(Evas_GL_Font_Texture *ft) { + if (!ft) return NULL; if (ft->gc->font_texture == ft->texture) { ft->gc->font_texture = 0; @@ -170,7 +171,7 @@ evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface, RGBA_Draw_Context /* 35 */ ft = fg->ext_dat; if (!ft) return; - if (surface == 0) +// if (surface == 0) { int r, g, b, a; diff --git a/legacy/evas/src/lib/engines/xrender_x11/.cvsignore b/legacy/evas/src/lib/engines/xrender_x11/.cvsignore new file mode 100644 index 0000000000..c22f260e44 --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/.cvsignore @@ -0,0 +1,17 @@ +Makefile.in +Makefile +.deps +.libs +libevas_engine_xrender_x11.la +evas_engine_font.lo +evas_engine_font.o +evas_engine_gradient.lo +evas_engine_gradient.o +evas_engine_image.lo +evas_engine_image.o +evas_engine.lo +evas_engine.o +evas_engine_ximage.lo +evas_engine_ximage.o +evas_engine_xrender.lo +evas_engine_xrender.o diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c new file mode 100644 index 0000000000..2a6b2f3f1e --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c @@ -0,0 +1,1041 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" + +static void *evas_engine_xrender_x11_info(Evas *e); +static void evas_engine_xrender_x11_info_free(Evas *e, void *info); +static void evas_engine_xrender_x11_setup(Evas *e, void *info); +static void evas_engine_xrender_x11_output_free(void *data); +static void evas_engine_xrender_x11_output_resize(void *data, int w, int h); +static void evas_engine_xrender_x11_output_tile_size_set(void *data, int w, int h); +static void evas_engine_xrender_x11_output_redraws_rect_add(void *data, int x, int y, int w, int h); +static void evas_engine_xrender_x11_output_redraws_rect_del(void *data, int x, int y, int w, int h); +static void evas_engine_xrender_x11_output_redraws_clear(void *data); +static void *evas_engine_xrender_x11_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch); +static void evas_engine_xrender_x11_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h); +static void evas_engine_xrender_x11_output_flush(void *data); +static void *evas_engine_xrender_x11_context_new(void *data); +static void evas_engine_xrender_x11_context_free(void *data, void *context); +static void evas_engine_xrender_x11_context_clip_set(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_xrender_x11_context_clip_clip(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_xrender_x11_context_clip_unset(void *data, void *context); +static int evas_engine_xrender_x11_context_clip_get(void *data, void *context, int *x, int *y, int *w, int *h); +static void evas_engine_xrender_x11_context_color_set(void *data, void *context, int r, int g, int b, int a); +static int evas_engine_xrender_x11_context_color_get(void *data, void *context, int *r, int *g, int *b, int *a); +static void evas_engine_xrender_x11_context_multiplier_set(void *data, void *context, int r, int g, int b, int a); +static void evas_engine_xrender_x11_context_multiplier_unset(void *data, void *context); +static int evas_engine_xrender_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); +static void evas_engine_xrender_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_xrender_x11_context_cutout_clear(void *data, void *context); +static void evas_engine_xrender_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); +static void evas_engine_xrender_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); +static void *evas_engine_xrender_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y); +static void *evas_engine_xrender_x11_polygon_points_clear(void *data, void *context, void *polygon); +static void evas_engine_xrender_x11_polygon_draw(void *data, void *context, void *surface, void *polygon); +static void *evas_engine_xrender_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); +static void *evas_engine_xrender_x11_gradient_colors_clear(void *data, void *context, void *gradient); +static void evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void *evas_engine_xrender_x11_image_load(void *data, char *file, char *key, int *error); +static void *evas_engine_xrender_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data); +static void *evas_engine_xrender_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); +static void evas_engine_xrender_x11_image_free(void *data, void *image); +static void evas_engine_xrender_x11_image_size_get(void *data, void *image, int *w, int *h); +static void *evas_engine_xrender_x11_image_size_set(void *data, void *image, int w, int h); +static void *evas_engine_xrender_x11_image_dirty_region(void *data, void *image, int x, int y, int w, int h); +static void *evas_engine_xrender_x11_image_data_get(void *data, void *image, int to_write, DATA32 **image_data); +static void *evas_engine_xrender_x11_image_data_put(void *data, void *image, DATA32 *image_data); +static void *evas_engine_xrender_x11_image_alpha_set(void *data, void *image, int has_alpha); +static int evas_engine_xrender_x11_image_alpha_get(void *data, void *image); +static void evas_engine_xrender_x11_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth); +static char *evas_engine_xrender_x11_image_comment_get(void *data, void *image, char *key); +static char *evas_engine_xrender_x11_image_format_get(void *data, void *image); +static void evas_engine_xrender_x11_image_cache_flush(void *data); +static void evas_engine_xrender_x11_image_cache_set(void *data, int bytes); +static int evas_engine_xrender_x11_image_cache_get(void *data); +static void *evas_engine_xrender_x11_font_load(void *data, char *name, int size); +static void *evas_engine_xrender_x11_font_memory_load(void *data, char *name, int size, const void *fdata, int fdata_size); +static void *evas_engine_xrender_x11_font_add(void *data, void *font, char *name, int size); +static void *evas_engine_xrender_x11_font_memory_add(void *data, void *font, char *name, int size, const void *fdata, int fdata_size); +static void evas_engine_xrender_x11_font_free(void *data, void *font); +static int evas_engine_xrender_x11_font_ascent_get(void *data, void *font); +static int evas_engine_xrender_x11_font_descent_get(void *data, void *font); +static int evas_engine_xrender_x11_font_max_ascent_get(void *data, void *font); +static int evas_engine_xrender_x11_font_max_descent_get(void *data, void *font); +static void evas_engine_xrender_x11_font_string_size_get(void *data, void *font, char *text, int *w, int *h); +static int evas_engine_xrender_x11_font_inset_get(void *data, void *font, char *text); +static int evas_engine_xrender_x11_font_h_advance_get(void *data, void *font, char *text); +static int evas_engine_xrender_x11_font_v_advance_get(void *data, void *font, char *text); +static int evas_engine_xrender_x11_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch); +static int evas_engine_xrender_x11_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch); +static void evas_engine_xrender_x11_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text); +static void evas_engine_xrender_x11_font_cache_flush(void *data); +static void evas_engine_xrender_x11_font_cache_set(void *data, int bytes); +static int evas_engine_xrender_x11_font_cache_get(void *data); + +static Visual *evas_engine_xrender_x11_best_visual_get(Display *disp, int screen); +static Colormap evas_engine_xrender_x11_best_colormap_get(Display *disp, int screen); +static int evas_engine_xrender_x11_best_depth_get(Display *disp, int screen); + +typedef struct _Render_Engine Render_Engine; + +struct _Render_Engine +{ + Display *disp; + Visual *vis; + Drawable win; + Pixmap mask; + + Ximage_Info *xinf; + Xrender_Surface *output; + + Tilebuf *tb; + Tilebuf_Rect *rects; + Evas_Object_List *cur_rect; + int end : 1; +}; + +Evas_Func evas_engine_xrender_x11_func = +{ + evas_engine_xrender_x11_info, + evas_engine_xrender_x11_info_free, + evas_engine_xrender_x11_setup, + evas_engine_xrender_x11_output_free, + evas_engine_xrender_x11_output_resize, + evas_engine_xrender_x11_output_tile_size_set, + evas_engine_xrender_x11_output_redraws_rect_add, + evas_engine_xrender_x11_output_redraws_rect_del, + evas_engine_xrender_x11_output_redraws_clear, + evas_engine_xrender_x11_output_redraws_next_update_get, + evas_engine_xrender_x11_output_redraws_next_update_push, + evas_engine_xrender_x11_output_flush, + /* draw context virtual methods */ + evas_engine_xrender_x11_context_new, + evas_engine_xrender_x11_context_free, + evas_engine_xrender_x11_context_clip_set, + evas_engine_xrender_x11_context_clip_clip, + evas_engine_xrender_x11_context_clip_unset, + evas_engine_xrender_x11_context_clip_get, + evas_engine_xrender_x11_context_color_set, + evas_engine_xrender_x11_context_color_get, + evas_engine_xrender_x11_context_multiplier_set, + evas_engine_xrender_x11_context_multiplier_unset, + evas_engine_xrender_x11_context_multiplier_get, + evas_engine_xrender_x11_context_cutout_add, + evas_engine_xrender_x11_context_cutout_clear, + /* rectangle draw funcs */ + evas_engine_xrender_x11_rectangle_draw, + /* line draw funcs */ + evas_engine_xrender_x11_line_draw, + /* polygon draw funcs */ + evas_engine_xrender_x11_polygon_point_add, + evas_engine_xrender_x11_polygon_points_clear, + evas_engine_xrender_x11_polygon_draw, + /* gradient draw funcs */ + evas_engine_xrender_x11_gradient_color_add, + evas_engine_xrender_x11_gradient_colors_clear, + evas_engine_xrender_x11_gradient_draw, + /* image draw funcs */ + evas_engine_xrender_x11_image_load, + evas_engine_xrender_x11_image_new_from_data, + evas_engine_xrender_x11_image_new_from_copied_data, + evas_engine_xrender_x11_image_free, + evas_engine_xrender_x11_image_size_get, + evas_engine_xrender_x11_image_size_set, + evas_engine_xrender_x11_image_dirty_region, + evas_engine_xrender_x11_image_data_get, + evas_engine_xrender_x11_image_data_put, + evas_engine_xrender_x11_image_alpha_set, + evas_engine_xrender_x11_image_alpha_get, + evas_engine_xrender_x11_image_draw, + evas_engine_xrender_x11_image_comment_get, + evas_engine_xrender_x11_image_format_get, + /* image cache funcs */ + evas_engine_xrender_x11_image_cache_flush, + evas_engine_xrender_x11_image_cache_set, + evas_engine_xrender_x11_image_cache_get, + /* font draw functions */ + evas_engine_xrender_x11_font_load, + evas_engine_xrender_x11_font_memory_load, + evas_engine_xrender_x11_font_add, + evas_engine_xrender_x11_font_memory_add, + evas_engine_xrender_x11_font_free, + evas_engine_xrender_x11_font_ascent_get, + evas_engine_xrender_x11_font_descent_get, + evas_engine_xrender_x11_font_max_ascent_get, + evas_engine_xrender_x11_font_max_descent_get, + evas_engine_xrender_x11_font_string_size_get, + evas_engine_xrender_x11_font_inset_get, + evas_engine_xrender_x11_font_h_advance_get, + evas_engine_xrender_x11_font_v_advance_get, + evas_engine_xrender_x11_font_char_coords_get, + evas_engine_xrender_x11_font_char_at_coords_get, + evas_engine_xrender_x11_font_draw, + /* font cache functions */ + evas_engine_xrender_x11_font_cache_flush, + evas_engine_xrender_x11_font_cache_set, + evas_engine_xrender_x11_font_cache_get +}; + +static void * +evas_engine_xrender_x11_info(Evas *e) +{ + Evas_Engine_Info_XRender_X11 *info; + + info = calloc(1, sizeof(Evas_Engine_Info_XRender_X11)); + if (!info) return NULL; + info->magic.magic = rand(); + info->func.best_visual_get = evas_engine_xrender_x11_best_visual_get; + info->func.best_colormap_get = evas_engine_xrender_x11_best_colormap_get; + info->func.best_depth_get = evas_engine_xrender_x11_best_depth_get; + return info; + e = NULL; +} + +static void +evas_engine_xrender_x11_info_free(Evas *e, void *info) +{ + Evas_Engine_Info_XRender_X11 *in; + + in = (Evas_Engine_Info_XRender_X11 *)info; + free(in); +} + +static void +evas_engine_xrender_x11_setup(Evas *e, void *in) +{ + Render_Engine *re; + Evas_Engine_Info_XRender_X11 *info; + + info = (Evas_Engine_Info_XRender_X11 *)in; + if (!e->engine.data.output) + { + re = calloc(1, sizeof(Render_Engine)); + evas_common_cpu_init(); + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_gradient_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + re->tb = evas_common_tilebuf_new(e->output.w, e->output.h); + if (re->tb) + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + e->engine.data.output = re; + } + re = e->engine.data.output; + if (!re) return; + + if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output); + + re->disp = info->info.display; + re->vis = info->info.visual; + re->win = info->info.drawable; + re->mask = info->info.mask; + if (re->xinf) _xr_image_info_free(re->xinf); + re->xinf = _xr_image_info_get(re->disp, re->win, re->vis); + + if (re->output) _xr_render_surface_free(re->output); + re->output = _xr_render_surface_adopt(re->xinf, re->win, e->output.w, e->output.h, 0); +} + +static void +evas_engine_xrender_x11_output_free(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_shutdown(); + evas_common_image_shutdown(); + if (re->xinf) _xr_image_info_free(re->xinf); + if (re->tb) evas_common_tilebuf_free(re->tb); + if (re->output) _xr_render_surface_free(re->output); + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + free(re); +} + +static void +evas_engine_xrender_x11_output_resize(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (re->output) + { + if ((re->output->w == w) && (re->output->h ==h)) return; + if (re->output) _xr_render_surface_free(re->output); + } + re->output = _xr_render_surface_adopt(re->xinf, re->win, w, h, 0); + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(w, h); + if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); +} + +static void +evas_engine_xrender_x11_output_tile_size_set(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_set_tile_size(re->tb, w, h); +} + +static void +evas_engine_xrender_x11_output_redraws_rect_add(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_xrender_x11_output_redraws_rect_del(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_xrender_x11_output_redraws_clear(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +evas_engine_xrender_x11_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + Tilebuf_Rect *rect; + int ux, uy, uw, uh; + + re = (Render_Engine *)data; + if (re->end) + { + re->end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = (Evas_Object_List *)re->rects; + } + if (!re->cur_rect) return NULL; + rect = (Tilebuf_Rect *)re->cur_rect; + ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; + re->cur_rect = re->cur_rect->next; + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->end = 1; + } + + *x = ux; *y = uy; *w = uw; *h = uh; + *cx = 0; *cy = 0; *cw = uw; *ch = uh; + return _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmt24, 0); +} + +static void +evas_engine_xrender_x11_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xr_render_surface_copy((Xrender_Surface *)surface, re->output, 0, 0, + x, y, w, h); + _xr_render_surface_free((Xrender_Surface *)surface); +} + +static void +evas_engine_xrender_x11_output_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + XSync(re->disp, False); + _xr_image_info_pool_flush(re->xinf, 0, 0); +} + +static void * +evas_engine_xrender_x11_context_new(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_draw_context_new(); +} + +static void +evas_engine_xrender_x11_context_free(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_free(context); +} + +static void +evas_engine_xrender_x11_context_clip_set(void *data, void *context, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_clip(context, x, y, w, h); +} + +static void +evas_engine_xrender_x11_context_clip_clip(void *data, void *context, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_clip_clip(context, x, y, w, h); +} + +static void +evas_engine_xrender_x11_context_clip_unset(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_unset_clip(context); +} + +static int +evas_engine_xrender_x11_context_clip_get(void *data, void *context, int *x, int *y, int *w, int *h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *x = ((RGBA_Draw_Context *)context)->clip.x; + *y = ((RGBA_Draw_Context *)context)->clip.y; + *w = ((RGBA_Draw_Context *)context)->clip.w; + *h = ((RGBA_Draw_Context *)context)->clip.h; + return ((RGBA_Draw_Context *)context)->clip.use; +} + +static void +evas_engine_xrender_x11_context_color_set(void *data, void *context, int r, int g, int b, int a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color(context, r, g, b, a); +} + +static int +evas_engine_xrender_x11_context_color_get(void *data, void *context, int *r, int *g, int *b, int *a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *r = (int)(R_VAL(&((RGBA_Draw_Context *)context)->col.col)); + *g = (int)(G_VAL(&((RGBA_Draw_Context *)context)->col.col)); + *b = (int)(B_VAL(&((RGBA_Draw_Context *)context)->col.col)); + *a = (int)(A_VAL(&((RGBA_Draw_Context *)context)->col.col)); + return 1; +} + +static void +evas_engine_xrender_x11_context_multiplier_set(void *data, void *context, int r, int g, int b, int a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_multiplier(context, r, g, b, a); +} + +static void +evas_engine_xrender_x11_context_multiplier_unset(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_unset_multiplier(context); +} + +static int +evas_engine_xrender_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *r = (int)(R_VAL(&((RGBA_Draw_Context *)context)->mul.col)); + *g = (int)(G_VAL(&((RGBA_Draw_Context *)context)->mul.col)); + *b = (int)(B_VAL(&((RGBA_Draw_Context *)context)->mul.col)); + *a = (int)(A_VAL(&((RGBA_Draw_Context *)context)->mul.col)); + return ((RGBA_Draw_Context *)context)->mul.use; +} + +static void +evas_engine_xrender_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h) +{ +/* + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_add_cutout(context, x, y, w, h); + */ +} + +static void +evas_engine_xrender_x11_context_cutout_clear(void *data, void *context) +{ +/* + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_clear_cutouts(context); + */ +} + + + + + + +static void +evas_engine_xrender_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xr_render_surface_rectangle_draw((Xrender_Surface *)surface, + (RGBA_Draw_Context *)context, + x, y, w, h); +} + +static void +evas_engine_xrender_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xr_render_surface_line_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, x1, y1, x2, y2); +} + +static void * +evas_engine_xrender_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_polygon_point_add(polygon, x, y); +} + +static void * +evas_engine_xrender_x11_polygon_points_clear(void *data, void *context, void *polygon) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_polygon_points_clear(polygon); +} + +static void +evas_engine_xrender_x11_polygon_draw(void *data, void *context, void *surface, void *polygon) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_poly_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, (RGBA_Polygon_Point *)polygon); +} + +static void * +evas_engine_xrender_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_gradient_color_add(re->xinf, (XR_Gradient *)gradient, r, g, b, a, distance); +} + +static void * +evas_engine_xrender_x11_gradient_colors_clear(void *data, void *context, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_gradient_colors_clear((XR_Gradient *)gradient); +} + +static void +evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_draw((Xrender_Surface *)surface, + (RGBA_Draw_Context *)context, + (XR_Gradient *)gradient, x, y, w, h, angle); +} + +static void * +evas_engine_xrender_x11_image_load(void *data, char *file, char *key, int *error) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *error = 0; + return _xre_image_load(re->xinf, file, key); +} + +static void * +evas_engine_xrender_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_image_new_from_data(re->xinf, w, h, image_data); +} + +static void * +evas_engine_xrender_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_image_new_from_copied_data(re->xinf, w, h, image_data); +} + +static void +evas_engine_xrender_x11_image_free(void *data, void *image) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (!image) return; + _xre_image_free((XR_Image *)image); +} + +static void +evas_engine_xrender_x11_image_size_get(void *data, void *image, int *w, int *h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (!image) return; + if (w) *w = ((XR_Image *)image)->w; + if (h) *h = ((XR_Image *)image)->h; +} + +static void * +evas_engine_xrender_x11_image_size_set(void *data, void *image, int w, int h) +{ + if (!image) return image; + if (((XR_Image *)image)->references > 1) + { + XR_Image *old_image; + + old_image = (XR_Image *)image; + image = _xre_image_copy((XR_Image *)old_image); + _xre_image_free(old_image); + } + else + _xre_image_dirty((XR_Image *)image); + if ((w <= 0) || (h <= 0)) + { + _xre_image_free((XR_Image *)image); + return NULL; + } + _xre_image_resize((XR_Image *)image, w, h); + return image; +} + +static void * +evas_engine_xrender_x11_image_dirty_region(void *data, void *image, int x, int y, int w, int h) +{ + if (!image) return image; + if (((XR_Image *)image)->references > 1) + { + XR_Image *old_image; + + old_image = (XR_Image *)image; + image = _xre_image_copy((XR_Image *)old_image); + _xre_image_free(old_image); + } + else + _xre_image_dirty((XR_Image *)image); + _xre_image_region_dirty((XR_Image *)image, x, y, w, h); + return image; +} + +static void * +evas_engine_xrender_x11_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) +{ + if (!image) return image; + if (to_write) + { + if (((XR_Image *)image)->references > 1) + { + XR_Image *old_image; + + old_image = (XR_Image *)image; + image = _xre_image_copy((XR_Image *)old_image); + if (image) + _xre_image_free(old_image); + else + image = old_image; + } + else + _xre_image_dirty((XR_Image *)image); + } + if (image_data) *image_data = _xre_image_data_get((XR_Image *)image); + return image; +} + +static void * +evas_engine_xrender_x11_image_data_put(void *data, void *image, DATA32 *image_data) +{ + if (!image) return image; + if (_xre_image_data_get((XR_Image *)image) != image_data) + { + XR_Image *old_image; + + old_image = (XR_Image *)image; + image = _xre_image_new_from_data(old_image->xinf, old_image->w, old_image->h, data); + if (image) + { + ((XR_Image *)image)->alpha = old_image->alpha; + _xre_image_free(old_image); + } + else + image = old_image; + } + return image; +} + +static void * +evas_engine_xrender_x11_image_alpha_set(void *data, void *image, int has_alpha) +{ + if (!image) return image; + if ((int)((XR_Image *)image)->alpha == has_alpha) return image; + if (((XR_Image *)image)->references > 1) + { + XR_Image *old_image; + + old_image = (XR_Image *)image; + image = _xre_image_copy((XR_Image *)old_image); + _xre_image_free(old_image); + } + else + _xre_image_dirty((XR_Image *)image); + _xre_image_alpha_set((XR_Image *)image, has_alpha); + return image; +} + +static int +evas_engine_xrender_x11_image_alpha_get(void *data, void *image) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (!image) return 0; + return _xre_image_alpha_get((XR_Image *)image); +} + +static void +evas_engine_xrender_x11_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if ((!image) || (!surface)) return; + _xre_image_surface_gen((XR_Image *)image); + if (((XR_Image *)image)->surface) + _xr_render_surface_composite(((XR_Image *)image)->surface, + (Xrender_Surface *)surface, + (RGBA_Draw_Context *)context, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + smooth); +} + +static char * +evas_engine_xrender_x11_image_comment_get(void *data, void *image, char *key) +{ + if (!image) return NULL; + return ((XR_Image *)image)->comment; +} + +static char * +evas_engine_xrender_x11_image_format_get(void *data, void *image) +{ + if (!image) return NULL; + return ((XR_Image *)image)->format; +} + +static void +evas_engine_xrender_x11_image_cache_flush(void *data) +{ + Render_Engine *re; + int tmp_size; + + re = (Render_Engine *)data; + tmp_size = evas_common_image_get_cache(); + evas_common_image_set_cache(0); + evas_common_image_set_cache(tmp_size); + _xre_image_cache_set(0); + _xre_image_cache_set(tmp_size); +} + +static void +evas_engine_xrender_x11_image_cache_set(void *data, int bytes) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_image_set_cache(bytes); + _xre_image_cache_set(bytes); +} + +static int +evas_engine_xrender_x11_image_cache_get(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_image_get_cache(); +} + +static void * +evas_engine_xrender_x11_font_load(void *data, char *name, int size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_load(name, size); +} + +static void * +evas_engine_xrender_x11_font_memory_load(void *data, char *name, int size, const void *fdata, int fdata_size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_memory_load(name, size, fdata, fdata_size); +} + +static void * +evas_engine_xrender_x11_font_add(void *data, void *font, char *name, int size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_add(font, name, size); +} + +static void * +evas_engine_xrender_x11_font_memory_add(void *data, void *font, char *name, int size, const void *fdata, int fdata_size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_memory_add(font, name, size, fdata, fdata_size); +} + +static void +evas_engine_xrender_x11_font_free(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_free(font); +} + +static int +evas_engine_xrender_x11_font_ascent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_ascent_get(font); +} + +static int +evas_engine_xrender_x11_font_descent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_descent_get(font); +} + +static int +evas_engine_xrender_x11_font_max_ascent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_max_ascent_get(font); +} + +static int +evas_engine_xrender_x11_font_max_descent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_max_descent_get(font); +} + +static void +evas_engine_xrender_x11_font_string_size_get(void *data, void *font, char *text, int *w, int *h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_query_size(font, text, w, h); +} + +static int +evas_engine_xrender_x11_font_inset_get(void *data, void *font, char *text) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_inset(font, text); +} + +static int +evas_engine_xrender_x11_font_h_advance_get(void *data, void *font, char *text) +{ + Render_Engine *re; + int h, v; + + re = (Render_Engine *)data; + evas_common_font_query_advance(font, text, &h, &v); + return h; +} + +static int +evas_engine_xrender_x11_font_v_advance_get(void *data, void *font, char *text) +{ + Render_Engine *re; + int h, v; + + re = (Render_Engine *)data; + evas_common_font_query_advance(font, text, &h, &v); + return v; +} + +static int +evas_engine_xrender_x11_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_char_coords(font, text, pos, cx, cy, cw, ch); +} + +static int +evas_engine_xrender_x11_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw, ch); +} + +static void +evas_engine_xrender_x11_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + { + static RGBA_Image *im = NULL; + + if (!im) + { + im = evas_common_image_new(); + im->image = evas_common_image_surface_new(im); + im->image->no_free = 1; + } + im->image->w = ((Xrender_Surface *)surface)->w; + im->image->h = ((Xrender_Surface *)surface)->h; + im->image->data = surface; + evas_common_draw_context_font_ext_set(context, + re->xinf, + _xre_font_surface_new, + _xre_font_surface_free, + _xre_font_surface_draw); + evas_common_font_draw(im, context, font, x, y, text); + evas_common_draw_context_font_ext_set(context, + NULL, + NULL, + NULL, + NULL); + evas_common_cpu_end_opt(); + } +} + +static void +evas_engine_xrender_x11_font_cache_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_flush(); +} + +static void +evas_engine_xrender_x11_font_cache_set(void *data, int bytes) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_cache_set(bytes); +} + +static int +evas_engine_xrender_x11_font_cache_get(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_cache_get(); +} + + + + + + + + + +/* private engine functions the calling prog can use */ + +static Visual * +evas_engine_xrender_x11_best_visual_get(Display *disp, int screen) +{ + if (!disp) return NULL; + return DefaultVisual(disp, screen); +} + +static Colormap +evas_engine_xrender_x11_best_colormap_get(Display *disp, int screen) +{ + if (!disp) return 0; + return DefaultColormap(disp, screen); +} + +static int +evas_engine_xrender_x11_best_depth_get(Display *disp, int screen) +{ + if (!disp) return 0; + return DefaultDepth(disp, screen); +} diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h new file mode 100644 index 0000000000..97453d261e --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h @@ -0,0 +1,149 @@ +#ifndef EVAS_ENGINE_H +#define EVAS_ENGINE_H + +#include +#include +#include +#include +#include +#include +#include + +typedef struct _Ximage_Info Ximage_Info; +typedef struct _Ximage_Image Ximage_Image; +typedef struct _Xrender_Surface Xrender_Surface; + +struct _Ximage_Info +{ + Display *disp; + Drawable root; + Drawable draw; + int depth; + Visual *vis; + int pool_mem; + Evas_List *pool; + unsigned char can_do_shm; + XRenderPictFormat *fmt32; + XRenderPictFormat *fmt24; + XRenderPictFormat *fmt8; + XRenderPictFormat *fmt4; + XRenderPictFormat *fmt1; + unsigned char mul_r, mul_g, mul_b, mul_a; + Xrender_Surface *mul; + int references; +}; + +struct _Ximage_Image +{ + Ximage_Info *xinf; + XImage *xim; + XShmSegmentInfo *shm_info; + int w, h; + int depth; + int line_bytes; + unsigned char *data; + unsigned char available : 1; +}; + +struct _Xrender_Surface +{ + Ximage_Info *xinf; + int w, h; + int depth; + XRenderPictFormat *fmt; + Drawable draw; + Picture pic; + unsigned char alpha : 1; + unsigned char allocated : 1; +}; + +/* ximage support calls (ximage vs xshmimage, cache etc.) */ +Ximage_Info *_xr_image_info_get(Display *disp, Drawable draw, Visual *vis); +void _xr_image_info_free(Ximage_Info *xinf); +void _xr_image_info_pool_flush(Ximage_Info *xinf, int max_num, int max_mem); +Ximage_Image *_xr_image_new(Ximage_Info *xinf, int w, int h, int depth); +void _xr_image_free(Ximage_Image *xim); +void _xr_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h); + +/* xrender support calls */ +Xrender_Surface *_xr_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha); +Xrender_Surface *_xr_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha); +void _xr_render_surface_free(Xrender_Surface *rs); +void _xr_render_surface_repeat_set(Xrender_Surface *rs, int repeat); +void _xr_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h); +void _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h); +void _xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h); +void _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth); +void _xr_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h); +void _xr_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h); +void _xr_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2); +void _xre_poly_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points); + + +typedef struct _XR_Image XR_Image; + +struct _XR_Image +{ + Ximage_Info *xinf; + char *file; + char *key; + char *fkey; + RGBA_Image *im; + void *data; + int w, h; + Xrender_Surface *surface; + int references; + char *format; + char *comment; + Tilebuf *updates; + unsigned char alpha : 1; + unsigned char dirty : 1; + unsigned char free_data : 1; +}; + +XR_Image *_xre_image_load(Ximage_Info *xinf, char *file, char *key); +XR_Image *_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data); +XR_Image *_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data); +XR_Image *_xre_image_new(Ximage_Info *xinf, int w, int h); +void _xre_image_free(XR_Image *im); +void _xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h); +void _xre_image_dirty(XR_Image *im); +XR_Image *_xre_image_copy(XR_Image *im); +void *_xre_image_data_get(XR_Image *im); +void _xre_image_data_put(XR_Image *im, void *data); +void _xre_image_alpha_set(XR_Image *im, int alpha); +int _xre_image_alpha_get(XR_Image *im); +void _xre_image_surface_gen(XR_Image *im); +void _xre_image_cache_set(int size); +int _xre_image_cache_get(void); + +typedef struct _XR_Font_Surface XR_Font_Surface; + +struct _XR_Font_Surface +{ + Ximage_Info *xinf; + RGBA_Font_Glyph *fg; + int w, h; + Drawable draw; + Picture pic; +}; + +XR_Font_Surface *_xre_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg); +void _xre_font_surface_free(XR_Font_Surface *fs); +void _xre_font_surface_draw(Ximage_Info *xinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y); + +typedef struct _XR_Gradient XR_Gradient; + +struct _XR_Gradient +{ + Ximage_Info *xinf; + Xrender_Surface *surface; + RGBA_Gradient *grad; + double angle; +}; + +XR_Gradient *_xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, int a, int distance); +XR_Gradient *_xre_gradient_colors_clear(XR_Gradient *gr); +void _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle); + +#endif diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_font.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_font.c new file mode 100644 index 0000000000..368d6494c8 --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_font.c @@ -0,0 +1,189 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" + +static Evas_Hash *_xr_fg_pool = NULL; + +XR_Font_Surface * +_xre_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg) +{ + XR_Font_Surface *fs; + DATA8 *data; + int w, h, j; + DATA8 *ndata; + XRenderPictureAttributes att; + Ximage_Image *xim; + Evas_Hash *pool; + char buf[256], buf2[256]; + + data = fg->glyph_out->bitmap.buffer; + w = fg->glyph_out->bitmap.width; + h = fg->glyph_out->bitmap.rows; + j = fg->glyph_out->bitmap.pitch; + if (j < w) j = w; + if ((w <= 0) || (h <= 0)) return NULL; + + if (fg->ext_dat) + { + fs = fg->ext_dat; + if ((fs->xinf->disp == xinf->disp) && (fs->xinf->root == xinf->root)) + return fs; + snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->disp, fs->xinf->root); + pool = evas_hash_find(_xr_fg_pool, buf); + if (pool) + { + snprintf(buf, sizeof(buf), "%p", fg); + fs = evas_hash_find(pool, buf); + if (fs) return fs; + } + } + + fs = calloc(1, sizeof(XR_Font_Surface)); + if (!fs) return NULL; + + fs->xinf = xinf; + fs->fg = fg; + fs->xinf->references++; + fs->w = w; + fs->h = h; + + snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->disp, fs->xinf->root); + pool = evas_hash_find(_xr_fg_pool, buf); + snprintf(buf2, sizeof(buf2), "%p", fg); + pool = evas_hash_add(pool, buf2, fs); + _xr_fg_pool = evas_hash_add(_xr_fg_pool, buf, pool); + + fs->draw = XCreatePixmap(xinf->disp, xinf->root, w, h, xinf->fmt8->depth); + att.dither = 1; + att.component_alpha = 1; + att.repeat = 0; + fs->pic = XRenderCreatePicture(xinf->disp, fs->draw, xinf->fmt8, CPRepeat | CPDither | CPComponentAlpha, &att); + + xim = _xr_image_new(fs->xinf, w, h, xinf->fmt8->depth); + if (fg->glyph_out->bitmap.num_grays == 256) + { + int x, y; + DATA8 *p1, *p2; + + for (y = 0; y < h; y++) + { + p1 = data + (j * y); + p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y); + for (x = 0; x < w; x++) + { + *p2 = *p1; + p1++; + p2++; + } + } + + } + else if (fg->glyph_out->bitmap.num_grays == 0) + { + DATA8 *tmpbuf = NULL, *dp, *tp, bits; + int bi, bj, end; + const DATA8 bitrepl[2] = {0x0, 0xff}; + + tmpbuf = malloc(w); + if (tmpbuf) + { + int x, y; + DATA8 *p1, *p2; + + for (y = 0; y < h; y++) + { + p1 = tmpbuf; + p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y); + tp = tmpbuf; + dp = data + (y * 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++; + } + for (x = 0; x < w; x++) + { + *p2 = *p1; + p1++; + p2++; + } + } + free(tmpbuf); + } + } + _xr_image_put(xim, fs->draw, 0, 0, w, h); + return fs; +} + +static Evas_Bool +_xre_font_pool_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) +{ + Evas_Hash *pool; + XR_Font_Surface *fs; + char buf[256], buf2[256]; + + fs = fdata; + pool = data; + snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->disp, fs->xinf->root); + pool = evas_hash_del(pool, buf, fs); + hash = evas_hash_modify(hash, key, pool); + return 1; +} + +void +_xre_font_surface_free(XR_Font_Surface *fs) +{ + if (!fs) return; + evas_hash_foreach(_xr_fg_pool, _xre_font_pool_cb, fs); + XFreePixmap(fs->xinf->disp, fs->draw); + XRenderFreePicture(fs->xinf->disp, fs->pic); + _xr_image_info_free(fs->xinf); + free(fs); +} + +void +_xre_font_surface_draw(Ximage_Info *xinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y) +{ + XR_Font_Surface *fs; + Xrender_Surface *target_surface; + XRectangle rect; + XRenderPictureAttributes att; + int r, g, b, a; + + fs = fg->ext_dat; + if (!fs) return; + target_surface = (Xrender_Surface *)(surface->image->data); + a = (dc->col.col >> 24) & 0xff; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + if ((fs->xinf->mul_r != r) || (fs->xinf->mul_g != g) || + (fs->xinf->mul_b != b) || (fs->xinf->mul_a != a)) + { + fs->xinf->mul_r = r; + fs->xinf->mul_g = g; + fs->xinf->mul_b = b; + fs->xinf->mul_a = a; + _xr_render_surface_solid_rectangle_set(fs->xinf->mul, r, g, b, a, 0, 0, 1, 1); + } + rect.x = x; rect.y = y; rect.width = fs->w; rect.height = fs->h; + if ((dc) && (dc->clip.use)) + { + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + } + XRenderSetPictureClipRectangles(target_surface->xinf->disp, + target_surface->pic, 0, 0, &rect, 1); + XRenderComposite(fs->xinf->disp, PictOpOver, fs->xinf->mul->pic, + fs->pic, target_surface->pic, + 0, 0, 0, 0, x, y, fs->w, fs->h); +} diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c new file mode 100644 index 0000000000..03eae01ea2 --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c @@ -0,0 +1,98 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" +#include + +XR_Gradient * +_xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, int a, int distance) +{ + if (!gr) + { + gr = calloc(1, sizeof(XR_Gradient)); + if (!gr) return NULL; + gr->xinf = xinf; + gr->xinf->references++; + gr->grad = evas_common_gradient_new(); + if (!gr->grad) + { + gr->xinf->references--; + free(gr); + return NULL; + } + } + evas_common_gradient_color_add(gr->grad, r, g, b, a, distance); + if (gr->surface) + { + _xr_render_surface_free(gr->surface); + gr->surface = NULL; + } + return gr; +} + +XR_Gradient * +_xre_gradient_colors_clear(XR_Gradient *gr) +{ + if (!gr) return NULL; + if (gr->grad) + { + evas_common_gradient_free(gr->grad); + gr->grad = NULL; + } + if (gr->surface) + { + _xr_render_surface_free(gr->surface); + gr->surface = NULL; + } + _xr_image_info_free(gr->xinf); + free(gr); + return NULL; +} + +void +_xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle) +{ + XTransform xf; + XRectangle rect; + XRenderPictureAttributes att; + Picture mask; + int r, g, b, a, op; + RGBA_Image *im; + double a2; + + if ((w <= 0) || (h <= 0)) return; + + if (angle != gr->angle) + { + if (gr->surface) + { + _xr_render_surface_free(gr->surface); + gr->surface = NULL; + } + } + if (!gr->surface) + { + im = evas_common_image_create(w, h); + if (im) + { + RGBA_Draw_Context *dc2; + + dc2 = evas_common_draw_context_new(); + if (dc2) + { + im->flags |= RGBA_IMAGE_HAS_ALPHA; + memset(im->image->data, 0, im->image->w * im->image->h * sizeof(DATA32)); + evas_common_gradient_draw(im, dc2, 0, 0, w, h, gr->grad, angle); + gr->surface = _xr_render_surface_new(gr->xinf, w, h, gr->xinf->fmt32, 1); + if (gr->surface) + _xr_render_surface_argb_pixels_fill(gr->surface, w, h, im->image->data, 0, 0, w, h); + evas_common_draw_context_free(dc2); + gr->angle = angle; + } + evas_common_image_free(im); + } + } + if (gr->surface) + _xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 1); +} diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c new file mode 100644 index 0000000000..0d4609626a --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c @@ -0,0 +1,492 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" + +static Evas_Hash *_xr_image_hash = NULL; +static int _xr_image_cache_size = 0; +static int _xr_image_cache_usage = 0; +static Evas_List *_xr_image_cache = NULL; + +static XR_Image * +__xre_image_find(char *fkey) +{ + XR_Image *im; + + im = evas_hash_find(_xr_image_hash, fkey); + if (!im) + { + Evas_List *l; + + for (l = _xr_image_cache; l; l = l->next) + { + im = l->data; + if (!strcmp(im->fkey, fkey)) + { + _xr_image_cache = evas_list_remove_list(_xr_image_cache, l); + _xr_image_hash = evas_hash_add(_xr_image_hash, im->fkey, im); + _xr_image_cache_usage -= (im->w * im->h * 4); + break; + } + im = NULL; + } + } + if (im) im->references++; + return im; +} + +XR_Image * +_xre_image_load(Ximage_Info *xinf, char *file, char *key) +{ + XR_Image *im; + char buf[4096]; + + if (!file) return NULL; + if (key) + snprintf(buf, sizeof(buf), "/@%p@%x@/%s//://%s", xinf->disp, xinf->root, file, key); + else + snprintf(buf, sizeof(buf), "/@%p@%x@/%s", xinf->disp, xinf->root, file); + im = __xre_image_find(buf); + if (im) return im; + + im = calloc(1, sizeof(XR_Image)); + if (!im) return NULL; + im->im = evas_common_load_image_from_file(file, key); + if (!im->im) + { + free(im); + return NULL; + } + im->xinf = xinf; + im->xinf->references++; + im->fkey = strdup(buf); + im->file = strdup(file); + if (key) im->key = strdup(key); + im->w = im->im->image->w; + im->h = im->im->image->h; + im->references = 1; + if (im->im->info.comment) im->comment = strdup(im->im->info.comment); + if (im->im->info.format == 1) im->format = strdup("png"); + if (im->im->flags & RGBA_IMAGE_HAS_ALPHA) im->alpha = 1; + _xr_image_hash = evas_hash_add(_xr_image_hash, im->fkey, im); + return im; +} + +XR_Image * +_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data) +{ + XR_Image *im; + + im = calloc(1, sizeof(XR_Image)); + if (!im) return NULL; + im->xinf = xinf; + im->xinf->references++; + im->w = w; + im->h = h; + im->references = 1; + im->data = data; + im->alpha = 1; + im->dirty = 1; + return im; +} + +XR_Image * +_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data) +{ + XR_Image *im; + + im = calloc(1, sizeof(XR_Image)); + if (!im) return NULL; + im->data = malloc(w * h * 4); + if (!im->data) + { + free(im); + return NULL; + } + im->w = w; + im->h = h; + im->references = 1; + im->xinf = xinf; + im->xinf->references++; + im->free_data = 1; + + { + Gfx_Func_Blend_Src_Dst func; + + func = evas_common_draw_func_copy_get(w * h, 0); + if (func) func(data, im->data, w * h); + evas_common_cpu_end_opt(); + } + + im->alpha = 1; + im->dirty = 1; + return im; +} + +XR_Image * +_xre_image_new(Ximage_Info *xinf, int w, int h) +{ + XR_Image *im; + + im = calloc(1, sizeof(XR_Image)); + if (!im) return NULL; + im->xinf = xinf; + im->xinf->references++; + im->w = w; + im->h = h; + im->references = 1; + im->data = malloc(w * h * 4); + if (!im->data) + { + im->xinf->references--; + free(im); + } + im->free_data = 1; + im->alpha = 1; + im->dirty = 1; + return im; +} + +static void +__xre_image_real_free(XR_Image *im) +{ + if (im->file) free(im->file); + if (im->key) free(im->key); + if (im->fkey) free(im->fkey); + if (im->im) evas_common_image_unref(im->im); + if ((im->free_data) && (im->data)) free(im->data); + if (im->surface) _xr_render_surface_free(im->surface); + if (im->format) free(im->format); + if (im->comment) free(im->comment); + if (im->updates) evas_common_tilebuf_free(im->updates); + _xr_image_info_free(im->xinf); + free(im); +} + +void +_xre_image_free(XR_Image *im) +{ + im->references--; + if (im->references != 0) return; + if (!im->dirty) + { + if (im->fkey) + _xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im); + _xr_image_cache = evas_list_prepend(_xr_image_cache, im); + _xr_image_cache_usage += (im->w * im->h * 4); + _xre_image_cache_set(_xr_image_cache_size); + } + else + __xre_image_real_free(im); +} + +void +_xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h) +{ + if (!im->updates) + { + im->updates = evas_common_tilebuf_new(im->w, im->h); + if (im->updates) evas_common_tilebuf_set_tile_size(im->updates, 8, 8); + } + if (im->updates) + evas_common_tilebuf_add_redraw(im->updates, x, y, w, h); +} + +void +_xre_image_dirty(XR_Image *im) +{ + if (im->dirty) return; + if (im->fkey) + _xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im); + im->dirty = 1; +} + +XR_Image * +_xre_image_copy(XR_Image *im) +{ + XR_Image *im2; + void *data = NULL; + + if (im->data) data = im->data; + else + { + if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key); + if (im->im) + { + evas_common_load_image_data_from_file(im->im); + data = im->im->image->data; + } + } + if (!data) return NULL; + im2 = _xre_image_new_from_copied_data(im->xinf, im->w, im->h, data); + if (im2) im2->alpha = im->alpha; + if ((im->im) && (!im->dirty)) + { + evas_common_image_unref(im->im); + im->im = NULL; + } + return im2; +} + +void +_xre_image_resize(XR_Image *im, int w, int h) +{ + if ((w == im->w) && (h == im->h)) return; + if (im->surface) + { + Xrender_Surface *old_surface; + int x = 0, y = 0, ww, hh; + + ww = w; hh = h; + RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h); + old_surface = im->surface; + im->surface = _xr_render_surface_new(old_surface->xinf, w, h, old_surface->fmt, old_surface->alpha); + if (im->surface) + _xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, ww, hh); + _xr_render_surface_free(old_surface); + } + if (im->data) + { + Gfx_Func_Blend_Src_Dst func; + int x = 0, y = 0, ww, hh; + unsigned int *sp, *dp; + void *data; + + data = malloc(w * h * 4); + if (!data) + { + if (im->surface) + { + _xr_render_surface_free(im->surface); + im->surface = NULL; + } + return; + } + ww = w; hh = h; + + RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h); + func = evas_common_draw_func_copy_get(w * h, 0); + if (func) + { + for (y = 0; y < hh; y++) + { + sp = ((unsigned int *)im->data) + (y * im->w); + dp = ((unsigned int *)data) + (y * w); + func(sp, dp, ww); + } + evas_common_cpu_end_opt(); + } + free(im->data); + im->data = data; + } + else if (im->im) + { + RGBA_Image *im_old; + + im_old = im->im; + im->im = evas_common_image_create(w, h); + if (!im->im) + { + im->im = im_old; + if (im->surface) + { + _xr_render_surface_free(im->surface); + im->surface = NULL; + } + return; + } + evas_common_load_image_data_from_file(im_old); + if (im_old->image->data) + { + int x = 0, y = 0, ww, hh; + + ww = w; hh = h; + RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h); + evas_common_blit_rectangle(im_old, im->im, 0, 0, ww, hh, 0, 0); + evas_common_cpu_end_opt(); + } + evas_common_image_unref(im_old); + } + else + { + im->data = malloc(w * h * 4); + im->free_data = 1; + } + im->w = w; + im->h = h; +} + +void * +_xre_image_data_get(XR_Image *im) +{ + void *data = NULL; + + if (im->data) data = im->data; + else + { + if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key); + if (im->im) + { + evas_common_load_image_data_from_file(im->im); + data = im->im->image->data; + } + } + return data; +} + +void +_xre_image_data_put(XR_Image *im, void *data) +{ + void *imdata = NULL; + + if (!data) return; + if (im->data) + { + imdata = im->data; + if (data == imdata) return; + if (im->free_data) free(im->data); + } + else + { + if (im->im) imdata = im->im->image->data; + if (data == imdata) return; + if (im->im) + { + evas_common_image_unref(im->im); + im->im = NULL; + } + } + im->data = data; + im->free_data = 0; + if (im->surface) + { + _xr_render_surface_free(im->surface); + im->surface = NULL; + } + _xre_image_dirty(im); + if (im->updates) + { + evas_common_tilebuf_free(im->updates); + im->updates = NULL; + } +} + +void +_xre_image_alpha_set(XR_Image *im, int alpha) +{ + if (im->alpha == alpha) return; + im->alpha = alpha; + if (im->surface) + { + Xrender_Surface *old_surface; + + old_surface = im->surface; + im->surface = NULL; + if (im->alpha) + im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt32, 1); + else + im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt24, 0); + if (im->surface) + _xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w, im->h); + _xr_render_surface_free(old_surface); + } + if (im->updates) + { + evas_common_tilebuf_free(im->updates); + im->updates = NULL; + } +} + +int +_xre_image_alpha_get(XR_Image *im) +{ + return im->alpha; +} + +void +_xre_image_surface_gen(XR_Image *im) +{ + void *data = NULL; + + if (im->data) data = im->data; + else + { + if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key); + if (im->im) + { + evas_common_load_image_data_from_file(im->im); + data = im->im->image->data; + } + } + if (!data) return; + if (im->surface) + { + if (im->updates) + { + Tilebuf_Rect *rects, *r; + + rects = evas_common_tilebuf_get_render_rects(im->updates); + if (rects) + { + for (r = rects; r; r = (Tilebuf_Rect *)((Evas_Object_List *)r)->next) + { + int rx, ry, rw, rh; + + rx = r->x; ry = r->y; rw = r->w, rh = r->h; + RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h); + if (im->alpha) + _xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh); + else + _xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh); + } + evas_common_tilebuf_free_render_rects(rects); + } + evas_common_tilebuf_free(im->updates); + im->updates = NULL; + } + return; + } + if (im->alpha) + { + im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt32, 1); + _xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h); + } + else + { + im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt24, 0); + _xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h); + } + if ((im->im) && (!im->dirty)) + { + evas_common_image_unref(im->im); + im->im = NULL; + } +} + +void +_xre_image_cache_set(int size) +{ + _xr_image_cache_size = size; + while (_xr_image_cache_usage > _xr_image_cache_size) + { + Evas_List *l; + + l = evas_list_last(_xr_image_cache); + if (l) + { + XR_Image *im; + + im = l->data; + _xr_image_cache = evas_list_remove_list(_xr_image_cache, l); + _xr_image_cache_usage -= (im->w * im->h * 4); + __xre_image_real_free(im); + } + } +} + +int +_xre_image_cache_get(void) +{ + return _xr_image_cache_size; +} diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c new file mode 100644 index 0000000000..8e2b149288 --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c @@ -0,0 +1,254 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" + +static Evas_List *_image_info_list = NULL; + +static int _x_err = 0; +static void +_tmp_x_err(Display *d, XErrorEvent *ev) +{ + _x_err = 1; + return; +} + +Ximage_Info * +_xr_image_info_get(Display *disp, Drawable draw, Visual *vis) +{ + Ximage_Info *xinf, *xinf2; + Evas_List *l; + int di; + unsigned int dui; + + xinf2 = NULL; + for (l = _image_info_list; l; l = l->next) + { + xinf = l->data; + if (xinf->disp == disp) + { + xinf2 = xinf; + break; + } + } + xinf = calloc(1, sizeof(Ximage_Info)); + if (!xinf) return NULL; + + xinf->references = 1; + xinf->disp = disp; + xinf->draw = draw; + XGetGeometry(xinf->disp, xinf->draw, &(xinf->root), &di, &di, &dui, &dui, &dui, &dui); + xinf->vis = vis; + xinf->fmt32 = XRenderFindStandardFormat(xinf->disp, PictStandardARGB32); + xinf->fmt24 = XRenderFindStandardFormat(xinf->disp, PictStandardRGB24); + xinf->fmt8 = XRenderFindStandardFormat(xinf->disp, PictStandardA8); + xinf->fmt4 = XRenderFindStandardFormat(xinf->disp, PictStandardA4); + xinf->fmt1 = XRenderFindStandardFormat(xinf->disp, PictStandardA1); + xinf->mul = _xr_render_surface_new(xinf, 1, 1, xinf->fmt32, 1); + _xr_render_surface_repeat_set(xinf->mul, 1); + xinf->mul_r = xinf->mul_g = xinf->mul_b = xinf->mul_a = 0xff; + _xr_render_surface_solid_rectangle_set(xinf->mul, xinf->mul_r, xinf->mul_g, xinf->mul_b, xinf->mul_a, 0, 0, 1, 1); + if (xinf2) + { + xinf->can_do_shm = xinf2->can_do_shm; + xinf->depth = xinf2->depth; + } + else + { + XVisualInfo *vi, vit; + XShmSegmentInfo shm_info; + XImage *xim; + int num = 0; + + vit.visualid = XVisualIDFromVisual(xinf->vis); + vi = XGetVisualInfo(xinf->disp, VisualIDMask, &vit, &num); + if (!vi) xinf->depth = 32; + else + { + xinf->depth = vi->depth; + XFree(vi); + } + xinf->can_do_shm = 0; + xim = XShmCreateImage(xinf->disp, xinf->vis, xinf->depth, ZPixmap, NULL, &shm_info, 1, 1); + if (xim) + { + shm_info.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height, IPC_CREAT | 0777); + if (shm_info.shmid >= 0) + { + shm_info.shmaddr = xim->data = shmat(shm_info.shmid, 0, 0); + if (shm_info.shmaddr != NULL) + { + XErrorHandler ph; + + XSync(xinf->disp, False); + _x_err = 0; + ph = XSetErrorHandler((XErrorHandler)_tmp_x_err); + XShmAttach(xinf->disp, &shm_info); + XSync(xinf->disp, False); + XSetErrorHandler((XErrorHandler)ph); + if (!_x_err) xinf->can_do_shm = 1; + } + shmdt(shm_info.shmaddr); + shmctl(shm_info.shmid, IPC_RMID, 0); + } + XDestroyImage(xim); + } + } + _image_info_list = evas_list_prepend(_image_info_list, xinf); + return xinf; +} + +void +_xr_image_info_free(Ximage_Info *xinf) +{ + if (xinf->pool) XSync(xinf->disp, False); + _xr_image_info_pool_flush(xinf, 0, 0); + xinf->references--; + if (xinf->references != 0) return; + _xr_render_surface_free(xinf->mul); + free(xinf); + _image_info_list = evas_list_remove(_image_info_list, xinf); +} + +void +_xr_image_info_pool_flush(Ximage_Info *xinf, int max_num, int max_mem) +{ + if ((xinf->pool_mem <= max_mem) && (evas_list_count(xinf->pool) <= max_num)) return; + while ((xinf->pool_mem > max_mem) || (evas_list_count(xinf->pool) > max_num)) + { + Ximage_Image *xim; + + if (!xinf->pool) break; + xim = xinf->pool->data; + _xr_image_free(xim); + } +} + +Ximage_Image * +_xr_image_new(Ximage_Info *xinf, int w, int h, int depth) +{ + Ximage_Image *xim, *xim2; + Evas_List *l; + + xim2 = NULL; + for (l = xinf->pool; l; l = l->next) + { + xim = l->data; + if ((xim->w >= w) && (xim->h >= h) && (xim->depth == depth) && (xim->available)) + { + if (!xim2) xim2 = xim; + else if ((xim->w * xim->h) < (xim2->w * xim2->h)) xim2 = xim; + } + } + if (xim2) + { + xim2->available = 0; + return xim2; + } + xim = calloc(1, sizeof(Ximage_Image)); + if (xim) + { + xim->xinf = xinf; + xim->w = w; + xim->h = h; + xim->depth = depth; + xim->available = 0; + if (xim->xinf->can_do_shm) + { + xim->shm_info = calloc(1, sizeof(XShmSegmentInfo)); + if (xim->shm_info) + { + xim->xim = XShmCreateImage(xim->xinf->disp, xim->xinf->vis, xim->depth, ZPixmap, NULL, xim->shm_info, xim->w, xim->h); + if (xim->xim) + { + xim->shm_info->shmid = shmget(IPC_PRIVATE, xim->xim->bytes_per_line * xim->xim->height, IPC_CREAT | 0777); + if (xim->shm_info->shmid >= 0) + { + xim->shm_info->shmaddr = xim->xim->data = shmat(xim->shm_info->shmid, 0, 0); + if (xim->shm_info->shmaddr != NULL) + { + XErrorHandler ph; + + XSync(xim->xinf->disp, False); + _x_err = 0; + ph = XSetErrorHandler((XErrorHandler)_tmp_x_err); + XShmAttach(xim->xinf->disp, xim->shm_info); + XSync(xim->xinf->disp, False); + XSetErrorHandler((XErrorHandler)ph); + if (!_x_err) goto xim_ok; + } + shmdt(xim->shm_info->shmaddr); + shmctl(xim->shm_info->shmid, IPC_RMID, 0); + } + XDestroyImage(xim->xim); + } + free(xim->shm_info); + xim->shm_info = NULL; + } + } + xim->xim = XCreateImage(xim->xinf->disp, xim->xinf->vis, xim->depth, ZPixmap, 0, NULL, xim->w, xim->h, 32, 0); + if (!xim->xim) + { + free(xim); + return NULL; + } + xim->xim->data = malloc(xim->xim->bytes_per_line * xim->xim->height); + if (!xim->xim->data) + { + XDestroyImage(xim->xim); + free(xim); + return NULL; + } + } + + xim_ok: + _xr_image_info_pool_flush(xinf, 32, (1600 * 1200 * 32 * 2)); + + xim->line_bytes = xim->xim->bytes_per_line; + xim->data = (void *)(xim->xim->data); + xinf->pool_mem += (xim->w * xim->h * xim->depth); + xinf->pool = evas_list_append(xinf->pool, xim); + return xim; +} + +void +_xr_image_free(Ximage_Image *xim) +{ + if (xim->shm_info) + { + if (!xim->available) XSync(xim->xinf->disp, False); + XShmDetach(xim->xinf->disp, xim->shm_info); + XDestroyImage(xim->xim); + shmdt(xim->shm_info->shmaddr); + shmctl(xim->shm_info->shmid, IPC_RMID, 0); + free(xim->shm_info); + } + else + { + free(xim->xim->data); + xim->xim->data = NULL; + XDestroyImage(xim->xim); + } + xim->xinf->pool_mem -= (xim->w * xim->h * xim->depth); + xim->xinf->pool = evas_list_remove(xim->xinf->pool, xim); + free(xim); +} + +void +_xr_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h) +{ + XGCValues gcv; + GC gc; + + gc = XCreateGC(xim->xinf->disp, draw, 0, &gcv); + if (xim->shm_info) + { + XShmPutImage(xim->xinf->disp, draw, gc, xim->xim, 0, 0, x, y, w, h, False); + XSync(xim->xinf->disp, False); + } + else + XPutImage(xim->xinf->disp, draw, gc, xim->xim, 0, 0, x, y, w, h); + xim->available = 1; + XFreeGC(xim->xinf->disp, gc); +} diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c new file mode 100644 index 0000000000..d25e866e86 --- /dev/null +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c @@ -0,0 +1,421 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_xrender_x11.h" +#include "Evas_Engine_XRender_X11.h" + +Xrender_Surface * +_xr_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha) +{ + Xrender_Surface *rs; + XRenderPictureAttributes att; + + rs = calloc(1, sizeof(Xrender_Surface)); + if (!rs) return NULL; + rs->xinf = xinf; + rs->w = w; + rs->h = h; + rs->fmt = fmt; + rs->alpha = alpha; + rs->depth = fmt->depth; + rs->allocated = 1; + rs->draw = XCreatePixmap(xinf->disp, xinf->root, w, h, fmt->depth); + att.dither = 1; + att.component_alpha = 1; + att.repeat = 0; + rs->pic = XRenderCreatePicture(xinf->disp, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att); + return rs; +} + +Xrender_Surface * +_xr_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha) +{ + Xrender_Surface *rs; + XRenderPictFormat *fmt; + XRenderPictureAttributes att; + + rs = calloc(1, sizeof(Xrender_Surface)); + fmt = XRenderFindVisualFormat(xinf->disp, xinf->vis); + rs->xinf = xinf; + rs->w = w; + rs->h = h; + rs->fmt = fmt; + rs->alpha = alpha; + rs->depth = fmt->depth; + rs->allocated = 0; + rs->draw = draw; + att.dither = 1; + att.component_alpha = 1; + att.repeat = 0; + rs->pic = XRenderCreatePicture(xinf->disp, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att); + return rs; +} + +void +_xr_render_surface_free(Xrender_Surface *rs) +{ + if (rs->allocated) XFreePixmap(rs->xinf->disp, rs->draw); + XRenderFreePicture(rs->xinf->disp, rs->pic); + free(rs); +} + +void +_xr_render_surface_repeat_set(Xrender_Surface *rs, int repeat) +{ + XRenderPictureAttributes att; + + att.repeat = repeat; + XRenderChangePicture(rs->xinf->disp, rs->pic, CPRepeat, &att); +} + +void +_xr_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h) +{ + XRenderColor col; + int aa; + + aa = a +1; + r = (r * aa) >> 8; + g = (g * aa) >> 8; + b = (b * aa) >> 8; + col.red = (r << 8) | r; + col.green = (g << 8) | g; + col.blue = (b << 8) | b; + col.alpha = (a << 8) | a; + XRenderFillRectangle(rs->xinf->disp, PictOpSrc, rs->pic, &col, x, y, w, h); +} + +void +_xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h) +{ + Ximage_Image *xim; + unsigned int *p, *sp, *sple, *spe; + unsigned int jump, sjump; + unsigned int a, r, g, b, aa; + + xim = _xr_image_new(rs->xinf, w, h, rs->depth); + if (!xim) return; + p = (unsigned int *)xim->data; + sp = ((unsigned int *)pixels) + (y * sw) + x; + jump = ((xim->line_bytes / 4) - w); + sjump = sw - w; + spe = sp + ((h - 1) * sw) + w; + while (sp < spe) + { + sple = sp + w; + while (sp < sple) + { + a = A_VAL(sp); + aa = a + 1; + r = ((R_VAL(sp)) * aa) >> 8; + g = ((G_VAL(sp)) * aa) >> 8; + b = ((B_VAL(sp)) * aa) >> 8; + *p = (a << 24) | (r << 16) | (g << 8) | b; + p++; + sp++; + } + p += jump; + sp += sjump; + } + _xr_image_put(xim, rs->draw, x, y, w, h); +} + +void +_xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h) +{ + Ximage_Image *xim; + unsigned int *p, *sp, *sple, *spe; + unsigned int jump, sjump; + + xim = _xr_image_new(rs->xinf, w, h, rs->depth); + if (!xim) return; + p = (unsigned int *)xim->data; + sp = ((unsigned int *)pixels) + (y * sw) + x; + jump = ((xim->line_bytes / 4) - w); + sjump = sw - w; + spe = sp + ((h - 1) * sw) + w; + while (sp < spe) + { + sple = sp + w; + while (sp < sple) + { + *p = 0xff000000 | ((R_VAL(sp)) << 16) | ((G_VAL(sp)) << 8) | (B_VAL(sp)); + p++; + sp++; + } + p += jump; + sp += sjump; + } + _xr_image_put(xim, rs->draw, x, y, w, h); +} + +void +_xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth) +{ + XTransform xf; + XRectangle rect; + XRenderPictureAttributes att; + Picture mask; + int r, g, b, a, op; + + if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return; + xf.matrix[0][0] = (0x10000 * sw) / w; + xf.matrix[0][1] = 0; + xf.matrix[0][2] = 0; + + xf.matrix[1][0] = 0; + xf.matrix[1][1] = (0x10000 * sh) / h; + xf.matrix[1][2] = 0; + + xf.matrix[2][0] = 0; + xf.matrix[2][1] = 0; + xf.matrix[2][2] = 0x10000; + + op = PictOpSrc; + if (srs->alpha) op = PictOpOver; + mask = None; + if ((dc) && (dc->mul.use)) + { + r = (int)(R_VAL(&dc->mul.col)); + g = (int)(G_VAL(&dc->mul.col)); + b = (int)(B_VAL(&dc->mul.col)); + a = (int)(A_VAL(&dc->mul.col)); + if (!(r == g == b == a == 0xff)) + { + if ((srs->xinf->mul_r != r) || (srs->xinf->mul_g != g) || + (srs->xinf->mul_b != b) || (srs->xinf->mul_a != a)) + { + srs->xinf->mul_r = r; + srs->xinf->mul_g = g; + srs->xinf->mul_b = b; + srs->xinf->mul_a = a; + _xr_render_surface_solid_rectangle_set(srs->xinf->mul, r, g, b, a, 0, 0, 1, 1); + } + op = PictOpOver; + mask = srs->xinf->mul->pic; + } + } + + XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); + att.clip_mask = None; + XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att); + XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att); + rect.x = x; rect.y = y; rect.width = w; rect.height = h; + if ((dc) && (dc->clip.use)) + { + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + } + + if (smooth) XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "bilinear", NULL, 0); + else XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "nearest", NULL, 0); + + XRenderSetPictureClipRectangles(srs->xinf->disp, drs->pic, 0, 0, &rect, 1); + XRenderComposite(srs->xinf->disp, op, srs->pic, mask, drs->pic, + ((sx * w) + (sw / 2)) / sw, + ((sy * h) + (sh / 2)) / sh, + 0, 0, x, y, w, h); +} + +void +_xr_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h) +{ + XTransform xf; + XRenderPictureAttributes att; + + if ((w <= 0) || (h <= 0)) return; + xf.matrix[0][0] = 1; + xf.matrix[0][1] = 0; + xf.matrix[0][2] = 0; + + xf.matrix[1][0] = 0; + xf.matrix[1][1] = 1; + xf.matrix[1][2] = 0; + + xf.matrix[2][0] = 0; + xf.matrix[2][1] = 0; + xf.matrix[2][2] = 1; + + XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); + att.clip_mask = None; + XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att); + XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att); + XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "nearest", NULL, 0); + + XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, drs->pic, + sx, sy, 0, 0, x, y, w, h); +} + +void +_xr_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h) +{ + XRenderColor col; + XRectangle rect; + XRenderPictureAttributes att; + int r, g, b, a, aa, op; + + if ((w <= 0) || (h <= 0)) return; + a = (dc->col.col >> 24) & 0xff; + if (a == 0) return; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + aa = a +1; + r = (r * aa) >> 8; + g = (g * aa) >> 8; + b = (b * aa) >> 8; + col.red = (r << 8) | r; + col.green = (g << 8) | g; + col.blue = (b << 8) | b; + col.alpha = (a << 8) | a; + op = PictOpSrc; + if (a < 0xff) op = PictOpOver; + att.clip_mask = None; + XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att); + if ((dc) && (dc->clip.use)) + { + rect.x = dc->clip.x; rect.y = dc->clip.y; + rect.width = dc->clip.w; rect.height = dc->clip.h; + XRenderSetPictureClipRectangles(rs->xinf->disp, rs->pic, 0, 0, &rect, 1); + } + XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x, y, w, h); +} + +void +_xr_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2) +{ + XRectangle rect; + XRenderPictureAttributes att; + int op; + + op = PictOpSrc; + att.clip_mask = None; + XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att); + if ((dc) && (dc->clip.use)) + { + rect.x = dc->clip.x; rect.y = dc->clip.y; + rect.width = dc->clip.w; rect.height = dc->clip.h; + XRenderSetPictureClipRectangles(rs->xinf->disp, rs->pic, 0, 0, &rect, 1); + } + if ((y1 == y2) || (x1 == x2)) + { + XRenderColor col; + int r, g, b, a, aa; + + a = (dc->col.col >> 24) & 0xff; + if (a == 0) return; + if (a < 0xff) op = PictOpOver; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + aa = a +1; + r = (r * aa) >> 8; + g = (g * aa) >> 8; + b = (b * aa) >> 8; + col.red = (r << 8) | r; + col.green = (g << 8) | g; + col.blue = (b << 8) | b; + col.alpha = (a << 8) | a; + if (y1 == y2) + XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x1, y1, x2 - x1 + 1, 1); + else + XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x1, y1, 1, y2 - y1 + 1); + } + else + { + int r, g, b, a; + XPointDouble poly[4]; + int dx, dy; + double len, ddx, ddy; + + dx = x2 - x1; + dy = y2 - y1; + len = sqrt((dx * dx) + (dy * dy)); + ddx = (0.5 * dx) / len; + ddy = (0.5 * dy) / len; + poly[0].x = (x1 + ddx); + poly[0].y = (y1 - ddy); + poly[1].x = (x2 + ddx); + poly[1].y = (y2 - ddy); + poly[2].x = (x2 - ddx); + poly[2].y = (y2 + ddy); + poly[3].x = (x1 - ddx); + poly[3].y = (y1 + ddy); + + a = (dc->col.col >> 24) & 0xff; + if (a == 0) return; + if (a < 0xff) op = PictOpOver; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) || + (rs->xinf->mul_b != b) || (rs->xinf->mul_a != a)) + { + rs->xinf->mul_r = r; + rs->xinf->mul_g = g; + rs->xinf->mul_b = b; + rs->xinf->mul_a = a; + _xr_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1); + } + XRenderCompositeDoublePoly(rs->xinf->disp, op, + rs->xinf->mul->pic, rs->pic, + rs->xinf->fmt8, 0, 0, 0, 0, + poly, 4, EvenOddRule); + } +} + +void +_xre_poly_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points) +{ + RGBA_Polygon_Point *pt; + int i, num; + XPointDouble *pts; + int r, g, b, a; + XRectangle rect; + XRenderPictureAttributes att; + int op; + + op = PictOpSrc; + num = 0; + for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next)) num++; + if (num < 3) return; + a = (dc->col.col >> 24) & 0xff; + if (a == 0) return; + if (a < 0xff) op = PictOpOver; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) || + (rs->xinf->mul_b != b) || (rs->xinf->mul_a != a)) + { + rs->xinf->mul_r = r; + rs->xinf->mul_g = g; + rs->xinf->mul_b = b; + rs->xinf->mul_a = a; + _xr_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1); + } + pts = malloc(num * sizeof(XPointDouble)); + if (!pts) return; + i = 0; + for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next)) + { + pts[i].x = pt->x; + pts[i].y = pt->y; + i++; + } + rect.x = 0; rect.y = 0; rect.width = rs->w; rect.height = rs->h; + att.clip_mask = None; + XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att); + if ((dc) && (dc->clip.use)) + { + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + } + XRenderSetPictureClipRectangles(rs->xinf->disp, rs->pic, 0, 0, &rect, 1); + XRenderCompositeDoublePoly(rs->xinf->disp, op, + rs->xinf->mul->pic, rs->pic, + rs->xinf->fmt8, 0, 0, 0, 0, + pts, num, Complex); + free(pts); +} + diff --git a/legacy/evas/src/lib/include/Makefile.am b/legacy/evas/src/lib/include/Makefile.am index 63793351cf..8db86c5dea 100644 --- a/legacy/evas/src/lib/include/Makefile.am +++ b/legacy/evas/src/lib/include/Makefile.am @@ -10,6 +10,7 @@ evas_engine_api_buffer.h \ evas_engine_api_software_qtopia.h \ evas_engine_api_gl_x11.h \ evas_engine_api_cairo_x11.h \ +evas_engine_api_xrender_x11.h \ evas_gl_common.h \ evas_cairo_common.h \ evas_mmx.h \ diff --git a/legacy/evas/src/lib/include/evas_engine_api_xrender_x11.h b/legacy/evas/src/lib/include/evas_engine_api_xrender_x11.h new file mode 100644 index 0000000000..268f2cae57 --- /dev/null +++ b/legacy/evas/src/lib/include/evas_engine_api_xrender_x11.h @@ -0,0 +1,7 @@ +#ifndef EVAS_ENGINE_XRENDER_X11_H +#define EVAS_ENGINE_XRENDER_X11_H +#include + +extern Evas_Func evas_engine_xrender_x11_func; + +#endif diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 50375d944c..427fc81b83 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -19,33 +19,10 @@ #define RENDER_METHOD_GL_X11 0x00000007 #define RENDER_METHOD_CAIRO_X11 0x00000008 #define RENDER_METHOD_SOFTWARE_XCB 0x00000009 +#define RENDER_METHOD_XRENDER_X11 0x0000000a #define RENDER_METHOD_INVALID 0x00000000 -typedef enum _Evas_Format_Type -{ - EVAS_FORMAT_NONE = 0, - EVAS_FORMAT_FONT, - EVAS_FORMAT_SIZE, - EVAS_FORMAT_COLOR, - EVAS_FORMAT_COLOR2, - EVAS_FORMAT_COLOR3, - EVAS_FORMAT_ALIGN, - EVAS_FORMAT_STYLE, - EVAS_FORMAT_UNDERLINE, - EVAS_FORMAT_NEWLINE, - EVAS_FORMAT_TAB, - EVAS_FORMAT_L2R, - EVAS_FORMAT_R2L, - EVAS_FORMAT_ANCHOR -} Evas_Format_Type; - -typedef enum _Evas_Format_Direction -{ - EVAS_FORMAT_DIRECTION_VERTICAL = 0, - EVAS_FORMAT_DIRECTION_HORIZONTAL = 1 -} Evas_Format_Direction; - typedef struct _Evas_Layer Evas_Layer; typedef struct _Evas_Font_Dir Evas_Font_Dir; typedef struct _Evas_Font Evas_Font;