changeset 612:b1d1b6c5af90 openvg

Implements setting pattern matrix for OpenVG
author Thinker K.F. Li <thinker@branda.to>
date Wed, 07 Jul 2010 18:44:17 +0800
parents 38383f5f645d
children 6a0be737a3f3
files include/mb_graph_engine_openvg.h src/graph_engine_openvg.c
diffstat 2 files changed, 106 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h	Mon Jul 05 14:41:43 2010 +0800
+++ b/include/mb_graph_engine_openvg.h	Wed Jul 07 18:44:17 2010 +0800
@@ -21,7 +21,6 @@
 #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_set_scaled_font(canvas, scaled)
 #define mbe_pattern_destroy(pattern)
@@ -80,6 +79,8 @@
     mbe_surface_t *tgt;
     EGLContext ctx;
     VGPath path;
+
+    VGfloat mtx[9];
 };
 
 struct _ge_openvg_surface {
@@ -92,6 +93,7 @@
 
 struct _ge_openvg_pattern {
     _ge_openvg_img_t *asso_img;
+    VGfloat mtx[9];
     VGPaint paint;
 };
 
@@ -129,6 +131,7 @@
 
 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 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,
@@ -142,6 +145,7 @@
 						grad_stop_t *stops,
 						int stop_cnt);
 extern mbe_pattern_t *mbe_pattern_create_image(mb_img_data_t *img);
+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 */
@@ -165,17 +169,17 @@
     } while(0)
 /* TODO: switch VGImage between VGPaint and surface. */
 #define _MK_CURRENT_PAINT(canvas)					\
-    if((canvas)->paint_installed)					\
-	vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH)
+    if((canvas)->paint_installed) {					\
+	vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH);	\
+    }
 
-static void
-mbe_transform(mbe_t *canvas, co_aix *mtx) {
-    VGfloat vg_mtx[9];
-    
-    _MK_CURRENT_CTX(canvas);
-    MB_MATRIX_2_OPENVG(vg_mtx, mtx);
-    vgLoadMatrix(vg_mtx);
-}
+#define mbe_transform(canvas, _mtx)				\
+    do {							\
+	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
@@ -217,6 +221,9 @@
 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);
@@ -226,6 +233,9 @@
 mbe_fill(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);
     vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL);
--- a/src/graph_engine_openvg.c	Mon Jul 05 14:41:43 2010 +0800
+++ b/src/graph_engine_openvg.c	Wed Jul 07 18:44:17 2010 +0800
@@ -13,6 +13,19 @@
 				   (((int)(0xf * b) & 0xf) << 16) |	\
 				   ((int)(0xf * a) & 0xf))
 
+#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)
+
 /*
  * This implementation supports only from image surface.
  */
@@ -20,6 +33,7 @@
 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 */
@@ -35,9 +49,22 @@
     pattern->asso_img = ge_img;
     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,
@@ -87,6 +114,8 @@
 
     pattern->paint = paint;
     pattern->asso_img = NULL;
+
+    MK_ID(pattern->mtx);
     
     return pattern;
 }
@@ -172,6 +201,22 @@
 }
 
 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;
@@ -224,7 +269,7 @@
 _openvg_find_config(mb_img_fmt_t fmt, int w, int h,
 		   EGLConfig *config) {
     EGLDisplay display;
-    EGLint attrib_list[16];
+    EGLint attrib_list[32];
     EGLConfig configs[1];
     EGLint nconfigs;
     int i = 0;
@@ -240,6 +285,8 @@
 	attrib_list[i++] = 8;
 	attrib_list[i++] = EGL_ALPHA_SIZE;
 	attrib_list[i++] = 8;
+	attrib_list[i++] = EGL_ALPHA_MASK_SIZE;
+	attrib_list[i++] = 8;
 	break;
 	
     case MB_IFMT_RGB24:
@@ -249,16 +296,22 @@
 	attrib_list[i++] = 8;
 	attrib_list[i++] = EGL_BLUE_SIZE;
 	attrib_list[i++] = 8;
+	attrib_list[i++] = EGL_ALPHA_MASK_SIZE;
+	attrib_list[i++] = 8;
 	break;
 	
     case MB_IFMT_A8:
 	attrib_list[i++] = EGL_ALPHA_SIZE;
 	attrib_list[i++] = 8;
+	attrib_list[i++] = EGL_ALPHA_MASK_SIZE;
+	attrib_list[i++] = 8;
 	break;
 	
     case MB_IFMT_A1:
 	attrib_list[i++] = EGL_ALPHA_SIZE;
 	attrib_list[i++] = 1;
+	attrib_list[i++] = EGL_ALPHA_MASK_SIZE;
+	attrib_list[i++] = 1;
 	break;
 	
     case MB_IFMT_RGB16_565:
@@ -268,6 +321,8 @@
 	attrib_list[i++] = 6;
 	attrib_list[i++] = EGL_BLUE_SIZE;
 	attrib_list[i++] = 5;
+	attrib_list[i++] = EGL_ALPHA_MASK_SIZE;
+	attrib_list[i++] = 5;
 	break;
 	
     default:
@@ -471,23 +526,33 @@
     free(canvas);
 }
 
-/*
- * This implementation support only paint with image paint.  OpenVG
- * does not support paint path with an alpha value.  But, it supports
- * to draw image with an alpha value.
- */
 void
 mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha) {
-    VGImage vg_img;
-    _ge_openvg_img_t *ge_img;
+    EGLDisplay display;
+    VGHandle mask;
+    EGLint w, h;
+    EGLBoolean r;
     
     _MK_CURRENT_CTX(canvas);
 
-    ASSERT(canvas->src != NULL && canvas->src->asso_img != NULL);
-    ge_img = canvas->src->asso_img;
-    vg_img = ge_img->img;
+    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);
+    
+    /* enable and fill mask layer with alpha value */
+    vgSeti(VG_MASKING, VG_TRUE);
+    mask = vgCreateMaskLayer(w, h);
+    ASSERT(mask != VG_INVALID_HANDLE);
+    vgFillMaskLayer(mask, 0, 0, w, h, alpha);
+    vgMask(mask, VG_SET_MASK, 0, 0, w, h);
+    vgDestroyMaskLayer(mask);
+    
+    mbe_paint(canvas);
 
-    vgDrawImage(vg_img);
+    vgSeti(VG_MASKING, VG_FALSE);
 }
 
 void
@@ -499,6 +564,9 @@
     
     _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();
     
@@ -507,7 +575,10 @@
     r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h);
     ASSERT(r == EGL_TRUE);
 
+    /* disable scissoring and identity transform matrix */
     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);
@@ -515,6 +586,8 @@
     vgDrawPath(path, VG_FILL_PATH);
     vgDestroyPath(path);
     
+    /* re-enable scissoring and restore transform matrix */
+    vgLoadMatrix(canvas->mtx);
     vgSeti(VG_SCISSORING, VG_TRUE);
 }