diff src/graph_engine_openvg.c @ 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 e78bff7d23d3
children 6a0be737a3f3
line wrap: on
line diff
--- 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);
 }