add shape recording to pictuures (sans serialization)



git-svn-id: http://skia.googlecode.com/svn/trunk@240 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gm_files.mk b/gm/gm_files.mk
index 02a416c..50eb311 100644
--- a/gm/gm_files.mk
+++ b/gm/gm_files.mk
@@ -2,6 +2,7 @@
 	bitmapfilters.cpp \
 	filltypes.cpp \
 	gradients.cpp \
+	shapes.cpp \
 	tilemodes.cpp \
 	xfermodes.cpp \
 	gmmain.cpp
diff --git a/samplecode/SampleShapes.cpp b/samplecode/SampleShapes.cpp
index 8db960c..81f6e4f 100644
--- a/samplecode/SampleShapes.cpp
+++ b/samplecode/SampleShapes.cpp
@@ -1,6 +1,7 @@
 #include "SampleCode.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
+#include "SkPicture.h"
 #include "SkView.h"
 
 #include "SkRectShape.h"
@@ -93,20 +94,29 @@
         fMatrixRefs[3]->preRotate(SkIntToScalar(fAngle), c, c);
         
         SkMatrix matrix;
-#if 1        
-        SkGroupShape gs;
-        gs.appendShape(&fGroup);
+     
+        SkGroupShape* gs = new SkGroupShape;
+        SkAutoUnref aur(gs);
+        gs->appendShape(&fGroup);
         matrix.setScale(-SK_Scalar1, SK_Scalar1);
         matrix.postTranslate(SkIntToScalar(220), SkIntToScalar(240));
-        gs.appendShape(&fGroup, matrix);
+        gs->appendShape(&fGroup, matrix);
         matrix.setTranslate(SkIntToScalar(240), 0);
         matrix.preScale(SK_Scalar1*2, SK_Scalar1*2);
-        gs.appendShape(&fGroup, matrix);
-        canvas->drawShape(&gs);
+        gs->appendShape(&fGroup, matrix);
+        
+#if 0        
+        canvas->drawShape(gs);
 #else
-        fGroup.draw(canvas);
-        fGroup.drawXY(canvas, 0, SkIntToScalar(240));
-        fGroup.drawMatrix(canvas, matrix);
+        SkPicture pict;
+        SkCanvas* cv = pict.beginRecording(1000, 1000);
+        cv->scale(SK_ScalarHalf, SK_ScalarHalf);
+        cv->drawShape(gs);
+        cv->translate(SkIntToScalar(680), SkIntToScalar(480));
+        cv->scale(-SK_Scalar1, SK_Scalar1);
+        cv->drawShape(gs);
+        pict.endRecording();
+        canvas->drawPicture(pict);
 #endif
 
         *fMatrixRefs[3] = saveM;
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index aad1dcd..86a161d 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -26,6 +26,7 @@
     DRAW_POS_TEXT_H,
     DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H
     DRAW_RECT,
+    DRAW_SHAPE,
     DRAW_SPRITE,
     DRAW_TEXT,
     DRAW_TEXT_ON_PATH,
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 421d5c2..24fcd8e 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -119,7 +119,17 @@
             fPictureRefs[i]->ref();
         }
     }
-
+    
+    const SkTDArray<SkShape* >& shapes = record.getShapes();
+    fShapeCount = shapes.count();
+    if (fShapeCount > 0) {
+        fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
+        for (int i = 0; i < fShapeCount; i++) {
+            fShapes[i] = shapes[i];
+            fShapes[i]->ref();
+        }
+    }
+    
     const SkTDArray<const SkFlatRegion* >& regions = record.getRegions();
     fRegionCount = regions.count();
     if (fRegionCount > 0) {
@@ -192,6 +202,13 @@
         fPictureRefs[i]->ref();
     }
     
+    fShapeCount = src.fShapeCount;
+    fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
+    for (int i = 0; i < fShapeCount; i++) {
+        fShapes[i] = src.fShapes[i];
+        fShapes[i]->ref();
+    }
+    
     fRegionCount = src.fRegionCount;
     fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
     for (i = 0; i < fRegionCount; i++) {
@@ -205,6 +222,7 @@
     fPaints = NULL;
     fPathHeap = NULL;
     fPictureRefs = NULL;
+    fShapes = NULL;
     fRegions = NULL;
     fBitmapCount = fMatrixCount = fPaintCount = fPictureCount = 
     fRegionCount = 0;
@@ -221,12 +239,17 @@
     SkDELETE_ARRAY(fRegions);
     
     fPathHeap->safeUnref();
-
+    
     for (int i = 0; i < fPictureCount; i++) {
         fPictureRefs[i]->unref();
     }
     SkDELETE_ARRAY(fPictureRefs);
     
+    for (int i = 0; i < fShapeCount; i++) {
+        fShapes[i]->unref();
+    }
+    SkDELETE_ARRAY(fShapes);
+    
     SkDELETE(fFactoryPlayback);
 }
 
@@ -362,7 +385,14 @@
     for (i = 0; i < fPictureCount; i++) {
         fPictureRefs[i]->serialize(stream);
     }
-
+    
+#if 0
+    writeTagSize(stream, PICT_SHAPE_TAG, fShapeCount);
+    for (i = 0; i < fShapeCount; i++) {
+        fShapes[i]->serialize(stream);
+    }
+#endif
+    
     writeTagSize(stream, PICT_ARRAYS_TAG, buffer.size());
     buffer.writeToStream(stream);
 }
@@ -603,6 +633,9 @@
                 const SkPaint& paint = *getPaint();
                 canvas.drawRect(*fReader.skipRect(), paint); 
             } break;
+            case DRAW_SHAPE:
+                canvas.drawShape(getShape());
+                break;
             case DRAW_SPRITE: {
                 const SkPaint* paint = getPaint();
                 const SkBitmap& bitmap = getBitmap(); 
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index b4e69ca..ae9641a 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -11,6 +11,7 @@
 #include "SkPathHeap.h"
 #include "SkRegion.h"
 #include "SkPictureFlat.h"
+#include "SkShape.h"
 
 class SkPictureRecord;
 class SkStream;
@@ -72,7 +73,13 @@
         SkASSERT(index > 0 && index <= fPictureCount);
         return *fPictureRefs[index - 1];
     }
-
+    
+    SkShape* getShape() {
+        int index = getInt();
+        SkASSERT(index > 0 && index <= fShapeCount);
+        return fShapes[index - 1];
+    }
+    
     const SkPaint* getPaint() {
         int index = getInt();
         if (index == 0) {
@@ -159,7 +166,9 @@
 
     SkPicture** fPictureRefs;
     int fPictureCount;
-    
+    SkShape** fShapes;
+    int fShapeCount;
+
     SkRefCntPlayback fRCPlayback;
     SkTypefacePlayback fTFPlayback;
     SkFactoryPlayback*   fFactoryPlayback;
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 77756a9..f0f3402 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -1,4 +1,5 @@
 #include "SkPictureRecord.h"
+#include "SkShape.h"
 #include "SkTSearch.h"
 
 #define MIN_WRITER_SIZE 16384
@@ -353,6 +354,20 @@
     validate();
 }
 
+void SkPictureRecord::drawShape(SkShape* shape) {
+    addDraw(DRAW_SHAPE);
+
+    int index = fShapes.find(shape);
+    if (index < 0) {    // not found
+        index = fShapes.count();
+        *fShapes.append() = shape;
+        shape->ref();
+    }
+    // follow the convention of recording a 1-based index
+    addInt(index + 1);
+    validate();
+}
+
 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
                           const SkPoint vertices[], const SkPoint texs[],
                           const SkColor colors[], SkXfermode*,
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 5325e1e..05761af 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -50,6 +50,7 @@
                             const SkPath& path, const SkMatrix* matrix, 
                                 const SkPaint&);
     virtual void drawPicture(SkPicture& picture);
+    virtual void drawShape(SkShape*);
     virtual void drawVertices(VertexMode, int vertexCount,
                           const SkPoint vertices[], const SkPoint texs[],
                           const SkColor colors[], SkXfermode*,
@@ -70,6 +71,9 @@
     const SkTDArray<SkPicture* >& getPictureRefs() const {
         return fPictureRefs;
     }
+    const SkTDArray<SkShape* >& getShapes() const {
+        return fShapes;
+    }
     const SkTDArray<const SkFlatRegion* >& getRegions() const {
         return fRegions;
     }
@@ -165,8 +169,9 @@
     SkPathHeap* fPathHeap;  // reference counted
     SkWriter32 fWriter;
 
-    // we ref each item in this array
+    // we ref each item in these arrays
     SkTDArray<SkPicture*> fPictureRefs;
+    SkTDArray<SkShape*> fShapes;
 
     SkRefCntRecorder fRCRecorder;
     SkRefCntRecorder fTFRecorder;
diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
index 19f3614..ab18fcc 100644
--- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
+++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
@@ -26,7 +26,6 @@
 		000A99820FD97526007E45BD /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; };
 		0028847B0EFAB46A0083E387 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 002884510EFAA35C0083E387 /* libcore.a */; };
 		002884BD0EFAB6A30083E387 /* libmaccore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 002884BC0EFAB69F0083E387 /* libmaccore.a */; };
-		003145320FB9B48F00B10956 /* SampleShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 003145310FB9B48F00B10956 /* SampleShapes.cpp */; };
 		0041CDDB0F00975E00695E8C /* SampleImageDir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CDDA0F00975E00695E8C /* SampleImageDir.cpp */; };
 		0041CDF30F009ED100695E8C /* SkImageRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CDF20F009ED100695E8C /* SkImageRef.cpp */; };
 		0041CDF60F009EED00695E8C /* SkImageRef_GlobalPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CDF50F009EED00695E8C /* SkImageRef_GlobalPool.cpp */; };
@@ -48,6 +47,7 @@
 		0041CE480F00A12400695E8C /* SampleOverflow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE320F00A12400695E8C /* SampleOverflow.cpp */; };
 		0041CE4A0F00A12400695E8C /* SamplePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE340F00A12400695E8C /* SamplePatch.cpp */; };
 		0057785F0FF17CCC00582CD9 /* SampleMipMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2794C04E0FE72903009AD112 /* SampleMipMap.cpp */; };
+		005778B40FF5616F00582CD9 /* SampleShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 003145310FB9B48F00B10956 /* SampleShapes.cpp */; };
 		005E92DC0FF08507008965B9 /* SampleFilter2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE290F00A12400695E8C /* SampleFilter2.cpp */; };
 		005E92DE0FF0850E008965B9 /* SampleFillType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE270F00A12400695E8C /* SampleFillType.cpp */; };
 		005E92E00FF08512008965B9 /* SampleFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE280F00A12400695E8C /* SampleFilter.cpp */; };
@@ -559,7 +559,6 @@
 				00C55DA10F8552DC000CAC09 /* SampleGradients.cpp in Sources */,
 				009490320FB0A5B90063C792 /* SampleLayerMask.cpp in Sources */,
 				007A7CB60F01658C00A2D6EE /* SampleRegion.cpp in Sources */,
-				003145320FB9B48F00B10956 /* SampleShapes.cpp in Sources */,
 				00FF39140FC6ED2C00915187 /* SampleEffects.cpp in Sources */,
 				2762F66D0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp in Sources */,
 				2762F66E0FCCCABE002BD8B4 /* SkPageFlipper.cpp in Sources */,
@@ -575,6 +574,7 @@
 				005E92DE0FF0850E008965B9 /* SampleFillType.cpp in Sources */,
 				005E92E00FF08512008965B9 /* SampleFilter.cpp in Sources */,
 				0057785F0FF17CCC00582CD9 /* SampleMipMap.cpp in Sources */,
+				005778B40FF5616F00582CD9 /* SampleShapes.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};