changeset 512:d186d1e24458 Android_Skia

Change prototype of mbe_copy_source(). - To make mbe_copy_source more portable, user of mbe_copy_source() should specify source and destinate canvas for copying. - Export a new function for Skia graphic engine, for Android JNI.
author Thinker K.F. Li <thinker@branda.to>
date Tue, 01 Dec 2009 22:55:27 +0800
parents caa087976b17
children 6394a1e33b2f
files include/mb_graph_engine_cairo.h include/mb_graph_engine_skia.h include/mb_types.h src/graph_engine_skia.cpp src/redraw_man.c
diffstat 5 files changed, 61 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_graph_engine_cairo.h	Tue Dec 01 22:55:27 2009 +0800
+++ b/include/mb_graph_engine_cairo.h	Tue Dec 01 22:55:27 2009 +0800
@@ -106,13 +106,19 @@
     cairo_set_operator(canvas, old_op);
 }
 
-static void mbe_copy_source(mbe_t *canvas) {
+static void mbe_copy_source(mbe_t *src, mbe_t *dst) {
     cairo_operator_t saved_op;
+    cairo_surface_t *surf;
+    cairo_pattern_t *ptn;
     
-    saved_op = cairo_get_operator(canvas);
-    cairo_set_operator(canvas, CAIRO_OPERATOR_SOURCE);
-    cairo_paint(canvas);
-    cairo_set_operator(canvas, saved_op);
+    surf = cairo_get_target(src);
+    ptn = cairo_pattern_create_for_surface(surf);
+    cairo_set_source(src, ptn);
+    cairo_pattern_destroy(ptn);
+    saved_op = cairo_get_operator(dst);
+    cairo_set_operator(dst, CAIRO_OPERATOR_SOURCE);
+    cairo_paint(dst);
+    cairo_set_operator(dst, saved_op);
 }
 
 static mbe_scaled_font_t *
--- a/include/mb_graph_engine_skia.h	Tue Dec 01 22:55:27 2009 +0800
+++ b/include/mb_graph_engine_skia.h	Tue Dec 01 22:55:27 2009 +0800
@@ -113,7 +113,7 @@
 extern void mbe_free_font_face(mbe_font_face_t *face);
 
 extern void mbe_clear(mbe_t *canvas);
-extern void mbe_copy_source(mbe_t *canvas);
+extern void mbe_copy_source(mbe_t *src, mbe_t *dst);
 extern void mbe_transform(mbe_t *mbe, co_aix matrix[6]);
 extern void mbe_arc(mbe_t *mbe, co_aix x, co_aix y, co_aix radius,
 		    co_aix angle_start, co_aix angle_stop);
--- a/include/mb_types.h	Tue Dec 01 22:55:27 2009 +0800
+++ b/include/mb_types.h	Tue Dec 01 22:55:27 2009 +0800
@@ -377,6 +377,7 @@
 #define sh_get_aggr_matrix(sh) (coord_get_aggr_matrix(sh_get_coord(sh)))
 #define sh_get_fill(sh) ((sh)->fill)
 #define sh_get_stroke(sh) ((sh)->stroke)
+#define sh_set_stroke_width(sh, v) do { (sh)->stroke_width = (v); } while(0)
 
 
 /*! \brief A sprite is a set of graphics that being an object in animation.
--- a/src/graph_engine_skia.cpp	Tue Dec 01 22:55:27 2009 +0800
+++ b/src/graph_engine_skia.cpp	Tue Dec 01 22:55:27 2009 +0800
@@ -515,7 +515,7 @@
 			   MB_CO_COMP_2_SK(r),
 			   MB_CO_COMP_2_SK(g),
 			   MB_CO_COMP_2_SK(b));
-    canvas->paint->ptn = NULL;
+    canvas->states->ptn = NULL;
 }
 
 void mbe_set_scaled_font(mbe_t *canvas,
@@ -653,10 +653,14 @@
     path->reset();
 }
 
-mbe_t *mbe_create(mbe_surface_t *target) {
+/*! \brief Create a mbe from a SkCanvas.
+ *
+ * It is only used for Android JNI.  It is used to create mbe_t from a
+ * SkCanvas created by Canvas class of Android Java application.
+ */
+mbe_t *skia_mbe_create_by_canvas(SkCanvas *canvas) {
     mbe_t *mbe;
     struct _mbe_states_t *states;
-    SkBitmap *bitmap = (SkBitmap *)target;
 
     mbe = (mbe_t *)malloc(sizeof(mbe_t));
     if(mbe == NULL)
@@ -670,7 +674,8 @@
 	return NULL;
     }
     
-    mbe->canvas = new SkCanvas(*bitmap);
+    canvas->ref();
+    mbe->canvas = canvas;
     mbe->path = new SkPath();
     mbe->subpath = new SkPath();
     mbe->saved_region = new SkRegion();
@@ -680,7 +685,7 @@
     states->line_width = 0;
     states->next = NULL;
 
-    if(mbe->canvas == NULL || mbe->path == NULL ||
+    if(mbe->path == NULL ||
        mbe->subpath == NULL || mbe->paint == NULL ||
        mbe->saved_region == NULL)
 	goto fail;
@@ -690,7 +695,7 @@
     return mbe;
 
  fail:
-    if(mbe->canvas) delete mbe->canvas;
+    canvas->unref();
     if(mbe->path) delete mbe->path;
     if(mbe->subpath) delete mbe->subpath;
     if(mbe->paint) delete mbe->paint;
@@ -701,10 +706,31 @@
     return NULL;
 }
 
+mbe_t *mbe_create(mbe_surface_t *target) {
+    mbe_t *mbe;
+    SkBitmap *bitmap = (SkBitmap *)target;
+    SkCanvas *canvas;
+
+    canvas = new SkCanvas(*bitmap);
+    if(canvas == NULL) {
+	delete bitmap;
+	return NULL;
+    }
+	
+    mbe = skia_mbe_create_by_canvas(canvas);
+    canvas->unref();
+    
+    if(mbe == NULL) {
+	delete bitmap;
+    }
+    
+    return mbe;
+}
+
 void mbe_destroy(mbe_t *canvas) {
     struct _mbe_states_t *states;
     
-    delete canvas->canvas;
+    canvas->canvas->unref();
     delete canvas->path;
     delete canvas->subpath;
     delete canvas->paint;
@@ -766,17 +792,25 @@
     canvas->canvas->drawColor(color, SkPorterDuff::kClear_Mode);
 }
 
-void mbe_copy_source(mbe_t *canvas) {
-    SkPaint *paint = canvas->paint;
+void mbe_copy_source(mbe_t *src, mbe_t *dst) {
+    SkPaint *paint = dst->paint;
+    SkShader *shader;
+    SkBitmap *bmap;
     SkXfermode *mode;
 
-    _prepare_paint(canvas, SkPaint::kFill_Style);
+    _prepare_paint(dst, SkPaint::kFill_Style);
     mode = SkPorterDuff::CreateXfermode(SkPorterDuff::kSrc_Mode);
     paint->setXfermode(mode);
-    /* mode->unref(); */
+    mode->unref();
+    bmap = &src->canvas->getDevice()->accessBitmap(false);
+    shader = SkShader::CreateBitmapShader(*bmap,
+					  SkShader::kClamp_TileMode ,
+					  SkShader::kClamp_TileMode);
+    paint->setShader(shader);
+    shader->unref();
 
-    canvas->canvas->drawPaint(*paint);
-
+    dst->canvas->drawPaint(*paint);
+    
     _finish_paint(canvas);
 }
 
--- a/src/redraw_man.c	Tue Dec 01 22:55:27 2009 +0800
+++ b/src/redraw_man.c	Tue Dec 01 22:55:27 2009 +0800
@@ -1917,7 +1917,7 @@
     if(n_dirty_areas)
 	make_clip(rdman->backend, n_dirty_areas, dirty_areas);
     
-    mbe_copy_source(rdman->backend);
+    mbe_copy_source(rdman->cr, rdman->backend);
 }
 #else /* UNITTEST */
 static void make_clip(mbe_t *cr, int n_dirty_areas,