changeset 604:38514a7c6b26 openvg

Linear gradient for OpenVG
author Thinker K.F. Li <thinker@branda.to>
date Sun, 04 Jul 2010 15:36:40 +0800
parents 39d27911c3ae
children a8fa4c550fe5
files include/mb_graph_engine_openvg.h src/graph_engine_openvg.c
diffstat 2 files changed, 68 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h	Sun Jul 04 00:16:43 2010 +0800
+++ b/include/mb_graph_engine_openvg.h	Sun Jul 04 15:36:40 2010 +0800
@@ -22,8 +22,6 @@
 #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_scaled_font_destroy(scaled)
 #define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL)
@@ -138,22 +136,32 @@
 extern EGLNativeDisplayType _ge_openvg_disp_id;
 extern mbe_t *_ge_openvg_current_canvas;
 
+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 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,	\
-			   (canvas)->tgt, (canvas)->ctx);	\
+	    eglMakeCurrent(_VG_DISPLAY(),			\
+			   (canvas)->tgt->surface,		\
+			   (canvas)->tgt->surface,		\
+			   (canvas)->ctx);			\
 	}							\
     } 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)
--- a/src/graph_engine_openvg.c	Sun Jul 04 00:16:43 2010 +0800
+++ b/src/graph_engine_openvg.c	Sun Jul 04 15:36:40 2010 +0800
@@ -1,4 +1,5 @@
 #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;
@@ -12,6 +13,60 @@
 				   (((int)(0xf * b) & 0xf) << 16) |	\
 				   ((int)(0xf * a) & 0xf))
 
+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) {
+    VGPaint paint;
+    mbe_pattern_t *pattern;
+    VGfloat gradient[] = {x0, y0, x1, y1};
+    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(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;
+    }
+    
+    paint = vgCreatePaint();
+    if(paint == VG_INVALID_HANDLE)
+	return NULL;
+    vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
+    vgSetParameterfv(paint, VG_PAINT_LINEAR_GRADIENT, 4, gradient);
+    vgSetParameterfv(paint, VG_PAINT_COLOR_RAMP_STOPS, 5 * stop_cnt, ov_stops);
+
+    pattern = O_ALLOC(mbe_pattern_t);
+    if(pattern == NULL) {
+	vgPaintDestroy(paint);
+	return NULL;
+    }
+
+    pattern->paint = paint;
+    pattern->asso_img = NULL;
+    
+    return pattern;
+}
+
 void
 mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g,
 		    co_comp_t b, co_comp_t a) {
@@ -44,7 +99,7 @@
 
     if(n_areas > n_scissors) {
 	if(scissors) free(scissors);
-	n_scissors = (n_areas + 0xf) & 0xf;
+	n_scissors = (n_areas + 0xf) & ~0xf;
 	scissors = (VGint *)malloc(sizeof(VGint) * n_scissors * 4);
 	ASSERT(scissors != NULL);
     }