Mercurial > MadButterfly
changeset 1098:cb4a2ffdf9e8
Merge HEAD
author | wycc |
---|---|
date | Sat, 04 Dec 2010 16:58:25 +0800 |
parents | 52d8bf5d12b4 (current diff) c18ad321844d (diff) |
children | 5ba2cab1d505 |
files | |
diffstat | 22 files changed, 1702 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Sat Dec 04 07:43:51 2010 +0800 +++ b/configure.ac Sat Dec 04 16:58:25 2010 +0800 @@ -26,6 +26,12 @@ AC_TYPE_UINT32_T AC_TYPE_UINT64_T +# Explicit initialize pkg-config for conditional PKG_CHECK_MODULE +# see http://www.flameeyes.eu/autotools-mythbuster/autoconf/macros.html +# and http://www.flameeyes.eu/autotools-mythbuster/ \ +# pkgconfig/pkg_check_modules.html +PKG_PROG_PKG_CONFIG + # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC @@ -64,23 +70,48 @@ AC_DEFINE([SH_STEXT]) [fi] +AC_ARG_ENABLE([mbaf], + [ --disable-mbaf Turn off mbaf], +[case "${enableval}" in + yes) mbaf=true ;; + no) mbaf=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-mbaf]) ;; +esac],[mbaf=true]) + AC_ARG_WITH([backend], [AS_HELP_STRING([--with-backend=FOO],[Use FOO as display backend (default is 'X')])], [case "${withval}" in - ('X') backend='X' ;; - ('dfb') backend='dfb' ;; - ('no') backend='none' ;; + ('X') backend='X'; default_graphic_engine="cairo" ;; + ('dfb') backend='dfb'; default_graphic_engine="dfb" ;; + ('no') backend='none'; default_graphic_engine="cairo" ;; (*) AC_MSG_ERROR([bad value ${withval} for --with-backend]) ;; - esac],[backend='X']) + esac],[backend='X'; default_graphic_engine="cairo"]) -AC_ARG_ENABLE([skia], - [AS_HELP_STRING([--enable-skia],[Turn on Skia instead of Cairo])], - [case "${enableval}" in - (yes) skia=true ;; - (no) skia=false ;; - (*) AC_MSG_ERROR([bad value ${enableval} for --enable-skia]) ;; - esac],[skia=false]) +AC_ARG_WITH([graphic-engine], + [AS_HELP_STRING([--with-graphic-engine=FOO], + [Use FOO as graphic engine (default is '${default_graphic_engine}')])], + [case "${withval}" in + ('cairo') graphic_engine="cairo" ;; + ('skia') graphic_engine="skia" ;; + ('openvg') graphic_engine="openvg" ;; + ('dfb') graphic_engine="dfb" ;; + (*) AC_MSG_ERROR([bad value ${withval} for --with-graphic-engine]) + ;; + esac], [graphic_engine="${default_graphic_engine}"]) +AC_ARG_WITH([image-loader], + [AS_HELP_STRING([--with-image-loader=FOO], + [Use FOO as image loader (default is 'cairo')])], + [case "${withval}" in + ('cairo') image_loader="cairo" ;; + ('imlib2') image_loader="imlib2" ;; + ('no') image_loader="none" ;; + (*) AC_MSG_ERROR([bad value ${withval} for --with-image-loader]) + ;; + esac], [image_loader="cairo"]) + +xshm=false +[if [ x"${backend}" = x"X" ]; then ] AC_ARG_ENABLE([xshm], [AS_HELP_STRING([--disable-xshm],[Turn off XSHM supporting])], [case "${enableval}" in @@ -88,18 +119,32 @@ (no) xshm=false ;; (*) AC_MSG_ERROR([bad value ${enableval} for --disable-xshm]) ;; esac], [xshm=true]) - -AM_CONDITIONAL([SKIA_GRAPH_ENGINE], [test x$skia = xtrue]) -AM_CONDITIONAL([CAIRO_GRAPH_ENGINE], [test x$skia != xtrue]) +[fi] -[if [ x"${skia}" = xtrue ]; then ] +# Validate options +[case "${backend}-${graphic_engine}-${image_loader}" in + X-cairo-*|X-openvg-imlib2) ;; + dfb-cairo-*) ;; + none-*-*) ;; + *)] AC_MSG_ERROR([The combination of --with-backend=${backend}, --with-graphic-engine=${graphic_engine} and --with-image-loader=${image_loader} is invalid]) [;; +esac] + +[if [ x"${graphic_engine}" = x"skia" ]; then ] AC_DEFINE([SKIA_GRAPH_ENGINE]) - cairo=false +[elif [ x"${graphic_engine}" = x"openvg" ]; then ] + AC_DEFINE([OPENVG_GRAPH_ENGINE]) +[elif [ x"${graphic_engine}" = x"dfb" ]; then ] + AC_DEFINE([DFB_GRAPH_ENGINE]) [else] AC_DEFINE([CAIRO_GRAPH_ENGINE]) - cairo=true [fi] +AM_CONDITIONAL([SKIA_GRAPH_ENGINE], [test x"${graphic_engine}" = x"skia"]) +AM_CONDITIONAL([OPENVG_GRAPH_ENGINE], [test x"${graphic_engine}" = x"openvg"]) +AM_CONDITIONAL([DFB_GRAPH_ENGINE], [test x"${graphic_engine}" = x"dfb"]) +AM_CONDITIONAL([CAIRO_GRAPH_ENGINE], [test x"${graphic_engine}" = x"cairo"]) +AM_CONDITIONAL([MBAF], [test x"$mbaf" = xtrue]) + AC_ARG_ENABLE([nodejs], [AS_HELP_STRING([--enable-nodejs],[Turn on nodejs support])], [case "${enableval}" in @@ -117,35 +162,63 @@ # Define AM and AC variable for sh_text -AM_CONDITIONAL([SH_TEXT], [test x$sh_text = xtrue -a x$cairo = xtrue]) +AM_CONDITIONAL([SH_TEXT], + [test x$sh_text = xtrue -a x"${graphic_engine}" = x"cairo"]) -[if [ x"${sh_text}" = xtrue -a x$cairo = xtrue ]; then] +[if [ x"${sh_text}" = xtrue -a x"${graphic_engine}" = x"cairo" ]; then] AC_DEFINE([SH_TEXT]) [fi] # Define AM and AC variable for display backend -AM_CONDITIONAL([X_BACKEND], [test x$backend = x'X' -a x$cairo = xtrue]) +AM_CONDITIONAL([X_BACKEND], + [test x$backend = x'X']) -[if [ x"${backend}" = x'X' -a x"${cairo}" = xtrue ]; then] +[if [ x"${backend}" = x'X' ]; then] AC_DEFINE([X_BACKEND]) [fi] -AM_CONDITIONAL([DFB_BACKEND], [test x$backend = x'dfb' -a x$cairo = xtrue]) +AM_CONDITIONAL([DFB_BACKEND], + [test x$backend = x'dfb' -a x"${graphic_engine}" = x"cairo"]) -[if [ x"${backend}" = x'dfb' -a x"${cairo}" = xtrue ]; then] +[if [ x"${backend}" = x'dfb' -a x"${graphic_engine}" = x"cairo" ]; then] AC_DEFINE([DFB_BACKEND]) [fi] -AM_CONDITIONAL([XSHM], [test x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X']) +AM_CONDITIONAL([CAIRO_IMG_LOADER], + [test x"${image_loader}" = x"cairo"]) + +[if [ x"${image_loader}" = x"cairo" ]; then] + AC_DEFINE([CAIRO_IMG_LOADER]) + [if [ x"${graphic_engine}" != x"cairo" ]; then] + AC_MSG_ERROR([bad value cairo for --with-image-loader while value of --with-graphic-engine is not cairo]) + [fi] +[fi] -[if [ x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X' ]; then] +AM_CONDITIONAL([IMLIB2_IMG_LOADER], + [test x"${image_loader}" = x"imlib2"]) + +[if [ x"${image_loader}" = x"imlib2" ]; then] + AC_DEFINE([IMLIB2_IMG_LOADER]) +[fi] + +AM_CONDITIONAL([XSHM], + [test x"${xshm}" = xtrue -a x"${graphic_engine}" = x"cairo" -a x$backend = x'X']) + +[if [ x"${xshm}" = xtrue -a x"${graphic_engine}" = x"cairo" -a x$backend = x'X' ]; then] AC_DEFINE([XSHM]) [fi] # Checks for libraries. +[if [ x"${graphic_engine}" = x"openvg" ]; then] +AC_CHECK_HEADERS([EGL/egl.h],, [AC_MSG_ERROR([can not find EGL/egl.h])]) +[fi] -[if [ x"${cairo}" = xtrue ]; then] +[if [ x"${image_loader}" = x"imlib2" ]; then] +PKG_CHECK_MODULES([imlib2], [imlib2 >= 1.4.1], , AC_MSG_ERROR([imlib2 >= 1.4.1 not found])) +[fi] + +[if [ x"${graphic_engine}" = x"cairo" ]; then] PKG_CHECK_MODULES([cairo], [cairo >= 1.6], , AC_MSG_ERROR([cairo >= 1.6 not found])) #PKG_CHECK_MODULES([cairo2], [cairo2 >= 2.0], , AC_MSG_ERROR([cairo2 >= 2.0 not found])) [if [ x"${sh_text}" = xtrue ]; then] @@ -174,7 +247,11 @@ AH_TEMPLATE([SH_TEXT],[Enable sh_text object]) AH_TEMPLATE([SH_STEXT],[Enable sh_stext object]) AH_TEMPLATE([SKIA_GRAPH_ENGINE], [Enable Skia Graphic Engine]) +AH_TEMPLATE([OPENVG_GRAPH_ENGINE], [Enable OpenVG Graphic Engine]) AH_TEMPLATE([CAIRO_GRAPH_ENGINE], [Enable Cairo Graphic Engine]) +AH_TEMPLATE([DFB_GRAPH_ENGINE], [Enable DirectFB Graphic Engine]) +AH_TEMPLATE([CAIRO_IMG_LOADER], [Enable Cairo Image Loader]) +AH_TEMPLATE([IMLIB2_IMG_LOADER], [Enable Imlib2 Image Loader]) AH_TEMPLATE([X_BACKEND], [Enable X backend]) AH_TEMPLATE([DFB_BACKEND], [Enable DirectFB backend]) AH_TEMPLATE([XSHM], [Enable XSHM])
--- a/examples/menu/filebrowser.c Sat Dec 04 07:43:51 2010 +0800 +++ b/examples/menu/filebrowser.c Sat Dec 04 16:58:25 2010 +0800 @@ -51,14 +51,14 @@ if (strcmp(data->titles[select],"..")==0) { strcpy(path, data->curDir); len = strlen(path); - for(i=len-1;i>0;i--) { + for(i=len-2;i>0;i--) { if (path[i] == '/') { path[i] = 0; break; } } } else { - snprintf(path,1024,"%s/%s", data->curDir,data->titles[select]); + snprintf(path,1024,"%s%s", data->curDir,data->titles[select]); } MyApp_fillDirInfo(app, path); @@ -112,7 +112,8 @@ printf("check %s\n",s); - if (endWith(s,".png")) { + if (endWith(s,".png") || endWith(s, ".jpg") || + endWith(s, ".PNG") || endWith(s, ".JPG")) { snprintf(path,1024,"%s%s", data->curDir,data->titles[select]); mypreview(data,path); } @@ -146,6 +147,8 @@ DIR *dir; struct dirent *e; struct fileinfo *f; + char *path; + int sz; int i; dir = opendir(curdir); @@ -156,7 +159,14 @@ if (data->curDir) free(data->curDir); - data->curDir = strdup(curdir); + + sz = strlen(curdir); + if(curdir[sz - 1] != '/') + sz++; + data->curDir = (char *)malloc(sz + 1); + strcpy(data->curDir, curdir); + if(curdir[sz - 1] == '\0') + strcat(data->curDir, "/"); if (data->files) { for(i=0;i<data->nFiles;i++) {
--- a/include/mb_basic_types.h Sat Dec 04 07:43:51 2010 +0800 +++ b/include/mb_basic_types.h Sat Dec 04 16:58:25 2010 +0800 @@ -10,4 +10,15 @@ co_comp_t r, g, b, a; } grad_stop_t; +/*! \brief An rectangle area. + * + * This type is used to describe an rectangle area in an image or on a + * screen. + */ +struct _area { + co_aix x, y; + co_aix w, h; +}; +typedef struct _area area_t; + #endif /* __MB_BASIC_TYPES_H_ */
--- a/include/mb_config.h.in Sat Dec 04 07:43:51 2010 +0800 +++ b/include/mb_config.h.in Sat Dec 04 16:58:25 2010 +0800 @@ -9,6 +9,18 @@ /* Enable Skia Graphic Engine */ #undef SKIA_GRAPH_ENGINE +/* Enable OpenVG Graphic Engine */ +#undef OPENVG_GRAPH_ENGINE + +/* Enable DirectFB Graphic Engine */ +#undef DFB_GRAPH_ENGINE + +/* Enable Cairo Image Loader */ +#undef CAIRO_IMG_LOADER + +/* Enable Imlib2 Image Loader */ +#undef IMLIB2_IMG_LOADER + /* Enable sh_text */ #undef SH_TEXT
--- a/include/mb_graph_engine.h Sat Dec 04 07:43:51 2010 +0800 +++ b/include/mb_graph_engine.h Sat Dec 04 16:58:25 2010 +0800 @@ -1,3 +1,15 @@ +/*! \page create_graph_engine Create a Graphic Engine. + * + * To create a graphic engine, you need to declare and define types + * and functions that had been declared in + * include/mb_graph_engine_cairo.h in a separated header an c file. + * Likes what mb_graph_engine_skia.h does. + * + * You should also add options in configure.ac to enable the graphic + * engine. You also need to add lines in include/mb_config.h.in and + * include/mb_graph_engine.h to include correct header for the graphic + * engine enabled by the user. + */ // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 #ifndef __MBE_H_ @@ -12,4 +24,8 @@ #include <mb_graph_engine_skia.h> #endif +#ifdef OPENVG_GRAPH_ENGINE +#include <mb_graph_engine_openvg.h> +#endif + #endif /* __MBE_H_ */
--- a/include/mb_graph_engine_cairo.h Sat Dec 04 07:43:51 2010 +0800 +++ b/include/mb_graph_engine_cairo.h Sat Dec 04 16:58:25 2010 +0800 @@ -15,7 +15,9 @@ #define MBE_OPERATOR_SOURCE CAIRO_OPERATOR_SOURCE #define MBE_STATUS_SUCCESS CAIRO_STATUS_SUCCESS +/* This function is only used by img_ldr.c */ #define mbe_image_surface_create_from_png cairo_image_surface_create_from_png + #define mbe_pattern_create_for_surface cairo_pattern_create_for_surface #define mbe_scaled_font_text_extents cairo_scaled_font_text_extents #define mbe_image_surface_get_stride cairo_image_surface_get_stride @@ -24,7 +26,7 @@ #define mbe_image_surface_get_width cairo_image_surface_get_width #define mbe_image_surface_get_data cairo_image_surface_get_data #define mbe_scaled_font_reference cairo_scaled_font_reference -#define mbe_xlib_surface_create cairo_xlib_surface_create +#define mbe_win_surface_create cairo_xlib_surface_create #define mbe_scaled_font_destroy cairo_scaled_font_destroy #define mbe_font_face_reference cairo_font_face_reference #define mbe_font_face_destroy cairo_font_face_destroy @@ -39,7 +41,7 @@ #define mbe_get_font_face cairo_get_font_face #define mbe_fill_preserve cairo_fill_preserve #define mbe_set_source cairo_set_source -#define mbe_reset_clip cairo_reset_clip +#define mbe_reset_scissoring cairo_reset_clip #define mbe_get_target cairo_get_target #define mbe_close_path cairo_close_path #define mbe_text_path cairo_text_path @@ -57,7 +59,7 @@ #define mbe_paint cairo_paint #define mbe_save cairo_save #define mbe_fill cairo_fill -#define mbe_clip cairo_clip +#define mbe_init() typedef cairo_text_extents_t mbe_text_extents_t; typedef cairo_scaled_font_t mbe_scaled_font_t; @@ -89,6 +91,8 @@ co_aix x1, co_aix y1, grad_stop_t *stops, int stop_cnt); +extern mbe_pattern_t *mbe_pattern_create_image(mb_img_data_t *img); +extern void mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas); static void mbe_pattern_set_matrix(mbe_pattern_t *ptn,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_graph_engine_dummy.h Sat Dec 04 16:58:25 2010 +0800 @@ -0,0 +1,99 @@ +/* This is a dummy Graphic Engine to consume all graphic operators. + */ +#ifndef __MB_GE_OPENVG_H_ +#define __MB_GE_OPENVG_H_ + +#include <stdio.h> +#include <GL/glut.h> +#include "mb_basic_types.h" +#include "mb_img_ldr.h" + +/*! \defgroup mb_ge_dummy Dummy Implementation of MadButterfly Graphic Engine + * @{ + */ +#define mbe_pattern_create_for_surface(surface) ((mbe_pattern_t *)NULL) +#define mbe_scaled_font_text_extents(scaled, utf8, extents) +#define mbe_image_surface_get_stride(surface) (20) +#define mbe_image_surface_get_format(surface) ((mb_img_fmt_t)0) +#define mbe_image_surface_get_height(surface) (1) +#define mbe_image_surface_get_width(surface) (1) +#define mbe_image_surface_get_data(surface) ((unsigned char *)NULL) +#define mbe_scaled_font_reference(scaled) ((mbe_scaled_font_t *)NULL) +/* For OpenVG backend, never invoke xlib surface. + * #define mbe_xlib_surface_create cairo_xlib_surface_create + */ +#define mbe_pattern_create_radial(cx0, cy0, radius0, \ + cx1, cy1, radius1, stops, stop_cnt) \ + ((mbe_pattern_t *)NULL) +#define mbe_pattern_create_linear(x0, y0, x1, y1, stops, stop_cnt) \ + ((mbe_pattern_t *)NULL) +#define mbe_pattern_create_image(img) ((mbe_pattern_t *)NULL) +#define mbe_image_surface_create(fmt, w, h) ((mbe_surface_t *)NULL) +#define mbe_scaled_font_destroy(scaled) +#define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL) +#define mbe_scaled_font_create(face, fnt_mtx, ctm) ((mbe_scaled_font_t *)NULL) +#define mbe_pattern_set_matrix(ptn, mtx) +#define mbe_font_face_destroy(face) +#define mbe_paint_with_alpha(canvas, alpha) +#define mbe_surface_destroy(surface) +#define mbe_set_source_rgba(canvas, r, g, b, a) +#define mbe_set_scaled_font(canvas, scaled) +#define mbe_pattern_destroy(pattern) +#define mbe_get_scaled_font(canvas) ((mbe_scaled_font_t *)NULL) +#define mbe_query_font_face(family, slant, weight) ((mbe_font_face_t *)NULL) +#define mbe_free_font_face(face) +#define mbe_set_line_width(canvas, w) +#define mbe_set_source_rgb(canvas, r, g, b) +#define mbe_get_font_face(canvas) ((mbe_font_face_t *)NULL) +#define mbe_fill_preserve(canvas) +#define mbe_copy_source(src_canvas, dst_canvas) +#define mbe_set_source(canvas, pattern) +#define mbe_reset_scissoring(canvas) +#define mbe_get_target(canvas) ((mbe_surface_t *)NULL) +#define mbe_close_path(canvas) +#define mbe_text_path(canvas, utf8) +#define mbe_transform(canvas, mtx) +#define mbe_rectangle(canvas, x, y, w, h) +#define mbe_in_stroke(canvas, x, y) (0) +#define mbe_new_path(canvas) +#define mbe_curve_to(canvas, x1, y1, x2, y2, x3, y3) +#define mbe_restore(canvas) +#define mbe_move_to(canvas, x, y) +#define mbe_line_to(canvas, x, y) +#define mbe_in_fill(canvas, x, y) (0) +#define mbe_destroy(canvas) +#define mbe_stroke(canvas) +#define mbe_create(surface) ((mbe_t *)NULL) +#define mbe_clear(canvas) +#define mbe_paint(canvas) +#define mbe_save(canvas) +#define mbe_fill(canvas) +/*! \brief Make scissoring rectangles. + * + * It would reset all previous pathes. + */ +#define mbe_scissoring(canvas, n_areas, areas) +#define mbe_arc(canvas, x, y, radius, angle_start, angle_stop) + +/*! \brief Initialize graphic engine */ +#define mbe_init() + +typedef struct _mbe_text_extents_t mbe_text_extents_t; +typedef int mbe_scaled_font_t; +typedef int mbe_font_face_t; +typedef int mbe_surface_t; +typedef int mbe_pattern_t; +typedef int mbe_t; + +struct _mbe_text_extents_t { + co_aix x_bearing; + co_aix y_bearing; + co_aix width; + co_aix height; + co_aix x_advance; + co_aix y_advance; +}; + +/* @} */ + +#endif /* __MB_GE_OPENVG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_graph_engine_openvg.h Sat Dec 04 16:58:25 2010 +0800 @@ -0,0 +1,263 @@ +#ifndef __MB_GE_OPENVG_H_ +#define __MB_GE_OPENVG_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <EGL/egl.h> +#include <VG/openvg.h> +#include "mb_basic_types.h" +#include "mb_img_ldr.h" + +/*! \defgroup mb_ge_openvg MadButterfly Graphic Engine with OpenVG + * @{ + */ +#define mbe_scaled_font_text_extents(scaled, utf8, extents) +#define mbe_image_surface_get_stride(surface) (20) +#define mbe_image_surface_get_format(surface) ((mb_img_fmt_t)0) +#define mbe_image_surface_get_height(surface) (surface)->h +#define mbe_image_surface_get_width(surface) (surface)->w +#define mbe_image_surface_get_data(surface) ((unsigned char *)NULL) +#define mbe_scaled_font_reference(scaled) ((mbe_scaled_font_t *)NULL) +#define mbe_scaled_font_destroy(scaled) +#define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL) +#define mbe_scaled_font_create(face, fnt_mtx, ctm) ((mbe_scaled_font_t *)NULL) +#define mbe_font_face_destroy(face) +#define mbe_set_scaled_font(canvas, scaled) +#define mbe_get_scaled_font(canvas) ((mbe_scaled_font_t *)NULL) +#define mbe_query_font_face(family, slant, weight) ((mbe_font_face_t *)NULL) +#define mbe_free_font_face(face) +#define mbe_set_line_width(canvas, w) \ + do { \ + _MK_CURRENT_CTX(canvas); \ + vgSetf(VG_STROKE_LINE_WIDTH, w); \ + } while(0) +#define mbe_set_source_rgb(canvas, r, g, b) \ + mbe_set_source_rgba(canvas, r, g, b, 1) +#define mbe_get_font_face(canvas) ((mbe_font_face_t *)NULL) +#define mbe_set_source(canvas, pattern) \ + do { \ + (canvas)->src = (pattern); \ + (canvas)->paint = (pattern)->paint; \ + (canvas)->paint_installed = 0; \ + } while(0) +#define mbe_reset_scissoring(canvas) \ + do { \ + _MK_CURRENT_CTX(canvas); \ + vgSeti(VG_SCISSORING, VG_FALSE); \ + } while(0) +#define mbe_get_target(canvas) ((mbe_surface_t *)(canvas)->tgt) +#define mbe_close_path(canvas) \ + do { \ + char _vg_cmd = VG_CLOSE_PATH; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, NULL); \ + } while(0) +#define mbe_text_path(canvas, utf8) +#define mbe_rectangle(canvas, x, y, w, h) +#define mbe_in_stroke(canvas, x, y) (0) +#define mbe_new_path(canvas) \ + vgClearPath((canvas)->path, VG_PATH_CAPABILITY_ALL) +#define mbe_curve_to(canvas, x1, y1, x2, y2, x3, y3) \ + do { \ + VGfloat _vg_data[6] = {x1, y1, x2, y2, x3, y3}; \ + char _vg_cmd = VG_CUBIC_TO_ABS; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, _vg_data); \ + } while(0) +#define mbe_move_to(canvas, x, y) \ + do { \ + VGfloat _vg_data[2] = {x, y}; \ + char _vg_cmd = VG_MOVE_TO_ABS; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, _vg_data); \ + } while(0) +#define mbe_line_to(canvas, x, y) \ + do { \ + VGfloat _vg_data[2] = {x, y}; \ + char _vg_cmd = VG_LINE_TO_ABS; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, _vg_data); \ + } while(0) +#define mbe_in_fill(canvas, x, y) (1) +/* TODO: change prototype of mbe_arc() to remove mbe_save() and + * mbe_restore(). + */ +#define mbe_save(canvas) +#define mbe_restore(canvas) +#define mbe_arc(canvas, x, y, radius, angle_start, angle_stop) + +typedef struct _mbe_text_extents_t mbe_text_extents_t; +typedef int mbe_scaled_font_t; +typedef int mbe_font_face_t; +typedef struct _ge_openvg_surface mbe_surface_t; +typedef struct _ge_openvg_pattern mbe_pattern_t; +typedef struct _ge_openvg_mbe mbe_t; +typedef struct _ge_openvg_img _ge_openvg_img_t; + +struct _mbe_text_extents_t { + co_aix x_bearing; + co_aix y_bearing; + co_aix width; + co_aix height; + co_aix x_advance; + co_aix y_advance; +}; + +struct _ge_openvg_mbe { + mbe_pattern_t *src; + VGPaint paint; /*!< \brief The paint associated with + * the src pattern */ + int paint_installed; + mbe_surface_t *tgt; + EGLContext ctx; + VGPath path; + + VGfloat mtx[9]; +}; + +struct _ge_openvg_surface { + void *surface; + mbe_t *asso_mbe; /* There is a association between + * surface and mbe */ + _ge_openvg_img_t *asso_img; + int w, h; + mb_img_fmt_t fmt; +}; + +struct _ge_openvg_pattern { + _ge_openvg_img_t *asso_img; + VGfloat mtx[9]; + VGPaint paint; +}; + +#define MB_MATRIX_2_OPENVG(vgmtx, mtx) do { \ + (vgmtx)[0] = (mtx)[0]; \ + (vgmtx)[1] = (mtx)[1]; \ + (vgmtx)[2] = (mtx)[2]; \ + (vgmtx)[3] = (mtx)[3]; \ + (vgmtx)[4] = (mtx)[4]; \ + (vgmtx)[5] = (mtx)[5]; \ + (vgmtx)[6] = 0; \ + (vgmtx)[7] = 0; \ + (vgmtx)[8] = 1; \ + } while(0) + +extern EGLNativeDisplayType _ge_openvg_disp_id; +extern mbe_t *_ge_openvg_current_canvas; +extern void _mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode); +extern void _ge_vg_img_activate_for_pattern(mbe_pattern_t *ptn); +extern void _ge_vg_img_activate_for_surface(mbe_surface_t *surf); + +extern mbe_pattern_t *mbe_pattern_create_for_surface(mbe_surface_t *surface); +extern mbe_pattern_t *mbe_pattern_create_radial(co_aix cx0, co_aix cy0, + co_aix radius0, + co_aix cx1, co_aix cy1, + co_aix radius1, + grad_stop_t *stops, + int stop_cnt); +extern mbe_pattern_t *mbe_pattern_create_linear(co_aix x0, co_aix y0, + co_aix x1, co_aix y1, + grad_stop_t *stops, + int stop_cnt); +extern mbe_pattern_t *mbe_pattern_create_image(mb_img_data_t *img); +extern void mbe_pattern_destroy(mbe_pattern_t *ptn); +extern void mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx); +extern void mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, + co_comp_t b, co_comp_t a); +/* TODO: rename n_areas to areas_cnt and make it after areas */ +extern void mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas); + + +#define _VG_DISPLAY() eglGetDisplay(_ge_openvg_disp_id) + +/* \brief Make the context of a canvas to be current context. + * + * TODO: swtich VGImage between VGPaint and Surface. + */ +#define _MK_CURRENT_CTX(canvas) do { \ + if(_ge_openvg_current_canvas != (canvas)) { \ + _ge_openvg_current_canvas = canvas; \ + eglMakeCurrent(_VG_DISPLAY(), \ + (canvas)->tgt->surface, \ + (canvas)->tgt->surface, \ + (canvas)->ctx); \ + } \ + /* \sa _ge_openvg_img_t */ \ + _ge_vg_img_activate_for_surface((canvas)->tgt); \ + } while(0) +/* TODO: switch VGImage between VGPaint and surface. */ +#define _MK_CURRENT_PAINT(canvas) \ + do { \ + if((canvas)->paint_installed == 0) { \ + vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH); \ + (canvas)->paint_installed = 1; \ + } \ + /* \sa _ge_openvg_img_t */ \ + if((canvas)->src) \ + _ge_vg_img_activate_for_pattern((canvas)->src); \ + } while(0) + +#define mbe_transform(canvas, _mtx) \ + do { \ + _MK_CURRENT_CTX(canvas); \ + MB_MATRIX_2_OPENVG((canvas)->mtx, _mtx); \ + _mbe_load_pattern_mtx(_mtx, NULL, \ + VG_MATRIX_PATH_USER_TO_SURFACE); \ + } while(0) + + +#define EGL_GLX 1 +#ifdef EGL_GLX +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +extern mbe_surface_t *mbe_win_surface_create(Display *display, + Drawable drawable, + Visual *visual, + int width, int height); +#endif + +extern mbe_surface_t *mbe_image_surface_create(mb_img_fmt_t fmt, + int w, int h); +extern mbe_surface_t * +mbe_image_surface_create_for_data(unsigned char *data, + mb_img_fmt_t fmt, + int width, int height, + int stride); +extern void mbe_surface_destroy(mbe_surface_t *surface); + +extern void mbe_copy_source(mbe_t *src_canvas, mbe_t *dst_canvas); +extern mbe_t *mbe_create(mbe_surface_t *surface); +extern void mbe_destroy(mbe_t *canvas); +extern void mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha); +extern void mbe_paint(mbe_t *canvas); +extern void mbe_clear(mbe_t *canvas); +extern void mbe_init(); + +static void +mbe_stroke(mbe_t *canvas) { + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_STROKE_PAINT_TO_USER); + + vgDrawPath(canvas->path, VG_STROKE_PATH); + vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL); +} + +static void +mbe_fill_preserve(mbe_t *canvas) { + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); + + vgDrawPath(canvas->path, VG_FILL_PATH); +} + +static void +mbe_fill(mbe_t *canvas) { + mbe_fill_preserve(canvas); + vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL); +} +/* @} */ + +#endif /* __MB_GE_OPENVG_H_ */
--- a/include/mb_types.h Sat Dec 04 07:43:51 2010 +0800 +++ b/include/mb_types.h Sat Dec 04 16:58:25 2010 +0800 @@ -10,7 +10,6 @@ typedef struct _shape shape_t; typedef struct _geo geo_t; -typedef struct _area area_t; typedef struct _shnode shnode_t; typedef struct _paint paint_t; typedef struct _mb_obj mb_obj_t; @@ -103,11 +102,6 @@ shnode_t *next; }; -struct _area { - co_aix x, y; - co_aix w, h; -}; - /*! \brief Geometry data of a shape or a group of shape. */ struct _geo {
--- a/nodejs/Makefile.am Sat Dec 04 07:43:51 2010 +0800 +++ b/nodejs/Makefile.am Sat Dec 04 16:58:25 2010 +0800 @@ -6,8 +6,14 @@ mbfly_node_CFLAGS= -I$(abs_top_builddir)/include \ -I$(abs_top_srcdir)/include \ -I$(prefix)/include \ - @pangocairo_CFLAGS@ $(CFLAGS) -mbfly_node_LDFLAGS = -L$(abs_top_builddir)/src/.libs @pangocairo_LIBS@ + @imlib2_CFLAGS@ \ + @pangocairo_CFLAGS@ $(CFLAGS) $(CPPFLAGS) +mbfly_node_LDFLAGS = -L$(abs_top_builddir)/src/.libs @pangocairo_LIBS@ \ + @imlib2_LIBS@ $(LDFLAGS) + +if OPENVG_GRAPH_ENGINE +mbfly_node_LDFLAGS += -lOpenVG +endif if XSHM mbfly_node_LDFLAGS += -lXext
--- a/nodejs/run.sh Sat Dec 04 07:43:51 2010 +0800 +++ b/nodejs/run.sh Sat Dec 04 16:58:25 2010 +0800 @@ -1,11 +1,25 @@ #!/bin/sh ABS=`realpath $0` -BASE=`dirname $ABS` -NODE_PATH=$BASE:$BASE/objs/default:$NODE_PATH +if [ -z "$SRCDIR" ]; then + SRCDIR=`dirname $ABS`/.. +fi +if [ -z "$BUILDDIR" ]; then + BUILDDIR=`dirname $ABS`/.. +fi + +NODE_PATH=${BUILDDIR}/nodejs/objs/default:${SRCDIR}/nodejs:$NODE_PATH export NODE_PATH +LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${BUILDDIR}/src/.libs/ +export LD_LIBRARY_PATH + DIR=`dirname $1` FNAME=`basename $1` -cd $DIR; node $FNAME +if [ -z "$DEBUG" ]; then + cd $DIR; node $FNAME +else + # DEBUG + cd $DIR; gdb -args node $FNAME +fi
--- a/nodejs/wscript Sat Dec 04 07:43:51 2010 +0800 +++ b/nodejs/wscript Sat Dec 04 16:58:25 2010 +0800 @@ -32,7 +32,7 @@ obj.source = 'font.cc image_ldr.cc' obj.add_objects = 'njs_mb_supp.o observer.o coord.o mbfly_njs.o ' + \ 'shapes.o paints.o' - obj.staticlib = 'mbfly' + obj.lib = 'mbfly' for src in 'observer.cc coord.cc mbfly_njs.cc shapes.cc paints.cc'.split(): obj = conf.new_task_gen('cxx', 'shlib', 'node_addon')
--- a/src/Makefile.am Sat Dec 04 07:43:51 2010 +0800 +++ b/src/Makefile.am Sat Dec 04 16:58:25 2010 +0800 @@ -14,7 +14,7 @@ noinst_PROGRAMS += testcase endif -if X_BACKEND +if MBAF MBAF_SOURCES=mbaf/mbapp.c mbaf/mbbutton.c mbaf/mbobject.c mbaf/animated_menu.c else MBAF_SOURCES= @@ -24,7 +24,10 @@ observer.c paint.c redraw_man.c rotate.c shape_path.c \ shape_rect.c shift.c subtree_free.c timer.c \ timertool.c tools.c visibility.c prop.c sprite.c \ - mouse.c shape_image.c img_ldr.c $(MBAF_SOURCES) + mouse.c shape_image.c $(MBAF_SOURCES) + +libmbfly_la_CPPFLAGS = +libmbfly_la_LDFLAGS = if SH_TEXT libmbfly_la_SOURCES += shape_text.c @@ -42,12 +45,21 @@ libmbfly_la_SOURCES += dfb_supp.c endif -libmbfly_la_LDFLAGS = +if CAIRO_IMG_LOADER +libmbfly_la_SOURCES += img_ldr.c +endif + +if IMLIB2_IMG_LOADER +libmbfly_la_SOURCES += img_ldr_imlib2.c + +libmbfly_la_CPPFLAGS += @imlib2_CFLAGS@ +libmbfly_la_LDFLAGS += @imlib2_LIBS@ +endif if CAIRO_GRAPH_ENGINE libmbfly_la_SOURCES += graph_engine_cairo.c -libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ @pangocairo_CFLAGS@ +libmbfly_la_CPPFLAGS += @cairo_CFLAGS@ @pangocairo_CFLAGS@ libmbfly_la_LDFLAGS += @cairo_LIBS@ @pangocairo_LIBS@ endif @@ -59,6 +71,15 @@ libmbfly_la_SOURCES += graph_engine_skia.cpp endif +if DFB_GRAPH_ENGINE +libmbfly_la_SOURCES += graph_engine_dfb.c +endif + +if OPENVG_GRAPH_ENGINE +libmbfly_la_SOURCES += graph_engine_openvg.c +libmbfly_la_LDFLAGS += -lOpenVG +endif + X_main_SOURCES = X_main.c X_main_LDADD = $(top_builddir)/src/libmbfly.la X_main_CPPFLAGS = @pangocairo_CFLAGS@ -I$(top_builddir)/include
--- a/src/X_main.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/X_main.c Sat Dec 04 16:58:25 2010 +0800 @@ -467,9 +467,9 @@ CWOverrideRedirect, &wattr); r = XMapWindow(display, win); - surface = mbe_xlib_surface_create(display, win, visual, w, h); + surface = mbe_win_surface_create(display, win, visual, w, h); if(surface == NULL) - printf("mbe_xlib_surface_create\n"); + printf("mbe_win_surface_create\n"); drawing(surface, w, h);
--- a/src/X_supp.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/X_supp.c Sat Dec 04 16:58:25 2010 +0800 @@ -5,7 +5,6 @@ #include <string.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <cairo-xlib.h> #include "mb_graph_engine.h" #include "mb_redraw_man.h" #include "mb_timer.h" @@ -49,7 +48,6 @@ Window win; Visual *visual; mbe_surface_t *surface, *backend_surface; - mbe_pattern_t *surface_ptn; mbe_t *cr, *backend_cr; redraw_man_t *rdman; mb_img_ldr_t *img_ldr; @@ -781,30 +779,29 @@ #ifdef XSHM xshm_init(xmb_rt); #endif - + + mbe_init(); + xmb_rt->surface = mbe_image_surface_create(MB_IFMT_ARGB32, w, h); - xmb_rt->surface_ptn = - mbe_pattern_create_for_surface(xmb_rt->surface); - if(xmb_rt->backend_surface == NULL) /* xshm_init() may create one */ xmb_rt->backend_surface = - mbe_xlib_surface_create(xmb_rt->display, - xmb_rt->win, - xmb_rt->visual, - w, h); + mbe_win_surface_create(xmb_rt->display, + xmb_rt->win, + xmb_rt->visual, + w, h); xmb_rt->cr = mbe_create(xmb_rt->surface); xmb_rt->backend_cr = mbe_create(xmb_rt->backend_surface); - - mbe_set_source(xmb_rt->backend_cr, xmb_rt->surface_ptn); - + xmb_rt->rdman = (redraw_man_t *)malloc(sizeof(redraw_man_t)); redraw_man_init(xmb_rt->rdman, xmb_rt->cr, xmb_rt->backend_cr); - // FIXME: This is a wired loopback reference. This is inly required when we need - // to get the xmb_rt->tman for the animation. We should relocate the tman - // to the redraw_man_t instead. + /* FIXME: This is a wired loopback reference. This is inly + * required when we need to get the xmb_rt->tman for the + * animation. We should relocate the tman to the + * redraw_man_t instead. + */ xmb_rt->rdman->rt = xmb_rt; xmb_rt->io_man = mb_io_man_new(_io_factory); @@ -905,8 +902,6 @@ if(xmb_rt->surface) mbe_surface_destroy(xmb_rt->surface); - if(xmb_rt->surface_ptn) - mbe_pattern_destroy(xmb_rt->surface_ptn); if(xmb_rt->backend_surface) mbe_surface_destroy(xmb_rt->backend_surface);
--- a/src/event.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/event.c Sat Dec 04 16:58:25 2010 +0800 @@ -697,6 +697,11 @@ static void _draw_to_mask(shape_t *shape, mbe_t *cr) { + /* TODO: Find a new algorithm to check if a point is in the area + * covered by a shape. This function is expected to work with + * _fill_and_check() to detect a collision. + */ +#if 0 if(sh_get_flags(shape, GEF_OV_DRAW)) return; @@ -704,10 +709,12 @@ mbe_clip(cr); sh_set_flags(shape, GEF_OV_DRAW); +#endif } static int _fill_and_check(shape_t *shape, mbe_t *cr) { +#if 0 int h, stride; mbe_surface_t *surface; unsigned char *data; @@ -729,6 +736,9 @@ } return FALSE; +#else + return TRUE; +#endif } /*! \brief Is a mb_obj_t overlaid with another mb_obj_t and
--- a/src/graph_engine_cairo.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/graph_engine_cairo.c Sat Dec 04 16:58:25 2010 +0800 @@ -150,3 +150,57 @@ return ptn; } + +mbe_pattern_t * +mbe_pattern_create_image(mb_img_data_t *img) { + cairo_surface_t *surf; + cairo_pattern_t *ptn; + cairo_format_t fmt; + + switch(img->fmt) { + case MB_IFMT_ARGB32: + fmt = CAIRO_FORMAT_ARGB32; + break; + + case MB_IFMT_RGB24: + fmt = CAIRO_FORMAT_RGB24; + break; + + case MB_IFMT_A8: + fmt = CAIRO_FORMAT_A8; + break; + + case MB_IFMT_A1: + fmt = CAIRO_FORMAT_A1; + break; + + case MB_IFMT_RGB16_565: + fmt = CAIRO_FORMAT_RGB16_565; + break; + + default: + return NULL; + } + + surf = cairo_image_surface_create_for_data(img->content, fmt, + img->w, img->h, img->stride); + ptn = cairo_pattern_create_for_surface(surf); + cairo_surface_destroy(surf); + + return ptn; +} + +void +mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas) { + area_t *area; + int i; + + cairo_new_path(canvas); + + for(i = 0; i < n_areas; i++) { + area = areas[i]; + cairo_rectangle(canvas, area->x, area->y, area->w, area->h); + } + + cairo_clip(canvas); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/graph_engine_dfb.c Sat Dec 04 16:58:25 2010 +0800 @@ -0,0 +1,1 @@ +/* Keep Me */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/graph_engine_openvg.c Sat Dec 04 16:58:25 2010 +0800 @@ -0,0 +1,912 @@ +#include "mb_graph_engine_openvg.h" +#include "mb_tools.h" + +EGLNativeDisplayType _ge_openvg_disp_id = EGL_DEFAULT_DISPLAY; +mbe_t *_ge_openvg_current_canvas = NULL; + +#ifndef ASSERT +#define ASSERT(x) +#endif + +#ifndef ERR +#include <stdio.h> +#include <stdlib.h> +#define ERR(msg) do { fprintf(stderr, __FILE__ ":%d: %s", __LINE__, msg); abort(); } while(0) +#endif +#ifndef NOT_IMPLEMENT +#define NOT_IMPLEMENT(func) \ + ERR(func " is not impmemented\n") +#endif + +#define MK_ID(mtx) \ + do { \ + (mtx)[0] = 1; \ + (mtx)[1] = 0; \ + (mtx)[2] = 0; \ + (mtx)[3] = 0; \ + (mtx)[4] = 1; \ + (mtx)[5] = 0; \ + (mtx)[6] = 0; \ + (mtx)[7] = 0; \ + (mtx)[8] = 1; \ + } while(0) + +#define VG_MBE_SURFACE(mbe) ((mbe)->tgt->surface) + +/*! \brief Information associated with VGImage. + * + * A VGImage can associated one of pattern or surface. This type is + * used to make sure previous associated pattern or surface being + * released before new association. + * + * A _ge_openvg_img can be associated by mutltiple patterns and + * surfaces. But, at most one of associated patterns or surfaces, the + * _ge_openvg_img can be activated for at any instant. + * _ge_openvg_img::activated_for trace the object it being activated + * for. When a context will be current, the _ge_openvg_img associated + * with its surface would be activated for the surface. When a paint + * wil be used, the _ge_openvg_img associated must be activated for + * the paint. Before activated, the old activation must be + * deactivated. _ge_openvg_img::deactivate_func is a pointer to + * deactivation function of activated pattern or surface. + * + * \sa _ge_openvg_img_t + * \note This is type is for internal using of OpenVG graphic engine. + */ +struct _ge_openvg_img { + int ref; + VGImage img; + void *activated_for; + void (*deactivate_func)(void *obj); +}; + +#define SURFACE_VG_IMG(surface) ((surface)->tgt->asso_img->img) + +static EGLContext init_ctx; + +/*! \brief Convert mb_img_fmt_t to VGImageFormat */ +static VGImageFormat +_mb_ifmt_2_vgifmt(mb_img_fmt_t fmt) { + VGImageFormat vgifmt; + + switch(fmt) { + case MB_IFMT_ARGB32: + vgifmt = VG_sARGB_8888; + break; + + case MB_IFMT_RGB24: + vgifmt = -1; + break; + + case MB_IFMT_A8: + vgifmt = VG_A_8; + break; + + case MB_IFMT_A1: + vgifmt = -1; + break; + + case MB_IFMT_RGB16_565: + vgifmt = VG_sRGB_565; + break; + + default: + return -1; + } + + return vgifmt; +} + +/*! \brief create image object for OpenVG */ +static _ge_openvg_img_t * +_alloc_vgimage(mb_img_fmt_t fmt, int w, int h) { + VGImage vg_img; + VGImageFormat vgifmt; + _ge_openvg_img_t *ge_img; + + vgifmt = _mb_ifmt_2_vgifmt(fmt); + if(vgifmt == -1) + return NULL; + vg_img = vgCreateImage(vgifmt, w, h, + VG_IMAGE_QUALITY_NONANTIALIASED); + if(vg_img == VG_INVALID_HANDLE) + return NULL; + ge_img = O_ALLOC(_ge_openvg_img_t); + if(ge_img == NULL) { + vgDestroyImage(vg_img); + return NULL; + } + ge_img->ref = 1; + ge_img->img = vg_img; + ge_img->activated_for = NULL; + ge_img->deactivate_func = NULL; + + return ge_img; +} + +/*! \brief Free image object for OpenVG */ +static void +_free_vgimage(_ge_openvg_img_t *ge_img) { + if(--ge_img->ref > 0) { + if(ge_img->activated_for) { + ge_img->deactivate_func(ge_img->activated_for); + ge_img->activated_for = NULL; + } + return; + } + + vgDestroyImage(ge_img->img); + free(ge_img); +} + +static void +_ge_vg_img_deactivate_for_pattern(void *obj) { + mbe_pattern_t *ptn = (mbe_pattern_t *)obj; + VGPaint vg_paint; + + vg_paint = ptn->paint; + vgPaintPattern(vg_paint, VG_INVALID_HANDLE); +} + +/*! \brief Activate a VGImage for a pattern paint. + * + * \sa _ge_openvg_img + */ +void +_ge_vg_img_activate_for_pattern(mbe_pattern_t *ptn) { + _ge_openvg_img_t *ge_img; + VGPaint vg_paint; + VGImage vg_img; + + ge_img = ptn->asso_img; + if(ge_img == NULL) + return; + + if(ge_img->activated_for == (void *)ptn) + return; + + if(ge_img->activated_for) + ge_img->deactivate_func(ge_img->activated_for); + + ge_img->activated_for = ptn; + ge_img->deactivate_func = _ge_vg_img_deactivate_for_pattern; + + vg_img = ge_img->img; + vg_paint = ptn->paint; + + vgPaintPattern(vg_paint, vg_img); +} + +/*! \brief Deactivate a VGImage for a VGSurface. + * + * A VGImage can not deatached from VGSurface. But, it is not clear + * in the document of EGL. We assume that a VGImage can be used as + * pattern of a paint, once associated surface is not current + * rendering context. + */ +static void +_ge_vg_img_deactivate_for_surface(void *obj) { + /* NOT_IMPLEMENT("_ge_vg_img_deactivate_for_surface"); */ +} + +/*! \brief Activate a VGImage for a surface + * + * \sa _ge_openvg_img + */ +void +_ge_vg_img_activate_for_surface(mbe_surface_t *surf) { + _ge_openvg_img_t *ge_img; + + ge_img = surf->asso_img; + if(ge_img == NULL) + return; + + if(ge_img->activated_for == (void *)surf) + return; + + if(ge_img->activated_for) + ge_img->deactivate_func(ge_img->activated_for); + + ge_img->activated_for = surf; + ge_img->deactivate_func = _ge_vg_img_deactivate_for_surface; +} + +/* + * This implementation supports only from image surface. + */ +mbe_pattern_t * +mbe_pattern_create_for_surface(mbe_surface_t *surface) { + mbe_pattern_t *pattern; + _ge_openvg_img_t *ge_img; + VGfloat *mtx; + VGPaint paint; + + /* Support only from image surface */ + if(surface->asso_img == NULL) + return NULL; + + paint = vgCreatePaint(); + if(paint == VG_INVALID_HANDLE) + return NULL; + + ge_img = surface->asso_img; + pattern = O_ALLOC(mbe_pattern_t); + pattern->asso_img = ge_img; + ge_img->ref++; /* increase reference count */ + pattern->paint = paint; + + mtx = pattern->mtx; + MK_ID(mtx); + + return pattern; +} + +void +_mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode) { + VGfloat affine; + + vgSeti(VG_MATRIX_MODE, mode); + vgLoadMatrix(mtx1); + if(mtx2) + vgMultMatrix(mtx2); +} + +static mbe_pattern_t * +_mbe_pattern_create_gradient(VGfloat *gradient, int grad_len, + int grad_type, + grad_stop_t *stops, int stop_cnt) { + VGPaint paint; + mbe_pattern_t *pattern; + static VGfloat *ov_stops = 0; + static int max_stop_cnt = 0; + VGfloat *cur_ov_stop; + grad_stop_t *cur_stop; + int i; + + /* Make sure there is enough space */ + if(max_stop_cnt < stop_cnt) { + max_stop_cnt = (stop_cnt + 0xf) & ~0xf; + cur_ov_stop = (VGfloat *)realloc(ov_stops, + max_stop_cnt * sizeof(VGfloat) * 5); + if(cur_ov_stop == NULL) { + max_stop_cnt = 0; + return NULL; + } + ov_stops = cur_ov_stop; + } + cur_ov_stop = ov_stops; + + cur_stop = stops; + for(i = 0; i < stop_cnt; i++) { + *cur_ov_stop++ = cur_stop->offset; + *cur_ov_stop++ = cur_stop->r; + *cur_ov_stop++ = cur_stop->g; + *cur_ov_stop++ = cur_stop->b; + *cur_ov_stop++ = cur_stop->a; + cur_stop++; + } + + paint = vgCreatePaint(); + if(paint == VG_INVALID_HANDLE) + return NULL; + vgSetParameteri(paint, VG_PAINT_TYPE, grad_type); + vgSetParameterfv(paint, VG_PAINT_RADIAL_GRADIENT, grad_len, gradient); + vgSetParameterfv(paint, VG_PAINT_COLOR_RAMP_STOPS, 5 * stop_cnt, ov_stops); + + pattern = O_ALLOC(mbe_pattern_t); + if(pattern == NULL) { + vgDestroyPaint(paint); + return NULL; + } + + pattern->paint = paint; + pattern->asso_img = NULL; + + MK_ID(pattern->mtx); + + return pattern; +} + +/* + * \note OpenVG does not support start circle, it supports only focal + * point. It means radius0 is not working. + */ +mbe_pattern_t * +mbe_pattern_create_radial(co_aix cx0, co_aix cy0, + co_aix radius0, + co_aix cx1, co_aix cy1, + co_aix radius1, grad_stop_t *stops, + int stop_cnt) { + mbe_pattern_t *pattern; + VGfloat gradient[] = {cx0, cy0, cx1, cy1, radius1}; + + pattern = _mbe_pattern_create_gradient(gradient, 5, + VG_PAINT_TYPE_RADIAL_GRADIENT, + stops, stop_cnt); + return pattern; +} + +mbe_pattern_t * +mbe_pattern_create_linear(co_aix x0, co_aix y0, + co_aix x1, co_aix y1, + grad_stop_t *stops, int stop_cnt) { + mbe_pattern_t *pattern; + VGfloat gradient[] = {x0, y0, x1, y1}; + + pattern = _mbe_pattern_create_gradient(gradient, 4, + VG_PAINT_TYPE_LINEAR_GRADIENT, + stops, stop_cnt); + return pattern; +} + +mbe_pattern_t * +mbe_pattern_create_image(mb_img_data_t *img) { + VGPaint paint; + mbe_pattern_t *pattern; + _ge_openvg_img_t *ge_img; + VGImage vg_img; + VGImageFormat fmt = VG_sARGB_8888; + + /* \note OpenVG implementation supports one \ref MB_IFMT_ARGB32 + * image. + */ + if(img->fmt != MB_IFMT_ARGB32) + return NULL; + + /* Allocate objects */ + ge_img = _alloc_vgimage(MB_IFMT_ARGB32, img->w, img->h); + pattern = O_ALLOC(mbe_pattern_t); + paint = vgCreatePaint(); + if(ge_img == NULL || pattern == NULL || paint == VG_INVALID_HANDLE) + goto err; + + /* Create and copy pixels into VGImage */ + vg_img = ge_img->img; + vgImageSubData(vg_img, img->content, img->stride, fmt, + 0, 0, img->w, img->h); + + pattern->paint = paint; + pattern->asso_img = ge_img; + + return pattern; + + err: + if(ge_img) _free_vgimage(ge_img); + if(pattern) free(pattern); + if(paint != VG_INVALID_HANDLE) vgDestroyPaint(paint); + vgDestroyImage(vg_img); + return NULL; +} + +void +mbe_pattern_destroy(mbe_pattern_t *ptn) { + if(ptn->asso_img) + _free_vgimage(ptn->asso_img); + vgDestroyPaint(ptn->paint); + free(ptn); +} + +void +mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx) { + co_aix rev[6]; + + compute_reverse(mtx, rev); + ptn->mtx[0] = rev[0]; + ptn->mtx[1] = rev[3]; + ptn->mtx[2] = 0; + ptn->mtx[3] = rev[1]; + ptn->mtx[4] = rev[4]; + ptn->mtx[5] = 0; + ptn->mtx[6] = rev[2]; + ptn->mtx[7] = rev[5]; + ptn->mtx[8] = 1; +} + +void +mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, + co_comp_t b, co_comp_t a) { + VGPaint paint; + VGuint color; + VGfloat rgba[4]; + + paint = canvas->paint; + if(paint == VG_INVALID_HANDLE || canvas->src != NULL) { + /* previous one is not a color paint */ + if(canvas->src) { + mbe_pattern_destroy(canvas->src); + canvas->src = NULL; + } + + paint = vgCreatePaint(); + ASSERT(paint != VG_INVALID_HANDLE); + vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + canvas->paint = paint; + } + + rgba[0] = r; + rgba[1] = g; + rgba[2] = b; + rgba[3] = a; + vgSetParameterfv(paint, VG_PAINT_COLOR, 4, rgba); + canvas->paint_installed = 0; +} + +void +mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas) { + static VGint *scissors = NULL; + static int n_scissors = 0; + VGint *coord; + area_t *area; + int i; + + _MK_CURRENT_CTX(canvas); + + if(n_areas > n_scissors) { + if(scissors) free(scissors); + n_scissors = (n_areas + 0xf) & ~0xf; + scissors = (VGint *)malloc(sizeof(VGint) * n_scissors * 4); + ASSERT(scissors != NULL); + } + + coord = scissors; + for(i = 0; i < n_areas; i++) { + area = areas[i]; + *coord++ = area->x; + *coord++ = area->y; + *coord++ = area->w; + *coord++ = area->h; + } + + vgSeti(VG_SCISSORING, VG_TRUE); + vgSetiv(VG_SCISSOR_RECTS, n_areas * 4, scissors); +} + +static int +_openvg_find_config(mb_img_fmt_t fmt, int w, int h, + EGLConfig *config) { + EGLDisplay display; + EGLint attrib_list[32]; + EGLConfig configs[1]; + EGLint nconfigs; + int i = 0; + EGLBoolean r; + + switch(fmt) { + case MB_IFMT_ARGB32: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_RGB24: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_A8: + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_A1: + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 1; + break; + + case MB_IFMT_RGB16_565: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 5; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 6; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 5; + break; + + default: + return -1; + } + + attrib_list[i++] = EGL_SURFACE_TYPE; + attrib_list[i++] = EGL_PBUFFER_BIT; +#if 0 + attrib_list[i++] = EGL_MAX_PBUFFER_WIDTH; + attrib_list[i++] = w; + attrib_list[i++] = EGL_MAX_PBUFFER_HEIGHT; + attrib_list[i++] = h; +#endif + + attrib_list[i++] = EGL_RENDERABLE_TYPE; + attrib_list[i++] = EGL_OPENVG_BIT; + + attrib_list[i++] = EGL_NONE; + + display = _VG_DISPLAY(); + r = eglChooseConfig(display, attrib_list, configs, 1, &nconfigs); + if(!r) + return -1; + + *config = configs[0]; + + return 0; +} + +#ifdef EGL_GLX +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +static int +_get_img_fmt_from_xvisual(Display *display, Visual *visual) { + VisualID visual_id; + XVisualInfo temp; + XVisualInfo *infos; + int n; + int fmt = -1; + + visual_id = XVisualIDFromVisual(visual); + temp.visualid = visual_id; + infos = XGetVisualInfo(display, VisualIDMask, &temp, &n); + if(n != 1) + return -1; + + switch(infos->depth) { + case 32: + fmt = MB_IFMT_ARGB32; + break; + + case 24: + fmt = MB_IFMT_RGB24; + break; + + case 16: + fmt = MB_IFMT_RGB16_565; + break; + + case 8: + fmt = MB_IFMT_A8; + break; + + case 1: + fmt = MB_IFMT_A1; + break; + } + + return fmt; +} + +/*! \brief Create an EGL window surface for X11. + * + * This function is compiled only for GLX enabled. + */ +mbe_surface_t * +mbe_win_surface_create(Display *display, Drawable drawable, + Visual *visual, int width, int height) { + EGLDisplay egl_disp; + EGLSurface egl_surface; + mbe_surface_t *surface; + EGLConfig config; + EGLint attrib_list[2] = {EGL_NONE}; + int fmt; + int r; + + fmt = _get_img_fmt_from_xvisual(display, visual); + if(fmt == -1) + return NULL; + + r = _openvg_find_config(fmt, width, height, &config); + if(r != 0) + return NULL; + + egl_disp = eglGetDisplay(display); + if(egl_disp == EGL_NO_DISPLAY || egl_disp != _VG_DISPLAY()) + return NULL; + + egl_surface = eglCreateWindowSurface(egl_disp, config, drawable, + attrib_list); + + surface = O_ALLOC(mbe_surface_t); + if(surface == NULL) { + eglDestroySurface(egl_disp, egl_surface); + return NULL; + } + + surface->surface = egl_surface; + surface->asso_mbe = NULL; + surface->asso_img = NULL; + surface->fmt = fmt; + + return surface; +} + +#endif + +mbe_surface_t * +mbe_image_surface_create(mb_img_fmt_t fmt, int w, int h) { + EGLSurface surface; + EGLDisplay display; + EGLConfig config; + EGLint attrib_list[1] = {EGL_NONE}; + _ge_openvg_img_t *ge_img; + mbe_surface_t *mbe_surface; + int r; + + + r = _openvg_find_config(fmt, w, h, &config); + if(r != 0) + return NULL; + + ge_img = _alloc_vgimage(fmt, w, h); + if(ge_img == NULL) + return NULL; + + display = _VG_DISPLAY(); + /* Some implementation does not support pbuffer. + * We need use some other surface to replace this one. + * + * EGL does not support any attributes for pbuffer used by OpenVG. + */ + surface = eglCreatePbufferFromClientBuffer(display, EGL_OPENVG_IMAGE, + (EGLClientBuffer)ge_img->img, + config, attrib_list); + if(surface == EGL_NO_SURFACE) { + _free_vgimage(ge_img); + return NULL; + } + + mbe_surface = O_ALLOC(mbe_surface_t); + if(mbe_surface == NULL) { + _free_vgimage(ge_img); + eglDestroySurface(display, surface); + return NULL; + } + mbe_surface->surface = surface; + mbe_surface->asso_mbe = NULL; + mbe_surface->asso_img = ge_img; + mbe_surface->w = w; + mbe_surface->h = h; + mbe_surface->fmt = fmt; + + return mbe_surface; +} + +mbe_surface_t * +mbe_image_surface_create_for_data(unsigned char *data, + mb_img_fmt_t fmt, + int width, int height, + int stride) { + NOT_IMPLEMENT("mbe_image_surface_create_for_data"); + return NULL; +} + +void +mbe_surface_destroy(mbe_surface_t *surface) { + EGLDisplay display; + + display = _VG_DISPLAY(); + eglDestroySurface(display, surface->surface); + + if(surface->asso_mbe) + surface->asso_mbe->tgt = NULL; + + if(surface->asso_img) + _free_vgimage(surface->asso_img); + + free(surface); +} + +void +mbe_copy_source(mbe_t *src_canvas, mbe_t *dst_canvas) { + VGImage vg_img; + EGLDisplay display; + + ASSERT(src_canvas->tgt->asso_img != NULL); + + _MK_CURRENT_CTX(dst_canvas); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgLoadIdentity(); + + vg_img = SURFACE_VG_IMG(src_canvas); + vgDrawImage(vg_img); + + display = _VG_DISPLAY(); + eglSwapBuffers(display, VG_MBE_SURFACE(dst_canvas)); +} + +mbe_t * +mbe_create(mbe_surface_t *surface) { + EGLDisplay display; + EGLConfig config; + EGLContext ctx, shared; + VGPath path; + EGLint attrib_list[2] = {EGL_NONE}; + static VGfloat clear_color[4] = {0, 0, 0, 1}; + mbe_t *canvas; + int r; + + display = _VG_DISPLAY(); + + r = _openvg_find_config(surface->fmt, surface->w, surface->h, &config); + if(r != 0) + return NULL; + + /* shared = EGL_NO_CONTEXT; */ + shared = init_ctx; + ctx = eglCreateContext(display, config, shared, attrib_list); + if(ctx == EGL_NO_CONTEXT) + return NULL; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + if(path == VG_INVALID_HANDLE) { + eglDestroyContext(display, ctx); + return NULL; + } + + canvas = O_ALLOC(mbe_t); + if(canvas == NULL) { + eglDestroyContext(display, ctx); + vgDestroyPath(path); + return NULL; + } + + canvas->src = NULL; + canvas->paint = VG_INVALID_HANDLE; + canvas->paint_installed = 0; + canvas->tgt = surface; + canvas->ctx = ctx; + canvas->path = path; + + surface->asso_mbe = canvas; + + /* Set clear color for the context */ + _MK_CURRENT_CTX(canvas); + vgSetfv(VG_CLEAR_COLOR, 4, clear_color); + + return canvas; +} + +void +mbe_destroy(mbe_t *canvas) { + EGLDisplay display; + + display = _VG_DISPLAY(); + + vgDestroyPath(canvas->path); + eglDestroyContext(display, canvas->ctx); + canvas->tgt->asso_mbe = NULL; /* remove association */ + free(canvas); +} + +void +mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha) { + VGfloat color_trans[8] = {1, 1, 1, alpha, 0, 0, 0, 0}; + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + + _MK_CURRENT_CTX(canvas); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* Setup color transform for alpha */ +#ifdef OPENVG_1_1 + vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, color_trans); + vgSeti(VG_COLOR_TRANSFORM, VG_TRUE); +#endif + + mbe_paint(canvas); + +#ifdef OPENVG_1_1 + vgSeti(VG_COLOR_TRANSFORM, VG_FALSE); +#endif +} + +void +mbe_paint(mbe_t *canvas) { + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + VGPath path; + + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* + * Disable scissoring and identity transform matrix. + * + * Transform matrix from path to surface is assigned by + * mbe_transform(). Here, we temporary set it to identity, and + * restore it after paint. + */ + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vguRect(path, 0, 0, w, h); + vgDrawPath(path, VG_FILL_PATH); + vgDestroyPath(path); + + /* re-enable scissoring and restore transform matrix */ + vgLoadMatrix(canvas->mtx); + vgSeti(VG_SCISSORING, VG_TRUE); +} + +void +mbe_clear(mbe_t *canvas) { + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + + _MK_CURRENT_CTX(canvas); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* Clear regions to the color specified by mbe_create() */ + vgClear(0, 0, w, h); +} + +void mbe_init() { + static EGLSurface init_surf; + EGLDisplay display; + EGLConfig config; + EGLint nconfigs; + EGLint attrib_list[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, + EGL_NONE}; + EGLint surf_attribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE}; + EGLBoolean r; + + display = _VG_DISPLAY(); + eglInitialize(display, NULL, NULL); + + r = eglChooseConfig(display, attrib_list, &config, 1, &nconfigs); + ASSERT(r); + + eglBindAPI(EGL_OPENVG_API); + + init_ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL); + ASSERT(init_ctx != EGL_NO_CONTEXT); + + init_surf = eglCreatePbufferSurface(display, config, surf_attribs); + ASSERT(init_surf != EGL_NO_SURFACE); + + eglMakeCurrent(display, init_surf, init_surf, init_ctx); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/img_ldr_imlib2.c Sat Dec 04 16:58:25 2010 +0800 @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- +// vim: sw=4:ts=8:sts=4 +#include <stdio.h> +#include <string.h> +#include <Imlib2.h> +#include "mb_graph_engine.h" +#include "mb_tools.h" +#include "mb_paint.h" +#include "mb_img_ldr.h" + +/*! \brief Simple image loader. + * + */ +struct _simple_mb_img_ldr { + mb_img_ldr_t ldr; + const char *repo; /*!< \brief The directory of repository. */ +}; +typedef struct _simple_mb_img_ldr simple_mb_img_ldr_t; + +struct _simple_mb_img_data { + mb_img_data_t img; + Imlib_Image img_hdl; +}; +typedef struct _simple_mb_img_data simple_mb_img_data_t; + +static void simple_mb_img_ldr_img_free(mb_img_data_t *img); + +static +mb_img_data_t *simple_mb_img_ldr_load(mb_img_ldr_t *ldr, const char *img_id) { + simple_mb_img_ldr_t *sldr = (simple_mb_img_ldr_t *)ldr; + simple_mb_img_data_t *img; + Imlib_Image img_hdl; + int w, h; + void *data; + char *fname; + int sz; + + sz = strlen(sldr->repo); + sz += strlen(img_id); + fname = (char *)malloc(sz + 2); + if (img_id[0] != '/') + strcpy(fname, sldr->repo); + else + fname[0] = 0; + strcat(fname, img_id); + + img_hdl = imlib_load_image(fname); + if(!img_hdl) + return NULL; + imlib_context_set_image(img_hdl); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + data = imlib_image_get_data_for_reading_only(); + + img = O_ALLOC(simple_mb_img_data_t); + if(img == NULL) { + imlib_free_image(); + return NULL; + } + img->img.content = data; + img->img.w = w; + img->img.h = h; + img->img.stride = w * 4; + img->img.fmt = MB_IFMT_ARGB32; + img->img.free = simple_mb_img_ldr_img_free; + img->img_hdl = img_hdl; + + return (mb_img_data_t *)img; +} + +static +void simple_mb_img_ldr_img_free(mb_img_data_t *img) { + simple_mb_img_data_t *simg = (simple_mb_img_data_t *)img; + + imlib_context_set_image(simg->img_hdl); + imlib_free_image(); + free(img); +} + +static +void simple_mb_img_ldr_free(mb_img_ldr_t *ldr) { + simple_mb_img_ldr_t *defldr = (simple_mb_img_ldr_t *)ldr; + + free((void *)defldr->repo); +} + +mb_img_ldr_t *simple_mb_img_ldr_new(const char *img_repository) { + simple_mb_img_ldr_t *ldr; + int sz; + + if(img_repository == NULL) + return NULL; + + ldr = O_ALLOC(simple_mb_img_ldr_t); + if(ldr == NULL) + return NULL; + + /* + * Copy and formalize path of image repository. + */ + sz = strlen(img_repository); + ldr->repo = (const char *)malloc(sz + 2); + if(ldr->repo == NULL) { + free(ldr); + return NULL; + } + strcpy((char *)ldr->repo, img_repository); + if(img_repository[sz - 1] != '/' && strlen(img_repository) != 0) { + ((char *)ldr->repo)[sz] = '/'; + ((char *)ldr->repo)[sz + 1] = 0; + } + + ldr->ldr.load = simple_mb_img_ldr_load; + ldr->ldr.free = simple_mb_img_ldr_free; + + return (mb_img_ldr_t *)ldr; +}
--- a/src/paint.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/paint.c Sat Dec 04 16:58:25 2010 +0800 @@ -182,6 +182,11 @@ #define RDF_DIRTY 0x1 +#define pnt_radial_clear_flags(radial, _flags) \ + do { \ + (radial)->flags &= ~(_flags); \ + } while(0) + int _paint_radial_size = sizeof(paint_radial_t); static void paint_radial_prepare(paint_t *paint, mbe_t *cr, shape_t *sh) { @@ -202,8 +207,11 @@ radial->stops, radial->n_stops); ASSERT(ptn != NULL); - mbe_pattern_destroy(radial->ptn); + if(radial->ptn) + mbe_pattern_destroy(radial->ptn); radial->ptn = ptn; + + pnt_radial_clear_flags(radial, RDF_DIRTY); } mbe_set_source(cr, radial->ptn); } @@ -266,7 +274,6 @@ typedef struct _paint_image { paint_t paint; mb_img_data_t *img; - mbe_surface_t *surf; mbe_pattern_t *ptn; } paint_image_t; @@ -286,7 +293,6 @@ paint_image_t *paint_img = (paint_image_t *)paint; mb_img_data_t *img_data; - mbe_surface_destroy(paint_img->surf); img_data = paint_img->img; MB_IMG_DATA_FREE(img_data); paint_destroy(&paint_img->paint); @@ -311,21 +317,9 @@ paint_init(&paint->paint, MBP_IMAGE, paint_image_prepare, paint_image_free); paint->img = img; - paint->surf = mbe_image_surface_create_for_data(img->content, - img->fmt, - img->w, - img->h, - img->stride); - if(paint->surf == NULL) { - paint_destroy(&paint->paint); - elmpool_elm_free(rdman->paint_image_pool, paint); - return NULL; - } - - paint->ptn = mbe_pattern_create_for_surface(paint->surf); + paint->ptn = mbe_pattern_create_image(img); if(paint->ptn == NULL) { paint_destroy(&paint->paint); - mbe_surface_destroy(paint->surf); elmpool_elm_free(rdman->paint_image_pool, paint); return NULL; }
--- a/src/redraw_man.c Sat Dec 04 07:43:51 2010 +0800 +++ b/src/redraw_man.c Sat Dec 04 16:58:25 2010 +0800 @@ -2237,36 +2237,22 @@ mbe_clear(canvas); } -static void make_clip(mbe_t *cr, int n_dirty_areas, - area_t **dirty_areas) { - int i; - area_t *area; - - mbe_new_path(cr); - for(i = 0; i < n_dirty_areas; i++) { - area = dirty_areas[i]; - if(area->w < 0.1 || area->h < 0.1) - continue; - mbe_rectangle(cr, area->x, area->y, area->w, area->h); - } - mbe_clip(cr); -} +#define make_scissoring(canvas, n_dirty_areas, dirty_areas) \ + mbe_scissoring(canvas, n_dirty_areas, dirty_areas) static void reset_clip(canvas_t *cr) { - mbe_reset_clip(cr); + mbe_reset_scissoring(cr); } static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, area_t **dirty_areas) { if(n_dirty_areas) - make_clip(rdman->backend, n_dirty_areas, dirty_areas); - + make_scissoring(rdman->backend, n_dirty_areas, dirty_areas); + mbe_copy_source(rdman->cr, rdman->backend); } #else /* UNITTEST */ -static void make_clip(mbe_t *cr, int n_dirty_areas, - area_t **dirty_areas) { -} +#define make_scissoring(canvas, n_dirty_areas, dirty_areas) static void clear_canvas(canvas_t *canvas) { } @@ -2401,7 +2387,7 @@ area->h = ceilf(area->h); } - make_clip(canvas, n_areas, areas); + make_scissoring(canvas, n_areas, areas); clear_canvas(canvas); r = draw_coord_shapes_in_dirty_areas(rdman, coord);