am 9f49e0e2: ignore from gingerbread-plus-aosp

* commit '9f49e0e274e7b1fd9b7381bbaeb49e297b4296f9':
  Adding skia header changes as needed for webkit MR1 to compile
  Add SkTypeface::isFixedWidth()
diff --git a/Android.mk b/Android.mk
index f2b86d4..86210bc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,9 +15,6 @@
     LOCAL_CFLAGS += -DANDROID_LARGE_MEMORY_DEVICE
 endif
 
-# enable this if we turn on SK_DEBUG, otherwise we exceed our prelink budget
-#LOCAL_PRELINK_MODULE := false
-
 ifneq ($(ARCH_ARM_HAVE_VFP),true)
 	LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
 endif
@@ -61,11 +58,13 @@
 	src/effects/SkEmbossMask.cpp \
 	src/effects/SkEmbossMaskFilter.cpp \
 	src/effects/SkGradientShader.cpp \
+	src/effects/SkGroupShape.cpp \
 	src/effects/SkLayerDrawLooper.cpp \
 	src/effects/SkLayerRasterizer.cpp \
 	src/effects/SkPaintFlagsDrawFilter.cpp \
 	src/effects/SkPixelXorXfermode.cpp \
 	src/effects/SkPorterDuff.cpp \
+	src/effects/SkRectShape.cpp \
 	src/effects/SkTableMaskFilter.cpp \
 	src/effects/SkTransparentShader.cpp \
 	src/images/bmpdecoderhelper.cpp \
@@ -123,6 +122,7 @@
 	src/core/SkColorFilter.cpp \
 	src/core/SkColorTable.cpp \
 	src/core/SkComposeShader.cpp \
+	src/core/SkCubicClipper.cpp \
 	src/core/SkDeque.cpp \
 	src/core/SkDevice.cpp \
 	src/core/SkDither.cpp \
@@ -155,7 +155,6 @@
 	src/core/SkPtrRecorder.cpp \
 	src/core/SkQuadClipper.cpp \
 	src/core/SkRasterizer.cpp \
-	src/core/SkRefCnt.cpp \
 	src/core/SkRefDict.cpp \
 	src/core/SkRegion_path.cpp \
 	src/core/SkScalerContext.cpp \
@@ -183,7 +182,10 @@
 	src/utils/SkLayer.cpp \
 	src/utils/SkMeshUtils.cpp \
 	src/utils/SkNinePatch.cpp \
-	src/utils/SkProxyCanvas.cpp
+	src/utils/SkParse.cpp \
+	src/utils/SkParsePath.cpp \
+	src/utils/SkProxyCanvas.cpp \
+	src/utils/SkUnitMappers.cpp
 
 ifeq ($(TARGET_ARCH),arm)
 LOCAL_SRC_FILES += \
@@ -238,6 +240,77 @@
 include $(BUILD_SHARED_LIBRARY)
 
 #############################################################
+# Build the skia gpu (ganesh) library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_ARM_MODE := arm
+
+ifneq ($(ARCH_ARM_HAVE_VFP),true)
+       LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT
+endif
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+       LOCAL_CFLAGS += -D__ARM_HAVE_NEON
+endif
+
+LOCAL_SRC_FILES:= \
+  gpu/src/GrAllocPool.cpp \
+  gpu/src/GrAtlas.cpp \
+  gpu/src/GrClip.cpp \
+  gpu/src/GrContext.cpp \
+  gpu/src/GrDrawTarget.cpp \
+  gpu/src/GrGLIndexBuffer.cpp	\
+  gpu/src/GrGLInterface.cpp \
+  gpu/src/GrGLTexture.cpp \
+  gpu/src/GrGLVertexBuffer.cpp \
+  gpu/src/GrGpu.cpp \
+  gpu/src/GrGpuGLShaders2.cpp \
+  gpu/src/GrGpuGLFixed.cpp \
+  gpu/src/GrGpuFactory.cpp \
+  gpu/src/GrGLUtil.cpp \
+  gpu/src/GrGpuGL.cpp \
+  gpu/src/GrInOrderDrawBuffer.cpp \
+  gpu/src/GrMatrix.cpp \
+  gpu/src/GrMemory.cpp \
+  gpu/src/GrPath.cpp \
+  gpu/src/GrRectanizer_fifo.cpp \
+  gpu/src/GrTextureCache.cpp \
+  gpu/src/GrTextContext.cpp \
+  gpu/src/GrTextStrike.cpp \
+  gpu/src/GrBufferAllocPool.cpp\
+  gpu/src/GrPathRenderer.cpp \
+  gpu/src/GrStencil.cpp \
+  src/gpu/SkGpuCanvas.cpp	\
+  src/gpu/SkGpuDevice.cpp \
+  src/gpu/SkGr.cpp \
+  src/gpu/SkGrTexturePixelRef.cpp \
+  src/gpu/SkGrFontScaler.cpp \
+	src/gpu/GrPrintf_skia.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+  libcutils \
+  libutils \
+  libskia \
+  libEGL \
+  libGLESv2
+
+LOCAL_C_INCLUDES += \
+  $(LOCAL_PATH)/gpu/include \
+  $(LOCAL_PATH)/gpu/src \
+  $(LOCAL_PATH)/include/core \
+  $(LOCAL_PATH)/include/gpu \
+  $(LOCAL_PATH)/src/core
+
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_MODULE:= libskiagpu
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+#############################################################
 # Build the skia tools
 #
 
@@ -245,7 +318,7 @@
 include $(BASE_PATH)/bench/Android.mk
 
 # golden-master (fidelity / regression test)
-#include $(BASE_PATH)/gm/Android.mk
+include $(BASE_PATH)/gm/Android.mk
 
 # unit-tests
 include $(BASE_PATH)/tests/Android.mk
diff --git a/bench/RectBench.cpp b/bench/RectBench.cpp
index 0c3eb56..a6f300e 100644
--- a/bench/RectBench.cpp
+++ b/bench/RectBench.cpp
@@ -3,6 +3,7 @@
 #include "SkPaint.h"
 #include "SkRandom.h"
 #include "SkString.h"
+#include "SkShader.h"
 
 class RectBench : public SkBenchmark {
 public:
@@ -112,6 +113,85 @@
     virtual const char* onGetName() { return fName; }
 };
 
+/*******************************************************************************
+ * to bench BlitMask [Opaque, Black, color, shader]
+ *******************************************************************************/
+
+class BlitMaskBench : public RectBench {
+public:
+    enum kMaskType {
+        kMaskOpaque = 0,
+        kMaskBlack,
+        kMaskColor,
+        KMaskShader
+    };
+    SkCanvas::PointMode fMode;
+    const char* fName;
+
+    BlitMaskBench(void* param, SkCanvas::PointMode mode, 
+                  BlitMaskBench::kMaskType type, const char* name) :
+                  RectBench(param, 2), fMode(mode), _type(type) {
+        fName = name;
+    }
+
+protected:
+    virtual void onDraw(SkCanvas* canvas) {
+        SkScalar gSizes[] = {
+            SkIntToScalar(13), SkIntToScalar(24)
+        };
+        size_t sizes = SK_ARRAY_COUNT(gSizes);
+
+        if (this->hasStrokeWidth()) {
+            gSizes[0] = this->getStrokeWidth();
+            sizes = 1;
+        }
+        SkRandom rand;
+        SkColor color = 0xFF000000;
+        U8CPU alpha = 0xFF;
+        SkPaint paint;
+        paint.setStrokeCap(SkPaint::kRound_Cap);
+        if (_type == KMaskShader) {
+            SkBitmap srcBM;
+            srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
+            srcBM.allocPixels();
+            srcBM.eraseColor(0xFF00FF00);
+
+            SkShader* s;
+            s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
+                                              SkShader::kClamp_TileMode);
+            paint.setShader(s)->unref();
+        }
+        for (size_t i = 0; i < sizes; i++) {
+            switch (_type) {	
+                case kMaskOpaque: 
+                    color = fColors[i]; 
+                    alpha = 0xFF; 
+                    break;
+                case kMaskBlack: 
+                    alpha = 0xFF;
+                    color = 0xFF000000;
+                    break;
+                case kMaskColor:
+                    color = fColors[i]; 
+                    alpha = rand.nextU() & 255;
+                    break;
+                case KMaskShader:
+                    break;
+            }
+            paint.setStrokeWidth(gSizes[i]);
+            this->setupPaint(&paint);
+            paint.setColor(color);
+            paint.setAlpha(alpha);
+            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
+       }
+    }
+    virtual const char* onGetName() { return fName; }
+private:
+	typedef RectBench INHERITED;
+	kMaskType _type;
+};
+
+
 static SkBenchmark* RectFactory1(void* p) { return SkNEW_ARGS(RectBench, (p, 1)); }
 static SkBenchmark* RectFactory2(void* p) { return SkNEW_ARGS(RectBench, (p, 3)); }
 static SkBenchmark* OvalFactory1(void* p) { return SkNEW_ARGS(OvalBench, (p, 1)); }
@@ -128,6 +208,32 @@
     return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon"));
 }
 
+/* init the blitmask bench
+ */
+static SkBenchmark* BlitMaskOpaqueFactory(void* p) {
+    return SkNEW_ARGS(BlitMaskBench,
+                      (p, SkCanvas::kPoints_PointMode,
+                      BlitMaskBench::kMaskOpaque, "maskopaque")
+                      );
+}
+static SkBenchmark* BlitMaskBlackFactory(void* p) {
+    return SkNEW_ARGS(BlitMaskBench,
+                      (p, SkCanvas::kPoints_PointMode,
+                      BlitMaskBench::kMaskBlack, "maskblack")
+                      );
+}
+static SkBenchmark* BlitMaskColorFactory(void* p) {
+    return SkNEW_ARGS(BlitMaskBench,
+                      (p, SkCanvas::kPoints_PointMode,
+                      BlitMaskBench::kMaskColor, "maskcolor")
+                      );
+}
+static SkBenchmark* BlitMaskShaderFactory(void* p) {
+    return SkNEW_ARGS(BlitMaskBench,
+                     (p, SkCanvas::kPoints_PointMode,
+                     BlitMaskBench::KMaskShader, "maskshader")
+                     );
+}
 static BenchRegistry gRectReg1(RectFactory1);
 static BenchRegistry gRectReg2(RectFactory2);
 static BenchRegistry gOvalReg1(OvalFactory1);
@@ -137,3 +243,7 @@
 static BenchRegistry gPointsReg(PointsFactory);
 static BenchRegistry gLinesReg(LinesFactory);
 static BenchRegistry gPolygonReg(PolygonFactory);
+static BenchRegistry gRectRegOpaque(BlitMaskOpaqueFactory);
+static BenchRegistry gRectRegBlack(BlitMaskBlackFactory);
+static BenchRegistry gRectRegColor(BlitMaskColorFactory);
+static BenchRegistry gRectRegShader(BlitMaskShaderFactory);
diff --git a/gm/Android.mk b/gm/Android.mk
index 6861e16..e7960d4 100644
--- a/gm/Android.mk
+++ b/gm/Android.mk
@@ -3,27 +3,40 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-	filltypes.cpp \
+  bitmapfilters.cpp \
+  blurs.cpp \
+  complexclip.cpp \
+  filltypes.cpp \
   gradients.cpp \
-	tilemodes.cpp \
-	bitmapfilters.cpp \
-	xfermodes.cpp \
-	gmmain.cpp
+  points.cpp \
+  poly2poly.cpp \
+  shadertext.cpp \
+  shadows.cpp \
+  shapes.cpp \
+  tilemodes.cpp \
+  xfermodes.cpp \
+  gmmain.cpp
 
 # additional optional class for this tool
 LOCAL_SRC_FILES += \
-	../src/utils/SkUnitMappers.cpp \
-	../src/utils/SkEGLContext_none.cpp
+  ../src/utils/SkEGLContext_none.cpp
 
-LOCAL_SHARED_LIBRARIES := libcutils libskia
+LOCAL_STATIC_LIBRARIES := libskiagpu
+LOCAL_SHARED_LIBRARIES := \
+  libcutils \
+  libutils \
+  libskia \
+  libEGL \
+  libGLESv2
+  
 LOCAL_C_INCLUDES := \
-    external/skia/include/config \
-    external/skia/include/core \
-    external/skia/include/images \
-    external/skia/include/utils \
-    external/skia/include/effects \
-    external/skia/gpu/include \
-    external/skia/include/gpu
+  external/skia/include/config \
+  external/skia/include/core \
+  external/skia/include/images \
+  external/skia/include/utils \
+  external/skia/include/effects \
+  external/skia/gpu/include \
+  external/skia/include/gpu
 
 #LOCAL_CFLAGS := 
 
diff --git a/gm/blurs.cpp b/gm/blurs.cpp
index 8250d76..26fdc79 100644
--- a/gm/blurs.cpp
+++ b/gm/blurs.cpp
@@ -74,7 +74,7 @@
                 canvas->drawText("Hamburgefons Style", 18, x, y, paint);
             }
             canvas->restore();
-//            flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
+            flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
             canvas->translate(350, 0);
         }
     }
diff --git a/gm/complexclip.cpp b/gm/complexclip.cpp
new file mode 100644
index 0000000..867d230
--- /dev/null
+++ b/gm/complexclip.cpp
@@ -0,0 +1,152 @@
+#include "gm.h"
+#include "SkCanvas.h"
+//#include "SkParsePath.h"
+#include "SkPath.h"
+//#include "SkRandom.h"
+
+namespace skiagm {
+
+class ComplexClipGM : public GM {
+public:
+	ComplexClipGM() {
+    }
+
+protected:
+
+    SkString onShortName() {
+        return SkString("complexclip");
+    }
+
+    SkISize onISize() { return make_isize(550, 1000); }
+
+    void drawBG(SkCanvas* canvas) {
+        canvas->drawColor(SkColorSetRGB(0xA0,0xDD,0xA0));
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        SkPath path;
+        path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
+        path.quadTo(SkIntToScalar(0),   SkIntToScalar(0),   SkIntToScalar(50),  SkIntToScalar(0));
+        path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
+        path.quadTo(SkIntToScalar(200), SkIntToScalar(0),   SkIntToScalar(200), SkIntToScalar(25));
+        path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
+        path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
+        path.lineTo(SkIntToScalar(0),   SkIntToScalar(200));
+        path.close();
+        path.moveTo(SkIntToScalar(50),  SkIntToScalar(50));
+        path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
+        path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
+        path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
+        path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
+        path.close();
+        path.setFillType(SkPath::kEvenOdd_FillType);
+        SkColor pathColor = SK_ColorBLACK;
+        SkPaint pathPaint;
+        pathPaint.setAntiAlias(true);
+        pathPaint.setColor(pathColor);
+
+        SkPath clipA;
+        clipA.moveTo(SkIntToScalar(10),  SkIntToScalar(20));
+        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
+        clipA.lineTo(SkIntToScalar(70),  SkIntToScalar(105));
+        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
+        clipA.lineTo(SkIntToScalar(-5),  SkIntToScalar(180));
+        clipA.close();
+        SkColor colorA = SK_ColorCYAN;
+
+        SkPath clipB;
+        clipB.moveTo(SkIntToScalar(40),  SkIntToScalar(10));
+        clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
+        clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
+        clipB.lineTo(SkIntToScalar(40),  SkIntToScalar(185));
+        clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
+        clipB.close();
+        SkColor colorB = SK_ColorRED;
+
+        drawBG(canvas);
+        SkPaint paint;
+        paint.setAntiAlias(true);
+
+        paint.setStyle(SkPaint::kStroke_Style);
+        paint.setStrokeWidth(0);
+
+        canvas->translate(SkIntToScalar(10),SkIntToScalar(10));
+        canvas->drawPath(path, pathPaint);
+        paint.setColor(colorA);
+        canvas->drawPath(clipA, paint);
+        paint.setColor(colorB);
+        canvas->drawPath(clipB, paint);
+
+        static const struct {
+            SkRegion::Op fOp;
+            const char*  fName;
+        } gOps[] = { //extra spaces in names for measureText
+            {SkRegion::kIntersect_Op,         "Isect "},
+            {SkRegion::kDifference_Op,        "Diff " },
+            {SkRegion::kUnion_Op,             "Union "},
+            {SkRegion::kXOR_Op,               "Xor "  },
+            {SkRegion::kReverseDifference_Op, "RDiff "}
+        };
+
+        canvas->translate(0, SkIntToScalar(40));
+        canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
+        canvas->save();
+
+        for (int invA = 0; invA < 2; ++invA) {
+            for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
+                int idx = invA * SK_ARRAY_COUNT(gOps) + op;
+                if (!(idx % 3)) {
+                    canvas->restore();
+                    canvas->translate(0, SkIntToScalar(250));
+                    canvas->save();
+                }
+                canvas->save();
+                    // set clip
+                    clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType :
+                                             SkPath::kEvenOdd_FillType);
+                    canvas->clipPath(clipA);
+                    canvas->clipPath(clipB, gOps[op].fOp);
+
+                    // draw path clipped
+                    canvas->drawPath(path, pathPaint);
+                canvas->restore();
+
+                // draw path in hairline
+                paint.setColor(pathColor);
+                canvas->drawPath(path, paint);
+
+                // draw clips in hair line
+                paint.setColor(colorA);
+                canvas->drawPath(clipA, paint);
+                paint.setColor(colorB);
+                canvas->drawPath(clipB, paint);
+
+                paint.setTextSize(SkIntToScalar(20));
+
+                SkScalar txtX = SkIntToScalar(55);
+                paint.setColor(colorA);
+                const char* aTxt = invA ? "InverseA " : "A ";
+                canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint);
+                txtX += paint.measureText(aTxt, strlen(aTxt));
+                paint.setColor(SK_ColorBLACK);
+                canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
+                                    txtX, SkIntToScalar(220), paint);
+                txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
+                paint.setColor(colorB);
+                canvas->drawText("B", 1, txtX, SkIntToScalar(220), paint);
+
+                canvas->translate(SkIntToScalar(250),0);
+            }
+        }
+        canvas->restore();
+    }
+private:
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new ComplexClipGM; }
+static GMRegistry reg(MyFactory);
+
+}
diff --git a/gm/gm_files.mk b/gm/gm_files.mk
deleted file mode 100644
index 2f7769e..0000000
--- a/gm/gm_files.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-SOURCE := \
-	bitmapfilters.cpp \
-	blurs.cpp \
-	filltypes.cpp \
-	gradients.cpp \
-	points.cpp \
-	poly2poly.cpp \
-	shapes.cpp \
-	tilemodes.cpp \
-	xfermodes.cpp \
-	shadertext.cpp \
-	gmmain.cpp
diff --git a/gm/shadows.cpp b/gm/shadows.cpp
new file mode 100644
index 0000000..5afde49
--- /dev/null
+++ b/gm/shadows.cpp
@@ -0,0 +1,99 @@
+#include "gm.h"
+#include "SkPicture.h"
+#include "SkRectShape.h"
+#include "SkBlurDrawLooper.h"
+
+namespace skiagm {
+
+///////////////////////////////////////////////////////////////////////////////
+
+class ShadowsGM : public GM {
+
+public:
+    SkPath fCirclePath;
+    SkPaint fPaint;
+    SkRectShape fRectShape;
+    ShadowsGM() {
+        fCirclePath.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(10) );
+    fPaint.setStrokeWidth(SkIntToScalar(4));
+    fPaint.setAntiAlias(true);
+    fPaint.setColor(0xFF00FF00);
+    fPaint.setStyle(SkPaint::kStroke_Style); 
+    SkRect rect;
+    rect.set(SkIntToScalar(10), SkIntToScalar(10),
+             SkIntToScalar(30), SkIntToScalar(30));
+    fRectShape.setRect(rect);
+    fRectShape.paint().setColor(SK_ColorRED);
+    }
+
+    virtual ~ShadowsGM() {
+    }
+
+protected:
+    virtual SkString onShortName() {
+        return SkString("shadows");
+    }
+
+    virtual SkISize onISize() {
+        return make_isize(200, 80);
+    }
+
+    void drawBG(SkCanvas* canvas) {
+        canvas->drawColor(0xFFDDDDDD);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        this->drawBG(canvas);
+
+    SkBlurDrawLooper* shadowLoopers[5];
+    shadowLoopers[0] =
+        new SkBlurDrawLooper (10, 5, 10, 0xFF0000FF, 
+                              SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
+                              SkBlurDrawLooper::kOverrideColor_BlurFlag |
+                              SkBlurDrawLooper::kHighQuality_BlurFlag );
+    SkAutoUnref aurL0(shadowLoopers[0]);
+    shadowLoopers[1] =
+        new SkBlurDrawLooper (10, 5, 10, 0xFF0000FF, 
+                              SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
+                              SkBlurDrawLooper::kOverrideColor_BlurFlag );
+    SkAutoUnref aurL1(shadowLoopers[1]);
+    shadowLoopers[2] =
+        new SkBlurDrawLooper (5, 5, 10, 0xFF000000,
+                              SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
+                              SkBlurDrawLooper::kHighQuality_BlurFlag  );
+    SkAutoUnref aurL2(shadowLoopers[2]);
+    shadowLoopers[3] =
+        new SkBlurDrawLooper (5, -5 ,-10, 0x7FFF0000, 
+                              SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
+                              SkBlurDrawLooper::kOverrideColor_BlurFlag |
+                              SkBlurDrawLooper::kHighQuality_BlurFlag  );
+    SkAutoUnref aurL3(shadowLoopers[3]);
+    shadowLoopers[4] =
+        new SkBlurDrawLooper (0, 5, 5, 0xFF000000, 
+                              SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
+                              SkBlurDrawLooper::kOverrideColor_BlurFlag |
+                              SkBlurDrawLooper::kHighQuality_BlurFlag  );
+    SkAutoUnref aurL4(shadowLoopers[4]);
+
+    for (int looper = 0; looper < 5; looper ++)
+    {
+        fRectShape.paint().setLooper(shadowLoopers[looper]);
+        canvas->resetMatrix();
+        canvas->translate(SkIntToScalar(looper*40), SkIntToScalar(0));
+        canvas->drawShape(&fRectShape);
+        fPaint.setLooper(shadowLoopers[looper]); 
+        canvas->translate(SkIntToScalar(0), SkIntToScalar(40));
+        canvas->drawPath(fCirclePath, fPaint);
+    }
+}
+
+private:
+    typedef GM INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new ShadowsGM; }
+static GMRegistry reg(MyFactory);
+
+}
diff --git a/gpu/include/FlingState.h b/gpu/include/FlingState.h
new file mode 100644
index 0000000..a1da4fb
--- /dev/null
+++ b/gpu/include/FlingState.h
@@ -0,0 +1,59 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkFlingState_DEFINED
+#define SkFlingState_DEFINED
+
+#include "SkScalar.h"
+#include "SkPoint.h"
+
+class SkMatrix;
+
+struct FlingState {
+    FlingState() : fActive(false) {}
+
+    bool isActive() const { return fActive; }
+    void stop() { fActive = false; }
+
+    void reset(float sx, float sy);
+    bool evaluateMatrix(SkMatrix* matrix);
+
+private:
+    SkPoint     fDirection;
+    SkScalar    fSpeed0;
+    double      fTime0;
+    bool        fActive;
+};
+
+class GrAnimateFloat {
+public:
+    GrAnimateFloat();
+
+    void start(float v0, float v1, float duration);
+    bool isActive() const { return fTime0 != 0; }
+    void stop() { fTime0 = 0; }
+
+    float evaluate();
+
+private:
+    float   fValue0, fValue1, fDuration;
+    SkMSec  fTime0;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrAllocPool.h b/gpu/include/GrAllocPool.h
new file mode 100644
index 0000000..251c0b4
--- /dev/null
+++ b/gpu/include/GrAllocPool.h
@@ -0,0 +1,71 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAllocPool_DEFINED
+#define GrAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAllocPool : GrNoncopyable {
+public:
+    GrAllocPool(size_t blockSize = 0);
+    ~GrAllocPool();
+
+    /**
+     *  Frees all blocks that have been allocated with alloc().
+     */
+    void reset();
+
+    /**
+     *  Returns a block of memory bytes size big. This address must not be
+     *  passed to realloc/free/delete or any other function that assumes the
+     *  address was allocated by malloc or new (because it hasn't).
+     */
+    void* alloc(size_t bytes);
+    
+    /**
+     * Releases the most recently allocated bytes back to allocpool.
+     */
+    void release(size_t bytes);
+
+private:
+    struct Block;
+
+    Block*  fBlock;
+    size_t  fMinBlockSize;
+
+#if GR_DEBUG
+    int fBlocksAllocated;
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+};
+
+template <typename T> class GrTAllocPool {
+public:
+    GrTAllocPool(int count) : fPool(count * sizeof(T)) {}
+
+    void reset() { fPool.reset(); }
+    T* alloc() { return (T*)fPool.alloc(sizeof(T)); }
+
+private:
+    GrAllocPool fPool;
+};
+
+#endif
+
diff --git a/gpu/include/GrAllocator.h b/gpu/include/GrAllocator.h
new file mode 100755
index 0000000..da02ba4
--- /dev/null
+++ b/gpu/include/GrAllocator.h
@@ -0,0 +1,230 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAllocator_DEFINED
+#define GrAllocator_DEFINED
+
+#include "GrConfig.h"
+#include "GrTArray.h"
+
+class GrAllocator {
+public:
+    virtual ~GrAllocator() {
+        reset();
+    }
+
+    /**
+     * Create an allocator
+     *
+     * @param   itemSize        the size of each item to allocate
+     * @param   itemsPerBlock   the number of items to allocate at once
+     * @param   initialBlock    optional memory to use for the first block.
+     *                          Must be at least itemSize*itemsPerBlock sized.
+     *                          Caller is responsible for freeing this memory.
+     */
+    GrAllocator(size_t itemSize, uint32_t itemsPerBlock, void* initialBlock) :
+            fBlocks(fBlockInitialStorage, NUM_INIT_BLOCK_PTRS),
+            fItemSize(itemSize),
+            fItemsPerBlock(itemsPerBlock),
+            fOwnFirstBlock(NULL == initialBlock),
+            fCount(0) {
+        fBlockSize = fItemSize * fItemsPerBlock;
+        fBlocks.push_back() = initialBlock;
+        GR_DEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
+    }
+
+    /**
+     * Adds an item and returns pointer to it.
+     *
+     * @return pointer to the added item.
+     */
+    void* push_back() {        
+        uint32_t indexInBlock = fCount % fItemsPerBlock;
+        // we always have at least one block
+        if (0 == indexInBlock) {
+            if (0 != fCount) {
+                fBlocks.push_back() = GrMalloc(fBlockSize);
+            } else if (fOwnFirstBlock) {
+                fBlocks[0] = GrMalloc(fBlockSize);
+            }
+        }        
+        void* ret = (char*)fBlocks[fCount/fItemsPerBlock] + 
+                    fItemSize * indexInBlock;
+        ++fCount;
+        return ret;
+    }
+
+    /**
+     * removes all added items
+     */
+    void reset() {        
+        uint32_t blockCount = GrMax((unsigned)1, 
+                                    GrUIDivRoundUp(fCount, fItemsPerBlock));
+        for (uint32_t i = 1; i < blockCount; ++i) {
+            GrFree(fBlocks[i]);
+        }
+        if (fOwnFirstBlock) {
+            GrFree(fBlocks[0]);
+            fBlocks[0] = NULL;
+        }
+        fBlocks.pop_back_n(blockCount-1);
+        fCount = 0;
+    }
+
+    /**
+     * count of items
+     */
+    uint32_t count() const {
+        return fCount;
+    }
+    
+    /**
+     * is the count 0
+     */
+    bool empty() const { return fCount == 0; }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    void* back() {
+        GrAssert(fCount);
+        return (*this)[fCount-1];
+    }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    const void* back() const {
+        GrAssert(fCount);
+        return (*this)[fCount-1];
+    }
+    
+    /**
+     * access item by index.
+     */    
+    void* operator[] (uint32_t i) {
+        GrAssert(i < fCount);
+        return (char*)fBlocks[i / fItemsPerBlock] + 
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+    /**
+     * access item by index.
+     */  
+    const void* operator[] (uint32_t i) const {
+        GrAssert(i < fCount);
+        return (const char*)fBlocks[i / fItemsPerBlock] + 
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+private:
+    static const uint32_t NUM_INIT_BLOCK_PTRS = 8;
+    
+    GrTArray<void*> fBlocks;
+    size_t          fBlockSize;    
+    char            fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];    
+    size_t          fItemSize;
+    uint32_t        fItemsPerBlock;
+    bool            fOwnFirstBlock;
+    uint32_t        fCount;    
+};
+
+template <typename T>
+class GrTAllocator {
+private:
+    GrAllocator fAllocator;
+    
+public:
+    virtual ~GrTAllocator() {};
+    
+    /**
+     * Create an allocator
+     *
+     * @param   itemsPerBlock   the number of items to allocate at once
+     * @param   initialBlock    optional memory to use for the first block.
+     *                          Must be at least size(T)*itemsPerBlock sized.
+     *                          Caller is responsible for freeing this memory.
+     */
+    GrTAllocator(uint32_t itemsPerBlock, void* initialBlock) :
+        fAllocator(sizeof(T), itemsPerBlock, initialBlock)
+    {}
+    
+    /**
+     * Adds an item and returns it.
+     *
+     * @return the added item.
+     */
+    T& push_back() {
+        void* item = fAllocator.push_back();
+        GrAssert(NULL != item);
+        new (item) T;
+        return *(T*)item;
+    }
+    
+    /**
+     * removes all added items
+     */
+    void reset() {
+        uint32_t c = fAllocator.count();
+        for (uint32_t i = 0; i < c; ++i) {
+            ((T*)fAllocator[i])->~T();
+        }
+        fAllocator.reset();
+    }
+    
+    /**
+     * count of items
+     */
+    uint32_t count() const {
+        return fAllocator.count();
+    }
+    
+    /**
+     * is the count 0
+     */
+    bool empty() const { return fAllocator.empty(); }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    T& back() {
+        return *(T*)fAllocator.back();
+    }
+
+    /**
+     * access last item, only call if count() != 0
+     */
+    const T& back() const {
+        return *(const T*)fAllocator.back();
+    }
+
+    /**
+     * access item by index.
+     */  
+    T& operator[] (uint32_t i) {
+        return *(T*)(fAllocator[i]);
+    }
+    
+    /**
+     * access item by index.
+     */
+    const T& operator[] (uint32_t i) const {
+        return *(const T*)(fAllocator[i]);
+    }    
+};
+
+#endif
diff --git a/gpu/include/GrAtlas.h b/gpu/include/GrAtlas.h
new file mode 100644
index 0000000..a933842
--- /dev/null
+++ b/gpu/include/GrAtlas.h
@@ -0,0 +1,93 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAtlas_DEFINED
+#define GrAtlas_DEFINED
+
+#include "GrPoint.h"
+#include "GrTexture.h"
+#include "GrTDArray.h"
+
+class GrGpu;
+class GrRectanizer;
+class GrAtlasMgr;
+
+class GrAtlas {
+public:
+    GrAtlas(GrAtlasMgr*, int plotX, int plotY, GrMaskFormat);
+
+    int getPlotX() const { return fPlot.fX; }
+    int getPlotY() const { return fPlot.fY; }
+    GrMaskFormat getMaskFormat() const { return fMaskFormat; }
+
+    GrTexture* texture() const { return fTexture; }
+
+    bool addSubImage(int width, int height, const void*, GrIPoint16*);
+
+    static void FreeLList(GrAtlas* atlas) {
+        while (atlas) {
+            GrAtlas* next = atlas->fNext;
+            delete atlas;
+            atlas = next;
+        }
+    }
+
+    // testing
+    GrAtlas* nextAtlas() const { return fNext; }
+
+private:
+    ~GrAtlas(); // does not try to delete the fNext field
+
+    GrAtlas*        fNext;
+    GrTexture*      fTexture;
+    GrRectanizer*   fRects;
+    GrAtlasMgr*     fAtlasMgr;
+    GrIPoint16      fPlot;
+    GrMaskFormat    fMaskFormat;
+
+    friend class GrAtlasMgr;
+};
+
+class GrPlotMgr;
+
+class GrAtlasMgr {
+public:
+    GrAtlasMgr(GrGpu*);
+    ~GrAtlasMgr();
+
+    GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
+                        GrMaskFormat, GrIPoint16*);
+
+    GrTexture* getTexture(GrMaskFormat format) const {
+        GrAssert((unsigned)format < kCount_GrMaskFormats);
+        return fTexture[format];
+    }
+
+    // to be called by ~GrAtlas()
+    void freePlot(int x, int y);
+
+    void abandonAll();
+
+private:
+    GrGpu*      fGpu;
+    GrTexture*  fTexture[kCount_GrMaskFormats];
+    GrPlotMgr*  fPlotMgr;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrClip.h b/gpu/include/GrClip.h
new file mode 100644
index 0000000..54082b7
--- /dev/null
+++ b/gpu/include/GrClip.h
@@ -0,0 +1,147 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrClip_DEFINED
+#define GrClip_DEFINED
+
+#include "GrClipIterator.h"
+#include "GrRect.h"
+#include "GrPath.h"
+#include "GrTArray.h"
+
+
+class GrClip {
+public:
+    GrClip();
+    GrClip(const GrClip& src);
+    /**
+     *  If specified, the conservativeBounds parameter already takes (tx,ty)
+     *  into account.
+     */
+    GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+           const GrRect* conservativeBounds = NULL);
+    GrClip(const GrIRect& rect);
+    GrClip(const GrRect& rect);
+
+    ~GrClip();
+
+    GrClip& operator=(const GrClip& src);
+
+    bool hasConservativeBounds() const { return fConservativeBoundsValid; }
+
+    const GrRect& getConservativeBounds() const { return fConservativeBounds; }
+
+    int getElementCount() const { return fList.count(); }
+
+    GrClipType getElementType(int i) const { return fList[i].fType; }
+
+    const GrPath& getPath(int i) const {
+        GrAssert(kPath_ClipType == fList[i].fType);
+        return fList[i].fPath;
+    }
+
+    GrPathFill getPathFill(int i) const {
+        GrAssert(kPath_ClipType == fList[i].fType);
+        return fList[i].fPathFill;
+    }
+
+    const GrRect& getRect(int i) const {
+        GrAssert(kRect_ClipType == fList[i].fType);
+        return fList[i].fRect;
+    }
+
+    GrSetOp getOp(int i) const { return fList[i].fOp; }
+
+    bool isRect() const {
+        if (1 == fList.count() && kRect_ClipType == fList[0].fType) {
+            // if we determined that the clip is a single rect
+            // we ought to have also used that rect as the bounds.
+            GrAssert(fConservativeBoundsValid);
+            GrAssert(fConservativeBounds == fList[0].fRect);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    bool isEmpty() const { return 0 == fList.count(); }
+
+    /**
+     *  Resets this clip to be empty
+     */
+    void setEmpty();
+
+    /**
+     *  If specified, the bounds parameter already takes (tx,ty) into account.
+     */
+    void setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+                         const GrRect* conservativeBounds = NULL);
+    void setFromRect(const GrRect& rect);
+    void setFromIRect(const GrIRect& rect);
+
+    friend bool operator==(const GrClip& a, const GrClip& b) {
+        if (a.fList.count() != b.fList.count()) {
+            return false;
+        }
+        int count = a.fList.count();
+        for (int i = 0; i < count; ++i) {
+            if (a.fList[i] != b.fList[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+    friend bool operator!=(const GrClip& a, const GrClip& b) {
+        return !(a == b);
+    }
+
+private:
+    struct Element {
+        GrClipType  fType;
+        GrRect      fRect;
+        GrPath      fPath;
+        GrPathFill  fPathFill;
+        GrSetOp     fOp;
+        bool operator ==(const Element& e) const {
+            if (e.fType != fType || e.fOp != fOp) {
+                return false;
+            }
+            switch (fType) {
+                case kRect_ClipType:
+                    return fRect == e.fRect;
+                    break;
+                case kPath_ClipType:
+                    return fPath == e.fPath;
+                default:
+                    GrCrash("Unknown clip element type.");
+                    return false; // suppress warning
+            }
+        }
+        bool operator !=(const Element& e) const { return !(*this == e); }
+    };
+
+    GrRect              fConservativeBounds;
+    bool                fConservativeBoundsValid;
+
+    enum {
+        kPreAllocElements = 4,
+    };
+    uint8_t             fListMemory[sizeof(Element) * kPreAllocElements];
+    GrTArray<Element>   fList;
+};
+#endif
+
diff --git a/gpu/include/GrClipIterator.h b/gpu/include/GrClipIterator.h
new file mode 100644
index 0000000..1fcbdd1
--- /dev/null
+++ b/gpu/include/GrClipIterator.h
@@ -0,0 +1,87 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrClipIterator_DEFINED
+#define GrClipIterator_DEFINED
+
+#include "GrPath.h"
+#include "GrRect.h"
+
+/**
+ * A clip is a list of paths and/or rects with set operations to combine them.
+ */
+class GrClipIterator {
+public:
+    virtual ~GrClipIterator() {}
+
+    /**
+     *  Returns true if there are no more rects to process
+     */
+    virtual bool isDone() const = 0;
+
+    /**
+     *  Rewind the iterator to replay the set of clip elements again
+     */
+    virtual void rewind() = 0;
+
+    /**
+     * Get the type of the current clip element
+     */
+    virtual GrClipType getType() const = 0;
+
+    /**
+     * Return the current path. It is an error to call this when isDone() is
+     * true or when getType() is kRect_Type.
+     */
+    virtual GrPathIter* getPathIter() = 0;
+
+    /**
+     * Return the fill rule for the path. It is an error to call this when
+     * isDone() is true or when getType is kRect_Type.
+     */
+    virtual GrPathFill getPathFill() const = 0;
+
+    /**
+    * Return the current rect. It is an error to call this when isDone is true
+    * or when getType() is kPath_Type.
+    */
+    virtual void getRect(GrRect* rect) const = 0;
+
+    /**
+     * Gets the operation used to apply the current item to previously iterated
+     * items. Iterators should not produce a Replace op.
+     */
+    virtual GrSetOp getOp() const = 0;
+
+    /**
+     *  Call to move to the next element in the list, previous path iter can be
+     *  made invalid.
+     */
+    virtual void next() = 0;
+};
+
+/**
+ *  Call to rewind iter, first checking to see if iter is NULL
+ */
+static inline void GrSafeRewind(GrClipIterator* iter) {
+    if (iter) {
+        iter->rewind();
+    }
+}
+
+#endif
+
diff --git a/gpu/include/GrColor.h b/gpu/include/GrColor.h
new file mode 100644
index 0000000..8dc03d2
--- /dev/null
+++ b/gpu/include/GrColor.h
@@ -0,0 +1,72 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrColor_DEFINED
+#define GrColor_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ *  GrColor is 4 bytes for R, G, B, A, in a compile-time specific order. The
+ *  components are stored premultiplied.
+ */
+typedef uint32_t GrColor;
+
+// indices for address a GrColor as an array of bytes
+
+#define GrColor_INDEX_R     0
+#define GrColor_INDEX_G     1
+#define GrColor_INDEX_B     2
+#define GrColor_INDEX_A     3
+
+// shfit amount to assign a component to a GrColor int
+
+#define GrColor_SHIFT_R     0
+#define GrColor_SHIFT_G     8
+#define GrColor_SHIFT_B     16
+#define GrColor_SHIFT_A     24
+
+/**
+ *  Pack 4 components (RGBA) into a GrColor int
+ */
+static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
+                                      unsigned b, unsigned a) {
+    GrAssert((uint8_t)r == r);
+    GrAssert((uint8_t)g == g);
+    GrAssert((uint8_t)b == b);
+    GrAssert((uint8_t)a == a);
+    return  (r << GrColor_SHIFT_R) |
+            (g << GrColor_SHIFT_G) |
+            (b << GrColor_SHIFT_B) |
+            (a << GrColor_SHIFT_A);
+}
+
+// extract a component (byte) from a GrColor int
+
+#define GrColorUnpackR(color)   (((color) >> GrColor_SHIFT_R) & 0xFF)
+#define GrColorUnpackG(color)   (((color) >> GrColor_SHIFT_G) & 0xFF)
+#define GrColorUnpackB(color)   (((color) >> GrColor_SHIFT_B) & 0xFF)
+#define GrColorUnpackA(color)   (((color) >> GrColor_SHIFT_A) & 0xFF)
+
+/**
+ *  Since premultiplied means that alpha >= color, we construct a color with
+ *  each component==255 and alpha == 0 to be "illegal"
+ */
+#define GrColor_ILLEGAL     (~(0xFF << GrColor_SHIFT_A))
+
+#endif
+
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
new file mode 100644
index 0000000..7805074
--- /dev/null
+++ b/gpu/include/GrConfig.h
@@ -0,0 +1,385 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrConfig_DEFINED
+#define GrConfig_DEFINED
+
+///////////////////////////////////////////////////////////////////////////////
+// preconfig section:
+//
+// All the work before including GrUserConfig.h should center around guessing
+// what platform we're on, and defining low-level symbols based on that.
+//
+// A build environment may have already defined symbols, so we first check
+// for that
+//
+
+// hack to ensure we know what sort of Apple platform we're on
+#if defined(__APPLE_CPP__) || defined(__APPLE_CC__)
+    #include <TargetConditionals.h>
+#endif
+
+/**
+ *  Gr defines are set to 0 or 1, rather than being undefined or defined
+ */
+
+#if !defined(GR_ANDROID_BUILD)
+    #define GR_ANDROID_BUILD    0
+#endif
+#if !defined(GR_IOS_BUILD)
+    #define GR_IOS_BUILD        0
+#endif
+#if !defined(GR_LINUX_BUILD)
+    #define GR_LINUX_BUILD      0
+#endif
+#if !defined(GR_MAC_BUILD)
+    #define GR_MAC_BUILD        0
+#endif
+#if !defined(GR_WIN32_BUILD)
+    #define GR_WIN32_BUILD      0
+#endif
+#if !defined(GR_QNX_BUILD)
+    #define GR_QNX_BUILD        0
+#endif
+
+/**
+ *  If no build target has been defined, attempt to infer.
+ */
+#if !GR_ANDROID_BUILD && !GR_IOS_BUILD && !GR_LINUX_BUILD && !GR_MAC_BUILD && !GR_WIN32_BUILD && !GR_QNX_BUILD
+    #if defined(_WIN32)
+        #undef GR_WIN32_BUILD
+        #define GR_WIN32_BUILD      1
+//      #error "WIN"
+    #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+        #undef GR_IOS_BUILD
+        #define GR_IOS_BUILD        1
+//      #error "IOS"
+    #elif (defined(ANDROID_NDK) && ANDROID_NDK) || defined(ANDROID)
+        #undef GR_ANDROID_BUILD
+        #define GR_ANDROID_BUILD    1
+//      #error "ANDROID"
+    #elif TARGET_OS_MAC
+        #undef GR_MAC_BUILD
+        #define GR_MAC_BUILD        1
+//      #error "MAC"
+    #elif TARGET_OS_QNX || defined(__QNXNTO__)
+        #undef GR_QNX_BUILD
+        #define GR_QNX_BUILD        1
+//      #error "QNX"
+    #else
+        #undef GR_LINUX_BUILD
+        #define GR_LINUX_BUILD      1
+//      #error "LINUX"
+    #endif
+#endif
+
+// we need both GR_DEBUG and GR_RELEASE to be defined as 0 or 1
+//
+#ifndef GR_DEBUG
+    #ifdef GR_RELEASE
+        #define GR_DEBUG !GR_RELEASE
+    #else
+        #ifdef NDEBUG
+            #define GR_DEBUG    0
+        #else
+            #define GR_DEBUG    1
+        #endif
+    #endif
+#endif
+
+#ifndef GR_RELEASE
+    #define GR_RELEASE  !GR_DEBUG
+#endif
+
+#if GR_DEBUG == GR_RELEASE
+    #error "GR_DEBUG and GR_RELEASE must not be the same"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+ *  Pull stdint.h in before user-config, to be sure our __STDC... macros are
+ *  defined before anyone else might try to include stdint.h
+ */
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+#include <stdint.h>
+
+/*
+ *  The "user config" file can be empty, and everything should work. It is
+ *  meant to store a given platform/client's overrides of our guess-work.
+ *
+ *  A alternate user config file can be specified by defining
+ *  GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h
+ *
+ *  e.g. it can specify GR_DEBUG/GR_RELEASE as it please, change the BUILD
+ *  target, or supply its own defines for anything else (e.g. GR_SCALAR)
+ */
+#if !defined(GR_USER_CONFIG_FILE)
+    #include "GrUserConfig.h"
+#else
+    #include GR_USER_CONFIG_FILE
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// postconfig section:
+//
+// By now we must have a GR_..._BUILD symbol set to 1, and a decision about
+// debug -vs- release
+//
+
+extern void GrPrintf(const char format[], ...);
+
+/**
+ *  GR_STRING makes a string of X where X is expanded before conversion to a string
+ *  if X itself contains macros.
+ */
+#define GR_STRING(X) GR_STRING_IMPL(X)
+#define GR_STRING_IMPL(X) #X
+
+/**
+ *  GR_CONCAT concatenates X and Y  where each is expanded before
+ *  contanenation if either contains macros.
+ */
+#define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y)
+#define GR_CONCAT_IMPL(X,Y) X##Y
+
+/**
+ *  Creates a string of the form "<filename>(<linenumber>) : "
+ */
+#define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : "
+
+/**
+ *  Compilers have different ways of issuing warnings. This macro
+ *  attempts to abstract them, but may need to be specialized for your
+ *  particular compiler.
+ *  To insert compiler warnings use "#pragma message GR_WARN(<string>)"
+ */
+#if defined(_MSC_VER) && _MSC_VER
+    #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG)
+#else//__GNUC__ - may need other defines for different compilers
+    #define GR_WARN(MSG) ("WARNING: " MSG)
+#endif
+
+/**
+ *  GR_ALWAYSBREAK is an unconditional break in all builds.
+ */
+#if !defined(GR_ALWAYSBREAK)
+    #if     GR_WIN32_BUILD
+        #define GR_ALWAYSBREAK __debugbreak()
+    #else
+        // TODO: do other platforms really not have continuable breakpoints?
+        // sign extend for 64bit architectures to be sure this is
+        // in the high address range
+        #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
+    #endif
+#endif
+
+/**
+ *  GR_DEBUGBREAK is an unconditional break in debug builds.
+ */
+#if !defined(GR_DEBUGBREAK)
+    #if GR_DEBUG
+        #define GR_DEBUGBREAK GR_ALWAYSBREAK
+    #else
+        #define GR_DEBUGBREAK
+    #endif
+#endif
+
+/**
+ *  GR_ALWAYSASSERT is an assertion in all builds.
+ */
+#if !defined(GR_ALWAYSASSERT)
+    #define GR_ALWAYSASSERT(COND)                                        \
+        do {                                                             \
+            if (!(COND)) {                                               \
+                GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \
+                GR_ALWAYSBREAK;                                          \
+            }                                                            \
+        } while (false)
+#endif
+
+/**
+ *  GR_DEBUGASSERT is an assertion in debug builds only.
+ */
+#if !defined(GR_DEBUGASSERT)
+    #if GR_DEBUG
+        #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND)
+    #else
+        #define GR_DEBUGASSERT(COND)
+    #endif
+#endif
+
+/**
+ *  Prettier forms of the above macros.
+ */
+#define GrAssert(COND) GR_DEBUGASSERT(COND)
+#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
+
+/**
+ * Crash from unrecoverable condition, optionally with a message.
+ */
+inline void GrCrash() { GrAlwaysAssert(false); }
+inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
+
+/**
+ *  GR_DEBUGCODE compiles the code X in debug builds only
+ */
+#if !defined(GR_DEBUGCODE)
+    #if GR_DEBUG
+        #define GR_DEBUGCODE(X) X
+    #else
+        #define GR_DEBUGCODE(X)
+    #endif
+#endif
+
+/**
+ *  GR_STATIC_ASSERT is a compile time assertion. Depending on the platform
+ *  it may print the message in the compiler log. Obviously, the condition must
+ *  be evaluatable at compile time.
+ */
+// VS 2010 and GCC compiled with c++0x or gnu++0x support the new
+// static_assert.
+#if !defined(GR_STATIC_ASSERT)
+    #if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)
+        #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug")
+    #else
+        template <bool> class GR_STATIC_ASSERT_FAILURE;
+        template <> class GR_STATIC_ASSERT_FAILURE<true> {};
+        #define GR_STATIC_ASSERT(CONDITION) \
+            enum {GR_CONCAT(X,__LINE__) = \
+            sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)}
+    #endif
+#endif
+
+#if !defined(GR_SCALAR_IS_FLOAT)
+    #define GR_SCALAR_IS_FLOAT   0
+#endif
+#if !defined(GR_SCALAR_IS_FIXED)
+    #define GR_SCALAR_IS_FIXED   0
+#endif
+
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_USHORT)
+    #define GR_TEXT_SCALAR_TYPE_IS_USHORT  0
+#endif
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FLOAT)
+    #define GR_TEXT_SCALAR_TYPE_IS_FLOAT   0
+#endif
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FIXED)
+    #define GR_TEXT_SCALAR_TYPE_IS_FIXED   0
+#endif
+
+#ifndef GR_DUMP_TEXTURE_UPLOAD
+    #define GR_DUMP_TEXTURE_UPLOAD  0
+#endif
+
+/**
+ *  GR_COLLECT_STATS controls whether the GrGpu class collects stats.
+ *  If not already defined then collect in debug build but not release.
+ */
+#if !defined(GR_COLLECT_STATS)
+    #define GR_COLLECT_STATS GR_DEBUG
+#endif
+
+/**
+ *  GR_STATIC_RECT_VB controls whether rects are drawn by issuing a vertex
+ *  for each corner or using a static vb that is positioned by modifying the
+ *  view / texture matrix.
+ */
+#if !defined(GR_STATIC_RECT_VB)
+    #define GR_STATIC_RECT_VB 0
+#endif
+
+/**
+ *  GR_AGGRESSIVE_SHADER_OPTS controls how aggressively shaders are optimized
+ *  for special cases. On systems where program changes are expensive this
+ *  may not be advantageous. Consecutive draws may no longer use the same
+ *  program.
+ */
+#if !defined(GR_AGGRESSIVE_SHADER_OPTS)
+    #define GR_AGGRESSIVE_SHADER_OPTS 0
+#endif
+
+/**
+ * GR_GEOM_BUFFER_LOCK_THRESHOLD gives a threshold (in bytes) for when Gr should
+ * lock a GrGeometryBuffer to update its contents. It will use Lock() if the
+ * size of the udpated region is greater than the threshold. Otherwise it will
+ * use updateData() or updateSubData().
+ */
+#if !defined(GR_GEOM_BUFFER_LOCK_THRESHOLD)
+    #define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// tail section:
+//
+// Now we just assert if we are missing some required define, or if we detect
+// and inconsistent combination of defines
+//
+
+
+/**
+ *  Only one build target macro should be 1 and the rest should be 0.
+ */
+#define GR_BUILD_SUM    (GR_WIN32_BUILD + GR_MAC_BUILD + GR_IOS_BUILD + GR_ANDROID_BUILD + GR_LINUX_BUILD + GR_QNX_BUILD)
+#if 0 == GR_BUILD_SUM
+    #error "Missing a GR_BUILD define"
+#elif 1 != GR_BUILD_SUM
+    #error "More than one GR_BUILD defined"
+#endif
+
+
+#if !GR_SCALAR_IS_FLOAT && !GR_SCALAR_IS_FIXED
+    #undef  GR_SCALAR_IS_FLOAT
+    #define GR_SCALAR_IS_FLOAT              1
+    #pragma message GR_WARN("Scalar type not defined, defaulting to float")
+#endif
+
+#if !GR_TEXT_SCALAR_IS_FLOAT && \
+    !GR_TEXT_SCALAR_IS_FIXED && \
+    !GR_TEXT_SCALAR_IS_USHORT
+    #undef  GR_TEXT_SCALAR_IS_FLOAT
+    #define GR_TEXT_SCALAR_IS_FLOAT         1
+    #pragma message GR_WARN("Text scalar type not defined, defaulting to float")
+#endif
+
+#if 0
+#if GR_WIN32_BUILD
+//    #pragma message GR_WARN("GR_WIN32_BUILD")
+#endif
+#if GR_MAC_BUILD
+//    #pragma message GR_WARN("GR_MAC_BUILD")
+#endif
+#if GR_IOS_BUILD
+//    #pragma message GR_WARN("GR_IOS_BUILD")
+#endif
+#if GR_ANDROID_BUILD
+//    #pragma message GR_WARN("GR_ANDROID_BUILD")
+#endif
+#if GR_LINUX_BUILD
+//    #pragma message GR_WARN("GR_LINUX_BUILD")
+#endif
+#if GR_QNX_BUILD
+//    #pragma message GR_WARN("GR_QNX_BUILD")
+#endif
+#endif
+
+#endif
+
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
new file mode 100644
index 0000000..1f90603
--- /dev/null
+++ b/gpu/include/GrContext.h
@@ -0,0 +1,523 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrContext_DEFINED
+#define GrContext_DEFINED
+
+#include "GrClip.h"
+#include "GrGpu.h"
+#include "GrTextureCache.h"
+#include "GrPaint.h"
+
+class GrFontCache;
+class GrPathIter;
+class GrVertexBufferAllocPool;
+class GrIndexBufferAllocPool;
+class GrInOrderDrawBuffer;
+class GrPathRenderer;
+
+class GrContext : public GrRefCnt {
+public:
+    /**
+     * Creates a GrContext from within a 3D context.
+     */
+    static GrContext* Create(GrGpu::Engine engine,
+                             GrGpu::Platform3DContext context3D);
+
+    /**
+     *  Helper to create a opengl-shader based context
+     */
+    static GrContext* CreateGLShaderContext();
+
+    virtual ~GrContext();
+
+    /**
+     * The GrContext normally assumes that no outsider is setting state
+     * within the underlying 3D API's context/device/whatever. This call informs
+     * the context that the state was modified and it should resend. Shouldn't
+     * be called frequently for good performance.
+     */
+    void resetContext();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Textures
+
+    /**
+     *  Abandons all textures. Call this if you have lost the associated GPU
+     *  context, and thus internal texture references/IDs are now invalid.
+     */
+    void abandonAllTextures();
+
+    /**
+     *  Search for an entry with the same Key. If found, "lock" it and return it.
+     *  If not found, return null.
+     */
+    GrTextureEntry* findAndLockTexture(GrTextureKey*,
+                                       const GrSamplerState&);
+
+
+    /**
+     *  Create a new entry, based on the specified key and texture, and return
+     *  its "locked" entry.
+     *
+     *  Ownership of the texture is transferred to the Entry, which will unref()
+     *  it when we are purged or deleted.
+     */
+    GrTextureEntry* createAndLockTexture(GrTextureKey* key,
+                                         const GrSamplerState&,
+                                         const GrGpu::TextureDesc&,
+                                         void* srcData, size_t rowBytes);
+
+    /**
+     *  When done with an entry, call unlockTexture(entry) on it, which returns
+     *  it to the cache, where it may be purged.
+     */
+    void unlockTexture(GrTextureEntry* entry);
+
+    /**
+     *  Removes an texture from the cache. This prevents the texture from
+     *  being found by a subsequent findAndLockTexture() until it is
+     *  reattached. The entry still counts against the cache's budget and should
+     *  be reattached when exclusive access is no longer needed.
+     */
+    void detachCachedTexture(GrTextureEntry*);
+
+    /**
+     * Reattaches a texture to the cache and unlocks it. Allows it to be found
+     * by a subsequent findAndLock or be purged (provided its lock count is
+     * now 0.)
+     */
+    void reattachAndUnlockCachedTexture(GrTextureEntry*);
+
+    /**
+     * Creates a texture that is outside the cache. Does not count against
+     * cache's budget.
+     */
+    GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,
+                                     void* srcData,
+                                     size_t rowBytes);
+
+    /**
+     *  Returns true if the specified use of an indexed texture is supported.
+     */
+    bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
+
+    /**
+     *  Return the current texture cache limits.
+     *
+     *  @param maxTextures If non-null, returns maximum number of textures that
+     *                     can be held in the cache.
+     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
+     *                         texture memory that can be held in the cache.
+     */
+    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
+
+    /**
+     *  Specify the texture cache limits. If the current cache exceeds either
+     *  of these, it will be purged (LRU) to keep the cache within these limits.
+     *
+     *  @param maxTextures The maximum number of textures that can be held in
+     *                     the cache.
+     *  @param maxTextureBytes The maximum number of bytes of texture memory
+     *                         that can be held in the cache.
+     */
+    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
+
+    /**
+     *  Return the max width or height of a texture supported by the current gpu
+     */
+    int getMaxTextureDimension();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Render targets
+
+    /**
+     * Wraps an externally-created rendertarget in a GrRenderTarget.
+     * @param platformRenderTarget  3D API-specific render target identifier
+     *                              e.g. in GL platforamRenderTarget is an FBO
+     *                              id.
+     * @param stencilBits           the number of stencil bits that the render
+     *                              target has.
+     * @param width                 width of the render target.
+     * @param height                height of the render target.
+     */
+    GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
+                                               int stencilBits,
+                                               int width, int height);
+
+    /**
+     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
+     * viewport state from the underlying 3D API and wraps it in a
+     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
+     * underlying object in its destructor and it is up to caller to guarantee
+     * that it remains valid while the GrRenderTarget is used.
+     *
+     * @return the newly created GrRenderTarget
+     */
+    GrRenderTarget* createRenderTargetFrom3DApiState() {
+        return fGpu->createRenderTargetFrom3DApiState();
+    }
+
+    /**
+     * Sets the render target.
+     * @param target    the render target to set. (should not be NULL.)
+     */
+    void setRenderTarget(GrRenderTarget* target);
+
+    /**
+     * Gets the current render target.
+     * @return the currently bound render target. Should never be NULL.
+     */
+    const GrRenderTarget* getRenderTarget() const;
+    GrRenderTarget* getRenderTarget();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Matrix state
+
+    /**
+     * Gets the current transformation matrix.
+     * @return the current matrix.
+     */
+    const GrMatrix& getMatrix() const;
+
+    /**
+     * Sets the transformation matrix.
+     * @param m the matrix to set.
+     */
+    void setMatrix(const GrMatrix& m);
+
+    /**
+     * Concats the current matrix. The passed matrix is applied before the
+     * current matrix.
+     * @param m the matrix to concat.
+     */
+    void concatMatrix(const GrMatrix& m) const;
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Clip state
+    /**
+     * Gets the current clip.
+     * @return the current clip.
+     */
+    const GrClip& getClip() const { return fGpu->getClip(); }
+
+    /**
+     * Sets the clip.
+     * @param clip  the clip to set.
+     */
+    void setClip(const GrClip& clip);
+
+    /**
+     * Convenience method for setting the clip to a rect.
+     * @param rect  the rect to set as the new clip.
+     */
+    void setClip(const GrIRect& rect);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Draws
+
+    /**
+     *  Erase the entire render target, ignoring any clips
+     */
+    void eraseColor(GrColor color);
+
+    /**
+     *  Draw everywhere (respecting the clip) with the paint.
+     */
+    void drawPaint(const GrPaint& paint);
+
+    /**
+     *  Draw the rect using a paint.
+     *  @param paint        describes how to color pixels.
+     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
+     *                      the rect is mitered stroked based on strokeWidth. If
+     *                      strokeWidth == 0, then the stroke is always a single
+     *                      pixel thick.
+     *  @param matrix       Optional matrix applied to the rect. Applied before
+     *                      context's matrix or the paint's matrix.
+     *  The rects coords are used to access the paint (through texture matrix)
+     */
+    void drawRect(const GrPaint& paint,
+                  const GrRect&,
+                  GrScalar strokeWidth = -1,
+                  const GrMatrix* matrix = NULL);
+
+    /**
+     * Maps a rect of paint coordinates onto the a rect of destination
+     * coordinates. Each rect can optionally be transformed. The srcRect
+     * is stretched over the dstRect. The dstRect is transformed by the
+     * context's matrix and the srcRect is transformed by the paint's matrix.
+     * Additional optional matrices can be provided by parameters.
+     *
+     * @param paint     describes how to color pixels.
+     * @param dstRect   the destination rect to draw.
+     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
+     * @param dstMatrix Optional matrix to transform dstRect. Applied before
+     *                  context's matrix.
+     * @param srcMatrix Optional matrix to transform srcRect Applied before
+     *                  paint's matrix.
+     */
+    void drawRectToRect(const GrPaint& paint,
+                        const GrRect& dstRect,
+                        const GrRect& srcRect,
+                        const GrMatrix* dstMatrix = NULL,
+                        const GrMatrix* srcMatrix = NULL);
+
+    /**
+     * Draws a path.
+     *
+     * @param paint         describes how to color pixels.
+     * @param pathIter      the path to draw
+     * @param fill          the path filling rule to use.
+     * @param translate     optional additional translation applied to the
+     *                      path.
+     */
+    void drawPath(const GrPaint& paint,
+                  GrPathIter* pathIter,
+                  GrPathFill fill,
+                  const GrPoint* translate = NULL);
+    /**
+     * Helper version of drawPath that takes a GrPath
+     */
+    void drawPath(const GrPaint& paint,
+                  const GrPath& path,
+                  GrPathFill fill,
+                  const GrPoint* translate = NULL);
+    /**
+     * Draws vertices with a paint.
+     *
+     * @param   paint           describes how to color pixels.
+     * @param   primitiveType   primitives type to draw.
+     * @param   vertexCount     number of vertices.
+     * @param   positions       array of vertex positions, required.
+     * @param   texCoords       optional array of texture coordinates used
+     *                          to access the paint.
+     * @param   colors          optional array of per-vertex colors, supercedes
+     *                          the paint's color field.
+     * @param   indices         optional array of indices. If NULL vertices
+     *                          are drawn non-indexed.
+     * @param   indexCount      if indices is non-null then this is the
+     *                          number of indices.
+     */
+    void drawVertices(const GrPaint& paint,
+                      GrPrimitiveType primitiveType,
+                      int vertexCount,
+                      const GrPoint positions[],
+                      const GrPoint texs[],
+                      const GrColor colors[],
+                      const uint16_t indices[],
+                      int indexCount);
+
+    /**
+     * Similar to drawVertices but caller provides objects that convert to Gr
+     * types. The count of vertices is given by posSrc.
+     *
+     * @param   paint           describes how to color pixels.
+     * @param   primitiveType   primitives type to draw.
+     * @param   posSrc          Source of vertex positions. Must implement
+     *                              int count() const;
+     *                              void writeValue(int i, GrPoint* point) const;
+     *                          count returns the total number of vertices and
+     *                          writeValue writes a vertex position to point.
+     * @param   texSrc          optional, pass NULL to not use explicit tex
+     *                          coords. If present provides tex coords with
+     *                          method:
+     *                              void writeValue(int i, GrPoint* point) const;
+     * @param   texSrc          optional, pass NULL to not use per-vertex colors
+     *                          If present provides colors with method:
+     *                              void writeValue(int i, GrColor* point) const;
+     * @param   indices         optional, pass NULL for non-indexed drawing. If
+     *                          present supplies indices for indexed drawing
+     *                          with following methods:
+     *                              int count() const;
+     *                              void writeValue(int i, uint16_t* point) const;
+     *                          count returns the number of indices and
+     *                          writeValue supplies each index.
+     */
+    template <typename POS_SRC,
+              typename TEX_SRC,
+              typename COL_SRC,
+              typename IDX_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc,
+                            const COL_SRC* colorSrc,
+                            const IDX_SRC* idxSrc);
+    /**
+     * To avoid the problem of having to create a typename for NULL parameters,
+     * these reduced versions of drawCustomVertices are provided.
+     */
+    template <typename POS_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc);
+    template <typename POS_SRC, typename TEX_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc);
+    template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc,
+                            const COL_SRC* colorSrc);
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Misc.
+
+    /**
+     * Flags that affect flush() behavior.
+     */
+    enum FlushBits {
+        /**
+         * A client may want Gr to bind a GrRenderTarget in the 3D API so that
+         * it can be rendered to directly. However, Gr lazily sets state. Simply
+         * calling setRenderTarget() followed by flush() without flags may not
+         * bind the render target. This flag forces the context to bind the last
+         * set render target in the 3D API.
+         */
+        kForceCurrentRenderTarget_FlushBit   = 0x1,
+        /**
+         * A client may reach a point where it has partially rendered a frame
+         * through a GrContext that it knows the user will never see. This flag
+         * causes the flush to skip submission of deferred content to the 3D API
+         * during the flush.
+         */
+        kDiscard_FlushBit                    = 0x2,
+    };
+
+    /**
+     * Call to ensure all drawing to the context has been issued to the
+     * underlying 3D API.
+     * @param flagsBitfield     flags that control the flushing behavior. See
+     *                          FlushBits.
+     */
+    void flush(int flagsBitfield);
+    /**
+     *  Return true on success, i.e. if we could copy the specified range of
+     *  pixels from the current render-target into the buffer, converting into
+     *  the specified pixel-config.
+     */
+    bool readPixels(int left, int top, int width, int height,
+                    GrTexture::PixelConfig, void* buffer);
+
+    /**
+     *  Copy the src pixels [buffer, stride, pixelconfig] into the current
+     *  render-target at the specified rectangle.
+     */
+    void writePixels(int left, int top, int width, int height,
+                     GrTexture::PixelConfig, const void* buffer, size_t stride);
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Statistics
+
+    void resetStats();
+
+    const GrGpu::Stats& getStats() const;
+
+    void printStats() const;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Helpers
+
+    class AutoRenderTarget : ::GrNoncopyable {
+    public:
+        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
+            fContext = NULL;
+            fPrevTarget = context->getRenderTarget();
+            if (fPrevTarget != target) {
+                context->setRenderTarget(target);
+                fContext = context;
+            }
+        }
+        ~AutoRenderTarget() {
+            if (fContext) {
+                fContext->setRenderTarget(fPrevTarget);
+            }
+        }
+    private:
+        GrContext*      fContext;
+        GrRenderTarget* fPrevTarget;
+    };
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Functions intended for internal use only.
+    GrGpu* getGpu() { return fGpu; }
+    GrFontCache* getFontCache() { return fFontCache; }
+    GrDrawTarget* getTextTarget(const GrPaint& paint);
+    void flushText();
+    const GrIndexBuffer* getQuadIndexBuffer() const;
+
+private:
+    // used to keep track of when we need to flush the draw buffer
+    enum DrawCategory {
+        kBuffered_DrawCategory,      // last draw was inserted in draw buffer
+        kUnbuffered_DrawCategory,    // last draw was not inserted in the draw buffer
+        kText_DrawCategory           // text context was last to draw
+    };
+    DrawCategory fLastDrawCategory;
+
+    GrGpu*          fGpu;
+    GrTextureCache* fTextureCache;
+    GrFontCache*    fFontCache;
+    GrPathRenderer* fPathRenderer;
+
+    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
+    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
+    GrInOrderDrawBuffer*        fDrawBuffer;
+
+    GrContext(GrGpu* gpu);
+    void flushDrawBuffer();
+
+    static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
+
+    bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
+
+    GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
+
+    void drawClipIntoStencil();
+};
+
+/**
+ *  Save/restore the view-matrix in the context.
+ */
+class GrAutoMatrix : GrNoncopyable {
+public:
+    GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
+        fMatrix = ctx->getMatrix();
+    }
+    GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
+        fMatrix = ctx->getMatrix();
+        ctx->setMatrix(matrix);
+    }
+    ~GrAutoMatrix() {
+        fContext->setMatrix(fMatrix);
+    }
+
+private:
+    GrContext*  fContext;
+    GrMatrix    fMatrix;
+};
+
+#endif
+
+#include "GrContext_impl.h"
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
new file mode 100644
index 0000000..fdcb2b1
--- /dev/null
+++ b/gpu/include/GrContext_impl.h
@@ -0,0 +1,135 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrContext_impl_DEFINED
+#define GrContext_impl_DEFINED
+
+template <typename POS_SRC, typename TEX_SRC,
+          typename COL_SRC, typename IDX_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc,
+                                          const COL_SRC* colorSrc,
+                                          const IDX_SRC* idxSrc) {
+
+    GrVertexLayout layout = 0;
+
+    GrDrawTarget::AutoReleaseGeometry geo;
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (NULL != paint.getTexture()) {
+        if (NULL != texCoordSrc) {
+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+        } else {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        }
+    }
+
+    if (NULL != colorSrc) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+    }
+
+    int vertexCount = posSrc.count();
+    int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
+
+    if (!geo.set(target, layout, vertexCount, indexCount)) {
+        GrPrintf("Failed to get space for vertices!");
+        return;
+    }
+
+    int texOffsets[GrDrawTarget::kMaxTexCoords];
+    int colorOffset;
+    int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+                                                        texOffsets,
+                                                        &colorOffset);
+    void* curVertex = geo.vertices();
+
+    for (int i = 0; i < vertexCount; ++i) {
+        posSrc.writeValue(i, (GrPoint*)curVertex);
+
+        if (texOffsets[0] > 0) {
+            texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0]));
+        }
+        if (colorOffset > 0) {
+            colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset));
+        }
+        curVertex = (void*)((intptr_t)curVertex + vsize);
+    }
+
+    uint16_t* indices = (uint16_t*) geo.indices();
+    for (int i = 0; i < indexCount; ++i) {
+        idxSrc->writeValue(i, indices + i);
+    }
+
+    if (NULL == idxSrc) {
+        target->drawNonIndexed(primitiveType, 0, vertexCount);
+    } else {
+        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+    }
+}
+
+class GrNullTexCoordSource {
+public:
+    void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); }
+};
+
+class GrNullColorSource {
+public:
+    void writeValue(int i, GrColor* dstColor) const { GrAssert(false); }
+};
+
+class GrNullIndexSource {
+public:
+    void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); }
+    int count() const { GrAssert(false); return 0; }
+};
+
+template <typename POS_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc) {
+    this->drawCustomVertices<POS_SRC,
+                             GrNullTexCoordSource,
+                             GrNullColorSource,
+                             GrNullIndexSource>(paint, primitiveType, posSrc,
+                                                NULL, NULL, NULL);
+}
+
+template <typename POS_SRC, typename TEX_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc) {
+    this->drawCustomVertices<POS_SRC, TEX_SRC,
+                             GrNullColorSource,
+                             GrNullIndexSource>(paint, primitiveType, posSrc,
+                                                texCoordSrc, NULL, NULL);
+}
+
+template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc,
+                                          const COL_SRC* colorSrc) {
+    drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC,
+                       GrNullIndexSource>(paint, primitiveType, posSrc, 
+                                          texCoordSrc, colorSrc, NULL);
+}
+
+#endif
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
new file mode 100644
index 0000000..35f912b
--- /dev/null
+++ b/gpu/include/GrDrawTarget.h
@@ -0,0 +1,1078 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrDrawTarget_DEFINED
+#define GrDrawTarget_DEFINED
+
+#include "GrMatrix.h"
+#include "GrColor.h"
+#include "GrRefCnt.h"
+#include "GrSamplerState.h"
+#include "GrClip.h"
+#include "GrTexture.h"
+#include "GrStencil.h"
+
+class GrTexture;
+class GrClipIterator;
+class GrVertexBuffer;
+class GrIndexBuffer;
+
+class GrDrawTarget : public GrRefCnt {
+public:
+    /**
+     * Number of texture stages. Each stage takes as input a color and
+     * 2D texture coordinates. The color input to the first enabled stage is the
+     * per-vertex color or the constant color (setColor/setAlpha) if there are
+     * no per-vertex colors. For subsequent stages the input color is the output
+     * color from the previous enabled stage. The output color of each stage is
+     * the input color modulated with the result of a texture lookup. Texture
+     * lookups are specified by a texture a sampler (setSamplerState). Texture
+     * coordinates for each stage come from the vertices based on a
+     * GrVertexLayout bitfield. The output fragment color is the output color of
+     * the last enabled stage. The presence or absence of texture coordinates
+     * for each stage in the vertex layout indicates whether a stage is enabled
+     * or not.
+     */
+    enum {
+        kNumStages = 2,
+        kMaxTexCoords = kNumStages
+    };
+
+    /**
+     *  Bitfield used to indicate which stages are in use.
+     */
+    typedef int StageBitfield;
+    GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages);
+
+    /**
+     *  Flags that affect rendering. Controlled using enable/disableState(). All
+     *  default to disabled.
+     */
+    enum StateBits {
+        kDither_StateBit          = 0x1,//<! Perform color dithering
+        kAntialias_StateBit       = 0x2,//<! Perform anti-aliasing. The render-
+                                        //   target must support some form of AA
+                                        //   (msaa, coverage sampling, etc). For
+                                        //   GrGpu-created rendertarget/textures
+                                        //   this is controlled by parameters
+                                        //   passed to createTexture.
+        kClip_StateBit            = 0x4,//<! Controls whether drawing is clipped
+                                        //   against the region specified by
+                                        //   setClip.
+        kNoColorWrites_StateBit   = 0x8,//<! If set it disables writing colors.
+                                        //   Useful while performing stencil ops.
+
+        // subclass may use additional bits internally
+        kDummyStateBit,
+        kLastPublicStateBit = kDummyStateBit-1
+    };
+
+    enum DrawFace {
+        kBoth_DrawFace,
+        kCCW_DrawFace,
+        kCW_DrawFace,
+    };
+
+    /**
+     * The DrawTarget may reserve some of the high bits of the stencil. The draw
+     * target will automatically trim reference and mask values so that the
+     * client doesn't overwrite these bits.
+     * The number of bits available is relative to the currently set render
+      *target.
+     * @return the number of bits usable by the draw target client.
+     */
+    int getUsableStencilBits() const {
+        int bits = fCurrDrawState.fRenderTarget->stencilBits();
+        if (bits) {
+            return bits - 1;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Sets the stencil settings to use for the next draw.
+     * Changing the clip has the side-effect of possibly zeroing
+     * out the client settable stencil bits. So multipass algorithms
+     * using stencil should not change the clip between passes.
+     * @param settings  the stencil settings to use.
+     */
+    void setStencil(const GrStencilSettings& settings) {
+        fCurrDrawState.fStencilSettings = settings;
+    }
+
+    /**
+     * Shortcut to disable stencil testing and ops.
+     */
+    void disableStencil() {
+        fCurrDrawState.fStencilSettings.setDisabled();
+    }
+
+protected:
+
+    struct DrState {
+        DrState() {
+            // make sure any pad is zero for memcmp
+            // all DrState members should default to something
+            // valid by the memset
+            memset(this, 0, sizeof(DrState));
+            GrAssert((intptr_t)(void*)NULL == 0LL);
+            GrAssert(fStencilSettings.isDisabled());
+        }
+        uint32_t                fFlagBits;
+        GrBlendCoeff            fSrcBlend;
+        GrBlendCoeff            fDstBlend;
+        GrColor                 fBlendConstant;
+        GrTexture*              fTextures[kNumStages];
+        GrSamplerState          fSamplerStates[kNumStages];
+        GrRenderTarget*         fRenderTarget;
+        GrColor                 fColor;
+        DrawFace                fDrawFace;
+
+        GrStencilSettings       fStencilSettings;
+        GrMatrix                fViewMatrix;
+        bool operator ==(const DrState& s) const {
+            return 0 == memcmp(this, &s, sizeof(DrState));
+        }
+        bool operator !=(const DrState& s) const { return !(*this == s); }
+    };
+
+public:
+    ///////////////////////////////////////////////////////////////////////////
+
+    GrDrawTarget();
+
+    /**
+     * Sets the current clip to the region specified by clip. All draws will be
+     * clipped against this clip if kClip_StateBit is enabled.
+     *
+     * Setting the clip may (or may not) zero out the client's stencil bits.
+     *
+     * @param description of the clipping region
+     */
+    void setClip(const GrClip& clip);
+
+    /**
+     * Gets the current clip.
+     *
+     * @return the clip.
+     */
+    const GrClip& getClip() const;
+
+    /**
+     * Sets the texture used at the next drawing call
+     *
+     * @param stage The texture stage for which the texture will be set
+     *
+     * @param texture The texture to set. Can be NULL though there is no advantage
+     * to settings a NULL texture if doing non-textured drawing
+     */
+    void setTexture(int stage, GrTexture* texture);
+
+    /**
+     * Retrieves the currently set texture.
+     *
+     * @return    The currently set texture. The return value will be NULL if no
+     *            texture has been set, NULL was most recently passed to
+     *            setTexture, or the last setTexture was destroyed.
+     */
+    const GrTexture* getTexture(int stage) const;
+    GrTexture* getTexture(int stage);
+
+    /**
+     * Sets the rendertarget used at the next drawing call
+     *
+     * @param target  The render target to set.
+     */
+    void setRenderTarget(GrRenderTarget* target);
+
+    /**
+     * Retrieves the currently set rendertarget.
+     *
+     * @return    The currently set render target.
+     */
+    const GrRenderTarget* getRenderTarget() const;
+    GrRenderTarget* getRenderTarget();
+
+    /**
+     * Sets the sampler state for a stage used in subsequent draws.
+     *
+     * The sampler state determines how texture coordinates are
+     * intepretted and used to sample the texture.
+     *
+     * @param stage           the stage of the sampler to set
+     * @param samplerState    Specifies the sampler state.
+     */
+    void setSamplerState(int stage, const GrSamplerState& samplerState);
+
+    /**
+     * Concats the matrix of a stage's sampler.
+     *
+     * @param stage   the stage of the sampler to set
+     * @param matrix  the matrix to concat
+     */
+    void preConcatSamplerMatrix(int stage, const GrMatrix& matrix)  {
+        GrAssert(stage >= 0 && stage < kNumStages);
+        fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
+    }
+
+    /**
+     * Gets the matrix of a stage's sampler
+     *
+     * @param stage     the stage to of sampler to get
+     * @return the sampler state's matrix
+     */
+    const GrMatrix& getSamplerMatrix(int stage) const {
+        return fCurrDrawState.fSamplerStates[stage].getMatrix();
+    }
+
+    /**
+     * Sets the matrix of a stage's sampler
+     *
+     * @param stage     the stage of sampler set
+     * @param matrix    the matrix to set
+     */
+    void setSamplerMatrix(int stage, const GrMatrix& matrix) {
+        fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
+    }
+
+    /**
+     * Sets the matrix applied to veretx positions.
+     *
+     * In the post-view-matrix space the rectangle [0,w]x[0,h]
+     * fully covers the render target. (w and h are the width and height of the
+     * the rendertarget.)
+     *
+     * @param m the matrix used to transform the vertex positions.
+     */
+    void setViewMatrix(const GrMatrix& m);
+
+    /**
+     *  Multiplies the current view matrix by a matrix
+     *
+     *  After this call V' = V*m where V is the old view matrix,
+     *  m is the parameter to this function, and V' is the new view matrix.
+     *  (We consider positions to be column vectors so position vector p is
+     *  transformed by matrix X as p' = X*p.)
+     *
+     *  @param m the matrix used to modify the view matrix.
+     */
+    void preConcatViewMatrix(const GrMatrix& m);
+
+    /**
+     * Retrieves the current view matrix
+     * @return the current view matrix.
+     */
+    const GrMatrix& getViewMatrix() const;
+
+    /**
+     *  Retrieves the inverse of the current view matrix.
+     *
+     *  If the current view matrix is invertible, return true, and if matrix
+     *  is non-null, copy the inverse into it. If the current view matrix is
+     *  non-invertible, return false and ignore the matrix parameter.
+     *
+     * @param matrix if not null, will receive a copy of the current inverse.
+     */
+    bool getViewInverse(GrMatrix* matrix) const;
+
+    /**
+     *  Sets color for next draw to a premultiplied-alpha color.
+     *
+     *  @param the color to set.
+     */
+    void setColor(GrColor);
+
+    /**
+     *  Sets the color to be used for the next draw to be
+     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
+     *
+     *  @param alpha The alpha value to set as the color.
+     */
+    void setAlpha(uint8_t alpha);
+
+    /**
+     * Controls whether clockwise, counterclockwise, or both faces are drawn.
+     * @param face  the face(s) to draw.
+     */
+    void setDrawFace(DrawFace face) { fCurrDrawState.fDrawFace = face; }
+
+    /**
+     * Gets whether the target is drawing clockwise, counterclockwise,
+     * or both faces.
+     * @return the current draw face(s).
+     */
+    DrawFace getDrawFace() const { return fCurrDrawState.fDrawFace; }
+
+    /**
+     * Enable render state settings.
+     *
+     * @param flags   bitfield of StateBits specifing the states to enable
+     */
+    void enableState(uint32_t stateBits);
+
+    /**
+     * Disable render state settings.
+     *
+     * @param flags   bitfield of StateBits specifing the states to disable
+     */
+    void disableState(uint32_t stateBits);
+
+    bool isDitherState() const {
+        return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
+    }
+
+    bool isClipState() const {
+        return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
+    }
+
+    bool isColorWriteDisabled() const {
+        return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
+    }
+
+    /**
+     * Sets the blending function coeffecients.
+     *
+     * The blend function will be:
+     *    D' = sat(S*srcCoef + D*dstCoef)
+     *
+     *   where D is the existing destination color, S is the incoming source
+     *   color, and D' is the new destination color that will be written. sat()
+     *   is the saturation function.
+     *
+     * @param srcCoef coeffecient applied to the src color.
+     * @param dstCoef coeffecient applied to the dst color.
+     */
+    void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef);
+
+    /**
+     * Sets the blending function constant referenced by the following blending
+     * coeffecients:
+     *      kConstC_BlendCoeff
+     *      kIConstC_BlendCoeff
+     *      kConstA_BlendCoeff
+     *      kIConstA_BlendCoeff
+     *
+     * @param constant the constant to set
+     */
+    void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
+
+    /**
+     * Retrieves the last value set by setBlendConstant()
+     * @return the blending constant value
+     */
+    GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
+
+    /**
+     * Used to save and restore the GrGpu's drawing state
+     */
+    struct SavedDrawState {
+    private:
+        DrState fState;
+        friend class GrDrawTarget;
+    };
+
+    /**
+     * Saves the current draw state. The state can be restored at a later time
+     * with restoreDrawState.
+     *
+     * See also AutoStateRestore class.
+     *
+     * @param   state will hold the state after the function returns.
+     */
+    void saveCurrentDrawState(SavedDrawState* state) const;
+
+    /**
+     * Restores previously saved draw state. The client guarantees that state
+     * was previously passed to saveCurrentDrawState and that the rendertarget
+     * and texture set at save are still valid.
+     *
+     * See also AutoStateRestore class.
+     *
+     * @param   state the previously saved state to restore.
+     */
+    void restoreDrawState(const SavedDrawState& state);
+
+    /**
+     * Copies the draw state from another target to this target.
+     *
+     * @param srcTarget     draw target used as src of the draw state.
+     */
+    void copyDrawState(const GrDrawTarget& srcTarget);
+
+    /**
+     * The format of vertices is represented as a bitfield of flags.
+     * Flags that indicate the layout of vertex data. Vertices always contain
+     * positions and may also contain up to kMaxTexCoords sets of 2D texture
+     * coordinates and per-vertex colors. Each stage can use any of the texture
+     * coordinates as its input texture coordinates or it may use the positions.
+     *
+     * If no texture coordinates are specified for a stage then the stage is
+     * disabled.
+     *
+     * Only one type of texture coord can be specified per stage. For
+     * example StageTexCoordVertexLayoutBit(0, 2) and
+     * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
+     *
+     * The order in memory is always (position, texture coord 0, ..., color)
+     * with any unused fields omitted. Note that this means that if only texture
+     * coordinates 1 is referenced then there is no texture coordinates 0 and
+     * the order would be (position, texture coordinate 1[, color]).
+     */
+
+    /**
+     * Generates a bit indicating that a texture stage uses texture coordinates
+     *
+     * @param stage       the stage that will use texture coordinates.
+     * @param texCoordIdx the index of the texture coordinates to use
+     *
+     * @return the bit to add to a GrVertexLayout bitfield.
+     */
+    static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
+        GrAssert(stage < kNumStages);
+        GrAssert(texCoordIdx < kMaxTexCoords);
+        return 1 << (stage + (texCoordIdx * kNumStages));
+    }
+
+    /**
+     * Determines if blend is effectively disabled.
+     *
+     * @return true if blend can be disabled without changing the rendering
+     *  result given the current state including the vertex layout specified
+     *  with the vertex source.
+     */
+    bool canDisableBlend() const;
+
+private:
+    static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
+public:
+    /**
+     * Generates a bit indicating that a texture stage uses the position
+     * as its texture coordinate.
+     *
+     * @param stage       the stage that will use position as texture
+     *                    coordinates.
+     *
+     * @return the bit to add to a GrVertexLayout bitfield.
+     */
+    static int StagePosAsTexCoordVertexLayoutBit(int stage) {
+        GrAssert(stage < kNumStages);
+        return (1 << (TEX_COORD_BIT_CNT + stage));
+    }
+private:
+    static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
+
+public:
+
+    /**
+     * Additional Bits that can be specified in GrVertexLayout.
+     */
+    enum VertexLayoutBits {
+
+        kColor_VertexLayoutBit              = 1 << (STAGE_BIT_CNT + 0),
+                                                //<! vertices have colors
+        kTextFormat_VertexLayoutBit         = 1 << (STAGE_BIT_CNT + 1),
+                                                //<! use text vertices. (Pos
+                                                //   and tex coords may be
+                                                //   a different type for
+                                                //   text [GrGpuTextVertex vs
+                                                //   GrPoint].)
+        // for below assert
+        kDummyVertexLayoutBit,
+        kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
+    };
+    // make sure we haven't exceeded the number of bits in GrVertexLayout.
+    GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
+
+    /**
+     * There are three paths for specifying geometry (vertices and optionally
+     * indices) to the draw target. When indexed drawing the indices and vertices
+     * can be each use a different path.
+     *
+     * 1. Provide a cpu array (set*SourceToArray). This is useful when the
+     *    caller's client has already provided vertex data in a format
+     *    the time compatible with a GrVertexLayout. The array must contain the
+     *    data at set*SourceToArray is called. The source stays in effect for
+     *    drawIndexed & drawNonIndexed calls until set*SourceToArray is called
+     *    again or one of the other two paths is chosen.
+     *
+     * 2. Reserve and Lock. This is most useful when the caller has data it must
+     *    transform before drawing and will not likely render it again. The
+     *    caller requests that the draw target make room for some amount of
+     *    vertex and/or index data. The target provides ptrs to hold the data
+     *    data. The caller can write the data into the pts up until the first
+     *    drawIndexed or drawNonIndexed call. At this point the data is frozen
+     *    and the ptrs are no longer guaranteed to be valid. All subsequent
+     *    drawIndexed & drawNonIndexed calls will use this data until
+     *    releaseReserved geometry is called. This must be called before another
+     *    source is set.
+     *
+     * 3. Vertex and Index Buffers. This is most useful for geometry that will
+     *    be rendered multiple times. SetVertexSourceToBuffer &
+     *    SetIndexSourceToBuffer are used to set the buffer and subsequent
+     *    drawIndexed and drawNonIndexed calls use this source until another
+     *    source is set.
+     */
+
+    /**
+     * Reserves space for vertices and/or indices. Draw target will use
+     * reserved vertices / indices at next draw.
+     *
+     * If succeeds:
+     *          if vertexCount is nonzero, *vertices will be the array
+     *          of vertices to be filled by caller. The next draw will read
+     *          these vertices.
+     *
+     *          if indecCount is nonzero, *indices will be the array of indices
+     *          to be filled by caller. The next indexed draw will read from
+     *          these indices.
+     *
+     * If a client does not already have a vertex buffer then this is the
+     * preferred way to allocate vertex/index array. It allows the subclass of
+     * GrDrawTarget to decide whether to put data in buffers, to group vertex
+     * data that uses the same state (e.g. for deferred rendering), etc.
+     *
+     * Following the first draw after reserveAndLockGeometry the ptrs returned
+     * by releaseReservedGeometry are no longer valid and the geometry data
+     * cannot be further modified. The contents that were put in the reserved
+     * space can be drawn by multiple draws, however.
+     *
+     * reserveAndLockGeometry must be matched with a releaseReservedGeometry
+     * call after all draws that reference the reserved geometry data have
+     * been called.
+     *
+     * AutoGeometryRelease can be used to automatically call the release.
+     *
+     * @param vertexCount  the number of vertices to reserve space for. Can be 0.
+     * @param indexCount   the number of indices to reserve space for. Can be 0.
+     * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
+     * @param vertices     will point to reserved vertex space if vertexCount is
+     *                     non-zero. Illegal to pass NULL if vertexCount > 0.
+     * @param indices      will point to reserved index space if indexCount is
+     *                     non-zero. Illegal to pass NULL if indexCount > 0.
+     *
+     * @return  true if succeeded in allocating space for the vertices and false
+     *               if not.
+     */
+    bool reserveAndLockGeometry(GrVertexLayout    vertexLayout,
+                                uint32_t          vertexCount,
+                                uint32_t          indexCount,
+                                void**            vertices,
+                                void**            indices);
+    /**
+     * Provides hints to caller about the number of vertices and indices
+     * that can be allocated cheaply. This can be useful if caller is reserving
+     * space but doesn't know exactly how much geometry is needed.
+     *
+     * Also may hint whether the draw target should be flushed first. This is
+     * useful for deferred targets.
+     *
+     * @param vertexLayout layout of vertices caller would like to reserve
+     * @param vertexCount  in: hint about how many vertices the caller would
+     *                     like to allocate.
+     *                     out: a hint about the number of vertices that can be
+     *                     allocated cheaply. Negative means no hint.
+     *                     Ignored if NULL.
+     * @param indexCount   in: hint about how many indices the caller would
+     *                     like to allocate.
+     *                     out: a hint about the number of indices that can be
+     *                     allocated cheaply. Negative means no hint.
+     *                     Ignored if NULL.
+     *
+     * @return  true if target should be flushed based on the input values.
+     */
+    virtual bool geometryHints(GrVertexLayout vertexLayout,
+                               int* vertexCount,
+                               int* indexCount) const;
+
+    /**
+     * Releases reserved vertex/index data from reserveAndLockGeometry().
+     */
+    void releaseReservedGeometry();
+
+    /**
+     * Sets source of vertex data for the next draw. Array must contain
+     * the vertex data when this is called.
+     *
+     * @param array         cpu array containing vertex data.
+     * @param size          size of the vertex data.
+     * @param vertexCount   the number of vertices in the array.
+     */
+    void setVertexSourceToArray(GrVertexLayout vertexLayout,
+                                const void* vertexArray,
+                                int vertexCount);
+
+    /**
+     * Sets source of index data for the next indexed draw. Array must contain
+     * the indices when this is called.
+     *
+     * @param array         cpu array containing index data.
+     * @param indexCount    the number of indices in the array.
+     */
+    void setIndexSourceToArray(const void* indexArray, int indexCount);
+
+    /**
+     * Sets source of vertex data for the next draw. Data does not have to be
+     * in the buffer until drawIndexed or drawNonIndexed.
+     *
+     * @param buffer        vertex buffer containing vertex data. Must be
+     *                      unlocked before draw call.
+     * @param vertexLayout  layout of the vertex data in the buffer.
+     */
+    void setVertexSourceToBuffer(GrVertexLayout vertexLayout,
+                                 const GrVertexBuffer* buffer);
+
+    /**
+     * Sets source of index data for the next indexed draw. Data does not have
+     * to be in the buffer until drawIndexed or drawNonIndexed.
+     *
+     * @param buffer index buffer containing indices. Must be unlocked
+     *               before indexed draw call.
+     */
+    void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+    /**
+     * Draws indexed geometry using the current state and current vertex / index
+     * sources.
+     *
+     * @param type         The type of primitives to draw.
+     * @param startVertex  the vertex in the vertex array/buffer corresponding
+     *                     to index 0
+     * @param startIndex   first index to read from index src.
+     * @param vertexCount  one greater than the max index.
+     * @param indexCount   the number of index elements to read. The index count
+     *                     is effectively trimmed to the last completely
+     *                     specified primitive.
+     */
+    virtual void drawIndexed(GrPrimitiveType type,
+                             int startVertex,
+                             int startIndex,
+                             int vertexCount,
+                             int indexCount) = 0;
+
+    /**
+     * Draws non-indexed geometry using the current state and current vertex
+     * sources.
+     *
+     * @param type         The type of primitives to draw.
+     * @param startVertex  the vertex in the vertex array/buffer corresponding
+     *                     to index 0
+     * @param vertexCount  one greater than the max index.
+     */
+    virtual void drawNonIndexed(GrPrimitiveType type,
+                                int startVertex,
+                                int vertexCount)  = 0;
+
+    /**
+     * Helper function for drawing rects. This does not use the current index
+     * and vertex sources. After returning, the vertex and index sources may
+     * have changed. They should be reestablished before the next drawIndexed
+     * or drawNonIndexed. This cannot be called between reserving and releasing
+     * geometry. The GrDrawTarget subclass may be able to perform additional
+     * optimizations if drawRect is used rather than drawIndexed or
+     * drawNonIndexed.
+     * @param rect      the rect to draw
+     * @param matrix    optional matrix applied to rect (before viewMatrix)
+     * @param stageEnableBitfield bitmask indicating which stages are enabled.
+     *                            Bit i indicates whether stage i is enabled.
+     * @param srcRects  specifies rects for stages enabled by stageEnableMask.
+     *                  if stageEnableMask bit i is 1, srcRects is not NULL,
+     *                  and srcRects[i] is not NULL, then srcRects[i] will be
+     *                  used as coordinates for stage i. Otherwise, if stage i
+     *                  is enabled then rect is used as the coordinates.
+     * @param srcMatrices   optional matrices applied to srcRects. If
+     *                      srcRect[i] is non-NULL and srcMatrices[i] is
+     *                      non-NULL then srcRect[i] will be transformed by
+     *                      srcMatrix[i]. srcMatrices can be NULL when no
+     *                      srcMatrices are desired.
+     */
+    virtual void drawRect(const GrRect& rect,
+                          const GrMatrix* matrix,
+                          StageBitfield stageEnableBitfield,
+                          const GrRect* srcRects[],
+                          const GrMatrix* srcMatrices[]);
+
+    /**
+     * Helper for drawRect when the caller doesn't need separate src rects or
+     * matrices.
+     */
+    void drawSimpleRect(const GrRect& rect,
+                        const GrMatrix* matrix,
+                        StageBitfield stageEnableBitfield) {
+         drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoStateRestore : ::GrNoncopyable {
+    public:
+        AutoStateRestore(GrDrawTarget* target);
+        ~AutoStateRestore();
+
+    private:
+        GrDrawTarget*       fDrawTarget;
+        SavedDrawState      fDrawState;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoViewMatrixRestore : ::GrNoncopyable {
+    public:
+        AutoViewMatrixRestore() {
+            fDrawTarget = NULL;
+        }
+
+        AutoViewMatrixRestore(GrDrawTarget* target)
+            : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
+            GrAssert(NULL != target);
+        }
+
+        void set(GrDrawTarget* target) {
+            GrAssert(NULL != target);
+            if (NULL != fDrawTarget) {
+                fDrawTarget->setViewMatrix(fMatrix);
+            }
+            fDrawTarget = target;
+            fMatrix = target->getViewMatrix();
+        }
+
+        ~AutoViewMatrixRestore() {
+            if (NULL != fDrawTarget) {
+                fDrawTarget->setViewMatrix(fMatrix);
+            }
+        }
+
+    private:
+        GrDrawTarget*       fDrawTarget;
+        GrMatrix            fMatrix;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoReleaseGeometry : ::GrNoncopyable {
+    public:
+        AutoReleaseGeometry(GrDrawTarget*  target,
+                            GrVertexLayout vertexLayout,
+                            uint32_t       vertexCount,
+                            uint32_t       indexCount) {
+            fTarget = target;
+            fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
+                                                       vertexCount,
+                                                       indexCount,
+                                                       &fVertices,
+                                                       &fIndices);
+        }
+
+        AutoReleaseGeometry() {
+            fSuccess = false;
+        }
+
+        ~AutoReleaseGeometry() {
+            if (fSuccess) {
+                fTarget->releaseReservedGeometry();
+            }
+        }
+
+        bool set(GrDrawTarget*  target,
+                 GrVertexLayout vertexLayout,
+                 uint32_t       vertexCount,
+                 uint32_t       indexCount) {
+            if (fSuccess) {
+                fTarget->releaseReservedGeometry();
+            }
+            fTarget = target;
+            fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
+                                                       vertexCount,
+                                                       indexCount,
+                                                       &fVertices,
+                                                       &fIndices);
+            return fSuccess;
+        }
+
+        bool succeeded() const { return fSuccess; }
+        void* vertices() const { return fVertices; }
+        void* indices() const { return fIndices; }
+
+        GrPoint* positions() const {
+            return static_cast<GrPoint*>(fVertices);
+        }
+
+    private:
+        GrDrawTarget* fTarget;
+        bool          fSuccess;
+        void*         fVertices;
+        void*         fIndices;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoClipRestore : ::GrNoncopyable {
+    public:
+        AutoClipRestore(GrDrawTarget* target) {
+            fTarget = target;
+            fClip = fTarget->getClip();
+        }
+
+        ~AutoClipRestore() {
+            fTarget->setClip(fClip);
+        }
+    private:
+        GrDrawTarget* fTarget;
+        GrClip        fClip;
+    };
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Helpers for picking apart vertex layouts
+
+    /**
+     * Helper function to compute the size of a vertex from a vertex layout
+     * @return size of a single vertex.
+     */
+    static size_t VertexSize(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function for determining the index of texture coordinates that
+     * is input for a texture stage. Note that a stage may instead use positions
+     * as texture coordinates, in which case the result of the function is
+     * indistinguishable from the case when the stage is disabled.
+     *
+     * @param stage         the stage to query
+     * @param vertexLayout  layout to query
+     *
+     * @return the texture coordinate index or -1 if the stage doesn't use
+     *         separate (non-position) texture coordinates.
+     */
+    static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of texture coordinates in a vertex
+     * @return offset of texture coordinates in vertex layout or -1 if the
+     *         layout has no texture coordinates. Will be 0 if positions are
+     *         used as texture coordinates for the stage.
+     */
+    static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of the color in a vertex
+     * @return offset of color in vertex layout or -1 if the
+     *         layout has no color.
+     */
+    static int VertexColorOffset(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to determine if vertex layout contains explicit texture
+     * coordinates of some index.
+     *
+     * @param coordIndex    the tex coord index to query
+     * @param vertexLayout  layout to query
+     *
+     * @return true if vertex specifies texture coordinates for the index,
+     *              false otherwise.
+     */
+    static bool VertexUsesTexCoordIdx(int coordIndex,
+                                      GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to determine if vertex layout contains either explicit or
+     * implicit texture coordinates for a stage.
+     *
+     * @param stage         the stage to query
+     * @param vertexLayout  layout to query
+     *
+     * @return true if vertex specifies texture coordinates for the stage,
+     *              false otherwise.
+     */
+    static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by tex coord
+     * index rather than by stage. (Each stage can be mapped to any t.c. index
+     * by StageTexCoordVertexLayoutBit.)
+     *
+     * @param vertexLayout          the layout to query
+     * @param texCoordOffsetsByIdx  after return it is the offset of each
+     *                              tex coord index in the vertex or -1 if
+     *                              index isn't used.
+     * @return size of a single vertex
+     */
+    static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
+                                         int texCoordOffsetsByIdx[kMaxTexCoords],
+                                         int *colorOffset);
+
+    /**
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by stage
+     * rather than by index. (Each stage can be mapped to any t.c. index
+     * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
+     * tex coords then that stage's offset will be 0 (positions are always at 0).
+     *
+     * @param vertexLayout              the layout to query
+     * @param texCoordOffsetsByStage    after return it is the offset of each
+     *                                  tex coord index in the vertex or -1 if
+     *                                  index isn't used.
+     * @return size of a single vertex
+     */
+    static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
+                                           int texCoordOffsetsByStage[kNumStages],
+                                           int *colorOffset);
+
+    /**
+     * Accessing positions, texture coords, or colors, of a vertex within an
+     * array is a hassle involving casts and simple math. These helpers exist
+     * to keep GrDrawTarget clients' code a bit nicer looking.
+     */
+
+    /**
+     * Gets a pointer to a GrPoint of a vertex's position or texture
+     * coordinate.
+     * @param vertices      the vetex array
+     * @param vertexIndex   the index of the vertex in the array
+     * @param vertexSize    the size of each vertex in the array
+     * @param offset        the offset in bytes of the vertex component.
+     *                      Defaults to zero (corresponding to vertex position)
+     * @return pointer to the vertex component as a GrPoint
+     */
+    static GrPoint* GetVertexPoint(void* vertices,
+                                   int vertexIndex,
+                                   int vertexSize,
+                                   int offset = 0) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<GrPoint*>(start + offset +
+                                 vertexIndex * vertexSize);
+    }
+    static const GrPoint* GetVertexPoint(const void* vertices,
+                                         int vertexIndex,
+                                         int vertexSize,
+                                         int offset = 0) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<const GrPoint*>(start + offset +
+                                       vertexIndex * vertexSize);
+    }
+
+    /**
+     * Gets a pointer to a GrColor inside a vertex within a vertex array.
+     * @param vertices      the vetex array
+     * @param vertexIndex   the index of the vertex in the array
+     * @param vertexSize    the size of each vertex in the array
+     * @param offset        the offset in bytes of the vertex color
+     * @return pointer to the vertex component as a GrColor
+     */
+    static GrColor* GetVertexColor(void* vertices,
+                                   int vertexIndex,
+                                   int vertexSize,
+                                   int offset) {
+        intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<GrColor*>(start + offset +
+                                 vertexIndex * vertexSize);
+    }
+    static const GrColor* GetVertexColor(const void* vertices,
+                                         int vertexIndex,
+                                         int vertexSize,
+                                         int offset) {
+        const intptr_t start = GrTCast<intptr_t>(vertices);
+        return GrTCast<const GrColor*>(start + offset +
+                                       vertexIndex * vertexSize);
+    }
+
+    static void VertexLayoutUnitTest();
+
+protected:
+
+    // Helpers for GrDrawTarget subclasses that won't have private access to
+    // SavedDrawState but need to peek at the state values.
+    static DrState& accessSavedDrawState(SavedDrawState& sds)
+                                                        { return sds.fState; }
+    static const DrState& accessSavedDrawState(const SavedDrawState& sds)
+                                                        { return sds.fState; }
+
+    // implemented by subclass
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void** vertices,
+                                       void** indices) = 0;
+
+    virtual void releaseGeometryHelper() = 0;
+
+    // subclass overrides to be notified when clip is set.
+    virtual void clipWillBeSet(const GrClip& clip) = 0;
+
+    virtual void setVertexSourceToArrayHelper(const void* vertexArray,
+                                              int vertexCount) = 0;
+
+    virtual void setIndexSourceToArrayHelper(const void* indexArray,
+                                             int indexCount) = 0;
+
+    // Helpers for drawRect, protected so subclasses that override drawRect
+    // can use them.
+    static GrVertexLayout GetRectVertexLayout(StageBitfield stageEnableBitfield,
+                                              const GrRect* srcRects[]);
+
+    static void SetRectVertices(const GrRect& rect,
+                                const GrMatrix* matrix,
+                                const GrRect* srcRects[],
+                                const GrMatrix* srcMatrices[],
+                                GrVertexLayout layout,
+                                void* vertices);
+
+    enum GeometrySrcType {
+        kReserved_GeometrySrcType,  // src was set using reserveAndLockGeometry
+        kArray_GeometrySrcType,     // src was set using set*SourceToArray
+        kBuffer_GeometrySrcType     // src was set using set*SourceToBuffer
+    };
+
+    struct ReservedGeometry {
+        bool            fLocked;
+        uint32_t        fVertexCount;
+        uint32_t        fIndexCount;
+    } fReservedGeometry;
+
+    struct GeometrySrc {
+        GeometrySrcType         fVertexSrc;
+        const GrVertexBuffer*   fVertexBuffer; // valid if src type is buffer
+        GeometrySrcType         fIndexSrc;
+        const GrIndexBuffer*    fIndexBuffer; // valid if src type is buffer
+        GrVertexLayout          fVertexLayout;
+    } fGeometrySrc;
+
+    GrClip fClip;
+
+    DrState fCurrDrawState;
+
+    // Not meant for external use. Only setVertexSourceToBuffer and
+    // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
+    // support nested reserveAndLockGeometry (and cpu arrays internally use the
+    // same path).
+    class AutoGeometrySrcRestore {
+    public:
+        AutoGeometrySrcRestore(GrDrawTarget* target) {
+            fTarget = target;
+            fGeometrySrc = fTarget->fGeometrySrc;
+        }
+        ~AutoGeometrySrcRestore() {
+            fTarget->fGeometrySrc = fGeometrySrc;
+        }
+    private:
+        GrDrawTarget *fTarget;
+        GeometrySrc  fGeometrySrc;
+
+        AutoGeometrySrcRestore();
+        AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
+        AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
+    };
+};
+
+#endif
diff --git a/gpu/include/GrFontScaler.h b/gpu/include/GrFontScaler.h
new file mode 100644
index 0000000..77730d7
--- /dev/null
+++ b/gpu/include/GrFontScaler.h
@@ -0,0 +1,44 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrFontScaler_DEFINED
+#define GrFontScaler_DEFINED
+
+#include "GrGlyph.h"
+#include "GrKey.h"
+
+class GrPath;
+
+/**
+ *  This is a virtual base class which Gr's interface to the host platform's
+ *  font scaler.
+ *
+ *  The client is responsible for subclassing, and instantiating this. The
+ *  instance is create for a specific font+size+matrix.
+ */
+class GrFontScaler : public GrRefCnt {
+public:
+    virtual const GrKey* getKey() = 0;
+    virtual GrMaskFormat getMaskFormat() = 0;
+    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
+    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+                                     int rowBytes, void* image) = 0;
+    virtual bool getGlyphPath(uint16_t glyphID, GrPath*) = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrGLConfig.h b/gpu/include/GrGLConfig.h
new file mode 100644
index 0000000..0a86e72
--- /dev/null
+++ b/gpu/include/GrGLConfig.h
@@ -0,0 +1,188 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLConfig_DEFINED
+#define GrGLConfig_DEFINED
+
+#include "GrTypes.h"
+#include "GrGLInterface.h"
+
+/**
+ * The following are optional defines that can be enabled at the compiler
+ * command line, in a IDE project, in a GrUserConfig.h file, or in a GL custom
+ * file (if one is in use). They don't require GR_GL_CUSTOM_SETUP or
+ * setup GR_GL_CUSTOM_SETUP_HEADER to be enabled:
+ *
+ * GR_GL_LOG_CALLS: if 1 Gr can print every GL call using GrPrintf. Defaults to
+ * 0. Logging can be enabled and disabled at runtime using a debugger via to
+ * global gLogCallsGL. The initial value of gLogCallsGL is controlled by
+ * GR_GL_LOG_CALLS_START.
+ *
+ * GR_GL_LOG_CALLS_START: controls the initial value of gLogCallsGL when
+ * GR_GL_LOG_CALLS is 1. Defaults to 0.
+ *
+ * GR_GL_CHECK_ERROR: if enabled Gr can do a glGetError() after every GL call.
+ * Defaults to 1 if GR_DEBUG is set, otherwise 0. When GR_GL_CHECK_ERROR is 1
+ * this can be toggled in a debugger using the gCheckErrorGL global. The initial
+ * value of gCheckErrorGL is controlled by by GR_GL_CHECK_ERROR_START.
+ *
+ * GR_GL_CHECK_ERROR_START: controls the initial value of gCheckErrorGL
+ * when GR_GL_CHECK_ERROR is 1.  Defaults to 1.
+ */
+
+
+#if !defined(GR_GL_LOG_CALLS)
+    #define GR_GL_LOG_CALLS             0
+#endif
+
+#if !defined(GR_GL_LOG_CALLS_START)
+    #define GR_GL_LOG_CALLS_START       0
+#endif
+
+#if !defined(GR_GL_CHECK_ERROR)
+    #define GR_GL_CHECK_ERROR           GR_DEBUG
+#endif
+
+#if !defined(GR_GL_CHECK_ERROR_START)
+    #define GR_GL_CHECK_ERROR_START     1
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if GR_SCALAR_IS_FIXED
+    #define GrGLType   GL_FIXED
+#elif GR_SCALAR_IS_FLOAT
+    #define GrGLType   GL_FLOAT
+#else
+    #error "unknown GR_SCALAR type"
+#endif
+
+#if GR_TEXT_SCALAR_IS_USHORT
+    #define GrGLTextType                    GL_UNSIGNED_SHORT
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   1
+#elif GR_TEXT_SCALAR_IS_FLOAT
+    #define GrGLTextType                    GL_FLOAT
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
+#elif GR_TEXT_SCALAR_IS_FIXED
+    #define GrGLTextType                    GL_FIXED
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
+#else
+    #error "unknown GR_TEXT_SCALAR type"
+#endif
+
+// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA (except on
+// Windows where we match GDI's order).
+#ifndef GR_GL_32BPP_COLOR_FORMAT
+    #if GR_WIN32_BUILD
+        #define GR_GL_32BPP_COLOR_FORMAT    GR_BGRA //use GR prefix because this
+    #else                                           //may be an extension.
+        #define GR_GL_32BPP_COLOR_FORMAT    GL_RGBA
+    #endif
+#endif
+
+
+
+// BGRA format
+#define GR_BGRA                     0x80E1
+
+// FBO / stencil formats
+#define GR_FRAMEBUFFER              0x8D40
+#define GR_FRAMEBUFFER_COMPLETE     0x8CD5
+#define GR_COLOR_ATTACHMENT0        0x8CE0
+#define GR_FRAMEBUFFER_BINDING      0x8CA6
+#define GR_RENDERBUFFER             0x8D41
+#define GR_STENCIL_ATTACHMENT       0x8D20
+#define GR_STENCIL_INDEX4           0x8D47
+#define GR_STENCIL_INDEX8           0x8D48
+#define GR_STENCIL_INDEX16          0x8D49
+#define GR_DEPTH24_STENCIL8         0x88F0
+#define GR_MAX_RENDERBUFFER_SIZE    0x84E8
+#define GR_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GR_DEPTH_STENCIL            0x84F9
+#define GR_RGBA8                    0x8058
+#define GR_RGB565                   0x8D62
+
+
+// Multisampling
+
+// IMG MAX_SAMPLES uses a different value than desktop, Apple ES extension.
+#define GR_MAX_SAMPLES              0x8D57
+#define GR_MAX_SAMPLES_IMG          0x9135
+#define GR_READ_FRAMEBUFFER         0x8CA8
+#define GR_DRAW_FRAMEBUFFER         0x8CA9
+
+// Buffer mapping
+#define GR_WRITE_ONLY               0x88B9
+#define GR_BUFFER_MAPPED            0x88BC
+
+// Palette texture
+#define GR_PALETTE8_RGBA8           0x8B91
+
+////////////////////////////////////////////////////////////////////////////////
+
+extern void GrGLCheckErr(const char* location, const char* call);
+
+static inline void GrGLClearErr() {
+    while (GL_NO_ERROR != GrGLGetGLInterface()->fGetError()) {}
+}
+
+#if GR_GL_CHECK_ERROR
+    extern bool gCheckErrorGL;
+    #define GR_GL_CHECK_ERROR_IMPL(X) if (gCheckErrorGL) GrGLCheckErr(GR_FILE_AND_LINE_STR, #X)
+#else
+    #define GR_GL_CHECK_ERROR_IMPL(X)
+#endif
+
+#if GR_GL_LOG_CALLS
+    extern bool gLogCallsGL;
+    #define GR_GL_LOG_CALLS_IMPL(X) if (gLogCallsGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+#else
+    #define GR_GL_LOG_CALLS_IMPL(X)
+#endif
+
+#define GR_GL(X)                 GrGLGetGLInterface()->f##X;; GR_GL_LOG_CALLS_IMPL(X); GR_GL_CHECK_ERROR_IMPL(X);
+#define GR_GL_NO_ERR(X)          GrGLGetGLInterface()->f##X;; GR_GL_LOG_CALLS_IMPL(X); GR_GL_CHECK_ERROR_IMPL(X);
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  GrGL_RestoreResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
+ *  this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
+ */
+#if GR_SUPPORT_GLDESKTOP
+    static inline void GrGL_RestoreResetRowLength() {
+        GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
+    }
+#else
+    #define GrGL_RestoreResetRowLength()
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Some drivers want the var-int arg to be zero-initialized on input.
+ */
+#define GR_GL_INIT_ZERO     0
+#define GR_GL_GetIntegerv(e, p)     \
+    do {                            \
+        *(p) = GR_GL_INIT_ZERO;     \
+        GR_GL(GetIntegerv(e, p));   \
+    } while (0)
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/gpu/include/GrGLConfig_chrome.h b/gpu/include/GrGLConfig_chrome.h
new file mode 100644
index 0000000..ff0d7b7
--- /dev/null
+++ b/gpu/include/GrGLConfig_chrome.h
@@ -0,0 +1,34 @@
+#ifndef GrGLConfig_chrome_DEFINED
+#define GrGLConfig_chrome_DEFINED
+
+#define GR_SUPPORT_GLES2    1
+
+// gl2ext.h will define these extensions macros but Chrome doesn't provide
+// prototypes.
+#define GL_OES_mapbuffer                      0
+#define GL_IMG_multisampled_render_to_texture 0
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#define GR_GL_FUNC
+
+#define GR_GL_PROC_ADDRESS(X)       &X
+
+// chrome always assumes BGRA
+#define GR_GL_32BPP_COLOR_FORMAT    GR_BGRA
+
+// glGetError() forces a sync with gpu process on chrome
+#define GR_GL_CHECK_ERROR_START     0
+
+// Using the static vb precludes batching rect-to-rect draws
+// because there are matrix changes between each one.
+// Chrome was getting top performance on Windows with
+// batched rect-to-rect draws. But there seems to be some 
+// regression that now causes any dynamic VB data to perform
+// very poorly. In any event the static VB seems to get equal
+// perf to what batching was producing and it always seems to
+// be better on Linux.
+#define GR_STATIC_RECT_VB 1
+
+#endif
diff --git a/gpu/include/GrGLIRect.h b/gpu/include/GrGLIRect.h
new file mode 100644
index 0000000..80237d9
--- /dev/null
+++ b/gpu/include/GrGLIRect.h
@@ -0,0 +1,64 @@
+#include "GrGLConfig.h"
+
+#ifndef GrGLIRect_DEFINED
+#define GrGLIRect_DEFINED
+
+/**
+ * Helper struct for dealing with the fact that Ganesh and GL use different
+ * window coordinate systems (top-down vs bottom-up)
+ */
+struct GrGLIRect {
+    GLint   fLeft;
+    GLint   fBottom;
+    GLsizei fWidth;
+    GLsizei fHeight;
+
+    void pushToGLViewport() const {
+        GR_GL(Viewport(fLeft, fBottom, fWidth, fHeight));
+    }
+
+    void pushToGLScissor() const {
+        GR_GL(Scissor(fLeft, fBottom, fWidth, fHeight));
+    }
+
+    void setFromGLViewport() {
+        GR_STATIC_ASSERT(sizeof(GrGLIRect) == 4*sizeof(GLint));
+        GR_GL_GetIntegerv(GL_VIEWPORT, (GLint*) this);
+    }
+
+    // sometimes we have a GrIRect from the client that we
+    // want to simultaneously make relative to GL's viewport
+    // and convert from top-down to bottom-up.
+    void setRelativeTo(const GrGLIRect& glRect,
+                       int leftOffset,
+                       int topOffset,
+                       int width,
+                       int height) {
+        fLeft = glRect.fLeft + leftOffset;
+        fWidth = width;
+        fBottom = glRect.fBottom + (glRect.fHeight - topOffset - height);
+        fHeight = height;
+
+        GrAssert(fLeft >= 0);
+        GrAssert(fWidth >= 0);
+        GrAssert(fBottom >= 0);
+        GrAssert(fHeight >= 0);
+    }
+
+    bool contains(const GrGLIRect& glRect) const {
+        return fLeft <= glRect.fLeft &&
+               fBottom <= glRect.fBottom &&
+               fLeft + fWidth >=  glRect.fLeft + glRect.fWidth &&
+               fBottom + fHeight >=  glRect.fBottom + glRect.fHeight;
+    }
+
+    void invalidate() {fLeft = fWidth = fBottom = fHeight = -1;}
+
+    bool operator ==(const GrGLIRect& glRect) const {
+        return 0 == memcmp(this, &glRect, sizeof(GrGLIRect));
+    }
+
+    bool operator !=(const GrGLIRect& glRect) const {return !(*this == glRect);}
+};
+
+#endif
diff --git a/gpu/include/GrGLIndexBuffer.h b/gpu/include/GrGLIndexBuffer.h
new file mode 100644
index 0000000..5755c07
--- /dev/null
+++ b/gpu/include/GrGLIndexBuffer.h
@@ -0,0 +1,59 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLIndexBuffer_DEFINED
+#define GrGLIndexBuffer_DEFINED
+
+#include "GrIndexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLIndexBuffer : public GrIndexBuffer {
+protected:
+    GrGLIndexBuffer(GLuint id,
+                    GrGpuGL* gl,
+                    size_t sizeInBytes,
+                    bool dynamic);
+public:
+    virtual ~GrGLIndexBuffer();
+
+    GLuint bufferID() const;
+
+    // overrides of GrIndexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void* lockPtr() const;
+    virtual void unlock();
+    virtual bool isLocked() const;
+    virtual bool updateData(const void* src, size_t srcSizeInBytes);
+    virtual bool updateSubData(const void* src,  
+                               size_t srcSizeInBytes, 
+                               size_t offset);
+private:
+    void bind() const;
+    
+    GrGpuGL*     fGL;
+    GLuint       fBufferID;
+    void*        fLockPtr;
+    
+    friend class GrGpuGL;
+
+    typedef GrIndexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLInterface.h b/gpu/include/GrGLInterface.h
new file mode 100644
index 0000000..0a41905
--- /dev/null
+++ b/gpu/include/GrGLInterface.h
@@ -0,0 +1,272 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLInterface_DEFINED
+#define GrGLInterface_DEFINED
+
+#include "GrGLPlatformIncludes.h"
+
+#if !defined(GR_GL_FUNCTION_TYPE)
+    #define GR_GL_FUNCTION_TYPE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Helpers for glGetString()
+ */
+bool has_gl_extension(const char* ext);
+void gl_version(int* major, int* minor);
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Routines managing the global interface used to invoke OpenGL calls.
+ */
+struct GrGLInterface;
+extern GrGLInterface* GrGLGetGLInterface();
+extern void GrGLSetGLInterface(GrGLInterface* gl_interface);
+
+/*
+ * Populates the global GrGLInterface pointer with an instance pointing to the
+ * GL implementation linked with the executable.
+ */
+extern void GrGLSetDefaultGLInterface();
+
+extern "C" {
+/*
+ * The following interface exports the OpenGL entry points used by the system.
+ * Use of OpenGL calls is disallowed.  All calls should be invoked through
+ * the global instance of this struct, defined above.
+ *
+ * IMPORTANT NOTE: The OpenGL entry points exposed here include both core GL
+ * functions, and extensions.  The system assumes that the address of the
+ * extension pointer will be valid across contexts.
+ */
+struct GrGLInterface {
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLActiveTextureProc)(GLenum texture);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLAttachShaderProc)(GLuint program, GLuint shader);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindAttribLocationProc)(GLuint program, GLuint index, const char* name);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindBufferProc)(GLenum target, GLuint buffer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindTextureProc)(GLenum target, GLuint texture);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendColorProc)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendFuncProc)(GLenum sfactor, GLenum dfactor);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferDataProc)(GLenum target, GLsizei size, const void* data, GLenum usage);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferSubDataProc)(GLenum target, GLint offset, GLsizei size, const void* data);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLClearProc)(GLbitfield mask);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLClearColorProc)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLClearStencilProc)(GLint s);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLClientActiveTextureProc)(GLenum texture);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLColor4ubProc)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLColorMaskProc)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLColorPointerProc)(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLCompileShaderProc)(GLuint shader);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLCompressedTexImage2DProc)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+    typedef GLuint (GR_GL_FUNCTION_TYPE *GrGLCreateProgramProc)(void);
+    typedef GLuint (GR_GL_FUNCTION_TYPE *GrGLCreateShaderProc)(GLenum type);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLCullFaceProc)(GLenum mode);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteBuffersProc)(GLsizei n, const GLuint* buffers);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteProgramProc)(GLuint program);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteShaderProc)(GLuint shader);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteTexturesProc)(GLsizei n, const GLuint* textures);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDepthMaskProc)(GLboolean flag);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableProc)(GLenum cap);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableClientStateProc)(GLenum array);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableVertexAttribArrayProc)(GLuint index);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawArraysProc)(GLenum mode, GLint first, GLsizei count);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawElementsProc)(GLenum mode, GLsizei count, GLenum type, const void* indices);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableProc)(GLenum cap);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableClientStateProc)(GLenum cap);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableVertexAttribArrayProc)(GLuint index);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLFrontFaceProc)(GLenum mode);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGenBuffersProc)(GLsizei n, GLuint* buffers);
+    typedef GLenum (GR_GL_FUNCTION_TYPE *GrGLGetErrorProc)(void);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGenTexturesProc)(GLsizei n, GLuint* textures);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetBufferParameterivProc)(GLenum target, GLenum pname, GLint* params);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetIntegervProc)(GLenum pname, GLint* params);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetProgramInfoLogProc)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetProgramivProc)(GLuint program, GLenum pname, GLint* params);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderInfoLogProc)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGetShaderivProc)(GLuint shader, GLenum pname, GLint* params);
+    typedef const GLubyte* (GR_GL_FUNCTION_TYPE *GrGLGetStringProc)(GLenum name);
+    typedef GLint (GR_GL_FUNCTION_TYPE *GrGLGetUniformLocationProc)(GLuint program, const char* name);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLLineWidthProc)(GLfloat width);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLLinkProgramProc)(GLuint program);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLLoadMatrixfProc)(const GLfloat* m);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLMatrixModeProc)(GLenum mode);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLPixelStoreiProc)(GLenum pname, GLint param);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLPointSizeProc)(GLfloat size);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLReadPixelsProc)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLScissorProc)(GLint x, GLint y, GLsizei width, GLsizei height);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLShadeModelProc)(GLenum mode);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLShaderSourceProc)(GLuint shader, GLsizei count, const char** str, const GLint* length);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncProc)(GLenum func, GLint ref, GLuint mask);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncSeparateProc)(GLenum face, GLenum func, GLint ref, GLuint mask);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilMaskProc)(GLuint mask);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilMaskSeparateProc)(GLenum face, GLuint mask);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpProc)(GLenum fail, GLenum zfail, GLenum zpass);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpSeparateProc)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLTexCoordPointerProc)(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLTexEnviProc)(GLenum target, GLenum pname, GLint param);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLTexImage2DProc)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLTexParameteriProc)(GLenum target, GLenum pname, GLint param);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLTexSubImage2DProc)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fvProc)(GLint location, GLsizei count, const GLfloat* v);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1iProc)(GLint location, GLint x);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4fvProc)(GLint location, GLsizei count, const GLfloat* v);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix3fvProc)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLUseProgramProc)(GLuint program);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttrib4fvProc)(GLuint indx, const GLfloat* values);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttribPointerProc)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexPointerProc)(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLViewportProc)(GLint x, GLint y, GLsizei width, GLsizei height);
+
+    // FBO Extension Functions
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindFramebufferProc)(GLenum target, GLuint framebuffer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindRenderbufferProc)(GLenum target, GLuint renderbuffer);
+    typedef GLenum (GR_GL_FUNCTION_TYPE *GrGLCheckFramebufferStatusProc)(GLenum target);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteFramebuffersProc)(GLsizei n, const GLuint *framebuffers);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteRenderbuffersProc)(GLsizei n, const GLuint *renderbuffers);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLFramebufferRenderbufferProc)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLFramebufferTexture2DProc)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGenFramebuffersProc)(GLsizei n, GLuint *framebuffers);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLGenRenderbuffersProc)(GLsizei n, GLuint *renderbuffers);
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLRenderbufferStorageProc)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+
+    // Multisampling Extension Functions
+    // same prototype for ARB_FBO, EXT_FBO, GL 3.0, & Apple ES extension
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLRenderbufferStorageMultisampleProc)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+    // desktop: ext_fbo_blit, arb_fbo, gl 3.0
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBlitFramebufferProc)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+    // apple's es extension
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLResolveMultisampleFramebufferProc)();
+
+    // IMG'e es extension
+    typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLFramebufferTexture2DMultisampleProc)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+
+    // Buffer mapping (extension in ES).
+    typedef GLvoid* (GR_GL_FUNCTION_TYPE *GrGLMapBufferProc)(GLenum target, GLenum access);
+    typedef GLboolean (GR_GL_FUNCTION_TYPE *GrGLUnmapBufferProc)(GLenum target);
+
+    GrGLActiveTextureProc fActiveTexture;
+    GrGLAttachShaderProc fAttachShader;
+    GrGLBindAttribLocationProc fBindAttribLocation;
+    GrGLBindBufferProc fBindBuffer;
+    GrGLBindTextureProc fBindTexture;
+    GrGLBlendFuncProc fBlendFunc;
+    GrGLBlendColorProc fBlendColor;
+    GrGLBufferDataProc fBufferData;
+    GrGLBufferSubDataProc fBufferSubData;
+    GrGLClearProc fClear;
+    GrGLClearColorProc fClearColor;
+    GrGLClearStencilProc fClearStencil;
+    GrGLClientActiveTextureProc fClientActiveTexture;
+    GrGLColor4ubProc fColor4ub;
+    GrGLColorMaskProc fColorMask;
+    GrGLColorPointerProc fColorPointer;
+    GrGLCompileShaderProc fCompileShader;
+    GrGLCompressedTexImage2DProc fCompressedTexImage2D;
+    GrGLCreateProgramProc fCreateProgram;
+    GrGLCreateShaderProc fCreateShader;
+    GrGLCullFaceProc fCullFace;
+    GrGLDeleteBuffersProc fDeleteBuffers;
+    GrGLDeleteProgramProc fDeleteProgram;
+    GrGLDeleteShaderProc fDeleteShader;
+    GrGLDeleteTexturesProc fDeleteTextures;
+    GrGLDepthMaskProc fDepthMask;
+    GrGLDisableProc fDisable;
+    GrGLDisableClientStateProc fDisableClientState;
+    GrGLDisableVertexAttribArrayProc fDisableVertexAttribArray;
+    GrGLDrawArraysProc fDrawArrays;
+    GrGLDrawElementsProc fDrawElements;
+    GrGLEnableProc fEnable;
+    GrGLEnableClientStateProc fEnableClientState;
+    GrGLEnableVertexAttribArrayProc fEnableVertexAttribArray;
+    GrGLFrontFaceProc fFrontFace;
+    GrGLGenBuffersProc fGenBuffers;
+    GrGLGenTexturesProc fGenTextures;
+    GrGLGetBufferParameterivProc fGetBufferParameteriv;
+    GrGLGetErrorProc fGetError;
+    GrGLGetIntegervProc fGetIntegerv;
+    GrGLGetProgramInfoLogProc fGetProgramInfoLog;
+    GrGLGetProgramivProc fGetProgramiv;
+    GrGLGetShaderInfoLogProc fGetShaderInfoLog;
+    GrGLGetShaderivProc fGetShaderiv;
+    GrGLGetStringProc fGetString;
+    GrGLGetUniformLocationProc fGetUniformLocation;
+    GrGLLineWidthProc fLineWidth;
+    GrGLLinkProgramProc fLinkProgram;
+    GrGLLoadMatrixfProc fLoadMatrixf;
+    GrGLMatrixModeProc fMatrixMode;
+    GrGLPixelStoreiProc fPixelStorei;
+    GrGLPointSizeProc fPointSize;
+    GrGLReadPixelsProc fReadPixels;
+    GrGLScissorProc fScissor;
+    GrGLShadeModelProc fShadeModel;
+    GrGLShaderSourceProc fShaderSource;
+    GrGLStencilFuncProc fStencilFunc;
+    GrGLStencilFuncSeparateProc fStencilFuncSeparate;
+    GrGLStencilMaskProc fStencilMask;
+    GrGLStencilMaskSeparateProc fStencilMaskSeparate;
+    GrGLStencilOpProc fStencilOp;
+    GrGLStencilOpSeparateProc fStencilOpSeparate;
+    GrGLTexCoordPointerProc fTexCoordPointer;
+    GrGLTexEnviProc fTexEnvi;
+    GrGLTexImage2DProc fTexImage2D;
+    GrGLTexParameteriProc fTexParameteri;
+    GrGLTexSubImage2DProc fTexSubImage2D;
+    GrGLUniform1fvProc fUniform1fv;
+    GrGLUniform1iProc fUniform1i;
+    GrGLUniform4fvProc fUniform4fv;
+    GrGLUniformMatrix3fvProc fUniformMatrix3fv;
+    GrGLUseProgramProc fUseProgram;
+    GrGLVertexAttrib4fvProc fVertexAttrib4fv;
+    GrGLVertexAttribPointerProc fVertexAttribPointer;
+    GrGLVertexPointerProc fVertexPointer;
+    GrGLViewportProc fViewport;
+
+    // FBO Extension Functions
+    GrGLBindFramebufferProc fBindFramebuffer;
+    GrGLBindRenderbufferProc fBindRenderbuffer;
+    GrGLCheckFramebufferStatusProc fCheckFramebufferStatus;
+    GrGLDeleteFramebuffersProc fDeleteFramebuffers;
+    GrGLDeleteRenderbuffersProc fDeleteRenderbuffers;
+    GrGLFramebufferRenderbufferProc fFramebufferRenderbuffer;
+    GrGLFramebufferTexture2DProc fFramebufferTexture2D;
+    GrGLGenFramebuffersProc fGenFramebuffers;
+    GrGLGenRenderbuffersProc fGenRenderbuffers;
+    GrGLRenderbufferStorageProc fRenderbufferStorage;
+
+    // Multisampling Extension Functions
+    // same prototype for ARB_FBO, EXT_FBO, GL 3.0, & Apple ES extension
+    GrGLRenderbufferStorageMultisampleProc fRenderbufferStorageMultisample;
+    // desktop: ext_fbo_blit, arb_fbo, gl 3.0
+    GrGLBlitFramebufferProc fBlitFramebuffer;
+    // apple's es extension
+    GrGLResolveMultisampleFramebufferProc fResolveMultisampleFramebuffer;
+
+    // IMG'e es extension
+    GrGLFramebufferTexture2DMultisampleProc fFramebufferTexture2DMultisample;
+
+    // Buffer mapping (extension in ES).
+    GrGLMapBufferProc fMapBuffer;
+    GrGLUnmapBufferProc fUnmapBuffer;
+};
+
+}  // extern "C"
+
+#endif
diff --git a/gpu/include/GrGLPlatformIncludes.h b/gpu/include/GrGLPlatformIncludes.h
new file mode 100644
index 0000000..978a992
--- /dev/null
+++ b/gpu/include/GrGLPlatformIncludes.h
@@ -0,0 +1,522 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLPlatformIncludes_DEFINED
+#define GrGLPlatformIncludes_DEFINED
+
+#include "GrConfig.h"
+
+#if !defined(GR_GL_CUSTOM_SETUP)
+    #define GR_GL_CUSTOM_SETUP 0
+#endif
+
+/**
+ * We need to pull in the right GL headers and determine whether we are
+ * compiling for ES1, ES2, or desktop GL. (We allow ES1 and ES2 to both be
+ * supported in the same build but not ESx and desktop). We also need to know
+ * the platform-specific way to get extension function pointers (e.g.
+ * eglGetProcAddress). The port specifies this info explicitly or we will infer
+ * it from the GR_*_BUILD flag.
+ *
+ * To specify GL setup directly define GR_GL_CUSTOM_SETUP to 1 and define:
+ *      GR_SUPPORT_GLDESKTOP or (GR_SUPPORT_GLES1 and/or GR_SUPPORT_GLES2) to 1
+ *
+ *      if GR_SUPPORT_GLDESKTOP is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLDESKTOP
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLDESKTOPext.
+ *      if GR_SUPPORT_GLES1 is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLES1
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLES1ext.
+ *      if GR_SUPPORT_GLES2 is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLES2
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLES2ext.
+ *
+ *      Optionally, define GR_GL_FUNC to any qualifier needed on GL function
+ *      pointer declarations (e.g. __stdcall).
+ *
+ *      Define GR_GL_PROC_ADDRESS to take a gl function and produce a
+ *      function pointer. Two examples:
+ *          1. Your platform doesn't require a proc address function, just take
+ *             the address of the function:
+ *             #define GR_GL_PROC_ADDRESS(X) &X
+ *          2. Your platform uses eglGetProcAddress:
+ *             #define GR_GL_PROC_ADDRESS eglGetProcAddress(#X)
+ *
+ *     Optionally define GR_GL_PROC_ADDRESS_HEADER to include any additional
+ *     header necessary to use GR_GL_PROC_ADDRESS (e.g. <EGL/egl.h>)
+ *
+ * Alternatively, define GR_GL_CUSTOM_SETUP_HEADER (and not GR_GL_CUSTOM_SETUP)
+ * to a header that can be included. This file should:
+ *      1. Define the approprate GR_SUPPORT_GL* macro(s) to 1
+ *      2. Includes all necessary GL headers.
+ *      3. Optionally define GR_GL_FUNC.
+ *      4. Define GR_GL_PROC_ADDRESS.
+ *      5. Optionally define GR_GL_PROC_ADDRESS_HEADER
+ */
+
+#if GR_GL_CUSTOM_SETUP
+
+    #ifdef GR_SUPPORT_GLES1
+        #include GR_INCLUDE_GLES1
+        #if defined(GR_INCLUDE_GLES1ext)
+            #include GR_INCLUDE_GLES1ext
+        #endif
+    #endif
+
+    #ifdef GR_SUPPORT_GLES2
+        #include GR_INCLUDE_GLES2
+        #if defined(GR_INCLUDE_GLES2ext)
+            #include GR_INCLUDE_GLES2ext
+        #endif
+    #endif
+
+    #ifdef GR_SUPPORT_GLDESKTOP
+        #include GR_INCLUDE_GLDESKTOP
+        #if defined(GR_INCLUDE_GLDESKTOPext)
+            #include GR_INCLUDE_GLDESKTOPext
+        #endif
+    #endif
+
+#elif defined(GR_GL_CUSTOM_SETUP_HEADER)
+
+    #include GR_GL_CUSTOM_SETUP_HEADER
+
+#else
+    #undef GR_GL_FUNCTION_TYPE
+    #undef GR_GL_PROC_ADDRESS
+    #undef GR_GL_PROC_ADDRESS_HEADER
+
+    #if GR_WIN32_BUILD
+        #define GR_SUPPORT_GLDESKTOP        1
+        #include <Windows.h>
+        #include <GL/gl.h>
+        // remove stupid windows defines
+        #undef near
+        #undef far
+        #define GR_GL_EMIT_GL_CONSTANTS     1
+        #define GR_GL_FUNCTION_TYPE __stdcall
+        #define GR_GL_PROC_ADDRESS(X)       wglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <windows.h>
+
+        // Force querying for the existence of these extensions on Windows
+        // builds.
+        #define GL_APPLE_framebuffer_multisample        1
+        #define GL_EXT_framebuffer_object               1
+        #define GL_IMG_multisampled_render_to_texture   1
+        #define GL_OES_mapbuffer                        1
+        #define GL_OES_mapbuffer                        1
+    #elif GR_MAC_BUILD
+        #define GR_SUPPORT_GLDESKTOP        1
+        #include <OpenGL/gl.h>
+        #include <OpenGL/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       &X
+    #elif GR_IOS_BUILD
+        #define GR_SUPPORT_GLES1            1
+        #include <OpenGLES/ES1/gl.h>
+        #include <OpenGLES/ES1/glext.h>
+        #define GR_SUPPORT_GLES2            1
+        #include <OpenGLES/ES2/gl.h>
+        #include <OpenGLES/ES2/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       &X
+    #elif GR_ANDROID_BUILD
+        #ifndef GL_GLEXT_PROTOTYPES
+            #define GL_GLEXT_PROTOTYPES
+        #endif
+        #define GR_SUPPORT_GLES2            1
+        #include <GLES2/gl2.h>
+        #include <GLES2/gl2ext.h>
+        #define GR_GL_PROC_ADDRESS(X)       eglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <EGL/egl.h>
+    #elif GR_QNX_BUILD
+        #ifndef GL_GLEXT_PROTOTYPES
+            #define GL_GLEXT_PROTOTYPES
+        #endif
+         #define GR_SUPPORT_GLES2           1
+        // This is needed by the QNX GLES2 headers
+        #define GL_API_EXT
+        #include <GLES2/gl2.h>
+        #include <GLES2/gl2ext.h>
+        #define GR_GL_PROC_ADDRESS(X)       eglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <EGL/egl.h>
+    #elif GR_LINUX_BUILD
+        #ifndef GL_GLEXT_PROTOTYPES
+            #define GL_GLEXT_PROTOTYPES
+        #endif
+        #include <GL/gl.h>
+        #include <GL/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       glXGetProcAddress(reinterpret_cast<const GLubyte*>(#X))
+        #define GR_SUPPORT_GLDESKTOP        1
+        #define GR_GL_PROC_ADDRESS_HEADER   <GL/glx.h>
+    #else
+        #error "unsupported GR_???_BUILD"
+    #endif
+
+#endif
+
+#if !defined(GR_SUPPORT_GLDESKTOP)
+    #define GR_SUPPORT_GLDESKTOP    0
+#endif
+#if !defined(GR_SUPPORT_GLES1)
+    #define GR_SUPPORT_GLES1        0
+#endif
+#if !defined(GR_SUPPORT_GLES2)
+    #define GR_SUPPORT_GLES2        0
+#endif
+
+#define GR_SUPPORT_GLES ((GR_SUPPORT_GLES1) || (GR_SUPPORT_GLES2))
+
+#if !GR_SUPPORT_GLES && !GR_SUPPORT_GLDESKTOP
+    #error "Either desktop or ES GL must be supported"
+#elif GR_SUPPORT_GLES && GR_SUPPORT_GLDESKTOP
+    #error "Cannot support both desktop and ES GL"
+#endif
+
+#if GR_WIN32_BUILD && GR_GL_EMIT_GL_CONSTANTS
+
+// The windows GL headers do not provide the constants used for extensions and
+// some versions of GL.  Define them here.
+
+// OpenGL 1.2 Defines
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+
+// OpenGL 1.3 Multi-Sample Constant Values
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_SUBTRACT 0x84E7
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#define GL_MULTISAMPLE_BIT 0x20000000
+
+// OpenGL 1.4 Defines
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+
+// OpenGL 1.5 Defines
+#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
+#define GL_FOG_COORD GL_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY
+#define GL_SRC0_RGB GL_SOURCE0_RGB
+#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER
+#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE
+#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA
+#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE
+#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA
+#define GL_SRC1_RGB GL_SOURCE1_RGB
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING
+#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA
+#define GL_SRC2_RGB GL_SOURCE2_RGB
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+
+// OpenGL 2.0 Defines
+#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+
+#endif  // GR_WIN32_BUILD
+
+#endif
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
new file mode 100644
index 0000000..7b7480c
--- /dev/null
+++ b/gpu/include/GrGLTexture.h
@@ -0,0 +1,220 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLTexture_DEFINED
+#define GrGLTexture_DEFINED
+
+#include "GrTexture.h"
+#include "GrScalar.h"
+#include "GrGLIRect.h"
+
+class GrGpuGL;
+class GrGLTexture;
+
+/**
+ * A ref counted tex id that deletes the texture in its destructor.
+ */
+class GrGLTexID : public GrRefCnt {
+public:
+    GrGLTexID(GLuint texID) : fTexID(texID) {}
+
+    virtual ~GrGLTexID() {
+        if (0 != fTexID) {
+            GR_GL(DeleteTextures(1, &fTexID));
+        }
+    }
+
+    void abandon() { fTexID = 0; }
+    GLuint id() const { return fTexID; }
+
+private:
+    GLuint      fTexID;
+};
+
+class GrGLRenderTarget : public GrRenderTarget {
+public:
+    virtual ~GrGLRenderTarget();
+    
+    bool resolveable() const { return fRTFBOID != fTexFBOID; }
+    bool needsResolve() const { return fNeedsResolve; }
+    void setDirty(bool dirty) { fNeedsResolve = resolveable() && dirty; }
+    
+    GLuint renderFBOID() const { return fRTFBOID; }
+    GLuint textureFBOID() const { return fTexFBOID; }
+
+    void   abandon();
+
+protected:
+
+    struct GLRenderTargetIDs {
+        GLuint      fRTFBOID;
+        GLuint      fTexFBOID;
+        GLuint      fStencilRenderbufferID;
+        GLuint      fMSColorRenderbufferID;
+        bool        fOwnIDs;
+    };
+    
+    GrGLRenderTarget(const GLRenderTargetIDs& ids,
+                     GrGLTexID* texID,
+                     GLuint stencilBits,
+                     const GrGLIRect& fViewport,
+                     GrGLTexture* texture,
+                     GrGpuGL* gl);
+    
+    void setViewport(const GrGLIRect& rect) { fViewport = rect; }
+    const GrGLIRect& getViewport() const { return fViewport; }
+private:
+    GrGpuGL*    fGL;
+    GLuint      fRTFBOID;
+    GLuint      fTexFBOID;
+    GLuint      fStencilRenderbufferID;
+    GLuint      fMSColorRenderbufferID;
+   
+    // Should this object delete IDs when it is destroyed or does someone
+    // else own them.
+    bool        fOwnIDs;
+    
+    // If there separate Texture and RenderTarget FBO IDs then the rendertarget
+    // must be resolved to the texture FBO before it is used as a texture.
+    bool fNeedsResolve;
+    
+    // when we switch to this rendertarget we want to set the viewport to 
+    // only render to to content area (as opposed to the whole allocation) and
+    // we want the rendering to be at top left (GL has origin in bottom left) 
+    GrGLIRect fViewport;
+
+    // non-NULL if this RT was created by Gr with an associated GrGLTexture.
+    GrGLTexID* fTexIDObj;
+
+    friend class GrGpuGL;
+    friend class GrGLTexture;
+    
+    typedef GrRenderTarget INHERITED;
+};
+
+class GrGLTexture : public GrTexture {
+public:
+    enum Orientation {
+        kBottomUp_Orientation,
+        kTopDown_Orientation,
+    };
+    
+    struct TexParams {
+        GLenum fFilter;
+        GLenum fWrapS;
+        GLenum fWrapT;
+    };
+
+protected:
+    struct GLTextureDesc {
+        uint32_t    fContentWidth;
+        uint32_t    fContentHeight;
+        uint32_t    fAllocWidth;
+        uint32_t    fAllocHeight;
+        PixelConfig fFormat;
+        GLuint      fTextureID;
+        GLenum      fUploadFormat;
+        GLenum      fUploadByteCount;
+        GLenum      fUploadType;
+        GLuint      fStencilBits;
+        Orientation fOrientation;
+    };
+    typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
+    GrGLTexture(const GLTextureDesc& textureDesc,
+                const GLRenderTargetIDs& rtIDs,
+                const TexParams& initialTexParams,
+                GrGpuGL* gl);
+
+public:
+    virtual ~GrGLTexture();
+    
+    // overloads of GrTexture
+    virtual void abandon();
+    virtual GrRenderTarget* asRenderTarget();
+    virtual void releaseRenderTarget();
+    virtual void uploadTextureData(uint32_t x,
+                                   uint32_t y,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   const void* srcData);
+    virtual intptr_t getTextureHandle();
+
+    const TexParams& getTexParams() const { return fTexParams; }
+    void setTexParams(const TexParams& texParams) { fTexParams = texParams; }
+    GLuint textureID() const { return fTexIDObj->id(); }
+
+    GLenum uploadFormat() const { return fUploadFormat; }
+    GLenum uploadByteCount() const { return fUploadByteCount; }
+    GLenum uploadType() const { return fUploadType; }
+
+    /**
+     * Retrieves the texture width actually allocated in texels.
+     *
+     * @return the width in texels
+     */
+    int allocWidth() const { return fAllocWidth; }
+
+    /**
+     * Retrieves the texture height actually allocated in texels.
+     *
+     * @return the height in texels
+     */
+    int allocHeight() const { return fAllocHeight; }
+
+    /**
+     * @return width() / allocWidth()
+     */
+    GrScalar contentScaleX() const { return fScaleX; }
+
+    /**
+     * @return height() / allocHeight()
+     */
+    GrScalar contentScaleY() const { return fScaleY; }
+
+    // Ganesh assumes texture coordinates have their origin
+    // in the top-left corner of the image. OpenGL, however,
+    // has the origin in the lower-left corner. For content that
+    // is loaded by Ganesh we just push the content "upside down"
+    // (by GL's understanding of the world ) in glTex*Image and the 
+    // addressing just works out. However, content generated by GL 
+    // (FBO or externally imported texture) will be updside down 
+    // and it is up to the GrGpuGL derivative to handle y-mirroing.
+    Orientation orientation() const { return fOrientation; }
+
+private:
+    TexParams           fTexParams;
+    GrGLTexID*          fTexIDObj;
+    GLenum              fUploadFormat;
+    GLenum              fUploadByteCount;
+    GLenum              fUploadType;
+    int                 fAllocWidth;
+    int                 fAllocHeight;
+    // precomputed content / alloc ratios
+    GrScalar            fScaleX;
+    GrScalar            fScaleY;
+    Orientation         fOrientation;
+    GrGLRenderTarget*   fRenderTarget;
+    GrGpuGL*            fGpuGL;
+
+    static const GLenum gWrapMode2GLWrap[];
+
+    friend class GrGpuGL;
+
+    typedef GrTexture INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLVertexBuffer.h b/gpu/include/GrGLVertexBuffer.h
new file mode 100644
index 0000000..30ae734
--- /dev/null
+++ b/gpu/include/GrGLVertexBuffer.h
@@ -0,0 +1,60 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLVertexBuffer_DEFINED
+#define GrGLVertexBuffer_DEFINED
+
+#include "GrVertexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLVertexBuffer : public GrVertexBuffer {
+protected:
+    GrGLVertexBuffer(GLuint id,
+                     GrGpuGL* gl,
+                     size_t sizeInBytes,
+                     bool dynamic);
+
+public:
+    virtual ~GrGLVertexBuffer();
+    
+    // overrides of GrVertexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void* lockPtr() const;
+    virtual void unlock();
+    virtual bool isLocked() const;
+    virtual bool updateData(const void* src, size_t srcSizeInBytes);
+    virtual bool updateSubData(const void* src,  
+                               size_t srcSizeInBytes, 
+                               size_t offset);
+    GLuint bufferID() const;
+
+private:
+    void bind() const;
+    
+    GrGpuGL*     fGL;
+    GLuint       fBufferID;
+    void*        fLockPtr;
+
+    friend class GrGpuGL;
+
+    typedef GrVertexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGeometryBuffer.h b/gpu/include/GrGeometryBuffer.h
new file mode 100644
index 0000000..1447e73
--- /dev/null
+++ b/gpu/include/GrGeometryBuffer.h
@@ -0,0 +1,116 @@
+/*
+ Copyright 2011 Google Inc.
+ 
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrGeometryBuffer_DEFINED
+#define GrGeometryBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+/**
+ * Parent class for vertex and index buffers
+ */
+class GrGeometryBuffer : public GrRefCnt {
+public:
+    virtual ~GrGeometryBuffer() {}
+    
+    /**
+     * Retrieves the size of the buffer
+     *
+     * @return the size of the buffer in bytes
+     */
+    size_t size() const { return fSizeInBytes; }
+    
+    /**
+     *Retrieves whether the buffer was created with the dynamic flag
+     *
+     * @return true if the buffer was created with the dynamic flag
+     */
+    bool dynamic() const { return fDynamic; }
+    
+    /**
+     * Indicates that GPU context in which this veretx buffer was created is 
+     * destroyed and that Ganesh should not attempt to free the buffer in the
+     * underlying API.
+     */
+    virtual void abandon() = 0;
+    
+    /**
+     * Locks the buffer to be written by the CPU.
+     * 
+     * The previous content of the buffer is invalidated. It is an error
+     * to draw from the buffer while it is locked. It is an error to call lock
+     * on an already locked buffer.
+     * 
+     * @return a pointer to the data or NULL if the lock fails.
+     */
+    virtual void* lock() = 0;
+    
+    /**
+     * Returns the same ptr that lock() returned at time of lock or NULL if the
+     * is not locked.
+     *
+     * @return ptr to locked buffer data or undefined if buffer is not locked.
+     */
+    virtual void* lockPtr() const = 0;
+    
+    /** 
+     * Unlocks the buffer. 
+     * 
+     * The pointer returned by the previous lock call will no longer be valid.
+     */
+    virtual void unlock() = 0;
+    
+    /** 
+     Queries whether the buffer has been locked.
+     
+     @return true if the buffer is locked, false otherwise.
+     */
+    virtual bool isLocked() const = 0;
+    
+    /**
+     * Updates the buffer data. 
+     *  
+     * The size of the buffer will be preserved. The src data will be 
+     * placed at the begining of the buffer and any remaining contents will
+     * be undefined.
+     * 
+     * @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateData(const void* src, size_t srcSizeInBytes) = 0;
+    
+    /**
+     * Updates a portion of the buffer data. 
+     * 
+     * The contents of the buffer outside the update region are preserved.
+     * 
+     * @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateSubData(const void* src, 
+                               size_t srcSizeInBytes, 
+                               size_t offset) = 0;
+protected:
+    GrGeometryBuffer(size_t sizeInBytes, bool dynamic) : 
+        fSizeInBytes(sizeInBytes),
+        fDynamic(dynamic) {}
+
+private:
+    size_t   fSizeInBytes;
+    bool     fDynamic;
+
+    typedef GrRefCnt INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGlyph.h b/gpu/include/GrGlyph.h
new file mode 100644
index 0000000..4a3b307
--- /dev/null
+++ b/gpu/include/GrGlyph.h
@@ -0,0 +1,89 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGlyph_DEFINED
+#define GrGlyph_DEFINED
+
+#include "GrPath.h"
+#include "GrRect.h"
+
+class GrAtlas;
+
+/*  Need this to be quad-state:
+    - complete w/ image
+    - just metrics
+    - failed to get image, but has metrics
+    - failed to get metrics
+ */
+struct GrGlyph {
+    typedef uint32_t PackedID;
+
+    GrAtlas*    fAtlas;
+    GrPath*     fPath;
+    PackedID    fPackedID;
+    GrIRect16   fBounds;
+    GrIPoint16  fAtlasLocation;
+
+    void init(GrGlyph::PackedID packed, const GrIRect& bounds) {
+        fAtlas = NULL;
+        fPath = NULL;
+        fPackedID = packed;
+        fBounds.set(bounds);
+        fAtlasLocation.set(0, 0);
+    }
+    
+    void free() {
+        if (fPath) {
+            delete fPath;
+            fPath = NULL;
+        }
+    }
+    
+    int width() const { return fBounds.width(); }
+    int height() const { return fBounds.height(); }
+    bool isEmpty() const { return fBounds.isEmpty(); }
+    uint16_t glyphID() const { return UnpackID(fPackedID); }
+
+    ///////////////////////////////////////////////////////////////////////////
+    
+    static inline unsigned ExtractSubPixelBitsFromFixed(GrFixed pos) {
+        // two most significant fraction bits from fixed-point
+        return (pos >> 14) & 3;
+    }
+    
+    static inline PackedID Pack(uint16_t glyphID, GrFixed x, GrFixed y) {
+        x = ExtractSubPixelBitsFromFixed(x);
+        y = ExtractSubPixelBitsFromFixed(y);
+        return (x << 18) | (y << 16) | glyphID;
+    }
+    
+    static inline GrFixed UnpackFixedX(PackedID packed) {
+        return ((packed >> 18) & 3) << 14;
+    }
+    
+    static inline GrFixed UnpackFixedY(PackedID packed) {
+        return ((packed >> 16) & 3) << 14;
+    }
+    
+    static inline uint16_t UnpackID(PackedID packed) {
+        return (uint16_t)packed;
+    }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
new file mode 100644
index 0000000..75fb1f4
--- /dev/null
+++ b/gpu/include/GrGpu.h
@@ -0,0 +1,574 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrGpu_DEFINED
+#define GrGpu_DEFINED
+
+#include "GrRect.h"
+#include "GrRefCnt.h"
+#include "GrDrawTarget.h"
+#include "GrTexture.h"
+
+class GrVertexBufferAllocPool;
+class GrIndexBufferAllocPool;
+class GrPathRenderer;
+
+class GrGpu : public GrDrawTarget {
+
+public:
+    /**
+     * Possible 3D APIs that may be used by Ganesh.
+     */
+    enum Engine {
+        kOpenGL_Shaders_Engine,
+        kOpenGL_Fixed_Engine,
+        kDirect3D9_Engine
+    };
+
+    /**
+     * Platform specific 3D context.
+     * For
+     *    kOpenGL_Shaders_Engine use NULL
+     *    kOpenGL_Fixed_Engine   use NULL
+     *    kDirect3D9_Engine      use an IDirect3DDevice9*
+     */
+    typedef void* Platform3DContext;
+
+    /**
+     *  Create an instance of GrGpu that matches the specified Engine backend.
+     *  If the requested engine is not supported (at compile-time or run-time)
+     *  this returns NULL.
+     */
+    static GrGpu* Create(Engine, Platform3DContext context3D);
+
+    /**
+     * Used to control the level of antialiasing available for a rendertarget.
+     * Anti-alias quality levels depend on the underlying API/GPU capabilities.
+     */
+    enum AALevels {
+        kNone_AALevel, //<! No antialiasing available.
+        kLow_AALevel,  //<! Low quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+        kMed_AALevel,  //<! Medium quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+        kHigh_AALevel, //<! High quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+    };
+
+
+    /**
+     * Optional bitfield flags that can be passed to createTexture.
+     */
+    enum TextureFlags {
+        kRenderTarget_TextureFlag  = 0x1,   //<! Creates a texture that can be
+                                            //   rendered to by calling
+                                            //   GrGpu::setRenderTarget() with
+                                            //   GrTexture::asRenderTarget().
+        kNoPathRendering_TextureFlag = 0x2, //<! If the texture is used as a
+                                            //   rendertarget but paths will not
+                                            //   be rendered to it.
+        kDynamicUpdate_TextureFlag = 0x4    //!< Hint that the CPU may modify
+                                            // this texture after creation
+    };
+
+    enum {
+        /**
+         *  For Index8 pixel config, the colortable must be 256 entries
+         */
+        kColorTableSize = 256 * sizeof(GrColor)
+    };
+    /**
+     * Describes a texture to be created.
+     */
+    struct TextureDesc {
+        uint32_t               fFlags;  //!< bitfield of TextureFlags
+        GrGpu::AALevels        fAALevel;//!< The level of antialiasing available
+                                        //   for a rendertarget texture. Only
+                                        //   flags contains
+                                        //   kRenderTarget_TextureFlag.
+        uint32_t               fWidth;  //!< Width of the texture
+        uint32_t               fHeight; //!< Height of the texture
+        GrTexture::PixelConfig fFormat; //!< Format of source data of the
+                                        //   texture. Not guaraunteed to be the
+                                        //   same as internal format used by
+                                        //   3D API.
+    };
+
+    /**
+     * Gpu usage statistics.
+     */
+    struct Stats {
+        uint32_t fVertexCnt;  //<! Number of vertices drawn
+        uint32_t fIndexCnt;   //<! Number of indices drawn
+        uint32_t fDrawCnt;    //<! Number of draws
+
+        uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
+
+        /*
+         *  Number of times the texture is set in 3D API
+         */
+        uint32_t fTextureChngCnt;
+        /*
+         *  Number of times the render target is set in 3D API
+         */
+        uint32_t fRenderTargetChngCnt;
+        /*
+         *  Number of textures created (includes textures that are rendertargets).
+         */
+        uint32_t fTextureCreateCnt;
+        /*
+         *  Number of rendertargets created.
+         */
+        uint32_t fRenderTargetCreateCnt;
+    };
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    GrGpu();
+    virtual ~GrGpu();
+
+    /**
+     * The GrGpu object normally assumes that no outsider is setting state
+     * within the underlying 3D API's context/device/whatever. This call informs
+     * the GrGpu that the state was modified and it shouldn't make assumptions
+     * about the state.
+     */
+    void markContextDirty() { fContextIsDirty = true; }
+
+    void unimpl(const char[]);
+
+    /**
+     * Creates a texture object. If desc width or height is not a power of
+     * two but underlying API requires a power of two texture then srcData
+     * will be embedded in a power of two texture. The extra width and height
+     * is filled as though srcData were rendered clamped into the texture.
+     *
+     * If kRenderTarget_TextureFlag is specified the GrRenderTarget is 
+     * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
+     * on the render target until its releaseRenderTarget() is called or it is
+     * destroyed.
+     *
+     * @param desc        describes the texture to be created.
+     * @param srcData     texel data to load texture. Begins with full-size
+     *                    palette data for paletted textures. Contains width*
+     *                    height texels. If NULL texture data is uninitialized.
+     *
+     * @return    The texture object if successful, otherwise NULL.
+     */
+    GrTexture* createTexture(const TextureDesc& desc,
+                             const void* srcData, size_t rowBytes);
+    /**
+     * Wraps an externally-created rendertarget in a GrRenderTarget.
+     * @param platformRenderTarget  handle to the the render target in the
+     *                              underlying 3D API. Interpretation depends on
+     *                              GrGpu subclass in use.
+     * @param stencilBits           number of stencil bits the target has
+     * @param width                 width of the render target
+     * @param height                height of the render target
+     */
+    virtual GrRenderTarget* createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height);
+
+    /**
+     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
+     * viewport state from the underlying 3D API and wraps it in a
+     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
+     * underlying object in its destructor and it is up to caller to guarantee
+     * that it remains valid while the GrRenderTarget is used.
+     *
+     * @return the newly created GrRenderTarget
+     */
+    GrRenderTarget* createRenderTargetFrom3DApiState();
+
+    /**
+     * Creates a vertex buffer.
+     *
+     * @param size    size in bytes of the vertex buffer
+     * @param dynamic hints whether the data will be frequently changed
+     *                by either GrVertexBuffer::lock or
+     *                GrVertexBuffer::updateData.
+     *
+     * @return    The vertex buffer if successful, otherwise NULL.
+     */
+    GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
+
+    /**
+     * Creates an index buffer.
+     *
+     * @param size    size in bytes of the index buffer
+     * @param dynamic hints whether the data will be frequently changed
+     *                by either GrIndexBuffer::lock or
+     *                GrIndexBuffer::updateData.
+     *
+     * @return The index buffer if successful, otherwise NULL.
+     */
+    GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
+
+    /**
+     * Erase the entire render target, ignoring any clips/scissors.
+     *
+     * This is issued to the GPU driver immediately.
+     */
+    void eraseColor(GrColor color);
+
+    /**
+     * Are 8 bit paletted textures supported.
+     *
+     * @return    true if 8bit palette textures are supported, false otherwise
+     */
+    bool supports8BitPalette() const { return f8bitPaletteSupport; }
+
+    /**
+     * returns true if two sided stenciling is supported. If false then only
+     * the front face values of the GrStencilSettings
+     * @return    true if only a single stencil pass is needed.
+     */
+    bool supportsTwoSidedStencil() const
+                                        { return fTwoSidedStencilSupport; }
+
+    /**
+     * returns true if stencil wrap is supported. If false then
+     * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as
+     * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively.
+     * @return    true if stencil wrap ops are supported.
+     */
+    bool supportsStencilWrapOps() const
+                                        { return fStencilWrapOpsSupport; }
+
+    /**
+     * Checks whether locking vertex and index buffers is supported.
+     *
+     * @return true if locking is supported.
+     */
+    bool supportsBufferLocking() const { return fBufferLockSupport; }
+
+    /**
+     * Gets the minimum width of a render target. If a texture/rt is created
+     * with a width less than this size the GrGpu object will clamp it to this
+     * value.
+     */
+    int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
+
+    /**
+     * Gets the minimum width of a render target. If a texture/rt is created
+     * with a height less than this size the GrGpu object will clamp it to this
+     * value.
+     */
+    int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
+
+    /**
+     * Returns true if NPOT textures can be created
+     *
+     * @return    true if NPOT textures can be created
+     */
+    bool npotTextureSupport() const { return fNPOTTextureSupport; }
+
+    /**
+     * Returns true if NPOT textures can be repeat/mirror tiled.
+     *
+     * @return    true if NPOT textures can be tiled
+     */
+    bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
+
+    /**
+     * Returns true if a NPOT texture can be a rendertarget
+     *
+     * @return    the true if NPOT texture/rendertarget can be created.
+     */
+    bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
+
+    int maxTextureDimension() const { return fMaxTextureDimension; }
+
+    // GrDrawTarget overrides
+    virtual void drawIndexed(GrPrimitiveType type,
+                             int startVertex,
+                             int startIndex,
+                             int vertexCount,
+                             int indexCount);
+
+    virtual void drawNonIndexed(GrPrimitiveType type,
+                                int startVertex,
+                                int vertexCount);
+
+    /**
+     * Returns an index buffer that can be used to render quads.
+     * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
+     * The max number of quads can be queried using GrIndexBuffer::maxQuads().
+     * Draw with kTriangles_PrimitiveType
+     * @ return the quad index buffer
+     */
+    const GrIndexBuffer* getQuadIndexBuffer() const;
+
+    /**
+     * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
+     * (1,1), (0,1)].
+     * @ return unit square vertex buffer
+     */
+    const GrVertexBuffer* getUnitSquareVertexBuffer() const;
+
+    /**
+     * Ensures that the current render target is actually set in the
+     * underlying 3D API. Used when client wants to use 3D API to directly
+     * render to the RT.
+     */
+    void forceRenderTargetFlush();
+
+    /**
+     * Reads a rectangle of pixels from the current render target.
+     * @param left      left edge of the rectangle to read (inclusive)
+     * @param top       top edge of the rectangle to read (inclusive)
+     * @param width     width of rectangle to read in pixels.
+     * @param height    height of rectangle to read in pixels.
+     * @param buffer    memory to read the rectangle into.
+     *
+     * @return true if the read succeeded, false if not. The read can fail
+     *              because of a unsupported pixel config or because no render
+     *              target is currently set.
+     */
+    bool readPixels(int left, int top, int width, int height,
+                    GrTexture::PixelConfig, void* buffer);
+
+
+    const Stats& getStats() const;
+    void resetStats();
+    void printStats() const;
+
+protected:
+    enum PrivateStateBits {
+        kFirstBit = (kLastPublicStateBit << 1),
+
+        kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
+                                                 // stencil bits used for
+                                                 // clipping.
+    };
+
+    /**
+     * Extensions to GrDrawTarget::StateBits to implement stencil clipping
+     */
+    struct ClipState {
+        bool            fClipInStencil;
+        bool            fClipIsDirty;
+    } fClipState;
+
+    // GrDrawTarget override
+    virtual void clipWillBeSet(const GrClip& newClip);
+
+    // prepares clip flushes gpu state before a draw
+    bool setupClipAndFlushState(GrPrimitiveType type);
+
+    // Functions used to map clip-respecting stencil tests into normal
+    // stencil funcs supported by GPUs.
+    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
+                                            GrStencilFunc func);
+    static void ConvertStencilFuncAndMask(GrStencilFunc func,
+                                          bool clipInStencil,
+                                          unsigned int clipBit,
+                                          unsigned int userBits,
+                                          unsigned int* ref,
+                                          unsigned int* mask);
+
+    // stencil settings to clip drawing when stencil clipping is in effect
+    // and the client isn't using the stencil test.
+    static const GrStencilSettings gClipStencilSettings;
+
+    // defaults to false, subclass can set true to support palleted textures
+    bool f8bitPaletteSupport;
+
+    // set by subclass
+    bool fNPOTTextureSupport;
+    bool fNPOTTextureTileSupport;
+    bool fNPOTRenderTargetSupport;
+    bool fTwoSidedStencilSupport;
+    bool fStencilWrapOpsSupport;
+
+    // set by subclass to true if index and vertex buffers can be locked, false
+    // otherwise.
+    bool fBufferLockSupport;
+
+    // set by subclass
+    int fMinRenderTargetWidth;
+    int fMinRenderTargetHeight;
+    int fMaxTextureDimension;
+
+    Stats           fStats;
+
+    const GrVertexBuffer*           fCurrPoolVertexBuffer;
+    int                             fCurrPoolStartVertex;
+
+    const GrIndexBuffer*            fCurrPoolIndexBuffer;
+    int                             fCurrPoolStartIndex;
+
+    // GrDrawTarget overrides
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void**         vertices,
+                                       void**         indices);
+    virtual void releaseGeometryHelper();
+
+    virtual void setVertexSourceToArrayHelper(const void* vertexArray,
+                                              int vertexCount);
+
+    virtual void setIndexSourceToArrayHelper(const void* indexArray,
+                                             int indexCount);
+    // Helpers for setting up geometry state
+    void finalizeReservedVertices();
+    void finalizeReservedIndices();
+
+    // overridden by API-specific derived class to handle re-emitting 3D API
+    // preample and dirtying state cache.
+    virtual void resetContext() = 0;
+
+    // overridden by API-specific derived class to create objects.
+    virtual GrTexture* createTextureHelper(const TextureDesc& desc,
+                                           const void* srcData,
+                                           size_t rowBytes) = 0;
+    virtual GrRenderTarget* createPlatformRenderTargetHelper(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height) = 0;
+    virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper() = 0;
+    virtual GrVertexBuffer* createVertexBufferHelper(uint32_t size,
+                                                     bool dynamic) = 0;
+    virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
+                                                   bool dynamic) = 0;
+
+    // overridden by API-specific derivated class to perform the erase.
+    virtual void eraseColorHelper(GrColor color) = 0;
+
+    // overridden by API-specific derived class to perform the draw call.
+    virtual void drawIndexedHelper(GrPrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount) = 0;
+
+    virtual void drawNonIndexedHelper(GrPrimitiveType type,
+                                      uint32_t vertexCount,
+                                      uint32_t numVertices) = 0;
+
+    // overridden by API-specific derived class to perform flush
+    virtual void forceRenderTargetFlushHelper() = 0;
+
+    // overridden by API-specific derived class to perform the read pixels.
+    virtual bool readPixelsHelper(int left, int top, int width, int height,
+                                  GrTexture::PixelConfig, void* buffer) = 0;
+
+    // called to program the vertex data, indexCount will be 0 if drawing non-
+    // indexed geometry. The subclass may adjust the startVertex and/or
+    // startIndex since it may have already accounted for these in the setup.
+    virtual void setupGeometry(int* startVertex,
+                               int* startIndex,
+                               int vertexCount,
+                               int indexCount) = 0;
+
+
+    // The GrGpu typically records the clients requested state and then flushes
+    // deltas from previous state at draw time. This function does the
+    // API-specific flush of the state
+    // returns false if current state is unsupported.
+    virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
+
+    // Sets the scissor rect, or disables if rect is NULL.
+    virtual void flushScissor(const GrIRect* rect) = 0;
+
+    // GrGpu subclass removes the clip from the stencil buffer
+    virtual void eraseStencilClip(const GrIRect& rect) = 0;
+
+private:
+    // readies the pools to provide vertex/index data.
+    void prepareVertexPool();
+    void prepareIndexPool();
+
+    GrPathRenderer* getPathRenderer();
+
+    void handleDirtyContext() {
+        if (fContextIsDirty) {
+            this->resetContext();
+            fContextIsDirty = false;
+        }
+    }
+
+    GrVertexBufferAllocPool*    fVertexPool;
+
+    GrIndexBufferAllocPool*     fIndexPool;
+
+    mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
+                                                  // created on-demand
+
+    mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
+                                                         // created on-demand
+
+    GrPathRenderer*             fPathRenderer;
+
+    bool                        fContextIsDirty;
+
+    // when in an internal draw these indicate whether the pools are in use
+    // by one of the outer draws. If false then it is safe to reset the
+    // pool.
+    bool                        fVertexPoolInUse;
+    bool                        fIndexPoolInUse;
+
+    // used to save and restore state when the GrGpu needs
+    // to make its geometry pools available internally
+    class AutoInternalDrawGeomRestore {
+    public:
+        AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
+            fGpu = gpu;
+
+            fVertexPoolWasInUse = gpu->fVertexPoolInUse;
+            fIndexPoolWasInUse  = gpu->fIndexPoolInUse;
+
+            gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
+                                   (kBuffer_GeometrySrcType !=
+                                    gpu->fGeometrySrc.fVertexSrc);
+            gpu->fIndexPoolInUse  = fIndexPoolWasInUse ||
+                                   (kBuffer_GeometrySrcType !=
+                                    gpu->fGeometrySrc.fIndexSrc);;
+
+            fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
+            fSavedPoolStartVertex  = gpu->fCurrPoolStartVertex;
+            fSavedPoolIndexBuffer  = gpu->fCurrPoolIndexBuffer;
+            fSavedPoolStartIndex   = gpu->fCurrPoolStartIndex;
+
+            fSavedReservedGeometry = gpu->fReservedGeometry;
+            gpu->fReservedGeometry.fLocked = false;
+        }
+        ~AutoInternalDrawGeomRestore() {
+            fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
+            fGpu->fCurrPoolStartVertex  = fSavedPoolStartVertex;
+            fGpu->fCurrPoolIndexBuffer  = fSavedPoolIndexBuffer;
+            fGpu->fCurrPoolStartIndex   = fSavedPoolStartIndex;
+            fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
+            fGpu->fIndexPoolInUse  = fIndexPoolWasInUse;
+            fGpu->fReservedGeometry = fSavedReservedGeometry;
+        }
+    private:
+        AutoGeometrySrcRestore  fAgsr;
+        GrGpu*                  fGpu;
+        const GrVertexBuffer*   fSavedPoolVertexBuffer;
+        int                     fSavedPoolStartVertex;
+        const GrIndexBuffer*    fSavedPoolIndexBuffer;
+        int                     fSavedPoolStartIndex;
+        bool                    fVertexPoolWasInUse;
+        bool                    fIndexPoolWasInUse;
+        ReservedGeometry        fSavedReservedGeometry;
+    };
+
+    typedef GrDrawTarget INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGpuVertex.h b/gpu/include/GrGpuVertex.h
new file mode 100644
index 0000000..1e3293a
--- /dev/null
+++ b/gpu/include/GrGpuVertex.h
@@ -0,0 +1,104 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuVertex_DEFINED
+#define GrGpuVertex_DEFINED
+
+#include "GrGLConfig.h"
+#include "GrPoint.h"
+
+#if GR_TEXT_SCALAR_IS_USHORT
+    typedef uint16_t                GrTextScalar;  
+    #define GrIntToTextScalar(x)    ((uint16_t)x)
+    #define GrFixedToTextScalar(x)  (x)
+#elif GR_TEXT_SCALAR_IS_FIXED
+    typedef GrFixed                 GrTextScalar;
+    #define GrIntToTextScalar(x)    GrIntToFixed(x)
+    #define GrFixedToTextScalar(x)  (x)
+#elif GR_TEXT_SCALAR_IS_FLOAT
+    typedef float                   GrTextScalar;    
+    #define GrIntToTextScalar(x)    ((GrTextScalar)x)
+    #define GrFixedToTextScalar(x)  GrFixedToFloat(x)
+#else
+    #error "Text scalar type not defined"
+#endif
+
+// text has its own vertex class, since it may want to be in fixed point (given)
+// that it starts with all integers) even when the default vertices are floats
+struct GrGpuTextVertex {
+    GrTextScalar fX;
+    GrTextScalar fY;
+
+    void set(GrTextScalar x, GrTextScalar y) {
+        fX = x;
+        fY = y;
+    }
+
+    void setI(int x, int y) {
+        fX = GrIntToTextScalar(x);
+        fY = GrIntToTextScalar(y);
+    }
+    
+    void setX(GrFixed x, GrFixed y) {
+        fX = GrFixedToTextScalar(x);
+        fY = GrFixedToTextScalar(y);
+    }
+    
+    // rect fan is counter-clockwise
+
+    void setRectFan(GrTextScalar l, GrTextScalar t, GrTextScalar r,
+                    GrTextScalar b) {
+        GrGpuTextVertex* v = this;
+        v[0].set(l, t);
+        v[1].set(l, b);
+        v[2].set(r, b);
+        v[3].set(r, t);
+    }
+
+    void setIRectFan(int l, int t, int r, int b) {
+        this->setRectFan(GrIntToTextScalar(l), GrIntToTextScalar(t),
+                         GrIntToTextScalar(r), GrIntToTextScalar(b));
+    }
+
+    void setIRectFan(int l, int t, int r, int b, size_t stride) {
+        GrAssert(stride > sizeof(GrGpuTextVertex));
+        char* v = (char*)this;
+        ((GrGpuTextVertex*)(v + 0*stride))->setI(l, t);
+        ((GrGpuTextVertex*)(v + 1*stride))->setI(l, b);
+        ((GrGpuTextVertex*)(v + 2*stride))->setI(r, b);
+        ((GrGpuTextVertex*)(v + 3*stride))->setI(r, t);
+    }
+
+    // counter-clockwise fan
+    void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b) {
+        this->setRectFan(GrFixedToTextScalar(l), GrFixedToTextScalar(t),
+                         GrFixedToTextScalar(r), GrFixedToTextScalar(b));
+    }
+
+    void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b, size_t stride) {
+        GrAssert(stride > sizeof(GrGpuTextVertex));
+        char* v = (char*)this;
+        ((GrGpuTextVertex*)(v + 0*stride))->setX(l, t);
+        ((GrGpuTextVertex*)(v + 1*stride))->setX(l, b);
+        ((GrGpuTextVertex*)(v + 2*stride))->setX(r, b);
+        ((GrGpuTextVertex*)(v + 3*stride))->setX(r, t);
+    }
+
+};
+
+#endif
+
diff --git a/gpu/include/GrIPoint.h b/gpu/include/GrIPoint.h
new file mode 100644
index 0000000..b979a09
--- /dev/null
+++ b/gpu/include/GrIPoint.h
@@ -0,0 +1,35 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrIPoint_DEFINED
+#define GrIPoint_DEFINED
+
+#include "GrTypes.h"
+
+struct GrIPoint {
+public:
+    int32_t fX, fY;
+    
+    GrIPoint(int32_t x, int32_t y) : fX(x), fY(y) {}
+   
+    void set(int32_t x, int32_t y) {
+        fX = x;
+        fY = y;
+    }
+};
+
+#endif
diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h
new file mode 100644
index 0000000..79ec458
--- /dev/null
+++ b/gpu/include/GrInOrderDrawBuffer.h
@@ -0,0 +1,176 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrInOrderDrawBuffer_DEFINED
+#define GrInOrderDrawBuffer_DEFINED
+
+#include "GrDrawTarget.h"
+#include "GrAllocPool.h"
+#include "GrAllocator.h"
+#include "GrClip.h"
+
+class GrVertexBufferAllocPool;
+class GrIndexBufferAllocPool;
+
+/**
+ * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
+ * draws for eventual playback into a GrGpu. In theory one draw buffer could
+ * playback into another. When index or vertex buffers are used as geometry
+ * sources it is the callers the draw buffer only holds references to the
+ * buffers. It is the callers responsibility to ensure that the data is still
+ * valid when the draw buffer is played back into a GrGpu. Similarly, it is the
+ * caller's responsibility to ensure that all referenced textures, buffers,
+ * and rendertargets are associated in the GrGpu object that the buffer is
+ * played back into. The buffer requires VB and IB pools to store geometry.
+ */
+
+class GrInOrderDrawBuffer : public GrDrawTarget {
+public:
+
+    /**
+     * Creates a GrInOrderDrawBuffer
+     *
+     * @param vertexPool pool where vertices for queued draws will be saved when
+     *                   the vertex source is either reserved or array.
+     * @param indexPool  pool where indices for queued draws will be saved when
+     *                   the index source is either reserved or array.
+     */
+    GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
+                        GrIndexBufferAllocPool* indexPool);
+
+    virtual ~GrInOrderDrawBuffer();
+
+    /**
+     * Copies the draw state and clip from target to this draw buffer.
+     *
+     * @param target    the target whose clip and state should be copied.
+     */
+    void initializeDrawStateAndClip(const GrDrawTarget& target);
+
+    /**
+     * Provides the buffer with an index buffer that can be used for quad rendering.
+     * The buffer may be able to batch consecutive drawRects if this is provided.
+     * @param indexBuffer   index buffer with quad indices.
+     */
+    void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
+
+    /**
+     * Empties the draw buffer of any queued up draws.
+     */
+    void reset();
+
+    /**
+     * plays the queued up draws to another target. Does not empty this buffer so
+     * that it can be played back multiple times.
+     * @param target    the target to receive the playback
+     */
+    void playback(GrDrawTarget* target);
+    
+    // overrides from GrDrawTarget
+    virtual void drawIndexed(GrPrimitiveType primitiveType,
+                             int startVertex,
+                             int startIndex,
+                             int vertexCount,
+                             int indexCount);
+    virtual void drawNonIndexed(GrPrimitiveType primitiveType,
+                                int startVertex,
+                                int vertexCount);
+
+    virtual void drawRect(const GrRect& rect, 
+                          const GrMatrix* matrix = NULL,
+                          int stageEnableMask = 0,
+                          const GrRect* srcRects[] = NULL,
+                          const GrMatrix* srcMatrices[] = NULL);
+
+    virtual bool geometryHints(GrVertexLayout vertexLayout,
+                               int* vertexCount,
+                               int* indexCount) const;
+
+private:
+
+    struct Draw {
+        GrPrimitiveType         fPrimitiveType;
+        int                     fStartVertex;
+        int                     fStartIndex;
+        int                     fVertexCount;
+        int                     fIndexCount;
+        bool                    fStateChanged;
+        bool                    fClipChanged;
+        GrVertexLayout          fVertexLayout;
+        const GrVertexBuffer*   fVertexBuffer;
+        const GrIndexBuffer*    fIndexBuffer;
+    };
+
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void**         vertices,
+                                       void**         indices);
+    virtual void releaseGeometryHelper();
+    virtual void clipWillBeSet(const GrClip& newClip);
+
+    virtual void setVertexSourceToArrayHelper(const void* vertexArray,
+                                              int vertexCount);
+
+    virtual void setIndexSourceToArrayHelper(const void* indexArray,
+                                             int indexCount);
+
+    bool needsNewState() const;
+    bool needsNewClip() const;
+
+    void pushState();
+    void pushClip();
+
+    GrTAllocator<Draw>              fDraws;
+    GrTAllocator<SavedDrawState>    fStates;
+
+    GrTAllocator<GrClip>            fClips;
+    bool                            fClipSet;
+
+    GrVertexLayout                  fLastRectVertexLayout;
+    const GrIndexBuffer*            fQuadIndexBuffer;
+    int                             fMaxQuads;
+    int                             fCurrQuad;
+
+    GrVertexBufferAllocPool&        fVertexPool;
+    const GrVertexBuffer*           fCurrPoolVertexBuffer;
+    int                             fCurrPoolStartVertex;
+
+    GrIndexBufferAllocPool&         fIndexPool;
+    const GrIndexBuffer*            fCurrPoolIndexBuffer;
+    int                             fCurrPoolStartIndex;
+
+    // caller may conservatively over reserve vertices / indices.
+    // we release unused space back to allocator if possible
+    size_t                          fReservedVertexBytes;
+    size_t                          fReservedIndexBytes;
+    size_t                          fUsedReservedVertexBytes;
+    size_t                          fUsedReservedIndexBytes;
+
+    static const uint32_t           STATES_BLOCK_SIZE = 8;
+    static const uint32_t           DRAWS_BLOCK_SIZE  = 8;
+    static const uint32_t           CLIPS_BLOCK_SIZE  = 8;
+    static const uint32_t           VERTEX_BLOCK_SIZE = 1 << 12;
+    static const uint32_t           INDEX_BLOCK_SIZE  = 1 << 10;
+    int8_t                          fDrawsStorage[sizeof(Draw) *
+                                                  DRAWS_BLOCK_SIZE];
+    int8_t                          fStatesStorage[sizeof(SavedDrawState) *
+                                                   STATES_BLOCK_SIZE];
+    int8_t                          fClipsStorage[sizeof(GrClip) *
+                                                  CLIPS_BLOCK_SIZE];
+    typedef GrDrawTarget INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrIndexBuffer.h b/gpu/include/GrIndexBuffer.h
new file mode 100644
index 0000000..09d1977
--- /dev/null
+++ b/gpu/include/GrIndexBuffer.h
@@ -0,0 +1,38 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrIndexBuffer_DEFINED
+#define GrIndexBuffer_DEFINED
+
+#include "GrGeometryBuffer.h"
+
+class GrIndexBuffer : public GrGeometryBuffer {
+public:
+        /**
+         * Retrieves the maximum number of quads that could be rendered
+         * from the index buffer (using kTriangles_PrimitiveType).
+         * @return the maximum number of quads using full size of index buffer.
+         */
+        int maxQuads() const { return size() / (sizeof(uint16_t) * 6); }
+protected:
+    GrIndexBuffer(size_t sizeInBytes, bool dynamic) :
+        INHERITED(sizeInBytes, dynamic) {}
+private:
+    typedef GrGeometryBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrInstanceCounter.h b/gpu/include/GrInstanceCounter.h
new file mode 100644
index 0000000..11cec2b
--- /dev/null
+++ b/gpu/include/GrInstanceCounter.h
@@ -0,0 +1,47 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrInstanceCounter_DEFINED
+#define GrInstanceCounter_DEFINED
+
+#include "GrTypes.h"
+
+template <typename T> class GrInstanceCounter {
+public:
+    GrInstanceCounter() {
+        ++gCounter;
+        GrPrintf("+ %s %d\n", T::InstanceCounterClassName(), gCounter);
+    }
+
+    ~GrInstanceCounter() {
+        --gCounter;
+        GrPrintf("- %s %d\n", T::InstanceCounterClassName(), gCounter);
+    }
+
+private:
+    static int gCounter;
+};
+
+template <typename T> int GrInstanceCounter<T>::gCounter;
+
+#define DECLARE_INSTANCE_COUNTER(T)                                 \
+    static const char* InstanceCounterClassName() { return #T; }    \
+    friend class GrInstanceCounter<T>;                              \
+    GrInstanceCounter<T> fInstanceCounter
+
+#endif
+
diff --git a/gpu/include/GrKey.h b/gpu/include/GrKey.h
new file mode 100644
index 0000000..19133ae
--- /dev/null
+++ b/gpu/include/GrKey.h
@@ -0,0 +1,47 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrKey_DEFINED
+#define GrKey_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrKey : public GrRefCnt {
+public:
+    typedef intptr_t Hash;
+
+    explicit GrKey(Hash hash) : fHash(hash) {}
+
+    intptr_t getHash() const { return fHash; }
+
+    bool operator<(const GrKey& rh) const {
+        return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
+    }
+    bool operator==(const GrKey& rh) const {
+        return fHash == rh.fHash && this->eq(rh);
+    }
+
+protected:
+    virtual bool lt(const GrKey& rh) const = 0;
+    virtual bool eq(const GrKey& rh) const = 0;
+
+private:
+    const Hash fHash;
+};
+
+#endif
+
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
new file mode 100644
index 0000000..9a2e660
--- /dev/null
+++ b/gpu/include/GrMatrix.h
@@ -0,0 +1,400 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrMatrix_DEFINED
+#define GrMatrix_DEFINED
+
+#include "GrPoint.h"
+
+struct GrRect;
+
+/*
+ * 3x3 matrix
+ */
+class GrMatrix {
+public:
+    static const GrMatrix& I() {
+        static const GrMatrix I = GrMatrix(GR_Scalar1, 0, 0,
+                                           0, GR_Scalar1, 0,
+                                           0, 0, gRESCALE);
+        return I;
+    };
+    static const GrMatrix& InvalidMatrix() {
+        static const GrMatrix INV = 
+            GrMatrix(GR_ScalarMax, GR_ScalarMax, GR_ScalarMax,
+                     GR_ScalarMax, GR_ScalarMax, GR_ScalarMax,
+                     GR_ScalarMax, GR_ScalarMax, GR_ScalarMax);
+        return INV;
+    }
+    /** 
+     * Handy index constants
+     */
+    enum {
+        kScaleX,
+        kSkewX,
+        kTransX,
+        kSkewY,
+        kScaleY,
+        kTransY,
+        kPersp0,
+        kPersp1,
+        kPersp2
+    };
+    
+    /**
+     * Create an uninitialized matrix
+     */
+    GrMatrix() {
+        fTypeMask = 0;
+    }
+    
+    /**
+     * Create a matrix from an array of values
+     * @param values    row-major array of matrix components
+     */
+    explicit GrMatrix(const GrScalar values[]) {
+        setToArray(values);
+    }
+    
+    /**
+     * Create a matrix from values
+     * @param scaleX    (0,0) matrix element
+     * @param skewX     (0,1) matrix element
+     * @param transX    (0,2) matrix element
+     * @param skewY     (1,0) matrix element
+     * @param scaleY    (1,1) matrix element
+     * @param transY    (1,2) matrix element
+     * @param persp0    (2,0) matrix element
+     * @param persp1    (2,1) matrix element
+     * @param persp2    (2,2) matrix element
+     */
+    GrMatrix(GrScalar scaleX,
+             GrScalar skewX,
+             GrScalar transX,
+             GrScalar skewY,
+             GrScalar scaleY,
+             GrScalar transY,
+             GrScalar persp0,
+             GrScalar persp1,
+             GrScalar persp2) {
+        setAll(scaleX, skewX,  transX,
+               skewY,  scaleY, transY,
+               persp0, persp1, persp2);
+    }
+
+    /**
+     * access matrix component
+     * @return matrix component value
+     */
+    const GrScalar& operator[] (int idx) const {
+        GrAssert((unsigned)idx < 9);
+        return fM[idx];
+    }
+
+    /**
+     * Set a matrix from an array of values
+     * @param values    row-major array of matrix components
+     */
+    void setToArray(const GrScalar values[]) {
+        for (int i = 0; i < 9; ++i) {
+            fM[i] = values[i];
+        }
+        this->computeTypeMask();
+    }
+    
+    /**
+     * Create a matrix from values
+     * @param scaleX    (0,0) matrix element
+     * @param skewX     (0,1) matrix element
+     * @param transX    (0,2) matrix element
+     * @param skewY     (1,0) matrix element
+     * @param scaleY    (1,1) matrix element
+     * @param transY    (1,2) matrix element
+     * @param persp0    (2,0) matrix element
+     * @param persp1    (2,1) matrix element
+     * @param persp2    (2,2) matrix element
+     */
+    void setAll(GrScalar scaleX,
+                GrScalar skewX,
+                GrScalar transX,
+                GrScalar skewY,
+                GrScalar scaleY,
+                GrScalar transY,
+                GrScalar persp0,
+                GrScalar persp1,                
+                GrScalar persp2) {
+        fM[kScaleX] = scaleX;
+        fM[kSkewX]  = skewX;
+        fM[kTransX] = transX;
+        fM[kSkewY]  = skewY;
+        fM[kScaleY] = scaleY;
+        fM[kTransY] = transY;
+        fM[kPersp0] = persp0;
+        fM[kPersp1] = persp1;
+        fM[kPersp2] = persp2;
+        
+        this->computeTypeMask();
+    }
+    
+    /**
+     * set matrix component
+     * @param idx    index of component to set
+     * @param value  value to set component to
+     */
+    inline void set(int idx, GrScalar value);
+    
+    /**
+     * make this matrix an identity matrix
+     */
+    void setIdentity();
+
+    /**
+     * overwrite entire matrix to be a translation matrix
+     * @param dx    amount to translate by in x
+     * @param dy    amount to translate by in y
+     */
+    void setTranslate(GrScalar dx, GrScalar dy);
+
+    /**
+     * overwrite entire matrix to be a scaling matrix
+     * @param sx    x scale factor
+     * @param sy    y scale factor
+     */
+    void setScale(GrScalar sx, GrScalar sy);
+
+    /**
+     * overwrite entire matrix to be a skew matrix
+     * @param skx   x skew factor
+     * @param sky   y skew factor
+     */
+    void setSkew(GrScalar skx, GrScalar sky);
+
+    /**
+     * set this matrix to be a concantenation of two
+     * matrices (a*b). Either a, b, or both can be this matrix.
+     * @param a     first matrix to multiply
+     * @param b     second matrix to multiply
+     */
+    void setConcat(const GrMatrix& a, const GrMatrix& b);
+
+    /**
+     * Set this matrix to this*m
+     * @param m     matrix to concatenate
+     */
+    void preConcat(const GrMatrix& m);
+
+    /**
+     * Set this matrix to m*this
+     * @param m     matrix to concatenate
+     */
+    void postConcat(const GrMatrix& m);
+
+    /**
+     *  Compute the inverse of this matrix, and return true if it is invertible,
+     *  or false if not.
+     *
+     *  If inverted is not null, and the matrix is invertible, then the inverse
+     *  is written into it. If the matrix is not invertible (this method returns
+     *  false) then inverted is left unchanged.
+     */
+    bool invert(GrMatrix* inverted) const;
+    
+    /**
+     * Transforms a point by the matrix
+     *
+     * @param src   the point to transform
+     * @return the transformed point
+     */
+    GrPoint mapPoint(const GrPoint& src) const {
+        GrPoint result;
+        (this->*gMapProcs[fTypeMask])(&result, &src, 1);
+        return result;
+    }
+    
+    /**
+     * Transforms an array of points by the matrix.
+     *
+     * @param dstPts the array to write transformed points into
+     * @param srcPts the array of points to transform
+     @ @param count the number of points to transform
+     */
+    void mapPoints(GrPoint dstPts[], 
+                   const GrPoint srcPts[], 
+                   uint32_t count) const {
+        (this->*gMapProcs[fTypeMask])(dstPts, srcPts, count);
+    }
+
+    /**
+     * Transforms pts with arbitrary stride in place.
+     *
+     * @param start  pointer to first point to transform
+     * @param stride distance in bytes between consecutive points
+     @ @param count the number of points to transform
+     */
+    void mapPointsWithStride(GrPoint* start, 
+                             size_t stride, 
+                             uint32_t count) const {
+        for (uint32_t i = 0; i < count; ++i) {            
+            this->mapPoints(start, start, 1);
+            start = (GrPoint*)((intptr_t)start + stride);
+        }
+    }
+    
+    /**
+     *  Transform the 4 corners of the src rect, and return the bounding rect
+     *  in the dst rect. Note: src and dst may point to the same memory.
+     */
+    void mapRect(GrRect* dst, const GrRect& src) const;
+
+    /**
+     *  Transform the 4 corners of the rect, and return their bounds in the rect
+     */
+    void mapRect(GrRect* rect) const {
+        this->mapRect(rect, *rect);
+    }
+
+    /**
+     * Checks if matrix is a perspective matrix.
+     * @return true if third row is not (0, 0, 1)
+     */
+    bool hasPerspective() const;
+    
+    /**
+     * Checks whether matrix is identity
+     * @return true if matrix is idenity
+     */
+    bool isIdentity() const;
+    
+    /**
+     * Calculates the maximum stretching factor of the matrix. Only defined if
+     * the matrix does not have perspective.
+     *
+     * @return maximum strecthing factor or negative if matrix has perspective.
+     */
+    GrScalar getMaxStretch() const;
+
+    /**
+     * Checks for matrix equality. Test is element-by-element equality,
+     * not a homogeneous test.
+     * @return true if matrices are equal, false otherwise
+     */
+    bool operator == (const GrMatrix& m) const;
+
+    /**
+     * Checks for matrix inequality. Test is element-by-element inequality,
+     * not a homogeneous test.
+     * @return true if matrices are not equal, false otherwise
+     */
+    bool operator != (const GrMatrix& m) const;
+    
+    static void UnitTest();
+
+private:
+    static const GrScalar gRESCALE;
+
+    void computeTypeMask() {
+        fTypeMask = 0;
+        if (0 != fM[kPersp0] || 0 != fM[kPersp1] || gRESCALE != fM[kPersp2]) {
+            fTypeMask |= kPerspective_TypeBit;
+        }
+        if (GR_Scalar1 != fM[kScaleX] || GR_Scalar1 != fM[kScaleY]) {
+            fTypeMask |= kScale_TypeBit;
+            if (0 == fM[kScaleX] && 0 == fM[kScaleY]) {
+                fTypeMask |= kZeroScale_TypeBit;
+            }
+        }
+        if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {
+            fTypeMask |= kSkew_TypeBit;
+        }
+        if (0 != fM[kTransX] || 0 != fM[kTransY]) {
+            fTypeMask |= kTranslate_TypeBit;
+        }
+    }
+
+    
+    double determinant() const;
+    
+    enum TypeBits {
+        kScale_TypeBit       = 1 << 0, // set if scales are not both 1
+        kTranslate_TypeBit   = 1 << 1, // set if translates are not both 0
+        kSkew_TypeBit        = 1 << 2, // set if skews are not both 0
+        kPerspective_TypeBit = 1 << 3, // set if perspective
+        kZeroScale_TypeBit   = 1 << 4, // set if scales are both zero
+    };
+
+    void mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    void mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    
+    void mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    
+    typedef void (GrMatrix::*MapProc) (GrPoint* dst, const GrPoint* src, uint32_t count) const;
+    static const MapProc gMapProcs[];
+
+    int      fTypeMask;
+    
+    GrScalar fM[9];
+};
+
+void GrMatrix::set(int idx, GrScalar value) {
+    GrAssert((unsigned)idx < 9);
+    fM[idx] = value;
+    if (idx > 5) {
+        if (0 != fM[kPersp0] || 0 != fM[kPersp1] ||
+            gRESCALE != fM[kPersp2]) {
+            fTypeMask |= kPerspective_TypeBit;
+        } else {
+            fTypeMask &= ~kPerspective_TypeBit;
+        }
+    } else if (!(idx % 4)) {
+        if ((GR_Scalar1 == fM[kScaleX] && GR_Scalar1 == fM[kScaleY])) {
+            fTypeMask &= ~kScale_TypeBit;
+            fTypeMask &= ~kZeroScale_TypeBit;
+        } else {
+            fTypeMask |= kScale_TypeBit;
+            if ((0 == fM[kScaleX] && 0 == fM[kScaleY])) {
+                fTypeMask |= kZeroScale_TypeBit;
+            } else {
+                fTypeMask &= ~kZeroScale_TypeBit;
+            }
+        }
+    } else if (2 == (idx % 3)) {
+        if (0 != fM[kTransX] || 0 != fM[kTransY]) {
+            fTypeMask |= kTranslate_TypeBit;
+        } else {
+            fTypeMask &= ~kTranslate_TypeBit;
+        }
+    } else {
+        if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {
+            fTypeMask |= kSkew_TypeBit;
+        } else {
+            fTypeMask &= ~kSkew_TypeBit;
+        }
+    }
+}
+
+#endif
diff --git a/gpu/include/GrMemory.h b/gpu/include/GrMemory.h
new file mode 100644
index 0000000..be8b1d7
--- /dev/null
+++ b/gpu/include/GrMemory.h
@@ -0,0 +1,181 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrMemory_DEFINED
+#define GrMemory_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAutoMalloc : GrNoncopyable {
+public:
+    GrAutoMalloc() : fPtr(NULL), fAllocatedBytes(0){
+    }
+
+    GrAutoMalloc(size_t bytes) : fPtr(GrMalloc(bytes)), fAllocatedBytes(bytes) {}
+    ~GrAutoMalloc() { GrFree(fPtr); }
+
+    /**
+     *  Return the allocated memory, or NULL if it has already been freed or
+     *  detached.
+     */
+    void* get() const { return fPtr; }
+
+    size_t size() const { return fAllocatedBytes; }
+
+    /**
+     *  transfer ownership of the memory to the caller. It must be freed with
+     *  a call to GrFree()
+     */
+    void* detach() {
+        void* ptr = fPtr;
+        fPtr = NULL;    // we no longer own the block
+        fAllocatedBytes = 0;
+        return ptr;
+    }
+
+    /**
+     *  Reallocates to a new size. May or may not call malloc. The contents
+     *  are not preserved. If growOnly is true it will never reduce the
+     *  allocated size.
+     */
+    void* realloc(size_t newSize, bool growOnly = false) {
+        bool alloc;
+        if (growOnly) {
+            alloc = newSize > fAllocatedBytes;
+        } else {
+            alloc = newSize != fAllocatedBytes;
+        }
+        if (alloc) {
+            GrFree(fPtr);
+            fPtr = newSize ? GrMalloc(newSize) : NULL;
+            fAllocatedBytes = newSize;
+        }
+        GrAssert(fAllocatedBytes >= newSize);
+        GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
+        return fPtr;
+    }
+
+    /**
+     *  free the block now. get() will now return NULL
+     */
+    void free() {
+        GrFree(fPtr);
+        fPtr = NULL;
+        fAllocatedBytes = 0;
+    }
+
+private:
+    void* fPtr;
+    size_t fAllocatedBytes;
+};
+
+/**
+ *  Variant of GrAutoMalloc with a compile-time specified byte size that is
+ *  pre-allocated in the class object, avoiding a call to to GrMalloc if
+ *  possible.
+ */
+template <size_t SIZE> class GrAutoSMalloc : GrNoncopyable {
+public:
+    GrAutoSMalloc() {
+        fPtr = fStorage;
+        fAllocatedBytes = SIZE;
+    }
+
+    explicit GrAutoSMalloc(size_t bytes) {
+        if (bytes > SIZE) {
+            fPtr = GrMalloc(bytes);
+            fAllocatedBytes = bytes;
+        } else {
+            fPtr = fStorage;
+            fAllocatedBytes = SIZE;
+        }
+    }
+
+    ~GrAutoSMalloc() {
+        if (fPtr != (void*)fStorage) {
+            GrFree(fPtr);
+        }
+    }
+
+    /**
+     *  Return the allocated memory, or NULL if it has already been freed or
+     *  detached.
+     */
+    void* get() const { return fPtr; }
+
+    /**
+     *  Reallocates to a new size. May or may not call malloc. The contents
+     *  are not preserved. If growOnly is true it will never reduce the
+     *  allocated size.
+     */
+    void* realloc(size_t newSize, bool growOnly = false) {
+        if (newSize <= SIZE) {
+            if (NULL == fPtr) {
+                fPtr = fStorage;
+                fAllocatedBytes = SIZE;
+            } else if (!growOnly && fPtr != (void*)fStorage) {
+                GrFree(fPtr);
+                fPtr = fStorage;
+                fAllocatedBytes = SIZE;
+            }
+        } else if ((newSize > fAllocatedBytes) ||
+                   (!growOnly && newSize < (fAllocatedBytes >> 1))) {
+            if (NULL != fPtr && fPtr != (void*)fStorage) {
+                GrFree(fPtr);
+            }
+            fPtr = GrMalloc(newSize);
+            fAllocatedBytes = newSize;
+        }
+        GrAssert(fAllocatedBytes >= newSize);
+        GrAssert((fPtr == fStorage) == (fAllocatedBytes == SIZE));
+        GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
+        return fPtr;
+    }
+
+    /**
+     *  free the block now. get() will now return NULL
+     */
+    void free() {
+        if (fPtr != (void*)fStorage) {
+            GrFree(fPtr);
+        }
+        fAllocatedBytes = 0;
+        fPtr = NULL;
+    }
+
+private:
+    void*    fPtr;
+    uint32_t fAllocatedBytes;
+    uint32_t fStorage[GrALIGN4(SIZE) >> 2];
+};
+
+/**
+ *  Variant of GrAutoMalloc with a compile-time specified byte size that is
+ *  pre-allocated in the class object, avoiding a call to to GrMalloc if
+ *  possible.
+ */
+template <int COUNT, typename T>
+class GrAutoSTMalloc : public GrAutoSMalloc<COUNT * sizeof(T)> {
+public:
+    GrAutoSTMalloc(int count) : GrAutoSMalloc<COUNT * sizeof(T)>(count * sizeof(T)) {}
+
+    operator T*() { return (T*)this->get(); }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrMesh.h b/gpu/include/GrMesh.h
new file mode 100644
index 0000000..4d904e4
--- /dev/null
+++ b/gpu/include/GrMesh.h
@@ -0,0 +1,42 @@
+#ifndef GrMesh_DEFINED
+#define GrMesh_DEFINED
+
+#include "SkRect.h"
+#include "SkPoint.h"
+
+class SkCanvas;
+class SkPaint;
+
+class GrMesh {
+public:
+    GrMesh();
+    ~GrMesh();
+
+    GrMesh& operator=(const GrMesh& src);
+
+    void init(const SkRect& bounds, int rows, int cols,
+              const SkRect& texture);
+
+    const SkRect& bounds() const { return fBounds; }
+
+    int rows() const { return fRows; }
+    int cols() const { return fCols; }
+    SkPoint& pt(int row, int col) {
+        return fPts[row * (fRows + 1) + col];
+    }
+
+    void draw(SkCanvas*, const SkPaint&);
+    void drawWireframe(SkCanvas* canvas, const SkPaint& paint);
+
+private:
+    SkRect      fBounds;
+    int         fRows, fCols;
+    SkPoint*    fPts;
+    SkPoint*    fTex;   // just points into fPts, not separately allocated
+    int         fCount;
+    uint16_t*   fIndices;
+    int         fIndexCount;
+};
+
+#endif
+
diff --git a/gpu/include/GrNoncopyable.h b/gpu/include/GrNoncopyable.h
new file mode 100644
index 0000000..888e3b1
--- /dev/null
+++ b/gpu/include/GrNoncopyable.h
@@ -0,0 +1,38 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrNoncopyable_DEFINED
+#define GrNoncopyable_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ *  Base for classes that want to disallow copying themselves. It makes its
+ *  copy-constructor and assignment operators private (and unimplemented).
+ */
+class GrNoncopyable {
+public:
+    GrNoncopyable() {}
+
+private:
+    // illegal
+    GrNoncopyable(const GrNoncopyable&);
+    GrNoncopyable& operator=(const GrNoncopyable&);
+};
+
+#endif
+
diff --git a/gpu/include/GrPaint.h b/gpu/include/GrPaint.h
new file mode 100644
index 0000000..9402209
--- /dev/null
+++ b/gpu/include/GrPaint.h
@@ -0,0 +1,103 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrPaint_DEFINED
+#define GrPaint_DEFINED
+
+#include "GrTexture.h"
+#include "GrColor.h"
+#include "GrSamplerState.h"
+
+/**
+ * The paint describes how pixels are colored when the context draws to
+ * them.
+ */
+class GrPaint {
+public:
+
+    // All the paint fields are public except texture (it's ref-counted)
+    GrBlendCoeff                fSrcBlendCoeff;
+    GrBlendCoeff                fDstBlendCoeff;
+    bool                        fAntiAlias;
+    bool                        fDither;
+
+    GrColor                     fColor;
+
+    GrSamplerState              fSampler;
+
+    void setTexture(GrTexture* texture) {
+        GrSafeRef(texture);
+        GrSafeUnref(fTexture);
+        fTexture = texture;
+    }
+
+    GrTexture* getTexture() const { return fTexture; }
+
+    // uninitialized
+    GrPaint() {
+        fTexture = NULL;
+    }
+
+    GrPaint(const GrPaint& paint) {
+        fSrcBlendCoeff = paint.fSrcBlendCoeff;
+        fDstBlendCoeff = paint.fDstBlendCoeff;
+        fAntiAlias = paint.fAntiAlias;
+        fDither = paint.fDither;
+
+        fColor = paint.fColor;
+
+        fSampler = paint.fSampler;
+        fTexture = paint.fTexture;
+        GrSafeRef(fTexture);
+    }
+
+    ~GrPaint() {
+        GrSafeUnref(fTexture);
+    }
+
+    // sets paint to src-over, solid white, no texture
+    void reset() {
+        resetBlend();
+        resetOptions();
+        resetColor();
+        resetTexture();
+    }
+
+private:
+    GrTexture*      fTexture;
+
+    void resetBlend() {
+        fSrcBlendCoeff = kOne_BlendCoeff;
+        fDstBlendCoeff = kZero_BlendCoeff;
+    }
+
+    void resetOptions() {
+        fAntiAlias = false;
+        fDither = false;
+    }
+
+    void resetColor() {
+        fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+    }
+
+    void resetTexture() {
+        setTexture(NULL);
+        fSampler.setClampNoFilter();
+    }
+
+};
+
+#endif
diff --git a/gpu/include/GrPath.h b/gpu/include/GrPath.h
new file mode 100644
index 0000000..80bbeb3
--- /dev/null
+++ b/gpu/include/GrPath.h
@@ -0,0 +1,103 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPath_DEFINED
+#define GrPath_DEFINED
+
+#include "GrPathSink.h"
+#include "GrPathIter.h"
+#include "GrTDArray.h"
+#include "GrPoint.h"
+
+class GrPath : public GrPathSink {
+public:
+    GrPath();
+    GrPath(const GrPath&);
+    explicit GrPath(GrPathIter&);
+    virtual ~GrPath();
+
+    GrConvexHint getConvexHint() const { return fConvexHint; }
+    void setConvexHint(GrConvexHint hint) { fConvexHint = hint; }
+
+    void resetFromIter(GrPathIter*);
+
+    bool operator ==(const GrPath& path) const;
+    bool operator !=(const GrPath& path) const { return !(*this == path); }
+    // overrides from GrPathSink
+
+    virtual void moveTo(GrScalar x, GrScalar y);
+    virtual void lineTo(GrScalar x, GrScalar y);
+    virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1);
+    virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                         GrScalar x2, GrScalar y2);
+    virtual void close();
+
+    /**
+     *  Offset the path by (tx, ty), adding tx to the horizontal position
+     *  and adds ty to the vertical position of every point.
+     */
+    void offset(GrScalar tx, GrScalar ty);
+
+    class Iter : public GrPathIter {
+    public:
+        /**
+         * Creates an uninitialized iterator
+         */
+        Iter();
+
+        Iter(const GrPath& path);
+
+        // overrides from GrPathIter
+        virtual GrPathCmd next(GrPoint points[]);
+        virtual GrConvexHint convexHint() const;
+        virtual GrPathCmd next();
+        virtual void rewind();
+
+        /**
+         * Sets iterator to begining of path
+         */
+        void reset(const GrPath& path);
+    private:
+        const GrPath* fPath;
+        GrPoint       fLastPt;
+        int           fCmdIndex;
+        int           fPtIndex;
+    };
+
+    static void ConvexUnitTest();
+
+private:
+
+    GrTDArray<GrPathCmd>    fCmds;
+    GrTDArray<GrPoint>      fPts;
+    GrConvexHint  fConvexHint;
+
+    // this ensures we have a moveTo at the start of each contour
+    inline void ensureMoveTo();
+
+    bool wasLastVerb(GrPathCmd cmd) const {
+        int count = fCmds.count();
+        return count > 0 && cmd == fCmds[count - 1];
+    }
+
+    friend class Iter;
+
+    typedef GrPathSink INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrPathIter.h b/gpu/include/GrPathIter.h
new file mode 100644
index 0000000..55427c0
--- /dev/null
+++ b/gpu/include/GrPathIter.h
@@ -0,0 +1,70 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPathIter_DEFINED
+#define GrPathIter_DEFINED
+
+#include "GrTypes.h"
+
+struct GrPoint;
+
+/**
+ 2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to
+ parse the top-level API's 2D paths. Supports lines, quadratics, and cubic
+ pieces and moves (multi-part paths).
+ */
+class GrPathIter {
+public:
+
+    virtual ~GrPathIter() {};
+
+    /**
+     * Iterates through the path. Should not be called after
+     * kEnd_Command has been returned once. This version retrieves the
+     * points for the command.
+     * @param points  The points relevant to returned commend. See Command
+     *               enum for number of points valid for each command.
+     * @return The next command of the path.
+     */
+    virtual GrPathCmd next(GrPoint points[4]) = 0;
+
+    /**
+     * If the host API has knowledge of the convexity of the path
+     * it can be communicated by this hint. Gr can analyze the path
+     * as it is iterated. So it is not necessary to do additional work to
+     * compute convexity status if it isn't already determined.
+     *
+     * @return a hint about the convexity of the path.
+     */
+    virtual GrConvexHint convexHint() const = 0;
+
+     /**
+      * Iterates through the path. Should not be called after
+      * kEnd_Command has been returned once. This version does not retrieve the
+      * points for the command.
+      * @return The next command of the path.
+      */
+     virtual GrPathCmd next() = 0;
+
+    /**
+     Restarts iteration from the beginning.
+     */
+    virtual void rewind() = 0;
+
+};
+
+#endif
diff --git a/gpu/include/GrPathSink.h b/gpu/include/GrPathSink.h
new file mode 100644
index 0000000..4e8a0c2
--- /dev/null
+++ b/gpu/include/GrPathSink.h
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPathSink_DEFINED
+#define GrPathSink_DEFINED
+
+#include "GrScalar.h"
+
+class GrPathSink {
+public:
+    virtual ~GrPathSink() {}
+
+    virtual void moveTo(GrScalar x, GrScalar y) = 0;
+    virtual void lineTo(GrScalar x, GrScalar y) = 0;
+    virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) = 0;
+    virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                         GrScalar x2, GrScalar y2) = 0;
+    virtual void close() = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrPlotMgr.h b/gpu/include/GrPlotMgr.h
new file mode 100644
index 0000000..cd60bde
--- /dev/null
+++ b/gpu/include/GrPlotMgr.h
@@ -0,0 +1,84 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPlotMgr_DEFINED
+#define GrPlotMgr_DEFINED
+
+#include "GrTypes.h"
+#include "GrPoint.h"
+
+class GrPlotMgr : GrNoncopyable {
+public:
+    GrPlotMgr(int width, int height) {
+        fDim.set(width, height);
+        size_t needed = width * height;
+        if (needed <= sizeof(fStorage)) {
+            fBusy = fStorage;
+        } else {
+            fBusy = new char[needed];
+        }
+        this->reset();
+    }
+
+    ~GrPlotMgr() {
+        if (fBusy != fStorage) {
+            delete[] fBusy;
+        }
+    }
+    
+    void reset() {
+        Gr_bzero(fBusy, fDim.fX * fDim.fY);
+    }
+
+    bool newPlot(GrIPoint16* loc) {
+        char* busy = fBusy;
+        for (int y = 0; y < fDim.fY; y++) {
+            for (int x = 0; x < fDim.fX; x++) {
+                if (!*busy) {
+                    *busy = true;
+                    loc->set(x, y);
+                    return true;
+                }
+                busy++;
+            }
+        }
+        return false;
+    }
+
+    bool isBusy(int x, int y) const {
+        GrAssert((unsigned)x < (unsigned)fDim.fX);
+        GrAssert((unsigned)y < (unsigned)fDim.fY);
+        return fBusy[y * fDim.fX + x] != 0;
+    }
+
+    void freePlot(int x, int y) {
+        GrAssert((unsigned)x < (unsigned)fDim.fX);
+        GrAssert((unsigned)y < (unsigned)fDim.fY);
+        fBusy[y * fDim.fX + x] = false;
+    }
+
+private:
+    enum {
+        STORAGE = 64
+    };
+    char fStorage[STORAGE];
+    char* fBusy;
+    GrIPoint16  fDim;
+};
+
+#endif
+
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
new file mode 100644
index 0000000..c07543b
--- /dev/null
+++ b/gpu/include/GrPoint.h
@@ -0,0 +1,334 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPoint_DEFINED
+#define GrPoint_DEFINED
+
+#include "GrTypes.h"
+#include "GrScalar.h"
+
+/**
+ *  2D Point struct
+ */
+struct GrPoint {
+public:
+    GrScalar fX, fY;
+
+    GrPoint() {}
+    GrPoint(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    void setAsMidPoint(const GrPoint& a, const GrPoint& b) {
+        fX = GrScalarAve(a.fX, b.fX);
+        fY = GrScalarAve(a.fY, b.fY);
+    }
+
+    void offset(GrScalar dx, GrScalar dy) {
+        fX += dx;
+        fY += dy;
+    }
+
+    GrScalar distanceToSqd(const GrPoint& p) const {
+        GrScalar dx = (p.fX - fX);
+        GrScalar dy = (p.fY - fY);
+        return GrMul(dx, dx) + GrMul(dy, dy);
+    }
+    
+    GrScalar distanceTo(const GrPoint& p) const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToSqd(p))));
+    }
+    
+    GrScalar distanceToOriginSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+
+    GrScalar distanceToOrigin() const {
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToOriginSqd())));
+    }
+    
+    inline GrScalar distanceToLineBetweenSqd(const GrPoint& a, 
+                                             const GrPoint& b) const;
+
+    inline GrScalar distanceToLineBetween(const GrPoint& a, 
+                                          const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                    const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetween(const GrPoint& a, 
+                                                 const GrPoint& b) const;
+    
+    // counter-clockwise fan
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b) {
+        GrPoint* v = this;
+        v[0].set(l, t);
+        v[1].set(l, b);
+        v[2].set(r, b);
+        v[3].set(r, t);
+    }
+    
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+    }
+    
+    // counter-clockwise fan
+    void setIRectFan(int l, int t, int r, int b) {
+        GrPoint* v = this;
+        v[0].set(GrIntToScalar(l), GrIntToScalar(t));
+        v[1].set(GrIntToScalar(l), GrIntToScalar(b));
+        v[2].set(GrIntToScalar(r), GrIntToScalar(b));
+        v[3].set(GrIntToScalar(r), GrIntToScalar(t));
+    }
+    
+    void setIRectFan(int l, int t, int r, int b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(t));
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(t));
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+struct GrIPoint16 {
+    int16_t fX, fY;
+    
+    void set(intptr_t x, intptr_t y) {
+        fX = GrToS16(x);
+        fY = GrToS16(y);
+    }
+};
+
+struct GrVec {
+public:
+    GrScalar fX, fY;
+    
+    GrVec() {}
+    GrVec(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+    
+    /**
+     * set x and y length of the vector.
+     */
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    /**
+     * set vector to point from a to b.
+     */
+    void setBetween(const GrPoint& a, const GrPoint& b) {
+        fX = b.fX - a.fX;
+        fY = b.fY - a.fY;
+    }
+    
+    /**
+     * Make this vector be orthogonal to vec. Looking down vec the
+     * new vector will point left.
+     */
+    void setOrthogLeft(const GrVec& vec) {
+        // vec could be this
+        GrVec v = vec;
+        fX = -v.fY;
+        fY = v.fX;
+    }
+
+    /**
+     * Make this vector be orthogonal to vec. Looking down vec the
+     * new vector will point right.
+     */
+    void setOrthogRight(const GrVec& vec) {
+        // vec could be this
+        GrVec v = vec;
+        fX = v.fY;
+        fY = -v.fX;
+    }
+
+    /**
+     * set orthogonal to vec from a to b. Will be facing left relative to a,b
+     * vec
+     */
+    void setOrthogLeftToVecBetween(const GrPoint& a, const GrPoint& b) {
+        fX = a.fY - b.fY;
+        fY = b.fX - a.fX;
+    }
+
+    /**
+     * set orthogonal to vec from a to b. Will be facing right relative to a,b
+     * vec.
+     */
+    void setOrthogRightToVecBetween(const GrPoint& a, const GrPoint& b) {
+        fX = b.fY - a.fY;
+        fY = a.fX - b.fX;
+    }
+
+    /**
+     * length of the vector squared.
+     */
+    GrScalar lengthSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+    
+    /**
+     * length of the vector.
+     */
+    GrScalar length() const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(lengthSqd())));
+    }
+    
+    /**
+     * normalizes the vector if it's length is not 0.
+     * @return true if normalized, otherwise false.
+     */
+    bool normalize() {
+        GrScalar l = lengthSqd();
+        if (l) {
+            // TODO: fixed point sqrt and invert
+            l = 1 / sqrtf(l);
+            fX *= l;
+            fY *= l;
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Dot product of this with vec.
+     */
+    GrScalar dot(const GrVec& vec) const {
+        return GrMul(vec.fX, fX) + GrMul(vec.fY, fY);
+    }
+   
+    /**
+     * Dot product of this vec with vector from (0,0) to a pt.
+     */
+    GrScalar dotWithVecToPt(const GrPoint& pt) const {
+        return GrMul(pt.fX, fX) + GrMul(pt.fY, fY);
+    }
+
+    /**
+     * z-value of this cross vec.
+     */
+    GrScalar cross(const GrVec& vec) const {
+        return GrMul(fX, vec.fY) - GrMul(fY, vec.fX);
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+GrScalar GrPoint::distanceToLineBetweenSqd(const GrPoint& a, 
+                                           const GrPoint& b) const {
+    // Let d be the distance between c (this) and line ab.
+    // The area of the triangle defined by a, b, and c is 
+    // A = |b-a|*d/2. Let u = b-a and v = c-a. The cross product of
+    // u and v is aligned with the z axis and its magnitude is 2A. 
+    // So d = |u x v| / |u|.
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrMul(det, det)) / u.lengthSqd();
+}
+
+GrScalar GrPoint::distanceToLineBetween(const GrPoint& a, 
+                                        const GrPoint& b) const {
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrScalarAbs(det)) / u.length();
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                  const GrPoint& b) const {
+    // See comments to distanceToLineBetweenSqd. If the projection of c onto
+    // u is between a and b then this returns the same result as that 
+    // function. Otherwise, it returns the distance to the closer of a and
+    // b. Let the projection of v onto u be v'.  There are three cases:
+    //    1. v' points opposite to u. c is not between a and b and is closer
+    //       to a than b.
+    //    2. v' points along u and has magnitude less than y. c is between
+    //       a and b and the distance to the segment is the same as distance
+    //       to the line ab.
+    //    3. v' points along u and has greater magnitude than u. c is not
+    //       not between a and b and is closer to b than a.
+    // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're 
+    // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
+    // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to 
+    // avoid a sqrt to compute |u|.
+    
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar uLengthSqd = u.lengthSqd();
+    GrScalar uDotV = u.dot(v);
+    
+    if (uDotV <= 0) {
+        return v.lengthSqd();
+    } else if (uDotV > uLengthSqd) {
+        return b.distanceToSqd(*this);
+    } else {
+        GrScalar det = u.cross(v);
+        return (GrMul(det, det)) / uLengthSqd;
+    }
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetween(const GrPoint& a, 
+                                               const GrPoint& b) const {
+    // TODO: fixed point sqrt
+    return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToLineSegmentBetweenSqd(a,b))));
+}
+
+
+#endif
+
diff --git a/gpu/include/GrRandom.h b/gpu/include/GrRandom.h
new file mode 100644
index 0000000..408f61d
--- /dev/null
+++ b/gpu/include/GrRandom.h
@@ -0,0 +1,62 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRandom_DEFINED
+#define GrRandom_DEFINED
+
+class GrRandom {
+public:
+    GrRandom() : fSeed(0) {}
+    GrRandom(uint32_t seed) : fSeed(seed) {}
+
+    uint32_t seed() const { return fSeed; }
+
+    uint32_t nextU() {
+        fSeed = fSeed * kMUL + kADD;
+        return fSeed;
+    }
+
+    int32_t nextS() { return (int32_t)this->nextU(); }
+
+    /**
+     *  Returns value [0...1) as a float
+     */
+    float nextF() {
+        // const is 1 / (2^32 - 1)
+        return (float)(this->nextU() * 2.32830644e-10);
+    }
+
+    /**
+     *  Returns value [min...max) as a float
+     */
+    float nextF(float min, float max) {
+        return min + this->nextF() * (max - min);
+    }
+
+private:
+    /*
+     *  These constants taken from "Numerical Recipes in C", reprinted 1999
+     */
+    enum {
+        kMUL = 1664525,
+        kADD = 1013904223
+    };
+    uint32_t    fSeed;
+};
+
+#endif
+
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
new file mode 100644
index 0000000..552fa5e
--- /dev/null
+++ b/gpu/include/GrRect.h
@@ -0,0 +1,366 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRect_DEFINED
+#define GrRect_DEFINED
+
+#include "GrPoint.h"
+
+struct GrIRect {
+    int32_t fLeft, fTop, fRight, fBottom;
+
+    GrIRect() {}
+    GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
+    int32_t x() const { return fLeft; }
+    int32_t y() const { return fTop; }
+    int32_t width() const { return fRight - fLeft; }
+    int32_t height() const { return fBottom - fTop; }
+
+    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+    bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
+
+    void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
+
+    void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + w;
+        fBottom = y + h;
+    }
+
+    void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
+        fLeft = l;
+        fTop = t;
+        fRight = r;
+        fBottom = b;
+    }
+
+    /**
+     *  Make the largest representable rectangle
+     */
+    void setLargest() {
+        fLeft = fTop = GR_Int32Min;
+        fRight = fBottom = GR_Int32Max;
+    }
+
+    bool quickReject(int l, int t, int r, int b) const {
+        return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
+    }
+
+    void unionWith(const GrIRect& r) {
+        if (fLeft > r.fLeft) fLeft = r.fLeft;
+        if (fTop > r.fTop) fTop = r.fTop;
+        if (fRight < r.fRight) fRight = r.fRight;
+        if (fBottom < r.fBottom) fBottom = r.fBottom;
+    }
+
+    /**
+     * Sets this rect to the intersection with a clip rect. If there is no
+     * intersection then this rect will be made empty.
+     */
+    void intersectWith(const GrIRect& clipRect) {
+        if (fRight < clipRect.fLeft ||
+            fLeft > clipRect.fRight ||
+            fBottom < clipRect.fTop ||
+            fTop > clipRect.fBottom) {
+            this->setEmpty();
+        } else {
+            fLeft = GrMax(fLeft, clipRect.fLeft);
+            fRight = GrMin(fRight, clipRect.fRight);
+            fTop = GrMax(fTop, clipRect.fTop);
+            fBottom = GrMin(fBottom, clipRect.fBottom);
+        }
+    }
+
+    friend bool operator==(const GrIRect& a, const GrIRect& b) {
+        return 0 == memcmp(&a, &b, sizeof(a));
+    }
+
+    friend bool operator!=(const GrIRect& a, const GrIRect& b) {
+        return 0 != memcmp(&a, &b, sizeof(a));
+    }
+
+    bool equalsLTRB(int l, int t, int r, int b) const {
+        return fLeft == l && fTop == t &&
+               fRight == r && fBottom == b;
+    }
+    bool equalsXYWH(int x, int y, int w, int h) const {
+        return fLeft == x && fTop == y &&
+               this->width() == w && this->height() == h;
+    }
+
+    bool contains(const GrIRect& r) const {
+        return fLeft   <= r.fLeft &&
+               fRight  >= r.fRight &&
+               fTop    <= r.fTop &&
+               fBottom >= r.fBottom;
+    }
+};
+
+struct GrIRect16 {
+    int16_t fLeft, fTop, fRight, fBottom;
+
+    int width() const { return fRight - fLeft; }
+    int height() const { return fBottom - fTop; }
+    int area() const { return this->width() * this->height(); }
+    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+    void set(const GrIRect& r) {
+        fLeft   = GrToS16(r.fLeft);
+        fTop    = GrToS16(r.fTop);
+        fRight  = GrToS16(r.fRight);
+        fBottom = GrToS16(r.fBottom);
+    }
+};
+
+/**
+ *  2D Rect struct
+ */
+struct GrRect {
+    GrScalar fLeft, fTop, fRight, fBottom;
+
+    /**
+     *  Uninitialized rectangle.
+     */
+    GrRect() {}
+
+    /**
+     *  Initialize a rectangle to a point.
+     *  @param pt the point used to initialize the rectanglee.
+     */
+    explicit GrRect(const GrPoint& pt) {
+        setToPoint(pt);
+    }
+
+    GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
+    explicit GrRect(const GrIRect& src) {
+        fLeft = GrIntToScalar(src.fLeft);
+        fTop = GrIntToScalar(src.fTop);
+        fRight = GrIntToScalar(src.fRight);
+        fBottom = GrIntToScalar(src.fBottom);
+    }
+
+    GrScalar x() const { return fLeft; }
+    GrScalar y() const { return fTop; }
+    GrScalar width() const { return fRight - fLeft; }
+    GrScalar height() const { return fBottom - fTop; }
+
+    GrScalar left() const { return fLeft; }
+    GrScalar top() const { return fTop; }
+    GrScalar right() const { return fRight; }
+    GrScalar bottom() const { return fBottom; }
+
+    GrScalar diagonalLengthSqd() const {
+        GrScalar w = width();
+        GrScalar h = height();
+        return GrMul(w, w) + GrMul(h, h);
+    }
+
+    GrScalar diagonalLength() const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
+    }
+
+    /**
+     *  Returns true if the width or height is <= 0
+     */
+    bool isEmpty() const {
+        return fLeft >= fRight || fTop >= fBottom;
+    }
+
+    void setEmpty() {
+        fLeft = fTop = fRight = fBottom = 0;
+    }
+
+    /**
+     *  returns true if the rectangle is inverted either in x or y
+     */
+    bool isInverted() const {
+        return (fLeft > fRight) || (fTop > fBottom);
+    }
+
+    /**
+     * Does this rect contain a point.
+     */
+    bool contains(const GrPoint& point) const {
+        return point.fX >= fLeft && point.fX < fRight &&
+               point.fY >= fTop && point.fY < fBottom;
+    }
+
+    /**
+     * Does this rect fully contain another rect.
+     */
+    bool contains(const GrRect& r) const {
+        return fLeft   <= r.fLeft &&
+               fRight  >= r.fRight &&
+               fTop    <= r.fTop &&
+               fBottom >= r.fBottom;
+    }
+
+    /**
+     *  Offset the rectangle by (tx, ty), adding tx to the horizontal position
+     *  and adds ty to the vertical position.
+     */
+    void offset(GrScalar tx, GrScalar ty) {
+        fLeft  += tx;   fTop    += ty;
+        fRight += tx;   fBottom += ty;
+    }
+
+    /**
+     *  Initialize a rectangle to a point.
+     *  @param pt the point used to initialize the rectangle.
+     */
+    void setToPoint(const GrPoint& pt) {
+        fLeft = pt.fX;
+        fTop = pt.fY;
+        fRight = pt.fX;
+        fBottom = pt.fY;
+    }
+
+    void set(const GrIRect& r) {
+        fLeft = GrIntToScalar(r.fLeft);
+        fTop = GrIntToScalar(r.fTop);
+        fRight = GrIntToScalar(r.fRight);
+        fBottom = GrIntToScalar(r.fBottom);
+    }
+
+    void roundOut(GrIRect* r) const {
+        r->setLTRB(GrScalarFloorToInt(fLeft),
+                   GrScalarFloorToInt(fTop),
+                   GrScalarCeilToInt(fRight),
+                   GrScalarCeilToInt(fBottom));
+    }
+
+    /**
+     *  Set the rect to the union of the array of points. If the array is empty
+     *  the rect will be empty [0,0,0,0]
+     */
+    void setBounds(const GrPoint pts[], int count);
+
+    /**
+     *  Make the largest representable rectangle
+     *  Set the rect to fLeft = fTop = GR_ScalarMin and
+     *  fRight = fBottom = GR_ScalarMax.
+     */
+    void setLargest() {
+        fLeft = fTop = GR_ScalarMin;
+        fRight = fBottom = GR_ScalarMax;
+    }
+
+    /**
+     Set the rect to fLeft = fTop = GR_ScalarMax and
+     fRight = fBottom = GR_ScalarMin.
+     Useful for initializing a bounding rectangle.
+     */
+    void setLargestInverted() {
+        fLeft = fTop = GR_ScalarMax;
+        fRight = fBottom = GR_ScalarMin;
+    }
+
+    void setLTRB(GrScalar left,
+                 GrScalar top,
+                 GrScalar right,
+                 GrScalar bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
+    void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + width;
+        fBottom = y + height;
+    }
+
+    /**
+     Expand the edges of the rectangle to include a point.
+     Useful for constructing a bounding rectangle.
+     @param pt  the point used to grow the rectangle.
+     */
+    void growToInclude(const GrPoint& pt) {
+        fLeft  = GrMin(pt.fX, fLeft);
+        fRight = GrMax(pt.fX, fRight);
+
+        fTop    = GrMin(pt.fY, fTop);
+        fBottom = GrMax(pt.fY, fBottom);
+    }
+
+    /**
+     * Grows a rect to include another rect.
+     * @param rect the rect to include
+     */
+    void growToInclude(const GrRect& rect) {
+        GrAssert(!rect.isEmpty());
+        fLeft  = GrMin(rect.fLeft, fLeft);
+        fRight = GrMax(rect.fRight, fRight);
+
+        fTop    = GrMin(rect.fTop, fTop);
+        fBottom = GrMax(rect.fBottom, fBottom);
+    }
+
+    /**
+     * Sets this rect to the intersection with a clip rect. If there is no
+     * intersection then this rect will be made empty.
+     */
+    void intersectWith(const GrRect& clipRect) {
+        if (fRight < clipRect.fLeft ||
+            fLeft > clipRect.fRight ||
+            fBottom < clipRect.fTop ||
+            fTop > clipRect.fBottom) {
+            this->setEmpty();
+        } else {
+            fLeft = GrMax(fLeft, clipRect.fLeft);
+            fRight = GrMin(fRight, clipRect.fRight);
+            fTop = GrMax(fTop, clipRect.fTop);
+            fBottom = GrMin(fBottom, clipRect.fBottom);
+        }
+    }
+
+    /**
+     *  Assigns 4 sequential points in order to construct a counter-clockwise
+     *  triangle fan, given the corners of this rect. Returns the address of
+     *  the next point, treating pts as an array.
+     */
+    GrPoint* setRectFan(GrPoint pts[4]) const {
+        pts->setRectFan(fLeft, fTop, fRight, fBottom);
+        return pts + 4;
+    }
+
+    bool operator ==(const GrRect& r) const {
+        return fLeft == r.fLeft     &&
+               fTop == r.fTop       &&
+               fRight == r.fRight   &&
+               fBottom == r.fBottom;
+    }
+};
+
+#endif
+
diff --git a/gpu/include/GrRectanizer.h b/gpu/include/GrRectanizer.h
new file mode 100644
index 0000000..50bb8fe
--- /dev/null
+++ b/gpu/include/GrRectanizer.h
@@ -0,0 +1,64 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRectanizer_DEFINED
+#define GrRectanizer_DEFINED
+
+#include "GrRect.h"
+#include "GrTDArray.h"
+
+class GrRectanizerPurgeListener {
+public:
+    virtual ~GrRectanizerPurgeListener() {}
+
+    virtual void notifyPurgeStrip(void*, int yCoord) = 0;
+};
+
+class GrRectanizer {
+public:
+    GrRectanizer(int width, int height) : fWidth(width), fHeight(height) {
+        GrAssert(width >= 0);
+        GrAssert(height >= 0);
+    }
+
+    virtual ~GrRectanizer() {}
+
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+
+    virtual bool addRect(int width, int height, GrIPoint16* loc) = 0;
+    virtual float percentFull() const = 0;
+
+    // return the Y-coordinate of a strip that should be purged, given height
+    // i.e. return the oldest such strip, or some other criteria. Return -1
+    // if there is no candidate
+    virtual int stripToPurge(int height) const = 0;
+    virtual void purgeStripAtY(int yCoord) = 0;
+
+    /**
+     *  Our factory, which returns the subclass du jour
+     */
+    static GrRectanizer* Factory(int width, int height);
+
+private:
+    int fWidth;
+    int fHeight;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrRefCnt.h b/gpu/include/GrRefCnt.h
new file mode 100644
index 0000000..7204aff
--- /dev/null
+++ b/gpu/include/GrRefCnt.h
@@ -0,0 +1,125 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRefCnt_DEFINED
+#define GrRefCnt_DEFINED
+
+#include "GrTypes.h"
+#include "GrNoncopyable.h"
+
+/**
+ *  Base class for reference counting. When an object is first instantiated,
+ *  its reference count is 1. If the object may be null, use GrSafeRef() and
+ *  GrSafeUnref().
+ *
+ *  It is an error (though only checked for in the debug build) to call unref()
+ *  such that the reference count becomes 0.
+ */
+class GrRefCnt : GrNoncopyable {
+public:
+            GrRefCnt() : fRefCnt(1) {}
+    virtual ~GrRefCnt() {
+        GrAssert(1 == fRefCnt);
+#if GR_DEBUG
+        fRefCnt = 0;    // force validate() to trigger if called afterwards
+#endif
+    }
+
+    int32_t refcnt() const { return fRefCnt; }
+
+    void ref() const {
+        GrAssert(fRefCnt > 0);
+        ++fRefCnt;
+    }
+
+    void unref() const {
+        GrAssert(fRefCnt > 0);
+        if (1 == fRefCnt) {
+            delete this;
+        } else {
+            --fRefCnt;
+        }
+    }
+
+#if GR_DEBUG
+    void validate() const {
+        GrAssert(fRefCnt > 0);
+    }
+#else
+    void validate() const {}
+#endif
+
+private:
+    mutable int32_t fRefCnt;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ *  but otherwise it calls ref().
+ */
+static inline void GrSafeRef(const GrRefCnt* obj) {
+    if (obj) {
+        obj->ref();
+    }
+}
+
+/**
+ *  Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ *  but otherwise it calls unref().
+ */
+static inline void GrSafeUnref(const GrRefCnt* obj) {
+    if (obj) {
+        obj->unref();
+    }
+}
+
+/**
+ *  Assigns src to dst, checking for NULLs in each, and correctly incrementing
+ *  the reference count of src, and decrementing the reference count of dst
+ */
+static inline void GrSafeAssign(GrRefCnt*& dst, GrRefCnt* src) {
+    if (src) {
+        src->ref();
+    }
+    if (dst) {
+        dst->unref();
+    }
+    dst = src;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrAutoRef : GrNoncopyable {
+public:
+    GrAutoRef(GrRefCnt* obj) : fObj(obj) { GrSafeRef(obj); }
+    ~GrAutoRef() { GrSafeUnref(fObj); }
+private:
+    GrRefCnt* fObj;
+};
+
+class GrAutoUnref : GrNoncopyable {
+public:
+    GrAutoUnref(GrRefCnt* obj) : fObj(obj) {}
+    ~GrAutoUnref() { GrSafeUnref(fObj); }
+private:
+    GrRefCnt* fObj;
+};
+
+#endif
+
diff --git a/gpu/include/GrSamplerState.h b/gpu/include/GrSamplerState.h
new file mode 100644
index 0000000..910bc74
--- /dev/null
+++ b/gpu/include/GrSamplerState.h
@@ -0,0 +1,191 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrSamplerState_DEFINED
+#define GrSamplerState_DEFINED
+
+#include "GrTypes.h"
+#include "GrMatrix.h"
+
+class GrSamplerState {
+public:
+    /**
+     * The intepretation of the texture matrix depends on the sample mode. The
+     * texture matrix is applied both when the texture coordinates are explicit
+     * and  when vertex positions are used as texture  coordinates. In the latter
+     * case the texture matrix is applied to the pre-view-matrix position 
+     * values.
+     *
+     * kNormal_SampleMode
+     *  The post-matrix texture coordinates are in normalize space with (0,0) at
+     *  the top-left and (1,1) at the bottom right.
+     * kRadial_SampleMode
+     *  The matrix specifies the radial gradient parameters.
+     *  (0,0) in the post-matrix space is center of the radial gradient.
+     * kRadial2_SampleMode
+     *   Matrix transforms to space where first circle is centered at the
+     *   origin. The second circle will be centered (x, 0) where x may be 
+     *   0 and is provided by setRadial2Params. The post-matrix space is 
+     *   normalized such that 1 is the second radius - first radius.
+     * kSweepSampleMode
+     *  The angle from the origin of texture coordinates in post-matrix space
+     *  determines the gradient value.
+     */
+    enum SampleMode {
+        kNormal_SampleMode,     //!< sample color directly
+        kRadial_SampleMode,     //!< treat as radial gradient
+        kRadial2_SampleMode,    //!< treat as 2-point radial gradient
+        kSweep_SampleMode,      //!< treat as sweep gradient
+    };
+
+    /**
+     * Describes how a texture is sampled when coordinates are outside the
+     * texture border
+     */
+    enum WrapMode {
+        kClamp_WrapMode,
+        kRepeat_WrapMode,
+        kMirror_WrapMode
+    };
+
+    /**
+     * Default sampler state is set to clamp, use normal sampling mode, be
+     * unfiltered, and use identity matrix.
+     */
+    GrSamplerState() {
+        this->setClampNoFilter();
+    }
+
+    explicit GrSamplerState(bool filter) {
+        fWrapX = kClamp_WrapMode;
+        fWrapY = kClamp_WrapMode;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = filter;
+        fMatrix.setIdentity();
+    }
+
+    GrSamplerState(WrapMode wx, WrapMode wy, bool filter) {
+        fWrapX = wx;
+        fWrapY = wy;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = filter;
+        fMatrix.setIdentity();
+    }
+
+    GrSamplerState(WrapMode wx, WrapMode wy, const GrMatrix& matrix, bool filter) {
+        fWrapX = wx;
+        fWrapY = wy;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = filter;
+        fMatrix = matrix;
+    }
+
+    GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, const GrMatrix& matrix, bool filter) {
+        fWrapX = wx;
+        fWrapY = wy;
+        fSampleMode = sample;
+        fMatrix = matrix;
+        fFilter = filter;
+    }
+
+    WrapMode getWrapX() const { return fWrapX; }
+    WrapMode getWrapY() const { return fWrapY; }
+    SampleMode getSampleMode() const { return fSampleMode; }
+    const GrMatrix& getMatrix() const { return fMatrix; }
+    bool isFilter() const { return fFilter; }
+
+    bool isGradient() const {
+        return  kRadial_SampleMode == fSampleMode ||
+                kRadial2_SampleMode == fSampleMode ||
+                kSweep_SampleMode == fSampleMode;
+    }
+
+    void setWrapX(WrapMode mode) { fWrapX = mode; }
+    void setWrapY(WrapMode mode) { fWrapY = mode; }
+    void setSampleMode(SampleMode mode) { fSampleMode = mode; }
+    
+    /**
+     * Sets the sampler's matrix. See SampleMode for explanation of
+     * relationship between the matrix and sample mode.
+     * @param matrix the matrix to set
+     */
+    void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; }
+    
+    /**
+     *  Multiplies the current sampler matrix  a matrix
+     *
+     *  After this call M' = M*m where M is the old matrix, m is the parameter
+     *  to this function, and M' is the new matrix. (We consider points to
+     *  be column vectors so tex cood vector t is transformed by matrix X as 
+     *  t' = X*t.)
+     *
+     *  @param matrix   the matrix used to modify the matrix.
+     */
+    void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
+
+    /**
+     * Enables or disables filtering.
+     * @param filter    indicates whether filtering is applied.
+     */
+    void setFilter(bool filter) { fFilter = filter; }
+
+    void setClampNoFilter() {
+        fWrapX = kClamp_WrapMode;
+        fWrapY = kClamp_WrapMode;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = false;
+        fMatrix.setIdentity();
+    }
+
+    GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
+    GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
+    bool     isRadial2PosRoot() const { return fRadial2PosRoot; }
+
+    /**
+     * Sets the parameters for kRadial2_SampleMode. The texture
+     * matrix must be set so that the first point is at (0,0) and the second
+     * point lies on the x-axis. The second radius minus the first is 1 unit.
+     * The additional parameters to define the gradient are specified by this
+     * function.
+     */
+    void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
+        fRadial2CenterX1 = centerX1;
+        fRadial2Radius0 = radius0;
+        fRadial2PosRoot = posRoot;
+    }
+
+    static const GrSamplerState& ClampNoFilter() {
+        return gClampNoFilter;
+    }
+
+private:
+    WrapMode    fWrapX;
+    WrapMode    fWrapY;
+    SampleMode  fSampleMode;
+    bool        fFilter;
+    GrMatrix    fMatrix;
+
+    // these are undefined unless fSampleMode == kRadial2_SampleMode
+    GrScalar    fRadial2CenterX1;
+    GrScalar    fRadial2Radius0;
+    bool        fRadial2PosRoot;
+
+    static const GrSamplerState gClampNoFilter;
+};
+
+#endif
+
diff --git a/gpu/include/GrScalar.h b/gpu/include/GrScalar.h
new file mode 100644
index 0000000..1353fb2
--- /dev/null
+++ b/gpu/include/GrScalar.h
@@ -0,0 +1,116 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrScalar_DEFINED
+#define GrScalar_DEFINED
+
+#include "GrTypes.h"
+
+#include <float.h>
+#include <math.h>
+
+#define GR_Int32Max            (0x7fffffff)
+#define GR_Int32Min            (0x80000000)
+
+/**
+ *  Convert an int to fixed point 
+ */
+#if GR_DEBUG
+    inline GrFixed GrIntToFixed(int i) {
+        GrAssert(((i & 0xffff0000) == 0xffff0000) || ((i & 0xffff0000) == 0x0));
+        return i << 16;
+    }
+#else
+    #define GrIntToFixed(i) (GrFixed)((i) << 16)
+#endif
+
+#define GR_Fixed1              (1 << 16)
+#define GR_FixedHalf           (1 << 15)
+#define GR_FixedMax            GR_Int32Max
+#define GR_FixedMin            GR_Int32Min
+
+#define GrFixedFloorToFixed(x)  ((x) & ~0xFFFF)
+#define GrFixedFloorToInt(x)    ((x) >> 16)
+
+/**
+ *  Convert fixed point to floating point
+ */
+#define GrFixedToFloat(x)      ((x) * 0.0000152587890625f)
+
+/**
+ *  Convert floating point to fixed point
+ */
+#define GrFloatToFixed(x)      ((GrFixed)((x) * GR_Fixed1))
+
+inline GrFixed GrFixedAbs(GrFixed x) {
+    int32_t s = (x & 0x80000000) >> 31;
+    return (GrFixed)(((int32_t)x ^ s) - s);  
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_SCALAR_IS_FIXED
+    typedef GrFixed                 GrScalar;
+    #define GrIntToScalar(x)        GrIntToFixed(x)
+    #define GrFixedToScalar(x)      (x)
+    #define GrScalarToFloat(x)      GrFixedToFloat(x)
+    #define GrFloatToScalar(x)      GrFloatToFixed(x)
+    #define GrScalarHalf(x)         ((x) >> 1)
+    #define GrScalarAve(x,y)        (((x)+(y)) >> 1)
+    #define GrScalarAbs(x)          GrFixedAbs(x)
+    #define GR_Scalar1              GR_Fixed1
+    #define GR_ScalarHalf           GR_FixedHalf
+    #define GR_ScalarMax            GR_FixedMax
+    #define GR_ScalarMin            GR_FixedMin
+#elif GR_SCALAR_IS_FLOAT
+    typedef float                   GrScalar;
+    #define GrIntToScalar(x)        ((GrScalar)x)
+    #define GrFixedToScalar(x)      GrFixedToFloat(x)
+    #define GrScalarToFloat(x)      (x)
+    #define GrFloatToScalar(x)      (x)
+    #define GrScalarHalf(x)         ((x) * 0.5f)
+    #define GrScalarAbs(x)          fabsf(x)
+    #define GrScalarAve(x,y)        (((x) + (y)) * 0.5f)
+    #define GR_Scalar1              1.f    
+    #define GR_ScalarHalf           0.5f
+    #define GR_ScalarMax            (FLT_MAX)
+    #define GR_ScalarMin            (-FLT_MAX)
+
+    static inline int32_t GrScalarFloorToInt(float x) {
+        return (int32_t)::floorf(x);
+    }
+    static inline int32_t GrScalarCeilToInt(float x) {
+        return (int32_t)::ceilf(x);
+    }
+#else
+    #error "Scalar type not defined"
+#endif
+
+/**
+ *  Multiply two GrScalar values
+ */
+static inline GrScalar GrMul(GrScalar a, GrScalar b) {
+#if GR_SCALAR_IS_FLOAT
+    return a * b;
+#else
+    int64_t tmp = (int64_t)a * b;
+    return (tmp + GR_FixedHalf) >> 16;
+#endif
+}
+
+#endif
+
diff --git a/gpu/include/GrStencil.h b/gpu/include/GrStencil.h
new file mode 100644
index 0000000..b014ee5
--- /dev/null
+++ b/gpu/include/GrStencil.h
@@ -0,0 +1,210 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrStencil_DEFINED
+#define GrStencil_DEFINED
+
+#include "GrTypes.h"
+/**
+ * Gr uses the stencil buffer to implement complex clipping inside the
+ * GrDrawTarget class. The GrDrawTarget makes a subset of the stencil buffer
+ * bits available for other uses by external code (clients). Client code can
+ * modify these bits. GrDrawTarget will ignore ref, mask, and writemask bits
+ * provided by clients that overlap the bits used to implement clipping. The
+ * client can use the getUsableStencilBits() function to find out how many
+ * client accessible stencil bits are available.
+ *
+ * When code outside the GrDrawTarget class uses the stencil buffer the contract
+ * is as follows:
+ *
+ * > Normal stencil funcs allow the GrGpu client to modify the client bits of
+ *   the stencil buffer outside of the clip.
+ * > Special functions allow a test against the clip. These are more limited
+ *   than the general stencil functions.
+ * > Client can assume all client bits are zero initially.
+ * > Client must ensure that after all its passes are finished it has only
+ *   written to the color buffer in the region inside the clip. Furthermore, it
+ *   must zero all client bits that were modifed (both inside and outside the
+ *   clip).
+ */
+
+/**
+ * Determines which pixels pass / fail the stencil test.
+ * Stencil test passes if (ref & mask) FUNC (stencil & mask) is true
+ */
+enum GrStencilFunc {
+    kAlways_StencilFunc = 0,
+    kNever_StencilFunc,
+    kGreater_StencilFunc,
+    kGEqual_StencilFunc,
+    kLess_StencilFunc,
+    kLEqual_StencilFunc,
+    kEqual_StencilFunc,
+    kNotEqual_StencilFunc,
+
+    // Gr stores the current clip in the
+    // stencil buffer in the high bits that
+    // are not directly accessible modifiable
+    // via the GrDrawTarget interface. The below
+    // stencil funcs test against the current
+    // clip in addition to the GrDrawTarget
+    // client's stencil bits.
+
+    // pass if inside the clip
+    kAlwaysIfInClip_StencilFunc,
+    kEqualIfInClip_StencilFunc,
+    kLessIfInClip_StencilFunc,
+    kLEqualIfInClip_StencilFunc,
+    kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0
+
+    // counts
+    kStencilFuncCount,
+    kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc -
+                            kAlwaysIfInClip_StencilFunc + 1,
+    kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount
+};
+
+/**
+ * Operations to perform based on whether stencil test passed failed.
+ */
+enum GrStencilOp {
+    kKeep_StencilOp = 0,    // preserve existing stencil value
+    kReplace_StencilOp,     // replace with reference value from stencl test
+    kIncWrap_StencilOp,     // increment and wrap at max
+    kIncClamp_StencilOp,    // increment and clamp at max
+    kDecWrap_StencilOp,     // decrement and wrap at 0
+    kDecClamp_StencilOp,    // decrement and clamp at 0
+    kZero_StencilOp,        // zero stencil bits
+    kInvert_StencilOp,      // invert stencil bits
+
+    kStencilOpCount
+};
+
+/**
+ * Struct representing stencil state.
+ */
+struct GrStencilSettings {
+    GrStencilOp   fFrontPassOp;     // op to perform when front faces pass
+    GrStencilOp   fBackPassOp;      // op to perform when back faces pass
+    GrStencilOp   fFrontFailOp;     // op to perform when front faces fail
+    GrStencilOp   fBackFailOp;      // op to perform when back faces fail
+    GrStencilFunc fFrontFunc;       // test function for front faces
+    GrStencilFunc fBackFunc;        // test function for back faces
+    unsigned int fFrontFuncMask;    // mask for front face test
+    unsigned int fBackFuncMask;     // mask for back face test
+    unsigned int fFrontFuncRef;     // reference value for front face test
+    unsigned int fBackFuncRef;      // reference value for back face test
+    unsigned int fFrontWriteMask;   // stencil write mask for front faces
+    unsigned int fBackWriteMask;    // stencil write mask for back faces
+
+    bool operator == (const GrStencilSettings& s) const {
+        // make sure this is tightly packed.
+        GR_STATIC_ASSERT(0 == sizeof(GrStencilOp)%4);
+        GR_STATIC_ASSERT(0 == sizeof(GrStencilFunc)%4);
+        GR_STATIC_ASSERT(sizeof(GrStencilSettings) ==
+                        4*sizeof(GrStencilOp) +
+                        2*sizeof(GrStencilFunc) +
+                        6*sizeof(unsigned int));
+        return 0 == memcmp(this, &s, sizeof(GrStencilSettings));
+    }
+
+    bool operator != (const GrStencilSettings& s) const {
+        return !(*this == s);
+    }
+
+    GrStencilSettings& operator =(const GrStencilSettings& s) {
+        memcpy(this, &s, sizeof(GrStencilSettings));
+        return *this;
+    }
+
+    void setSame(GrStencilOp passOp,
+                 GrStencilOp failOp,
+                 GrStencilFunc func,
+                 unsigned int funcMask,
+                 unsigned int funcRef,
+                 unsigned int writeMask) {
+        fFrontPassOp        = passOp;
+        fBackPassOp         = passOp;
+        fFrontFailOp        = failOp;
+        fBackFailOp         = failOp;
+        fFrontFunc          = func;
+        fBackFunc           = func;
+        fFrontFuncMask      = funcMask;
+        fBackFuncMask       = funcMask;
+        fFrontFuncRef       = funcRef;
+        fBackFuncRef        = funcRef;
+        fFrontWriteMask     = writeMask;
+        fBackWriteMask      = writeMask;
+    }
+
+    // canonical value for disabled stenciling
+    static const GrStencilSettings gDisabled;
+    void setDisabled() {
+        *this = gDisabled;
+    }
+    bool isDisabled() const {
+        return kKeep_StencilOp == fFrontPassOp   &&
+               kKeep_StencilOp == fBackPassOp    &&
+               kKeep_StencilOp == fFrontFailOp   &&
+               kKeep_StencilOp == fFrontFailOp   &&
+               kAlways_StencilFunc == fFrontFunc &&
+               kAlways_StencilFunc == fBackFunc;
+    }
+    void invalidate()  {
+        // just write an illegal value to the first member
+        fFrontPassOp = (GrStencilOp)-1;
+    }
+
+private:
+    friend class GrGpu;
+
+    enum {
+        kMaxStencilClipPasses = 2  // maximum number of passes to add a clip 
+                                   // element to the stencil buffer.
+    };
+
+    /**
+     * Given a thing to draw into the stencil clip, a fill type, and a set op
+     * this function determines:
+     *      1. Whether the thing can be draw directly to the stencil clip or
+     *      needs to be drawn to the client portion of the stencil first.
+     *      2. How many passes are needed.
+     *      3. What those passes are.
+     *      4. The fill rule that should actually be used to render (will 
+     *         always be non-inverted).
+     *
+     * @param op                the set op to combine this element with the 
+     *                          existing clip
+     * @param stencilClipMask   mask with just the stencil bit used for clipping
+     *                          enabled.
+     * @param invertedFill      is this path inverted
+     * @param numPasses         out: the number of passes needed to add the 
+     *                               element to the clip.
+     * @param settings          out: the stencil settings to use for each pass
+     *
+     * @return true if the clip element's geometry can be drawn directly to the
+     *         stencil clip bit. Will only be true if canBeDirect is true.
+     *         numPasses will be 1 if return value is true.
+     */
+    static bool GetClipPasses(GrSetOp op, 
+                              bool canBeDirect,
+                              unsigned int stencilClipMask,
+                              bool invertedFill,
+                              int* numPasses,
+                              GrStencilSettings settings[kMaxStencilClipPasses]);
+};
+
+#endif
diff --git a/gpu/include/GrStopwatch.h b/gpu/include/GrStopwatch.h
new file mode 100644
index 0000000..4945897
--- /dev/null
+++ b/gpu/include/GrStopwatch.h
@@ -0,0 +1,135 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrStopwatch_DEFINED
+#define GrStopwatch_DEFINED
+
+#include "GrTypes.h"
+
+template <typename PLATFORM_TIMER>
+/**
+ * Base class for stopwatch. Relies on PLATFORM_TIMER for platform-specific
+ * timer functions. PLATFORM_TIMER provides:
+ *      - typename TIMESTAMP : a timestamp value that can be used with Diff()
+ *      - static TIMESTAMP Now() : gets current timestamp
+ *      - static double Diff(const TIMESTAMP& begin, const TIMESTAMP& end) : 
+ *           computes delta in seconds between two timestamps
+ */
+class GrStopwatchBase {
+public:
+    /**
+     * Contructor - implicit reset()
+     */
+    GrStopwatchBase() {
+        fRunning = false;
+        fTotalElapsed = 0.0;        
+    }
+
+    /**
+     * begins a new lap
+     */
+    void start() {
+        double lastLap = lapTime();
+        fTotalElapsed += lastLap;
+        fRunning = true;
+        fLastStart = PLATFORM_TIMER::Now();
+    }
+    
+    /**
+     * ends current lap (or no effect if lap not started)
+     */
+    void stop() {
+        double lastLap = lapTime();
+        fTotalElapsed += lastLap;
+        fRunning = false;
+    }
+
+    /**
+     * ends current lap, resets total time
+     */
+    void reset() {
+        fRunning = false;
+        fTotalElapsed = 0.f;
+    }
+    
+    /**
+     * Computes the time of all laps since last reset() including current lap
+     * if lap is still running.
+     *
+     * @return the sum time in seconds of all laps since last reset().
+     */
+    double totalTime() const {
+        return fTotalElapsed + lapTime();
+    }
+
+    /**
+     * Current lap time.
+     *
+     * @return time in seconds of current lap if one is running otherwise 0.
+     */
+    double lapTime() const {
+        if (fRunning) {
+            PLATFORM_TIMER::Timestamp now = PLATFORM_TIMER::Now();
+            return PLATFORM_TIMER::Elapsed(fLastStart, now);
+        }
+        return 0.0;
+    }
+
+private:
+    double fTotalElapsed;
+
+    typename PLATFORM_TIMER::Timestamp fLastStart;
+    bool                               fRunning;
+};
+
+#if GR_WIN32_BUILD
+
+    #include <Windows.h>
+
+    class GrWin32Timer {
+    public:
+        typedef LARGE_INTEGER Timestamp;  
+
+        static Timestamp Now() {
+            LARGE_INTEGER now;
+            QueryPerformanceCounter(&now);
+            return now;
+        }
+
+        static double Elapsed(const Timestamp& begin, const Timestamp& end) {
+            double diff = (double)(end.QuadPart - begin.QuadPart);
+            return diff * Scale();
+        }
+    private:
+        static double Scale() {
+            static double scale;
+            if (0.0 == scale) {
+                LARGE_INTEGER freq;
+                QueryPerformanceFrequency(&freq);
+                GrAssert(0 != freq.QuadPart);
+                scale = 1 / (double) freq.QuadPart;
+            }
+            return scale;
+        }
+    };
+    typedef GrStopwatchBase<GrWin32Timer> GrStopwatch;
+#else
+    #error "Implement platform timer for stopwatch"
+#endif
+
+
+#endif
diff --git a/gpu/include/GrStringBuilder.h b/gpu/include/GrStringBuilder.h
new file mode 100644
index 0000000..bcf124f
--- /dev/null
+++ b/gpu/include/GrStringBuilder.h
@@ -0,0 +1,182 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrStringBuilder_DEFINED
+#define GrStringBuilder_DEFINED
+
+#include <GrTArray.h>
+#include <stdio.h>
+
+// Class used to concat strings together into a single string
+// See below for GrSStringBuilder subclass that has a pool of
+// stack storage (to avoid malloc).
+class GrStringBuilder {
+public:
+    GrStringBuilder() :
+            fChars() {
+        fChars.push_back() = '\0';
+    }
+
+    GrStringBuilder(const GrStringBuilder& s) :
+            fChars(s.fChars) {
+        GrAssert('\0' == s.fChars.back());
+    }
+
+    GrStringBuilder(const char* s) :
+            fChars(s, strlen(s)+1) {
+    }
+
+    GrStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) {
+        GrAssert('\0' == a.fChars.back());
+        GrAssert('\0' == b.fChars.back());
+
+        fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+        char* s = &fChars.front();
+        memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+        s += a.fChars.count() - 1;
+        memcpy(s, &b.fChars.front(), b.fChars.count());
+    }
+
+    GrStringBuilder& operator =(const GrStringBuilder& s) {
+        fChars = s.fChars;
+        return *this;
+    }
+
+    GrStringBuilder& operator =(const char* s) {
+        GrAssert('\0' == fChars.back());
+
+        int l = strlen(s);
+        fChars.resize_back(l + 1);
+        memcpy(&fChars.front(), s, l + 1);
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(const GrStringBuilder& s) {
+        GrAssert('\0' == fChars.back());
+        GrAssert('\0' == s.fChars.back());
+        fChars.push_back_n(s.length());
+        memcpy(&fChars.fromBack(s.length()), &s.fChars.front(), s.fChars.count());
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(const char* s) {
+        GrAssert('\0' == fChars.back());
+        int l = strlen(s);
+        fChars.push_back_n(l);
+        memcpy(&fChars.fromBack(l), s, l + 1);
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(char c) {
+        GrAssert('\0' == fChars.back());
+        fChars.back() = c;
+        fChars.push_back() = '\0';
+        return *this;
+    }
+
+    void appendInt(int x) {
+        GR_STATIC_ASSERT(4 == sizeof(int));
+        // -, 10 digits, null char
+        char temp[12];
+        sprintf(temp, "%d", x);
+        *this += temp;
+    }
+
+    char& operator [](int i) {
+        GrAssert(i < length());
+        return fChars[i];
+    }
+
+    char operator [](int i) const {
+        GrAssert(i < length());
+        return fChars[i];
+    }
+
+    const char* cstr() const { return &fChars.front(); }
+
+    int length() const { return fChars.count() - 1; }
+
+protected:
+    // helpers for GrSStringBuilder (with storage on the stack)
+
+    GrStringBuilder(void* stackChars, int stackCount) :
+            fChars(stackCount ? stackChars : NULL,
+                   stackCount) {
+        fChars.push_back() = '\0';
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const GrStringBuilder& s) :
+            fChars(s.fChars,
+                   (stackCount ? stackChars : NULL),
+                   stackCount) {
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const char* s) :
+            fChars(s,
+                   strlen(s)+1,
+                   stackCount ? stackChars : NULL,
+                   stackCount) {
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const GrStringBuilder& a,
+                    const GrStringBuilder& b) :
+            fChars(stackCount ? stackChars : NULL,
+                   stackCount) {
+        GrAssert('\0' == a.fChars.back());
+        GrAssert('\0' == b.fChars.back());
+
+        fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+        char* s = &fChars.front();
+        memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+        s += a.fChars.count() - 1;
+        memcpy(s, &b.fChars.front(), b.fChars.count());
+    }
+
+private:
+    GrTArray<char, true>  fChars;
+};
+
+template <int STACK_COUNT = 128>
+class GrSStringBuilder : public GrStringBuilder {
+public:
+    GrSStringBuilder() : GrStringBuilder(fStackChars, STACK_COUNT) {}
+
+    GrSStringBuilder(const GrStringBuilder& s) : GrStringBuilder(fStackChars,
+                                                                 STACK_COUNT,
+                                                                 s) {
+    }
+
+    GrSStringBuilder(const char* s) : GrStringBuilder(fStackChars,
+                                                      STACK_COUNT,
+                                                      s) {
+    }
+
+    GrSStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) :
+            GrStringBuilder(fStackChars, STACK_COUNT, a, b) {
+    }
+private:
+    char fStackChars[STACK_COUNT];
+};
+
+#endif
+
diff --git a/gpu/include/GrTArray.h b/gpu/include/GrTArray.h
new file mode 100644
index 0000000..6ef1a13
--- /dev/null
+++ b/gpu/include/GrTArray.h
@@ -0,0 +1,319 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTArray_DEFINED
+#define GrTArray_DEFINED
+
+#include <new>
+#include "GrTypes.h"
+
+// DATA_TYPE indicates that T has a trivial cons, destructor
+// and can be shallow-copied
+template <typename T, bool DATA_TYPE = false> class GrTArray {
+public:
+    GrTArray() {
+        fCount = 0;
+        fReserveCount = MIN_ALLOC_COUNT;
+        fAllocCount = 0;
+        fMemArray = NULL;
+        fPreAllocMemArray = NULL;
+    }
+
+    explicit GrTArray(int reserveCount) {
+        GrAssert(reserveCount >= 0);
+        fCount = 0;
+        fReserveCount = reserveCount > MIN_ALLOC_COUNT ? reserveCount :
+                                                         MIN_ALLOC_COUNT;
+        fAllocCount = fReserveCount;
+        fMemArray = GrMalloc(sizeof(T) * fReserveCount);
+        fPreAllocMemArray = NULL;
+    }
+
+    GrTArray(void* preAllocStorage, int preAllocCount) {
+        GrAssert(preAllocCount >= 0);
+        // we allow NULL,0 args and revert to the default cons. behavior
+        // this makes it possible for a owner-object to use same constructor
+        // to get either prealloc or nonprealloc behavior based using same line
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = 0;
+        fReserveCount       = preAllocCount > 0 ? preAllocCount :
+                                                  MIN_ALLOC_COUNT;
+        fAllocCount         = preAllocCount;
+        fMemArray           = preAllocStorage;
+        fPreAllocMemArray   = preAllocStorage;
+    }
+
+    explicit GrTArray(const GrTArray& array) {
+        fCount              = array.count();
+        fReserveCount       = MIN_ALLOC_COUNT;
+        fAllocCount         = GrMax(fReserveCount, fCount);
+        fMemArray           = GrMalloc(sizeof(T) * fAllocCount);
+        fPreAllocMemArray   = NULL;
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (int i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const T* array, int count) {
+        GrAssert(count >= 0);
+        fCount              = count;
+        fReserveCount       = MIN_ALLOC_COUNT;
+        fAllocCount         = GrMax(fReserveCount, fCount);
+        fMemArray           = GrMalloc(sizeof(T) * fAllocCount);
+        fPreAllocMemArray   = NULL;
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array, sizeof(T) * fCount);
+        } else {
+            for (int i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const GrTArray& array,
+             void* preAllocStorage, int preAllocCount) {
+
+        GrAssert(preAllocCount >= 0);
+
+        // for same reason as non-copying cons we allow NULL, 0 for prealloc
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = array.count();
+        fReserveCount       = preAllocCount > 0 ? preAllocCount :
+                                                  MIN_ALLOC_COUNT;
+        fPreAllocMemArray   = preAllocStorage;
+
+        if (fReserveCount >= fCount && preAllocCount) {
+            fAllocCount = fReserveCount;
+            fMemArray = preAllocStorage;
+        } else {
+            fAllocCount = GrMax(fCount, fReserveCount);
+            fMemArray = GrMalloc(fAllocCount * sizeof(T));
+        }
+
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (int i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const T* array, int count,
+             void* preAllocStorage, int preAllocCount) {
+
+        GrAssert(count >= 0);
+        GrAssert(preAllocCount >= 0);
+
+        // for same reason as non-copying cons we allow NULL, 0 for prealloc
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = count;
+        fReserveCount       = (preAllocCount > 0) ? preAllocCount :
+                                                    MIN_ALLOC_COUNT;
+        fPreAllocMemArray   = preAllocStorage;
+
+        if (fReserveCount >= fCount && preAllocCount) {
+            fAllocCount = fReserveCount;
+            fMemArray = preAllocStorage;
+        } else {
+            fAllocCount = GrMax(fCount, fReserveCount);
+            fMemArray = GrMalloc(fAllocCount * sizeof(T));
+        }
+
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array, sizeof(T) * fCount);
+        } else {
+            for (int i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray& operator =(const GrTArray& array) {
+        for (int i = 0; i < fCount; ++i) {
+            fItemArray[i].~T();
+        }
+        fCount = 0;
+        checkRealloc((int)array.count());
+        fCount = array.count();
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (int i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+        return *this;
+    }
+
+    ~GrTArray() {
+        for (int i = 0; i < fCount; ++i) {
+            fItemArray[i].~T();
+        }
+        if (fMemArray != fPreAllocMemArray) {
+            GrFree(fMemArray);
+        }
+    }
+
+    void reset() { this->pop_back_n(fCount); }
+
+    int count() const { return fCount; }
+
+    bool empty() const { return !fCount; }
+
+    T& push_back() {
+        checkRealloc(1);
+        new ((char*)fMemArray+sizeof(T)*fCount) T;
+        ++fCount;
+        return fItemArray[fCount-1];
+    }
+
+    void push_back_n(int n) {
+        GrAssert(n >= 0);
+        checkRealloc(n);
+        for (int i = 0; i < n; ++i) {
+            new (fItemArray + fCount + i) T;
+        }
+        fCount += n;
+    }
+
+    void pop_back() {
+        GrAssert(fCount > 0);
+        --fCount;
+        fItemArray[fCount].~T();
+        checkRealloc(0);
+    }
+
+    void pop_back_n(int n) {
+        GrAssert(n >= 0);
+        GrAssert(fCount >= n);
+        fCount -= n;
+        for (int i = 0; i < n; ++i) {
+            fItemArray[i].~T();
+        }
+        checkRealloc(0);
+    }
+
+    // pushes or pops from the back to resize
+    void resize_back(int newCount) {
+        GrAssert(newCount >= 0);
+
+        if (newCount > fCount) {
+            push_back_n(newCount - fCount);
+        } else if (newCount < fCount) {
+            pop_back_n(fCount - newCount);
+        }
+    }
+
+    T& operator[] (int i) {
+        GrAssert(i < fCount);
+        GrAssert(i >= 0);
+        return fItemArray[i];
+    }
+
+    const T& operator[] (int i) const {
+        GrAssert(i < fCount);
+        GrAssert(i >= 0);
+        return fItemArray[i];
+    }
+
+    T& front() { GrAssert(fCount > 0); return fItemArray[0];}
+
+    const T& front() const { GrAssert(fCount > 0); return fItemArray[0];}
+
+    T& back() { GrAssert(fCount); return fItemArray[fCount - 1];}
+
+    const T& back() const { GrAssert(fCount > 0); return fItemArray[fCount - 1];}
+
+    T& fromBack(int i) {
+        GrAssert(i >= 0);
+        GrAssert(i < fCount);
+        return fItemArray[fCount - i - 1];
+    }
+
+    const T& fromBack(int i) const {
+        GrAssert(i >= 0);
+        GrAssert(i < fCount);
+        return fItemArray[fCount - i - 1];
+    }
+
+private:
+
+    static const int MIN_ALLOC_COUNT = 8;
+
+    inline void checkRealloc(int delta) {
+        GrAssert(fCount >= 0);
+        GrAssert(fAllocCount >= 0);
+
+        GrAssert(-delta <= fCount);
+
+        int newCount = fCount + delta;
+        int fNewAllocCount = fAllocCount;
+
+        if (newCount > fAllocCount) {
+            fNewAllocCount = GrMax(newCount + ((newCount + 1) >> 1),
+                                   fReserveCount);
+        } else if (newCount < fAllocCount / 3) {
+            fNewAllocCount = GrMax(fAllocCount / 2, fReserveCount);
+        }
+
+        if (fNewAllocCount != fAllocCount) {
+
+            fAllocCount = fNewAllocCount;
+            char* fNewMemArray;
+
+            if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) {
+                fNewMemArray = (char*) fPreAllocMemArray;
+            } else {
+                fNewMemArray = (char*) GrMalloc(fAllocCount*sizeof(T));
+            }
+
+            if (DATA_TYPE) {
+                memcpy(fNewMemArray, fMemArray, fCount * sizeof(T));
+            } else {
+                for (int i = 0; i < fCount; ++i) {
+                    new (fNewMemArray + sizeof(T) * i) T(fItemArray[i]);
+                    fItemArray[i].~T();
+                }
+            }
+
+            if (fMemArray != fPreAllocMemArray) {
+                GrFree(fMemArray);
+            }
+            fMemArray = fNewMemArray;
+        }
+    }
+
+    int fReserveCount;
+    int fCount;
+    int fAllocCount;
+    void*    fPreAllocMemArray;
+    union {
+        T*       fItemArray;
+        void*    fMemArray;
+    };
+};
+
+#endif
+
diff --git a/gpu/include/GrTBSearch.h b/gpu/include/GrTBSearch.h
new file mode 100644
index 0000000..264ccb0
--- /dev/null
+++ b/gpu/include/GrTBSearch.h
@@ -0,0 +1,53 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTBSearch_DEFINED
+#define GrTBSearch_DEFINED
+
+template <typename ELEM, typename KEY>
+int GrTBSearch(const ELEM array[], int count, KEY target) {
+    GrAssert(count >= 0);
+    if (0 == count) {
+        // we should insert it at 0
+        return ~0;
+    }
+    
+    int high = count - 1;
+    int low = 0;
+    while (high > low) {
+        int index = (low + high) >> 1;
+        if (LT(array[index], target)) {
+            low = index + 1;
+        } else {
+            high = index;
+        }
+    }
+    
+    // check if we found it
+    if (EQ(array[high], target)) {
+        return high;
+    }
+    
+    // now return the ~ of where we should insert it
+    if (LT(array[high], target)) {
+        high += 1;
+    }
+    return ~high;
+}
+
+#endif
+
diff --git a/gpu/include/GrTDArray.h b/gpu/include/GrTDArray.h
new file mode 100644
index 0000000..092242e
--- /dev/null
+++ b/gpu/include/GrTDArray.h
@@ -0,0 +1,222 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTDArray_DEFINED
+#define GrTDArray_DEFINED
+
+#include "GrTypes.h"
+
+static int GrInitialArrayAllocationCount() {
+    return 4;
+}
+
+static int GrNextArrayAllocationCount(int count) {
+    return count + ((count + 1) >> 1);
+}
+
+template <typename T> class GrTDArray {
+public:
+    GrTDArray() : fArray(NULL), fAllocated(0), fCount(0) {}
+    GrTDArray(const GrTDArray& src) {
+        fCount = fAllocated = src.fCount;
+        fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        memcpy(fArray, src.fArray, fCount * sizeof(T));
+    }
+    ~GrTDArray() {
+        if (fArray) {
+            GrFree(fArray);
+        }
+    }
+
+    bool isEmpty() const { return 0 == fCount; }
+    int count() const { return fCount; }
+
+    const T& at(int index) const {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        return fArray[index];
+    }
+    T& at(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        return fArray[index];
+    }
+
+    const T& operator[](int index) const { return this->at(index); }
+    T& operator[](int index) { return this->at(index); }
+
+    GrTDArray& operator=(const GrTDArray& src) {
+        if (fAllocated < src.fCount) {
+            fAllocated = src.fCount;
+            GrFree(fArray);
+            fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        }
+        fCount = src.fCount;
+        memcpy(fArray, src.fArray, fCount * sizeof(T));
+        return *this;
+    }
+
+    void reset() {
+        if (fArray) {
+            GrFree(fArray);
+            fArray = NULL;
+        }
+        fAllocated = fCount = 0;
+    }
+
+    T* begin() const { return fArray; }
+    T* end() const { return fArray + fCount; }
+    T* back() const { GrAssert(fCount); return fArray + (fCount - 1); } 
+
+    T* prepend() {
+        this->growAt(0);
+        return fArray;
+    }
+
+    T* append() {
+        this->growAt(fCount);
+        return fArray + fCount - 1;
+    }
+
+    /**
+     *  index may be [0..count], so that you can insert at the end (like append)
+     */
+    T* insert(int index) {
+        GrAssert((unsigned)index <= (unsigned)fCount);
+        this->growAt(index);
+        return fArray + index;
+    }
+
+    void remove(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        fCount -= 1;
+        if (index < fCount) {
+            int remaining = fCount - index;
+            memmove(fArray + index, fArray + index + 1, remaining * sizeof(T));
+        }
+    }
+
+    void removeShuffle(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        fCount -= 1;
+        if (index < fCount) {
+            memmove(fArray + index, fArray + fCount, sizeof(T));
+        }
+    }
+
+    // Utility iterators
+
+    /**
+     *  Calls GrFree() on each element. Assumes each is NULL or was allocated
+     *  with GrMalloc().
+     */
+    void freeAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            GrFree(*curr);
+        }
+        this->reset();
+    }
+
+    /**
+     *  Calls delete on each element. Assumes each is NULL or was allocated
+     *  with new.
+     */
+    void deleteAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            delete *curr;
+        }
+        this->reset();
+    }
+
+    /**
+     *  Calls GrSafeUnref() on each element. Assumes each is NULL or is a
+     *  subclass of GrRefCnt.
+     */
+    void unrefAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            GrSafeUnref(*curr);
+        }
+        this->reset();
+    }
+
+    void visit(void visitor(T&)) const {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            if (*curr) {
+                visitor(*curr);
+            }
+        }
+    }
+
+    int find(const T& elem) const {
+        int count = this->count();
+        T* curr = this->begin();
+        for (int i = 0; i < count; i++) {
+            if (elem == curr[i]) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    friend bool operator==(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+        return a.count() == b.count() &&
+               (0 == a.count() ||
+                0 == memcmp(a.begin(), b.begin(), a.count() * sizeof(T)));
+    }
+    friend bool operator!=(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+        return !(a == b);
+    }
+
+private:
+    T*  fArray;
+    int fAllocated, fCount;
+
+    // growAt will increment fCount, reallocate fArray (as needed), and slide
+    // the contents of fArray to make a hole for new data at index.
+    void growAt(int index) {
+        GrAssert(fCount <= fAllocated);
+        if (0 == fAllocated) {
+            fAllocated = GrInitialArrayAllocationCount();
+            fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        } else if (fCount == fAllocated) {
+            fAllocated = GrNextArrayAllocationCount(fAllocated);
+            T* newArray = (T*)GrMalloc(fAllocated * sizeof(T));
+            memcpy(newArray, fArray, index * sizeof(T));
+            memcpy(newArray + index + 1, fArray + index,
+                   (fCount - index) * sizeof(T));
+            GrFree(fArray);
+            fArray = newArray;
+        } else {
+            // check that we're not just appending
+            if (index < fCount) {
+                memmove(fArray + index + 1, fArray + index,
+                        (fCount - index) * sizeof(T));
+            }
+        }
+        GrAssert(fCount < fAllocated);
+        fCount += 1;
+    }
+};
+
+extern void* GrTDArray_growAt(void*, int* allocated, int& count, int index,
+                              size_t);
+
+
+#endif
+
diff --git a/gpu/include/GrTHashCache.h b/gpu/include/GrTHashCache.h
new file mode 100644
index 0000000..510f9ab
--- /dev/null
+++ b/gpu/include/GrTHashCache.h
@@ -0,0 +1,226 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTHashCache_DEFINED
+#define GrTHashCache_DEFINED
+
+#include "GrTDArray.h"
+
+/**
+ *  Key needs
+ *      static bool EQ(const Entry&, const HashKey&);
+ *      static bool LT(const Entry&, const HashKey&);
+ *      uint32_t getHash() const;
+ *
+ *  Allows duplicate key entries but on find you may get
+ *  any of the duplicate entries returned.
+ */
+template <typename T, typename Key, size_t kHashBits> class GrTHashTable {
+public:
+    GrTHashTable() { Gr_bzero(fHash, sizeof(fHash)); }
+    ~GrTHashTable() {}
+
+    int count() const { return fSorted.count(); }
+    T*  find(const Key&) const;
+    // return true if key was unique when inserted.
+    bool insert(const Key&, T*);
+    void remove(const Key&, const T*);
+    T* removeAt(int index, uint32_t hash);
+    void removeAll();
+    void deleteAll();
+    void unrefAll();
+
+    /**
+     *  Return the index for the element, using a linear search.
+     */
+    int slowFindIndex(T* elem) const { return fSorted.find(elem); }
+
+#if GR_DEBUG
+    void validate() const;
+    bool contains(T*) const;
+#endif
+
+    // testing
+    const GrTDArray<T*>& getArray() const { return fSorted; }
+private:
+    enum {
+        kHashCount = 1 << kHashBits,
+        kHashMask  = kHashCount - 1
+    };
+    static unsigned hash2Index(uint32_t hash) {
+        hash ^= hash >> 16;
+        if (kHashBits <= 8) {
+            hash ^= hash >> 8;
+        }
+        return hash & kHashMask;
+    }
+
+    mutable T* fHash[kHashCount];
+    GrTDArray<T*> fSorted;
+
+    // search fSorted, and return the found index, or ~index of where it
+    // should be inserted
+    int searchArray(const Key&) const;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T, typename Key, size_t kHashBits>
+int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const {
+    int count = fSorted.count();
+    if (0 == count) {
+        // we should insert it at 0
+        return ~0;
+    }
+
+    const T* const* array = fSorted.begin();
+    int high = count - 1;
+    int low = 0;
+    while (high > low) {
+        int index = (low + high) >> 1;
+        if (Key::LT(*array[index], key)) {
+            low = index + 1;
+        } else {
+            high = index;
+        }
+    }
+
+    // check if we found it
+    if (Key::EQ(*array[high], key)) {
+        // above search should have found the first occurrence if there
+        // are multiple.
+        GrAssert(0 == high || Key::LT(*array[high - 1], key));
+        return high;
+    }
+
+    // now return the ~ of where we should insert it
+    if (Key::LT(*array[high], key)) {
+        high += 1;
+    }
+    return ~high;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::find(const Key& key) const {
+    int hashIndex = hash2Index(key.getHash());
+    T* elem = fHash[hashIndex];
+
+    if (NULL == elem || !Key::EQ(*elem, key)) {
+        // bsearch for the key in our sorted array
+        int index = this->searchArray(key);
+        if (index < 0) {
+            return NULL;
+        }
+        elem = fSorted[index];
+        // update the hash
+        fHash[hashIndex] = elem;
+    }
+    return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::insert(const Key& key, T* elem) {
+    int index = this->searchArray(key);
+    bool first = index < 0;
+    if (first) {
+        // turn it into the actual index
+        index = ~index;
+    }
+    // add it to our array
+    *fSorted.insert(index) = elem;
+    // update our hash table (overwrites any dupe's position in the hash)
+    fHash[hash2Index(key.getHash())] = elem;
+    return first;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::remove(const Key& key, const T* elem) {
+    int index = hash2Index(key.getHash());
+    if (fHash[index] == elem) {
+        fHash[index] = NULL;
+    }
+
+    // remove from our sorted array
+    index = this->searchArray(key);
+    GrAssert(index >= 0);
+    // if there are multiple matches searchArray will give us the first match
+    // march forward until we find elem.
+    while (elem != fSorted[index]) {
+        ++index;
+        GrAssert(index < fSorted.count());
+    }
+    GrAssert(elem == fSorted[index]);
+    fSorted.remove(index);
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::removeAt(int elemIndex, uint32_t hash) {
+    int hashIndex = hash2Index(hash);
+    if (fHash[hashIndex] == fSorted[elemIndex]) {
+        fHash[hashIndex] = NULL;
+    }
+    // remove from our sorted array
+    T* elem = fSorted[elemIndex];
+    fSorted.remove(elemIndex);
+    return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::removeAll() {
+    fSorted.reset();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::deleteAll() {
+    fSorted.deleteAll();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::unrefAll() {
+    fSorted.unrefAll();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+#if GR_DEBUG
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::validate() const {
+    for (size_t i = 0; i < GR_ARRAY_COUNT(fHash); i++) {
+        if (fHash[i]) {
+            unsigned hashIndex = hash2Index(Key::GetHash(*fHash[i]));
+            GrAssert(hashIndex == i);
+        }
+    }
+
+    int count = fSorted.count();
+    for (int i = 1; i < count; i++) {
+        GrAssert(Key::LT(*fSorted[i - 1], *fSorted[i]) ||
+                 Key::EQ(*fSorted[i - 1], *fSorted[i]));
+    }
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::contains(T* elem) const {
+    int index = fSorted.find(elem);
+    return index >= 0;
+}
+
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTLList.h b/gpu/include/GrTLList.h
new file mode 100644
index 0000000..1f59635
--- /dev/null
+++ b/gpu/include/GrTLList.h
@@ -0,0 +1,61 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTLList_DEFINED
+#define GrTLList_DEFINED
+
+#include "GrNoncopyable.h"
+
+template <typename T> class GrTLList : GrNoncopyable {
+public:
+    class Entry {
+        Entry*  fPrev;
+        Entry*  fNext;
+    };
+
+    GrTLList() : fHead(NULL), fTail(NULL) {}
+#if GR_DEBUG
+    ~GrTLList() {
+        GrAssert(NULL == fHead);
+        GrAssert(NULL == ftail);
+    }
+#endif
+
+    T*  head() const { return fHead; }
+    T*  tail() const { return fTail; }
+    
+    void addToHead(T*);
+    void addToTail(T*);
+    void removeFromList(T*);
+
+private:
+    Entry*  fHead;
+    Entry*  fTail;
+
+    friend class Entry;
+};
+
+
+class Parent {
+    GrTDLList<Child>    fList;
+};
+
+class Child : public GrTLList::Entry<Child> {
+};
+
+#endif
+
diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h
new file mode 100644
index 0000000..a598251
--- /dev/null
+++ b/gpu/include/GrTextContext.h
@@ -0,0 +1,74 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextContext_DEFINED
+#define GrTextContext_DEFINED
+
+#include "GrGlyph.h"
+#include "GrPaint.h"
+
+struct GrGpuTextVertex;
+class GrMatrix;
+class GrContext;
+class GrTextStrike;
+class GrFontScaler;
+class GrDrawTarget;
+
+class GrTextContext {
+public:
+    GrTextContext(GrContext*,
+                  const GrPaint& paint,
+                  const GrMatrix* extMatrix = NULL);
+    ~GrTextContext();
+
+    void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
+                         GrFontScaler*);
+
+    void flush();   // optional; automatically called by destructor
+
+private:
+    GrPaint         fPaint;
+    GrVertexLayout  fVertexLayout;
+    GrContext*      fContext;
+    GrDrawTarget*   fDrawTarget;
+
+    GrMatrix        fExtMatrix;
+    GrFontScaler*   fScaler;
+    GrTextStrike*   fStrike;
+
+    inline void flushGlyphs();
+
+    enum {
+        kMinRequestedGlyphs      = 1,
+        kDefaultRequestedGlyphs  = 64,
+        kMinRequestedVerts       = kMinRequestedGlyphs * 4,
+        kDefaultRequestedVerts   = kDefaultRequestedGlyphs * 4,
+    };
+
+    GrGpuTextVertex* fVertices;
+
+    int32_t     fMaxVertices;
+    GrTexture*  fCurrTexture;
+    int         fCurrVertex;
+
+    GrIRect     fClipRect;
+    GrMatrix    fOrigViewMatrix;    // restore previous viewmatrix
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTextStrike.h b/gpu/include/GrTextStrike.h
new file mode 100644
index 0000000..610222c
--- /dev/null
+++ b/gpu/include/GrTextStrike.h
@@ -0,0 +1,123 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextStrike_DEFINED
+#define GrTextStrike_DEFINED
+
+#include "GrAllocPool.h"
+#include "GrFontScaler.h"
+#include "GrTHashCache.h"
+#include "GrPoint.h"
+#include "GrGlyph.h"
+
+class GrAtlasMgr;
+class GrFontCache;
+class GrGpu;
+class GrFontPurgeListener;
+
+/**
+ *  The textcache maps a hostfontscaler instance to a dictionary of
+ *  glyphid->strike
+ */
+class GrTextStrike {
+public:
+    GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrMaskFormat,
+                 GrAtlasMgr*);
+    ~GrTextStrike();
+
+    const GrKey* getFontScalerKey() const { return fFontScalerKey; }
+    GrFontCache* getFontCache() const { return fFontCache; }
+    GrMaskFormat getMaskFormat() const { return fMaskFormat; }
+
+    inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
+    bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
+
+    // testing
+    int countGlyphs() const { return fCache.getArray().count(); }
+    const GrGlyph* glyphAt(int index) const {
+        return fCache.getArray()[index];
+    }
+    GrAtlas* getAtlas() const { return fAtlas; }
+
+public:
+    // for LRU
+    GrTextStrike*   fPrev;
+    GrTextStrike*   fNext;
+
+private:
+    class Key;
+    GrTHashTable<GrGlyph, Key, 7> fCache;
+    const GrKey* fFontScalerKey;
+    GrTAllocPool<GrGlyph> fPool;
+
+    GrFontCache*    fFontCache;
+    GrAtlasMgr*     fAtlasMgr;
+    GrAtlas*        fAtlas;     // linklist
+
+    GrMaskFormat fMaskFormat;
+
+    GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
+    // returns true if after the purge, the strike is empty
+    bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
+
+    friend class GrFontCache;
+};
+
+class GrFontCache {
+public:
+    GrFontCache(GrGpu*);
+    ~GrFontCache();
+
+    inline GrTextStrike* getStrike(GrFontScaler*);
+
+    void freeAll();
+    void abandonAll();
+
+    void purgeExceptFor(GrTextStrike*);
+
+    // testing
+    int countStrikes() const { return fCache.getArray().count(); }
+    const GrTextStrike* strikeAt(int index) const {
+        return fCache.getArray()[index];
+    }
+    GrTextStrike* getHeadStrike() const { return fHead; }
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    friend class GrFontPurgeListener;
+
+    class Key;
+    GrTHashTable<GrTextStrike, Key, 8> fCache;
+    // for LRU
+    GrTextStrike* fHead;
+    GrTextStrike* fTail;
+
+    GrGpu*      fGpu;
+    GrAtlasMgr* fAtlasMgr;
+
+
+    GrTextStrike* generateStrike(GrFontScaler*, const Key&);
+    inline void detachStrikeFromList(GrTextStrike*);
+};
+
+#endif
+
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
new file mode 100644
index 0000000..0a65ff7
--- /dev/null
+++ b/gpu/include/GrTexture.h
@@ -0,0 +1,207 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTexture_DEFINED
+#define GrTexture_DEFINED
+
+#include "GrRefCnt.h"
+#include "GrClip.h"
+
+class GrTexture;
+
+/**
+ * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
+ * A context's render target is set by setRenderTarget(). Render targets are
+ * created by a createTexture with the kRenderTarget_TextureFlag flag.
+ * Additionally, GrContext provides methods for creating GrRenderTargets
+ * that wrap externally created render targets.
+ */
+class GrRenderTarget : public GrRefCnt {
+public:
+    /**
+     * @return the width of the rendertarget
+     */
+    int width() const { return fWidth; }
+    /**
+     * @return the height of the rendertarget
+     */
+    int height() const { return fHeight; }
+
+    /**
+     * @return the number of stencil bits in the rendertarget
+     */
+    int stencilBits() const { return fStencilBits; }
+
+    /**
+     * @return the texture associated with the rendertarget, may be NULL.
+     */
+    GrTexture* asTexture() {return fTexture;}
+
+protected:
+    GrRenderTarget(GrTexture* texture,
+                   int width,
+                   int height,
+                   int stencilBits)
+        : fTexture(texture),
+          fWidth(width),
+          fHeight(height),
+          fStencilBits(stencilBits) {}
+
+
+    GrTexture* fTexture;
+    int        fWidth;
+    int        fHeight;
+    int        fStencilBits;
+
+private:
+    // GrGpu keeps a cached clip in the render target to avoid redundantly
+    // rendering the clip into the same stencil buffer.
+    friend class GrGpu;
+    GrClip     fLastStencilClip;
+
+    typedef GrRefCnt INHERITED;
+};
+
+class GrTexture : public GrRefCnt {
+public:
+    enum PixelConfig {
+        kUnknown_PixelConfig,
+        kAlpha_8_PixelConfig,
+        kIndex_8_PixelConfig,
+        kRGB_565_PixelConfig,
+        kRGBA_4444_PixelConfig, //!< premultiplied
+        kRGBA_8888_PixelConfig, //!< premultiplied
+        kRGBX_8888_PixelConfig, //!< treat the alpha channel as opaque
+    };
+    static size_t BytesPerPixel(PixelConfig);
+    static bool PixelConfigIsOpaque(PixelConfig);
+    static bool PixelConfigIsAlphaOnly(PixelConfig);
+
+protected:
+    GrTexture(int width,
+              int height,
+              PixelConfig config) :
+                fWidth(width),
+                fHeight(height),
+                fConfig(config) {
+                    // only make sense if alloc size is pow2
+                    fShiftFixedX = 31 - Gr_clz(fWidth);
+                    fShiftFixedY = 31 - Gr_clz(fHeight);
+                }
+public:
+    virtual ~GrTexture();
+
+    /**
+     * Retrieves the width of the texture.
+     *
+     * @return the width in texels
+     */
+    int width() const { return fWidth; }
+    /**
+     * Retrieves the height of the texture.
+     *
+     * @return the height in texels
+     */
+    int height() const { return fHeight; }
+
+    /**
+     * Convert from texels to normalized texture coords for POT textures
+     * only.
+     */
+    GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
+                                               return x >> fShiftFixedX; }
+    GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
+                                               return y >> fShiftFixedY; }
+
+    /**
+     * Retrieves the pixel config specified when the texture was created.
+     */
+    PixelConfig config() const { return fConfig; }
+
+    /**
+     *  Approximate number of bytes used by the texture
+     */
+    size_t sizeInBytes() const {
+        return fWidth * fHeight * BytesPerPixel(fConfig);
+    }
+
+    /**
+     * Updates a subrectangle of texels in the texture.
+     *
+     * @param x       left edge of rectangle to update
+     * @param y       top edge of rectangle to update
+     * @param width   width of rectangle to update
+     * @param height  height of rectangle to update
+     * @param srcData width*height texels of data in same format that was used
+     *                at texture creation.
+     */
+    virtual void uploadTextureData(uint32_t x,
+                                   uint32_t y,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   const void* srcData) = 0;
+    /**
+     * Indicates that GPU context in which this texture was created is destroyed
+     * and that Ganesh should not attempt to free the texture with the
+     * underlying API.
+     */
+    virtual void abandon() = 0;
+
+    /**
+     * Retrieves the render target underlying this texture that can be passed to
+     * GrGpu::setRenderTarget().
+     *
+     * @return    handle to render target or undefined if the texture is not a
+     *            render target
+     */
+    virtual GrRenderTarget* asRenderTarget() = 0;
+
+    /**
+     * Removes the reference on the associated GrRenderTarget held by this
+     * texture. Afterwards asRenderTarget() will return NULL. The 
+     * GrRenderTarget survives the release if another ref is held on it.
+     */
+    virtual void releaseRenderTarget() = 0;
+
+    /**
+     *  Return the native ID or handle to the texture, depending on the
+     *  platform. e.g. on opengl, return the texture ID.
+     */
+    virtual intptr_t getTextureHandle() = 0;
+
+#if GR_DEBUG
+    void validate() const {
+        this->INHERITED::validate();
+    }
+#else
+    void validate() const {}
+#endif
+
+private:
+    int fWidth;
+    int fHeight;
+    // these two shift a fixed-point value into normalized coordinates
+    // for this texture if the texture is power of two sized.
+    int      fShiftFixedX;
+    int      fShiftFixedY;
+    PixelConfig fConfig;
+
+    typedef GrRefCnt INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrTextureCache.h b/gpu/include/GrTextureCache.h
new file mode 100644
index 0000000..68e1daa
--- /dev/null
+++ b/gpu/include/GrTextureCache.h
@@ -0,0 +1,310 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextureCache_DEFINED
+#define GrTextureCache_DEFINED
+
+#include "GrTypes.h"
+#include "GrTHashCache.h"
+
+class GrTexture;
+
+// return true if a<b, or false if b<a
+//
+#define RET_IF_LT_OR_GT(a, b)   \
+    do {                        \
+        if ((a) < (b)) {        \
+            return true;        \
+        }                       \
+        if ((b) < (a)) {        \
+            return false;       \
+        }                       \
+    } while (0)
+
+/**
+ *  Helper class for GrTextureCache, the Key is used to identify src data for
+ *  a texture. It is identified by 2 32bit data fields which can hold any
+ *  data (uninterpreted by the cache) and a width/height.
+ */
+class GrTextureKey {
+public:
+    enum {
+        kHashBits   = 7,
+        kHashCount  = 1 << kHashBits,
+        kHashMask   = kHashCount - 1
+    };
+
+    GrTextureKey(uint32_t p0, uint32_t p1, uint16_t width, uint16_t height) {
+        fP0 = p0;
+        fP1 = p1;
+        fP2 = width | (height << 16);
+        GR_DEBUGCODE(fHashIndex = -1);
+    }
+
+    GrTextureKey(const GrTextureKey& src) {
+        fP0 = src.fP0;
+        fP1 = src.fP1;
+        fP2 = src.fP2;
+        finalize(src.fPrivateBits);
+    }
+
+    //!< returns hash value [0..kHashMask] for the key
+    int hashIndex() const { return fHashIndex; }
+
+    friend bool operator==(const GrTextureKey& a, const GrTextureKey& b) {
+        GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+        return a.fP0 == b.fP0 && a.fP1 == b.fP1 && a.fP2 == b.fP2 &&
+               a.fPrivateBits == b.fPrivateBits;
+    }
+
+    friend bool operator!=(const GrTextureKey& a, const GrTextureKey& b) {
+        GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+        return !(a == b);
+    }
+
+    friend bool operator<(const GrTextureKey& a, const GrTextureKey& b) {
+        RET_IF_LT_OR_GT(a.fP0, b.fP0);
+        RET_IF_LT_OR_GT(a.fP1, b.fP1);
+        RET_IF_LT_OR_GT(a.fP2, b.fP2);
+        return a.fPrivateBits < b.fPrivateBits;
+    }
+
+private:
+    void finalize(uint32_t privateBits) {
+        fPrivateBits = privateBits;
+        this->computeHashIndex();
+    }
+
+    uint16_t width() const { return fP2 & 0xffff; }
+    uint16_t height() const { return (fP2 >> 16); }
+
+    static uint32_t rol(uint32_t x) {
+        return (x >> 24) | (x << 8);
+    }
+    static uint32_t ror(uint32_t x) {
+        return (x >> 8) | (x << 24);
+    }
+    static uint32_t rohalf(uint32_t x) {
+        return (x >> 16) | (x << 16);
+    }
+
+    void computeHashIndex() {
+        uint32_t hash = fP0 ^ rol(fP1) ^ ror(fP2) ^ rohalf(fPrivateBits);
+        // this way to mix and reduce hash to its index may have to change
+        // depending on how many bits we allocate to the index
+        hash ^= hash >> 16;
+        hash ^= hash >> 8;
+        fHashIndex = hash & kHashMask;
+    }
+
+    uint32_t    fP0;
+    uint32_t    fP1;
+    uint32_t    fP2;
+    uint32_t    fPrivateBits;
+
+    // this is computed from the fP... fields
+    int         fHashIndex;
+
+    friend class GrContext;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrTextureEntry {
+public:
+    GrTexture* texture() const { return fTexture; }
+    const GrTextureKey& key() const { return fKey; }
+
+#if GR_DEBUG
+    GrTextureEntry* next() const { return fNext; }
+    GrTextureEntry* prev() const { return fPrev; }
+#endif
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    GrTextureEntry(const GrTextureKey& key, GrTexture* texture);
+    ~GrTextureEntry();
+
+    bool isLocked() const { return fLockCount != 0; }
+    void lock() { ++fLockCount; }
+    void unlock() {
+        GrAssert(fLockCount > 0);
+        --fLockCount;
+    }
+
+    GrTextureKey    fKey;
+    GrTexture*      fTexture;
+
+    // track if we're in use, used when we need to purge
+    // we only purge unlocked entries
+    int fLockCount;
+
+    // we're a dlinklist
+    GrTextureEntry* fPrev;
+    GrTextureEntry* fNext;
+
+    friend class GrTextureCache;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "GrTHashCache.h"
+
+/**
+ *  Cache of GrTexture objects.
+ *
+ *  These have a corresponding GrTextureKey, built from 96bits identifying the
+ *  texture/bitmap.
+ *
+ *  The cache stores the entries in a double-linked list, which is its LRU.
+ *  When an entry is "locked" (i.e. given to the caller), it is moved to the
+ *  head of the list. If/when we must purge some of the entries, we walk the
+ *  list backwards from the tail, since those are the least recently used.
+ *
+ *  For fast searches, we maintain a sorted array (based on the GrTextureKey)
+ *  which we can bsearch. When a new entry is added, it is inserted into this
+ *  array.
+ *
+ *  For even faster searches, a hash is computed from the Key. If there is
+ *  a collision between two keys with the same hash, we fall back on the
+ *  bsearch, and update the hash to reflect the most recent Key requested.
+ */
+class GrTextureCache {
+public:
+    GrTextureCache(int maxCount, size_t maxBytes);
+    ~GrTextureCache();  // uses kFreeTexture_DeleteMode
+
+    /**
+     *  Return the current texture cache limits.
+     *
+     *  @param maxTextures If non-null, returns maximum number of textures that
+     *                     can be held in the cache.
+     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
+     *                         texture memory that can be held in the cache.
+     */
+    void getLimits(int* maxTextures, size_t* maxTextureBytes) const;
+
+    /**
+     *  Specify the texture cache limits. If the current cache exceeds either
+     *  of these, it will be purged (LRU) to keep the cache within these limits.
+     *
+     *  @param maxTextures The maximum number of textures that can be held in
+     *                     the cache.
+     *  @param maxTextureBytes The maximum number of bytes of texture memory
+     *                         that can be held in the cache.
+     */
+    void setLimits(int maxTextures, size_t maxTextureBytes);
+
+    /**
+     *  Search for an entry with the same Key. If found, "lock" it and return it.
+     *  If not found, return null.
+     */
+    GrTextureEntry* findAndLock(const GrTextureKey&);
+
+    /**
+     *  Create a new entry, based on the specified key and texture, and return
+     *  its "locked" entry.
+     *
+     *  Ownership of the texture is transferred to the Entry, which will unref()
+     *  it when we are purged or deleted.
+     */
+    GrTextureEntry* createAndLock(const GrTextureKey&, GrTexture*);
+
+    /**
+     * Detach removes an entry from the cache. This prevents the entry from
+     * being found by a subsequent findAndLock() until it is reattached. The
+     * entry still counts against the cache's budget and should be reattached
+     * when exclusive access is no longer needed.
+     */
+    void detach(GrTextureEntry*);
+
+    /**
+     * Reattaches a texture to the cache and unlocks it. Allows it to be found
+     * by a subsequent findAndLock or be purged (provided its lock count is
+     * now 0.)
+     */
+    void reattachAndUnlock(GrTextureEntry*);
+
+    /**
+     *  When done with an entry, call unlock(entry) on it, which returns it to
+     *  a purgable state.
+     */
+    void unlock(GrTextureEntry*);
+
+    enum DeleteMode {
+        kFreeTexture_DeleteMode,
+        kAbandonTexture_DeleteMode
+    };
+    void deleteAll(DeleteMode);
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    void internalDetach(GrTextureEntry*, bool);
+    void attachToHead(GrTextureEntry*, bool);
+    void purgeAsNeeded();   // uses kFreeTexture_DeleteMode
+
+    class Key;
+    GrTHashTable<GrTextureEntry, Key, 8> fCache;
+
+    // manage the dlink list
+    GrTextureEntry* fHead;
+    GrTextureEntry* fTail;
+
+    // our budget, used in purgeAsNeeded()
+    int fMaxCount;
+    size_t fMaxBytes;
+
+    // our current stats, related to our budget
+    int fEntryCount;
+    size_t fEntryBytes;
+    int fClientDetachedCount;
+    size_t fClientDetachedBytes;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+    class GrAutoTextureCacheValidate {
+    public:
+        GrAutoTextureCacheValidate(GrTextureCache* cache) : fCache(cache) {
+            cache->validate();
+        }
+        ~GrAutoTextureCacheValidate() {
+            fCache->validate();
+        }
+    private:
+        GrTextureCache* fCache;
+    };
+#else
+    class GrAutoTextureCacheValidate {
+    public:
+        GrAutoTextureCacheValidate(GrTextureCache*) {}
+    };
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTouchGesture.h b/gpu/include/GrTouchGesture.h
new file mode 100644
index 0000000..03f970b
--- /dev/null
+++ b/gpu/include/GrTouchGesture.h
@@ -0,0 +1,56 @@
+#ifndef GrTouchGesture_DEFINED
+#define GrTouchGesture_DEFINED
+
+#include "GrTypes.h"
+#include "SkTDArray.h"
+#include "SkMatrix.h"
+
+#include "FlingState.h"
+
+class GrTouchGesture {
+public:
+    GrTouchGesture();
+    ~GrTouchGesture();
+
+    void touchBegin(void* owner, float x, float y);
+    void touchMoved(void* owner, float x, float y);
+    void touchEnd(void* owner);
+    void reset();
+
+    const SkMatrix& localM();
+    const SkMatrix& globalM() const { return fGlobalM; }
+
+private:
+    enum State {
+        kEmpty_State,
+        kTranslate_State,
+        kZoom_State,
+    };
+
+    struct Rec {
+        void*   fOwner;
+        float   fStartX, fStartY;
+        float   fPrevX, fPrevY;
+        float   fLastX, fLastY;
+        SkMSec  fPrevT, fLastT;
+    };
+    SkTDArray<Rec> fTouches;
+
+    State    fState;
+    SkMatrix fLocalM, fGlobalM;
+    FlingState  fFlinger;
+    SkMSec  fLastUpT;
+    SkPoint fLastUpP;
+
+
+    void flushLocalM();
+    int findRec(void* owner) const;
+    void appendNewRec(void* owner, float x, float y);
+    float computePinch(const Rec&, const Rec&);
+    float limitTotalZoom(float scale) const;
+    bool handleDblTap(float, float);
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
new file mode 100644
index 0000000..cc78c3e
--- /dev/null
+++ b/gpu/include/GrTypes.h
@@ -0,0 +1,338 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTypes_DEFINED
+#define GrTypes_DEFINED
+
+#include "GrConfig.h"
+
+#include <memory.h>
+#include <string.h>
+
+/**
+ *  Macro to round n up to the next multiple of 4, or return it unchanged if
+ *  n is already a multiple of 4
+ */
+#define GrALIGN4(n)     (((n) + 3) >> 2 << 2)
+#define GrIsALIGN4(n)   (((n) & 3) == 0)
+
+template <typename T> const T& GrMin(const T& a, const T& b) {
+	return (a < b) ? a : b;
+}
+
+template <typename T> const T& GrMax(const T& a, const T& b) {
+	return (b < a) ? a : b;
+}
+
+// compile time versions of min/max
+#define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
+#define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
+
+/**
+ *  divide, rounding up
+ */
+static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
+    return (x + (y-1)) / y;
+}
+static inline size_t GrSizeDivRoundUp(size_t x, uint32_t y) {
+    return (x + (y-1)) / y;
+}
+
+/**
+ *  align up
+ */
+static inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
+    return GrUIDivRoundUp(x, alignment) * alignment;
+}
+static inline uint32_t GrSizeAlignUp(size_t x, uint32_t alignment) {
+    return GrSizeDivRoundUp(x, alignment) * alignment;
+}
+
+/**
+ * amount of pad needed to align up
+ */
+static inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
+    return (alignment - x % alignment) % alignment;
+}
+static inline size_t GrSizeAlignUpPad(size_t x, uint32_t alignment) {
+    return (alignment - x % alignment) % alignment;
+}
+
+/**
+ *  align down
+ */
+static inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
+    return (x / alignment) * alignment;
+}
+static inline uint32_t GrSizeAlignDown(size_t x, uint32_t alignment) {
+    return (x / alignment) * alignment;
+}
+
+/**
+ *  Count elements in an array
+ */
+#define GR_ARRAY_COUNT(array)  (sizeof(array) / sizeof(array[0]))
+
+//!< allocate a block of memory, will never return NULL
+extern void* GrMalloc(size_t bytes);
+
+//!< free block allocated by GrMalloc. ptr may be NULL
+extern void GrFree(void* ptr);
+
+static inline void Gr_bzero(void* dst, size_t size) {
+    memset(dst, 0, size);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Return the number of leading zeros in n
+ */
+extern int Gr_clz(uint32_t n);
+
+/**
+ *  Return true if n is a power of 2
+ */
+static inline bool GrIsPow2(unsigned n) {
+    return n && 0 == (n & (n - 1));
+}
+
+/**
+ *  Return the next power of 2 >= n.
+ */
+static inline uint32_t GrNextPow2(uint32_t n) {
+    return n ? (1 << (32 - Gr_clz(n - 1))) : 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  16.16 fixed point type
+ */
+typedef int32_t GrFixed;
+
+#if GR_DEBUG
+
+static inline int16_t GrToS16(intptr_t x) {
+    GrAssert((int16_t)x == x);
+    return (int16_t)x;
+}
+
+#else
+
+#define GrToS16(x)  x
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Use to cast a ptr to a different type, and maintain strict-aliasing
+ */
+template <typename Dst, typename Src> Dst GrTCast(Src src) {
+    union {
+        Src src;
+        Dst dst;
+    } data;
+    data.src = src;
+    return data.dst;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Type used to describe format of vertices in arrays
+ * Values are defined in GrDrawTarget
+ */
+typedef uint16_t GrVertexLayout;
+
+/**
+* Geometric primitives used for drawing.
+*/
+enum GrPrimitiveType {
+    kTriangles_PrimitiveType,
+    kTriangleStrip_PrimitiveType,
+    kTriangleFan_PrimitiveType,
+    kPoints_PrimitiveType,
+    kLines_PrimitiveType,
+    kLineStrip_PrimitiveType
+};
+
+/**
+ * Coeffecients for alpha-blending.
+ */
+enum GrBlendCoeff {
+    kZero_BlendCoeff,    //<! 0
+    kOne_BlendCoeff,     //<! 1
+    kSC_BlendCoeff,      //<! src color
+    kISC_BlendCoeff,     //<! one minus src color
+    kDC_BlendCoeff,      //<! dst color
+    kIDC_BlendCoeff,     //<! one minus dst color
+    kSA_BlendCoeff,      //<! src alpha
+    kISA_BlendCoeff,     //<! one minus src alpha
+    kDA_BlendCoeff,      //<! dst alpha
+    kIDA_BlendCoeff,     //<! one minus dst alpha
+    kConstC_BlendCoeff,  //<! constant color
+    kIConstC_BlendCoeff, //<! one minus constant color
+    kConstA_BlendCoeff,  //<! constant color alpha
+    kIConstA_BlendCoeff, //<! one minus constant color alpha
+
+    kBlendCoeffCount
+};
+
+/**
+ *  Formats for masks, used by the font cache.
+ *  Important that these are 0-based.
+ */
+enum GrMaskFormat {
+    kA8_GrMaskFormat,   //!< 1-byte per pixel
+    kA565_GrMaskFormat  //!< 2-bytes per pixel
+};
+#define kCount_GrMaskFormats    2
+
+/**
+ *  Return the number of bytes-per-pixel for the specified mask format.
+ */
+static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
+    GrAssert((unsigned)format <= 1);
+    return (int)format + 1;
+}
+
+/**
+ * Set Operations used to construct clips.
+ */
+enum GrSetOp {
+    kReplace_SetOp,
+    kIntersect_SetOp,
+    kUnion_SetOp,
+    kXor_SetOp,
+    kDifference_SetOp,
+    kReverseDifference_SetOp,
+};
+
+/**
+ * Clips are composed from these objects.
+ */
+enum GrClipType {
+    kRect_ClipType,
+    kPath_ClipType
+};
+
+/**
+ * Commands used to describe a path. Each command
+ * is accompanied by some number of points.
+ */
+enum GrPathCmd {
+    kMove_PathCmd,      //!< Starts a new subpath at
+                        //   at the returned point
+                        // 1 point
+    kLine_PathCmd,      //!< Adds a line segment
+                        // 2 points
+    kQuadratic_PathCmd, //!< Adds a quadratic segment
+                        // 3 points
+    kCubic_PathCmd,     //!< Adds a cubic segment
+                        // 4 points
+    kClose_PathCmd,     //!< Closes the current subpath
+                        //   by connecting a line to the
+                        //   starting point.
+                        // 0 points
+    kEnd_PathCmd        //!< Indicates the end of the last subpath
+                        //   when iterating
+                        // 0 points.
+};
+
+/**
+ * Gets the number of points associated with a path command.
+ */
+static int inline NumPathCmdPoints(GrPathCmd cmd) {
+    static const int gNumPoints[] = {
+        1, 2, 3, 4, 0, 0
+    };
+    return gNumPoints[cmd];
+}
+
+/**
+ * Path filling rules
+ */
+enum GrPathFill {
+    kWinding_PathFill,
+    kEvenOdd_PathFill,
+    kInverseWinding_PathFill,
+    kInverseEvenOdd_PathFill,
+    kHairLine_PathFill,
+
+    kPathFillCount
+};
+
+static inline GrPathFill NonInvertedFill(GrPathFill fill) {
+    static const GrPathFill gNonInvertedFills[] = {
+        kWinding_PathFill, // kWinding_PathFill
+        kEvenOdd_PathFill, // kEvenOdd_PathFill
+        kWinding_PathFill, // kInverseWinding_PathFill
+        kEvenOdd_PathFill, // kInverseEvenOdd_PathFill
+        kHairLine_PathFill,// kHairLine_PathFill
+    };
+    GR_STATIC_ASSERT(0 == kWinding_PathFill);
+    GR_STATIC_ASSERT(1 == kEvenOdd_PathFill);
+    GR_STATIC_ASSERT(2 == kInverseWinding_PathFill);
+    GR_STATIC_ASSERT(3 == kInverseEvenOdd_PathFill);
+    GR_STATIC_ASSERT(4 == kHairLine_PathFill);
+    GR_STATIC_ASSERT(5 == kPathFillCount);
+    return gNonInvertedFills[fill];
+}
+
+static inline bool IsFillInverted(GrPathFill fill) {
+    static const bool gIsFillInverted[] = {
+        false, // kWinding_PathFill
+        false, // kEvenOdd_PathFill
+        true,  // kInverseWinding_PathFill
+        true,  // kInverseEvenOdd_PathFill
+        false, // kHairLine_PathFill
+    };
+    GR_STATIC_ASSERT(0 == kWinding_PathFill);
+    GR_STATIC_ASSERT(1 == kEvenOdd_PathFill);
+    GR_STATIC_ASSERT(2 == kInverseWinding_PathFill);
+    GR_STATIC_ASSERT(3 == kInverseEvenOdd_PathFill);
+    GR_STATIC_ASSERT(4 == kHairLine_PathFill);
+    GR_STATIC_ASSERT(5 == kPathFillCount);
+    return gIsFillInverted[fill];
+}
+
+/**
+ * Hints provided about a path's convexity (or lack thereof).
+ */
+enum GrConvexHint {
+    kNone_ConvexHint,                         //<! No hint about convexity
+                                              //   of the path
+    kConvex_ConvexHint,                       //<! Path is one convex piece
+    kNonOverlappingConvexPieces_ConvexHint,   //<! Multiple convex pieces,
+                                              //   pieces are known to be
+                                              //   disjoint
+    kSameWindingConvexPieces_ConvexHint,      //<! Multiple convex pieces,
+                                              //   may or may not intersect,
+                                              //   either all wind cw or all
+                                              //   wind ccw.
+    kConcave_ConvexHint                       //<! Path is known to be
+                                              //   concave
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// this is included only to make it easy to use this debugging facility
+#include "GrInstanceCounter.h"
+
+#endif
diff --git a/gpu/include/GrUserConfig.h b/gpu/include/GrUserConfig.h
new file mode 100644
index 0000000..201d836
--- /dev/null
+++ b/gpu/include/GrUserConfig.h
@@ -0,0 +1,90 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrUserConfig_DEFINED
+#define GrUserConfig_DEFINED
+
+#if defined(GR_USER_CONFIG_FILE)
+    #error "default user config pulled in but GR_USER_CONFIG_FILE is defined."
+#endif
+
+#if 0
+    #undef GR_RELEASE
+    #undef GR_DEBUG
+    #define GR_RELEASE  0
+    #define GR_DEBUG    1
+#endif
+
+/*
+ *  The default 32bit pixel config for texture upload is GL_RGBA on all
+ *  platforms except on Windows where it is GL_BGRA. If your bitmaps map to a
+ *  different GL enum, specify that with this define. For portability use
+ *  GR_BGRA rather than GL_BGRA for platforms where this format is an
+ *  extension.
+ */
+//#define GR_GL_32BPP_COLOR_FORMAT  GL_RGBA
+
+/*
+ *  To diagnose texture cache performance, define this to 1 if you want to see
+ *  a log statement everytime we upload an image to create a texture.
+ */
+//#define GR_DUMP_TEXTURE_UPLOAD    1
+
+/*
+ * To log all GL calls define this. Can be turned on and off at runtime by
+ * gPrintGL global variable.
+ */
+//#define GR_GL_LOG_CALLS 1
+
+/*
+ * When drawing rects this causes Ganesh to use a vertex buffer containing
+ * a unit square that is positioned by a matrix. Enable on systems where
+ * emitting per-rect-draw verts is more expensive than constant/matrix
+ * updates. Defaults to 0.
+ */
+//#define GR_STATIC_RECT_VB 1
+
+/*
+ * This causes more aggressive shader optimization. May hurt performance if
+ * switching shaders is expensive.
+ */
+//#define GR_AGGRESSIVE_SHADER_OPTS 1
+
+/*
+ * This gives a threshold in bytes of when to lock a GrGeometryBuffer vs using
+ * updateData or updateSubData. (Note the depending on the underlying 3D API
+ * the update functions may always be implemented using a lock)
+ */
+//#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1<<15)
+
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *  temporary flags (may go away soon)
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+// Decide Ganesh types
+
+#define GR_SCALAR_IS_FIXED          0
+#define GR_SCALAR_IS_FLOAT          1
+
+#define GR_TEXT_SCALAR_IS_USHORT    0
+#define GR_TEXT_SCALAR_IS_FIXED     0
+#define GR_TEXT_SCALAR_IS_FLOAT     1
+
+#endif
+
+
diff --git a/gpu/include/GrVertexBuffer.h b/gpu/include/GrVertexBuffer.h
new file mode 100644
index 0000000..3792c15
--- /dev/null
+++ b/gpu/include/GrVertexBuffer.h
@@ -0,0 +1,31 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrVertexBuffer_DEFINED
+#define GrVertexBuffer_DEFINED
+
+#include "GrGeometryBuffer.h"
+
+class GrVertexBuffer : public GrGeometryBuffer {
+protected:
+    GrVertexBuffer(size_t sizeInBytes, bool dynamic) : 
+        INHERITED(sizeInBytes, dynamic) {}
+private:
+    typedef GrGeometryBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/SkUIView.h b/gpu/include/SkUIView.h
new file mode 100644
index 0000000..5e12e00
--- /dev/null
+++ b/gpu/include/SkUIView.h
@@ -0,0 +1,64 @@
+#import <UIKit/UIKit.h>
+
+#include "SkMatrix.h"
+#include "FlingState.h"
+
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+class SkOSWindow;
+class SkEvent;
+
+@interface SkUIView : UIView <UIAccelerometerDelegate> {
+    BOOL fRedrawRequestPending;
+    SkOSWindow* fWind;
+    SkMatrix    fMatrix, fLocalMatrix;
+    bool        fNeedGestureEnded;
+
+    SkMatrix    fRotateMatrix;
+
+    float       fFirstPinchX, fFirstPinchY;
+    bool        fNeedFirstPinch;
+
+    float       fZoomAroundX, fZoomAroundY;
+    bool        fZoomAround;
+
+    FlingState  fFlingState;
+
+    GrAnimateFloat  fWarpState;
+    bool            fUseWarp;
+
+    struct {
+        EAGLContext*    fContext;
+        GLuint          fRenderbuffer;
+        GLuint          fStencilbuffer;
+        GLuint          fFramebuffer;
+        GLint           fWidth;
+        GLint           fHeight;
+    } fGL;
+    
+    UILabel* fTitleLabel;
+
+    enum Backend {
+        kGL_Backend,
+        kRaster_Backend,
+    };
+
+    // these are visible to DetailViewController
+    Backend fBackend;
+    bool    fComplexClip;
+}
+
+@property (nonatomic, assign) SkOSWindow *fWind;
+@property (nonatomic, retain) UILabel* fTitleLabel;
+@property (nonatomic, assign) Backend fBackend;
+@property (nonatomic, assign) bool fComplexClip;
+@property (nonatomic, assign, setter=setWarpState) bool fUseWarp;
+
+- (void)setSkTitle:(const char*)title;
+- (void)postInvalWithRect:(const SkIRect*)rectOrNil;
+- (BOOL)onHandleEvent:(const SkEvent&)event;
+
+@end
+
diff --git a/gpu/src/FlingState.cpp b/gpu/src/FlingState.cpp
new file mode 100644
index 0000000..cb634cc
--- /dev/null
+++ b/gpu/src/FlingState.cpp
@@ -0,0 +1,134 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "FlingState.h"
+#include "SkMatrix.h"
+#include "SkTime.h"
+
+#define DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER   true
+
+static const float MAX_FLING_SPEED = 1500;
+
+static float pin_max_fling(float speed) {
+    if (speed > MAX_FLING_SPEED) {
+        speed = MAX_FLING_SPEED;
+    }
+    return speed;
+}
+
+static double getseconds() {
+    return SkTime::GetMSecs() * 0.001;
+}
+
+// returns +1 or -1, depending on the sign of x
+// returns +1 if x is zero
+static SkScalar SkScalarSign(SkScalar x) {
+    SkScalar sign = SK_Scalar1;
+    if (x < 0) {
+        sign = -sign;
+    }
+    return sign;
+}
+
+static void unit_axis_align(SkVector* unit) {
+    const SkScalar TOLERANCE = SkDoubleToScalar(0.15);
+    if (SkScalarAbs(unit->fX) < TOLERANCE) {
+        unit->fX = 0;
+        unit->fY = SkScalarSign(unit->fY);
+    } else if (SkScalarAbs(unit->fY) < TOLERANCE) {
+        unit->fX = SkScalarSign(unit->fX);
+        unit->fY = 0;
+    }
+}
+
+void FlingState::reset(float sx, float sy) {
+    fActive = true;
+    fDirection.set(sx, sy);
+    fSpeed0 = SkPoint::Normalize(&fDirection);
+    fSpeed0 = pin_max_fling(fSpeed0);
+    fTime0 = getseconds();
+
+    unit_axis_align(&fDirection);
+//    printf("---- speed %g dir %g %g\n", fSpeed0, fDirection.fX, fDirection.fY);
+}
+
+bool FlingState::evaluateMatrix(SkMatrix* matrix) {
+    if (!fActive) {
+        return false;
+    }
+
+    const float t =  getseconds() - fTime0;
+    const float MIN_SPEED = 2;
+    const float K0 = 5.0;
+    const float K1 = 0.02;
+    const float speed = fSpeed0 * (sk_float_exp(- K0 * t) - K1);
+    if (speed <= MIN_SPEED) {
+        fActive = false;
+        return false;
+    }
+    float dist = (fSpeed0 - speed) / K0;
+
+//    printf("---- time %g speed %g dist %g\n", t, speed, dist);
+    float tx = fDirection.fX * dist;
+    float ty = fDirection.fY * dist;
+    if (DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER) {
+        tx = sk_float_round2int(tx);
+        ty = sk_float_round2int(ty);
+    }
+    matrix->setTranslate(tx, ty);
+//    printf("---- evaluate (%g %g)\n", tx, ty);
+
+    return true;
+}
+
+////////////////////////////////////////
+
+GrAnimateFloat::GrAnimateFloat() : fTime0(0) {}
+
+void GrAnimateFloat::start(float v0, float v1, float duration) {
+    fValue0 = v0;
+    fValue1 = v1;
+    fDuration = duration;
+    if (duration > 0) {
+        fTime0 = SkTime::GetMSecs();
+        if (!fTime0) {
+            fTime0 = 1;  // time0 is our sentinel
+        }
+    } else {
+        fTime0 = 0;
+    }
+}
+
+float GrAnimateFloat::evaluate() {
+    if (!fTime0) {
+        return fValue1;
+    }
+    
+    double elapsed = (SkTime::GetMSecs() - fTime0) * 0.001;
+    if (elapsed >= fDuration) {
+        fTime0 = 0;
+        return fValue1;
+    }
+    
+    double t = elapsed / fDuration;
+    if (true) {
+        t = (3 - 2 * t) * t * t;
+    }
+    return fValue0 + t * (fValue1 - fValue0);
+}
+
+
diff --git a/gpu/src/GrAllocPool.cpp b/gpu/src/GrAllocPool.cpp
new file mode 100644
index 0000000..f133f97
--- /dev/null
+++ b/gpu/src/GrAllocPool.cpp
@@ -0,0 +1,127 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAllocPool.h"
+
+#define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
+
+struct GrAllocPool::Block {
+    Block*  fNext;
+    char*   fPtr;
+    size_t  fBytesFree;
+    size_t  fBytesTotal;
+
+    static Block* Create(size_t size, Block* next) {
+        GrAssert(size >= GrAllocPool_MIN_BLOCK_SIZE);
+
+        Block* block = (Block*)GrMalloc(sizeof(Block) + size);
+        block->fNext = next;
+        block->fPtr = (char*)block + sizeof(Block);
+        block->fBytesFree = size;
+        block->fBytesTotal = size;
+        return block;
+    }
+
+    bool canAlloc(size_t bytes) const {
+        return bytes <= fBytesFree;
+    }
+
+    void* alloc(size_t bytes) {
+        GrAssert(bytes <= fBytesFree);
+        fBytesFree -= bytes;
+        void* ptr = fPtr;
+        fPtr += bytes;
+        return ptr;
+    }
+    
+    size_t release(size_t bytes) {
+        GrAssert(bytes > 0);
+        size_t free = GrMin(bytes, fBytesTotal - fBytesFree);
+        fBytesFree += free;
+        fPtr -= free;
+        return bytes - free;
+    }
+    
+    bool empty() const { return fBytesTotal == fBytesFree; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrAllocPool::GrAllocPool(size_t blockSize) {
+    fBlock = NULL;
+    fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
+    GR_DEBUGCODE(fBlocksAllocated = 0;)
+}
+
+GrAllocPool::~GrAllocPool() {
+    this->reset();
+}
+
+void GrAllocPool::reset() {
+    this->validate();
+
+    Block* block = fBlock;
+    while (block) {
+        Block* next = block->fNext;
+        GrFree(block);
+        block = next;
+    }
+    fBlock = NULL;
+    GR_DEBUGCODE(fBlocksAllocated = 0;)
+}
+
+void* GrAllocPool::alloc(size_t size) {
+    this->validate();
+    
+    if (!fBlock || !fBlock->canAlloc(size)) {
+        size_t blockSize = GrMax(fMinBlockSize, size);
+        fBlock = Block::Create(blockSize, fBlock);
+        GR_DEBUGCODE(fBlocksAllocated += 1;)
+    }
+    return fBlock->alloc(size);
+}
+
+void GrAllocPool::release(size_t bytes) {
+    this->validate();
+    
+    while (bytes && NULL != fBlock) {
+        bytes = fBlock->release(bytes);
+        if (fBlock->empty()) {
+            Block* next = fBlock->fNext;
+            GrFree(fBlock);
+            fBlock = next;
+            GR_DEBUGCODE(fBlocksAllocated -= 1;)
+        }
+    }
+}
+
+
+#if GR_DEBUG
+
+void GrAllocPool::validate() const {
+    Block* block = fBlock;
+    int count = 0;
+    while (block) {
+        count += 1;
+        block = block->fNext;
+    }
+    GrAssert(fBlocksAllocated == count);
+}
+
+#endif
+
+
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
new file mode 100644
index 0000000..ab99d9a
--- /dev/null
+++ b/gpu/src/GrAtlas.cpp
@@ -0,0 +1,218 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAtlas.h"
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrRectanizer.h"
+#include "GrPlotMgr.h"
+
+#if 0
+#define GR_PLOT_WIDTH   8
+#define GR_PLOT_HEIGHT  4
+#define GR_ATLAS_WIDTH  256
+#define GR_ATLAS_HEIGHT 256
+
+#define GR_ATLAS_TEXTURE_WIDTH  (GR_PLOT_WIDTH * GR_ATLAS_WIDTH)
+#define GR_ATLAS_TEXTURE_HEIGHT (GR_PLOT_HEIGHT * GR_ATLAS_HEIGHT)
+
+#else
+
+#define GR_ATLAS_TEXTURE_WIDTH  1024
+#define GR_ATLAS_TEXTURE_HEIGHT 2048
+
+#define GR_ATLAS_WIDTH  341
+#define GR_ATLAS_HEIGHT 341
+
+#define GR_PLOT_WIDTH   (GR_ATLAS_TEXTURE_WIDTH / GR_ATLAS_WIDTH)
+#define GR_PLOT_HEIGHT  (GR_ATLAS_TEXTURE_HEIGHT / GR_ATLAS_HEIGHT)
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define BORDER      1
+
+#if GR_DEBUG
+    static int gCounter;
+#endif
+
+GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) {
+    fAtlasMgr = mgr;    // just a pointer, not an owner
+    fNext = NULL;
+    fTexture = mgr->getTexture(format); // we're not an owner, just a pointer
+    fPlot.set(plotX, plotY);
+
+    fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
+                                   GR_ATLAS_HEIGHT - BORDER);
+
+    fMaskFormat = format;
+
+#if GR_DEBUG
+    GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
+    gCounter += 1;
+#endif
+}
+
+GrAtlas::~GrAtlas() {
+    fAtlasMgr->freePlot(fPlot.fX, fPlot.fY);
+
+    delete fRects;
+
+#if GR_DEBUG
+    --gCounter;
+    GrPrintf("~GrAtlas %p [%d %d] %d\n", this, fPlot.fX, fPlot.fY, gCounter);
+#endif
+}
+
+static void adjustForPlot(GrIPoint16* loc, const GrIPoint16& plot) {
+    loc->fX += plot.fX * GR_ATLAS_WIDTH;
+    loc->fY += plot.fY * GR_ATLAS_HEIGHT;
+}
+
+static uint8_t* zerofill(uint8_t* ptr, int count) {
+    while (--count >= 0) {
+        *ptr++ = 0;
+    }
+    return ptr;
+}
+
+bool GrAtlas::addSubImage(int width, int height, const void* image,
+                          GrIPoint16* loc) {
+    if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
+        return false;
+    }
+
+    GrAutoSMalloc<1024> storage;
+    int dstW = width + 2*BORDER;
+    int dstH = height + 2*BORDER;
+    if (BORDER) {
+        const int bpp = GrMaskFormatBytesPerPixel(fMaskFormat);
+        const size_t dstRB = dstW * bpp;
+        uint8_t* dst = (uint8_t*)storage.realloc(dstH * dstRB);
+        Gr_bzero(dst, dstRB);                // zero top row
+        dst += dstRB;
+        for (int y = 0; y < height; y++) {
+            dst = zerofill(dst, bpp);   // zero left edge
+            memcpy(dst, image, width * bpp);
+            dst += width * bpp;
+            dst = zerofill(dst, bpp);   // zero right edge
+            image = (const void*)((const char*)image + width * bpp);
+        }
+        Gr_bzero(dst, dstRB);                // zero bottom row
+        image = storage.get();
+    }
+    adjustForPlot(loc, fPlot);
+    fTexture->uploadTextureData(loc->fX, loc->fY, dstW, dstH, image);
+
+    // now tell the caller to skip the top/left BORDER
+    loc->fX += BORDER;
+    loc->fY += BORDER;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrAtlasMgr::GrAtlasMgr(GrGpu* gpu) {
+    fGpu = gpu;
+    gpu->ref();
+    Gr_bzero(fTexture, sizeof(fTexture));
+    fPlotMgr = new GrPlotMgr(GR_PLOT_WIDTH, GR_PLOT_HEIGHT);
+}
+
+GrAtlasMgr::~GrAtlasMgr() {
+    for (size_t i = 0; i < GR_ARRAY_COUNT(fTexture); i++) {
+        GrSafeUnref(fTexture[i]);
+    }
+    delete fPlotMgr;
+    fGpu->unref();
+}
+
+static GrTexture::PixelConfig maskformat2pixelconfig(GrMaskFormat format) {
+    switch (format) {
+        case kA8_GrMaskFormat:
+            return GrTexture::kAlpha_8_PixelConfig;
+        case kA565_GrMaskFormat:
+            return GrTexture::kRGB_565_PixelConfig;
+        default:
+            GrAssert(!"unknown maskformat");
+    }
+    return GrTexture::kUnknown_PixelConfig;
+}
+
+GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
+                                int width, int height, const void* image,
+                                GrMaskFormat format,
+                                GrIPoint16* loc) {
+    GrAssert(NULL == atlas || atlas->getMaskFormat() == format);
+
+    if (atlas && atlas->addSubImage(width, height, image, loc)) {
+        return atlas;
+    }
+
+    // If the above fails, then either we have no starting atlas, or the current
+    // one is full. Either way we need to allocate a new atlas
+
+    GrIPoint16 plot;
+    if (!fPlotMgr->newPlot(&plot)) {
+        return NULL;
+    }
+
+    GrAssert(0 == kA8_GrMaskFormat);
+    GrAssert(1 == kA565_GrMaskFormat);
+    if (NULL == fTexture[format]) {
+        GrGpu::TextureDesc desc = {
+            GrGpu::kDynamicUpdate_TextureFlag,
+            GrGpu::kNone_AALevel,
+            GR_ATLAS_TEXTURE_WIDTH,
+            GR_ATLAS_TEXTURE_HEIGHT,
+            maskformat2pixelconfig(format)
+        };
+        fTexture[format] = fGpu->createTexture(desc, NULL, 0);
+        if (NULL == fTexture[format]) {
+            return NULL;
+        }
+    }
+
+    GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY, format);
+    if (!newAtlas->addSubImage(width, height, image, loc)) {
+        delete newAtlas;
+        return NULL;
+    }
+
+    newAtlas->fNext = atlas;
+    return newAtlas;
+}
+
+void GrAtlasMgr::freePlot(int x, int y) {
+    GrAssert(fPlotMgr->isBusy(x, y));
+    fPlotMgr->freePlot(x, y);
+}
+
+void GrAtlasMgr::abandonAll() {
+#if 0
+    GrAtlas** curr = fList.begin();
+    GrAtlas** stop = fList.end();
+    for (; curr < stop; curr++) {
+        (*curr)->texture()->abandon();
+        delete *curr;
+    }
+    fList.reset();
+#endif
+}
+
+
diff --git a/gpu/src/GrBufferAllocPool.cpp b/gpu/src/GrBufferAllocPool.cpp
new file mode 100644
index 0000000..35f0c5e
--- /dev/null
+++ b/gpu/src/GrBufferAllocPool.cpp
@@ -0,0 +1,430 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrBufferAllocPool.h"
+#include "GrTypes.h"
+#include "GrVertexBuffer.h"
+#include "GrIndexBuffer.h"
+#include "GrGpu.h"
+
+#if GR_DEBUG
+    #define VALIDATE validate
+#else
+    #define VALIDATE()
+#endif
+
+#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
+
+GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
+                                     BufferType bufferType,
+                                     bool frequentResetHint,
+                                     size_t blockSize,
+                                     int preallocBufferCnt) :
+        fBlocks(GrMax(8, 2*preallocBufferCnt)) {
+    GrAssert(NULL != gpu);
+    fGpu = gpu;
+    fBufferType = bufferType;
+    fFrequentResetHint = frequentResetHint;
+    fGpu->ref();
+    fBufferPtr = NULL;
+    fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
+
+    fPreallocBuffersInUse = 0;
+    fFirstPreallocBuffer = 0;
+    for (int i = 0; i < preallocBufferCnt; ++i) {
+        GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
+        if (NULL != buffer) {
+            *fPreallocBuffers.append() = buffer;
+            buffer->ref();
+        }
+    }
+}
+
+GrBufferAllocPool::~GrBufferAllocPool() {
+    VALIDATE();
+    if (fBlocks.count()) {
+        GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
+        if (buffer->isLocked()) {
+            buffer->unlock();
+        }
+    }
+    fPreallocBuffers.unrefAll();
+    while (!fBlocks.empty()) {
+        destroyBlock();
+    }
+    fGpu->unref();
+}
+
+void GrBufferAllocPool::reset() {
+    VALIDATE();
+    if (fBlocks.count()) {
+        GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
+        if (buffer->isLocked()) {
+            buffer->unlock();
+        }
+    }
+    while (!fBlocks.empty()) {
+        destroyBlock();
+    }
+    if (fPreallocBuffers.count()) {
+        // must set this after above loop.
+        fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) %
+                               fPreallocBuffers.count();
+    }
+    fCpuData.realloc(fGpu->supportsBufferLocking() ? 0 : fMinBlockSize);
+    GrAssert(0 == fPreallocBuffersInUse);
+    VALIDATE();
+}
+
+void GrBufferAllocPool::unlock() {
+    VALIDATE();
+
+    if (NULL != fBufferPtr) {
+        BufferBlock& block = fBlocks.back();
+        if (block.fBuffer->isLocked()) {
+            block.fBuffer->unlock();
+        } else {
+            size_t flushSize = block.fBuffer->size() - block.fBytesFree;
+            flushCpuData(fBlocks.back().fBuffer, flushSize);
+        }
+        fBufferPtr = NULL;
+    }
+    VALIDATE();
+}
+
+#if GR_DEBUG
+void GrBufferAllocPool::validate() const {
+    if (NULL != fBufferPtr) {
+        GrAssert(!fBlocks.empty());
+        if (fBlocks.back().fBuffer->isLocked()) {
+            GrGeometryBuffer* buf = fBlocks.back().fBuffer;
+            GrAssert(buf->lockPtr() == fBufferPtr);
+        } else {
+            GrAssert(fCpuData.get() == fBufferPtr);
+            GrAssert(fCpuData.size() == fBlocks.back().fBuffer->size());
+        }
+    } else {
+        GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
+    }
+    for (int i = 0; i < fBlocks.count() - 1; ++i) {
+        GrAssert(!fBlocks[i].fBuffer->isLocked());
+    }
+}
+#endif
+
+void* GrBufferAllocPool::makeSpace(size_t size,
+                                   size_t alignment,
+                                   const GrGeometryBuffer** buffer,
+                                   size_t* offset) {
+    VALIDATE();
+
+    GrAssert(NULL != buffer);
+    GrAssert(NULL != offset);
+
+    if (NULL != fBufferPtr) {
+        BufferBlock& back = fBlocks.back();
+        size_t usedBytes = back.fBuffer->size() - back.fBytesFree;
+        size_t pad = GrSizeAlignUpPad(usedBytes,
+                                      alignment);
+        if ((size + pad) <= back.fBytesFree) {
+            usedBytes += pad;
+            *offset = usedBytes;
+            *buffer = back.fBuffer;
+            back.fBytesFree -= size + pad;
+            return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
+        }
+    }
+
+    if (!createBlock(size)) {
+        return NULL;
+    }
+    VALIDATE();
+    GrAssert(NULL != fBufferPtr);
+
+    *offset = 0;
+    BufferBlock& back = fBlocks.back();
+    *buffer = back.fBuffer;
+    back.fBytesFree -= size;
+    return fBufferPtr;
+}
+
+int GrBufferAllocPool::currentBufferItems(size_t itemSize) const {
+    VALIDATE();
+    if (NULL != fBufferPtr) {
+        const BufferBlock& back = fBlocks.back();
+        size_t usedBytes = back.fBuffer->size() - back.fBytesFree;
+        size_t pad = GrSizeAlignUpPad(usedBytes, itemSize);
+        return (back.fBytesFree - pad) / itemSize;
+    } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
+        return fMinBlockSize / itemSize;
+    }
+    return 0;
+}
+
+int GrBufferAllocPool::preallocatedBuffersRemaining() const {
+    return fPreallocBuffers.count() - fPreallocBuffersInUse;
+}
+
+int GrBufferAllocPool::preallocatedBufferCount() const {
+    return fPreallocBuffers.count();
+}
+
+void GrBufferAllocPool::putBack(size_t bytes) {
+    VALIDATE();
+    if (NULL != fBufferPtr) {
+        BufferBlock& back = fBlocks.back();
+        size_t bytesUsed = back.fBuffer->size() - back.fBytesFree;
+        if (bytes >= bytesUsed) {
+            destroyBlock();
+            bytes -= bytesUsed;
+        } else {
+            back.fBytesFree += bytes;
+            return;
+        }
+    }
+    VALIDATE();
+    GrAssert(NULL == fBufferPtr);
+    // we don't partially roll-back buffers because our VB semantics say locking
+    // a VB discards its previous content.
+    // We could honor it by being sure we use updateSubData and not lock
+    // we will roll-back fully released buffers, though.
+    while (!fBlocks.empty() &&
+           bytes >= fBlocks.back().fBuffer->size()) {
+        bytes -= fBlocks.back().fBuffer->size();
+        destroyBlock();
+    }
+    VALIDATE();
+}
+
+bool GrBufferAllocPool::createBlock(size_t requestSize) {
+
+    size_t size = GrMax(requestSize, fMinBlockSize);
+    GrAssert(size >= GrBufferAllocPool_MIN_BLOCK_SIZE);
+
+    VALIDATE();
+
+    BufferBlock& block = fBlocks.push_back();
+
+    if (size == fMinBlockSize &&
+        fPreallocBuffersInUse < fPreallocBuffers.count()) {
+
+        uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) %
+                               fPreallocBuffers.count();
+        block.fBuffer = fPreallocBuffers[nextBuffer];
+        block.fBuffer->ref();
+        ++fPreallocBuffersInUse;
+    } else {
+        block.fBuffer = this->createBuffer(size);
+        if (NULL == block.fBuffer) {
+            fBlocks.pop_back();
+            return false;
+        }
+    }
+
+    block.fBytesFree = size;
+    if (NULL != fBufferPtr) {
+        GrAssert(fBlocks.count() > 1);
+        BufferBlock& prev = fBlocks.fromBack(1);
+        if (prev.fBuffer->isLocked()) {
+            prev.fBuffer->unlock();
+        } else {
+            flushCpuData(prev.fBuffer,
+                         prev.fBuffer->size() - prev.fBytesFree);
+        }
+        fBufferPtr = NULL;
+    }
+
+    GrAssert(NULL == fBufferPtr);
+
+    if (fGpu->supportsBufferLocking() &&
+        size > GR_GEOM_BUFFER_LOCK_THRESHOLD &&
+        (!fFrequentResetHint || requestSize > GR_GEOM_BUFFER_LOCK_THRESHOLD)) {
+        fBufferPtr = block.fBuffer->lock();
+    }
+
+    if (NULL == fBufferPtr) {
+        fBufferPtr = fCpuData.realloc(size);
+    }
+
+    VALIDATE();
+
+    return true;
+}
+
+void GrBufferAllocPool::destroyBlock() {
+    GrAssert(!fBlocks.empty());
+
+    BufferBlock& block = fBlocks.back();
+    if (fPreallocBuffersInUse > 0) {
+        uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
+                                       fFirstPreallocBuffer +
+                                       (fPreallocBuffers.count() - 1)) %
+                                      fPreallocBuffers.count();
+        if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {
+            --fPreallocBuffersInUse;
+        }
+    }
+    GrAssert(!block.fBuffer->isLocked());
+    block.fBuffer->unref();
+    fBlocks.pop_back();
+    fBufferPtr = NULL;
+}
+
+void GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer,
+                                     size_t flushSize) {
+    GrAssert(NULL != buffer);
+    GrAssert(!buffer->isLocked());
+    GrAssert(fCpuData.get() == fBufferPtr);
+    GrAssert(fCpuData.size() == buffer->size());
+    GrAssert(flushSize <= buffer->size());
+
+    bool updated = false;
+    if (fGpu->supportsBufferLocking() &&
+        flushSize > GR_GEOM_BUFFER_LOCK_THRESHOLD) {
+        void* data = buffer->lock();
+        if (NULL != data) {
+            memcpy(data, fBufferPtr, flushSize);
+            buffer->unlock();
+            updated = true;
+        }
+    }
+    buffer->updateData(fBufferPtr, flushSize);
+}
+
+GrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) {
+    if (kIndex_BufferType == fBufferType) {
+        return fGpu->createIndexBuffer(size, true);
+    } else {
+        GrAssert(kVertex_BufferType == fBufferType);
+        return fGpu->createVertexBuffer(size, true);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
+                                                 bool frequentResetHint,
+                                                 size_t bufferSize,
+                                                 int preallocBufferCnt)
+: GrBufferAllocPool(gpu,
+                    kVertex_BufferType,
+                    frequentResetHint,
+                    bufferSize,
+                    preallocBufferCnt) {
+}
+
+void* GrVertexBufferAllocPool::makeSpace(GrVertexLayout layout,
+                                         int vertexCount,
+                                         const GrVertexBuffer** buffer,
+                                         int* startVertex) {
+
+    GrAssert(vertexCount >= 0);
+    GrAssert(NULL != buffer);
+    GrAssert(NULL != startVertex);
+
+    size_t vSize = GrDrawTarget::VertexSize(layout);
+    size_t offset;
+    const GrGeometryBuffer* geomBuffer;
+    void* ptr = INHERITED::makeSpace(vSize * vertexCount,
+                                     vSize,
+                                     &geomBuffer,
+                                     &offset);
+
+    *buffer = (const GrVertexBuffer*) geomBuffer;
+    GrAssert(0 == offset % vSize);
+    *startVertex = offset / vSize;
+    return ptr;
+}
+
+bool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout,
+                                             int vertexCount,
+                                             const void* vertices,
+                                             const GrVertexBuffer** buffer,
+                                             int* startVertex) {
+    void* space = makeSpace(layout, vertexCount, buffer, startVertex);
+    if (NULL != space) {
+        memcpy(space,
+               vertices,
+               GrDrawTarget::VertexSize(layout) * vertexCount);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
+    return INHERITED::preallocatedBufferSize() /
+            GrDrawTarget::VertexSize(layout);
+}
+
+int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
+    return currentBufferItems(GrDrawTarget::VertexSize(layout));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu,
+                                               bool frequentResetHint,
+                                               size_t bufferSize,
+                                               int preallocBufferCnt)
+: GrBufferAllocPool(gpu,
+                    kIndex_BufferType,
+                    frequentResetHint,
+                    bufferSize,
+                    preallocBufferCnt) {
+}
+
+void* GrIndexBufferAllocPool::makeSpace(int indexCount,
+                                        const GrIndexBuffer** buffer,
+                                        int* startIndex) {
+
+    GrAssert(indexCount >= 0);
+    GrAssert(NULL != buffer);
+    GrAssert(NULL != startIndex);
+
+    size_t offset;
+    const GrGeometryBuffer* geomBuffer;
+    void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
+                                     sizeof(uint16_t),
+                                     &geomBuffer,
+                                     &offset);
+
+    *buffer = (const GrIndexBuffer*) geomBuffer;
+    GrAssert(0 == offset % sizeof(uint16_t));
+    *startIndex = offset / sizeof(uint16_t);
+    return ptr;
+}
+
+bool GrIndexBufferAllocPool::appendIndices(int indexCount,
+                                           const void* indices,
+                                           const GrIndexBuffer** buffer,
+                                           int* startIndex) {
+    void* space = makeSpace(indexCount, buffer, startIndex);
+    if (NULL != space) {
+        memcpy(space, indices, sizeof(uint16_t) * indexCount);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+int GrIndexBufferAllocPool::preallocatedBufferIndices() const {
+    return INHERITED::preallocatedBufferSize() / sizeof(uint16_t);
+}
+
+int GrIndexBufferAllocPool::currentBufferIndices() const {
+    return currentBufferItems(sizeof(uint16_t));
+}
diff --git a/gpu/src/GrBufferAllocPool.h b/gpu/src/GrBufferAllocPool.h
new file mode 100644
index 0000000..80f16ab
--- /dev/null
+++ b/gpu/src/GrBufferAllocPool.h
@@ -0,0 +1,349 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrBufferAllocPool_DEFINED
+#define GrBufferAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+#include "GrTDArray.h"
+#include "GrTArray.h"
+#include "GrMemory.h"
+
+class GrGeometryBuffer;
+class GrGpu;
+
+/**
+ * A pool of geometry buffers tied to a GrGpu.
+ *
+ * The pool allows a client to make space for geometry and then put back excess
+ * space if it over allocated. When a client is ready to draw from the pool
+ * it calls unlock on the pool ensure buffers are ready for drawing. The pool
+ * can be reset after drawing is completed to recycle space.
+ *
+ * At creation time a minimum per-buffer size can be specified. Additionally,
+ * a number of buffers to preallocate can be specified. These will
+ * be allocated at the min size and kept around until the pool is destroyed.
+ */
+class GrBufferAllocPool : GrNoncopyable {
+protected:
+
+    // We could make the createBuffer a virtual except that we want to use it
+    // in the cons for pre-allocated buffers.
+    enum BufferType {
+        kVertex_BufferType,
+        kIndex_BufferType,
+    };
+
+    /**
+     * Constructor
+     *
+     * @param gpu                   The GrGpu used to create the buffers.
+     * @param bufferType            The type of buffers to create.
+     * @param frequentResetHint     A hint that indicates that the pool
+     *                              should expect frequent unlock() calls
+     *                              (as opposed to many makeSpace / acquires
+     *                              between resets).
+     * @param bufferSize            The minimum size of created buffers.
+     *                              This value will be clamped to some
+     *                              reasonable minimum.
+     * @param preallocBufferCnt     The pool will allocate this number of
+     *                              buffers at bufferSize and keep them until it
+     *                              is destroyed.
+     */
+     GrBufferAllocPool(GrGpu* gpu,
+                       BufferType bufferType,
+                       bool frequentResetHint,
+                       size_t   bufferSize = 0,
+                       int preallocBufferCnt = 0);
+
+    virtual ~GrBufferAllocPool();
+
+public:
+    /**
+     * Ensures all buffers are unlocked and have all data written to them.
+     * Call before drawing using buffers from the pool.
+     */
+    void unlock();
+
+    /**
+     *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
+     */
+    void reset();
+
+    /**
+     * Gets the number of preallocated buffers that are yet to be used.
+     */
+    int preallocatedBuffersRemaining() const;
+
+    /**
+     * gets the number of preallocated buffers
+     */
+    int preallocatedBufferCount() const;
+
+
+    /**
+     * Frees data from makeSpaces in LIFO order.
+     */
+    void putBack(size_t bytes);
+
+    /**
+     * Gets the GrGpu that this pool is associated with.
+     */
+    GrGpu* getGpu() { return fGpu; }
+
+protected:
+    /**
+     * Gets the size of the preallocated buffers.
+     *
+     * @return the size of preallocated buffers.
+     */
+    size_t preallocatedBufferSize() const {
+        return fPreallocBuffers.count() ? fMinBlockSize : 0;
+    }
+
+    /**
+     * Returns a block of memory to hold data. A buffer designated to hold the
+     * data is given to the caller. The buffer may or may not be locked. The
+     * returned ptr remains valid until any of the following:
+     *      *makeSpace is called again.
+     *      *unlock is called.
+     *      *reset is called.
+     *      *this object is destroyed.
+     *
+     * Once unlock on the pool is called the data is guaranteed to be in the
+     * buffer at the offset indicated by offset. Until that time it may be
+     * in temporary storage and/or the buffer may be locked.
+     *
+     * @param size         the amount of data to make space for
+     * @param alignment    alignment constraint from start of buffer
+     * @param buffer       returns the buffer that will hold the data.
+     * @param offset       returns the offset into buffer of the data.
+     * @return pointer to where the client should write the data.
+     */
+    void* makeSpace(size_t size,
+                    size_t alignment,
+                    const GrGeometryBuffer** buffer,
+                    size_t* offset);
+
+    /**
+     * Gets the number of items of a size that can be added to the current
+     * buffer without spilling to another buffer. If the pool has been reset, or
+     * the previous makeSpace completely exhausted a buffer then the returned
+     * size will be the size of the next available preallocated buffer, or zero
+     * if no preallocated buffer remains available. It is assumed that items
+     * should be itemSize-aligned from the start of a buffer.
+     *
+     * @return the number of items that would fit in the current buffer.
+     */
+    int currentBufferItems(size_t itemSize) const;
+
+    GrGeometryBuffer* createBuffer(size_t size);
+
+private:
+
+    struct BufferBlock {
+        size_t              fBytesFree;
+        GrGeometryBuffer*   fBuffer;
+    };
+
+    bool createBlock(size_t requestSize);
+    void destroyBlock();
+    void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
+#if GR_DEBUG
+    void validate() const;
+#endif
+
+    GrGpu*                          fGpu;
+    bool                            fFrequentResetHint;
+    GrTDArray<GrGeometryBuffer*>    fPreallocBuffers;
+    size_t                          fMinBlockSize;
+    BufferType                      fBufferType;
+
+    GrTArray<BufferBlock>           fBlocks;
+    int                             fPreallocBuffersInUse;
+    int                             fFirstPreallocBuffer;
+    GrAutoMalloc                    fCpuData;
+    void*                       	fBufferPtr;
+};
+
+class GrVertexBuffer;
+
+/**
+ * A GrBufferAllocPool of vertex buffers
+ */
+class GrVertexBufferAllocPool : public GrBufferAllocPool {
+public:
+    /**
+     * Constructor
+     *
+     * @param gpu                   The GrGpu used to create the vertex buffers.
+     * @param frequentResetHint     A hint that indicates that the pool
+     *                              should expect frequent unlock() calls
+     *                              (as opposed to many makeSpace / acquires
+     *                              between resets).
+     * @param bufferSize            The minimum size of created VBs This value
+     *                              will be clamped to some reasonable minimum.
+     * @param preallocBufferCnt     The pool will allocate this number of VBs at
+     *                              bufferSize and keep them until it is
+     *                              destroyed.
+     */
+    GrVertexBufferAllocPool(GrGpu* gpu,
+                            bool frequentResetHint,
+                            size_t bufferSize = 0,
+                            int preallocBufferCnt = 0);
+
+    /**
+     * Returns a block of memory to hold vertices. A buffer designated to hold
+     * the vertices given to the caller. The buffer may or may not be locked.
+     * The returned ptr remains valid until any of the following:
+     *      *makeSpace is called again.
+     *      *unlock is called.
+     *      *reset is called.
+     *      *this object is destroyed.
+     *
+     * Once unlock on the pool is called the vertices are guaranteed to be in
+     * the buffer at the offset indicated by startVertex. Until that time they
+     * may be in temporary storage and/or the buffer may be locked.
+     *
+     * @param layout       specifies type of vertices to allocate space for
+     * @param vertexCount  number of vertices to allocate space for
+     * @param buffer       returns the vertex buffer that will hold the
+     *                     vertices.
+     * @param startVertex  returns the offset into buffer of the first vertex.
+     *                     In units of the size of a vertex from layout param.
+     * @return pointer to first vertex.
+     */
+    void* makeSpace(GrVertexLayout layout,
+                    int vertexCount,
+                    const GrVertexBuffer** buffer,
+                    int* startVertex);
+
+    /**
+     * Shortcut to make space and then write verts into the made space.
+     */
+    bool appendVertices(GrVertexLayout layout,
+                        int vertexCount,
+                        const void* vertices,
+                        const GrVertexBuffer** buffer,
+                        int* startVertex);
+
+    /**
+     * Gets the number of vertices that can be added to the current VB without
+     * spilling to another VB. If the pool has been reset, or the previous
+     * makeSpace completely exhausted a VB then the returned number of vertices
+     * would fit in the next available preallocated buffer. If any makeSpace
+     * would force a new VB to be created the return value will be zero.
+     *
+     * @param   the format of vertices to compute space for.
+     * @return the number of vertices that would fit in the current buffer.
+     */
+    int currentBufferVertices(GrVertexLayout layout) const;
+
+    /**
+     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
+     * Zero if no preallocated buffers.
+     *
+     * @param   the format of vertices to compute space for.
+     *
+     * @return number of vertices that fit in one of the preallocated vertex
+     *         buffers.
+     */
+    int preallocatedBufferVertices(GrVertexLayout layout) const;
+
+private:
+    typedef GrBufferAllocPool INHERITED;
+};
+
+class GrIndexBuffer;
+
+/**
+ * A GrBufferAllocPool of index buffers
+ */
+class GrIndexBufferAllocPool : public GrBufferAllocPool {
+public:
+    /**
+     * Constructor
+     *
+     * @param gpu                   The GrGpu used to create the index buffers.
+     * @param frequentResetHint     A hint that indicates that the pool
+     *                              should expect frequent unlock() calls
+     *                              (as opposed to many makeSpace / acquires
+     *                              between resets).
+     * @param bufferSize            The minimum size of created IBs This value
+     *                              will be clamped to some reasonable minimum.
+     * @param preallocBufferCnt     The pool will allocate this number of VBs at
+     *                              bufferSize and keep them until it is
+     *                              destroyed.
+     */
+    GrIndexBufferAllocPool(GrGpu* gpu,
+                           bool frequentResetHint,
+                           size_t bufferSize = 0,
+                           int preallocBufferCnt = 0);
+
+    /**
+     * Returns a block of memory to hold indices. A buffer designated to hold
+     * the indices is given to the caller. The buffer may or may not be locked.
+     * The returned ptr remains valid until any of the following:
+     *      *makeSpace is called again.
+     *      *unlock is called.
+     *      *reset is called.
+     *      *this object is destroyed.
+     *
+     * Once unlock on the pool is called the indices are guaranteed to be in the
+     * buffer at the offset indicated by startIndex. Until that time they may be
+     * in temporary storage and/or the buffer may be locked.
+     *
+     * @param indexCount   number of indices to allocate space for
+     * @param buffer       returns the index buffer that will hold the indices.
+     * @param startIndex   returns the offset into buffer of the first index.
+     * @return pointer to first index.
+     */
+    void* makeSpace(int indexCount,
+                    const GrIndexBuffer** buffer,
+                    int* startIndex);
+
+    /**
+     * Shortcut to make space and then write indices into the made space.
+     */
+    bool appendIndices(int indexCount,
+                       const void* indices,
+                       const GrIndexBuffer** buffer,
+                       int* startIndex);
+
+    /**
+     * Gets the number of indices that can be added to the current IB without
+     * spilling to another IB. If the pool has been reset, or the previous
+     * makeSpace completely exhausted a IB then the returned number of indices
+     * would fit in the next available preallocated buffer. If any makeSpace
+     * would force a new IB to be created the return value will be zero.
+     */
+    int currentBufferIndices() const;
+
+    /**
+     * Gets the number of indices that can fit in a preallocated index buffer.
+     * Zero if no preallocated buffers.
+     *
+     * @return number of indices that fit in one of the preallocated index
+     *         buffers.
+     */
+    int preallocatedBufferIndices() const;
+
+private:
+    typedef GrBufferAllocPool INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrClip.cpp b/gpu/src/GrClip.cpp
new file mode 100644
index 0000000..e8da3d1
--- /dev/null
+++ b/gpu/src/GrClip.cpp
@@ -0,0 +1,153 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrClip.h"
+
+GrClip::GrClip()
+    : fList(fListMemory, kPreAllocElements) {
+    fConservativeBounds.setEmpty();
+    fConservativeBoundsValid = true;
+}
+
+GrClip::GrClip(const GrClip& src)
+    : fList(fListMemory, kPreAllocElements) {
+    *this = src;
+}
+
+GrClip::GrClip(const GrIRect& rect)
+    : fList(fListMemory, kPreAllocElements) {
+    this->setFromIRect(rect);
+}
+
+GrClip::GrClip(const GrRect& rect)
+    : fList(fListMemory, kPreAllocElements) {
+    this->setFromRect(rect);
+}
+
+GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+               const GrRect* bounds)
+    : fList(fListMemory, kPreAllocElements) {
+    this->setFromIterator(iter, tx, ty, bounds);
+}
+
+GrClip::~GrClip() {}
+
+GrClip& GrClip::operator=(const GrClip& src) {
+    fList = src.fList;
+    fConservativeBounds = src.fConservativeBounds;
+    fConservativeBoundsValid = src.fConservativeBoundsValid;
+    return *this;
+}
+
+void GrClip::setEmpty() {
+    fList.reset();
+    fConservativeBounds.setEmpty();
+    fConservativeBoundsValid = true;
+}
+
+void GrClip::setFromRect(const GrRect& r) {
+    fList.reset();
+    if (r.isEmpty()) {
+        // use a canonical empty rect for == testing.
+        setEmpty();
+    } else {
+        fList.push_back();
+        fList.back().fRect = r;
+        fList.back().fType = kRect_ClipType;
+        fConservativeBounds = r;
+        fConservativeBoundsValid = true;
+    }
+}
+
+void GrClip::setFromIRect(const GrIRect& r) {
+    fList.reset();
+    if (r.isEmpty()) {
+        // use a canonical empty rect for == testing.
+        setEmpty();
+    } else {
+        fList.push_back();
+        fList.back().fRect.set(r);
+        fList.back().fType = kRect_ClipType;
+        fConservativeBounds.set(r);
+        fConservativeBoundsValid = true;
+    }
+}
+
+void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
+                             const GrRect* conservativeBounds) {
+    fList.reset();
+
+    int rectCount = 0;
+
+    // compute bounds for common case of series of intersecting rects.
+    bool isectRectValid = true;
+
+    if (iter) {
+        for (iter->rewind(); !iter->isDone(); iter->next()) {
+            Element& e = fList.push_back();
+            e.fType = iter->getType();
+            e.fOp = iter->getOp();
+            // iterators should not emit replace
+            GrAssert(kReplace_SetOp != e.fOp);
+            switch (e.fType) {
+                case kRect_ClipType:
+                    iter->getRect(&e.fRect);
+                    if (tx || ty) {
+                        e.fRect.offset(tx, ty);
+                    }
+                    ++rectCount;
+                    if (isectRectValid) {
+                        if (1 == rectCount || kIntersect_SetOp == e.fOp) {
+                            GrAssert(fList.count() <= 2);
+                            if (fList.count() > 1) {
+                                GrAssert(2 == rectCount);
+                                rectCount = 1;
+                                fList.pop_back();
+                                GrAssert(kRect_ClipType == fList.back().fType);
+                                fList.back().fRect.intersectWith(e.fRect);
+                            }
+                        } else {
+                            isectRectValid = false;
+                        }
+                    }
+                    break;
+                case kPath_ClipType:
+                    e.fPath.resetFromIter(iter->getPathIter());
+                    if (tx || ty) {
+                        e.fPath.offset(tx, ty);
+                    }
+                    e.fPathFill = iter->getPathFill();
+                    isectRectValid = false;
+                    break;
+                default:
+                    GrCrash("Unknown clip element type.");
+            }
+        }
+    }
+    fConservativeBoundsValid = false;
+    if (isectRectValid) {
+        fConservativeBoundsValid = true;
+        if (rectCount > 0) {
+            fConservativeBounds = fList[0].fRect;
+        } else {
+            fConservativeBounds.setEmpty();
+        }
+    } else if (NULL != conservativeBounds) {
+        fConservativeBounds = *conservativeBounds;
+        fConservativeBoundsValid = true;
+    }
+}
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
new file mode 100644
index 0000000..cf51cc9
--- /dev/null
+++ b/gpu/src/GrContext.cpp
@@ -0,0 +1,810 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrContext.h"
+#include "GrTypes.h"
+#include "GrTextureCache.h"
+#include "GrTextStrike.h"
+#include "GrMemory.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+#include "GrInOrderDrawBuffer.h"
+#include "GrBufferAllocPool.h"
+#include "GrPathRenderer.h"
+
+#define DEFER_TEXT_RENDERING 1
+
+#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
+
+static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
+static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
+
+static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
+static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
+
+// We are currently only batching Text and drawRectToRect, both
+// of which use the quad index buffer.
+static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
+static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
+
+GrContext* GrContext::Create(GrGpu::Engine engine,
+                             GrGpu::Platform3DContext context3D) {
+    GrContext* ctx = NULL;
+    GrGpu* fGpu = GrGpu::Create(engine, context3D);
+    if (NULL != fGpu) {
+        ctx = new GrContext(fGpu);
+        fGpu->unref();
+    }
+    return ctx;
+}
+
+GrContext* GrContext::CreateGLShaderContext() {
+    return GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+}
+
+GrContext::~GrContext() {
+    fGpu->unref();
+    delete fTextureCache;
+    delete fFontCache;
+    delete fDrawBuffer;
+    delete fDrawBufferVBAllocPool;
+    delete fDrawBufferIBAllocPool;
+    delete fPathRenderer;
+}
+
+void GrContext::abandonAllTextures() {
+    fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
+    fFontCache->abandonAll();
+}
+
+GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
+                                              const GrSamplerState& sampler) {
+    finalizeTextureKey(key, sampler);
+    return fTextureCache->findAndLock(*key);
+}
+
+static void stretchImage(void* dst,
+                         int dstW,
+                         int dstH,
+                         void* src,
+                         int srcW,
+                         int srcH,
+                         int bpp) {
+    GrFixed dx = (srcW << 16) / dstW;
+    GrFixed dy = (srcH << 16) / dstH;
+
+    GrFixed y = dy >> 1;
+
+    int dstXLimit = dstW*bpp;
+    for (int j = 0; j < dstH; ++j) {
+        GrFixed x = dx >> 1;
+        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
+        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
+        for (int i = 0; i < dstXLimit; i += bpp) {
+            memcpy((uint8_t*) dstRow + i,
+                   (uint8_t*) srcRow + (x>>16)*bpp,
+                   bpp);
+            x += dx;
+        }
+        y += dy;
+    }
+}
+
+GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
+                                                const GrSamplerState& sampler,
+                                                const GrGpu::TextureDesc& desc,
+                                                void* srcData, size_t rowBytes) {
+    GrAssert(key->width() == desc.fWidth);
+    GrAssert(key->height() == desc.fHeight);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
+#endif
+
+    GrTextureEntry* entry = NULL;
+    bool special = finalizeTextureKey(key, sampler);
+    if (special) {
+        GrTextureEntry* clampEntry;
+        GrTextureKey clampKey(*key);
+        clampEntry = findAndLockTexture(&clampKey, GrSamplerState::ClampNoFilter());
+
+        if (NULL == clampEntry) {
+            clampEntry = createAndLockTexture(&clampKey,
+                                              GrSamplerState::ClampNoFilter(),
+                                              desc, srcData, rowBytes);
+            GrAssert(NULL != clampEntry);
+            if (NULL == clampEntry) {
+                return NULL;
+            }
+        }
+        GrGpu::TextureDesc rtDesc = desc;
+        rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag |
+                         GrGpu::kNoPathRendering_TextureFlag;
+        rtDesc.fWidth  = GrNextPow2(GrMax<int>(desc.fWidth,
+                                               fGpu->minRenderTargetWidth()));
+        rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight,
+                                               fGpu->minRenderTargetHeight()));
+
+        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
+
+        if (NULL != texture) {
+            GrDrawTarget::AutoStateRestore asr(fGpu);
+            fGpu->setRenderTarget(texture->asRenderTarget());
+            fGpu->setTexture(0, clampEntry->texture());
+            fGpu->disableStencil();
+            fGpu->setViewMatrix(GrMatrix::I());
+            fGpu->setAlpha(0xff);
+            fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
+            fGpu->disableState(GrDrawTarget::kDither_StateBit |
+                               GrDrawTarget::kClip_StateBit   |
+                               GrDrawTarget::kAntialias_StateBit);
+            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
+                                          GrSamplerState::kClamp_WrapMode,
+                                          sampler.isFilter());
+            fGpu->setSamplerState(0, stretchSampler);
+
+            static const GrVertexLayout layout =
+                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
+
+            if (arg.succeeded()) {
+                GrPoint* verts = (GrPoint*) arg.vertices();
+                verts[0].setIRectFan(0, 0,
+                                     texture->width(),
+                                     texture->height(),
+                                     2*sizeof(GrPoint));
+                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
+                fGpu->drawNonIndexed(kTriangleFan_PrimitiveType,
+                                     0, 4);
+                entry = fTextureCache->createAndLock(*key, texture);
+            }
+            texture->releaseRenderTarget();
+        } else {
+            // TODO: Our CPU stretch doesn't filter. But we create separate
+            // stretched textures when the sampler state is either filtered or
+            // not. Either implement filtered stretch blit on CPU or just create
+            // one when FBO case fails.
+
+            rtDesc.fFlags = 0;
+            // no longer need to clamp at min RT size.
+            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
+            rtDesc.fHeight = GrNextPow2(desc.fHeight);
+            int bpp = GrTexture::BytesPerPixel(desc.fFormat);
+            GrAutoSMalloc<128*128*4> stretchedPixels(bpp *
+                                                     rtDesc.fWidth *
+                                                     rtDesc.fHeight);
+            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
+                         srcData, desc.fWidth, desc.fHeight, bpp);
+
+            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
+
+            GrTexture* texture = fGpu->createTexture(rtDesc,
+                                                     stretchedPixels.get(),
+                                                     stretchedRowBytes);
+            GrAssert(NULL != texture);
+            entry = fTextureCache->createAndLock(*key, texture);
+        }
+        fTextureCache->unlock(clampEntry);
+
+    } else {
+        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
+        if (NULL != texture) {
+            entry = fTextureCache->createAndLock(*key, texture);
+        } else {
+            entry = NULL;
+        }
+    }
+    return entry;
+}
+
+void GrContext::unlockTexture(GrTextureEntry* entry) {
+    fTextureCache->unlock(entry);
+}
+
+void GrContext::detachCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->detach(entry);
+}
+
+void GrContext::reattachAndUnlockCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->reattachAndUnlock(entry);
+}
+
+GrTexture* GrContext::createUncachedTexture(const GrGpu::TextureDesc& desc,
+                                            void* srcData,
+                                            size_t rowBytes) {
+    return fGpu->createTexture(desc, srcData, rowBytes);
+}
+
+void GrContext::getTextureCacheLimits(int* maxTextures,
+                                      size_t* maxTextureBytes) const {
+    fTextureCache->getLimits(maxTextures, maxTextureBytes);
+}
+
+void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
+    fTextureCache->setLimits(maxTextures, maxTextureBytes);
+}
+
+int GrContext::getMaxTextureDimension() {
+    return fGpu->maxTextureDimension();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRenderTarget* GrContext::createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height) {
+    return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,
+                                            width, height);
+}
+
+bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
+                                          int width, int height) {
+    if (!fGpu->supports8BitPalette()) {
+        return false;
+    }
+
+
+    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+    if (!isPow2) {
+        if (!fGpu->npotTextureSupport()) {
+            return false;
+        }
+
+        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
+                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
+        if (tiled && !fGpu->npotTextureTileSupport()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::setClip(const GrClip& clip) {
+    fGpu->setClip(clip);
+    fGpu->enableState(GrDrawTarget::kClip_StateBit);
+}
+
+void GrContext::setClip(const GrIRect& rect) {
+    GrClip clip;
+    clip.setFromIRect(rect);
+    fGpu->setClip(clip);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::eraseColor(GrColor color) {
+    fGpu->eraseColor(color);
+}
+
+void GrContext::drawPaint(const GrPaint& paint) {
+    // set rect to be big enough to fill the space, but not super-huge, so we
+    // don't overflow fixed-point implementations
+    GrRect r;
+    r.setLTRB(0, 0,
+              GrIntToScalar(getRenderTarget()->width()),
+              GrIntToScalar(getRenderTarget()->height()));
+    GrMatrix inverse;
+    if (fGpu->getViewInverse(&inverse)) {
+        inverse.mapRect(&r);
+    } else {
+        GrPrintf("---- fGpu->getViewInverse failed\n");
+    }
+    this->drawRect(paint, r);
+}
+
+/*  create a triangle strip that strokes the specified triangle. There are 8
+ unique vertices, but we repreat the last 2 to close up. Alternatively we
+ could use an indices array, and then only send 8 verts, but not sure that
+ would be faster.
+ */
+static void setStrokeRectStrip(GrPoint verts[10], const GrRect& rect,
+                               GrScalar width) {
+    const GrScalar rad = GrScalarHalf(width);
+
+    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
+    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
+    verts[2].set(rect.fRight - rad, rect.fTop + rad);
+    verts[3].set(rect.fRight + rad, rect.fTop - rad);
+    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
+    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
+    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
+    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
+    verts[8] = verts[0];
+    verts[9] = verts[1];
+}
+
+void GrContext::drawRect(const GrPaint& paint,
+                         const GrRect& rect,
+                         GrScalar width,
+                         const GrMatrix* matrix) {
+
+    bool textured = NULL != paint.getTexture();
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (width >= 0) {
+        // TODO: consider making static vertex buffers for these cases.
+        // Hairline could be done by just adding closing vertex to
+        // unitSquareVertexBuffer()
+        GrVertexLayout layout = (textured) ?
+                                 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                                 0;
+        static const int worstCaseVertCount = 10;
+        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
+
+        if (!geo.succeeded()) {
+            return;
+        }
+
+        GrPrimitiveType primType;
+        int vertCount;
+        GrPoint* vertex = geo.positions();
+
+        if (width > 0) {
+            vertCount = 10;
+            primType = kTriangleStrip_PrimitiveType;
+            setStrokeRectStrip(vertex, rect, width);
+        } else {
+            // hairline
+            vertCount = 5;
+            primType = kLineStrip_PrimitiveType;
+            vertex[0].set(rect.fLeft, rect.fTop);
+            vertex[1].set(rect.fRight, rect.fTop);
+            vertex[2].set(rect.fRight, rect.fBottom);
+            vertex[3].set(rect.fLeft, rect.fBottom);
+            vertex[4].set(rect.fLeft, rect.fTop);
+        }
+
+        GrDrawTarget::AutoViewMatrixRestore avmr;
+        if (NULL != matrix) {
+            avmr.set(target);
+            target->preConcatViewMatrix(*matrix);
+            target->preConcatSamplerMatrix(0, *matrix);
+        }
+
+        target->drawNonIndexed(primType, 0, vertCount);
+    } else {
+        #if GR_STATIC_RECT_VB
+            GrVertexLayout layout = (textured) ?
+                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                            0;
+            target->setVertexSourceToBuffer(layout,
+                                            fGpu->getUnitSquareVertexBuffer());
+            GrDrawTarget::AutoViewMatrixRestore avmr(target);
+            GrMatrix m;
+            m.setAll(rect.width(), 0,             rect.fLeft,
+                     0,            rect.height(), rect.fTop,
+                     0,            0,             GrMatrix::I()[8]);
+
+            if (NULL != matrix) {
+                m.postConcat(*matrix);
+            }
+
+            target->preConcatViewMatrix(m);
+
+            if (textured) {
+                target->preConcatSamplerMatrix(0, m);
+            }
+            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+        #else
+            target->drawSimpleRect(rect, matrix, textured ? 1 : 0);
+        #endif
+    }
+}
+
+void GrContext::drawRectToRect(const GrPaint& paint,
+                               const GrRect& dstRect,
+                               const GrRect& srcRect,
+                               const GrMatrix* dstMatrix,
+                               const GrMatrix* srcMatrix) {
+
+    if (NULL == paint.getTexture()) {
+        drawRect(paint, dstRect, -1, dstMatrix);
+        return;
+    }
+
+    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
+
+#if GR_STATIC_RECT_VB
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    GrDrawTarget::AutoViewMatrixRestore avmr(target);
+
+    GrMatrix m;
+
+    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
+             0,               dstRect.height(), dstRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != dstMatrix) {
+        m.postConcat(*dstMatrix);
+    }
+    target->preConcatViewMatrix(m);
+
+    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
+             0,               srcRect.height(), srcRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != srcMatrix) {
+        m.postConcat(*srcMatrix);
+    }
+    target->preConcatSamplerMatrix(0, m);
+
+    target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());
+    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+#else
+
+    GrDrawTarget* target;
+#if BATCH_RECT_TO_RECT
+    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
+#else
+    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+
+    const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL};
+    const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL};
+    srcRects[0] = &srcRect;
+    srcMatrices[0] = srcMatrix;
+
+    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
+#endif
+}
+
+void GrContext::drawVertices(const GrPaint& paint,
+                             GrPrimitiveType primitiveType,
+                             int vertexCount,
+                             const GrPoint positions[],
+                             const GrPoint texCoords[],
+                             const GrColor colors[],
+                             const uint16_t indices[],
+                             int indexCount) {
+    GrVertexLayout layout = 0;
+    int vertexSize = sizeof(GrPoint);
+
+    GrDrawTarget::AutoReleaseGeometry geo;
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (NULL != paint.getTexture()) {
+        if (NULL == texCoords) {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        } else {
+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            vertexSize += sizeof(GrPoint);
+        }
+    }
+
+    if (NULL != colors) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+        vertexSize += sizeof(GrColor);
+    }
+
+    if (sizeof(GrPoint) != vertexSize) {
+        if (!geo.set(target, layout, vertexCount, 0)) {
+            GrPrintf("Failed to get space for vertices!");
+            return;
+        }
+        int texOffsets[GrDrawTarget::kMaxTexCoords];
+        int colorOffset;
+        int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+                                                            texOffsets,
+                                                            &colorOffset);
+        void* curVertex = geo.vertices();
+
+        for (int i = 0; i < vertexCount; ++i) {
+            *((GrPoint*)curVertex) = positions[i];
+
+            if (texOffsets[0] > 0) {
+                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
+            }
+            if (colorOffset > 0) {
+                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
+            }
+            curVertex = (void*)((intptr_t)curVertex + vsize);
+        }
+    } else {
+        target->setVertexSourceToArray(layout, positions, vertexCount);
+    }
+
+    if (NULL != indices) {
+        target->setIndexSourceToArray(indices, indexCount);
+        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+    } else {
+        target->drawNonIndexed(primitiveType, 0, vertexCount);
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::drawPath(const GrPaint& paint,
+                         GrPathIter* path,
+                         GrPathFill fill,
+                         const GrPoint* translate) {
+
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrDrawTarget::StageBitfield enabledStages = 0;
+    if (NULL != paint.getTexture()) {
+        enabledStages |= 1;
+    }
+    fPathRenderer->drawPath(target, enabledStages, path, fill, translate);
+}
+
+void GrContext::drawPath(const GrPaint& paint,
+                         const GrPath& path,
+                         GrPathFill fill,
+                         const GrPoint* translate) {
+    GrPath::Iter iter(path);
+    this->drawPath(paint, &iter, fill, translate);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::flush(int flagsBitfield) {
+    if (kDiscard_FlushBit & flagsBitfield) {
+        fDrawBuffer->reset();
+    } else {
+        flushDrawBuffer();
+    }
+
+    if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) {
+        fGpu->forceRenderTargetFlush();
+    }
+}
+
+void GrContext::flushText() {
+    if (kText_DrawCategory == fLastDrawCategory) {
+        flushDrawBuffer();
+    }
+}
+
+void GrContext::flushDrawBuffer() {
+#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
+    fDrawBuffer->playback(fGpu);
+    fDrawBuffer->reset();
+#endif
+}
+
+bool GrContext::readPixels(int left, int top, int width, int height,
+                           GrTexture::PixelConfig config, void* buffer) {
+    this->flush(true);
+    return fGpu->readPixels(left, top, width, height, config, buffer);
+}
+
+void GrContext::writePixels(int left, int top, int width, int height,
+                            GrTexture::PixelConfig config, const void* buffer,
+                            size_t stride) {
+
+    // TODO: when underlying api has a direct way to do this we should use it
+    // (e.g. glDrawPixels on desktop GL).
+
+    const GrGpu::TextureDesc desc = {
+        0, GrGpu::kNone_AALevel, width, height, config
+    };
+    GrTexture* texture = fGpu->createTexture(desc, buffer, stride);
+    if (NULL == texture) {
+        return;
+    }
+
+    this->flush(true);
+
+    GrAutoUnref                     aur(texture);
+    GrDrawTarget::AutoStateRestore  asr(fGpu);
+
+    GrMatrix matrix;
+    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
+    fGpu->setViewMatrix(matrix);
+
+    fGpu->disableState(GrDrawTarget::kClip_StateBit);
+    fGpu->setAlpha(0xFF);
+    fGpu->setBlendFunc(kOne_BlendCoeff,
+                       kZero_BlendCoeff);
+    fGpu->setTexture(0, texture);
+
+    GrSamplerState sampler;
+    sampler.setClampNoFilter();
+    matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height);
+    sampler.setMatrix(matrix);
+    fGpu->setSamplerState(0, sampler);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    static const int VCOUNT = 4;
+
+    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
+    if (!geo.succeeded()) {
+        return;
+    }
+    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
+    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {
+    target->setTexture(0, paint.getTexture());
+    target->setSamplerState(0, paint.fSampler);
+    target->setColor(paint.fColor);
+
+    if (paint.fDither) {
+        target->enableState(GrDrawTarget::kDither_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kDither_StateBit);
+    }
+    if (paint.fAntiAlias) {
+        target->enableState(GrDrawTarget::kAntialias_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kAntialias_StateBit);
+    }
+    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
+}
+
+GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint,
+                                       DrawCategory category) {
+    if (category != fLastDrawCategory) {
+        flushDrawBuffer();
+        fLastDrawCategory = category;
+    }
+    SetPaint(paint, fGpu);
+    GrDrawTarget* target = fGpu;
+    switch (category) {
+    case kText_DrawCategory:
+#if DEFER_TEXT_RENDERING
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+#else
+        target = fGpu;
+#endif
+        break;
+    case kUnbuffered_DrawCategory:
+        target = fGpu;
+        break;
+    case kBuffered_DrawCategory:
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+        break;
+    }
+    return target;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::resetContext() {
+    fGpu->markContextDirty();
+}
+
+void GrContext::setRenderTarget(GrRenderTarget* target) {
+    flush(false);
+    fGpu->setRenderTarget(target);
+}
+
+GrRenderTarget* GrContext::getRenderTarget() {
+    return fGpu->getRenderTarget();
+}
+
+const GrRenderTarget* GrContext::getRenderTarget() const {
+    return fGpu->getRenderTarget();
+}
+
+const GrMatrix& GrContext::getMatrix() const {
+    return fGpu->getViewMatrix();
+}
+
+void GrContext::setMatrix(const GrMatrix& m) {
+    fGpu->setViewMatrix(m);
+}
+
+void GrContext::concatMatrix(const GrMatrix& m) const {
+    fGpu->preConcatViewMatrix(m);
+}
+
+static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
+    intptr_t mask = 1 << shift;
+    if (pred) {
+        bits |= mask;
+    } else {
+        bits &= ~mask;
+    }
+    return bits;
+}
+
+void GrContext::resetStats() {
+    fGpu->resetStats();
+}
+
+const GrGpu::Stats& GrContext::getStats() const {
+    return fGpu->getStats();
+}
+
+void GrContext::printStats() const {
+    fGpu->printStats();
+}
+
+GrContext::GrContext(GrGpu* gpu) {
+    fGpu = gpu;
+    fGpu->ref();
+    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
+                                       MAX_TEXTURE_CACHE_BYTES);
+    fFontCache = new GrFontCache(fGpu);
+
+    fLastDrawCategory = kUnbuffered_DrawCategory;
+
+#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
+    fDrawBufferVBAllocPool =
+        new GrVertexBufferAllocPool(gpu, false,
+                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
+                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
+    fDrawBufferIBAllocPool =
+        new GrIndexBufferAllocPool(gpu, false,
+                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
+                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
+
+    fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
+                                          fDrawBufferIBAllocPool);
+#else
+    fDrawBuffer = NULL;
+    fDrawBufferVBAllocPool = NULL;
+    fDrawBufferIBAllocPool = NULL;
+#endif
+
+#if BATCH_RECT_TO_RECT
+    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
+#endif
+    fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsTwoSidedStencil(),
+                                              fGpu->supportsStencilWrapOps());
+}
+
+bool GrContext::finalizeTextureKey(GrTextureKey* key,
+                                   const GrSamplerState& sampler) const {
+    uint32_t bits = 0;
+    uint16_t width = key->width();
+    uint16_t height = key->height();
+
+
+    if (!fGpu->npotTextureTileSupport()) {
+        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
+                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
+
+        if (tiled && !isPow2) {
+            bits |= 1;
+            bits |= sampler.isFilter() ? 2 : 0;
+        }
+    }
+    key->finalize(bits);
+    return 0 != bits;
+}
+
+GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
+    GrDrawTarget* target;
+#if DEFER_TEXT_RENDERING
+    target = prepareToDraw(paint, kText_DrawCategory);
+#else
+    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+    SetPaint(paint, target);
+    return target;
+}
+
+const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
+    return fGpu->getQuadIndexBuffer();
+}
diff --git a/gpu/src/GrDrawMesh.cpp b/gpu/src/GrDrawMesh.cpp
new file mode 100644
index 0000000..bd79005
--- /dev/null
+++ b/gpu/src/GrDrawMesh.cpp
@@ -0,0 +1,140 @@
+#include "GrMesh.h"
+#include "SkCanvas.h"
+
+GrMesh::GrMesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
+
+GrMesh::~GrMesh() {
+    delete[] fPts;
+    delete[] fIndices;
+}
+
+GrMesh& GrMesh::operator=(const GrMesh& src) {
+    delete[] fPts;
+    delete[] fIndices;
+
+    fBounds = src.fBounds;
+    fRows = src.fRows;
+    fCols = src.fCols;
+
+    fCount = src.fCount;
+    fPts = new SkPoint[fCount * 2];
+    fTex = fPts + fCount;
+    memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));
+    
+    delete[] fIndices;
+    fIndexCount = src.fIndexCount;
+    fIndices = new uint16_t[fIndexCount];
+    memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));
+
+    return *this;
+}
+
+void GrMesh::init(const SkRect& bounds, int rows, int cols,
+                const SkRect& texture) {
+    SkASSERT(rows > 0 && cols > 0);
+
+    fBounds = bounds;
+    fRows = rows;
+    fCols = cols;
+
+    delete[] fPts;
+    fCount = (rows + 1) * (cols + 1);
+    fPts = new SkPoint[fCount * 2];
+    fTex = fPts + fCount;
+
+    delete[] fIndices;
+    fIndexCount = rows * cols * 6;
+    fIndices = new uint16_t[fIndexCount];
+    
+    SkPoint* pts = fPts;
+    const SkScalar dx = bounds.width() / rows;
+    const SkScalar dy = bounds.height() / cols;
+    SkPoint* tex = fTex;
+    const SkScalar dtx = texture.width() / rows;
+    const SkScalar dty = texture.height() / cols;
+    uint16_t* idx = fIndices;
+    int index = 0;
+    for (int y = 0; y <= cols; y++) {
+        for (int x = 0; x <= rows; x++) {
+            pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
+            pts += 1;
+            tex->set(texture.fLeft + x*dtx, texture.fTop + y*dty);
+            tex += 1;
+            
+            if (y < cols && x < rows) {
+                *idx++ = index;
+                *idx++ = index + rows + 1;
+                *idx++ = index + 1;
+
+                *idx++ = index + 1;
+                *idx++ = index + rows + 1;
+                *idx++ = index + rows + 2;
+                
+                index += 1;
+            }
+        }
+        index += 1;
+    }
+}
+
+void GrMesh::draw(SkCanvas* canvas, const SkPaint& paint) {
+    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
+                         fPts, fTex, NULL, NULL, fIndices, fIndexCount,
+                         paint);
+}
+
+/////////////////////////////////////////////
+
+#include "SkBoundaryPatch.h"
+#include "SkMeshUtils.h"
+
+static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
+    return SkPoint::Make(SkScalarInterp(a.fX, b.fX, t),
+                         SkScalarInterp(a.fY, b.fY, t));
+}
+
+static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
+                      SkScalar x3, SkScalar y3, SkScalar scale = 1) {
+    SkPoint tmp, tmp2;
+    
+    pts[0].set(x0, y0);
+    pts[3].set(x3, y3);
+    
+    tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
+    tmp2 = pts[0] - tmp;
+    tmp2.rotateCW();
+    tmp2.scale(scale);
+    pts[1] = tmp + tmp2;
+    
+    tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
+    tmp2 = pts[3] - tmp;
+    tmp2.rotateCW();
+    tmp2.scale(scale);
+    pts[2] = tmp + tmp2;
+}
+
+void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
+    const float w = bm.width();
+    const float h = bm.height();
+    SkCubicBoundary cubic;    
+    set_cubic(cubic.fPts + 0, 0, 0, w, 0, scale);
+    set_cubic(cubic.fPts + 3, w, 0, w, h, scale);
+    set_cubic(cubic.fPts + 6, w, h, 0, h, -scale);
+    set_cubic(cubic.fPts + 9, 0, h, 0, 0, scale);
+    
+    SkBoundaryPatch patch;
+    patch.setBoundary(&cubic);
+    
+    const int Rows = 16;
+    const int Cols = 16;
+    SkPoint pts[Rows * Cols];
+    patch.evalPatch(pts, Rows, Cols);
+    
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setFilterBitmap(true);
+
+    SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
+}
+
+
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
new file mode 100644
index 0000000..7973361
--- /dev/null
+++ b/gpu/src/GrDrawTarget.cpp
@@ -0,0 +1,597 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrDrawTarget.h"
+#include "GrGpuVertex.h"
+#include "GrTexture.h"
+
+// recursive helper for creating mask with all the tex coord bits set for
+// one stage
+template <int N>
+static int stage_mask_recur(int stage) {
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
+           stage_mask_recur<N+1>(stage);
+}
+template<> // linux build doesn't like static on specializations
+int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
+
+// mask of all tex coord indices for one stage
+static int stage_tex_coord_mask(int stage) {
+    return stage_mask_recur<0>(stage);
+}
+
+// mask of all bits relevant to one stage
+static int stage_mask(int stage) {
+    return stage_tex_coord_mask(stage) |
+           GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
+}
+
+// recursive helper for creating mask of with all bits set relevant to one
+// texture coordinate index
+template <int N>
+static int tex_coord_mask_recur(int texCoordIdx) {
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
+           tex_coord_mask_recur<N+1>(texCoordIdx);
+}
+template<> // linux build doesn't like static on specializations
+int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
+
+// mask of all bits relevant to one texture coordinate index
+static int tex_coord_idx_mask(int texCoordIdx) {
+    return tex_coord_mask_recur<0>(texCoordIdx);
+}
+
+bool check_layout(GrVertexLayout layout) {
+    // can only have 1 or 0 bits set for each stage.
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        int stageBits = layout & stage_mask(s);
+        if (stageBits && !GrIsPow2(stageBits)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                        sizeof(GrGpuTextVertex) :
+                        sizeof(GrPoint);
+
+    size_t size = vecSize; // position
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (tex_coord_idx_mask(t) & vertexLayout) {
+            size += vecSize;
+        }
+    }
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        size += sizeof(GrColor);
+    }
+    return size;
+}
+
+int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+    if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
+        return 0;
+    }
+    int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
+    if (tcIdx >= 0) {
+
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize; // position
+        // figure out how many tex coordinates are present and precede this one.
+        for (int t = 0; t < tcIdx; ++t) {
+            if (tex_coord_idx_mask(t) & vertexLayout) {
+                offset += vecSize;
+            }
+        }
+        return offset;
+    }
+
+    return -1;
+}
+
+int  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
+    GrAssert(check_layout(vertexLayout));
+
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                    sizeof(GrGpuTextVertex) :
+                                    sizeof(GrPoint);
+        int offset = vecSize; // position
+        // figure out how many tex coordinates are present and precede this one.
+        for (int t = 0; t < kMaxTexCoords; ++t) {
+            if (tex_coord_idx_mask(t) & vertexLayout) {
+                offset += vecSize;
+            }
+        }
+        return offset;
+    }
+    return -1;
+}
+
+int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
+                                             int texCoordOffsetsByIdx[kMaxTexCoords],
+                                             int* colorOffset) {
+    GrAssert(check_layout(vertexLayout));
+
+    GrAssert(NULL != texCoordOffsetsByIdx);
+    GrAssert(NULL != colorOffset);
+
+    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
+                                                    sizeof(GrGpuTextVertex) :
+                                                    sizeof(GrPoint);
+    int size = vecSize; // position
+
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (tex_coord_idx_mask(t) & vertexLayout) {
+            texCoordOffsetsByIdx[t] = size;
+            size += vecSize;
+        } else {
+            texCoordOffsetsByIdx[t] = -1;
+        }
+    }
+    if (kColor_VertexLayoutBit & vertexLayout) {
+        *colorOffset = size;
+        size += sizeof(GrColor);
+    } else {
+        *colorOffset = -1;
+    }
+    return size;
+}
+
+int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
+                                              int texCoordOffsetsByStage[kNumStages],
+                                              int* colorOffset) {
+    GrAssert(check_layout(vertexLayout));
+
+    GrAssert(NULL != texCoordOffsetsByStage);
+    GrAssert(NULL != colorOffset);
+
+    int texCoordOffsetsByIdx[kMaxTexCoords];
+    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
+                                         texCoordOffsetsByIdx,
+                                         colorOffset);
+    for (int s = 0; s < kNumStages; ++s) {
+        int tcIdx;
+        if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
+            texCoordOffsetsByStage[s] = 0;
+        } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
+            texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
+        } else {
+            texCoordOffsetsByStage[s] = -1;
+        }
+    }
+    return size;
+}
+
+bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(stage < kNumStages);
+    GrAssert(check_layout(vertexLayout));
+    return !!(stage_mask(stage) & vertexLayout);
+}
+
+bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
+                                         GrVertexLayout vertexLayout) {
+    GrAssert(coordIndex < kMaxTexCoords);
+    GrAssert(check_layout(vertexLayout));
+    return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
+}
+
+int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
+    GrAssert(stage < kNumStages);
+    GrAssert(check_layout(vertexLayout));
+    int bit = vertexLayout & stage_tex_coord_mask(stage);
+    if (bit) {
+        // figure out which set of texture coordates is used
+        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
+        // and start at bit 0.
+        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
+        return (32 - Gr_clz(bit) - 1) / kNumStages;
+    }
+    return -1;
+}
+
+void GrDrawTarget::VertexLayoutUnitTest() {
+    // not necessarily exhaustive
+    static bool run;
+    if (!run) {
+        run = true;
+        for (int s = 0; s < kNumStages; ++s) {
+
+            GrAssert(!VertexUsesStage(s, 0));
+            GrAssert(-1 == VertexStageCoordOffset(s, 0));
+            GrVertexLayout stageMask = 0;
+            for (int t = 0; t < kMaxTexCoords; ++t) {
+                stageMask |= StageTexCoordVertexLayoutBit(s,t);
+            }
+            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
+            GrAssert(stage_tex_coord_mask(s) == stageMask);
+            stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
+            GrAssert(stage_mask(s) == stageMask);
+            GrAssert(!check_layout(stageMask));
+        }
+        for (int t = 0; t < kMaxTexCoords; ++t) {
+            GrVertexLayout tcMask = 0;
+            GrAssert(!VertexUsesTexCoordIdx(t, 0));
+            for (int s = 0; s < kNumStages; ++s) {
+                tcMask |= StageTexCoordVertexLayoutBit(s,t);
+                GrAssert(VertexUsesStage(s, tcMask));
+                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
+                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
+                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
+                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
+                for (int s2 = s + 1; s2 < kNumStages; ++s2) {
+                    GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
+                    GrAssert(!VertexUsesStage(s2, tcMask));
+                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
+
+                #if GR_DEBUG
+                    GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
+                #endif
+                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
+                    GrAssert(VertexUsesStage(s2, posAsTex));
+                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
+                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
+                }
+            #if GR_DEBUG
+                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
+            #endif
+                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
+                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
+            }
+            GrAssert(tex_coord_idx_mask(t) == tcMask);
+            GrAssert(check_layout(tcMask));
+
+            int stageOffsets[kNumStages];
+            int colorOffset;
+            int size;
+            size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
+            GrAssert(2*sizeof(GrPoint) == size);
+            GrAssert(-1 == colorOffset);
+            for (int s = 0; s < kNumStages; ++s) {
+                GrAssert(VertexUsesStage(s, tcMask));
+                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
+                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
+            }
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::GrDrawTarget() {
+#if GR_DEBUG
+    VertexLayoutUnitTest();
+#endif
+    fReservedGeometry.fLocked = false;
+#if GR_DEBUG
+    fReservedGeometry.fVertexCount  = ~0;
+    fReservedGeometry.fIndexCount   = ~0;
+#endif
+    fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
+    fGeometrySrc.fIndexSrc  = kReserved_GeometrySrcType;
+}
+
+void GrDrawTarget::setClip(const GrClip& clip) {
+    clipWillBeSet(clip);
+    fClip = clip;
+}
+
+const GrClip& GrDrawTarget::getClip() const {
+    return fClip;
+}
+
+void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    fCurrDrawState.fTextures[stage] = tex;
+}
+
+const GrTexture* GrDrawTarget::getTexture(int stage) const {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    return fCurrDrawState.fTextures[stage];
+}
+
+GrTexture* GrDrawTarget::getTexture(int stage) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    return fCurrDrawState.fTextures[stage];
+}
+
+void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
+    fCurrDrawState.fRenderTarget = target;
+}
+
+const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
+    return fCurrDrawState.fRenderTarget;
+}
+
+GrRenderTarget* GrDrawTarget::getRenderTarget() {
+    return fCurrDrawState.fRenderTarget;
+}
+
+void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
+    fCurrDrawState.fViewMatrix = m;
+}
+
+void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
+    fCurrDrawState.fViewMatrix.preConcat(matrix);
+}
+
+const GrMatrix& GrDrawTarget::getViewMatrix() const {
+    return fCurrDrawState.fViewMatrix;
+}
+
+bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
+    // Mike:  Can we cache this somewhere?
+    // Brian: Sure, do we use it often?
+
+    GrMatrix inverse;
+    if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
+        if (matrix) {
+            *matrix = inverse;
+        }
+        return true;
+    }
+    return false;
+}
+
+void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    fCurrDrawState.fSamplerStates[stage] = state;
+}
+
+void GrDrawTarget::enableState(uint32_t bits) {
+    fCurrDrawState.fFlagBits |= bits;
+}
+
+void GrDrawTarget::disableState(uint32_t bits) {
+    fCurrDrawState.fFlagBits &= ~(bits);
+}
+
+void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoef,
+                                GrBlendCoeff dstCoef) {
+    fCurrDrawState.fSrcBlend = srcCoef;
+    fCurrDrawState.fDstBlend = dstCoef;
+}
+
+void GrDrawTarget::setColor(GrColor c) {
+    fCurrDrawState.fColor = c;
+}
+
+void GrDrawTarget::setAlpha(uint8_t a) {
+    this->setColor((a << 24) | (a << 16) | (a << 8) | a);
+}
+
+void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
+    state->fState = fCurrDrawState;
+}
+
+void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
+    fCurrDrawState = state.fState;
+}
+
+void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
+    fCurrDrawState = srcTarget.fCurrDrawState;
+}
+
+
+bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
+                                          uint32_t          vertexCount,
+                                          uint32_t          indexCount,
+                                          void**            vertices,
+                                          void**            indices) {
+    GrAssert(!fReservedGeometry.fLocked);
+    fReservedGeometry.fVertexCount  = vertexCount;
+    fReservedGeometry.fIndexCount   = indexCount;
+
+    fReservedGeometry.fLocked = acquireGeometryHelper(vertexLayout,
+                                                      vertices,
+                                                      indices);
+    if (fReservedGeometry.fLocked) {
+        if (vertexCount) {
+            fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
+            fGeometrySrc.fVertexLayout = vertexLayout;
+        }
+        if (indexCount) {
+            fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
+        }
+    }
+    return fReservedGeometry.fLocked;
+}
+
+bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
+                                 int32_t* vertexCount,
+                                 int32_t* indexCount) const {
+    GrAssert(!fReservedGeometry.fLocked);
+    if (NULL != vertexCount) {
+        *vertexCount = -1;
+    }
+    if (NULL != indexCount) {
+        *indexCount = -1;
+    }
+    return false;
+}
+
+void GrDrawTarget::releaseReservedGeometry() {
+    GrAssert(fReservedGeometry.fLocked);
+    releaseGeometryHelper();
+    fReservedGeometry.fLocked = false;
+}
+
+void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
+                                          const void* vertexArray,
+                                          int vertexCount) {
+    fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
+    fGeometrySrc.fVertexLayout = vertexLayout;
+    setVertexSourceToArrayHelper(vertexArray, vertexCount);
+}
+
+void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
+                                         int indexCount) {
+    fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
+    setIndexSourceToArrayHelper(indexArray, indexCount);
+}
+
+void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
+                                           const GrVertexBuffer* buffer) {
+    fGeometrySrc.fVertexSrc    = kBuffer_GeometrySrcType;
+    fGeometrySrc.fVertexBuffer = buffer;
+    fGeometrySrc.fVertexLayout = vertexLayout;
+}
+
+void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
+    fGeometrySrc.fIndexSrc     = kBuffer_GeometrySrcType;
+    fGeometrySrc.fIndexBuffer  = buffer;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool GrDrawTarget::canDisableBlend() const {
+    if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
+        (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
+            return true;
+    }
+
+    // If we have vertex color without alpha then we can't force blend off
+    if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
+         0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
+        return false;
+    }
+
+    // If the src coef will always be 1...
+    if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
+        kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
+        return false;
+    }
+
+    // ...and the dst coef is always 0...
+    if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
+        kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
+        return false;
+    }
+
+    // ...and there isn't a texture with an alpha channel...
+    for (int s = 0; s < kNumStages; ++s) {
+        if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) {
+            GrAssert(NULL != fCurrDrawState.fTextures[s]);
+            GrTexture::PixelConfig config = fCurrDrawState.fTextures[s]->config();
+
+            if (GrTexture::kRGB_565_PixelConfig != config &&
+                GrTexture::kRGBX_8888_PixelConfig != config) {
+                return false;
+            }
+        }
+    }
+
+    // ...then we disable blend.
+    return true;
+}
+///////////////////////////////////////////////////////////////////////////////
+void GrDrawTarget::drawRect(const GrRect& rect, 
+                            const GrMatrix* matrix,
+                            StageBitfield stageEnableBitfield,
+                            const GrRect* srcRects[],
+                            const GrMatrix* srcMatrices[]) {
+    GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
+
+    AutoReleaseGeometry geo(this, layout, 4, 0);
+
+    SetRectVertices(rect, matrix, srcRects, 
+                    srcMatrices, layout, geo.vertices());
+
+    drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+}
+
+GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield, 
+                                                 const GrRect* srcRects[]) {
+    GrVertexLayout layout = 0;
+
+    for (int i = 0; i < kNumStages; ++i) {
+        int numTC = 0;
+        if (stageEnableBitfield & (1 << i)) {
+            if (NULL != srcRects && NULL != srcRects[i]) {
+                layout |= StageTexCoordVertexLayoutBit(i, numTC);
+                ++numTC;
+            } else {
+                layout |= StagePosAsTexCoordVertexLayoutBit(i);
+            }
+        }
+    }
+    return layout;
+}
+void GrDrawTarget::SetRectVertices(const GrRect& rect,
+                                   const GrMatrix* matrix, 
+                                   const GrRect* srcRects[], 
+                                   const GrMatrix* srcMatrices[],
+                                   GrVertexLayout layout, 
+                                   void* vertices) {
+#if GR_DEBUG
+    // check that the layout and srcRects agree
+    for (int i = 0; i < kNumStages; ++i) {
+        if (VertexTexCoordsForStage(i, layout) >= 0) {
+            GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
+        } else {
+            GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
+        }
+    }
+#endif
+
+    int stageOffsets[kNumStages];
+    int colorOffset;
+    int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset);
+    GrAssert(-1 == colorOffset);
+
+    GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, 
+                                            rect.fRight, rect.fBottom,
+                                            vsize);
+    if (NULL != matrix) {
+        matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
+    }
+
+    for (int i = 0; i < kNumStages; ++i) {
+        if (stageOffsets[i] > 0) {
+            GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + 
+                                                stageOffsets[i]);
+            coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
+                               srcRects[i]->fRight, srcRects[i]->fBottom, 
+                               vsize);
+            if (NULL != srcMatrices && NULL != srcMatrices[i]) {
+                srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
+            }
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
+    fDrawTarget = target;
+    if (NULL != fDrawTarget) {
+        fDrawTarget->saveCurrentDrawState(&fDrawState);
+    }
+}
+
+GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
+    if (NULL != fDrawTarget) {
+        fDrawTarget->restoreDrawState(fDrawState);
+    }
+}
+
diff --git a/gpu/src/GrGLIndexBuffer.cpp b/gpu/src/GrGLIndexBuffer.cpp
new file mode 100644
index 0000000..9539c8a
--- /dev/null
+++ b/gpu/src/GrGLIndexBuffer.cpp
@@ -0,0 +1,124 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLIndexBuffer.h"
+#include "GrGpuGL.h"
+
+GrGLIndexBuffer::GrGLIndexBuffer(GLuint id, GrGpuGL* gl, size_t sizeInBytes,
+                                   bool dynamic) :
+                                INHERITED(sizeInBytes, dynamic),
+                                fGL(gl),
+                                fBufferID(id),
+                                fLockPtr(NULL) {
+}
+
+GrGLIndexBuffer::~GrGLIndexBuffer() {
+    // make sure we've not been abandoned
+    if (fBufferID) {
+        fGL->notifyIndexBufferDelete(this);
+        GR_GL(DeleteBuffers(1, &fBufferID));
+    }
+}
+
+void GrGLIndexBuffer::bind() const {
+    GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+    fGL->notifyIndexBufferBind(this);
+}
+
+GLuint GrGLIndexBuffer::bufferID() const {
+    return fBufferID;
+}
+
+void GrGLIndexBuffer::abandon() {
+    fBufferID = 0;
+    fGL = NULL;
+    fLockPtr = NULL;
+}
+
+void* GrGLIndexBuffer::lock() {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (fGL->supportsBufferLocking()) {
+        bind();
+        // Let driver know it can discard the old data
+        GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL,
+                         dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        fLockPtr = GR_GL(MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GR_WRITE_ONLY));
+
+        return fLockPtr;
+    }
+    return NULL;
+}
+
+void* GrGLIndexBuffer::lockPtr() const {
+    return fLockPtr;
+}
+
+void GrGLIndexBuffer::unlock() {
+    GrAssert(fBufferID);
+    GrAssert(isLocked());
+    GrAssert(fGL->supportsBufferLocking());
+
+    bind();
+    GR_GL(UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
+    fLockPtr = NULL;
+}
+
+bool GrGLIndexBuffer::isLocked() const {
+    GrAssert(fBufferID);
+#if GR_DEBUG
+    if (fGL->supportsBufferLocking()) {
+        bind();
+        GLint mapped;
+        GR_GL(GetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER,
+                                   GR_BUFFER_MAPPED, &mapped));
+        GrAssert(!!mapped == !!fLockPtr);
+    }
+#endif
+    return NULL != fLockPtr;
+}
+
+bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes > size()) {
+        return false;
+    }
+    bind();
+    GLenum usage = dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
+    if (size() == srcSizeInBytes) {
+        GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+    } else {
+        GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL, usage));
+        GR_GL(BufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+    }
+    return true;
+}
+
+bool GrGLIndexBuffer::updateSubData(const void* src,
+                                    size_t srcSizeInBytes,
+                                    size_t offset) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes + offset > size()) {
+        return false;
+    }
+    bind();
+    GR_GL(BufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, srcSizeInBytes, src));
+    return true;
+}
+
diff --git a/gpu/src/GrGLInterface.cpp b/gpu/src/GrGLInterface.cpp
new file mode 100644
index 0000000..fa6aa92
--- /dev/null
+++ b/gpu/src/GrGLInterface.cpp
@@ -0,0 +1,351 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLInterface.h"
+#include "GrTypes.h"
+
+#include <stdio.h>
+
+#if defined(GR_GL_PROC_ADDRESS_HEADER)
+    #include GR_GL_PROC_ADDRESS_HEADER
+#endif
+
+#if !defined(GR_GL_PROC_ADDRESS)
+    #error "Must define GR_GL_PROC_ADDRESS"
+#endif
+
+#define GR_GL_GET_PROC(PROC_NAME) \
+    glBindings->f##PROC_NAME = \
+                reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>( \
+                            GR_GL_PROC_ADDRESS(gl##PROC_NAME)); \
+    GrAssert(NULL != glBindings->f##PROC_NAME && \
+             "Missing GL binding: " #PROC_NAME);
+
+#define GR_GL_GET_PROC_SUFFIX(PROC_NAME, SUFFIX) \
+    glBindings->f##PROC_NAME = \
+                reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>( \
+                        GR_GL_PROC_ADDRESS(gl##PROC_NAME##SUFFIX)); \
+    GrAssert(NULL != glBindings->f##PROC_NAME && \
+             "Missing GL binding: " #PROC_NAME);
+
+#define GR_GL_GET_PROC_SYMBOL(PROC_NAME) \
+    glBindings->f##PROC_NAME = reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>(gl##PROC_NAME);
+
+namespace {
+
+void gl_version_from_string(int* major, int* minor,
+                            const char* versionString) {
+    if (NULL == versionString) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#if GR_SUPPORT_GLDESKTOP
+    int n = sscanf(versionString, "%d.%d", major, minor);
+    if (n != 2) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#else
+    char profile[2];
+    int n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
+                   major, minor);
+    bool ok = 4 == n;
+    if (!ok) {
+        int n = sscanf(versionString, "OpenGL ES %d.%d", major, minor);
+        ok = 2 == n;
+    }
+    if (!ok) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#endif
+}
+
+bool has_gl_extension_from_string(const char* ext,
+                                  const char* extensionString) {
+    int extLength = strlen(ext);
+
+    while (true) {
+        int n = strcspn(extensionString, " ");
+        if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
+            return true;
+        }
+        if (0 == extensionString[n]) {
+            return false;
+        }
+        extensionString += n+1;
+    }
+
+    return false;
+}
+
+GrGLInterface* gGLInterface = NULL;
+
+void InitializeGLInterfaceExtensions(GrGLInterface* glBindings) {
+    int major, minor;
+    const char* versionString = reinterpret_cast<const char*>(
+                glBindings->fGetString(GL_VERSION));
+    const char* extensionString = reinterpret_cast<const char*>(
+                glBindings->fGetString(GL_EXTENSIONS));
+    gl_version_from_string(&major, &minor, versionString);
+
+    bool fboFound = false;
+#if GR_SUPPORT_GLDESKTOP
+    if (major >= 3 || has_gl_extension_from_string("GL_ARB_framebuffer_object",
+                                                   extensionString)) {
+        // GL_ARB_framebuffer_object doesn't use ARB suffix.
+        GR_GL_GET_PROC(GenFramebuffers);
+        GR_GL_GET_PROC(BindFramebuffer);
+        GR_GL_GET_PROC(FramebufferTexture2D);
+        GR_GL_GET_PROC(CheckFramebufferStatus);
+        GR_GL_GET_PROC(DeleteFramebuffers);
+        GR_GL_GET_PROC(RenderbufferStorage);
+        GR_GL_GET_PROC(GenRenderbuffers);
+        GR_GL_GET_PROC(DeleteRenderbuffers);
+        GR_GL_GET_PROC(FramebufferRenderbuffer);
+        GR_GL_GET_PROC(BindRenderbuffer);
+        GR_GL_GET_PROC(RenderbufferStorageMultisample);
+        GR_GL_GET_PROC(BlitFramebuffer);
+        fboFound = true;
+    }
+
+    #if GL_EXT_framebuffer_object && !GR_MAC_BUILD
+    if (!fboFound &&
+            has_gl_extension_from_string("GL_EXT_framebuffer_object",
+                                         extensionString)) {
+        GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
+        GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
+        GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
+        GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
+        GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
+        GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
+        GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
+        GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
+        GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
+        GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
+        fboFound = true;
+
+        if (has_gl_extension_from_string("GL_EXT_framebuffer_multisample",
+                                         extensionString)) {
+            GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
+        }
+        if (has_gl_extension_from_string("GL_EXT_framebuffer_blit",
+                                         extensionString)) {
+            GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
+        }
+    }
+    #endif
+
+    // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
+    GrAssert((major == 1 && minor >= 5) || major >=2);
+    GR_GL_GET_PROC(MapBuffer);
+    GR_GL_GET_PROC(UnmapBuffer);
+#else // !GR_SUPPORT_GLDESKTOP
+    #if GR_SUPPORT_GLES2
+    if (!fboFound && major >= 2) {// ES 2.0 supports FBO
+        GR_GL_GET_PROC(GenFramebuffers);
+        GR_GL_GET_PROC(BindFramebuffer);
+        GR_GL_GET_PROC(FramebufferTexture2D);
+        GR_GL_GET_PROC(CheckFramebufferStatus);
+        GR_GL_GET_PROC(DeleteFramebuffers);
+        GR_GL_GET_PROC(RenderbufferStorage);
+        GR_GL_GET_PROC(GenRenderbuffers);
+        GR_GL_GET_PROC(DeleteRenderbuffers);
+        GR_GL_GET_PROC(FramebufferRenderbuffer);
+        GR_GL_GET_PROC(BindRenderbuffer);
+        fboFound = true;
+    }
+    #endif
+
+    #if GL_OES_mapbuffer
+    if (!fboFound &&
+            has_gl_extension_from_string("GL_OES_framebuffer_object",
+                                         extensionString)) {
+        GR_GL_GET_PROC_SUFFIX(GenFramebuffers, OES);
+        GR_GL_GET_PROC_SUFFIX(BindFramebuffer, OES);
+        GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, OES);
+        GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, OES);
+        GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, OES);
+        GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, OES);
+        GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, OES);
+        GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, OES);
+        GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, OES);
+        GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, OES);
+        fboFound = true;
+    }
+    #endif
+
+    #if GL_APPLE_framebuffer_multisample
+    if (has_gl_extension_from_string("GL_APPLE_framebuffer_multisample",
+                                     extensionString)) {
+        GR_GL_GET_PROC_SUFFIX(ResolveMultisampleFramebuffer, APPLE);
+    }
+    #endif
+
+    #if GL_IMG_multisampled_render_to_texture
+    if (has_gl_extension_from_string(
+                "GL_IMG_multisampled_render_to_texture", extensionString)) {
+        GR_GL_GET_PROC_SUFFIX(FramebufferTexture2DMultisample, IMG);
+    }
+    #endif
+
+    #if GL_OES_mapbuffer
+    if (has_gl_extension_from_string("GL_OES_mapbuffer", extensionString)) {
+        GR_GL_GET_PROC_SUFFIX(MapBuffer, OES);
+        GR_GL_GET_PROC_SUFFIX(UnmapBuffer, OES);
+    }
+    #endif
+#endif  // !GR_SUPPORT_GLDESKTOP
+
+    if (!fboFound) {
+        // we require some form of FBO
+        GrAssert(!"No FBOs supported?");
+    }
+}
+
+void GrGLInitializeGLInterface(GrGLInterface* glBindings) {
+    Gr_bzero(glBindings, sizeof(GrGLInterface));
+
+#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES1
+    // These entry points only exist on desktop GL implementations.
+    GR_GL_GET_PROC_SYMBOL(Color4ub);
+    GR_GL_GET_PROC_SYMBOL(ColorPointer);
+    GR_GL_GET_PROC_SYMBOL(DisableClientState);
+    GR_GL_GET_PROC_SYMBOL(EnableClientState);
+    GR_GL_GET_PROC_SYMBOL(LoadMatrixf);
+    GR_GL_GET_PROC_SYMBOL(MatrixMode);
+    GR_GL_GET_PROC_SYMBOL(PointSize);
+    GR_GL_GET_PROC_SYMBOL(ShadeModel);
+    GR_GL_GET_PROC_SYMBOL(TexCoordPointer);
+    GR_GL_GET_PROC_SYMBOL(TexEnvi);
+    GR_GL_GET_PROC_SYMBOL(VertexPointer);
+    GR_GL_GET_PROC(ClientActiveTexture);
+#endif
+
+    // The following gl entry points are part of GL 1.1, and will always be
+    // exported as symbols.
+    // Note that on windows, the wglGetProcAddress call will fail to retrieve
+    // these entry points.
+    GR_GL_GET_PROC_SYMBOL(BlendFunc);
+    GR_GL_GET_PROC_SYMBOL(Clear);
+    GR_GL_GET_PROC_SYMBOL(ClearColor);
+    GR_GL_GET_PROC_SYMBOL(ClearStencil);
+    GR_GL_GET_PROC_SYMBOL(ColorMask);
+    GR_GL_GET_PROC_SYMBOL(CullFace);
+    GR_GL_GET_PROC_SYMBOL(DeleteTextures);
+    GR_GL_GET_PROC_SYMBOL(DepthMask);
+    GR_GL_GET_PROC_SYMBOL(Disable);
+    GR_GL_GET_PROC_SYMBOL(DrawArrays);
+    GR_GL_GET_PROC_SYMBOL(DrawElements);
+    GR_GL_GET_PROC_SYMBOL(Enable);
+    GR_GL_GET_PROC_SYMBOL(FrontFace);
+    GR_GL_GET_PROC_SYMBOL(GenTextures);
+    GR_GL_GET_PROC_SYMBOL(GetError);
+    GR_GL_GET_PROC_SYMBOL(GetIntegerv);
+    GR_GL_GET_PROC_SYMBOL(GetString);
+    GR_GL_GET_PROC_SYMBOL(LineWidth);
+    GR_GL_GET_PROC_SYMBOL(PixelStorei);
+    GR_GL_GET_PROC_SYMBOL(ReadPixels);
+    GR_GL_GET_PROC_SYMBOL(Scissor);
+    GR_GL_GET_PROC_SYMBOL(StencilFunc);
+    GR_GL_GET_PROC_SYMBOL(StencilMask);
+    GR_GL_GET_PROC_SYMBOL(StencilOp);
+    GR_GL_GET_PROC_SYMBOL(TexImage2D);
+    GR_GL_GET_PROC_SYMBOL(TexParameteri);
+    GR_GL_GET_PROC_SYMBOL(TexSubImage2D);
+    GR_GL_GET_PROC_SYMBOL(Viewport);
+
+    // Capture the remaining entry points as gl extensions.
+    GR_GL_GET_PROC(ActiveTexture);
+    GR_GL_GET_PROC(AttachShader);
+    GR_GL_GET_PROC(BindAttribLocation);
+    GR_GL_GET_PROC(BindBuffer);
+    GR_GL_GET_PROC(BindTexture);
+    GR_GL_GET_PROC(BlendColor);
+    GR_GL_GET_PROC(BufferData);
+    GR_GL_GET_PROC(BufferSubData);
+    GR_GL_GET_PROC(CompileShader);
+    GR_GL_GET_PROC(CompressedTexImage2D);
+    GR_GL_GET_PROC(CreateProgram);
+    GR_GL_GET_PROC(CreateShader);
+    GR_GL_GET_PROC(DeleteBuffers);
+    GR_GL_GET_PROC(DeleteProgram);
+    GR_GL_GET_PROC(DeleteShader);
+    GR_GL_GET_PROC(DisableVertexAttribArray);
+    GR_GL_GET_PROC(EnableVertexAttribArray);
+    GR_GL_GET_PROC(GenBuffers);
+    GR_GL_GET_PROC(GetBufferParameteriv);
+    GR_GL_GET_PROC(GetProgramInfoLog);
+    GR_GL_GET_PROC(GetProgramiv);
+    GR_GL_GET_PROC(GetShaderInfoLog);
+    GR_GL_GET_PROC(GetShaderiv);
+    GR_GL_GET_PROC(GetUniformLocation);
+    GR_GL_GET_PROC(LinkProgram);
+    GR_GL_GET_PROC(ShaderSource);
+    GR_GL_GET_PROC(StencilFuncSeparate);
+    GR_GL_GET_PROC(StencilMaskSeparate);
+    GR_GL_GET_PROC(StencilOpSeparate);
+    GR_GL_GET_PROC(Uniform1fv);
+    GR_GL_GET_PROC(Uniform1i);
+    GR_GL_GET_PROC(Uniform4fv);
+    GR_GL_GET_PROC(UniformMatrix3fv);
+    GR_GL_GET_PROC(UseProgram);
+    GR_GL_GET_PROC(VertexAttrib4fv);
+    GR_GL_GET_PROC(VertexAttribPointer);
+
+    InitializeGLInterfaceExtensions(glBindings);
+}
+
+}  // unnamed namespace
+
+void GrGLSetGLInterface(GrGLInterface* gl_interface) {
+    gGLInterface = gl_interface;
+}
+
+GrGLInterface* GrGLGetGLInterface() {
+    return gGLInterface;
+}
+
+void GrGLSetDefaultGLInterface() {
+    static GrGLInterface gDefaultInterface;
+    static bool gDefaultInitialized = false;
+    GrAssert(!gDefaultInitialized);
+
+    if (!gDefaultInitialized) {
+        GrGLInitializeGLInterface(&gDefaultInterface);
+        GrGLSetGLInterface(&gDefaultInterface);
+    }
+}
+
+bool has_gl_extension(const char* ext) {
+    const char* glstr = reinterpret_cast<const char*>(
+                GrGLGetGLInterface()->fGetString(GL_EXTENSIONS));
+
+    return has_gl_extension_from_string(ext, glstr);
+}
+
+void gl_version(int* major, int* minor) {
+    const char* v = reinterpret_cast<const char*>(
+                GrGLGetGLInterface()->fGetString(GL_VERSION));
+    gl_version_from_string(major, minor, v);
+}
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
new file mode 100644
index 0000000..7488d0f
--- /dev/null
+++ b/gpu/src/GrGLTexture.cpp
@@ -0,0 +1,173 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLTexture.h"
+#include "GrGpuGL.h"
+
+GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
+                                   GrGLTexID* texID,
+                                   GLuint stencilBits,
+                                   const GrGLIRect& viewport,
+                                   GrGLTexture* texture,
+                                   GrGpuGL* gl) : INHERITED(texture,
+                                                            viewport.fWidth,
+                                                            viewport.fHeight,
+                                                            stencilBits) {
+    fGL                     = gl;
+    fRTFBOID                = ids.fRTFBOID;
+    fTexFBOID               = ids.fTexFBOID;
+    fStencilRenderbufferID  = ids.fStencilRenderbufferID;
+    fMSColorRenderbufferID  = ids.fMSColorRenderbufferID;
+    fNeedsResolve           = false;
+    fViewport               = viewport;
+    fOwnIDs                 = ids.fOwnIDs;
+    fTexIDObj               = texID;
+    GrSafeRef(fTexIDObj);
+}
+
+GrGLRenderTarget::~GrGLRenderTarget() {
+    fGL->notifyRenderTargetDelete(this);
+    if (fOwnIDs) {
+        if (fTexFBOID) {
+            GR_GL(DeleteFramebuffers(1, &fTexFBOID));
+        }
+        if (fRTFBOID && fRTFBOID != fTexFBOID) {
+            GR_GL(DeleteFramebuffers(1, &fRTFBOID));
+        }
+        if (fStencilRenderbufferID) {
+            GR_GL(DeleteRenderbuffers(1, &fStencilRenderbufferID));
+        }
+        if (fMSColorRenderbufferID) {
+            GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
+        }
+    }
+    GrSafeUnref(fTexIDObj);
+}
+
+void GrGLRenderTarget::abandon() {
+    fRTFBOID                = 0;
+    fTexFBOID               = 0;
+    fStencilRenderbufferID  = 0;
+    fMSColorRenderbufferID  = 0;
+    if (NULL != fTexIDObj) {
+        fTexIDObj->abandon();
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+const GLenum GrGLTexture::gWrapMode2GLWrap[] = {
+    GL_CLAMP_TO_EDGE,
+    GL_REPEAT,
+#ifdef GL_MIRRORED_REPEAT
+    GL_MIRRORED_REPEAT
+#else
+    GL_REPEAT       // GL_MIRRORED_REPEAT not supported :(
+#endif
+};
+
+
+GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
+                         const GLRenderTargetIDs& rtIDs,
+                         const TexParams& initialTexParams,
+                         GrGpuGL* gl)
+        : INHERITED(textureDesc.fContentWidth, 
+                    textureDesc.fContentHeight, 
+                    textureDesc.fFormat) {
+
+    fTexParams          = initialTexParams;
+    fTexIDObj           = new GrGLTexID(textureDesc.fTextureID);
+    fUploadFormat       = textureDesc.fUploadFormat;
+    fUploadByteCount    = textureDesc.fUploadByteCount;
+    fUploadType         = textureDesc.fUploadType;
+    fOrientation        = textureDesc.fOrientation;
+    fAllocWidth         = textureDesc.fAllocWidth;
+    fAllocHeight        = textureDesc.fAllocHeight;
+    fScaleX             = GrIntToScalar(textureDesc.fContentWidth) /
+                            textureDesc.fAllocWidth;
+    fScaleY             = GrIntToScalar(textureDesc.fContentHeight) /
+                            textureDesc.fAllocHeight;
+    fRenderTarget       = NULL;
+    fGpuGL              = gl;
+
+    GrAssert(0 != textureDesc.fTextureID);
+
+    if (rtIDs.fTexFBOID) {
+        // we render to the top left
+        GrGLIRect vp;
+        vp.fLeft   = 0;
+        vp.fWidth  = textureDesc.fContentWidth;
+        vp.fHeight = textureDesc.fContentHeight;
+        vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
+
+        fRenderTarget = new GrGLRenderTarget(rtIDs, fTexIDObj,
+                                             textureDesc.fStencilBits,
+                                             vp, this, gl);
+    }
+}
+
+GrGLTexture::~GrGLTexture() {
+    fGpuGL->notifyTextureDelete(this);
+    fTexIDObj->unref();
+    GrSafeUnref(fRenderTarget);
+}
+
+void GrGLTexture::abandon() {
+    fTexIDObj->abandon();
+    if (NULL != fRenderTarget) {
+        fRenderTarget->abandon();
+    }
+}
+
+GrRenderTarget* GrGLTexture::asRenderTarget() {
+    return (GrRenderTarget*)fRenderTarget;
+}
+
+void GrGLTexture::releaseRenderTarget() {
+    GrSafeUnref(fRenderTarget);
+    fRenderTarget = NULL;
+}
+
+void GrGLTexture::uploadTextureData(uint32_t x,
+                                    uint32_t y,
+                                    uint32_t width,
+                                    uint32_t height,
+                                    const void* srcData) {
+    
+    fGpuGL->setSpareTextureUnit();
+
+    // glCompressedTexSubImage2D doesn't support any formats
+    // (at least without extensions)
+    GrAssert(fUploadFormat != GR_PALETTE8_RGBA8);
+
+    // If we need to update textures that are created upside down
+    // then we have to modify this code to flip the srcData
+    GrAssert(kTopDown_Orientation == fOrientation);
+    GR_GL(BindTexture(GL_TEXTURE_2D, fTexIDObj->id()));
+    GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount));
+    GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, 
+                        fUploadFormat, fUploadType, srcData));
+
+}
+
+intptr_t GrGLTexture::getTextureHandle() {
+    return fTexIDObj->id();
+}
+
+
+
diff --git a/gpu/src/GrGLUtil.cpp b/gpu/src/GrGLUtil.cpp
new file mode 100644
index 0000000..2cb887a
--- /dev/null
+++ b/gpu/src/GrGLUtil.cpp
@@ -0,0 +1,37 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "GrGLConfig.h"
+
+void GrGLCheckErr(const char* location, const char* call) {
+    uint32_t err =  GrGLGetGLInterface()->fGetError();
+    if (GL_NO_ERROR != err) {
+        GrPrintf("---- glGetError %x", err);
+        if (NULL != location) {
+            GrPrintf(" at\n\t%s", location);
+        }
+        if (NULL != call) {
+            GrPrintf("\n\t\t%s", call);
+        }
+        GrPrintf("\n");
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
+
+bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
diff --git a/gpu/src/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
new file mode 100644
index 0000000..69913bf
--- /dev/null
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -0,0 +1,122 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLVertexBuffer.h"
+#include "GrGpuGL.h"
+
+GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, size_t sizeInBytes,
+                                   bool dynamic) :
+                                   INHERITED(sizeInBytes, dynamic),
+                                   fGL(gl),
+                                   fBufferID(id),
+                                   fLockPtr(NULL) {
+}
+
+GrGLVertexBuffer::~GrGLVertexBuffer() {
+    // make sure we've not been abandoned
+    if (fBufferID) {
+        fGL->notifyVertexBufferDelete(this);
+        GR_GL(DeleteBuffers(1, &fBufferID));
+    }
+}
+
+void GrGLVertexBuffer::bind() const {
+    GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+    fGL->notifyVertexBufferBind(this);
+}
+
+GLuint GrGLVertexBuffer::bufferID() const {
+    return fBufferID;
+}
+
+void GrGLVertexBuffer::abandon() {
+    fBufferID = 0;
+    fGL = NULL;
+    fLockPtr = NULL;
+}
+
+void* GrGLVertexBuffer::lock() {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (fGL->supportsBufferLocking()) {
+        bind();
+        // Let driver know it can discard the old data
+        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL,
+                         dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        fLockPtr = GR_GL(MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY));
+        return fLockPtr;
+    }
+    return NULL;
+}
+
+void* GrGLVertexBuffer::lockPtr() const {
+    return fLockPtr;
+}
+
+void GrGLVertexBuffer::unlock() {
+    GrAssert(fBufferID);
+    GrAssert(isLocked());
+    GrAssert(fGL->supportsBufferLocking());
+
+    bind();
+    GR_GL(UnmapBuffer(GL_ARRAY_BUFFER));
+    fLockPtr = NULL;
+}
+
+bool GrGLVertexBuffer::isLocked() const {
+    GrAssert(fBufferID);
+#if GR_DEBUG
+    if (fGL->supportsBufferLocking()) {
+        GLint mapped;
+        bind();
+        GR_GL(GetBufferParameteriv(GL_ARRAY_BUFFER, GR_BUFFER_MAPPED, &mapped));
+        GrAssert(!!mapped == !!fLockPtr);
+    }
+#endif
+    return NULL != fLockPtr;
+}
+
+bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes > size()) {
+        return false;
+    }
+    bind();
+    GLenum usage = dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
+    if (size() == srcSizeInBytes) {
+        GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+    } else {
+        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL, usage));
+        GR_GL(BufferSubData(GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+    }
+    return true;
+}
+
+bool GrGLVertexBuffer::updateSubData(const void* src,
+                                     size_t srcSizeInBytes,
+                                     size_t offset) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes + offset > size()) {
+        return false;
+    }
+    bind();
+    GR_GL(BufferSubData(GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
+    return true;
+}
+
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
new file mode 100644
index 0000000..2d763e2
--- /dev/null
+++ b/gpu/src/GrGpu.cpp
@@ -0,0 +1,697 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrTextStrike.h"
+#include "GrTextureCache.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+#include "GrVertexBuffer.h"
+#include "GrBufferAllocPool.h"
+#include "GrPathRenderer.h"
+
+// probably makes no sense for this to be less than a page
+static const size_t VERTEX_POOL_VB_SIZE = 1 << 12;
+static const int VERTEX_POOL_VB_COUNT = 1;
+
+////////////////////////////////////////////////////////////////////////////////
+
+size_t GrTexture::BytesPerPixel(PixelConfig config) {
+    switch (config) {
+        case kAlpha_8_PixelConfig:
+        case kIndex_8_PixelConfig:
+            return 1;
+        case kRGB_565_PixelConfig:
+        case kRGBA_4444_PixelConfig:
+            return 2;
+        case kRGBA_8888_PixelConfig:
+        case kRGBX_8888_PixelConfig:
+            return 4;
+        default:
+            return 0;
+    }
+}
+
+bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
+    switch (config) {
+        case GrTexture::kRGB_565_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool GrTexture::PixelConfigIsAlphaOnly(PixelConfig config) {
+    switch (config) {
+        case GrTexture::kAlpha_8_PixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+extern void gr_run_unittests();
+
+GrGpu::GrGpu() : f8bitPaletteSupport(false),
+                 fCurrPoolVertexBuffer(NULL),
+                 fCurrPoolStartVertex(0),
+                 fCurrPoolIndexBuffer(NULL),
+                 fCurrPoolStartIndex(0),
+                 fVertexPool(NULL),
+                 fIndexPool(NULL),
+                 fQuadIndexBuffer(NULL),
+                 fUnitSquareVertexBuffer(NULL),
+                 fPathRenderer(NULL),
+                 fContextIsDirty(true),
+                 fVertexPoolInUse(false),
+                 fIndexPoolInUse(false) {
+#if GR_DEBUG
+    //gr_run_unittests();
+#endif
+    resetStats();
+}
+
+GrGpu::~GrGpu() {
+    GrSafeUnref(fQuadIndexBuffer);
+    GrSafeUnref(fUnitSquareVertexBuffer);
+    delete fVertexPool;
+    delete fIndexPool;
+    delete fPathRenderer;
+}
+
+void GrGpu::resetContext() {
+}
+
+void GrGpu::unimpl(const char msg[]) {
+#if GR_DEBUG
+    GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrTexture* GrGpu::createTexture(const TextureDesc& desc,
+                                const void* srcData, size_t rowBytes) {
+    this->handleDirtyContext();
+    return this->createTextureHelper(desc, srcData, rowBytes);
+}
+
+GrRenderTarget* GrGpu::createPlatformRenderTarget(intptr_t platformRenderTarget,
+                                                  int stencilBits,
+                                                  int width, int height) {
+    this->handleDirtyContext();
+    return this->createPlatformRenderTargetHelper(platformRenderTarget,
+                                                  stencilBits,
+                                                  width, height);
+}
+
+GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
+    this->handleDirtyContext();
+    return this->createRenderTargetFrom3DApiStateHelper();
+}
+
+GrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) {
+    this->handleDirtyContext();
+    return this->createVertexBufferHelper(size, dynamic);
+}
+
+GrIndexBuffer* GrGpu::createIndexBuffer(uint32_t size, bool dynamic) {
+    this->handleDirtyContext();
+    return this->createIndexBufferHelper(size, dynamic);
+}
+
+void GrGpu::eraseColor(GrColor color) {
+    this->handleDirtyContext();
+    this->eraseColorHelper(color);
+}
+
+void GrGpu::forceRenderTargetFlush() {
+    this->handleDirtyContext();
+    this->forceRenderTargetFlushHelper();
+}
+
+bool GrGpu::readPixels(int left, int top, int width, int height,
+                       GrTexture::PixelConfig config, void* buffer) {
+    this->handleDirtyContext();
+    return this->readPixelsHelper(left, top, width, height, config, buffer);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
+
+GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535);
+
+static inline void fill_indices(uint16_t* indices, int quadCount) {
+    for (int i = 0; i < quadCount; ++i) {
+        indices[6 * i + 0] = 4 * i + 0;
+        indices[6 * i + 1] = 4 * i + 1;
+        indices[6 * i + 2] = 4 * i + 2;
+        indices[6 * i + 3] = 4 * i + 0;
+        indices[6 * i + 4] = 4 * i + 2;
+        indices[6 * i + 5] = 4 * i + 3;
+    }
+}
+
+const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
+    if (NULL == fQuadIndexBuffer) {
+        static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
+        GrGpu* me = const_cast<GrGpu*>(this);
+        fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
+        if (NULL != fQuadIndexBuffer) {
+            uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock();
+            if (NULL != indices) {
+                fill_indices(indices, MAX_QUADS);
+                fQuadIndexBuffer->unlock();
+            } else {
+                indices = (uint16_t*)GrMalloc(SIZE);
+                fill_indices(indices, MAX_QUADS);
+                if (!fQuadIndexBuffer->updateData(indices, SIZE)) {
+                    fQuadIndexBuffer->unref();
+                    fQuadIndexBuffer = NULL;
+                    GrCrash("Can't get indices into buffer!");
+                }
+                GrFree(indices);
+            }
+        }
+    }
+
+    return fQuadIndexBuffer;
+}
+
+const GrVertexBuffer* GrGpu::getUnitSquareVertexBuffer() const {
+    if (NULL == fUnitSquareVertexBuffer) {
+
+        static const GrPoint DATA[] = {
+            GrPoint(0,         0),
+            GrPoint(GR_Scalar1,0),
+            GrPoint(GR_Scalar1,GR_Scalar1),
+            GrPoint(0,         GR_Scalar1)
+        };
+        static const size_t SIZE = sizeof(DATA);
+
+        GrGpu* me = const_cast<GrGpu*>(this);
+        fUnitSquareVertexBuffer = me->createVertexBuffer(SIZE, false);
+        if (NULL != fUnitSquareVertexBuffer) {
+            if (!fUnitSquareVertexBuffer->updateData(DATA, SIZE)) {
+                fUnitSquareVertexBuffer->unref();
+                fUnitSquareVertexBuffer = NULL;
+                GrCrash("Can't get vertices into buffer!");
+            }
+        }
+    }
+
+    return fUnitSquareVertexBuffer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrGpu::clipWillBeSet(const GrClip& newClip) {
+    if (newClip != fClip) {
+        fClipState.fClipIsDirty = true;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// stencil settings to use when clip is in stencil
+const GrStencilSettings GrGpu::gClipStencilSettings = {
+    kKeep_StencilOp,             kKeep_StencilOp,
+    kKeep_StencilOp,             kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
+    0,                           0,
+    0,                           0,
+    0,                           0
+};
+
+// mapping of clip-respecting stencil funcs to normal stencil funcs
+// mapping depends on whether stencil-clipping is in effect.
+static const GrStencilFunc gGrClipToNormalStencilFunc[2][kClipStencilFuncCount] = {
+    {// Stencil-Clipping is DISABLED, effectively always inside the clip
+        // In the Clip Funcs
+        kAlways_StencilFunc,          // kAlwaysIfInClip_StencilFunc
+        kEqual_StencilFunc,           // kEqualIfInClip_StencilFunc
+        kLess_StencilFunc,            // kLessIfInClip_StencilFunc
+        kLEqual_StencilFunc,          // kLEqualIfInClip_StencilFunc
+        // Special in the clip func that forces user's ref to be 0.
+        kNotEqual_StencilFunc,        // kNonZeroIfInClip_StencilFunc
+                                      // make ref 0 and do normal nequal.
+    },
+    {// Stencil-Clipping is ENABLED
+        // In the Clip Funcs
+        kEqual_StencilFunc,           // kAlwaysIfInClip_StencilFunc
+                                      // eq stencil clip bit, mask
+                                      // out user bits.
+
+        kEqual_StencilFunc,           // kEqualIfInClip_StencilFunc
+                                      // add stencil bit to mask and ref
+
+        kLess_StencilFunc,            // kLessIfInClip_StencilFunc
+        kLEqual_StencilFunc,          // kLEqualIfInClip_StencilFunc
+                                      // for both of these we can add
+                                      // the clip bit to the mask and
+                                      // ref and compare as normal
+        // Special in the clip func that forces user's ref to be 0.
+        kLess_StencilFunc,            // kNonZeroIfInClip_StencilFunc
+                                      // make ref have only the clip bit set
+                                      // and make comparison be less
+                                      // 10..0 < 1..user_bits..
+    }
+};
+
+GrStencilFunc GrGpu::ConvertStencilFunc(bool stencilInClip, GrStencilFunc func) {
+    GrAssert(func >= 0);
+    if (func >= kBasicStencilFuncCount) {
+        GrAssert(func < kStencilFuncCount);
+        func = gGrClipToNormalStencilFunc[stencilInClip ? 1 : 0][func - kBasicStencilFuncCount];
+        GrAssert(func >= 0 && func < kBasicStencilFuncCount);
+    }
+    return func;
+}
+
+void GrGpu::ConvertStencilFuncAndMask(GrStencilFunc func,
+                                      bool clipInStencil,
+                                      unsigned int clipBit,
+                                      unsigned int userBits,
+                                      unsigned int* ref,
+                                      unsigned int* mask) {
+    if (func < kBasicStencilFuncCount) {
+        *mask &= userBits;
+        *ref &= userBits;
+    } else {
+        if (clipInStencil) {
+            switch (func) {
+                case kAlwaysIfInClip_StencilFunc:
+                    *mask = clipBit;
+                    *ref = clipBit;
+                    break;
+                case kEqualIfInClip_StencilFunc:
+                case kLessIfInClip_StencilFunc:
+                case kLEqualIfInClip_StencilFunc:
+                    *mask = (*mask & userBits) | clipBit;
+                    *ref = (*ref & userBits) | clipBit;
+                    break;
+                case kNonZeroIfInClip_StencilFunc:
+                    *mask = (*mask & userBits) | clipBit;
+                    *ref = clipBit;
+                    break;
+                default:
+                    GrCrash("Unknown stencil func");
+            }
+        } else {
+            *mask &= userBits;
+            *ref &= userBits;
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define VISUALIZE_COMPLEX_CLIP 0
+
+#if VISUALIZE_COMPLEX_CLIP
+    #include "GrRandom.h"
+    GrRandom gRandom;
+    #define SET_RANDOM_COLOR this->setColor(0xff000000 | gRandom.nextU());
+#else
+    #define SET_RANDOM_COLOR
+#endif
+
+bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
+    const GrIRect* r = NULL;
+    GrIRect clipRect;
+
+    // we check this early because we need a valid
+    // render target to setup stencil clipping
+    // before even going into flushGraphicsState
+    if (NULL == fCurrDrawState.fRenderTarget) {
+        GrAssert(!"No render target bound.");
+        return false;
+    }
+
+    if (fCurrDrawState.fFlagBits & kClip_StateBit) {
+        GrRenderTarget& rt = *fCurrDrawState.fRenderTarget;
+
+        GrRect bounds;
+        GrRect rtRect;
+        rtRect.setLTRB(0, 0,
+                       GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
+        if (fClip.hasConservativeBounds()) {
+            bounds = fClip.getConservativeBounds();
+            bounds.intersectWith(rtRect);
+        } else {
+            bounds = rtRect;
+        }
+
+        bounds.roundOut(&clipRect);
+        if  (clipRect.isEmpty()) {
+            clipRect.setLTRB(0,0,0,0);
+        }
+        r = &clipRect;
+
+        fClipState.fClipInStencil = !fClip.isRect() &&
+                                    !fClip.isEmpty() &&
+                                    !bounds.isEmpty();
+
+        if (fClipState.fClipInStencil &&
+            (fClipState.fClipIsDirty ||
+             fClip != rt.fLastStencilClip)) {
+
+            rt.fLastStencilClip = fClip;
+            // we set the current clip to the bounds so that our recursive
+            // draws are scissored to them. We use the copy of the complex clip
+            // in the rt to render
+            const GrClip& clip = rt.fLastStencilClip;
+            fClip.setFromRect(bounds);
+
+            AutoStateRestore asr(this);
+            AutoInternalDrawGeomRestore aidgr(this);
+
+            this->setViewMatrix(GrMatrix::I());
+            this->eraseStencilClip(clipRect);
+            this->flushScissor(NULL);
+#if !VISUALIZE_COMPLEX_CLIP
+            this->enableState(kNoColorWrites_StateBit);
+#else
+            this->disableState(kNoColorWrites_StateBit);
+#endif
+            int count = clip.getElementCount();
+            int clipBit = rt.stencilBits();
+            clipBit = (1 << (clipBit-1));
+
+            // often we'll see the first two elements of the clip are
+            // the full rt size and another element intersected with it.
+            // We can skip the first full-size rect and save a big rect draw.
+            int firstElement = 0;
+            if (clip.getElementCount() > 1 &&
+                kRect_ClipType == clip.getElementType(0) &&
+                kIntersect_SetOp == clip.getOp(1)&&
+                clip.getRect(0).contains(bounds)) {
+                firstElement = 1;
+            }
+
+            // walk through each clip element and perform its set op
+            // with the existing clip.
+            for (int c = firstElement; c < count; ++c) {
+                GrPathFill fill;
+                // enabled at bottom of loop
+                this->disableState(kModifyStencilClip_StateBit);
+
+                bool canDrawDirectToClip;
+                if (kRect_ClipType == clip.getElementType(c)) {
+                    canDrawDirectToClip = true;
+                    fill = kEvenOdd_PathFill;
+                } else {
+                    fill = clip.getPathFill(c);
+                    GrPathRenderer* pr = this->getPathRenderer();
+                    canDrawDirectToClip = pr->requiresStencilPass(this, clip.getPath(c), fill);
+                }
+
+                GrSetOp op = firstElement == c ? kReplace_SetOp : clip.getOp(c);
+                int passes;
+                GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
+
+                canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, canDrawDirectToClip,
+                                                                       clipBit, IsFillInverted(fill),
+                                                                       &passes, stencilSettings);
+
+                // draw the element to the client stencil bits if necessary
+                if (!canDrawDirectToClip) {
+                    if (kRect_ClipType == clip.getElementType(c)) {
+                        static const GrStencilSettings gDrawToStencil = {
+                            kIncClamp_StencilOp, kIncClamp_StencilOp,
+                            kIncClamp_StencilOp, kIncClamp_StencilOp,
+                            kAlways_StencilFunc, kAlways_StencilFunc,
+                            0xffffffff,          0xffffffff,
+                            0x00000000,          0x00000000,
+                            0xffffffff,          0xffffffff,
+                        };
+                        this->setStencil(gDrawToStencil);
+                        SET_RANDOM_COLOR
+                        this->drawSimpleRect(clip.getRect(c), NULL, 0);
+                    } else {
+                        SET_RANDOM_COLOR
+                        getPathRenderer()->drawPathToStencil(this, clip.getPath(c),
+                                                             NonInvertedFill(fill),
+                                                             NULL);
+                    }
+                }
+
+                // now we modify the clip bit by rendering either the clip
+                // element directly or a bounding rect of the entire clip.
+                this->enableState(kModifyStencilClip_StateBit);
+                for (int p = 0; p < passes; ++p) {
+                    this->setStencil(stencilSettings[p]);
+                    if (canDrawDirectToClip) {
+                        if (kRect_ClipType == clip.getElementType(c)) {
+                            SET_RANDOM_COLOR
+                            this->drawSimpleRect(clip.getRect(c), NULL, 0);
+                        } else {
+                            SET_RANDOM_COLOR
+                            getPathRenderer()->drawPath(this, 0,
+                                                        clip.getPath(c),
+                                                        fill, NULL);
+                        }
+                    } else {
+                        SET_RANDOM_COLOR
+                        this->drawSimpleRect(bounds, 0, NULL);
+                    }
+                }
+            }
+            fClip = clip;
+            // recusive draws would have disabled this.
+            fClipState.fClipInStencil = true;
+        }
+
+        fClipState.fClipIsDirty = false;
+    }
+
+    // Must flush the scissor after graphics state
+    if (!this->flushGraphicsState(type)) {
+        return false;
+    }
+    this->flushScissor(r);
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrGpu::drawIndexed(GrPrimitiveType type,
+                        int startVertex,
+                        int startIndex,
+                        int vertexCount,
+                        int indexCount) {
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
+             fReservedGeometry.fLocked);
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
+             fReservedGeometry.fLocked);
+
+    this->handleDirtyContext();
+
+    if (!this->setupClipAndFlushState(type)) {
+        return;
+    }
+
+#if GR_COLLECT_STATS
+    fStats.fVertexCnt += vertexCount;
+    fStats.fIndexCnt  += indexCount;
+    fStats.fDrawCnt   += 1;
+#endif
+
+    int sVertex = startVertex;
+    int sIndex = startIndex;
+    setupGeometry(&sVertex, &sIndex, vertexCount, indexCount);
+
+    drawIndexedHelper(type, sVertex, sIndex,
+                      vertexCount, indexCount);
+}
+
+void GrGpu::drawNonIndexed(GrPrimitiveType type,
+                           int startVertex,
+                           int vertexCount) {
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
+             fReservedGeometry.fLocked);
+
+    this->handleDirtyContext();
+
+    if (!this->setupClipAndFlushState(type)) {
+        return;
+    }
+#if GR_COLLECT_STATS
+    fStats.fVertexCnt += vertexCount;
+    fStats.fDrawCnt   += 1;
+#endif
+
+    int sVertex = startVertex;
+    setupGeometry(&sVertex, NULL, vertexCount, 0);
+
+    drawNonIndexedHelper(type, sVertex, vertexCount);
+}
+
+void GrGpu::finalizeReservedVertices() {
+    GrAssert(NULL != fVertexPool);
+    fVertexPool->unlock();
+}
+
+void GrGpu::finalizeReservedIndices() {
+    GrAssert(NULL != fIndexPool);
+    fIndexPool->unlock();
+}
+
+void GrGpu::prepareVertexPool() {
+    if (NULL == fVertexPool) {
+        fVertexPool = new GrVertexBufferAllocPool(this, true,
+                                                  VERTEX_POOL_VB_SIZE,
+                                                  VERTEX_POOL_VB_COUNT);
+    } else if (!fVertexPoolInUse) {
+        // the client doesn't have valid data in the pool
+        fVertexPool->reset();
+    }
+}
+
+void GrGpu::prepareIndexPool() {
+    if (NULL == fVertexPool) {
+        fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
+    } else if (!fIndexPoolInUse) {
+        // the client doesn't have valid data in the pool
+        fIndexPool->reset();
+    }
+}
+
+bool GrGpu::acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                  void**         vertices,
+                                  void**         indices) {
+    GrAssert(!fReservedGeometry.fLocked);
+    size_t reservedVertexSpace = 0;
+
+    if (fReservedGeometry.fVertexCount) {
+        GrAssert(NULL != vertices);
+
+        this->prepareVertexPool();
+
+        *vertices = fVertexPool->makeSpace(vertexLayout,
+                                           fReservedGeometry.fVertexCount,
+                                           &fCurrPoolVertexBuffer,
+                                           &fCurrPoolStartVertex);
+        if (NULL == *vertices) {
+            return false;
+        }
+        reservedVertexSpace = VertexSize(vertexLayout) *
+                              fReservedGeometry.fVertexCount;
+    }
+    if (fReservedGeometry.fIndexCount) {
+        GrAssert(NULL != indices);
+
+        this->prepareIndexPool();
+
+        *indices = fIndexPool->makeSpace(fReservedGeometry.fIndexCount,
+                                         &fCurrPoolIndexBuffer,
+                                         &fCurrPoolStartIndex);
+        if (NULL == *indices) {
+            fVertexPool->putBack(reservedVertexSpace);
+            fCurrPoolVertexBuffer = NULL;
+            return false;
+        }
+    }
+    return true;
+}
+
+void GrGpu::releaseGeometryHelper() {}
+
+void GrGpu::setVertexSourceToArrayHelper(const void* vertexArray, int vertexCount) {
+    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+    prepareVertexPool();
+#if GR_DEBUG
+    bool success =
+#endif
+    fVertexPool->appendVertices(fGeometrySrc.fVertexLayout,
+                                vertexCount,
+                                vertexArray,
+                                &fCurrPoolVertexBuffer,
+                                &fCurrPoolStartVertex);
+    GR_DEBUGASSERT(success);
+}
+
+void GrGpu::setIndexSourceToArrayHelper(const void* indexArray, int indexCount) {
+    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+    prepareIndexPool();
+#if GR_DEBUG
+    bool success =
+#endif
+    fIndexPool->appendIndices(indexCount,
+                              indexArray,
+                              &fCurrPoolIndexBuffer,
+                              &fCurrPoolStartIndex);
+    GR_DEBUGASSERT(success);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrPathRenderer* GrGpu::getPathRenderer() {
+    if (NULL == fPathRenderer) {
+        fPathRenderer = new GrDefaultPathRenderer(this->supportsTwoSidedStencil(),
+                                                  this->supportsStencilWrapOps());
+    }
+    return fPathRenderer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+const GrGpu::Stats& GrGpu::getStats() const {
+    return fStats;
+}
+
+void GrGpu::resetStats() {
+    memset(&fStats, 0, sizeof(fStats));
+}
+
+void GrGpu::printStats() const {
+    if (GR_COLLECT_STATS) {
+     GrPrintf(
+     "-v-------------------------GPU STATS----------------------------v-\n"
+     "Stats collection is: %s\n"
+     "Draws: %04d, Verts: %04d, Indices: %04d\n"
+     "ProgChanges: %04d, TexChanges: %04d, RTChanges: %04d\n"
+     "TexCreates: %04d, RTCreates:%04d\n"
+     "-^--------------------------------------------------------------^-\n",
+     (GR_COLLECT_STATS ? "ON" : "OFF"),
+    fStats.fDrawCnt, fStats.fVertexCnt, fStats.fIndexCnt,
+    fStats.fProgChngCnt, fStats.fTextureChngCnt, fStats.fRenderTargetChngCnt,
+    fStats.fTextureCreateCnt, fStats.fRenderTargetCreateCnt);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrTexture::~GrTexture() {
+    // use this to set a break-point if needed
+//    Gr_clz(3);
+}
+
+const GrSamplerState GrSamplerState::gClampNoFilter(
+    GrSamplerState::kClamp_WrapMode,
+    GrSamplerState::kClamp_WrapMode,
+    GrSamplerState::kNormal_SampleMode,
+    GrMatrix::I(),
+    false);
+
+
+
+
diff --git a/gpu/src/GrGpuFactory.cpp b/gpu/src/GrGpuFactory.cpp
new file mode 100644
index 0000000..7c2db2b
--- /dev/null
+++ b/gpu/src/GrGpuFactory.cpp
@@ -0,0 +1,74 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+// must be before GrGLConfig.h
+#if GR_WIN32_BUILD
+//    #include "GrGpuD3D9.h"
+#endif
+
+#include "GrGLConfig.h"
+
+
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+    #include "GrGpuGLFixed.h"
+#endif
+
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+    #include "GrGpuGLShaders2.h"
+#endif
+
+#include "GrGpu.h"
+
+GrGpu* GrGpu::Create(Engine engine, Platform3DContext context3D) {
+    // If no GL bindings have been installed, fall-back to calling the
+    // GL functions that have been linked with the executable.
+    if (!GrGLGetGLInterface())
+        GrGLSetDefaultGLInterface();
+
+    GrGpu* gpu = NULL;
+
+    switch (engine) {
+        case kOpenGL_Shaders_Engine:
+            GrAssert(NULL == context3D);
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+            gpu = new GrGpuGLShaders2;
+#endif
+            break;
+        case kOpenGL_Fixed_Engine:
+            GrAssert(NULL == context3D);
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+            gpu = new GrGpuGLFixed;
+#endif
+            break;
+        case kDirect3D9_Engine:
+            GrAssert(NULL != context3D);
+#if GR_WIN32_BUILD
+//            gpu = new GrGpuD3D9((IDirect3DDevice9*)context3D);
+#endif
+            break;
+        default:
+            GrAssert(!"unknown engine");
+            break;
+    }
+
+    return gpu;
+}
+
+
+
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
new file mode 100644
index 0000000..f2a2a8f
--- /dev/null
+++ b/gpu/src/GrGpuGL.cpp
@@ -0,0 +1,1924 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrGpuGL.h"
+#include "GrMemory.h"
+#if GR_WIN32_BUILD
+    // need to get wglGetProcAddress
+    #undef WIN32_LEAN_AND_MEAN
+    #define WIN32_LEAN_AND_MEAN 1
+    #include <windows.h>
+    #undef WIN32_LEAN_AND_MEAN
+#endif
+
+
+static const GLuint GR_MAX_GLUINT = ~0;
+static const GLint  GR_INVAL_GLINT = ~0;
+
+// we use a spare texture unit to avoid
+// mucking with the state of any of the stages.
+static const int SPARE_TEX_UNIT = GrGpuGL::kNumStages;
+
+#define SKIP_CACHE_CHECK    true
+
+static const GLenum gXfermodeCoeff2Blend[] = {
+    GL_ZERO,
+    GL_ONE,
+    GL_SRC_COLOR,
+    GL_ONE_MINUS_SRC_COLOR,
+    GL_DST_COLOR,
+    GL_ONE_MINUS_DST_COLOR,
+    GL_SRC_ALPHA,
+    GL_ONE_MINUS_SRC_ALPHA,
+    GL_DST_ALPHA,
+    GL_ONE_MINUS_DST_ALPHA,
+    GL_CONSTANT_COLOR,
+    GL_ONE_MINUS_CONSTANT_COLOR,
+    GL_CONSTANT_ALPHA,
+    GL_ONE_MINUS_CONSTANT_ALPHA,
+};
+
+bool GrGpuGL::BlendCoefReferencesConstant(GrBlendCoeff coeff) {
+    static const bool gCoeffReferencesBlendConst[] = {
+        false,
+        false,
+        false,
+        false,
+        false,
+        false,
+        false,
+        false,
+        false,
+        false,
+        true,
+        true,
+        true,
+        true,
+    };
+    return gCoeffReferencesBlendConst[coeff];
+    GR_STATIC_ASSERT(kBlendCoeffCount == GR_ARRAY_COUNT(gCoeffReferencesBlendConst));
+}
+
+GR_STATIC_ASSERT(0 == kZero_BlendCoeff);
+GR_STATIC_ASSERT(1 == kOne_BlendCoeff);
+GR_STATIC_ASSERT(2 == kSC_BlendCoeff);
+GR_STATIC_ASSERT(3 == kISC_BlendCoeff);
+GR_STATIC_ASSERT(4 == kDC_BlendCoeff);
+GR_STATIC_ASSERT(5 == kIDC_BlendCoeff);
+GR_STATIC_ASSERT(6 == kSA_BlendCoeff);
+GR_STATIC_ASSERT(7 == kISA_BlendCoeff);
+GR_STATIC_ASSERT(8 == kDA_BlendCoeff);
+GR_STATIC_ASSERT(9 == kIDA_BlendCoeff);
+GR_STATIC_ASSERT(10 == kConstC_BlendCoeff);
+GR_STATIC_ASSERT(11 == kIConstC_BlendCoeff);
+GR_STATIC_ASSERT(12 == kConstA_BlendCoeff);
+GR_STATIC_ASSERT(13 == kIConstA_BlendCoeff);
+
+GR_STATIC_ASSERT(kBlendCoeffCount == GR_ARRAY_COUNT(gXfermodeCoeff2Blend));
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
+                                  GrSamplerState::SampleMode mode,
+                                  GrMatrix* matrix) {
+    GrAssert(NULL != texture);
+    GrAssert(NULL != matrix);
+    if (GR_Scalar1 != texture->contentScaleX() ||
+        GR_Scalar1 != texture->contentScaleY()) {
+        if (GrSamplerState::kRadial_SampleMode == mode) {
+            GrMatrix scale;
+            scale.setScale(texture->contentScaleX(), texture->contentScaleX());
+            matrix->postConcat(scale);
+        } else if (GrSamplerState::kNormal_SampleMode == mode) {
+            GrMatrix scale;
+            scale.setScale(texture->contentScaleX(), texture->contentScaleY());
+            matrix->postConcat(scale);
+        } else {
+            GrPrintf("We haven't handled NPOT adjustment for other sample modes!");
+        }
+    }
+    GrGLTexture::Orientation orientation = texture->orientation();
+    if (GrGLTexture::kBottomUp_Orientation == orientation) {
+        GrMatrix invY;
+        invY.setAll(GR_Scalar1, 0,           0,
+                    0,          -GR_Scalar1, GR_Scalar1,
+                    0,          0,           GrMatrix::I()[8]);
+        matrix->postConcat(invY);
+    } else {
+        GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
+    }
+}
+
+bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture,
+                                      const GrSamplerState& sampler) {
+    GrAssert(NULL != texture);
+    if (!sampler.getMatrix().isIdentity()) {
+        return false;
+    }
+    if (GR_Scalar1 != texture->contentScaleX() ||
+        GR_Scalar1 != texture->contentScaleY()) {
+        return false;
+    }
+    GrGLTexture::Orientation orientation = texture->orientation();
+    if (GrGLTexture::kBottomUp_Orientation == orientation) {
+        return false;
+    } else {
+        GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool gPrintStartupSpew;
+
+static bool fbo_test(int w, int h) {
+
+    GLint savedFBO;
+    GLint savedTexUnit;
+    GR_GL_GetIntegerv(GL_ACTIVE_TEXTURE, &savedTexUnit);
+    GR_GL_GetIntegerv(GR_FRAMEBUFFER_BINDING, &savedFBO);
+
+    GR_GL(ActiveTexture(GL_TEXTURE0 + SPARE_TEX_UNIT));
+
+    GLuint testFBO;
+    GR_GL(GenFramebuffers(1, &testFBO));
+    GR_GL(BindFramebuffer(GR_FRAMEBUFFER, testFBO));
+    GLuint testRTTex;
+    GR_GL(GenTextures(1, &testRTTex));
+    GR_GL(BindTexture(GL_TEXTURE_2D, testRTTex));
+    // some implementations require texture to be mip-map complete before
+    // FBO with level 0 bound as color attachment will be framebuffer complete.
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+    GR_GL(TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
+                     0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
+    GR_GL(BindTexture(GL_TEXTURE_2D, 0));
+    GR_GL(FramebufferTexture2D(GR_FRAMEBUFFER, GR_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_2D, testRTTex, 0));
+    GLenum status = GR_GL(CheckFramebufferStatus(GR_FRAMEBUFFER));
+    GR_GL(DeleteFramebuffers(1, &testFBO));
+    GR_GL(DeleteTextures(1, &testRTTex));
+
+    GR_GL(ActiveTexture(savedTexUnit));
+    GR_GL(BindFramebuffer(GR_FRAMEBUFFER, savedFBO));
+
+    return status == GR_FRAMEBUFFER_COMPLETE;
+}
+
+GrGpuGL::GrGpuGL() {
+
+    if (gPrintStartupSpew) {
+        GrPrintf("------------------------- create GrGpuGL %p --------------\n",
+                 this);
+        GrPrintf("------ VENDOR %s\n",
+                 GrGLGetGLInterface()->fGetString(GL_VENDOR));
+        GrPrintf("------ RENDERER %s\n",
+                 GrGLGetGLInterface()->fGetString(GL_RENDERER));
+        GrPrintf("------ VERSION %s\n",
+                 GrGLGetGLInterface()->fGetString(GL_VERSION));
+        GrPrintf("------ EXTENSIONS\n %s \n",
+                 GrGLGetGLInterface()->fGetString(GL_EXTENSIONS));
+    }
+
+    GrGLClearErr();
+
+    resetDirtyFlags();
+
+    GLint maxTextureUnits;
+    // check FS and fixed-function texture unit limits
+    // we only use textures in the fragment stage currently.
+    // checks are > to make sure we have a spare unit.
+#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES2
+    GR_GL_GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
+    GrAssert(maxTextureUnits > kNumStages);
+#endif
+#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES1
+    GR_GL_GetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
+    GrAssert(maxTextureUnits > kNumStages);
+#endif
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Check for supported features.
+
+    int major, minor;
+    gl_version(&major, &minor);
+
+    GLint numFormats;
+    GR_GL_GetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
+    GrAutoSTMalloc<10, GLint> formats(numFormats);
+    GR_GL_GetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
+    for (int i = 0; i < numFormats; ++i) {
+        if (formats[i] == GR_PALETTE8_RGBA8) {
+            f8bitPaletteSupport = true;
+            break;
+        }
+    }
+
+    if (gPrintStartupSpew) {
+        GrPrintf("Palette8 support: %s\n", (f8bitPaletteSupport ? "YES" : "NO"));
+    }
+
+    GR_STATIC_ASSERT(0 == kNone_AALevel);
+    GR_STATIC_ASSERT(1 == kLow_AALevel);
+    GR_STATIC_ASSERT(2 == kMed_AALevel);
+    GR_STATIC_ASSERT(3 == kHigh_AALevel);
+
+    memset(fAASamples, 0, sizeof(fAASamples));
+    fMSFBOType = kNone_MSFBO;
+    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
+        fMSFBOType = kIMG_MSFBO;
+        if (gPrintStartupSpew) {
+            GrPrintf("MSAA Support: IMG ES EXT.\n");
+        }
+    }
+    else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
+        fMSFBOType = kApple_MSFBO;
+        if (gPrintStartupSpew) {
+            GrPrintf("MSAA Support: APPLE ES EXT.\n");
+        }
+    }
+#if GR_SUPPORT_GLDESKTOP
+    else if ((major >= 3) ||
+             has_gl_extension("GL_ARB_framebuffer_object") ||
+             (has_gl_extension("GL_EXT_framebuffer_multisample") &&
+              has_gl_extension("GL_EXT_framebuffer_blit"))) {
+        fMSFBOType = kDesktop_MSFBO;
+         if (gPrintStartupSpew) {
+             GrPrintf("MSAA Support: DESKTOP\n");
+         }
+    }
+#endif
+    else {
+        if (gPrintStartupSpew) {
+            GrPrintf("MSAA Support: NONE\n");
+        }
+    }
+
+    if (kNone_MSFBO != fMSFBOType) {
+        GLint maxSamples;
+        GLenum maxSampleGetter = (kIMG_MSFBO == fMSFBOType) ?
+                                                            GR_MAX_SAMPLES_IMG :
+                                                            GR_MAX_SAMPLES;
+        GR_GL_GetIntegerv(maxSampleGetter, &maxSamples);
+        if (maxSamples > 1 ) {
+            fAASamples[kNone_AALevel] = 0;
+            fAASamples[kLow_AALevel] = GrMax(2,
+                                             GrFixedFloorToInt((GR_FixedHalf) *
+                                                             maxSamples));
+            fAASamples[kMed_AALevel] = GrMax(2,
+                                             GrFixedFloorToInt(((GR_Fixed1*3)/4) *
+                                                             maxSamples));
+            fAASamples[kHigh_AALevel] = maxSamples;
+        }
+        if (gPrintStartupSpew) {
+            GrPrintf("\tMax Samples: %d\n", maxSamples);
+        }
+    }
+
+#if GR_SUPPORT_GLDESKTOP
+    fHasStencilWrap = (major >= 2 || (major == 1 && minor >= 4)) ||
+                      has_gl_extension("GL_EXT_stencil_wrap");
+#else
+    fHasStencilWrap = (major >= 2) || has_gl_extension("GL_OES_stencil_wrap");
+#endif
+    if (gPrintStartupSpew) {
+        GrPrintf("Stencil Wrap: %s\n", (fHasStencilWrap ? "YES" : "NO"));
+    }
+
+#if GR_SUPPORT_GLDESKTOP
+    // we could also look for GL_ATI_separate_stencil extension or
+    // GL_EXT_stencil_two_side but they use different function signatures
+    // than GL2.0+ (and than each other).
+    fTwoSidedStencilSupport = (major >= 2);
+    // supported on GL 1.4 and higher or by extension
+    fStencilWrapOpsSupport = (major > 1) ||
+                             ((1 == major) && (minor >= 4)) ||
+                              has_gl_extension("GL_EXT_stencil_wrap");
+#else
+    // ES 2 has two sided stencil but 1.1 doesn't. There doesn't seem to be
+    // an ES1 extension.
+    fTwoSidedStencilSupport = (major >= 2);
+    // stencil wrap support is in ES2, ES1 requires extension.
+    fStencilWrapOpsSupport = (major > 1) ||
+                              has_gl_extension("GL_OES_stencil_wrap");
+
+#endif
+    if (gPrintStartupSpew) {
+        GrPrintf("Stencil Caps: TwoSide: %s, Wrap: %s\n",
+                (fTwoSidedStencilSupport ? "YES" : "NO"),
+                (fStencilWrapOpsSupport ? "YES" : "NO"));
+    }
+
+#if GR_SUPPORT_GLDESKTOP
+    fRGBA8Renderbuffer = true;
+#else
+    fRGBA8Renderbuffer = has_gl_extension("GL_OES_rgb8_rgba8");
+#endif
+    if (gPrintStartupSpew) {
+        GrPrintf("RGBA Renderbuffer: %s\n", (fRGBA8Renderbuffer ? "YES" : "NO"));
+    }
+
+#if GR_SUPPORT_GLES
+    if (GR_GL_32BPP_COLOR_FORMAT == GR_BGRA) {
+        GrAssert(has_gl_extension("GL_EXT_texture_format_BGRA8888"));
+    }
+#endif
+
+#if GR_SUPPORT_GLDESKTOP
+    fBufferLockSupport = true; // we require VBO support and the desktop VBO
+                               // extension includes glMapBuffer.
+#else
+    fBufferLockSupport = has_gl_extension("GL_OES_mapbuffer");
+#endif
+
+    if (gPrintStartupSpew) {
+        GrPrintf("Map Buffer: %s\n", (fBufferLockSupport ? "YES" : "NO"));
+    }
+
+#if GR_SUPPORT_GLDESKTOP
+    if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
+        fNPOTTextureTileSupport = true;
+        fNPOTTextureSupport = true;
+    } else {
+        fNPOTTextureTileSupport = false;
+        fNPOTTextureSupport = false;
+    }
+#else
+    if (major >= 2) {
+        fNPOTTextureSupport = true;
+        fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot");
+    } else {
+        fNPOTTextureSupport = has_gl_extension("GL_APPLE_texture_2D_limited_npot");
+        fNPOTTextureTileSupport = false;
+    }
+#endif
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Experiments to determine limitations that can't be queried. TODO: Make
+    // these a preprocess that generate some compile time constants.
+
+    // sanity check to make sure we can at least create an FBO from a POT texture
+
+    bool simpleFBOSuccess = fbo_test(128, 128);
+    if (gPrintStartupSpew) {
+        if (!simpleFBOSuccess) {
+            GrPrintf("FBO Sanity Test: FAILED\n");
+        } else {
+            GrPrintf("FBO Sanity Test: PASSED\n");
+        }
+    }
+    GrAssert(simpleFBOSuccess);
+
+    /* Experimentation has found that some GLs that support NPOT textures
+       do not support FBOs with a NPOT texture. They report "unsupported" FBO
+       status. I don't know how to explicitly query for this. Do an
+       experiment. Note they may support NPOT with a renderbuffer but not a
+       texture. Presumably, the implementation bloats the renderbuffer
+       internally to the next POT.
+     */
+    bool fNPOTRenderTargetSupport = false;
+    if (fNPOTTextureSupport) {
+        fNPOTRenderTargetSupport = fbo_test(200, 200);
+    }
+
+    if (gPrintStartupSpew) {
+        if (fNPOTTextureSupport) {
+            GrPrintf("NPOT textures supported\n");
+            if (fNPOTTextureTileSupport) {
+                GrPrintf("NPOT texture tiling supported\n");
+            } else {
+                GrPrintf("NPOT texture tiling NOT supported\n");
+            }
+            if (fNPOTRenderTargetSupport) {
+                GrPrintf("NPOT render targets supported\n");
+            } else {
+                GrPrintf("NPOT render targets NOT supported\n");
+            }
+        } else {
+            GrPrintf("NPOT textures NOT supported\n");
+        }
+    }
+
+    /* The iPhone 4 has a restriction that for an FBO with texture color
+       attachment with height <= 8 then the width must be <= height. Here
+       we look for such a limitation.
+     */
+    fMinRenderTargetHeight = GR_INVAL_GLINT;
+    GLint maxRenderSize;
+    GR_GL_GetIntegerv(GR_MAX_RENDERBUFFER_SIZE, &maxRenderSize);
+
+    if (gPrintStartupSpew) {
+        GrPrintf("Small height FBO texture experiments\n");
+    }
+
+    for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? ++i : i *= 2) {
+        GLuint w = maxRenderSize;
+        GLuint h = i;
+        if (fbo_test(w, h)) {
+            if (gPrintStartupSpew) {
+                GrPrintf("\t[%d, %d]: PASSED\n", w, h);
+            }
+            fMinRenderTargetHeight = i;
+            break;
+        } else {
+            if (gPrintStartupSpew) {
+                GrPrintf("\t[%d, %d]: FAILED\n", w, h);
+            }
+        }
+    }
+    GrAssert(GR_INVAL_GLINT != fMinRenderTargetHeight);
+
+    if (gPrintStartupSpew) {
+        GrPrintf("Small width FBO texture experiments\n");
+    }
+    fMinRenderTargetWidth = GR_MAX_GLUINT;
+    for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) {
+        GLuint w = i;
+        GLuint h = maxRenderSize;
+        if (fbo_test(w, h)) {
+            if (gPrintStartupSpew) {
+                GrPrintf("\t[%d, %d]: PASSED\n", w, h);
+            }
+            fMinRenderTargetWidth = i;
+            break;
+        } else {
+            if (gPrintStartupSpew) {
+                GrPrintf("\t[%d, %d]: FAILED\n", w, h);
+            }
+        }
+    }
+    GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth);
+
+    GR_GL_GetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension);
+}
+
+GrGpuGL::~GrGpuGL() {
+}
+
+void GrGpuGL::resetContext() {
+    // We detect cases when blending is effectively off
+    fHWBlendDisabled = false;
+    GR_GL(Enable(GL_BLEND));
+
+    // we don't use the zb at all
+    GR_GL(Disable(GL_DEPTH_TEST));
+    GR_GL(DepthMask(GL_FALSE));
+
+    GR_GL(Disable(GL_CULL_FACE));
+    GR_GL(FrontFace(GL_CCW));
+    fHWDrawState.fDrawFace = kBoth_DrawFace;
+
+    GR_GL(Disable(GL_DITHER));
+#if GR_SUPPORT_GLDESKTOP
+    GR_GL(Disable(GL_LINE_SMOOTH));
+    GR_GL(Disable(GL_POINT_SMOOTH));
+    GR_GL(Disable(GL_MULTISAMPLE));
+#endif
+
+    GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+    fHWDrawState.fFlagBits = 0;
+
+    // we only ever use lines in hairline mode
+    GR_GL(LineWidth(1));
+
+    // invalid
+    fActiveTextureUnitIdx = -1;
+
+    // illegal values
+    fHWDrawState.fSrcBlend = (GrBlendCoeff)-1;
+    fHWDrawState.fDstBlend = (GrBlendCoeff)-1;
+
+    fHWDrawState.fBlendConstant = 0x00000000;
+    GR_GL(BlendColor(0,0,0,0));
+
+    fHWDrawState.fColor = GrColor_ILLEGAL;
+
+    fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+
+    for (int s = 0; s < kNumStages; ++s) {
+        fHWDrawState.fTextures[s] = NULL;
+        fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax,
+                                                        -GR_ScalarMax,
+                                                        true);
+
+        fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix());
+    }
+
+    fHWBounds.fScissorRect.invalidate();
+    fHWBounds.fScissorEnabled = false;
+    GR_GL(Disable(GL_SCISSOR_TEST));
+    fHWBounds.fViewportRect.invalidate();
+
+    fHWDrawState.fStencilSettings.invalidate();
+    fHWStencilClip = false;
+    fClipState.fClipIsDirty = true;
+
+    fHWGeometryState.fIndexBuffer = NULL;
+    fHWGeometryState.fVertexBuffer = NULL;
+    GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+    GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+    fHWGeometryState.fArrayPtrsDirty = true;
+
+    GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+    fHWDrawState.fRenderTarget = NULL;
+}
+
+GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width,
+                                                int height) {
+    GrGLRenderTarget::GLRenderTargetIDs rtIDs;
+    rtIDs.fStencilRenderbufferID = 0;
+    rtIDs.fMSColorRenderbufferID = 0;
+    rtIDs.fTexFBOID              = 0;
+    rtIDs.fOwnIDs                = false;
+    GrGLIRect viewport;
+
+    // viewport is in GL coords (top >= bottom)
+    viewport.fLeft      = 0;
+    viewport.fBottom    = 0;
+    viewport.fWidth     = width;
+    viewport.fHeight    = height;
+
+    rtIDs.fRTFBOID  = (GLuint)platformRenderTarget;
+    rtIDs.fTexFBOID = (GLuint)platformRenderTarget;
+
+    return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+}
+
+GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
+
+    GrGLRenderTarget::GLRenderTargetIDs rtIDs;
+
+    GR_GL_GetIntegerv(GR_FRAMEBUFFER_BINDING, (GLint*)&rtIDs.fRTFBOID);
+    rtIDs.fTexFBOID = rtIDs.fRTFBOID;
+    rtIDs.fMSColorRenderbufferID = 0;
+    rtIDs.fStencilRenderbufferID = 0;
+
+    GrGLIRect viewport;
+    viewport.setFromGLViewport();
+    GLuint stencilBits;
+    GR_GL_GetIntegerv(GL_STENCIL_BITS, (GLint*)&stencilBits);
+
+    rtIDs.fOwnIDs = false;
+
+    return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const GLuint UNKNOWN_BITS = ~0;
+
+// defines stencil formats from more to less preferred
+static const struct {
+    GLenum  fEnum;
+    GLuint  fBits;
+} gStencilFormats[] = {
+    {GR_STENCIL_INDEX8,     8},
+
+#if GR_SUPPORT_GLDESKTOP
+    {GR_STENCIL_INDEX16,    16},
+#endif
+
+    {GR_DEPTH24_STENCIL8,   8},
+    {GR_STENCIL_INDEX4,     4},
+
+#if GR_SUPPORT_GLDESKTOP
+    {GL_STENCIL_INDEX,      UNKNOWN_BITS},
+    {GR_DEPTH_STENCIL,      UNKNOWN_BITS}
+#endif
+};
+
+// good to set a break-point here to know when createTexture fails
+static GrTexture* return_null_texture() {
+//    GrAssert(!"null texture");
+    return NULL;
+}
+
+#if GR_DEBUG
+static size_t as_size_t(int x) {
+    return x;
+}
+#endif
+
+GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc,
+                                        const void* srcData,
+                                        size_t rowBytes) {
+
+#if GR_COLLECT_STATS
+    ++fStats.fTextureCreateCnt;
+#endif
+
+    setSpareTextureUnit();
+
+    static const GrGLTexture::TexParams DEFAULT_PARAMS = {
+        GL_NEAREST,
+        GL_CLAMP_TO_EDGE,
+        GL_CLAMP_TO_EDGE
+    };
+
+    GrGLTexture::GLTextureDesc glDesc;
+    GLenum internalFormat;
+
+    glDesc.fContentWidth  = desc.fWidth;
+    glDesc.fContentHeight = desc.fHeight;
+    glDesc.fAllocWidth    = desc.fWidth;
+    glDesc.fAllocHeight   = desc.fHeight;
+    glDesc.fStencilBits   = 0;
+    glDesc.fFormat        = desc.fFormat;
+
+    bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag);
+    if (!canBeTexture(desc.fFormat,
+                      &internalFormat,
+                      &glDesc.fUploadFormat,
+                      &glDesc.fUploadType)) {
+        return return_null_texture();
+    }
+
+    GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples));
+    GLint samples = fAASamples[desc.fAALevel];
+    if (kNone_MSFBO == fMSFBOType && desc.fAALevel != kNone_AALevel) {
+        GrPrintf("AA RT requested but not supported on this platform.");
+    }
+
+    GR_GL(GenTextures(1, &glDesc.fTextureID));
+    if (!glDesc.fTextureID) {
+        return return_null_texture();
+    }
+
+    glDesc.fUploadByteCount = GrTexture::BytesPerPixel(desc.fFormat);
+
+    /*
+     *  check if our srcData has extra bytes past each row. If so, we need
+     *  to trim those off here, since GL doesn't let us pass the rowBytes as
+     *  a parameter to glTexImage2D
+     */
+#if GR_SUPPORT_GLDESKTOP
+    if (srcData) {
+        GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH,
+                          rowBytes / glDesc.fUploadByteCount));
+    }
+#else
+    GrAutoSMalloc<128 * 128> trimStorage;
+    size_t trimRowBytes = desc.fWidth * glDesc.fUploadByteCount;
+    if (srcData && (trimRowBytes < rowBytes)) {
+        size_t trimSize = desc.fHeight * trimRowBytes;
+        trimStorage.realloc(trimSize);
+        // now copy the data into our new storage, skipping the trailing bytes
+        const char* src = (const char*)srcData;
+        char* dst = (char*)trimStorage.get();
+        for (uint32_t y = 0; y < desc.fHeight; y++) {
+            memcpy(dst, src, trimRowBytes);
+            src += rowBytes;
+            dst += trimRowBytes;
+        }
+        // now point srcData to our trimmed version
+        srcData = trimStorage.get();
+    }
+#endif
+
+    if (renderTarget) {
+        if (!this->npotRenderTargetSupport()) {
+            glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
+            glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
+        }
+
+        glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
+                                        glDesc.fAllocWidth);
+        glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
+                                         glDesc.fAllocHeight);
+    } else if (!this->npotTextureSupport()) {
+        glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
+        glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
+    }
+
+    GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_MAG_FILTER,
+                        DEFAULT_PARAMS.fFilter));
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_MIN_FILTER,
+                        DEFAULT_PARAMS.fFilter));
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_WRAP_S,
+                        DEFAULT_PARAMS.fWrapS));
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_WRAP_T,
+                        DEFAULT_PARAMS.fWrapT));
+
+    GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount));
+    if (GrTexture::kIndex_8_PixelConfig == desc.fFormat &&
+        supports8BitPalette()) {
+        // ES only supports CompressedTexImage2D, not CompressedTexSubimage2D
+        GrAssert(desc.fWidth == glDesc.fAllocWidth);
+        GrAssert(desc.fHeight == glDesc.fAllocHeight);
+        GLsizei imageSize = glDesc.fAllocWidth * glDesc.fAllocHeight +
+                            kColorTableSize;
+        GR_GL(CompressedTexImage2D(GL_TEXTURE_2D, 0, glDesc.fUploadFormat,
+                                   glDesc.fAllocWidth, glDesc.fAllocHeight,
+                                   0, imageSize, srcData));
+        GrGL_RestoreResetRowLength();
+    } else {
+        if (NULL != srcData && (glDesc.fAllocWidth != desc.fWidth ||
+                                glDesc.fAllocHeight != desc.fHeight)) {
+            GR_GL(TexImage2D(GL_TEXTURE_2D, 0, internalFormat,
+                             glDesc.fAllocWidth, glDesc.fAllocHeight,
+                             0, glDesc.fUploadFormat, glDesc.fUploadType, NULL));
+            GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, desc.fWidth,
+                                desc.fHeight, glDesc.fUploadFormat,
+                                glDesc.fUploadType, srcData));
+            GrGL_RestoreResetRowLength();
+
+            uint32_t extraW = glDesc.fAllocWidth  - desc.fWidth;
+            uint32_t extraH = glDesc.fAllocHeight - desc.fHeight;
+            uint32_t maxTexels = extraW * extraH;
+            maxTexels = GrMax(extraW * desc.fHeight, maxTexels);
+            maxTexels = GrMax(desc.fWidth * extraH, maxTexels);
+
+            GrAutoSMalloc<128*128> texels(glDesc.fUploadByteCount * maxTexels);
+
+            uint32_t rowSize = desc.fWidth * glDesc.fUploadByteCount;
+            if (extraH) {
+                uint8_t* lastRowStart = (uint8_t*) srcData +
+                                        (desc.fHeight - 1) * rowSize;
+                uint8_t* extraRowStart = (uint8_t*)texels.get();
+
+                for (uint32_t i = 0; i < extraH; ++i) {
+                    memcpy(extraRowStart, lastRowStart, rowSize);
+                    extraRowStart += rowSize;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, 0, desc.fHeight, desc.fWidth,
+                                    extraH, glDesc.fUploadFormat, glDesc.fUploadType,
+                                    texels.get()));
+            }
+            if (extraW) {
+                uint8_t* edgeTexel = (uint8_t*)srcData + rowSize - glDesc.fUploadByteCount;
+                uint8_t* extraTexel = (uint8_t*)texels.get();
+                for (uint32_t j = 0; j < desc.fHeight; ++j) {
+                    for (uint32_t i = 0; i < extraW; ++i) {
+                        memcpy(extraTexel, edgeTexel, glDesc.fUploadByteCount);
+                        extraTexel += glDesc.fUploadByteCount;
+                    }
+                    edgeTexel += rowSize;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, desc.fWidth, 0, extraW,
+                                    desc.fHeight, glDesc.fUploadFormat,
+                                    glDesc.fUploadType, texels.get()));
+            }
+            if (extraW && extraH) {
+                uint8_t* cornerTexel = (uint8_t*)srcData + desc.fHeight * rowSize
+                                       - glDesc.fUploadByteCount;
+                uint8_t* extraTexel = (uint8_t*)texels.get();
+                for (uint32_t i = 0; i < extraW*extraH; ++i) {
+                    memcpy(extraTexel, cornerTexel, glDesc.fUploadByteCount);
+                    extraTexel += glDesc.fUploadByteCount;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, desc.fWidth, desc.fHeight,
+                                    extraW, extraH, glDesc.fUploadFormat,
+                                    glDesc.fUploadType, texels.get()));
+            }
+
+        } else {
+            GR_GL(TexImage2D(GL_TEXTURE_2D, 0, internalFormat, glDesc.fAllocWidth,
+                             glDesc.fAllocHeight, 0, glDesc.fUploadFormat,
+                             glDesc.fUploadType, srcData));
+            GrGL_RestoreResetRowLength();
+        }
+    }
+
+    glDesc.fOrientation = GrGLTexture::kTopDown_Orientation;
+
+    GrGLRenderTarget::GLRenderTargetIDs rtIDs;
+    rtIDs.fStencilRenderbufferID = 0;
+    rtIDs.fMSColorRenderbufferID = 0;
+    rtIDs.fRTFBOID = 0;
+    rtIDs.fTexFBOID = 0;
+    rtIDs.fOwnIDs = true;
+    GLenum msColorRenderbufferFormat = -1;
+
+    if (renderTarget) {
+#if GR_COLLECT_STATS
+        ++fStats.fRenderTargetCreateCnt;
+#endif
+        bool failed = true;
+        GLenum status;
+        GLint err;
+
+        // If need have both RT flag and srcData we have
+        // to invert the data before uploading because FBO
+        // will be rendered bottom up
+        GrAssert(NULL == srcData);
+        glDesc.fOrientation =  GrGLTexture::kBottomUp_Orientation;
+
+        GR_GL(GenFramebuffers(1, &rtIDs.fTexFBOID));
+        GrAssert(rtIDs.fTexFBOID);
+
+        // If we are using multisampling and any extension other than the IMG
+        // one we will create two FBOs. We render to one and then resolve to
+        // the texture bound to the other. The IMG extension does an implicit
+        // resolve.
+        if (samples > 1 && kIMG_MSFBO != fMSFBOType && kNone_MSFBO != fMSFBOType) {
+            GR_GL(GenFramebuffers(1, &rtIDs.fRTFBOID));
+            GrAssert(0 != rtIDs.fRTFBOID);
+            GR_GL(GenRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+            GrAssert(0 != rtIDs.fMSColorRenderbufferID);
+            if (!fboInternalFormat(desc.fFormat, &msColorRenderbufferFormat)) {
+                GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+                GR_GL(DeleteTextures(1, &glDesc.fTextureID));
+                GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID));
+                GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID));
+                return return_null_texture();
+            }
+        } else {
+            rtIDs.fRTFBOID = rtIDs.fTexFBOID;
+        }
+        int attempts = 1;
+        if (!(kNoPathRendering_TextureFlag & desc.fFlags)) {
+            GR_GL(GenRenderbuffers(1, &rtIDs.fStencilRenderbufferID));
+            GrAssert(0 != rtIDs.fStencilRenderbufferID);
+            attempts = GR_ARRAY_COUNT(gStencilFormats);
+        }
+
+        // someone suggested that some systems might require
+        // unbinding the texture before we call FramebufferTexture2D
+        // (seems unlikely)
+        GR_GL(BindTexture(GL_TEXTURE_2D, 0));
+
+        err = ~GL_NO_ERROR;
+        for (int i = 0; i < attempts; ++i) {
+            if (rtIDs.fStencilRenderbufferID) {
+                GR_GL(BindRenderbuffer(GR_RENDERBUFFER,
+                                       rtIDs.fStencilRenderbufferID));
+                if (samples > 1) {
+                    GR_GL_NO_ERR(RenderbufferStorageMultisample(
+                                                GR_RENDERBUFFER,
+                                                samples,
+                                                gStencilFormats[i].fEnum,
+                                                glDesc.fAllocWidth,
+                                                glDesc.fAllocHeight));
+                } else {
+                    GR_GL_NO_ERR(RenderbufferStorage(GR_RENDERBUFFER,
+                                                     gStencilFormats[i].fEnum,
+                                                     glDesc.fAllocWidth,
+                                                     glDesc.fAllocHeight));
+                }
+                err = glGetError();
+                if (err != GL_NO_ERROR) {
+                    continue;
+                }
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GrAssert(samples > 1);
+                GR_GL(BindRenderbuffer(GR_RENDERBUFFER,
+                                       rtIDs.fMSColorRenderbufferID));
+                GR_GL_NO_ERR(RenderbufferStorageMultisample(
+                                                   GR_RENDERBUFFER,
+                                                   samples,
+                                                   msColorRenderbufferFormat,
+                                                   glDesc.fAllocWidth,
+                                                   glDesc.fAllocHeight));
+                err = glGetError();
+                if (err != GL_NO_ERROR) {
+                    continue;
+                }
+            }
+            GR_GL(BindFramebuffer(GR_FRAMEBUFFER, rtIDs.fTexFBOID));
+
+#if GR_COLLECT_STATS
+            ++fStats.fRenderTargetChngCnt;
+#endif
+            if (kIMG_MSFBO == fMSFBOType && samples > 1) {
+                GR_GL(FramebufferTexture2DMultisample(GR_FRAMEBUFFER,
+                                                      GR_COLOR_ATTACHMENT0,
+                                                      GL_TEXTURE_2D,
+                                                      glDesc.fTextureID,
+                                                      0,
+                                                      samples));
+
+            } else {
+                GR_GL(FramebufferTexture2D(GR_FRAMEBUFFER,
+                                           GR_COLOR_ATTACHMENT0,
+                                           GL_TEXTURE_2D,
+                                           glDesc.fTextureID, 0));
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GLenum status = GR_GL(CheckFramebufferStatus(GR_FRAMEBUFFER));
+                if (status != GR_FRAMEBUFFER_COMPLETE) {
+                    GrPrintf("-- glCheckFramebufferStatus %x %d %d\n",
+                             status, desc.fWidth, desc.fHeight);
+                    continue;
+                }
+                GR_GL(BindFramebuffer(GR_FRAMEBUFFER, rtIDs.fRTFBOID));
+            #if GR_COLLECT_STATS
+                ++fStats.fRenderTargetChngCnt;
+            #endif
+                GR_GL(FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                              GR_COLOR_ATTACHMENT0,
+                                              GR_RENDERBUFFER,
+                                              rtIDs.fMSColorRenderbufferID));
+
+            }
+            if (rtIDs.fStencilRenderbufferID) {
+                // bind the stencil to rt fbo if present, othewise the tex fbo
+                GR_GL(FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                              GR_STENCIL_ATTACHMENT,
+                                              GR_RENDERBUFFER,
+                                              rtIDs.fStencilRenderbufferID));
+            }
+            status = GR_GL(CheckFramebufferStatus(GR_FRAMEBUFFER));
+
+#if GR_SUPPORT_GLDESKTOP
+            // On some implementations you have to be bound as DEPTH_STENCIL.
+            // (Even binding to DEPTH and STENCIL separately with the same
+            // buffer doesn't work.)
+            if (rtIDs.fStencilRenderbufferID &&
+                status != GR_FRAMEBUFFER_COMPLETE) {
+                GR_GL(FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                              GR_STENCIL_ATTACHMENT,
+                                              GR_RENDERBUFFER,
+                                              0));
+                GR_GL(FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                              GR_DEPTH_STENCIL_ATTACHMENT,
+                                              GR_RENDERBUFFER,
+                                              rtIDs.fStencilRenderbufferID));
+                status = GR_GL(CheckFramebufferStatus(GR_FRAMEBUFFER));
+            }
+#endif
+            if (status != GR_FRAMEBUFFER_COMPLETE) {
+                GrPrintf("-- glCheckFramebufferStatus %x %d %d\n",
+                         status, desc.fWidth, desc.fHeight);
+#if GR_SUPPORT_GLDESKTOP
+                if (rtIDs.fStencilRenderbufferID) {
+                    GR_GL(FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                  GR_DEPTH_STENCIL_ATTACHMENT,
+                                                  GR_RENDERBUFFER,
+                                                  0));
+                }
+#endif
+                continue;
+            }
+            // we're successful!
+            failed = false;
+            if (rtIDs.fStencilRenderbufferID) {
+                if (UNKNOWN_BITS == gStencilFormats[i].fBits) {
+                    GR_GL_GetIntegerv(GL_STENCIL_BITS, (GLint*)&glDesc.fStencilBits);
+                } else {
+                    glDesc.fStencilBits = gStencilFormats[i].fBits;
+                }
+            }
+            break;
+        }
+        if (failed) {
+            if (rtIDs.fStencilRenderbufferID) {
+                GR_GL(DeleteRenderbuffers(1, &rtIDs.fStencilRenderbufferID));
+            }
+            if (rtIDs.fMSColorRenderbufferID) {
+                GR_GL(DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GR_GL(DeleteFramebuffers(1, &rtIDs.fRTFBOID));
+            }
+            if (rtIDs.fTexFBOID) {
+                GR_GL(DeleteFramebuffers(1, &rtIDs.fTexFBOID));
+            }
+            GR_GL(DeleteTextures(1, &glDesc.fTextureID));
+            return return_null_texture();
+        }
+    }
+#ifdef TRACE_TEXTURE_CREATION
+    GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n",
+             tex->fTextureID, width, height, tex->fUploadByteCount);
+#endif
+    GrGLTexture* tex = new GrGLTexture(glDesc, rtIDs, DEFAULT_PARAMS, this);
+
+    if (0 != rtIDs.fTexFBOID) {
+        GrRenderTarget* rt = tex->asRenderTarget();
+        // We've messed with FBO state but may not have set the correct viewport
+        // so just dirty the rendertarget state to force a resend.
+        fHWDrawState.fRenderTarget = NULL;
+
+        // clear the new stencil buffer if we have one
+        if (!(desc.fFlags & kNoPathRendering_TextureFlag)) {
+            GrRenderTarget* rtSave = fCurrDrawState.fRenderTarget;
+            fCurrDrawState.fRenderTarget = rt;
+            eraseStencil(0, ~0);
+            fCurrDrawState.fRenderTarget = rtSave;
+        }
+    }
+    return tex;
+}
+
+GrVertexBuffer* GrGpuGL::createVertexBufferHelper(uint32_t size, bool dynamic) {
+    GLuint id;
+    GR_GL(GenBuffers(1, &id));
+    if (id) {
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, id));
+        fHWGeometryState.fArrayPtrsDirty = true;
+        GrGLClearErr();
+        // make sure driver can allocate memory for this buffer
+        GR_GL_NO_ERR(BufferData(GL_ARRAY_BUFFER, size, NULL,
+                                dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        if (glGetError() != GL_NO_ERROR) {
+            GR_GL(DeleteBuffers(1, &id));
+            // deleting bound buffer does implicit bind to 0
+            fHWGeometryState.fVertexBuffer = NULL;
+            return NULL;
+        }
+        GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(id, this,
+                                                              size, dynamic);
+        fHWGeometryState.fVertexBuffer = vertexBuffer;
+        return vertexBuffer;
+    }
+    return NULL;
+}
+
+GrIndexBuffer* GrGpuGL::createIndexBufferHelper(uint32_t size, bool dynamic) {
+    GLuint id;
+    GR_GL(GenBuffers(1, &id));
+    if (id) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, id));
+        GrGLClearErr();
+        // make sure driver can allocate memory for this buffer
+        GR_GL_NO_ERR(BufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL,
+                                dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        if (glGetError() != GL_NO_ERROR) {
+            GR_GL(DeleteBuffers(1, &id));
+            // deleting bound buffer does implicit bind to 0
+            fHWGeometryState.fIndexBuffer = NULL;
+            return NULL;
+        }
+        GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(id, this,
+                                                         size, dynamic);
+        fHWGeometryState.fIndexBuffer = indexBuffer;
+        return indexBuffer;
+    }
+    return NULL;
+}
+
+void GrGpuGL::flushScissor(const GrIRect* rect) {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    const GrGLIRect& vp =
+            ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport();
+
+    GrGLIRect scissor;
+    if (NULL != rect) {
+        scissor.setRelativeTo(vp, rect->fLeft, rect->fTop,
+                              rect->width(), rect->height());
+        if (scissor.contains(vp)) {
+            rect = NULL;
+        }
+    }
+
+    if (NULL != rect) {
+        if (fHWBounds.fScissorRect != scissor) {
+            scissor.pushToGLScissor();
+            fHWBounds.fScissorRect = scissor;
+        }
+        if (!fHWBounds.fScissorEnabled) {
+            GR_GL(Enable(GL_SCISSOR_TEST));
+            fHWBounds.fScissorEnabled = true;
+        }
+    } else {
+        if (fHWBounds.fScissorEnabled) {
+            GR_GL(Disable(GL_SCISSOR_TEST));
+            fHWBounds.fScissorEnabled = false;
+        }
+    }
+}
+
+void GrGpuGL::eraseColorHelper(GrColor color) {
+    if (NULL == fCurrDrawState.fRenderTarget) {
+        return;
+    }
+    flushRenderTarget();
+    if (fHWBounds.fScissorEnabled) {
+        GR_GL(Disable(GL_SCISSOR_TEST));
+        fHWBounds.fScissorEnabled = false;
+    }
+    GR_GL(ColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE));
+    fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit;
+    GR_GL(ClearColor(GrColorUnpackR(color)/255.f,
+                     GrColorUnpackG(color)/255.f,
+                     GrColorUnpackB(color)/255.f,
+                     GrColorUnpackA(color)/255.f));
+    GR_GL(Clear(GL_COLOR_BUFFER_BIT));
+}
+
+void GrGpuGL::eraseStencil(uint32_t value, uint32_t mask) {
+    if (NULL == fCurrDrawState.fRenderTarget) {
+        return;
+    }
+    flushRenderTarget();
+    if (fHWBounds.fScissorEnabled) {
+        GR_GL(Disable(GL_SCISSOR_TEST));
+        fHWBounds.fScissorEnabled = false;
+    }
+    GR_GL(StencilMask(mask));
+    GR_GL(ClearStencil(value));
+    GR_GL(Clear(GL_STENCIL_BUFFER_BIT));
+    fHWDrawState.fStencilSettings.invalidate();
+}
+
+void GrGpuGL::eraseStencilClip(const GrIRect& rect) {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+#if 0
+    GLint stencilBitCount = fCurrDrawState.fRenderTarget->stencilBits();
+    GrAssert(stencilBitCount > 0);
+    GLint clipStencilMask  = (1 << (stencilBitCount - 1));
+#else
+    // we could just clear the clip bit but when we go through
+    // angle a partial stencil mask will cause clears to be
+    // turned into draws. Our contract on GrDrawTarget says that
+    // changing the clip between stencil passes may or may not
+    // zero the client's clip bits. So we just clear the whole thing.
+    static const GLint clipStencilMask  = ~0;
+#endif
+    flushRenderTarget();
+    flushScissor(&rect);
+    GR_GL(StencilMask(clipStencilMask));
+    GR_GL(ClearStencil(0));
+    GR_GL(Clear(GL_STENCIL_BUFFER_BIT));
+    fHWDrawState.fStencilSettings.invalidate();
+}
+
+void GrGpuGL::forceRenderTargetFlushHelper() {
+    flushRenderTarget();
+}
+
+bool GrGpuGL::readPixelsHelper(int left, int top, int width, int height,
+                               GrTexture::PixelConfig config, void* buffer) {
+    GLenum internalFormat;  // we don't use this for glReadPixels
+    GLenum format;
+    GLenum type;
+    if (!this->canBeTexture(config, &internalFormat, &format, &type)) {
+        return false;
+    }
+
+    if (NULL == fCurrDrawState.fRenderTarget) {
+        return false;
+    }
+    flushRenderTarget();
+
+    const GrGLIRect& glvp = ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport();
+
+    // the read rect is viewport-relative
+    GrGLIRect readRect;
+    readRect.setRelativeTo(glvp, left, top, width, height);
+    GR_GL(ReadPixels(readRect.fLeft, readRect.fBottom,
+                     readRect.fWidth, readRect.fHeight,
+                     format, type, buffer));
+
+    // now reverse the order of the rows, since GL's are bottom-to-top, but our
+    // API presents top-to-bottom
+    {
+        size_t stride = width * GrTexture::BytesPerPixel(config);
+        GrAutoMalloc rowStorage(stride);
+        void* tmp = rowStorage.get();
+
+        const int halfY = height >> 1;
+        char* top = reinterpret_cast<char*>(buffer);
+        char* bottom = top + (height - 1) * stride;
+        for (int y = 0; y < halfY; y++) {
+            memcpy(tmp, top, stride);
+            memcpy(top, bottom, stride);
+            memcpy(bottom, tmp, stride);
+            top += stride;
+            bottom -= stride;
+        }
+    }
+    return true;
+}
+
+void GrGpuGL::flushRenderTarget() {
+
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+
+    if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) {
+        GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget;
+        GR_GL(BindFramebuffer(GR_FRAMEBUFFER, rt->renderFBOID()));
+    #if GR_COLLECT_STATS
+        ++fStats.fRenderTargetChngCnt;
+    #endif
+        rt->setDirty(true);
+    #if GR_DEBUG
+        GLenum status = GR_GL(CheckFramebufferStatus(GR_FRAMEBUFFER));
+        if (status != GR_FRAMEBUFFER_COMPLETE) {
+            GrPrintf("-- glCheckFramebufferStatus %x\n", status);
+        }
+    #endif
+        fDirtyFlags.fRenderTargetChanged = true;
+        fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget;
+        const GrGLIRect& vp = rt->getViewport();
+        if (fHWBounds.fViewportRect != vp) {
+            vp.pushToGLViewport();
+            fHWBounds.fViewportRect = vp;
+        }
+    }
+}
+
+GLenum gPrimitiveType2GLMode[] = {
+    GL_TRIANGLES,
+    GL_TRIANGLE_STRIP,
+    GL_TRIANGLE_FAN,
+    GL_POINTS,
+    GL_LINES,
+    GL_LINE_STRIP
+};
+
+#define SWAP_PER_DRAW 0
+
+#if SWAP_PER_DRAW
+    #if GR_MAC_BUILD
+        #include <AGL/agl.h>
+    #elif GR_WIN32_BUILD
+        void SwapBuf() {
+            DWORD procID = GetCurrentProcessId();
+            HWND hwnd = GetTopWindow(GetDesktopWindow());
+            while(hwnd) {
+                DWORD wndProcID = 0;
+                GetWindowThreadProcessId(hwnd, &wndProcID);
+                if(wndProcID == procID) {
+                    SwapBuffers(GetDC(hwnd));
+                }
+                hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
+            }
+         }
+    #endif
+#endif
+
+void GrGpuGL::drawIndexedHelper(GrPrimitiveType type,
+                                uint32_t startVertex,
+                                uint32_t startIndex,
+                                uint32_t vertexCount,
+                                uint32_t indexCount) {
+    GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
+
+    GLvoid* indices = (GLvoid*)(sizeof(uint16_t) * startIndex);
+
+    GrAssert(NULL != fHWGeometryState.fIndexBuffer);
+    GrAssert(NULL != fHWGeometryState.fVertexBuffer);
+
+    // our setupGeometry better have adjusted this to zero since
+    // DrawElements always draws from the begining of the arrays for idx 0.
+    GrAssert(0 == startVertex);
+
+    GR_GL(DrawElements(gPrimitiveType2GLMode[type], indexCount,
+                       GL_UNSIGNED_SHORT, indices));
+#if SWAP_PER_DRAW
+    glFlush();
+    #if GR_MAC_BUILD
+        aglSwapBuffers(aglGetCurrentContext());
+        int set_a_break_pt_here = 9;
+        aglSwapBuffers(aglGetCurrentContext());
+    #elif GR_WIN32_BUILD
+        SwapBuf();
+        int set_a_break_pt_here = 9;
+        SwapBuf();
+    #endif
+#endif
+}
+
+void GrGpuGL::drawNonIndexedHelper(GrPrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t vertexCount) {
+    GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
+
+    GrAssert(NULL != fHWGeometryState.fVertexBuffer);
+
+    // our setupGeometry better have adjusted this to zero.
+    // DrawElements doesn't take an offset so we always adjus the startVertex.
+    GrAssert(0 == startVertex);
+
+    // pass 0 for parameter first. We have to adjust gl*Pointer() to
+    // account for startVertex in the DrawElements case. So we always
+    // rely on setupGeometry to have accounted for startVertex.
+    GR_GL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount));
+#if SWAP_PER_DRAW
+    glFlush();
+    #if GR_MAC_BUILD
+        aglSwapBuffers(aglGetCurrentContext());
+        int set_a_break_pt_here = 9;
+        aglSwapBuffers(aglGetCurrentContext());
+    #elif GR_WIN32_BUILD
+        SwapBuf();
+        int set_a_break_pt_here = 9;
+        SwapBuf();
+    #endif
+#endif
+}
+
+void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) {
+    GrGLRenderTarget* rt = (GrGLRenderTarget*) texture->asRenderTarget();
+
+    if (NULL != rt && rt->needsResolve()) {
+        GrAssert(kNone_MSFBO != fMSFBOType);
+        GrAssert(rt->textureFBOID() != rt->renderFBOID());
+        GR_GL(BindFramebuffer(GR_READ_FRAMEBUFFER,
+                                        rt->renderFBOID()));
+        GR_GL(BindFramebuffer(GR_DRAW_FRAMEBUFFER,
+                                        rt->textureFBOID()));
+    #if GR_COLLECT_STATS
+        ++fStats.fRenderTargetChngCnt;
+    #endif
+        // make sure we go through set render target
+        fHWDrawState.fRenderTarget = NULL;
+
+        GLint left = 0;
+        GLint right = texture->width();
+        // we will have rendered to the top of the FBO.
+        GLint top = texture->allocHeight();
+        GLint bottom = texture->allocHeight() - texture->height();
+        if (kApple_MSFBO == fMSFBOType) {
+            GR_GL(Enable(GL_SCISSOR_TEST));
+            GR_GL(Scissor(left, bottom, right-left, top-bottom));
+            GR_GL(ResolveMultisampleFramebuffer());
+            fHWBounds.fScissorRect.invalidate();
+            fHWBounds.fScissorEnabled = true;
+        } else {
+            GR_GL(BlitFramebuffer(left, bottom, right, top,
+                                     left, bottom, right, top,
+                                     GL_COLOR_BUFFER_BIT, GL_NEAREST));
+        }
+        rt->setDirty(false);
+
+    }
+}
+
+static const GLenum grToGLStencilFunc[] = {
+    GL_ALWAYS,           // kAlways_StencilFunc
+    GL_NEVER,            // kNever_StencilFunc
+    GL_GREATER,          // kGreater_StencilFunc
+    GL_GEQUAL,           // kGEqual_StencilFunc
+    GL_LESS,             // kLess_StencilFunc
+    GL_LEQUAL,           // kLEqual_StencilFunc,
+    GL_EQUAL,            // kEqual_StencilFunc,
+    GL_NOTEQUAL,         // kNotEqual_StencilFunc,
+};
+GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilFunc) == kBasicStencilFuncCount);
+GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
+GR_STATIC_ASSERT(1 == kNever_StencilFunc);
+GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
+GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
+GR_STATIC_ASSERT(4 == kLess_StencilFunc);
+GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
+GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
+GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
+
+static const GLenum grToGLStencilOp[] = {
+    GL_KEEP,        // kKeep_StencilOp
+    GL_REPLACE,     // kReplace_StencilOp
+    GL_INCR_WRAP,   // kIncWrap_StencilOp
+    GL_INCR,        // kIncClamp_StencilOp
+    GL_DECR_WRAP,   // kDecWrap_StencilOp
+    GL_DECR,        // kDecClamp_StencilOp
+    GL_ZERO,        // kZero_StencilOp
+    GL_INVERT,      // kInvert_StencilOp
+};
+GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilOp) == kStencilOpCount);
+GR_STATIC_ASSERT(0 == kKeep_StencilOp);
+GR_STATIC_ASSERT(1 == kReplace_StencilOp);
+GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
+GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
+GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
+GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
+GR_STATIC_ASSERT(6 == kZero_StencilOp);
+GR_STATIC_ASSERT(7 == kInvert_StencilOp);
+
+void GrGpuGL::flushStencil() {
+    const GrStencilSettings* settings = &fCurrDrawState.fStencilSettings;
+
+    // use stencil for clipping if clipping is enabled and the clip
+    // has been written into the stencil.
+    bool stencilClip = fClipState.fClipInStencil &&
+                       (kClip_StateBit & fCurrDrawState.fFlagBits);
+    bool stencilChange = fHWStencilClip != stencilClip  ||
+                         fHWDrawState.fStencilSettings != *settings ||
+                         ((fHWDrawState.fFlagBits & kModifyStencilClip_StateBit) !=
+                          (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+
+    if (stencilChange) {
+
+        // we can't simultaneously perform stencil-clipping and modify the stencil clip
+        GrAssert(!stencilClip || !(fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+
+        if (settings->isDisabled()) {
+            if (stencilClip) {
+                settings = &gClipStencilSettings;
+            }
+        }
+
+        if (settings->isDisabled()) {
+            GR_GL(Disable(GL_STENCIL_TEST));
+        } else {
+            GR_GL(Enable(GL_STENCIL_TEST));
+    #if GR_DEBUG
+            if (!fStencilWrapOpsSupport) {
+                GrAssert(settings->fFrontPassOp != kIncWrap_StencilOp);
+                GrAssert(settings->fFrontPassOp != kDecWrap_StencilOp);
+                GrAssert(settings->fFrontFailOp != kIncWrap_StencilOp);
+                GrAssert(settings->fBackFailOp != kDecWrap_StencilOp);
+                GrAssert(settings->fBackPassOp != kIncWrap_StencilOp);
+                GrAssert(settings->fBackPassOp != kDecWrap_StencilOp);
+                GrAssert(settings->fBackFailOp != kIncWrap_StencilOp);
+                GrAssert(settings->fFrontFailOp != kDecWrap_StencilOp);
+            }
+    #endif
+            int stencilBits = fCurrDrawState.fRenderTarget->stencilBits();
+            GrAssert(stencilBits ||
+                     (GrStencilSettings::gDisabled ==
+                      fCurrDrawState.fStencilSettings));
+            GLuint clipStencilMask = 1 << (stencilBits - 1);
+            GLuint userStencilMask = clipStencilMask - 1;
+
+            unsigned int frontRef  = settings->fFrontFuncRef;
+            unsigned int frontMask = settings->fFrontFuncMask;
+            unsigned int frontWriteMask = settings->fFrontWriteMask;
+            GLenum frontFunc;
+
+            if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
+
+                GrAssert(settings->fFrontFunc < kBasicStencilFuncCount);
+                frontFunc = grToGLStencilFunc[settings->fFrontFunc];
+            } else {
+                frontFunc = grToGLStencilFunc[ConvertStencilFunc(stencilClip, settings->fFrontFunc)];
+
+                ConvertStencilFuncAndMask(settings->fFrontFunc,
+                                          stencilClip,
+                                          clipStencilMask,
+                                          userStencilMask,
+                                          &frontRef,
+                                          &frontMask);
+                frontWriteMask &= userStencilMask;
+            }
+            GrAssert(settings->fFrontFailOp >= 0 &&
+                     settings->fFrontFailOp < GR_ARRAY_COUNT(grToGLStencilOp));
+            GrAssert(settings->fFrontPassOp >= 0 &&
+                     settings->fFrontPassOp < GR_ARRAY_COUNT(grToGLStencilOp));
+            GrAssert(settings->fBackFailOp >= 0 &&
+                     settings->fBackFailOp < GR_ARRAY_COUNT(grToGLStencilOp));
+            GrAssert(settings->fBackPassOp >= 0 &&
+                     settings->fBackPassOp < GR_ARRAY_COUNT(grToGLStencilOp));
+            if (fTwoSidedStencilSupport) {
+                GLenum backFunc;
+
+                unsigned int backRef  = settings->fBackFuncRef;
+                unsigned int backMask = settings->fBackFuncMask;
+                unsigned int backWriteMask = settings->fBackWriteMask;
+
+
+                if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
+                    GrAssert(settings->fBackFunc < kBasicStencilFuncCount);
+                    backFunc = grToGLStencilFunc[settings->fBackFunc];
+                } else {
+                    backFunc = grToGLStencilFunc[ConvertStencilFunc(stencilClip, settings->fBackFunc)];
+                    ConvertStencilFuncAndMask(settings->fBackFunc,
+                                              stencilClip,
+                                              clipStencilMask,
+                                              userStencilMask,
+                                              &backRef,
+                                              &backMask);
+                    backWriteMask &= userStencilMask;
+                }
+
+                GR_GL(StencilFuncSeparate(GL_FRONT, frontFunc, frontRef, frontMask));
+                GR_GL(StencilMaskSeparate(GL_FRONT, frontWriteMask));
+                GR_GL(StencilFuncSeparate(GL_BACK, backFunc, backRef, backMask));
+                GR_GL(StencilMaskSeparate(GL_BACK, backWriteMask));
+                GR_GL(StencilOpSeparate(GL_FRONT, grToGLStencilOp[settings->fFrontFailOp],
+                                                  grToGLStencilOp[settings->fFrontPassOp],
+                                                  grToGLStencilOp[settings->fFrontPassOp]));
+
+                GR_GL(StencilOpSeparate(GL_BACK,  grToGLStencilOp[settings->fBackFailOp],
+                                                  grToGLStencilOp[settings->fBackPassOp],
+                                                  grToGLStencilOp[settings->fBackPassOp]));
+            } else {
+                GR_GL(StencilFunc(frontFunc, frontRef, frontMask));
+                GR_GL(StencilMask(frontWriteMask));
+                GR_GL(StencilOp(grToGLStencilOp[settings->fFrontFailOp],
+                                grToGLStencilOp[settings->fFrontPassOp],
+                                grToGLStencilOp[settings->fFrontPassOp]));
+            }
+        }
+        fHWDrawState.fStencilSettings = fCurrDrawState.fStencilSettings;
+        fHWStencilClip = stencilClip;
+    }
+}
+
+bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
+
+    // GrGpu::setupClipAndFlushState should have already checked this
+    // and bailed if not true.
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+
+    for (int s = 0; s < kNumStages; ++s) {
+        bool usingTexture = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
+
+        // bind texture and set sampler state
+        if (usingTexture) {
+            GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s];
+
+            if (NULL != nextTexture) {
+                // if we created a rt/tex and rendered to it without using a
+                // texture and now we're texuring from the rt it will still be
+                // the last bound texture, but it needs resolving. So keep this
+                // out of the "last != next" check.
+                resolveTextureRenderTarget(nextTexture);
+
+                if (fHWDrawState.fTextures[s] != nextTexture) {
+                    setTextureUnit(s);
+                    GR_GL(BindTexture(GL_TEXTURE_2D, nextTexture->textureID()));
+                #if GR_COLLECT_STATS
+                    ++fStats.fTextureChngCnt;
+                #endif
+                    //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
+                    fHWDrawState.fTextures[s] = nextTexture;
+                }
+
+                const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+                const GrGLTexture::TexParams& oldTexParams =
+                                                    nextTexture->getTexParams();
+                GrGLTexture::TexParams newTexParams;
+
+                newTexParams.fFilter = sampler.isFilter() ? GL_LINEAR :
+                                                            GL_NEAREST;
+                newTexParams.fWrapS =
+                            GrGLTexture::gWrapMode2GLWrap[sampler.getWrapX()];
+                newTexParams.fWrapT =
+                            GrGLTexture::gWrapMode2GLWrap[sampler.getWrapY()];
+
+                if (newTexParams.fFilter != oldTexParams.fFilter) {
+                    setTextureUnit(s);
+                    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                        GL_TEXTURE_MAG_FILTER,
+                                        newTexParams.fFilter));
+                    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                        GL_TEXTURE_MIN_FILTER,
+                                        newTexParams.fFilter));
+                }
+                if (newTexParams.fWrapS != oldTexParams.fWrapS) {
+                    setTextureUnit(s);
+                    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                        GL_TEXTURE_WRAP_S,
+                                        newTexParams.fWrapS));
+                }
+                if (newTexParams.fWrapT != oldTexParams.fWrapT) {
+                    setTextureUnit(s);
+                    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                        GL_TEXTURE_WRAP_T,
+                                        newTexParams.fWrapT));
+                }
+                nextTexture->setTexParams(newTexParams);
+
+                // The texture matrix has to compensate for texture width/height
+                // and NPOT-embedded-in-POT
+                fDirtyFlags.fTextureChangedMask |= (1 << s);
+            } else {
+                GrAssert(!"Rendering with texture vert flag set but no texture");
+                return false;
+            }
+        }
+    }
+
+    flushRenderTarget();
+
+    if ((fCurrDrawState.fFlagBits & kDither_StateBit) !=
+        (fHWDrawState.fFlagBits & kDither_StateBit)) {
+        if (fCurrDrawState.fFlagBits & kDither_StateBit) {
+            GR_GL(Enable(GL_DITHER));
+        } else {
+            GR_GL(Disable(GL_DITHER));
+        }
+    }
+
+    if ((fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) !=
+        (fHWDrawState.fFlagBits & kNoColorWrites_StateBit)) {
+        GLenum mask;
+        if (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) {
+            mask = GL_FALSE;
+        } else {
+            mask = GL_TRUE;
+        }
+        GR_GL(ColorMask(mask, mask, mask, mask));
+    }
+
+#if GR_SUPPORT_GLDESKTOP
+    // ES doesn't support toggling GL_MULTISAMPLE and doesn't have
+    // smooth lines.
+    if (fDirtyFlags.fRenderTargetChanged ||
+        (fCurrDrawState.fFlagBits & kAntialias_StateBit) !=
+        (fHWDrawState.fFlagBits & kAntialias_StateBit)) {
+        GLint msaa = 0;
+        // only perform query if we know MSAA is supported.
+        // calling on non-MSAA target caused a crash in one environment,
+        // though I don't think it should.
+        if (fAASamples[kHigh_AALevel]) {
+            GR_GL_GetIntegerv(GL_SAMPLE_BUFFERS, &msaa);
+        }
+        if (fCurrDrawState.fFlagBits & kAntialias_StateBit) {
+            if (msaa) {
+                GR_GL(Enable(GL_MULTISAMPLE));
+            } else {
+                GR_GL(Enable(GL_LINE_SMOOTH));
+            }
+        } else {
+            if (msaa) {
+                GR_GL(Disable(GL_MULTISAMPLE));
+            }
+            GR_GL(Disable(GL_LINE_SMOOTH));
+        }
+    }
+#endif
+
+    bool blendOff = canDisableBlend();
+    if (fHWBlendDisabled != blendOff) {
+        if (blendOff) {
+            GR_GL(Disable(GL_BLEND));
+        } else {
+            GR_GL(Enable(GL_BLEND));
+        }
+        fHWBlendDisabled = blendOff;
+    }
+
+    if (!blendOff) {
+        if (fHWDrawState.fSrcBlend != fCurrDrawState.fSrcBlend ||
+              fHWDrawState.fDstBlend != fCurrDrawState.fDstBlend) {
+            GR_GL(BlendFunc(gXfermodeCoeff2Blend[fCurrDrawState.fSrcBlend],
+                            gXfermodeCoeff2Blend[fCurrDrawState.fDstBlend]));
+            fHWDrawState.fSrcBlend = fCurrDrawState.fSrcBlend;
+            fHWDrawState.fDstBlend = fCurrDrawState.fDstBlend;
+        }
+        if ((BlendCoefReferencesConstant(fCurrDrawState.fSrcBlend) ||
+             BlendCoefReferencesConstant(fCurrDrawState.fDstBlend)) &&
+            fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) {
+
+            float c[] = {
+                GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f,
+                GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f,
+                GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f,
+                GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f
+            };
+            GR_GL(BlendColor(c[0], c[1], c[2], c[3]));
+            fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant;
+        }
+    }
+
+    if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) {
+        switch (fCurrDrawState.fDrawFace) {
+            case kCCW_DrawFace:
+                glEnable(GL_CULL_FACE);
+                GR_GL(CullFace(GL_BACK));
+                break;
+            case kCW_DrawFace:
+                GR_GL(Enable(GL_CULL_FACE));
+                GR_GL(CullFace(GL_FRONT));
+                break;
+            case kBoth_DrawFace:
+                GR_GL(Disable(GL_CULL_FACE));
+                break;
+            default:
+                GrCrash("Unknown draw face.");
+        }
+        fHWDrawState.fDrawFace = fCurrDrawState.fDrawFace;
+    }
+
+#if GR_DEBUG
+    // check for circular rendering
+    for (int s = 0; s < kNumStages; ++s) {
+        GrAssert(!VertexUsesStage(s, fGeometrySrc.fVertexLayout) ||
+                 NULL == fCurrDrawState.fRenderTarget ||
+                 NULL == fCurrDrawState.fTextures[s] ||
+                 fCurrDrawState.fTextures[s]->asRenderTarget() !=
+                    fCurrDrawState.fRenderTarget);
+    }
+#endif
+
+    flushStencil();
+
+    // flushStencil may look at the private state bits, so keep it before this.
+    fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits;
+    return true;
+}
+
+void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
+    if (fHWGeometryState.fVertexBuffer != buffer) {
+        fHWGeometryState.fArrayPtrsDirty = true;
+        fHWGeometryState.fVertexBuffer = buffer;
+    }
+}
+
+void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
+    GrAssert(!(kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc &&
+               buffer == fGeometrySrc.fVertexBuffer));
+
+    if (fHWGeometryState.fVertexBuffer == buffer) {
+        // deleting bound buffer does implied bind to 0
+        fHWGeometryState.fVertexBuffer = NULL;
+        fHWGeometryState.fArrayPtrsDirty = true;
+    }
+}
+
+void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
+    fGeometrySrc.fIndexBuffer = buffer;
+}
+
+void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
+    GrAssert(!(kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc &&
+               buffer == fGeometrySrc.fIndexBuffer));
+
+    if (fHWGeometryState.fIndexBuffer == buffer) {
+        // deleting bound buffer does implied bind to 0
+        fHWGeometryState.fIndexBuffer = NULL;
+    }
+}
+
+void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
+    GrAssert(NULL != renderTarget);
+    if (fCurrDrawState.fRenderTarget == renderTarget) {
+        fCurrDrawState.fRenderTarget = NULL;
+    }
+    if (fHWDrawState.fRenderTarget == renderTarget) {
+        fHWDrawState.fRenderTarget = NULL;
+    }
+}
+
+void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
+    for (int s = 0; s < kNumStages; ++s) {
+        if (fCurrDrawState.fTextures[s] == texture) {
+            fCurrDrawState.fTextures[s] = NULL;
+        }
+        if (fHWDrawState.fTextures[s] == texture) {
+            // deleting bound texture does implied bind to 0
+            fHWDrawState.fTextures[s] = NULL;
+       }
+    }
+}
+
+bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config,
+                           GLenum* internalFormat,
+                           GLenum* format,
+                           GLenum* type) {
+    switch (config) {
+        case GrTexture::kRGBA_8888_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig: // todo: can we tell it our X?
+            *format = GR_GL_32BPP_COLOR_FORMAT;
+#if GR_SUPPORT_GLES
+            // according to GL_EXT_texture_format_BGRA8888 the *internal*
+            // format for a BGRA is BGRA not RGBA (as on desktop)
+            *internalFormat = GR_GL_32BPP_COLOR_FORMAT;
+#else
+            *internalFormat = GL_RGBA;
+#endif
+            *type = GL_UNSIGNED_BYTE;
+            break;
+        case GrTexture::kRGB_565_PixelConfig:
+            *format = GL_RGB;
+            *internalFormat = GL_RGB;
+            *type = GL_UNSIGNED_SHORT_5_6_5;
+            break;
+        case GrTexture::kRGBA_4444_PixelConfig:
+            *format = GL_RGBA;
+            *internalFormat = GL_RGBA;
+            *type = GL_UNSIGNED_SHORT_4_4_4_4;
+            break;
+        case GrTexture::kIndex_8_PixelConfig:
+            if (this->supports8BitPalette()) {
+                *format = GR_PALETTE8_RGBA8;
+                *internalFormat = GR_PALETTE8_RGBA8;
+                *type = GL_UNSIGNED_BYTE;   // unused I think
+            } else {
+                return false;
+            }
+            break;
+        case GrTexture::kAlpha_8_PixelConfig:
+            *format = GL_ALPHA;
+            *internalFormat = GL_ALPHA;
+            *type = GL_UNSIGNED_BYTE;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+void GrGpuGL::setTextureUnit(int unit) {
+    GrAssert(unit >= 0 && unit < kNumStages);
+    if (fActiveTextureUnitIdx != unit) {
+        GR_GL(ActiveTexture(GL_TEXTURE0 + unit));
+        fActiveTextureUnitIdx = unit;
+    }
+}
+
+void GrGpuGL::setSpareTextureUnit() {
+    if (fActiveTextureUnitIdx != (GL_TEXTURE0 + SPARE_TEX_UNIT)) {
+        GR_GL(ActiveTexture(GL_TEXTURE0 + SPARE_TEX_UNIT));
+        fActiveTextureUnitIdx = SPARE_TEX_UNIT;
+    }
+}
+
+/* On ES the internalFormat and format must match for TexImage and we use
+   GL_RGB, GL_RGBA for color formats. We also generally like having the driver
+   decide the internalFormat. However, on ES internalFormat for
+   RenderBufferStorage* has to be a specific format (not a base format like
+   GL_RGBA).
+ */
+bool GrGpuGL::fboInternalFormat(GrTexture::PixelConfig config, GLenum* format) {
+    switch (config) {
+        case GrTexture::kRGBA_8888_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig:
+            if (fRGBA8Renderbuffer) {
+                *format = GR_RGBA8;
+                return true;
+            } else {
+                return false;
+            }
+#if GR_SUPPORT_GLES // ES2 supports 565. ES1 supports it with FBO extension
+                    // desktop GL has no such internal format
+        case GrTexture::kRGB_565_PixelConfig:
+            *format = GR_RGB565;
+            return true;
+#endif
+        case GrTexture::kRGBA_4444_PixelConfig:
+            *format = GL_RGBA4;
+            return true;
+        default:
+            return false;
+    }
+}
+
+void GrGpuGL::resetDirtyFlags() {
+    Gr_bzero(&fDirtyFlags, sizeof(fDirtyFlags));
+}
+
+void GrGpuGL::setBuffers(bool indexed,
+                         int* extraVertexOffset,
+                         int* extraIndexOffset) {
+
+    GrAssert(NULL != extraVertexOffset);
+
+    GrGLVertexBuffer* vbuf;
+    switch (fGeometrySrc.fVertexSrc) {
+    case kBuffer_GeometrySrcType:
+        *extraVertexOffset = 0;
+        vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer;
+        break;
+    case kArray_GeometrySrcType:
+    case kReserved_GeometrySrcType:
+        finalizeReservedVertices();
+        *extraVertexOffset = fCurrPoolStartVertex;
+        vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer;
+        break;
+    default:
+        vbuf = NULL; // suppress warning
+        GrCrash("Unknown geometry src type!");
+    }
+
+    GrAssert(NULL != vbuf);
+    GrAssert(!vbuf->isLocked());
+    if (fHWGeometryState.fVertexBuffer != vbuf) {
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, vbuf->bufferID()));
+        fHWGeometryState.fArrayPtrsDirty = true;
+        fHWGeometryState.fVertexBuffer = vbuf;
+    }
+
+    if (indexed) {
+        GrAssert(NULL != extraIndexOffset);
+
+        GrGLIndexBuffer* ibuf;
+        switch (fGeometrySrc.fIndexSrc) {
+        case kBuffer_GeometrySrcType:
+            *extraIndexOffset = 0;
+            ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+            break;
+        case kArray_GeometrySrcType:
+        case kReserved_GeometrySrcType:
+            finalizeReservedIndices();
+            *extraIndexOffset = fCurrPoolStartIndex;
+            ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer;
+            break;
+        default:
+            ibuf = NULL; // suppress warning
+            GrCrash("Unknown geometry src type!");
+        }
+
+        GrAssert(NULL != ibuf);
+        GrAssert(!ibuf->isLocked());
+        if (fHWGeometryState.fIndexBuffer != ibuf) {
+            GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID()));
+            fHWGeometryState.fIndexBuffer = ibuf;
+        }
+    }
+}
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
new file mode 100644
index 0000000..ea0c081
--- /dev/null
+++ b/gpu/src/GrGpuGL.h
@@ -0,0 +1,185 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGL_DEFINED
+#define GrGpuGL_DEFINED
+
+#include "GrGpu.h"
+#include "GrGLConfig.h"
+#include "GrGLIRect.h"
+#include "GrGLTexture.h"
+
+#include "GrGLVertexBuffer.h"
+#include "GrGLIndexBuffer.h"
+
+class GrGpuGL : public GrGpu {
+public:
+            GrGpuGL();
+    virtual ~GrGpuGL();
+
+protected:
+    struct {
+        size_t                  fVertexOffset;
+        GrVertexLayout          fVertexLayout;
+        const GrVertexBuffer*   fVertexBuffer;
+        const GrIndexBuffer*    fIndexBuffer;
+        bool                    fArrayPtrsDirty;
+    } fHWGeometryState;
+
+    DrState   fHWDrawState;
+    bool      fHWStencilClip;
+
+    // As flush of GL state proceeds it updates fHDrawState
+    // to reflect the new state. Later parts of the state flush
+    // may perform cascaded changes but cannot refer to fHWDrawState.
+    // These code paths can refer to the dirty flags. Subclass should
+    // call resetDirtyFlags after its flush is complete
+    struct {
+        bool fRenderTargetChanged : 1;
+        int  fTextureChangedMask;
+    } fDirtyFlags;
+    GR_STATIC_ASSERT(8 * sizeof(int) >= kNumStages);
+
+    // clears the dirty flags
+    void resetDirtyFlags();
+
+    // last scissor / viewport scissor state seen by the GL.
+    struct {
+        bool        fScissorEnabled;
+        GrGLIRect   fScissorRect;
+        GrGLIRect   fViewportRect;
+    } fHWBounds;
+
+    // GrGpu overrides
+    // overrides from GrGpu
+    virtual void resetContext();
+
+    virtual GrTexture* createTextureHelper(const TextureDesc& desc,
+                                           const void* srcData,
+                                           size_t rowBytes);
+    virtual GrVertexBuffer* createVertexBufferHelper(uint32_t size,
+                                                     bool dynamic);
+    virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
+                                                   bool dynamic);
+
+    virtual GrRenderTarget* createPlatformRenderTargetHelper(
+                                                 intptr_t platformRenderTarget,
+                                                 int stencilBits,
+                                                 int width, int height);
+
+    virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper();
+
+    virtual void eraseColorHelper(GrColor color);
+
+    virtual void forceRenderTargetFlushHelper();
+
+    virtual bool readPixelsHelper(int left, int top, int width, int height,
+                                  GrTexture::PixelConfig, void* buffer);
+
+    virtual void drawIndexedHelper(GrPrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount);
+    virtual void drawNonIndexedHelper(GrPrimitiveType type,
+                                      uint32_t vertexCount,
+                                      uint32_t numVertices);
+    virtual void flushScissor(const GrIRect* rect);
+    void eraseStencil(uint32_t value, uint32_t mask);
+    virtual void eraseStencilClip(const GrIRect& rect);
+
+    // binds texture unit in GL
+    void setTextureUnit(int unitIdx);
+
+    // binds appropriate vertex and index buffers, also returns any extra
+    // extra verts or indices to offset by.
+    void setBuffers(bool indexed,
+                    int* extraVertexOffset,
+                    int* extraIndexOffset);
+
+    // flushes state that is common to fixed and programmable GL
+    // dither
+    // line smoothing
+    // blend func
+    // texture binding
+    // sampler state (filtering, tiling)
+    // FBO binding
+    // line width
+    bool flushGLStateCommon(GrPrimitiveType type);
+
+    // adjusts texture matrix to account for orientation, size, and npotness
+    static void AdjustTextureMatrix(const GrGLTexture* texture,
+                                    GrSamplerState::SampleMode mode,
+                                    GrMatrix* matrix);
+
+    // subclass may try to take advantage of identity tex matrices.
+    // This helper determines if matrix will be identity after all
+    // adjustments are applied.
+    static bool TextureMatrixIsIdentity(const GrGLTexture* texture,
+                                        const GrSamplerState& sampler);
+
+    static bool BlendCoefReferencesConstant(GrBlendCoeff coeff);
+
+private:
+    // notify callbacks to update state tracking when related
+    // objects are bound to GL or deleted outside of the class
+    void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
+    void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer);
+    void notifyIndexBufferBind(const GrGLIndexBuffer* buffer);
+    void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
+    void notifyTextureDelete(GrGLTexture* texture);
+    void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
+
+    void setSpareTextureUnit();
+
+    void flushRenderTarget();
+    void flushStencil();
+    void resolveTextureRenderTarget(GrGLTexture* texture);
+
+    bool canBeTexture(GrTexture::PixelConfig config,
+                      GLenum* internalFormat,
+                      GLenum* format,
+                      GLenum* type);
+    bool fboInternalFormat(GrTexture::PixelConfig config, GLenum* format);
+
+    friend class GrGLVertexBuffer;
+    friend class GrGLIndexBuffer;
+    friend class GrGLTexture;
+    friend class GrGLRenderTarget;
+
+    bool fHWBlendDisabled;
+
+    GLuint fAASamples[4];
+    enum {
+        kNone_MSFBO = 0,
+        kDesktop_MSFBO,
+        kApple_MSFBO,
+        kIMG_MSFBO
+    } fMSFBOType;
+
+    // Do we have stencil wrap ops.
+    bool fHasStencilWrap;
+
+    // ES requires an extension to support RGBA8 in RenderBufferStorage
+    bool fRGBA8Renderbuffer;
+
+    int fActiveTextureUnitIdx;
+
+    typedef GrGpu INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
new file mode 100644
index 0000000..afd9bb6
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -0,0 +1,335 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLFixed.h"
+#include "GrGpuVertex.h"
+
+#define SKIP_CACHE_CHECK    true
+
+struct GrGpuMatrix {
+    GLfloat    fMat[16];
+
+    void reset() {
+        Gr_bzero(fMat, sizeof(fMat));
+        fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
+    }
+
+    void set(const GrMatrix& m) {
+        Gr_bzero(fMat, sizeof(fMat));
+        fMat[0]  = GrScalarToFloat(m[GrMatrix::kScaleX]);
+        fMat[4]  = GrScalarToFloat(m[GrMatrix::kSkewX]);
+        fMat[12] = GrScalarToFloat(m[GrMatrix::kTransX]);
+
+        fMat[1]  = GrScalarToFloat(m[GrMatrix::kSkewY]);
+        fMat[5]  = GrScalarToFloat(m[GrMatrix::kScaleY]);
+        fMat[13] = GrScalarToFloat(m[GrMatrix::kTransY]);
+
+        fMat[3]  = GrScalarToFloat(m[GrMatrix::kPersp0]);
+        fMat[7]  = GrScalarToFloat(m[GrMatrix::kPersp1]);
+        fMat[15] = GrScalarToFloat(m[GrMatrix::kPersp2]);
+
+        fMat[10] = 1.f;    // z-scale
+    }
+};
+
+// these must match the order in the corresponding enum in GrGpu.h
+static const GLenum gMatrixMode2Enum[] = {
+    GL_MODELVIEW, GL_TEXTURE
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrGpuGLFixed::GrGpuGLFixed() {
+}
+
+GrGpuGLFixed::~GrGpuGLFixed() {
+}
+
+void GrGpuGLFixed::resetContext() {
+    INHERITED::resetContext();
+
+    GR_GL(Disable(GL_TEXTURE_2D));
+
+    for (int s = 0; s < kNumStages; ++s) {
+        setTextureUnit(s);
+        GR_GL(EnableClientState(GL_VERTEX_ARRAY));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,   GL_MODULATE));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,      GL_TEXTURE0+s));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,      GL_PREVIOUS));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,  GL_SRC_COLOR));
+
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0+s));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS));
+        GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
+
+        // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending
+        // upon whether we have a (premultiplied) RGBA texture or just an ALPHA
+        // texture, e.g.:
+        //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,  GL_SRC_COLOR);
+        fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
+    }
+
+    fHWGeometryState.fVertexLayout = 0;
+    fHWGeometryState.fVertexOffset  = ~0;
+    GR_GL(EnableClientState(GL_VERTEX_ARRAY));
+    GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+    GR_GL(ShadeModel(GL_FLAT));
+    GR_GL(DisableClientState(GL_COLOR_ARRAY));
+
+    GR_GL(PointSize(1.f));
+
+    GrGLClearErr();
+    fTextVerts = false;
+
+    fBaseVertex = 0xffffffff;
+}
+
+
+void GrGpuGLFixed::flushProjectionMatrix() {
+    float mat[16];
+    Gr_bzero(mat, sizeof(mat));
+
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+
+    mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
+    mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
+    mat[10] = -1.f;
+    mat[15] = 1;
+
+    mat[12] = -1.f;
+    mat[13] = 1.f;
+
+    GR_GL(MatrixMode(GL_PROJECTION));
+    GR_GL(LoadMatrixf(mat));
+}
+
+bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) {
+
+    bool usingTextures[kNumStages];
+
+    for (int s = 0; s < kNumStages; ++s) {
+        usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
+
+        if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
+            unimpl("Fixed pipe doesn't support radial/sweep gradients");
+            return false;
+        }
+    }
+
+#if GR_SUPPORT_GLES1
+    if (BlendCoefReferencesConstant(fCurrDrawState.fSrcBlend) ||
+        BlendCoefReferencesConstant(fCurrDrawState.fDstBlend)) {
+        uimpl("ES1 doesn't support blend constant");
+        return false;
+    }
+#endif
+
+    if (!flushGLStateCommon(type)) {
+        return false;
+    }
+
+    if (fDirtyFlags.fRenderTargetChanged) {
+        flushProjectionMatrix();
+    }
+
+    for (int s = 0; s < kNumStages; ++s) {
+        bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
+        if (usingTextures[s] != wasUsingTexture) {
+            setTextureUnit(s);
+            if (usingTextures[s]) {
+                GR_GL(Enable(GL_TEXTURE_2D));
+            } else {
+                GR_GL(Disable(GL_TEXTURE_2D));
+            }
+        }
+    }
+
+    uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+    uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
+                              kColor_VertexLayoutBit);
+
+    if (vertColor != prevVertColor) {
+        if (vertColor) {
+            GR_GL(ShadeModel(GL_SMOOTH));
+            // invalidate the immediate mode color
+            fHWDrawState.fColor = GrColor_ILLEGAL;
+        } else {
+            GR_GL(ShadeModel(GL_FLAT));
+        }
+    }
+
+
+    if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
+        GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
+                       GrColorUnpackG(fCurrDrawState.fColor),
+                       GrColorUnpackB(fCurrDrawState.fColor),
+                       GrColorUnpackA(fCurrDrawState.fColor)));
+        fHWDrawState.fColor = fCurrDrawState.fColor;
+    }
+
+    // set texture environment, decide whether we are modulating by RGB or A.
+    for (int s = 0; s < kNumStages; ++s) {
+        if (usingTextures[s]) {
+            GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
+            if (NULL != texture) {
+                TextureEnvRGBOperands nextRGBOperand0 =
+                    (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
+                        kAlpha_TextureEnvRGBOperand :
+                        kColor_TextureEnvRGBOperand;
+                if (fHWRGBOperand0[s] != nextRGBOperand0) {
+                    setTextureUnit(s);
+                    GR_GL(TexEnvi(GL_TEXTURE_ENV,
+                                  GL_OPERAND0_RGB,
+                                  (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
+                                    GL_SRC_ALPHA :
+                                    GL_SRC_COLOR));
+                    fHWRGBOperand0[s] = nextRGBOperand0;
+                }
+
+                if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
+                    (fHWDrawState.fSamplerStates[s].getMatrix() !=
+                     getSamplerMatrix(s))) {
+
+                    GrMatrix texMat = getSamplerMatrix(s);
+                    AdjustTextureMatrix(texture,
+                                        GrSamplerState::kNormal_SampleMode,
+                                        &texMat);
+                    GrGpuMatrix glm;
+                    glm.set(texMat);
+                    setTextureUnit(s);
+                    GR_GL(MatrixMode(GL_TEXTURE));
+                    GR_GL(LoadMatrixf(glm.fMat));
+                    recordHWSamplerMatrix(s, getSamplerMatrix(s));
+                }
+            } else {
+                GrAssert(!"Rendering with texture vert flag set but no bound texture");
+                return false;
+            }
+        }
+    }
+
+    if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
+        GrGpuMatrix glm;
+        glm.set(fCurrDrawState.fViewMatrix);
+        GR_GL(MatrixMode(GL_MODELVIEW));
+        GR_GL(LoadMatrixf(glm.fMat));
+        fHWDrawState.fViewMatrix =
+        fCurrDrawState.fViewMatrix;
+    }
+    resetDirtyFlags();
+    return true;
+}
+
+void GrGpuGLFixed::setupGeometry(int* startVertex,
+                                 int* startIndex,
+                                 int vertexCount,
+                                 int indexCount) {
+
+    int newColorOffset;
+    int newTexCoordOffsets[kNumStages];
+
+    GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
+                                                    newTexCoordOffsets,
+                                                    &newColorOffset);
+    int oldColorOffset;
+    int oldTexCoordOffsets[kNumStages];
+    GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
+                                                    oldTexCoordOffsets,
+                                                    &oldColorOffset);
+
+    bool indexed = NULL != startIndex;
+
+    int extraVertexOffset;
+    int extraIndexOffset;
+    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+
+    GLenum scalarType;
+    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+        scalarType = GrGLTextType;
+    } else {
+        scalarType = GrGLType;
+    }
+
+    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+    *startVertex = 0;
+    if (indexed) {
+        *startIndex += extraIndexOffset;
+    }
+
+    // all the Pointers must be set if any of these are true
+    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
+                             vertexOffset != fHWGeometryState.fVertexOffset ||
+                             newStride != oldStride;
+
+    // position and tex coord offsets change if above conditions are true
+    // or the type changed based on text vs nontext type coords.
+    bool posAndTexChange = allOffsetsChange ||
+                           ((GrGLTextType != GrGLType) &&
+                                (kTextFormat_VertexLayoutBit &
+                                  (fHWGeometryState.fVertexLayout ^
+                                   fGeometrySrc.fVertexLayout)));
+
+    if (posAndTexChange) {
+        GR_GL(VertexPointer(2, scalarType, newStride, (GLvoid*)vertexOffset));
+        fHWGeometryState.fVertexOffset = vertexOffset;
+    }
+
+    for (int s = 0; s < kNumStages; ++s) {
+        // need to enable array if tex coord offset is 0
+        // (using positions as coords)
+        if (newTexCoordOffsets[s] >= 0) {
+            GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[s]);
+            if (oldTexCoordOffsets[s] < 0) {
+                GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+                GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
+                GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
+            } else if (posAndTexChange ||
+                       newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
+                GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+                GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
+            }
+        } else if (oldTexCoordOffsets[s] >= 0) {
+            GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+            GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+        }
+    }
+
+    if (newColorOffset > 0) {
+        GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset);
+        if (oldColorOffset <= 0) {
+            GR_GL(EnableClientState(GL_COLOR_ARRAY));
+            GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
+        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
+            GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
+        }
+    } else if (oldColorOffset > 0) {
+        GR_GL(DisableClientState(GL_COLOR_ARRAY));
+    }
+
+    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+    fHWGeometryState.fArrayPtrsDirty = false;
+}
+
+#endif
+
diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h
new file mode 100644
index 0000000..077b6e2
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.h
@@ -0,0 +1,72 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGLFixed_DEFINED
+#define GrGpuGLFixed_DEFINED
+
+#include "GrGpuGL.h"
+
+// Fixed Pipeline OpenGL or OpenGL ES 1.x
+class GrGpuGLFixed : public GrGpuGL {
+public:
+             GrGpuGLFixed();
+    virtual ~GrGpuGLFixed();
+
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(GrPrimitiveType type);
+    virtual void setupGeometry(int* startVertex,
+                               int* startIndex,
+                               int vertexCount,
+                               int indexCount);
+
+private:
+    virtual void resetContext();
+
+    // Helpers to make code more readable
+    const GrMatrix& getHWSamplerMatrix(int stage) const {
+        return fHWDrawState.fSamplerStates[stage].getMatrix();
+    }
+    const void recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
+        fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
+    }
+
+    // when the texture is GL_RGBA we set the GL_COMBINE texture
+    // environment rgb operand 0 to be GL_COLOR to modulate each incoming
+    // R,G, & B by the texture's R, G, & B. When the texture is alpha-only we
+    // set the operand to GL_ALPHA so that the incoming frag's R, G, &B are all
+    // modulated by the texture's A.
+    enum TextureEnvRGBOperands {
+        kAlpha_TextureEnvRGBOperand,
+        kColor_TextureEnvRGBOperand,
+    };
+    TextureEnvRGBOperands fHWRGBOperand0[kNumStages];
+
+    void flushProjectionMatrix();
+
+    // are the currently bound vertex buffers/arrays laid
+    // out for text or other drawing.
+    bool fTextVerts;
+
+    // On GL we have to build the base vertex offset into the
+    // glVertexPointer/glTexCoordPointer/etc
+    int fBaseVertex;
+
+    typedef GrGpuGL INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
new file mode 100644
index 0000000..f79e9c8
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -0,0 +1,1406 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLShaders2.h"
+#include "GrGpuVertex.h"
+#include "GrMemory.h"
+#include "GrStringBuilder.h"
+
+
+#define ATTRIBUTE_MATRIX        0
+
+#define PRINT_SHADERS           0
+
+#define SKIP_CACHE_CHECK    true
+
+#if GR_SUPPORT_GLES2
+    #define GR_PRECISION                "mediump"
+    const char GR_SHADER_PRECISION[] =  "precision mediump float;\n";
+#else
+    #define GR_PRECISION                ""
+    const char GR_SHADER_PRECISION[] =  "";
+#endif
+
+
+#define POS_ATTR_LOCATION 0
+#define TEX_ATTR_LOCATION(X) (1 + X)
+#define COL_ATTR_LOCATION (2 + GrDrawTarget::kMaxTexCoords)
+#if ATTRIBUTE_MATRIX
+#define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
+#define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
+#define BOGUS_MATRIX_UNI_LOCATION 1000
+#endif
+
+#define GR_UINT32_MAX   static_cast<uint32_t>(-1)
+
+struct GrGpuGLShaders2::StageUniLocations {
+    GLint fTextureMatrixUni;
+    GLint fSamplerUni;
+    GLint fRadial2Uni;
+};
+
+struct GrGpuGLShaders2::UniLocations {
+    GLint fViewMatrixUni;
+    StageUniLocations fStages[kNumStages];
+};
+
+// Records per-program information
+// we can specify the attribute locations so that they are constant
+// across our shaders. But the driver determines the uniform locations
+// at link time. We don't need to remember the sampler uniform location
+// because we will bind a texture slot to it and never change it
+// Uniforms are program-local so we can't rely on fHWState to hold the
+// previous uniform state after a program change.
+struct  GrGpuGLShaders2::Program {
+    // IDs
+    GLuint    fVShaderID;
+    GLuint    fFShaderID;
+    GLuint    fProgramID;
+
+    // shader uniform locations (-1 if shader doesn't use them)
+    UniLocations fUniLocations;
+
+    // these reflect the current values of uniforms
+    // (GL uniform values travel with program)
+    GrMatrix                    fViewMatrix;
+    GrMatrix                    fTextureMatrices[kNumStages];
+    GrScalar                    fRadial2CenterX1[kNumStages];
+    GrScalar                    fRadial2Radius0[kNumStages];
+    bool                        fRadial2PosRoot[kNumStages];
+
+};
+
+// must be tightly packed
+struct GrGpuGLShaders2::StageDesc {
+    enum OptFlagBits {
+        kNoPerspective_OptFlagBit  = 0x1,
+        kIdentityMatrix_OptFlagBit = 0x2,
+    };
+    unsigned fOptFlags : 8;
+
+    unsigned fEnabled : 8;
+
+    enum Modulation {
+        kColor_Modulation,
+        kAlpha_Modulation,
+    } fModulation : 8;
+
+    enum CoordMapping {
+        kIdentity_CoordMapping,
+        kRadialGradient_CoordMapping,
+        kSweepGradient_CoordMapping,
+        kRadial2Gradient_CoordMapping,
+    } fCoordMapping : 8;
+};
+
+// must be tightly packed
+struct GrGpuGLShaders2::ProgramDesc {
+    GrVertexLayout fVertexLayout;
+    GR_STATIC_ASSERT(2 == sizeof(GrVertexLayout)); // pack with next field
+
+    enum {
+        kNotPoints_OptFlagBit = 0x1,
+        kVertexColorAllOnes_OptFlagBit = 0x2,
+    };
+    // we're assuming optflags and layout pack into 32 bits
+    // VS 2010 seems to require short rather than just unsigned
+    // for this to pack
+    unsigned short fOptFlags : 16;
+
+    StageDesc fStages[kNumStages];
+
+    bool operator == (const ProgramDesc& desc) const {
+        // keep 4-byte aligned and tightly packed
+        GR_STATIC_ASSERT(4 == sizeof(StageDesc));
+        GR_STATIC_ASSERT(2 + 2 + 4 * kNumStages == sizeof(ProgramDesc));
+        return 0 == memcmp(this, &desc, sizeof(ProgramDesc));
+    }
+};
+
+#include "GrTHashCache.h"
+
+class GrGpuGLShaders2::ProgramCache : public ::GrNoncopyable {
+private:
+    struct Entry;
+    class HashKey {
+    public:
+        HashKey();
+        HashKey(const ProgramDesc& desc);
+        static const HashKey& GetKey(const Entry&);
+        static bool EQ(const Entry&, const HashKey&);
+        static bool LT(const Entry&, const HashKey&);
+        bool operator <(const HashKey& key) const;
+        bool operator ==(const HashKey& key) const;
+        uint32_t getHash() const;
+    private:
+        ProgramDesc fDesc;
+        uint32_t fHash;
+    };
+
+    struct Entry {
+        Program     fProgram;
+        HashKey     fKey;
+        uint32_t    fLRUStamp;
+    };
+
+    // if hash bits is changed, need to change hash function
+    GrTHashTable<Entry, HashKey, 8> fHashCache;
+
+    static const int MAX_ENTRIES = 16;
+    Entry        fEntries[MAX_ENTRIES];
+    int          fCount;
+    uint32_t     fCurrLRUStamp;
+
+public:
+    ProgramCache() {
+        fCount        = 0;
+        fCurrLRUStamp = 0;
+    }
+
+    ~ProgramCache() {
+        for (int i = 0; i < fCount; ++i) {
+            GrGpuGLShaders2::DeleteProgram(&fEntries[i].fProgram);
+        }
+    }
+
+    void abandon() {
+        fCount = 0;
+    }
+
+    void invalidateViewMatrices() {
+        for (int i = 0; i < fCount; ++i) {
+            // set to illegal matrix
+            fEntries[i].fProgram.fViewMatrix = GrMatrix::InvalidMatrix();
+        }
+    }
+
+    Program* getProgram(const ProgramDesc& desc) {
+        HashKey key(desc);
+        Entry* entry = fHashCache.find(key);
+        if (NULL == entry) {
+            if (fCount < MAX_ENTRIES) {
+                entry = fEntries + fCount;
+                ++fCount;
+            } else {
+                GrAssert(MAX_ENTRIES == fCount);
+                entry = fEntries;
+                for (int i = 1; i < MAX_ENTRIES; ++i) {
+                    if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
+                        entry = fEntries + i;
+                    }
+                }
+                fHashCache.remove(entry->fKey, entry);
+                GrGpuGLShaders2::DeleteProgram(&entry->fProgram);
+            }
+            entry->fKey = key;
+            GrGpuGLShaders2::GenProgram(desc, &entry->fProgram);
+            fHashCache.insert(entry->fKey, entry);
+        }
+
+        entry->fLRUStamp = fCurrLRUStamp;
+        if (GR_UINT32_MAX == fCurrLRUStamp) {
+            // wrap around! just trash our LRU, one time hit.
+            for (int i = 0; i < fCount; ++i) {
+                fEntries[i].fLRUStamp = 0;
+            }
+        }
+        ++fCurrLRUStamp;
+        return &entry->fProgram;
+    }
+};
+
+GrGpuGLShaders2::ProgramCache::HashKey::HashKey() {
+}
+
+static uint32_t ror(uint32_t x) {
+    return (x >> 8) | (x << 24);
+}
+
+static uint32_t rol(uint32_t x) {
+    return (x << 8) | (x >> 24);
+}
+
+GrGpuGLShaders2::ProgramCache::HashKey::HashKey(const ProgramDesc& desc) {
+    fDesc = desc;
+    // if you change the size of the desc, need to update the hash function
+    GR_STATIC_ASSERT(12 == sizeof(ProgramDesc));
+
+    uint32_t* d = GrTCast<uint32_t*>(&fDesc);
+    fHash = d[0] ^ ror(d[1]) ^ rol(d[2]);
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::EQ(const Entry& entry,
+                                                const HashKey& key) {
+    return entry.fKey == key;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::LT(const Entry& entry,
+                                                const HashKey& key) {
+    return entry.fKey < key;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::operator ==(const HashKey& key) const {
+    return fDesc == key.fDesc;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::operator <(const HashKey& key) const {
+    return memcmp(&fDesc, &key.fDesc, sizeof(HashKey)) < 0;
+}
+
+uint32_t GrGpuGLShaders2::ProgramCache::HashKey::getHash() const {
+    return fHash;
+}
+
+struct GrGpuGLShaders2::ShaderCodeSegments {
+    GrSStringBuilder<256> fVSUnis;
+    GrSStringBuilder<256> fVSAttrs;
+    GrSStringBuilder<256> fVaryings;
+    GrSStringBuilder<256> fFSUnis;
+    GrSStringBuilder<512> fVSCode;
+    GrSStringBuilder<512> fFSCode;
+};
+// for variable names etc
+typedef GrSStringBuilder<16> GrTokenString;
+
+#if ATTRIBUTE_MATRIX
+    #define VIEW_MATRIX_NAME "aViewM"
+#else
+    #define VIEW_MATRIX_NAME "uViewM"
+#endif
+
+#define POS_ATTR_NAME "aPosition"
+#define COL_ATTR_NAME "aColor"
+
+static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
+    *s = "aTexCoord";
+    s->appendInt(coordIdx);
+}
+
+static inline const char* float_vector_type(int count) {
+    static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"};
+    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(FLOAT_VECS));
+    return FLOAT_VECS[count];
+}
+
+static inline const char* vector_homog_coord(int count) {
+    static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
+    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
+    return HOMOGS[count];
+}
+
+static inline const char* vector_nonhomog_coords(int count) {
+    static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
+    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
+    return NONHOMOGS[count];
+}
+
+static inline const char* vector_all_coords(int count) {
+    static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"};
+    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ALL));
+    return ALL[count];
+}
+
+static void tex_matrix_name(int stage, GrStringBuilder* s) {
+#if ATTRIBUTE_MATRIX
+    *s = "aTexM";
+#else
+    *s = "uTexM";
+#endif
+    s->appendInt(stage);
+}
+
+static void sampler_name(int stage, GrStringBuilder* s) {
+    *s = "uSampler";
+    s->appendInt(stage);
+}
+
+static void stage_varying_name(int stage, GrStringBuilder* s) {
+    *s = "vStage";
+    s->appendInt(stage);
+}
+
+static void radial2_param_name(int stage, GrStringBuilder* s) {
+    *s = "uRadial2Params";
+    s->appendInt(stage);
+}
+
+static void radial2_varying_name(int stage, GrStringBuilder* s) {
+    *s = "vB";
+    s->appendInt(stage);
+}
+
+#include "GrRandom.h"
+
+void GrGpuGLShaders2::ProgramUnitTest() {
+    static const int PROG_OPTS[] = {
+        0,
+        ProgramDesc::kNotPoints_OptFlagBit,
+        ProgramDesc::kVertexColorAllOnes_OptFlagBit,
+        ProgramDesc::kNotPoints_OptFlagBit | ProgramDesc::kVertexColorAllOnes_OptFlagBit
+    };
+    static const int STAGE_OPTS[] = {
+        0,
+        StageDesc::kNoPerspective_OptFlagBit,
+        StageDesc::kIdentity_CoordMapping
+    };
+    static const int STAGE_MODULATES[] = {
+        StageDesc::kColor_Modulation,
+        StageDesc::kAlpha_Modulation
+    };
+    static const int STAGE_COORD_MAPPINGS[] = {
+        StageDesc::kIdentity_CoordMapping,
+        StageDesc::kRadialGradient_CoordMapping,
+        StageDesc::kSweepGradient_CoordMapping,
+        StageDesc::kRadial2Gradient_CoordMapping
+    };
+    ProgramDesc pdesc;
+    memset(&pdesc, 0, sizeof(pdesc));
+
+    static const int NUM_TESTS = 512;
+
+    // GrRandoms nextU() values have patterns in the low bits
+    // So using nextU() % array_count might never take some values.
+    GrRandom random;
+    for (int t = 0; t < NUM_TESTS; ++t) {
+
+        pdesc.fVertexLayout = 0;
+        for (int s = 0; s < kNumStages; ++s) {
+            // enable the stage?
+            if (random.nextF() > .5f) {
+                // use separate tex coords?
+                if (random.nextF() > .5f) {
+                    int t = (int)(random.nextF() * kMaxTexCoords);
+                    pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
+                } else {
+                    pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s);
+                }
+            }
+            // use text-formatted verts?
+            if (random.nextF() > .5f) {
+                pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
+            }
+        }
+
+        int x = (int)(random.nextF() * GR_ARRAY_COUNT(PROG_OPTS));
+        pdesc.fOptFlags = PROG_OPTS[x];
+        for (int s = 0; s < kNumStages; ++s) {
+            pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout);
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
+            pdesc.fStages[s].fOptFlags = STAGE_OPTS[x];
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
+            pdesc.fStages[s].fModulation = (StageDesc::Modulation) STAGE_MODULATES[x];
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_COORD_MAPPINGS));
+            pdesc.fStages[s].fCoordMapping = (StageDesc::CoordMapping) STAGE_COORD_MAPPINGS[x];
+        }
+        Program program;
+        GenProgram(pdesc, &program);
+        DeleteProgram(&program);
+    }
+}
+
+void GrGpuGLShaders2::GenStageCode(int stageNum,
+                                   const StageDesc& desc,
+                                   const char* fsInColor, // NULL means no incoming color
+                                   const char* fsOutColor,
+                                   const char* vsInCoord,
+                                   ShaderCodeSegments* segments,
+                                   StageUniLocations* locations) {
+
+    GrAssert(stageNum >= 0 && stageNum <= 9);
+
+    GrTokenString varyingName;
+    stage_varying_name(stageNum, &varyingName);
+
+    // First decide how many coords are needed to access the texture
+    // Right now it's always 2 but we could start using 1D textures for
+    // gradients.
+    static const int coordDims = 2;
+    int varyingDims;
+    /// Vertex Shader Stuff
+
+    // decide whether we need a matrix to transform texture coords
+    // and whether the varying needs a perspective coord.
+    GrTokenString texMName;
+    tex_matrix_name(stageNum, &texMName);
+    if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
+        varyingDims = coordDims;
+    } else {
+    #if ATTRIBUTE_MATRIX
+        segments->fVSAttrs += "attribute mat3 ";
+        segments->fVSAttrs += texMName;
+        segments->fVSAttrs += ";\n";
+    #else
+        segments->fVSUnis += "uniform mat3 ";
+        segments->fVSUnis += texMName;
+        segments->fVSUnis += ";\n";
+        locations->fTextureMatrixUni = 1;
+    #endif
+        if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
+            varyingDims = coordDims;
+        } else {
+            varyingDims = coordDims + 1;
+        }
+    }
+
+    GrTokenString samplerName;
+    sampler_name(stageNum, &samplerName);
+    segments->fFSUnis += "uniform sampler2D ";
+    segments->fFSUnis += samplerName;
+    segments->fFSUnis += ";\n";
+    locations->fSamplerUni = 1;
+
+    segments->fVaryings += "varying ";
+    segments->fVaryings += float_vector_type(varyingDims);
+    segments->fVaryings += " ";
+    segments->fVaryings += varyingName;
+    segments->fVaryings += ";\n";
+
+    if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
+        GrAssert(varyingDims == coordDims);
+        segments->fVSCode += "\t";
+        segments->fVSCode += varyingName;
+        segments->fVSCode += " = ";
+        segments->fVSCode += vsInCoord;
+        segments->fVSCode += ";\n";
+    } else {
+        segments->fVSCode += "\t";
+        segments->fVSCode += varyingName;
+        segments->fVSCode += " = (";
+        segments->fVSCode += texMName;
+        segments->fVSCode += " * vec3(";
+        segments->fVSCode += vsInCoord;
+        segments->fVSCode += ", 1))";
+        segments->fVSCode += vector_all_coords(varyingDims);
+        segments->fVSCode += ";\n";
+    }
+
+    GrTokenString radial2ParamsName;
+    radial2_param_name(stageNum, &radial2ParamsName);
+    // for radial grads without perspective we can pass the linear
+    // part of the quadratic as a varying.
+    GrTokenString radial2VaryingName;
+    radial2_varying_name(stageNum, &radial2VaryingName);
+
+    if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) {
+
+        segments->fVSUnis += "uniform " GR_PRECISION " float ";
+        segments->fVSUnis += radial2ParamsName;
+        segments->fVSUnis += "[6];\n";
+
+        segments->fFSUnis += "uniform " GR_PRECISION " float ";
+        segments->fFSUnis += radial2ParamsName;
+        segments->fFSUnis += "[6];\n";
+        locations->fRadial2Uni = 1;
+
+        // if there is perspective we don't interpolate this
+        if (varyingDims == coordDims) {
+            GrAssert(2 == coordDims);
+            segments->fVaryings += "varying float ";
+            segments->fVaryings += radial2VaryingName;
+            segments->fVaryings += ";\n";
+
+            segments->fVSCode += "\t";
+            segments->fVSCode += radial2VaryingName;
+            segments->fVSCode += " = 2.0 * (";
+            segments->fVSCode += radial2ParamsName;
+            segments->fVSCode += "[2] * ";
+            segments->fVSCode += varyingName;
+            segments->fVSCode += ".x ";
+            segments->fVSCode += " - ";
+            segments->fVSCode += radial2ParamsName;
+            segments->fVSCode += "[3]);\n";
+        }
+    }
+
+    /// Fragment Shader Stuff
+    GrTokenString fsCoordName;
+    // function used to access the shader, may be made projective
+    GrTokenString texFunc("texture2D");
+    if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
+                          StageDesc::kNoPerspective_OptFlagBit)) {
+        GrAssert(varyingDims == coordDims);
+        fsCoordName = varyingName;
+    } else {
+        // if we have to do some non-matrix op on the varyings to get
+        // our final tex coords then when in perspective we have to
+        // do an explicit divide
+        if  (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping) {
+            texFunc += "Proj";
+            fsCoordName = varyingName;
+        } else {
+            fsCoordName = "tCoord";
+            fsCoordName.appendInt(stageNum);
+
+            segments->fFSCode += "\t";
+            segments->fFSCode += float_vector_type(coordDims);
+            segments->fFSCode += " ";
+            segments->fFSCode += fsCoordName;
+            segments->fFSCode += " = ";
+            segments->fFSCode += varyingName;
+            segments->fFSCode += vector_nonhomog_coords(varyingDims);
+            segments->fFSCode += " / ";
+            segments->fFSCode += varyingName;
+            segments->fFSCode += vector_homog_coord(varyingDims);
+            segments->fFSCode += ";\n";
+        }
+    }
+
+    GrSStringBuilder<96> sampleCoords;
+    switch (desc.fCoordMapping) {
+    case StageDesc::kIdentity_CoordMapping:
+        sampleCoords = fsCoordName;
+        break;
+    case StageDesc::kSweepGradient_CoordMapping:
+        sampleCoords = "vec2(atan(-";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".y, -";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".x)*0.1591549430918 + 0.5, 0.5)";
+        break;
+    case StageDesc::kRadialGradient_CoordMapping:
+        sampleCoords = "vec2(length(";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".xy), 0.5)";
+        break;
+    case StageDesc::kRadial2Gradient_CoordMapping: {
+        GrTokenString cName    = "c";
+        GrTokenString ac4Name  = "ac4";
+        GrTokenString rootName = "root";
+
+        cName.appendInt(stageNum);
+        ac4Name.appendInt(stageNum);
+        rootName.appendInt(stageNum);
+
+        GrTokenString bVar;
+        if (coordDims == varyingDims) {
+            bVar = radial2VaryingName;
+            GrAssert(2 == varyingDims);
+        } else {
+            GrAssert(3 == varyingDims);
+            bVar = "b";
+            bVar.appendInt(stageNum);
+            segments->fFSCode += "\tfloat ";
+            segments->fFSCode += bVar;
+            segments->fFSCode += " = 2.0 * (";
+            segments->fFSCode += radial2ParamsName;
+            segments->fFSCode += "[2] * ";
+            segments->fFSCode += fsCoordName;
+            segments->fFSCode += ".x ";
+            segments->fFSCode += " - ";
+            segments->fFSCode += radial2ParamsName;
+            segments->fFSCode += "[3]);\n";
+        }
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += cName;
+        segments->fFSCode += " = dot(";
+        segments->fFSCode += fsCoordName;
+        segments->fFSCode += ", ";
+        segments->fFSCode += fsCoordName;
+        segments->fFSCode += ") + ";
+        segments->fFSCode += " - ";
+        segments->fFSCode += radial2ParamsName;
+        segments->fFSCode += "[4];\n";
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += ac4Name;
+        segments->fFSCode += " = ";
+        segments->fFSCode += radial2ParamsName;
+        segments->fFSCode += "[0] * 4.0 * ";
+        segments->fFSCode += cName;
+        segments->fFSCode += ";\n";
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += rootName;
+        segments->fFSCode += " = sqrt(abs(";
+        segments->fFSCode += bVar;
+        segments->fFSCode += " * ";
+        segments->fFSCode += bVar;
+        segments->fFSCode += " - ";
+        segments->fFSCode += ac4Name;
+        segments->fFSCode += "));\n";
+
+        sampleCoords = "vec2((-";
+        sampleCoords += bVar;
+        sampleCoords += " + ";
+        sampleCoords += radial2ParamsName;
+        sampleCoords += "[5] * ";
+        sampleCoords += rootName;
+        sampleCoords += ") * ";
+        sampleCoords += radial2ParamsName;
+        sampleCoords += "[1], 0.5)\n";
+        break;}
+    };
+
+    segments->fFSCode += "\t";
+    segments->fFSCode += fsOutColor;
+    segments->fFSCode += " = ";
+    if (NULL != fsInColor) {
+        segments->fFSCode += fsInColor;
+        segments->fFSCode += " * ";
+    }
+    segments->fFSCode += texFunc;
+    segments->fFSCode += "(";
+    segments->fFSCode += samplerName;
+    segments->fFSCode += ", ";
+    segments->fFSCode += sampleCoords;
+    segments->fFSCode += ")";
+    if (desc.fModulation == StageDesc::kAlpha_Modulation) {
+        segments->fFSCode += ".aaaa";
+    }
+    segments->fFSCode += ";\n";
+
+}
+
+void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
+                                 Program* program) {
+
+    ShaderCodeSegments segments;
+    const uint32_t& layout = desc.fVertexLayout;
+
+    memset(&program->fUniLocations, 0, sizeof(UniLocations));
+
+    bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit &
+                       desc.fOptFlags);
+
+#if ATTRIBUTE_MATRIX
+    segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n";
+#else
+    segments.fVSUnis  = "uniform mat3 " VIEW_MATRIX_NAME ";\n";
+    segments.fVSAttrs = "";
+#endif
+    segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
+    if (haveColor) {
+        segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
+        segments.fVaryings = "varying vec4 vColor;\n";
+    } else {
+        segments.fVaryings = "";
+    }
+
+    segments.fVSCode   = "void main() {\n"
+                         "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
+                         "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
+    if (haveColor) {
+        segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
+    }
+
+    if (!(desc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)){
+        segments.fVSCode += "\tgl_PointSize = 1.0;\n";
+    }
+    segments.fFSCode   = "void main() {\n";
+
+    // add texture coordinates that are used to the list of vertex attr decls
+    GrTokenString texCoordAttrs[kMaxTexCoords];
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (VertexUsesTexCoordIdx(t, layout)) {
+            tex_attr_name(t, texCoordAttrs + t);
+
+            segments.fVSAttrs += "attribute vec2 ";
+            segments.fVSAttrs += texCoordAttrs[t];
+            segments.fVSAttrs += ";\n";
+        }
+    }
+
+    // for each enabled stage figure out what the input coordinates are
+    // and count the number of stages in use.
+    const char* stageInCoords[kNumStages];
+    int numActiveStages = 0;
+
+    for (int s = 0; s < kNumStages; ++s) {
+        if (desc.fStages[s].fEnabled) {
+            if (StagePosAsTexCoordVertexLayoutBit(s) & layout) {
+                stageInCoords[s] = POS_ATTR_NAME;
+            } else {
+                int tcIdx = VertexTexCoordsForStage(s, layout);
+                 // we better have input tex coordinates if stage is enabled.
+                GrAssert(tcIdx >= 0);
+                GrAssert(texCoordAttrs[tcIdx].length());
+                stageInCoords[s] = texCoordAttrs[tcIdx].cstr();
+            }
+            ++numActiveStages;
+        }
+    }
+
+    GrTokenString inColor = "vColor";
+
+    // if we have active stages string them together, feeding the output color
+    // of each to the next and generating code for each stage.
+    if (numActiveStages) {
+        int currActiveStage = 0;
+        for (int s = 0; s < kNumStages; ++s) {
+            if (desc.fStages[s].fEnabled) {
+                GrTokenString outColor;
+                if (currActiveStage < (numActiveStages - 1)) {
+                    outColor = "color";
+                    outColor.appendInt(currActiveStage);
+                    segments.fFSCode += "\tvec4 ";
+                    segments.fFSCode += outColor;
+                    segments.fFSCode += ";\n";
+                } else {
+                    outColor = "gl_FragColor";
+                }
+                GenStageCode(s,
+                             desc.fStages[s],
+                             haveColor ? inColor.cstr() : NULL,
+                             outColor.cstr(),
+                             stageInCoords[s],
+                             &segments,
+                             &program->fUniLocations.fStages[s]);
+                ++currActiveStage;
+                inColor = outColor;
+                haveColor = true;
+            }
+        }
+    } else {
+        segments.fFSCode += "\tgl_FragColor = ";
+        if (haveColor) {
+            segments.fFSCode += inColor;
+        } else {
+            segments.fFSCode += "vec4(1,1,1,1)";
+        }
+        segments.fFSCode += ";\n";
+    }
+    segments.fFSCode += "}\n";
+    segments.fVSCode += "}\n";
+
+
+    const char* strings[4];
+    int lengths[4];
+    int stringCnt = 0;
+
+    if (segments.fVSUnis.length()) {
+        strings[stringCnt] = segments.fVSUnis.cstr();
+        lengths[stringCnt] = segments.fVSUnis.length();
+        ++stringCnt;
+    }
+    if (segments.fVSAttrs.length()) {
+        strings[stringCnt] = segments.fVSAttrs.cstr();
+        lengths[stringCnt] = segments.fVSAttrs.length();
+        ++stringCnt;
+    }
+    if (segments.fVaryings.length()) {
+        strings[stringCnt] = segments.fVaryings.cstr();
+        lengths[stringCnt] = segments.fVaryings.length();
+        ++stringCnt;
+    }
+
+    GrAssert(segments.fVSCode.length());
+    strings[stringCnt] = segments.fVSCode.cstr();
+    lengths[stringCnt] = segments.fVSCode.length();
+    ++stringCnt;
+
+#if PRINT_SHADERS
+    GrPrintf("%s%s%s%s\n",
+             segments.fVSUnis.cstr(),
+             segments.fVSAttrs.cstr(),
+             segments.fVaryings.cstr(),
+             segments.fVSCode.cstr());
+#endif
+    program->fVShaderID = CompileShader(GL_VERTEX_SHADER,
+                                        stringCnt,
+                                        strings,
+                                        lengths);
+
+    stringCnt = 0;
+
+    if (GR_ARRAY_COUNT(GR_SHADER_PRECISION) > 1) {
+        strings[stringCnt] = GR_SHADER_PRECISION;
+        lengths[stringCnt] = GR_ARRAY_COUNT(GR_SHADER_PRECISION) - 1;
+        ++stringCnt;
+    }
+    if (segments.fFSUnis.length()) {
+        strings[stringCnt] = segments.fFSUnis.cstr();
+        lengths[stringCnt] = segments.fFSUnis.length();
+        ++stringCnt;
+    }
+    if (segments.fVaryings.length()) {
+        strings[stringCnt] = segments.fVaryings.cstr();
+        lengths[stringCnt] = segments.fVaryings.length();
+        ++stringCnt;
+    }
+
+    GrAssert(segments.fFSCode.length());
+    strings[stringCnt] = segments.fFSCode.cstr();
+    lengths[stringCnt] = segments.fFSCode.length();
+    ++stringCnt;
+
+#if PRINT_SHADERS
+    GrPrintf("%s%s%s%s\n",
+             GR_SHADER_PRECISION,
+             segments.fFSUnis.cstr(),
+             segments.fVaryings.cstr(),
+             segments.fFSCode.cstr());
+#endif
+    program->fFShaderID = CompileShader(GL_FRAGMENT_SHADER,
+                                        stringCnt,
+                                        strings,
+                                        lengths);
+
+    program->fProgramID = GR_GL(CreateProgram());
+    const GLint& progID = program->fProgramID;
+
+    GR_GL(AttachShader(progID, program->fVShaderID));
+    GR_GL(AttachShader(progID, program->fFShaderID));
+
+    // Bind the attrib locations to same values for all shaders
+    GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME));
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (texCoordAttrs[t].length()) {
+            GR_GL(BindAttribLocation(progID,
+                                     TEX_ATTR_LOCATION(t),
+                                     texCoordAttrs[t].cstr()));
+        }
+    }
+
+#if ATTRIBUTE_MATRIX
+    // set unis to a bogus value so that checks against -1 before
+    // flushing will pass.
+    GR_GL(BindAttribLocation(progID,
+                             VIEWMAT_ATTR_LOCATION,
+                             VIEW_MATRIX_NAME));
+
+    program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION;
+
+    for (int s = 0; s < kNumStages; ++s) {
+        if (desc.fStages[s].fEnabled) {
+            GrStringBuilder matName;
+            tex_matrix_name(s, &matName);
+            GR_GL(BindAttribLocation(progID,
+                                     TEXMAT_ATTR_LOCATION(s),
+                                     matName.cstr()));
+            program->fUniLocations.fStages[s].fTextureMatrixUni =
+                                                    BOGUS_MATRIX_UNI_LOCATION;
+        }
+    }
+#endif
+
+    GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME));
+
+    GR_GL(LinkProgram(progID));
+
+    GLint linked = GR_GL_INIT_ZERO;
+    GR_GL(GetProgramiv(progID, GL_LINK_STATUS, &linked));
+    if (!linked) {
+        GLint infoLen = GR_GL_INIT_ZERO;
+        GR_GL(GetProgramiv(progID, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
+        if (infoLen > 0) {
+            GR_GL(GetProgramInfoLog(progID,
+                                    infoLen+1,
+                                    NULL,
+                                    (char*)log.get()));
+            GrPrintf((char*)log.get());
+        }
+        GrAssert(!"Error linking program");
+        GR_GL(DeleteProgram(progID));
+        program->fProgramID = 0;
+        return;
+    }
+
+    // Get uniform locations
+#if !ATTRIBUTE_MATRIX
+    program->fUniLocations.fViewMatrixUni =
+                    GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
+    GrAssert(-1 != program->fUniLocations.fViewMatrixUni);
+#endif
+    for (int s = 0; s < kNumStages; ++s) {
+        StageUniLocations& locations = program->fUniLocations.fStages[s];
+        if (desc.fStages[s].fEnabled) {
+#if !ATTRIBUTE_MATRIX
+            if (locations.fTextureMatrixUni) {
+                GrTokenString texMName;
+                tex_matrix_name(s, &texMName);
+                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
+                                                progID,
+                                                texMName.cstr()));
+                GrAssert(-1 != locations.fTextureMatrixUni);
+            } else {
+                locations.fTextureMatrixUni = -1;
+
+            }
+#endif
+
+            if (locations.fSamplerUni) {
+                GrTokenString samplerName;
+                sampler_name(s, &samplerName);
+                locations.fSamplerUni = GR_GL(GetUniformLocation(
+                                                     progID,
+                                                     samplerName.cstr()));
+                GrAssert(-1 != locations.fSamplerUni);
+            } else {
+                locations.fSamplerUni = -1;
+            }
+
+            if (locations.fRadial2Uni) {
+                GrTokenString radial2ParamName;
+                radial2_param_name(s, &radial2ParamName);
+                locations.fRadial2Uni = GR_GL(GetUniformLocation(
+                                             progID,
+                                             radial2ParamName.cstr()));
+                GrAssert(-1 != locations.fRadial2Uni);
+            } else {
+                locations.fRadial2Uni = -1;
+            }
+        } else {
+            locations.fSamplerUni = -1;
+            locations.fRadial2Uni = -1;
+            locations.fTextureMatrixUni = -1;
+        }
+    }
+    GR_GL(UseProgram(progID));
+
+    // init sampler unis and set bogus values for state tracking
+    for (int s = 0; s < kNumStages; ++s) {
+        if (-1 != program->fUniLocations.fStages[s].fSamplerUni) {
+            GR_GL(Uniform1i(program->fUniLocations.fStages[s].fSamplerUni, s));
+        }
+        program->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
+        program->fRadial2CenterX1[s] = GR_ScalarMax;
+        program->fRadial2Radius0[s] = -GR_ScalarMax;
+    }
+    program->fViewMatrix = GrMatrix::InvalidMatrix();
+}
+
+void GrGpuGLShaders2::getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc) {
+
+    // Must initialize all fields or cache will have false negatives!
+    desc->fVertexLayout = fGeometrySrc.fVertexLayout;
+
+    desc->fOptFlags = 0;
+    if (kPoints_PrimitiveType != primType) {
+        desc->fOptFlags |= ProgramDesc::kNotPoints_OptFlagBit;
+    }
+#if GR_AGGRESSIVE_SHADER_OPTS
+    if (!(desc->fVertexLayout & kColor_VertexLayoutBit) &&
+        (0xffffffff == fCurrDrawState.fColor)) {
+        desc->fOptFlags |= ProgramDesc::kVertexColorAllOnes_OptFlagBit;
+    }
+#endif
+
+    for (int s = 0; s < kNumStages; ++s) {
+        StageDesc& stage = desc->fStages[s];
+
+        stage.fEnabled = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
+
+        if (stage.fEnabled) {
+            GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+            GrAssert(NULL != texture);
+            // we matrix to invert when orientation is TopDown, so make sure
+            // we aren't in that case before flagging as identity.
+            if (TextureMatrixIsIdentity(texture, fCurrDrawState.fSamplerStates[s])) {
+                stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit;
+            } else if (!getSamplerMatrix(s).hasPerspective()) {
+                stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit;
+            } else {
+                stage.fOptFlags = 0;
+            }
+            switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
+            case GrSamplerState::kNormal_SampleMode:
+                stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
+                break;
+            case GrSamplerState::kRadial_SampleMode:
+                stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
+                break;
+            case GrSamplerState::kRadial2_SampleMode:
+                stage.fCoordMapping = StageDesc::kRadial2Gradient_CoordMapping;
+                break;
+            case GrSamplerState::kSweep_SampleMode:
+                stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
+                break;
+            default:
+                GrAssert(!"Unexpected sample mode!");
+                break;
+            }
+            if (GrTexture::kAlpha_8_PixelConfig == texture->config()) {
+                stage.fModulation = StageDesc::kAlpha_Modulation;
+            } else {
+                stage.fModulation = StageDesc::kColor_Modulation;
+            }
+        } else {
+            stage.fOptFlags     = 0;
+            stage.fCoordMapping = (StageDesc::CoordMapping)0;
+            stage.fModulation   = (StageDesc::Modulation)0;
+        }
+    }
+}
+
+GLuint GrGpuGLShaders2::CompileShader(GLenum type,
+                                      int stringCnt,
+                                      const char** strings,
+                                      int* stringLengths) {
+    GLuint shader = GR_GL(CreateShader(type));
+    if (0 == shader) {
+        return 0;
+    }
+
+    GLint compiled = GR_GL_INIT_ZERO;
+    GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths));
+    GR_GL(CompileShader(shader));
+    GR_GL(GetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
+
+    if (!compiled) {
+        GLint infoLen = GR_GL_INIT_ZERO;
+        GR_GL(GetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+        if (infoLen > 0) {
+            GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get()));
+            for (int i = 0; i < stringCnt; ++i) {
+                if (NULL == stringLengths || stringLengths[i] < 0) {
+                    GrPrintf(strings[i]);
+                } else {
+                    GrPrintf("%.*s", stringLengths[i], strings[i]);
+                }
+            }
+            GrPrintf("\n%s", log.get());
+        }
+        GrAssert(!"Shader compilation failed!");
+        GR_GL(DeleteShader(shader));
+        return 0;
+    }
+    return shader;
+}
+
+void GrGpuGLShaders2::DeleteProgram(Program* program) {
+    GR_GL(DeleteShader(program->fVShaderID));
+    GR_GL(DeleteShader(program->fFShaderID));
+    GR_GL(DeleteProgram(program->fProgramID));
+    GR_DEBUGCODE(memset(program, 0, sizeof(Program)));
+}
+
+
+GrGpuGLShaders2::GrGpuGLShaders2() {
+
+    fProgram = NULL;
+    fProgramCache = new ProgramCache();
+
+#if 0
+    ProgramUnitTest();
+#endif
+}
+
+GrGpuGLShaders2::~GrGpuGLShaders2() {
+    delete fProgramCache;
+}
+
+const GrMatrix& GrGpuGLShaders2::getHWSamplerMatrix(int stage) {
+#if ATTRIBUTE_MATRIX
+    return fHWDrawState.fSamplerStates[stage].getMatrix();
+#else
+    return fProgram->fTextureMatrices[stage];
+#endif
+}
+
+void GrGpuGLShaders2::recordHWSamplerMatrix(int stage, const GrMatrix& matrix){
+#if ATTRIBUTE_MATRIX
+    fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
+#else
+    fProgram->fTextureMatrices[stage] = matrix;
+#endif
+}
+
+void GrGpuGLShaders2::resetContext() {
+
+    INHERITED::resetContext();
+
+    fHWGeometryState.fVertexLayout = 0;
+    fHWGeometryState.fVertexOffset  = ~0;
+    GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
+    }
+    GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION));
+
+    fHWProgramID = 0;
+}
+
+void GrGpuGLShaders2::flushViewMatrix() {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrMatrix m (
+        GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
+        0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
+        0, 0, GrMatrix::I()[8]);
+    m.setConcat(m, fCurrDrawState.fViewMatrix);
+
+    // ES doesn't allow you to pass true to the transpose param,
+    // so do our own transpose
+    GrScalar mt[]  = {
+        m[GrMatrix::kScaleX],
+        m[GrMatrix::kSkewY],
+        m[GrMatrix::kPersp0],
+        m[GrMatrix::kSkewX],
+        m[GrMatrix::kScaleY],
+        m[GrMatrix::kPersp1],
+        m[GrMatrix::kTransX],
+        m[GrMatrix::kTransY],
+        m[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0));
+    GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3));
+    GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6));
+#else
+    GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fViewMatrixUni,1,false,mt));
+#endif
+}
+
+void GrGpuGLShaders2::flushTextureMatrix(int stage) {
+    GrAssert(NULL != fCurrDrawState.fTextures[stage]);
+
+    GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage];
+
+    GrMatrix m = getSamplerMatrix(stage);
+    GrSamplerState::SampleMode mode = 
+        fCurrDrawState.fSamplerStates[0].getSampleMode();
+    AdjustTextureMatrix(texture, mode, &m);
+
+    // ES doesn't allow you to pass true to the transpose param,
+    // so do our own transpose
+    GrScalar mt[]  = {
+        m[GrMatrix::kScaleX],
+        m[GrMatrix::kSkewY],
+        m[GrMatrix::kPersp0],
+        m[GrMatrix::kSkewX],
+        m[GrMatrix::kScaleY],
+        m[GrMatrix::kPersp1],
+        m[GrMatrix::kTransX],
+        m[GrMatrix::kTransY],
+        m[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
+    GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
+    GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
+#else
+    GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[stage].fTextureMatrixUni,
+                           1, false, mt));
+#endif
+}
+
+void GrGpuGLShaders2::flushRadial2(int stage) {
+
+    const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage];
+
+    GrScalar centerX1 = sampler.getRadial2CenterX1();
+    GrScalar radius0 = sampler.getRadial2Radius0();
+
+    GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
+
+    float unis[6] = {
+        GrScalarToFloat(a),
+        1 / (2.f * unis[0]),
+        GrScalarToFloat(centerX1),
+        GrScalarToFloat(radius0),
+        GrScalarToFloat(GrMul(radius0, radius0)),
+        sampler.isRadial2PosRoot() ? 1.f : -1.f
+    };
+    GR_GL(Uniform1fv(fProgram->fUniLocations.fStages[stage].fRadial2Uni,
+                     6,
+                     unis));
+}
+
+void GrGpuGLShaders2::flushProgram(GrPrimitiveType type) {
+    ProgramDesc desc;
+    getProgramDesc(type, &desc);
+    fProgram = fProgramCache->getProgram(desc);
+
+    if (fHWProgramID != fProgram->fProgramID) {
+        GR_GL(UseProgram(fProgram->fProgramID));
+        fHWProgramID = fProgram->fProgramID;
+#if GR_COLLECT_STATS
+        ++fStats.fProgChngCnt;
+#endif
+    }
+}
+
+bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) {
+
+    if (!flushGLStateCommon(type)) {
+        return false;
+    }
+
+    if (fDirtyFlags.fRenderTargetChanged) {
+        // our coords are in pixel space and the GL matrices map to NDC
+        // so if the viewport changed, our matrix is now wrong.
+#if ATTRIBUTE_MATRIX
+        fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+#else
+        // we assume all shader matrices may be wrong after viewport changes
+        fProgramCache->invalidateViewMatrices();
+#endif
+    }
+
+    flushProgram(type);
+
+    if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+        // invalidate the immediate mode color
+        fHWDrawState.fColor = GrColor_ILLEGAL;
+    } else {
+        if (fHWDrawState.fColor != fCurrDrawState.fColor &&
+            (!GR_AGGRESSIVE_SHADER_OPTS || 0xffffffff != fCurrDrawState.fColor)) {
+            // avoid pushing the color attrib if the shader will optimize it out
+
+            // OpenGL ES only supports the float varities of glVertexAttrib
+            float c[] = {
+                GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+            };
+            GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
+            fHWDrawState.fColor = fCurrDrawState.fColor;
+        }
+    }
+
+#if ATTRIBUTE_MATRIX
+    GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
+#else
+    GrMatrix& currViewMatrix = fProgram->fViewMatrix;
+#endif
+
+    if (currViewMatrix != fCurrDrawState.fViewMatrix) {
+        flushViewMatrix();
+        currViewMatrix = fCurrDrawState.fViewMatrix;
+    }
+
+    for (int s = 0; s < kNumStages; ++s) {
+        GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+        if (NULL != texture) {
+            if (-1 != fProgram->fUniLocations.fStages[s].fTextureMatrixUni &&
+                (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
+                getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
+                flushTextureMatrix(s);
+                recordHWSamplerMatrix(s, getSamplerMatrix(s));
+            }
+        }
+
+        const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+        if (-1 != fProgram->fUniLocations.fStages[s].fRadial2Uni &&
+            (fProgram->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
+             fProgram->fRadial2Radius0[s]  != sampler.getRadial2Radius0()  ||
+             fProgram->fRadial2PosRoot[s]  != sampler.isRadial2PosRoot())) {
+
+            flushRadial2(s);
+
+            fProgram->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
+            fProgram->fRadial2Radius0[s]  = sampler.getRadial2Radius0();
+            fProgram->fRadial2PosRoot[s]  = sampler.isRadial2PosRoot();
+        }
+    }
+    resetDirtyFlags();
+    return true;
+}
+
+void GrGpuGLShaders2::setupGeometry(int* startVertex,
+                                    int* startIndex,
+                                    int vertexCount,
+                                    int indexCount) {
+
+    int newColorOffset;
+    int newTexCoordOffsets[kMaxTexCoords];
+
+    GLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
+                                                  newTexCoordOffsets,
+                                                  &newColorOffset);
+    int oldColorOffset;
+    int oldTexCoordOffsets[kMaxTexCoords];
+    GLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
+                                                  oldTexCoordOffsets,
+                                                  &oldColorOffset);
+    bool indexed = NULL != startIndex;
+
+    int extraVertexOffset;
+    int extraIndexOffset;
+    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+
+    GLenum scalarType;
+    bool texCoordNorm;
+    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+        scalarType = GrGLTextType;
+        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
+    } else {
+        scalarType = GrGLType;
+        texCoordNorm = false;
+    }
+
+    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+    *startVertex = 0;
+    if (indexed) {
+        *startIndex += extraIndexOffset;
+    }
+
+    // all the Pointers must be set if any of these are true
+    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
+                             vertexOffset != fHWGeometryState.fVertexOffset ||
+                             newStride != oldStride;
+
+    // position and tex coord offsets change if above conditions are true
+    // or the type/normalization changed based on text vs nontext type coords.
+    bool posAndTexChange = allOffsetsChange ||
+                           (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
+                                (kTextFormat_VertexLayoutBit &
+                                  (fHWGeometryState.fVertexLayout ^
+                                   fGeometrySrc.fVertexLayout)));
+
+    if (posAndTexChange) {
+        GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
+                                  false, newStride, (GLvoid*)vertexOffset));
+        fHWGeometryState.fVertexOffset = vertexOffset;
+    }
+
+    for (int t = 0; t < kMaxTexCoords; ++t) {
+        if (newTexCoordOffsets[t] > 0) {
+            GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[t]);
+            if (oldTexCoordOffsets[t] <= 0) {
+                GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
+                GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
+                                          texCoordNorm, newStride, texCoordOffset));
+            } else if (posAndTexChange ||
+                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
+                GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
+                                          texCoordNorm, newStride, texCoordOffset));
+            }
+        } else if (oldTexCoordOffsets[t] > 0) {
+            GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
+        }
+    }
+
+    if (newColorOffset > 0) {
+        GLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
+        if (oldColorOffset <= 0) {
+            GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
+            GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
+                                      GL_UNSIGNED_BYTE,
+                                      true, newStride, colorOffset));
+        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
+            GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
+                                      GL_UNSIGNED_BYTE,
+                                      true, newStride, colorOffset));
+        }
+    } else if (oldColorOffset > 0) {
+        GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
+    }
+
+    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+    fHWGeometryState.fArrayPtrsDirty = false;
+}
+#endif
+
+
diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h
new file mode 100644
index 0000000..4c501be
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders2.h
@@ -0,0 +1,102 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGLShaders2_DEFINED
+#define GrGpuGLShaders2_DEFINED
+
+#include "GrGpuGL.h"
+
+// Programmable OpenGL or OpenGL ES 2.0
+class GrGpuGLShaders2 : public GrGpuGL {
+public:
+             GrGpuGLShaders2();
+    virtual ~GrGpuGLShaders2();
+
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(GrPrimitiveType type);
+    virtual void setupGeometry(int* startVertex,
+                               int* startIndex,
+                               int vertexCount,
+                               int indexCount);
+
+private:
+
+    virtual void resetContext();
+
+    // Helpers to make code more readable
+    const GrMatrix& getHWSamplerMatrix(int stage);
+    void recordHWSamplerMatrix(int stage, const GrMatrix& matrix);
+
+    // sets the texture matrix uniform for currently bound program
+    void flushTextureMatrix(int stage);
+
+    // sets the MVP matrix uniform for currently bound program
+    void flushViewMatrix();
+
+    // flushes the parameters to two point radial gradient
+    void flushRadial2(int stage);
+
+    // called at flush time to setup the appropriate program
+    void flushProgram(GrPrimitiveType type);
+
+    struct Program;
+
+    struct StageDesc;
+    struct ProgramDesc;
+
+    struct UniLocations;
+    struct StageUniLocations;
+
+    struct ShaderCodeSegments;
+
+    class ProgramCache;
+
+    // gets a description of needed shader
+    void getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc);
+
+    // generates and compiles a program from a description and vertex layout
+    // will change GL's bound program
+    static void GenProgram(const ProgramDesc& desc, Program* program);
+
+    // generates code for a stage of the shader
+    static void GenStageCode(int stageNum,
+                             const StageDesc& desc,
+                             const char* psInColor,
+                             const char* psOutColor,
+                             const char* vsInCoord,
+                             ShaderCodeSegments* segments,
+                             StageUniLocations* locations);
+
+    // Compiles a GL shader, returns shader ID or 0 if failed
+    // params have same meaning as glShaderSource
+    static GLuint CompileShader(GLenum type, int stringCnt,
+                                             const char** strings,
+                                             int* stringLengths);
+    static void DeleteProgram(Program* program);
+
+    void ProgramUnitTest();
+
+    ProgramCache*   fProgramCache;
+    Program*        fProgram;
+    GLuint          fHWProgramID;
+
+    typedef GrGpuGL INHERITED;
+};
+
+#endif
+
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
new file mode 100644
index 0000000..8225425
--- /dev/null
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -0,0 +1,521 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrInOrderDrawBuffer.h"
+#include "GrTexture.h"
+#include "GrBufferAllocPool.h"
+#include "GrIndexBuffer.h"
+#include "GrVertexBuffer.h"
+#include "GrGpu.h"
+
+GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
+                                         GrIndexBufferAllocPool* indexPool) :
+        fDraws(DRAWS_BLOCK_SIZE, fDrawsStorage),
+        fStates(STATES_BLOCK_SIZE, fStatesStorage),
+        fClips(CLIPS_BLOCK_SIZE, fClipsStorage),
+        fClipSet(true),
+
+        fLastRectVertexLayout(0),
+        fQuadIndexBuffer(NULL),
+        fMaxQuads(0),
+        fCurrQuad(0),
+
+        fVertexPool(*vertexPool),
+        fCurrPoolVertexBuffer(NULL),
+        fCurrPoolStartVertex(0),
+        fIndexPool(*indexPool),
+        fCurrPoolIndexBuffer(NULL),
+        fCurrPoolStartIndex(0),
+        fReservedVertexBytes(0),
+        fReservedIndexBytes(0),
+        fUsedReservedVertexBytes(0),
+        fUsedReservedIndexBytes(0) {
+    GrAssert(NULL != vertexPool);
+    GrAssert(NULL != indexPool);
+}
+
+GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
+    this->reset();
+    GrSafeUnref(fQuadIndexBuffer);
+}
+
+void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
+    this->copyDrawState(target);
+    this->setClip(target.getClip());
+}
+
+void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
+    bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
+    if (newIdxBuffer) {
+        GrSafeUnref(fQuadIndexBuffer);
+        fQuadIndexBuffer = indexBuffer;
+        GrSafeRef(fQuadIndexBuffer);
+        fCurrQuad = 0;
+        fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
+    } else {
+        GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
+                 (indexBuffer->maxQuads() == fMaxQuads));
+    }
+}
+
+void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
+                                   const GrMatrix* matrix,
+                                   StageBitfield stageEnableBitfield,
+                                   const GrRect* srcRects[],
+                                   const GrMatrix* srcMatrices[]) {
+
+    GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
+    GrAssert(!(fDraws.empty() && fCurrQuad));
+    GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
+
+    // if we have a quad IB then either append to the previous run of
+    // rects or start a new run
+    if (fMaxQuads) {
+
+        bool appendToPreviousDraw = false;
+        GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
+        AutoReleaseGeometry geo(this, layout, 4, 0);
+        AutoViewMatrixRestore avmr(this);
+        GrMatrix combinedMatrix = this->getViewMatrix();
+        this->setViewMatrix(GrMatrix::I());
+        if (NULL != matrix) {
+            combinedMatrix.preConcat(*matrix);
+        }
+
+        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
+
+        // we don't want to miss an opportunity to batch rects together
+        // simply because the clip has changed if the clip doesn't affect
+        // the rect.
+        bool disabledClip = false;
+        if (this->isClipState() && fClip.isRect()) {
+
+            GrRect clipRect = fClip.getRect(0);
+            // If the clip rect touches the edge of the viewport, extended it
+            // out (close) to infinity to avoid bogus intersections.
+            // We might consider a more exact clip to viewport if this
+            // conservative test fails.
+            const GrRenderTarget* target = this->getRenderTarget();
+            if (0 >= clipRect.fLeft) {
+                clipRect.fLeft = GR_ScalarMin;
+            }
+            if (target->width() <= clipRect.fRight) {
+                clipRect.fRight = GR_ScalarMax;
+            }
+            if (0 >= clipRect.top()) {
+                clipRect.fTop = GR_ScalarMin;
+            }
+            if (target->height() <= clipRect.fBottom) {
+                clipRect.fBottom = GR_ScalarMax;
+            }
+            int stride = VertexSize(layout);
+            bool insideClip = true;
+            for (int v = 0; v < 4; ++v) {
+                const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
+                if (!clipRect.contains(p)) {
+                    insideClip = false;
+                    break;
+                }
+            }
+            if (insideClip) {
+                this->disableState(kClip_StateBit);
+                disabledClip = true;
+            }
+        }
+        if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
+            fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
+
+            int vsize = VertexSize(layout);
+
+            Draw& lastDraw = fDraws.back();
+
+            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
+            GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
+            GrAssert(0 == lastDraw.fVertexCount % 4);
+            GrAssert(0 == lastDraw.fIndexCount % 6);
+            GrAssert(0 == lastDraw.fStartIndex);
+
+            appendToPreviousDraw = lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
+                                   (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
+            if (appendToPreviousDraw) {
+                lastDraw.fVertexCount += 4;
+                lastDraw.fIndexCount += 6;
+                fCurrQuad += 1;
+                GrAssert(0 == fUsedReservedVertexBytes);
+                fUsedReservedVertexBytes = 4 * vsize;
+            }
+        }
+        if (!appendToPreviousDraw) {
+            this->setIndexSourceToBuffer(fQuadIndexBuffer);
+            drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
+            fCurrQuad = 1;
+            fLastRectVertexLayout = layout;
+        }
+        if (disabledClip) {
+            this->enableState(kClip_StateBit);
+        }
+    } else {
+        INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
+    }
+}
+
+void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
+                                      int startVertex,
+                                      int startIndex,
+                                      int vertexCount,
+                                      int indexCount) {
+
+    if (!vertexCount || !indexCount) {
+        return;
+    }
+
+    fCurrQuad = 0;
+
+    Draw& draw = fDraws.push_back();
+    draw.fPrimitiveType = primitiveType;
+    draw.fStartVertex   = startVertex;
+    draw.fStartIndex    = startIndex;
+    draw.fVertexCount   = vertexCount;
+    draw.fIndexCount    = indexCount;
+
+    draw.fClipChanged = this->needsNewClip();
+    if (draw.fClipChanged) {
+       this->pushClip();
+    }
+
+    draw.fStateChanged = this->needsNewState();
+    if (draw.fStateChanged) {
+        this->pushState();
+    }
+
+    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
+    switch (fGeometrySrc.fVertexSrc) {
+    case kBuffer_GeometrySrcType:
+        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        break;
+    case kReserved_GeometrySrcType: {
+        size_t vertexBytes = (vertexCount + startVertex) *
+        VertexSize(fGeometrySrc.fVertexLayout);
+        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
+    } // fallthrough
+    case kArray_GeometrySrcType:
+        draw.fVertexBuffer = fCurrPoolVertexBuffer;
+        draw.fStartVertex += fCurrPoolStartVertex;
+        break;
+    default:
+        GrCrash("unknown geom src type");
+    }
+    draw.fVertexBuffer->ref();
+
+    switch (fGeometrySrc.fIndexSrc) {
+    case kBuffer_GeometrySrcType:
+        draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        break;
+    case kReserved_GeometrySrcType: {
+        size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
+        fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
+    } // fallthrough
+    case kArray_GeometrySrcType:
+        draw.fIndexBuffer = fCurrPoolIndexBuffer;
+        draw.fStartIndex += fCurrPoolStartVertex;
+        break;
+    default:
+        GrCrash("unknown geom src type");
+    }
+    draw.fIndexBuffer->ref();
+}
+
+void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
+                                         int startVertex,
+                                         int vertexCount) {
+    if (!vertexCount) {
+        return;
+    }
+
+    fCurrQuad = 0;
+
+    Draw& draw = fDraws.push_back();
+    draw.fPrimitiveType = primitiveType;
+    draw.fStartVertex   = startVertex;
+    draw.fStartIndex    = 0;
+    draw.fVertexCount   = vertexCount;
+    draw.fIndexCount    = 0;
+
+    draw.fClipChanged = this->needsNewClip();
+    if (draw.fClipChanged) {
+        this->pushClip();
+    }
+
+    draw.fStateChanged = this->needsNewState();
+    if (draw.fStateChanged) {
+        this->pushState();
+    }
+
+    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
+    switch (fGeometrySrc.fVertexSrc) {
+    case kBuffer_GeometrySrcType:
+        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        break;
+    case kReserved_GeometrySrcType: {
+        size_t vertexBytes = (vertexCount + startVertex) *
+        VertexSize(fGeometrySrc.fVertexLayout);
+        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
+                                         vertexBytes);
+    } // fallthrough
+    case kArray_GeometrySrcType:
+        draw.fVertexBuffer = fCurrPoolVertexBuffer;
+        draw.fStartVertex += fCurrPoolStartVertex;
+        break;
+    default:
+        GrCrash("unknown geom src type");
+    }
+    draw.fVertexBuffer->ref();
+    draw.fIndexBuffer = NULL;
+}
+
+void GrInOrderDrawBuffer::reset() {
+    GrAssert(!fReservedGeometry.fLocked);
+    uint32_t numStates = fStates.count();
+    for (uint32_t i = 0; i < numStates; ++i) {
+        const DrState& dstate = this->accessSavedDrawState(fStates[i]);
+        for (int s = 0; s < kNumStages; ++s) {
+            GrSafeUnref(dstate.fTextures[s]);
+        }
+        GrSafeUnref(dstate.fRenderTarget);
+    }
+    int numDraws = fDraws.count();
+    for (int d = 0; d < numDraws; ++d) {
+        // we always have a VB, but not always an IB
+        GrAssert(NULL != fDraws[d].fVertexBuffer);
+        fDraws[d].fVertexBuffer->unref();
+        GrSafeUnref(fDraws[d].fIndexBuffer);
+    }
+    fDraws.reset();
+    fStates.reset();
+
+    fVertexPool.reset();
+    fIndexPool.reset();
+
+    fClips.reset();
+
+    fCurrQuad = 0;
+}
+
+void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
+    GrAssert(NULL != target);
+    GrAssert(target != this); // not considered and why?
+
+    uint32_t numDraws = fDraws.count();
+    if (!numDraws) {
+        return;
+    }
+
+    fVertexPool.unlock();
+    fIndexPool.unlock();
+
+    GrDrawTarget::AutoStateRestore asr(target);
+    GrDrawTarget::AutoClipRestore acr(target);
+    // important to not mess with reserve/lock geometry in the target with this
+    // on the stack.
+    GrDrawTarget::AutoGeometrySrcRestore agsr(target);
+
+    uint32_t currState = ~0;
+    uint32_t currClip  = ~0;
+
+    for (uint32_t i = 0; i < numDraws; ++i) {
+        const Draw& draw = fDraws[i];
+        if (draw.fStateChanged) {
+            ++currState;
+            target->restoreDrawState(fStates[currState]);
+        }
+        if (draw.fClipChanged) {
+            ++currClip;
+            target->setClip(fClips[currClip]);
+        }
+        uint32_t vertexReserveCount = 0;
+        uint32_t indexReserveCount = 0;
+
+        target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
+
+        if (draw.fIndexCount) {
+            target->setIndexSourceToBuffer(draw.fIndexBuffer);
+        }
+
+        if (draw.fIndexCount) {
+            target->drawIndexed(draw.fPrimitiveType,
+                                draw.fStartVertex,
+                                draw.fStartIndex,
+                                draw.fVertexCount,
+                                draw.fIndexCount);
+        } else {
+            target->drawNonIndexed(draw.fPrimitiveType,
+                                   draw.fStartVertex,
+                                   draw.fVertexCount);
+        }
+        if (vertexReserveCount || indexReserveCount) {
+            target->releaseReservedGeometry();
+        }
+    }
+}
+
+bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
+                                        int* vertexCount,
+                                        int* indexCount) const {
+    // we will recommend a flush if the data could fit in a single
+    // preallocated buffer but none are left and it can't fit
+    // in the current buffer (which may not be prealloced).
+    bool flush = false;
+    if (NULL != indexCount) {
+        int32_t currIndices = fIndexPool.currentBufferIndices();
+        if (*indexCount > currIndices &&
+            (!fIndexPool.preallocatedBuffersRemaining() &&
+             *indexCount <= fIndexPool.preallocatedBufferIndices())) {
+
+            flush = true;
+        }
+        *indexCount = currIndices;
+    }
+    if (NULL != vertexCount) {
+        int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
+        if (*vertexCount > currVertices &&
+            (!fVertexPool.preallocatedBuffersRemaining() &&
+             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
+
+            flush = true;
+        }
+        *vertexCount = currVertices;
+    }
+    return flush;
+}
+
+bool GrInOrderDrawBuffer::acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                                void**         vertices,
+                                                void**         indices) {
+    GrAssert(!fReservedGeometry.fLocked);
+    if (fReservedGeometry.fVertexCount) {
+        GrAssert(NULL != vertices);
+        GrAssert(0 == fReservedVertexBytes);
+        GrAssert(0 == fUsedReservedVertexBytes);
+
+        fReservedVertexBytes = VertexSize(vertexLayout) *
+                               fReservedGeometry.fVertexCount;
+        *vertices = fVertexPool.makeSpace(vertexLayout,
+                                          fReservedGeometry.fVertexCount,
+                                          &fCurrPoolVertexBuffer,
+                                          &fCurrPoolStartVertex);
+        if (NULL == *vertices) {
+            return false;
+        }
+    }
+    if (fReservedGeometry.fIndexCount) {
+        GrAssert(NULL != indices);
+        GrAssert(0 == fReservedIndexBytes);
+        GrAssert(0 == fUsedReservedIndexBytes);
+
+        *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
+                                        &fCurrPoolIndexBuffer,
+                                        &fCurrPoolStartIndex);
+        if (NULL == *indices) {
+            fVertexPool.putBack(fReservedVertexBytes);
+            fReservedVertexBytes = 0;
+            fCurrPoolVertexBuffer = NULL;
+            return false;
+        }
+    }
+    return true;
+}
+
+void GrInOrderDrawBuffer::releaseGeometryHelper() {
+    GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
+    GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
+
+    size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
+    fVertexPool.putBack(vertexSlack);
+
+    size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
+    fIndexPool.putBack(indexSlack);
+
+    fReservedVertexBytes = 0;
+    fReservedIndexBytes  = 0;
+    fUsedReservedVertexBytes = 0;
+    fUsedReservedIndexBytes  = 0;
+    fCurrPoolVertexBuffer = 0;
+    fCurrPoolStartVertex = 0;
+
+}
+
+void GrInOrderDrawBuffer::setVertexSourceToArrayHelper(const void* vertexArray,
+                                                       int vertexCount) {
+    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+#if GR_DEBUG
+    bool success =
+#endif
+    fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
+                               vertexCount,
+                               vertexArray,
+                               &fCurrPoolVertexBuffer,
+                               &fCurrPoolStartVertex);
+    GR_DEBUGASSERT(success);
+}
+
+void GrInOrderDrawBuffer::setIndexSourceToArrayHelper(const void* indexArray,
+                                                      int indexCount) {
+    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+#if GR_DEBUG
+    bool success =
+#endif
+    fIndexPool.appendIndices(indexCount,
+                             indexArray,
+                             &fCurrPoolIndexBuffer,
+                             &fCurrPoolStartIndex);
+    GR_DEBUGASSERT(success);
+}
+
+bool GrInOrderDrawBuffer::needsNewState() const {
+     if (fStates.empty()) {
+        return true;
+     } else {
+         const DrState& old = this->accessSavedDrawState(fStates.back());
+        return old != fCurrDrawState;
+     }
+}
+
+void GrInOrderDrawBuffer::pushState() {
+    for (int s = 0; s < kNumStages; ++s) {
+        GrSafeRef(fCurrDrawState.fTextures[s]);
+    }
+    GrSafeRef(fCurrDrawState.fRenderTarget);
+    this->saveCurrentDrawState(&fStates.push_back());
+ }
+
+bool GrInOrderDrawBuffer::needsNewClip() const {
+   if (fCurrDrawState.fFlagBits & kClip_StateBit) {
+       if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
+           return true;
+       }
+    }
+    return false;
+}
+
+void GrInOrderDrawBuffer::pushClip() {
+    fClips.push_back() = fClip;
+    fClipSet = false;
+}
+
+void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip)  {
+    fClipSet = true;
+}
diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp
new file mode 100644
index 0000000..0a2d1b2
--- /dev/null
+++ b/gpu/src/GrMatrix.cpp
@@ -0,0 +1,729 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrMatrix.h"
+#include "GrRect.h"
+#include <stddef.h>
+
+#if GR_SCALAR_IS_FLOAT
+    const GrScalar GrMatrix::gRESCALE(GR_Scalar1);
+#else
+    GR_STATIC_ASSERT(GR_SCALAR_IS_FIXED);
+    // fixed point isn't supported right now
+    GR_STATIC_ASSERT(false);
+const GrScalar GrMatrix::gRESCALE(1 << 30);
+#endif
+
+const GrMatrix::MapProc GrMatrix::gMapProcs[] = {
+// Scales are not both zero
+    &GrMatrix::mapIdentity,
+    &GrMatrix::mapScale,
+    &GrMatrix::mapTranslate,
+    &GrMatrix::mapScaleAndTranslate,
+    &GrMatrix::mapSkew,
+    &GrMatrix::mapScaleAndSkew,
+    &GrMatrix::mapSkewAndTranslate,
+    &GrMatrix::mapNonPerspective,
+    // no optimizations for perspective matrices
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+
+// Scales are zero (every other is invalid because kScale_TypeBit must be set if
+// kZeroScale_TypeBit is set)
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSetToTranslate,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScale,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScaleAndTranslate,
+
+    // no optimizations for perspective matrices
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+};
+
+void GrMatrix::setIdentity() {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = 0;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = 0;
+}
+
+void GrMatrix::setTranslate(GrScalar dx, GrScalar dy) {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = dx;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = dy;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = (0 != dx || 0 != dy) ? kTranslate_TypeBit : 0;
+}
+
+void GrMatrix::setScale(GrScalar sx, GrScalar sy) {
+    fM[0] = sx; fM[1] = 0;  fM[2] = 0;
+    fM[3] = 0;  fM[4] = sy; fM[5] = 0;
+    fM[6] = 0;  fM[7] = 0;  fM[8] = gRESCALE;
+    fTypeMask = (GR_Scalar1 != sx || GR_Scalar1 != sy) ? kScale_TypeBit : 0;
+}
+
+void GrMatrix::setSkew(GrScalar skx, GrScalar sky) {
+    fM[0] = GR_Scalar1; fM[1] = skx;        fM[2] = 0;
+    fM[3] = sky;        fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = (0 != skx || 0 != sky) ? kSkew_TypeBit : 0;
+}
+
+void GrMatrix::setConcat(const GrMatrix& a, const GrMatrix& b) {
+    if (a.isIdentity()) {
+        if (this != &b) {
+            for (int i = 0; i < 9; ++i) {
+                fM[i] = b.fM[i];
+            }
+            fTypeMask = b.fTypeMask;
+        }
+        return;
+    }
+
+    if (b.isIdentity()) {
+        GrAssert(!a.isIdentity());
+        if (this != &a) {
+            for (int i = 0; i < 9; ++i) {
+                    fM[i] = a.fM[i];
+            }
+            fTypeMask = a.fTypeMask;
+        }
+        return;
+    }
+
+    // a and/or b could be this
+    GrMatrix tmp;
+
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+    // TODO: make this work for fixed point
+    if (!((b.fTypeMask | a.fTypeMask) & kPerspective_TypeBit)) {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * gRESCALE;
+
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * gRESCALE;
+
+        tmp.fM[6] = 0;
+        tmp.fM[7] = 0;
+        tmp.fM[8] = gRESCALE * gRESCALE;
+    } else {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3] + a.fM[2] * b.fM[6];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4] + a.fM[2] * b.fM[7];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * b.fM[8];
+
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3] + a.fM[5] * b.fM[6];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4] + a.fM[5] * b.fM[7];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * b.fM[8];
+
+        tmp.fM[6] = a.fM[6] * b.fM[0] + a.fM[7] * b.fM[3] + a.fM[8] * b.fM[6];
+        tmp.fM[7] = a.fM[6] * b.fM[1] + a.fM[7] * b.fM[4] + a.fM[8] * b.fM[7];
+        tmp.fM[8] = a.fM[6] * b.fM[2] + a.fM[7] * b.fM[5] + a.fM[8] * b.fM[8];
+    }
+    *this = tmp;
+    this->computeTypeMask();
+}
+
+void GrMatrix::preConcat(const GrMatrix& m) {
+    setConcat(*this, m);
+}
+
+void GrMatrix::postConcat(const GrMatrix& m) {
+    setConcat(m, *this);
+}
+
+double GrMatrix::determinant() const {
+    if (fTypeMask & kPerspective_TypeBit) {
+        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) +
+                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) +
+                fM[2]*((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+    } else {
+        return (double)fM[0]*fM[4]*gRESCALE -
+               (double)fM[1]*fM[3]*gRESCALE;
+    }
+}
+
+bool GrMatrix::invert(GrMatrix* inverted) const {
+
+    if (isIdentity()) {
+        if (inverted != this) {
+            inverted->setIdentity();
+        }
+        return true;
+    }
+    static const double MIN_DETERMINANT_SQUARED = 1.e-16;
+
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+
+    double det = determinant();
+
+    // check if we can't be inverted
+    if (det*det <= MIN_DETERMINANT_SQUARED) {
+        return false;
+    } else if (NULL == inverted) {
+        return true;
+    }
+
+    double t[9];
+
+    if (fTypeMask & kPerspective_TypeBit) {
+        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]);
+        t[1] = ((double)fM[2]*fM[7] - (double)fM[1]*fM[8]);
+        t[2] = ((double)fM[1]*fM[5] - (double)fM[2]*fM[4]);
+        t[3] = ((double)fM[5]*fM[6] - (double)fM[3]*fM[8]);
+        t[4] = ((double)fM[0]*fM[8] - (double)fM[2]*fM[6]);
+        t[5] = ((double)fM[2]*fM[3] - (double)fM[0]*fM[5]);
+        t[6] = ((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+        t[7] = ((double)fM[1]*fM[6] - (double)fM[0]*fM[7]);
+        t[8] = ((double)fM[0]*fM[4] - (double)fM[1]*fM[3]);
+        det = 1.0 / det;
+        for (int i = 0; i < 9; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+    } else {
+        t[0] =  (double)fM[4]*gRESCALE;
+        t[1] = -(double)fM[1]*gRESCALE;
+        t[2] =  (double)fM[1]*fM[5] - (double)fM[2]*fM[4];
+        t[3] = -(double)fM[3]*gRESCALE;
+        t[4] =  (double)fM[0]*gRESCALE;
+        t[5] =  (double)fM[2]*fM[3] - (double)fM[0]*fM[5];
+        //t[6] = 0.0;
+        //t[7] = 0.0;
+        t[8] = (double)fM[0]*fM[4] - (double)fM[1]*fM[3];
+        det = 1.0 / det;
+        for (int i = 0; i < 6; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+        inverted->fM[6] = 0;
+        inverted->fM[7] = 0;
+        inverted->fM[8] = (GrScalar)(t[8] * det);
+    }
+    inverted->computeTypeMask();
+    return true;
+}
+
+void GrMatrix::mapRect(GrRect* dst, const GrRect& src) const {
+    GrPoint srcPts[4], dstPts[4];
+    srcPts[0].set(src.fLeft, src.fTop);
+    srcPts[1].set(src.fRight, src.fTop);
+    srcPts[2].set(src.fRight, src.fBottom);
+    srcPts[3].set(src.fLeft, src.fBottom);
+    this->mapPoints(dstPts, srcPts, 4);
+    dst->setBounds(dstPts, 4);
+}
+
+bool GrMatrix::hasPerspective() const {
+    GrAssert(!!(kPerspective_TypeBit & fTypeMask) ==
+             (fM[kPersp0] != 0 || fM[kPersp1] != 0 || fM[kPersp2] != gRESCALE));
+    return 0 != (kPerspective_TypeBit & fTypeMask);
+}
+
+bool GrMatrix::isIdentity() const {
+    GrAssert((0 == fTypeMask) ==
+             (GR_Scalar1 == fM[kScaleX] && 0          == fM[kSkewX]  && 0          == fM[kTransX] &&
+              0          == fM[kSkewY]  && GR_Scalar1 == fM[kScaleY] && 0          == fM[kTransY] &&
+              0          == fM[kPersp0] && 0          == fM[kPersp1] && gRESCALE == fM[kPersp2]));
+    return (0 == fTypeMask);
+}
+
+
+GrScalar GrMatrix::getMaxStretch() const {
+
+    if (fTypeMask & kPerspective_TypeBit) {
+        return -GR_Scalar1;
+    }
+
+    GrScalar stretch;
+
+    if (isIdentity()) {
+        stretch = GR_Scalar1;
+    } else if (!(fTypeMask & kSkew_TypeBit)) {
+        stretch = GrMax(GrScalarAbs(fM[kScaleX]), GrScalarAbs(fM[kScaleY]));
+    } else if (fTypeMask & kZeroScale_TypeBit) {
+        stretch = GrMax(GrScalarAbs(fM[kSkewX]), GrScalarAbs(fM[kSkewY]));
+    } else {
+        // ignore the translation part of the matrix, just look at 2x2 portion.
+        // compute singular values, take largest abs value.
+        // [a b; b c] = A^T*A
+        GrScalar a = GrMul(fM[kScaleX], fM[kScaleX]) + GrMul(fM[kSkewY],  fM[kSkewY]);
+        GrScalar b = GrMul(fM[kScaleX], fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kSkewY]);
+        GrScalar c = GrMul(fM[kSkewX],  fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kScaleY]);
+        // eigenvalues of A^T*A are the squared singular values of A.
+        // characteristic equation is det((A^T*A) - l*I) = 0
+        // l^2 - (a + c)l + (ac-b^2)
+        // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
+        // and roots are guaraunteed to be pos and real).
+        GrScalar largerRoot;
+        GrScalar bSqd = GrMul(b,b);
+        // TODO: fixed point tolerance value.
+        if (bSqd < 1e-10) { // will be true if upper left 2x2 is orthogonal, which is common, so save some math
+            largerRoot = GrMax(a, c);
+        } else {
+            GrScalar aminusc = a - c;
+            GrScalar apluscdiv2 = (a + c) / 2;
+            GrScalar x = sqrtf(GrMul(aminusc,aminusc) + GrMul(4,(bSqd))) / 2;
+            largerRoot = apluscdiv2 + x;
+        }
+
+        stretch = sqrtf(largerRoot);
+    }
+#if GR_DEBUG && 0
+    // test a bunch of vectors. None should be scaled by more than stretch
+    // (modulo some error) and we should find a vector that is scaled by almost
+    // stretch.
+    GrPoint pt;
+    GrScalar max = 0;
+    for (int i = 0; i < 1000; ++i) {
+        GrScalar x = (float)rand() / RAND_MAX;
+        GrScalar y = sqrtf(1 - (x*x));
+        pt.fX = fM[kScaleX]*x + fM[kSkewX]*y;
+        pt.fY = fM[kSkewY]*x + fM[kScaleY]*y;
+        GrScalar d = pt.distanceToOrigin();
+        GrAssert(d <= (1.0001 * stretch));
+        max = GrMax(max, pt.distanceToOrigin());
+    }
+    GrAssert((stretch - max) < .05*stretch);
+#endif
+    return stretch;
+}
+
+bool GrMatrix::operator == (const GrMatrix& m) const {
+    if (fTypeMask != m.fTypeMask) {
+        return false;
+    }
+    if (!fTypeMask) {
+        return true;
+    }
+    for (int i = 0; i < 9; ++i) {
+        if (m.fM[i] != fM[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool GrMatrix::operator != (const GrMatrix& m) const {
+    return !(*this == m);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Matrix transformation procs
+//////
+
+void GrMatrix::mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i] = src[i];
+        }
+    }
+}
+
+void GrMatrix::mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]);
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]);
+    }
+}
+
+
+void GrMatrix::mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = src[i].fX + fM[kTransX];
+        dst[i].fY = src[i].fY + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + fM[kTransX];
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        GrScalar x, y, w;
+        x = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+        y = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+        w = GrMul(fM[kPersp0], src[i].fX) + GrMul(fM[kPersp1], src[i].fY) + fM[kPersp2];
+        // TODO need fixed point invert
+        if (w) {
+            w = 1 / w;
+        }
+        dst[i].fX = GrMul(x, w);
+        dst[i].fY = GrMul(y, w);
+    }
+}
+
+void GrMatrix::mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    GrAssert(0);
+}
+
+void GrMatrix::mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    memset(dst, 0, sizeof(GrPoint)*count);
+}
+
+void GrMatrix::mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = fM[kTransX];
+        dst[i].fY = fM[kTransY];
+    }
+}
+
+void GrMatrix::mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Unit test
+//////
+
+#include "GrRandom.h"
+
+#if GR_DEBUG
+enum MatrixType {
+    kRotate_MatrixType,
+    kScaleX_MatrixType,
+    kScaleY_MatrixType,
+    kSkewX_MatrixType,
+    kSkewY_MatrixType,
+    kTranslateX_MatrixType,
+    kTranslateY_MatrixType,
+    kSwapScaleXY_MatrixType,
+    kPersp_MatrixType,
+
+    kMatrixTypeCount
+};
+
+static void create_matrix(GrMatrix* matrix, GrRandom& rand) {
+    MatrixType type = (MatrixType)(rand.nextU() % kMatrixTypeCount);
+    switch (type) {
+        case kRotate_MatrixType: {
+            float angle = rand.nextF() * 2 *3.14159265358979323846f;
+            GrScalar cosa = GrFloatToScalar(cosf(angle));
+            GrScalar sina = GrFloatToScalar(sinf(angle));
+            matrix->setAll(cosa,      -sina,           0,
+                           sina,       cosa,           0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleX_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(scale,      0,              0,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleY_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          scale,          0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSkewX_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, skew,           0,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSkewY_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           skew,       GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kTranslateX_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              trans,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kTranslateY_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          GR_Scalar1,     trans,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSwapScaleXY_MatrixType: {
+            GrScalar xy = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar yx = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(0,          xy,             0,
+                           yx,         0,              0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kPersp_MatrixType: {
+            GrScalar p0 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p1 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p2 = GrFloatToScalar(rand.nextF(-0.5f, 0.75f));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          GR_Scalar1,     0,
+                           p0,         p1,             GrMul(p2,GrMatrix::I()[8]));
+        } break;
+        default:
+            GrAssert(0);
+            break;
+    }
+}
+#endif
+
+void GrMatrix::UnitTest() {
+    GrRandom rand;
+
+    // Create a bunch of matrices and test point mapping, max stretch calc,
+    // inversion and multiply-by-inverse.
+#if GR_DEBUG
+    for (int i = 0; i < 10000; ++i) {
+        GrMatrix a, b;
+        a.setIdentity();
+        int num = rand.nextU() % 6;
+        // force testing of I and swapXY
+        if (0 == i) {
+            num = 0;
+            GrAssert(a.isIdentity());
+        } else if (1 == i) {
+            num = 0;
+            a.setAll(0, GR_Scalar1, 0,
+                     GR_Scalar1, 0, 0,
+                     0, 0, I()[8]);
+        }
+        for (int j = 0; j < num; ++j) {
+            create_matrix(&b, rand);
+            a.preConcat(b);
+        }
+
+        GrScalar maxStretch = a.getMaxStretch();
+        if (maxStretch > 0) {
+            maxStretch = GrMul(GR_Scalar1 + GR_Scalar1 / 100, maxStretch);
+        }
+        GrPoint origin = a.mapPoint(GrPoint(0,0));
+
+        for (int j = 0; j < 9; ++j) {
+            int mask, origMask = a.fTypeMask;
+            GrScalar old = a[j];
+
+            a.set(j, GR_Scalar1);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 0);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 10 * GR_Scalar1);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, old);
+            GrAssert(a.fTypeMask == origMask);
+        }
+
+        for (int j = 0; j < 100; ++j) {
+            GrPoint pt;
+            pt.fX = GrFloatToScalar(rand.nextF(-10, 10));
+            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));
+
+            GrPoint t0, t1, t2;
+            t0 = a.mapPoint(pt);             // map to a new point
+            t1 = pt;
+            a.mapPoints(&t1, &t1, 1);        // in place
+            a.mapPerspective(&t2, &pt, 1);   // full mult
+            GrAssert(t0 == t1 && t1 == t2);
+            if (maxStretch >= 0.f) {
+                GrVec vec;
+                vec.setBetween(t0, origin);
+                GrScalar stretch = vec.length() / pt.distanceToOrigin();
+                GrAssert(stretch <= maxStretch);
+            }
+        }
+        double det = a.determinant();
+        if (fabs(det) > 1e-3 && a.invert(&b)) {
+            GrMatrix c;
+            c.setConcat(a,b);
+            for (int i = 0; i < 9; ++i) {
+                GrScalar diff = GrScalarAbs(c[i] - I()[i]);
+                GrAssert(diff < (5*GR_Scalar1 / 100));
+            }
+        }
+    }
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+int Gr_clz(uint32_t n) {
+    if (0 == n) {
+        return 32;
+    }
+
+    int count = 0;
+    if (0 == (n & 0xFFFF0000)) {
+        count += 16;
+        n <<= 16;
+    }
+    if (0 == (n & 0xFF000000)) {
+        count += 8;
+        n <<= 8;
+    }
+    if (0 == (n & 0xF0000000)) {
+        count += 4;
+        n <<= 4;
+    }
+    if (0 == (n & 0xC0000000)) {
+        count += 2;
+        n <<= 2;
+    }
+    if (0 == (n & 0x80000000)) {
+        count += 1;
+    }
+    return count;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#include "GrRect.h"
+
+void GrRect::setBounds(const GrPoint pts[], int count) {
+    if (count <= 0) {
+        this->setEmpty();
+    } else {
+        GrScalar L, R, T, B;
+        L = R = pts[0].fX;
+        T = B = pts[0].fY;
+        for (int i = 1; i < count; i++) {
+            GrScalar x = pts[i].fX;
+            GrScalar y = pts[i].fY;
+            if (x < L) {
+                L = x;
+            } else if (x > R) {
+                R = x;
+            }
+            if (y < T) {
+                T = y;
+            } else if (y > B) {
+                B = y;
+            }
+        }
+        this->setLTRB(L, T, R, B);
+    }
+}
+
+
+
diff --git a/gpu/src/GrMemory.cpp b/gpu/src/GrMemory.cpp
new file mode 100644
index 0000000..3da924a
--- /dev/null
+++ b/gpu/src/GrMemory.cpp
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrMemory.h"
+
+#include <stdlib.h>
+
+void* GrMalloc(size_t bytes) {
+    void* ptr = ::malloc(bytes);
+    if (NULL == ptr) {
+        ::exit(-1);
+    }
+    return ptr;
+}
+
+void GrFree(void* ptr) {
+    if (ptr) {
+        ::free(ptr);
+    }
+}
+
+
diff --git a/gpu/src/GrPath.cpp b/gpu/src/GrPath.cpp
new file mode 100644
index 0000000..a740dfc
--- /dev/null
+++ b/gpu/src/GrPath.cpp
@@ -0,0 +1,488 @@
+#include "GrPath.h"
+
+GrPath::GrPath() {
+    fConvexHint = kNone_ConvexHint;
+}
+
+GrPath::GrPath(const GrPath& src) : INHERITED() {
+    GrPath::Iter iter(src);
+    this->resetFromIter(&iter);
+}
+
+GrPath::GrPath(GrPathIter& iter) {
+    this->resetFromIter(&iter);
+}
+
+GrPath::~GrPath() {
+}
+
+bool GrPath::operator ==(const GrPath& path) const {
+    if (fCmds.count() != path.fCmds.count() ||
+        fPts.count() != path.fPts.count()) {
+        return false;
+    }
+
+    for (int v = 0; v < fCmds.count(); ++v) {
+        if (fCmds[v] != path.fCmds[v]) {
+            return false;
+        }
+    }
+
+    for (int p = 0; p < fPts.count(); ++p) {
+        if (fPts[p] != path.fPts[p]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void GrPath::ensureMoveTo() {
+    if (fCmds.isEmpty() || this->wasLastVerb(kClose_PathCmd)) {
+        *fCmds.append() = kMove_PathCmd;
+        fPts.append()->set(0, 0);
+    }
+}
+
+void GrPath::moveTo(GrScalar x, GrScalar y) {
+    if (this->wasLastVerb(kMove_PathCmd)) {
+        // overwrite prev kMove value
+        fPts[fPts.count() - 1].set(x, y);
+    } else {
+        *fCmds.append() = kMove_PathCmd;
+        fPts.append()->set(x, y);
+    }
+}
+
+void GrPath::lineTo(GrScalar x, GrScalar y) {
+    this->ensureMoveTo();
+    *fCmds.append() = kLine_PathCmd;
+    fPts.append()->set(x, y);
+}
+
+void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
+    this->ensureMoveTo();
+    *fCmds.append() = kQuadratic_PathCmd;
+    fPts.append()->set(x0, y0);
+    fPts.append()->set(x1, y1);
+}
+
+void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                     GrScalar x2, GrScalar y2) {
+    this->ensureMoveTo();
+    *fCmds.append() = kCubic_PathCmd;
+    fPts.append()->set(x0, y0);
+    fPts.append()->set(x1, y1);
+    fPts.append()->set(x2, y2);
+}
+
+void GrPath::close() {
+    if (!fCmds.isEmpty() && !this->wasLastVerb(kClose_PathCmd)) {
+        // should we allow kMove followed by kClose?
+        *fCmds.append() = kClose_PathCmd;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrPath::offset(GrScalar tx, GrScalar ty) {
+    if (!tx && !ty) {
+        return; // nothing to do
+    }
+
+    GrPoint* iter = fPts.begin();
+    GrPoint* stop = fPts.end();
+    while (iter < stop) {
+        iter->offset(tx, ty);
+        ++iter;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool check_two_vecs(const GrVec& prevVec,
+                           const GrVec& currVec,
+                           GrScalar turnDir,
+                           int* xDir,
+                           int* yDir,
+                           int* flipX,
+                           int* flipY) {
+    if (currVec.fX * *xDir < 0) {
+        ++*flipX;
+        if (*flipX > 2) {
+            return false;
+        }
+        *xDir = -*xDir;
+    }
+    if (currVec.fY * *yDir < 0) {
+        ++*flipY;
+        if (*flipY > 2) {
+            return false;
+        }
+        *yDir = -*yDir;
+    }
+    GrScalar d = prevVec.cross(currVec);
+    return (d * turnDir) >= 0;
+}
+
+static void init_from_two_vecs(const GrVec& firstVec,
+                               const GrVec& secondVec,
+                               GrScalar* turnDir,
+                               int* xDir, int* yDir) {
+    *turnDir = firstVec.cross(secondVec);
+    if (firstVec.fX > 0) {
+        *xDir = 1;
+    } else if (firstVec.fX < 0) {
+        *xDir = -1;
+    } else {
+        *xDir = 0;
+    }
+    if (firstVec.fY > 0) {
+        *yDir = 1;
+    } else if (firstVec.fY < 0) {
+        *yDir = -1;
+    } else {
+        *yDir = 0;
+    }
+}
+
+void GrPath::resetFromIter(GrPathIter* iter) {
+    fPts.reset();
+    fCmds.reset();
+
+    fConvexHint = iter->convexHint();
+
+    // first point of the subpath
+    GrPoint firstPt(0,0);
+    // first edge of the subpath
+    GrVec firstVec(0,0);
+    // vec of most recently processed edge, that wasn't degenerate
+    GrVec previousVec(0,0);
+    // most recently processed point
+    GrPoint previousPt(0,0);
+
+    // sign indicates whether we're bending left or right
+    GrScalar turnDir = 0;
+    // number of times the direction has flipped in x or y
+
+    // we track which direction we are moving in x/y and the
+    // number of times it changes.
+    int xDir = 0;
+    int yDir = 0;
+    int flipX = 0;
+    int flipY = 0;
+
+    // counts number of sub path pts that didn't add a degenerate edge.
+    int subPathPts = 0;
+    bool subPathClosed = false;
+
+    int numSubPaths = 0;
+    iter->rewind();
+    GrPathCmd cmd;
+    GrPoint pts[4];
+    do {
+        cmd = iter->next(pts);
+        // If the convexity test is ever updated to handle multiple subpaths
+        // the loop has to be adjusted to handle moving to a new subpath without
+        // closing the previous one. Currently the implicit closing vectors for a
+        // filled path would never be examined.
+        switch (cmd) {
+            case kMove_PathCmd:
+                this->moveTo(pts[0].fX, pts[0].fY);
+                subPathPts = 0;
+                subPathClosed = false;
+                break;
+            case kLine_PathCmd:
+                this->lineTo(pts[1].fX, pts[1].fY);
+                break;
+            case kQuadratic_PathCmd:
+                this->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+                break;
+            case kCubic_PathCmd:
+                this->cubicTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
+                              pts[3].fX, pts[3].fY);
+                break;
+            case kClose_PathCmd:
+                this->close();
+                subPathClosed = true;
+                break;
+            case kEnd_PathCmd:
+                break;
+        }
+        int n = NumPathCmdPoints(cmd);
+        if (0 == subPathPts && n > 0) {
+            previousPt = pts[0];
+            firstPt = previousPt;
+            flipX = 0;
+            flipY = 0;
+            turnDir = 0;
+            subPathPts = 1;
+            ++numSubPaths;
+        }
+        // either we skip the first pt because it is redundant with
+        // last point of the previous subpath cmd or we just ate it
+        // in the above if.
+        int consumed = 1;
+        if (numSubPaths < 2 && kNone_ConvexHint == fConvexHint) {
+            while (consumed < n) {
+                GrAssert(pts[consumed-1] == previousPt);
+                GrVec vec;
+                vec.setBetween(previousPt, pts[consumed]);
+                if (vec.fX || vec.fY) {
+                    if (subPathPts >= 2) {
+                        if (0 == turnDir) {
+                            firstVec = previousVec;
+                            init_from_two_vecs(firstVec, vec,
+                                               &turnDir, &xDir, &yDir);
+                            // here we aren't checking whether the x/y dirs
+                            // change between the first and second edge. It
+                            // gets covered when the path is closed.
+                        } else {
+                            if (!check_two_vecs(previousVec, vec, turnDir,
+                                                &xDir, &yDir,
+                                                &flipX, &flipY)) {
+                                fConvexHint = kConcave_ConvexHint;
+                                break;
+                            }
+                        }
+                    }
+                    previousVec = vec;
+                    previousPt = pts[consumed];
+                    ++subPathPts;
+                }
+                ++consumed;
+            }
+            if (subPathPts > 2 && (kClose_PathCmd == cmd ||
+                        (!subPathClosed && kEnd_PathCmd == cmd ))) {
+                // if an additional vector is needed to close the loop check
+                // that it validates against the previous vector.
+                GrVec vec;
+                vec.setBetween(previousPt, firstPt);
+                if (vec.fX || vec.fY) {
+                    if (!check_two_vecs(previousVec, vec, turnDir,
+                                        &xDir, &yDir, &flipX, &flipY)) {
+                        fConvexHint = kConcave_ConvexHint;
+                        break;
+                    }
+                    previousVec = vec;
+                }
+                // check that closing vector validates against the first vector.
+                if (!check_two_vecs(previousVec, firstVec, turnDir,
+                                    &xDir, &yDir, &flipX, &flipY)) {
+                    fConvexHint = kConcave_ConvexHint;
+                    break;
+                }
+            }
+        }
+    } while (cmd != kEnd_PathCmd);
+    if (kNone_ConvexHint == fConvexHint && numSubPaths < 2) {
+        fConvexHint = kConvex_ConvexHint;
+    } else {
+        bool recurse = false;
+        if (recurse) {
+            this->resetFromIter(iter);
+        }
+    }
+}
+
+void GrPath::ConvexUnitTest() {
+    GrPath testPath;
+    GrPath::Iter testIter;
+
+    GrPath pt;
+    pt.moveTo(0, 0);
+    pt.close();
+
+    testIter.reset(pt);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath line;
+    line.moveTo(GrIntToScalar(12), GrIntToScalar(20));
+    line.lineTo(GrIntToScalar(-12), GrIntToScalar(-20));
+    line.close();
+
+    testIter.reset(line);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath triLeft;
+    triLeft.moveTo(0, 0);
+    triLeft.lineTo(1, 0);
+    triLeft.lineTo(1, 1);
+    triLeft.close();
+
+    testIter.reset(triLeft);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath triRight;
+    triRight.moveTo(0, 0);
+    triRight.lineTo(-1, 0);
+    triRight.lineTo(1, 1);
+    triRight.close();
+
+    testIter.reset(triRight);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath square;
+    square.moveTo(0, 0);
+    square.lineTo(1, 0);
+    square.lineTo(1, 1);
+    square.lineTo(0, 1);
+    square.close();
+
+    testIter.reset(square);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath redundantSquare;
+    square.moveTo(0, 0);
+    square.lineTo(0, 0);
+    square.lineTo(0, 0);
+    square.lineTo(1, 0);
+    square.lineTo(1, 0);
+    square.lineTo(1, 0);
+    square.lineTo(1, 1);
+    square.lineTo(1, 1);
+    square.lineTo(1, 1);
+    square.lineTo(0, 1);
+    square.lineTo(0, 1);
+    square.lineTo(0, 1);
+    square.close();
+
+    testIter.reset(redundantSquare);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
+
+    GrPath bowTie;
+    bowTie.moveTo(0, 0);
+    bowTie.lineTo(0, 0);
+    bowTie.lineTo(0, 0);
+    bowTie.lineTo(1, 1);
+    bowTie.lineTo(1, 1);
+    bowTie.lineTo(1, 1);
+    bowTie.lineTo(1, 0);
+    bowTie.lineTo(1, 0);
+    bowTie.lineTo(1, 0);
+    bowTie.lineTo(0, 1);
+    bowTie.lineTo(0, 1);
+    bowTie.lineTo(0, 1);
+    bowTie.close();
+
+    testIter.reset(bowTie);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConcave_ConvexHint == testPath.getConvexHint());
+
+    GrPath spiral;
+    spiral.moveTo(0, 0);
+    spiral.lineTo(1, 0);
+    spiral.lineTo(1, 1);
+    spiral.lineTo(0, 1);
+    spiral.lineTo(0,.5);
+    spiral.lineTo(.5,.5);
+    spiral.lineTo(.5,.75);
+    spiral.close();
+
+    testIter.reset(spiral);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConcave_ConvexHint == testPath.getConvexHint());
+
+    GrPath dent;
+    dent.moveTo(0, 0);
+    dent.lineTo(1, 1);
+    dent.lineTo(0, 1);
+    dent.lineTo(-.5,2);
+    dent.lineTo(-2, 1);
+    dent.close();
+
+    testIter.reset(dent);
+    testPath.resetFromIter(&testIter);
+    GrAssert(kConcave_ConvexHint == testPath.getConvexHint());
+}
+///////////////////////////////////////////////////////////////////////////////
+
+GrPath::Iter::Iter() : fPath(NULL) {
+}
+
+GrPath::Iter::Iter(const GrPath& path) : fPath(&path) {
+    this->rewind();
+}
+
+GrPathCmd GrPath::Iter::next(GrPoint points[]) {
+    if (fCmdIndex == fPath->fCmds.count()) {
+        GrAssert(fPtIndex == fPath->fPts.count());
+        return kEnd_PathCmd;
+    } else {
+        GrAssert(fCmdIndex < fPath->fCmds.count());
+    }
+
+    GrPathCmd cmd = fPath->fCmds[fCmdIndex++];
+    const GrPoint* srcPts = fPath->fPts.begin() + fPtIndex;
+
+    switch (cmd) {
+        case kMove_PathCmd:
+            if (points) {
+                points[0] = srcPts[0];
+            }
+            fLastPt = srcPts[0];
+            GrAssert(fPtIndex <= fPath->fPts.count() + 1);
+            fPtIndex += 1;
+            break;
+        case kLine_PathCmd:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+            }
+            fLastPt = srcPts[0];
+            GrAssert(fPtIndex <= fPath->fPts.count() + 1);
+            fPtIndex += 1;
+            break;
+        case kQuadratic_PathCmd:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+                points[2] = srcPts[1];
+            }
+            fLastPt = srcPts[1];
+            GrAssert(fPtIndex <= fPath->fPts.count() + 2);
+            fPtIndex += 2;
+            break;
+        case kCubic_PathCmd:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+                points[2] = srcPts[1];
+                points[3] = srcPts[2];
+            }
+            fLastPt = srcPts[2];
+            GrAssert(fPtIndex <= fPath->fPts.count() + 3);
+            fPtIndex += 3;
+            break;
+        case kClose_PathCmd:
+            break;
+        default:
+            GrAssert(!"unknown grpath cmd");
+            break;
+    }
+    return cmd;
+}
+
+GrConvexHint GrPath::Iter::convexHint() const {
+    return fPath->getConvexHint();
+}
+
+GrPathCmd GrPath::Iter::next() {
+    return this->next(NULL);
+}
+
+void GrPath::Iter::rewind() {
+    this->reset(*fPath);
+}
+
+void GrPath::Iter::reset(const GrPath& path) {
+    fPath = &path;
+    fCmdIndex = fPtIndex = 0;
+}
+
+
diff --git a/gpu/src/GrPathRenderer.cpp b/gpu/src/GrPathRenderer.cpp
new file mode 100644
index 0000000..6d7aabb
--- /dev/null
+++ b/gpu/src/GrPathRenderer.cpp
@@ -0,0 +1,569 @@
+#include "GrPathRenderer.h"
+
+#include "GrPoint.h"
+#include "GrDrawTarget.h"
+#include "GrPathIter.h"
+#include "GrMemory.h"
+#include "GrTexture.h"
+
+GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
+                                             bool stencilWrapOpsSupport)
+    : fSeparateStencil(separateStencilSupport),
+      fStencilWrapOps(stencilWrapOpsSupport) {
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Stencil rules for paths
+
+////// Even/Odd
+
+static const GrStencilSettings gEOStencilPass = {
+    kInvert_StencilOp,           kInvert_StencilOp,
+    kKeep_StencilOp,             kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
+    0xffffffff,                  0xffffffff,
+    0xffffffff,                  0xffffffff,
+    0xffffffff,                  0xffffffff
+};
+
+// ok not to check clip b/c stencil pass only wrote inside clip
+static const GrStencilSettings gEOColorPass = {
+    kZero_StencilOp,          kZero_StencilOp,
+    kZero_StencilOp,          kZero_StencilOp,
+    kNotEqual_StencilFunc,    kNotEqual_StencilFunc,
+    0xffffffff,               0xffffffff,
+    0x0,                      0x0,
+    0xffffffff,               0xffffffff
+};
+
+// have to check clip b/c outside clip will always be zero.
+static const GrStencilSettings gInvEOColorPass = {
+    kZero_StencilOp,            kZero_StencilOp,
+    kZero_StencilOp,            kZero_StencilOp,
+    kEqualIfInClip_StencilFunc, kEqualIfInClip_StencilFunc,
+    0xffffffff,                 0xffffffff,
+    0x0,                        0x0,
+    0xffffffff,                 0xffffffff
+};
+
+////// Winding
+
+// when we have separate stencil we increment front faces / decrement back faces
+// when we don't have wrap incr and decr we use the stencil test to simulate
+// them.
+
+static const GrStencilSettings gWindStencilSeparateWithWrap = {
+    kIncWrap_StencilOp,             kDecWrap_StencilOp,
+    kKeep_StencilOp,                kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc,    kAlwaysIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff
+};
+
+// if inc'ing the max value, invert to make 0
+// if dec'ing zero invert to make all ones.
+// we can't avoid touching the stencil on both passing and
+// failing, so we can't resctrict ourselves to the clip.
+static const GrStencilSettings gWindStencilSeparateNoWrap = {
+    kInvert_StencilOp,              kInvert_StencilOp,
+    kIncClamp_StencilOp,            kDecClamp_StencilOp,
+    kEqual_StencilFunc,             kEqual_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0x0,
+    0xffffffff,                     0xffffffff
+};
+
+// When there are no separate faces we do two passes to setup the winding rule
+// stencil. First we draw the front faces and inc, then we draw the back faces
+// and dec. These are same as the above two split into the incrementing and
+// decrementing passes.
+static const GrStencilSettings gWindSingleStencilWithWrapInc = {
+    kIncWrap_StencilOp,             kIncWrap_StencilOp,
+    kKeep_StencilOp,                kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc,    kAlwaysIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff
+};
+static const GrStencilSettings gWindSingleStencilWithWrapDec = {
+    kDecWrap_StencilOp,             kDecWrap_StencilOp,
+    kKeep_StencilOp,                kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc,    kAlwaysIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff
+};
+static const GrStencilSettings gWindSingleStencilNoWrapInc = {
+    kInvert_StencilOp,              kInvert_StencilOp,
+    kIncClamp_StencilOp,            kIncClamp_StencilOp,
+    kEqual_StencilFunc,             kEqual_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff,
+    0xffffffff,                     0xffffffff
+};
+static const GrStencilSettings gWindSingleStencilNoWrapDec = {
+    kInvert_StencilOp,              kInvert_StencilOp,
+    kDecClamp_StencilOp,            kDecClamp_StencilOp,
+    kEqual_StencilFunc,             kEqual_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0x0,                            0x0,
+    0xffffffff,                     0xffffffff
+};
+
+static const GrStencilSettings gWindColorPass = {
+    kZero_StencilOp,                kZero_StencilOp,
+    kZero_StencilOp,                kZero_StencilOp,
+    kNonZeroIfInClip_StencilFunc,   kNonZeroIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0x0,                            0x0,
+    0xffffffff,                     0xffffffff
+};
+
+static const GrStencilSettings gInvWindColorPass = {
+    kZero_StencilOp,                kZero_StencilOp,
+    kZero_StencilOp,                kZero_StencilOp,
+    kEqualIfInClip_StencilFunc,     kEqualIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0x0,                            0x0,
+    0xffffffff,                     0xffffffff
+};
+
+////// Normal render to stencil
+
+// Sometimes the default path renderer can draw a path directly to the stencil
+// buffer without having to first resolve the interior / exterior.
+static const GrStencilSettings gDirectToStencil = {
+    kZero_StencilOp,                kZero_StencilOp,
+    kIncClamp_StencilOp,            kIncClamp_StencilOp,
+    kAlwaysIfInClip_StencilFunc,    kAlwaysIfInClip_StencilFunc,
+    0xffffffff,                     0xffffffff,
+    0x0,                            0x0,
+    0xffffffff,                     0xffffffff
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helpers for drawPath
+
+#define STENCIL_OFF     0   // Always disable stencil (even when needed)
+static const GrScalar gTolerance = GR_Scalar1;
+
+static const uint32_t MAX_POINTS_PER_CURVE = 1 << 10;
+
+static uint32_t quadratic_point_count(const GrPoint points[], GrScalar tol) {
+    GrScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]);
+    if (d < tol) {
+        return 1;
+    } else {
+        // Each time we subdivide, d should be cut in 4. So we need to
+        // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x)
+        // points.
+        // 2^(log4(x)) = sqrt(x);
+        d = ceilf(sqrtf(d/tol));
+        return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE);
+    }
+}
+
+static uint32_t generate_quadratic_points(const GrPoint& p0,
+                                          const GrPoint& p1,
+                                          const GrPoint& p2,
+                                          GrScalar tolSqd,
+                                          GrPoint** points,
+                                          uint32_t pointsLeft) {
+    if (pointsLeft < 2 ||
+        (p1.distanceToLineSegmentBetweenSqd(p0, p2)) < tolSqd) {
+        (*points)[0] = p2;
+        *points += 1;
+        return 1;
+    }
+
+    GrPoint q[] = {
+        GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)),
+        GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)),
+    };
+    GrPoint r(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY));
+
+    pointsLeft >>= 1;
+    uint32_t a = generate_quadratic_points(p0, q[0], r, tolSqd, points, pointsLeft);
+    uint32_t b = generate_quadratic_points(r, q[1], p2, tolSqd, points, pointsLeft);
+    return a + b;
+}
+
+static uint32_t cubic_point_count(const GrPoint points[], GrScalar tol) {
+    GrScalar d = GrMax(points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]),
+                       points[2].distanceToLineSegmentBetweenSqd(points[0], points[3]));
+    d = sqrtf(d);
+    if (d < tol) {
+        return 1;
+    } else {
+        d = ceilf(sqrtf(d/tol));
+        return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE);
+    }
+}
+
+static uint32_t generate_cubic_points(const GrPoint& p0,
+                                      const GrPoint& p1,
+                                      const GrPoint& p2,
+                                      const GrPoint& p3,
+                                      GrScalar tolSqd,
+                                      GrPoint** points,
+                                      uint32_t pointsLeft) {
+    if (pointsLeft < 2 ||
+        (p1.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd &&
+         p2.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd)) {
+            (*points)[0] = p3;
+            *points += 1;
+            return 1;
+        }
+    GrPoint q[] = {
+        GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)),
+        GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)),
+        GrPoint(GrScalarAve(p2.fX, p3.fX), GrScalarAve(p2.fY, p3.fY))
+    };
+    GrPoint r[] = {
+        GrPoint(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)),
+        GrPoint(GrScalarAve(q[1].fX, q[2].fX), GrScalarAve(q[1].fY, q[2].fY))
+    };
+    GrPoint s(GrScalarAve(r[0].fX, r[1].fX), GrScalarAve(r[0].fY, r[1].fY));
+    pointsLeft >>= 1;
+    uint32_t a = generate_cubic_points(p0, q[0], r[0], s, tolSqd, points, pointsLeft);
+    uint32_t b = generate_cubic_points(s, r[1], q[2], p3, tolSqd, points, pointsLeft);
+    return a + b;
+}
+
+static int worst_case_point_count(GrPathIter* path,
+                                  int* subpaths,
+                                  GrScalar tol) {
+    int pointCount = 0;
+    *subpaths = 1;
+
+    bool first = true;
+
+    GrPathCmd cmd;
+
+    GrPoint pts[4];
+    while ((cmd = path->next(pts)) != kEnd_PathCmd) {
+
+        switch (cmd) {
+            case kLine_PathCmd:
+                pointCount += 1;
+                break;
+            case kQuadratic_PathCmd:
+                pointCount += quadratic_point_count(pts, tol);
+                break;
+            case kCubic_PathCmd:
+                pointCount += cubic_point_count(pts, tol);
+                break;
+            case kMove_PathCmd:
+                pointCount += 1;
+                if (!first) {
+                    ++(*subpaths);
+                }
+                break;
+            default:
+                break;
+        }
+        first = false;
+    }
+    return pointCount;
+}
+
+static inline bool single_pass_path(const GrDrawTarget& target,
+                                    const GrPathIter& path,
+                                    GrPathFill fill) {
+#if STENCIL_OFF
+    return true;
+#else
+    if (kEvenOdd_PathFill == fill) {
+        GrConvexHint hint = path.convexHint();
+        return hint == kConvex_ConvexHint ||
+               hint == kNonOverlappingConvexPieces_ConvexHint;
+    } else if (kWinding_PathFill == fill) {
+        GrConvexHint hint = path.convexHint();
+        return hint == kConvex_ConvexHint ||
+               hint == kNonOverlappingConvexPieces_ConvexHint ||
+               (hint == kSameWindingConvexPieces_ConvexHint &&
+                target.canDisableBlend() && !target.isDitherState());
+
+    }
+    return false;
+#endif
+}
+
+bool GrDefaultPathRenderer::requiresStencilPass(const GrDrawTarget* target,
+                                                GrPathIter* path, 
+                                                GrPathFill fill) const {
+    return single_pass_path(*target, *path, fill);
+}
+
+void GrDefaultPathRenderer::drawPathHelper(GrDrawTarget* target,
+                                           GrDrawTarget::StageBitfield stages,
+                                           GrPathIter* path,
+                                           GrPathFill fill,
+                                           const GrPoint* translate,
+                                           bool stencilOnly) {
+
+    GrDrawTarget::AutoStateRestore asr(target);
+    bool colorWritesWereDisabled = target->isColorWriteDisabled();
+    // face culling doesn't make sense here
+    GrAssert(GrDrawTarget::kBoth_DrawFace == target->getDrawFace());
+
+    GrMatrix viewM = target->getViewMatrix();
+    // In order to tesselate the path we get a bound on how much the matrix can
+    // stretch when mapping to screen coordinates.
+    GrScalar stretch = viewM.getMaxStretch();
+    bool useStretch = stretch > 0;
+    GrScalar tol = gTolerance;
+
+    if (!useStretch) {
+        // TODO: deal with perspective in some better way.
+        tol /= 10;
+    } else {
+        GrScalar sinv = GR_Scalar1 / stretch;
+        tol = GrMul(tol, sinv);
+    }
+    GrScalar tolSqd = GrMul(tol, tol);
+
+    path->rewind();
+
+    int subpathCnt;
+    int maxPts = worst_case_point_count(path,
+                                        &subpathCnt,
+                                        tol);
+
+    GrVertexLayout layout = 0;
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        if ((1 << s) & stages) {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
+        }
+    }
+
+    // add 4 to hold the bounding rect
+    GrDrawTarget::AutoReleaseGeometry arg(target, layout, maxPts + 4, 0);
+
+    GrPoint* base = (GrPoint*) arg.vertices();
+    GrPoint* vert = base;
+    GrPoint* subpathBase = base;
+
+    GrAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt);
+
+    path->rewind();
+
+    // TODO: use primitve restart if available rather than multiple draws
+    GrPrimitiveType             type;
+    int                         passCount = 0;
+    const GrStencilSettings*    passes[3];
+    GrDrawTarget::DrawFace      drawFace[3];
+    bool                        reverse = false;
+    bool                        lastPassIsBounds;
+
+    if (kHairLine_PathFill == fill) {
+        type = kLineStrip_PrimitiveType;
+        passCount = 1;
+        if (stencilOnly) {
+            passes[0] = &gDirectToStencil;
+        } else {
+            passes[0] = NULL;
+        }
+        lastPassIsBounds = false;
+        drawFace[0] = GrDrawTarget::kBoth_DrawFace;
+    } else {
+        type = kTriangleFan_PrimitiveType;
+        if (single_pass_path(*target, *path, fill)) {
+            passCount = 1;
+            if (stencilOnly) {
+                passes[0] = &gDirectToStencil;
+            } else {
+                passes[0] = NULL;
+            }
+            drawFace[0] = GrDrawTarget::kBoth_DrawFace;
+            lastPassIsBounds = false;
+        } else {
+            switch (fill) {
+                case kInverseEvenOdd_PathFill:
+                    reverse = true;
+                    // fallthrough
+                case kEvenOdd_PathFill:
+                    passes[0] = &gEOStencilPass;
+                    if (stencilOnly) {
+                        passCount = 1;
+                        lastPassIsBounds = false;
+                    } else {
+                        passCount = 2;
+                        lastPassIsBounds = true;
+                        if (reverse) {
+                            passes[1] = &gInvEOColorPass;
+                        } else {
+                            passes[1] = &gEOColorPass;
+                        }
+                    }
+                    drawFace[0] = drawFace[1] = GrDrawTarget::kBoth_DrawFace;
+                    break;
+
+                case kInverseWinding_PathFill:
+                    reverse = true;
+                    // fallthrough
+                case kWinding_PathFill:
+                    if (fSeparateStencil) {
+                        if (fStencilWrapOps) {
+                            passes[0] = &gWindStencilSeparateWithWrap;
+                        } else {
+                            passes[0] = &gWindStencilSeparateNoWrap;
+                        }
+                        passCount = 2;
+                        drawFace[0] = GrDrawTarget::kBoth_DrawFace;
+                    } else {
+                        if (fStencilWrapOps) {
+                            passes[0] = &gWindSingleStencilWithWrapInc;
+                            passes[1] = &gWindSingleStencilWithWrapDec;
+                        } else {
+                            passes[0] = &gWindSingleStencilNoWrapInc;
+                            passes[1] = &gWindSingleStencilNoWrapDec;
+                        }
+                        // which is cw and which is ccw is arbitrary.
+                        drawFace[0] = GrDrawTarget::kCW_DrawFace;
+                        drawFace[1] = GrDrawTarget::kCCW_DrawFace;
+                        passCount = 3;
+                    }
+                    if (stencilOnly) {
+                        lastPassIsBounds = false;
+                        --passCount;
+                    } else {
+                        lastPassIsBounds = true;
+                        drawFace[passCount-1] = GrDrawTarget::kBoth_DrawFace;
+                        if (reverse) {
+                            passes[passCount-1] = &gInvWindColorPass;
+                        } else {
+                            passes[passCount-1] = &gWindColorPass;
+                        }
+                    }
+                    break;
+                default:
+                    GrAssert(!"Unknown path fill!");
+                    return;
+            }
+        }
+    }
+
+    GrPoint pts[4];
+
+    bool first = true;
+    int subpath = 0;
+
+    for (;;) {
+        GrPathCmd cmd = path->next(pts);
+        switch (cmd) {
+            case kMove_PathCmd:
+                if (!first) {
+                    subpathVertCount[subpath] = vert-subpathBase;
+                    subpathBase = vert;
+                    ++subpath;
+                }
+                *vert = pts[0];
+                vert++;
+                break;
+            case kLine_PathCmd:
+                *vert = pts[1];
+                vert++;
+                break;
+            case kQuadratic_PathCmd: {
+                generate_quadratic_points(pts[0], pts[1], pts[2],
+                                          tolSqd, &vert,
+                                          quadratic_point_count(pts, tol));
+                break;
+            }
+            case kCubic_PathCmd: {
+                generate_cubic_points(pts[0], pts[1], pts[2], pts[3],
+                                      tolSqd, &vert,
+                                      cubic_point_count(pts, tol));
+                break;
+            }
+            case kClose_PathCmd:
+                break;
+            case kEnd_PathCmd:
+                subpathVertCount[subpath] = vert-subpathBase;
+                ++subpath; // this could be only in debug
+                goto FINISHED;
+        }
+        first = false;
+    }
+FINISHED:
+    GrAssert(subpath == subpathCnt);
+    GrAssert((vert - base) <= maxPts);
+
+    if (translate) {
+        int count = vert - base;
+        for (int i = 0; i < count; i++) {
+            base[i].offset(translate->fX, translate->fY);
+        }
+    }
+
+    // if we're stenciling we will follow with a pass that draws
+    // a bounding rect to set the color. We're stenciling when
+    // passCount > 1.
+    const int& boundVertexStart = maxPts;
+    GrPoint* boundsVerts = base + boundVertexStart;
+    if (lastPassIsBounds) {
+        GrRect bounds;
+        if (reverse) {
+            GrAssert(NULL != target->getRenderTarget());
+            // draw over the whole world.
+            bounds.setLTRB(0, 0,
+                           GrIntToScalar(target->getRenderTarget()->width()),
+                           GrIntToScalar(target->getRenderTarget()->height()));
+            GrMatrix vmi;
+            if (target->getViewInverse(&vmi)) {
+                vmi.mapRect(&bounds);
+            }
+        } else {
+            bounds.setBounds((GrPoint*)base, vert - base);
+        }
+        boundsVerts[0].setRectFan(bounds.fLeft, bounds.fTop, bounds.fRight,
+                                  bounds.fBottom);
+    }
+
+    for (int p = 0; p < passCount; ++p) {
+        target->setDrawFace(drawFace[p]);
+        if (NULL != passes[p]) {
+            target->setStencil(*passes[p]);
+        }
+
+        if (lastPassIsBounds && (p == passCount-1)) {
+            if (!colorWritesWereDisabled) {
+                target->disableState(GrDrawTarget::kNoColorWrites_StateBit);
+            }
+            target->drawNonIndexed(kTriangleFan_PrimitiveType,
+                                   boundVertexStart, 4);
+
+        } else {
+            if (passCount > 1) {
+                target->enableState(GrDrawTarget::kNoColorWrites_StateBit);
+            }
+            int baseVertex = 0;
+            for (int sp = 0; sp < subpathCnt; ++sp) {
+                target->drawNonIndexed(type,
+                                      baseVertex,
+                                      subpathVertCount[sp]);
+                baseVertex += subpathVertCount[sp];
+            }
+        }
+    }
+}
+
+void GrDefaultPathRenderer::drawPath(GrDrawTarget* target,
+                                     GrDrawTarget::StageBitfield stages,
+                                     GrPathIter* path,
+                                     GrPathFill fill,
+                                     const GrPoint* translate) {
+    this->drawPathHelper(target, stages, path, fill, translate, false);
+}
+
+void GrDefaultPathRenderer::drawPathToStencil(GrDrawTarget* target,
+                                              GrPathIter* path,
+                                              GrPathFill fill,
+                                              const GrPoint* translate) {
+     GrAssert(kInverseEvenOdd_PathFill != fill);
+     GrAssert(kInverseWinding_PathFill != fill);
+     this->drawPathHelper(target, 0, path, fill, translate, true);
+ }
diff --git a/gpu/src/GrPathRenderer.h b/gpu/src/GrPathRenderer.h
new file mode 100644
index 0000000..19e284f
--- /dev/null
+++ b/gpu/src/GrPathRenderer.h
@@ -0,0 +1,157 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrPathRenderer_DEFINED
+#define GrPathRenderer_DEFINED
+
+#include "GrDrawTarget.h"
+
+class GrPathIter;
+struct GrPoint;
+
+/**
+ *  Base class for drawing paths into a GrDrawTarget.
+ */
+class GrPathRenderer {
+public:
+    virtual ~GrPathRenderer() { };
+
+    /**
+     * Draws a path into the draw target. The target will already have its draw
+     * state configured for the draw.
+     * @param target                the target to draw into.
+     * @param stages                indicates which stages the are already
+     *                              in use. All enabled stages expect positions
+     *                              as texture coordinates. The path renderer
+     *                              use the remaining stages for its path
+     *                              filling algorithm.
+     * @param path                  the path to draw.
+     * @param fill                  the fill rule to apply.
+     * @param translate             optional additional translation to apply to
+     *                              the path. NULL means (0,0).
+     */
+    virtual void drawPath(GrDrawTarget* target,
+                          GrDrawTarget::StageBitfield stages,
+                          GrPathIter* path,
+                          GrPathFill fill,
+                          const GrPoint* translate) = 0;
+
+    void drawPath(GrDrawTarget* target,
+                  GrDrawTarget::StageBitfield stages,
+                  const GrPath& path,
+                  GrPathFill fill,
+                  const GrPoint* translate) {
+            GrPath::Iter iter(path);
+            this->drawPath(target, stages, &iter, fill, translate);
+    }
+
+    /**
+     * For complex clips Gr uses the stencil buffer. The path renderer must be
+     * able to render paths into the stencil buffer. However, the path renderer
+     * itself may require the stencil buffer to resolve the path fill rule. This
+     * function queries whether the path render needs its own stencil
+     * pass. If this returns false then drawPath() should not modify the
+     * the target's stencil settings but use those already set on target.
+     *
+     * @param target target that the path will be rendered to
+     * @param path   the path that will be drawn
+     * @param fill   the fill rule that will be used
+     *
+     * @return false if this path renderer can generate interior-only fragments
+     *         without changing the stencil settings on the target. If it
+     *         returns true the drawPathToStencil will be used when rendering
+     *         clips.
+     */
+    virtual bool requiresStencilPass(const GrDrawTarget* target,
+                                     GrPathIter* path,
+                                     GrPathFill fill) const { return false; }
+
+    bool requiresStencilPass(const GrDrawTarget* target,
+                             const GrPath& path,
+                             GrPathFill fill) const {
+        GrPath::Iter iter(path);
+        return requiresStencilPass(target, &iter, fill);
+    }
+
+    /**
+     * Draws a path to the stencil buffer. Assume the writable stencil bits
+     * are already initialized to zero. Fill will always be either
+     * kWinding_PathFill or kEvenOdd_PathFill.
+     *
+     * Only called if requiresStencilPass returns true for the same combo of
+     * target, path, and fill (or inverse of the fill).
+     *
+     * The default implementation assumes the path filling algorithm doesn't
+     * require a separate stencil pass and so crashes.
+     *
+     *
+     * @param target                the target to draw into.
+     * @param path                  the path to draw.
+     * @param fill                  the fill rule to apply.
+     * @param translate             optional additional translation to apply to
+     *                              the path. NULL means (0,0).
+     */
+    virtual void drawPathToStencil(GrDrawTarget* target,
+                                   GrPathIter* path,
+                                   GrPathFill fill,
+                                   const GrPoint* translate) {
+        GrCrash("Unexpected call to drawPathToStencil.");
+    }
+
+    void drawPathToStencil(GrDrawTarget* target,
+                           const GrPath& path,
+                           GrPathFill fill,
+                           const GrPoint* translate) {
+        GrPath::Iter iter(path);
+        this->drawPathToStencil(target, &iter, fill, translate);
+    }
+};
+
+/**
+ *  Subclass that renders the path using the stencil buffer to resolve fill
+ *  rules (e.g. winding, even-odd)
+ */
+class GrDefaultPathRenderer : public GrPathRenderer {
+public:
+    GrDefaultPathRenderer(bool separateStencilSupport,
+                          bool stencilWrapOpsSupport);
+
+    virtual void drawPath(GrDrawTarget* target,
+                          GrDrawTarget::StageBitfield stages,
+                          GrPathIter* path,
+                          GrPathFill fill,
+                          const GrPoint* translate);
+    virtual bool requiresStencilPass(const GrDrawTarget* target,
+                                     GrPathIter* path,
+                                     GrPathFill fill) const;
+    virtual void drawPathToStencil(GrDrawTarget* target,
+                                   GrPathIter* path,
+                                   GrPathFill fill,
+                                   const GrPoint* translate);
+private:
+
+    void drawPathHelper(GrDrawTarget* target,
+                        GrDrawTarget::StageBitfield stages,
+                        GrPathIter* path,
+                        GrPathFill fill,
+                        const GrPoint* translate,
+                        bool stencilOnly);
+
+    bool    fSeparateStencil;
+    bool    fStencilWrapOps;
+};
+
+#endif
diff --git a/gpu/src/GrPrintf_printf.cpp b/gpu/src/GrPrintf_printf.cpp
new file mode 100644
index 0000000..ad239ec
--- /dev/null
+++ b/gpu/src/GrPrintf_printf.cpp
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+void GrPrintf(const char format[], ...) {
+    const size_t MAX_BUFFER_SIZE = 2048;
+
+    char buffer[MAX_BUFFER_SIZE + 1];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buffer, MAX_BUFFER_SIZE, format, args);
+    va_end(args);
+
+    printf("%s", buffer);
+}
+
+
diff --git a/gpu/src/GrRectanizer.cpp b/gpu/src/GrRectanizer.cpp
new file mode 100644
index 0000000..cb6576a
--- /dev/null
+++ b/gpu/src/GrRectanizer.cpp
@@ -0,0 +1,130 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrRectanizer.h"
+#include "GrTBSearch.h"
+
+#define MIN_HEIGHT_POW2     2
+
+class GrRectanizerPow2 : public GrRectanizer {
+public:
+    GrRectanizerPow2(int w, int h) : GrRectanizer(w, h) {
+        fNextStripY = 0;
+        fAreaSoFar = 0;
+        Gr_bzero(fRows, sizeof(fRows));
+    }
+
+    virtual ~GrRectanizerPow2() {
+    }
+
+    virtual bool addRect(int w, int h, GrIPoint16* loc);
+
+    virtual float percentFull() const {
+        return fAreaSoFar / ((float)this->width() * this->height());
+    }
+
+    virtual int stripToPurge(int height) const { return -1; }
+    virtual void purgeStripAtY(int yCoord) { }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    struct Row {
+        GrIPoint16  fLoc;
+        int         fRowHeight;
+        
+        bool canAddWidth(int width, int containerWidth) const {
+            return fLoc.fX + width <= containerWidth;
+        }
+    };
+
+    Row fRows[16];
+
+    static int HeightToRowIndex(int height) {
+        GrAssert(height >= MIN_HEIGHT_POW2);
+        return 32 - Gr_clz(height - 1);
+    }
+
+    int fNextStripY;
+    int32_t fAreaSoFar;
+
+    bool canAddStrip(int height) const {
+        return fNextStripY + height <= this->height();
+    }
+
+    void initRow(Row* row, int rowHeight) {
+        row->fLoc.set(0, fNextStripY);
+        row->fRowHeight = rowHeight;
+        fNextStripY += rowHeight;
+    }
+};
+
+bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) {
+    if ((unsigned)width > (unsigned)this->width() ||
+        (unsigned)height > (unsigned)this->height()) {
+        return false;
+    }
+
+    int32_t area = width * height;
+
+    /*
+        We use bsearch, but there may be more than one row with the same height,
+        so we actually search for height-1, which can only be a pow2 itself if
+        height == 2. Thus we set a minimum height.
+     */
+    height = GrNextPow2(height);
+    if (height < MIN_HEIGHT_POW2) {
+        height = MIN_HEIGHT_POW2;
+    }
+
+    Row* row = &fRows[HeightToRowIndex(height)];
+    GrAssert(row->fRowHeight == 0 || row->fRowHeight == height);
+
+    if (0 == row->fRowHeight) {
+        if (!this->canAddStrip(height)) {
+            return false;
+        }
+        this->initRow(row, height);
+    } else {
+        if (!row->canAddWidth(width, this->width())) {
+            if (!this->canAddStrip(height)) {
+                return false;
+            }
+            // that row is now "full", so retarget our Row record for
+            // another one
+            this->initRow(row, height);
+        }
+    }
+
+    GrAssert(row->fRowHeight == height);
+    GrAssert(row->canAddWidth(width, this->width()));
+    *loc = row->fLoc;
+    row->fLoc.fX += width;
+
+    GrAssert(row->fLoc.fX <= this->width());
+    GrAssert(row->fLoc.fY <= this->height());
+    GrAssert(fNextStripY <= this->height());
+    fAreaSoFar += area;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRectanizer* GrRectanizer::Factory(int width, int height) {
+    return new GrRectanizerPow2(width, height);
+}
+
+
diff --git a/gpu/src/GrRectanizer_fifo.cpp b/gpu/src/GrRectanizer_fifo.cpp
new file mode 100644
index 0000000..6b1cad2
--- /dev/null
+++ b/gpu/src/GrRectanizer_fifo.cpp
@@ -0,0 +1,130 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrRectanizer.h"
+#include "GrTBSearch.h"
+
+#define MIN_HEIGHT_POW2     2
+
+class GrRectanizerFIFO : public GrRectanizer {
+public:
+    GrRectanizerFIFO(int w, int h) : GrRectanizer(w, h) {
+        fNextStripY = 0;
+        fAreaSoFar = 0;
+        Gr_bzero(fRows, sizeof(fRows));
+    }
+    
+    virtual ~GrRectanizerFIFO() {
+    }
+    
+    virtual bool addRect(int w, int h, GrIPoint16* loc);
+    
+    virtual float percentFull() const {
+        return fAreaSoFar / ((float)this->width() * this->height());
+    }
+    
+    virtual int stripToPurge(int height) const { return -1; }
+    virtual void purgeStripAtY(int yCoord) { }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    
+    struct Row {
+        GrIPoint16  fLoc;
+        int         fRowHeight;
+        
+        bool canAddWidth(int width, int containerWidth) const {
+            return fLoc.fX + width <= containerWidth;
+        }
+    };
+    
+    Row fRows[16];
+    
+    static int HeightToRowIndex(int height) {
+        GrAssert(height >= MIN_HEIGHT_POW2);
+        return 32 - Gr_clz(height - 1);
+    }
+    
+    int fNextStripY;
+    int32_t fAreaSoFar;
+    
+    bool canAddStrip(int height) const {
+        return fNextStripY + height <= this->height();
+    }
+    
+    void initRow(Row* row, int rowHeight) {
+        row->fLoc.set(0, fNextStripY);
+        row->fRowHeight = rowHeight;
+        fNextStripY += rowHeight;
+    }
+};
+
+bool GrRectanizerFIFO::addRect(int width, int height, GrIPoint16* loc) {
+    if ((unsigned)width > (unsigned)this->width() ||
+        (unsigned)height > (unsigned)this->height()) {
+        return false;
+    }
+    
+    int32_t area = width * height;
+    
+    /*
+     We use bsearch, but there may be more than one row with the same height,
+     so we actually search for height-1, which can only be a pow2 itself if
+     height == 2. Thus we set a minimum height.
+     */
+    height = GrNextPow2(height);
+    if (height < MIN_HEIGHT_POW2) {
+        height = MIN_HEIGHT_POW2;
+    }
+    
+    Row* row = &fRows[HeightToRowIndex(height)];
+    GrAssert(row->fRowHeight == 0 || row->fRowHeight == height);
+    
+    if (0 == row->fRowHeight) {
+        if (!this->canAddStrip(height)) {
+            return false;
+        }
+        this->initRow(row, height);
+    } else {
+        if (!row->canAddWidth(width, this->width())) {
+            if (!this->canAddStrip(height)) {
+                return false;
+            }
+            // that row is now "full", so retarget our Row record for
+            // another one
+            this->initRow(row, height);
+        }
+    }
+    
+    GrAssert(row->fRowHeight == height);
+    GrAssert(row->canAddWidth(width, this->width()));
+    *loc = row->fLoc;
+    row->fLoc.fX += width;
+    
+    GrAssert(row->fLoc.fX <= this->width());
+    GrAssert(row->fLoc.fY <= this->height());
+    GrAssert(fNextStripY <= this->height());
+    fAreaSoFar += area;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRectanizer* GrRectanizer::Factory(int width, int height) {
+    return new GrRectanizerFIFO(width, height);
+}
+
+
diff --git a/gpu/src/GrRedBlackTree.h b/gpu/src/GrRedBlackTree.h
new file mode 100644
index 0000000..7ba326f
--- /dev/null
+++ b/gpu/src/GrRedBlackTree.h
@@ -0,0 +1,1125 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrRedBlackTree_DEFINED
+#define GrRedBlackTree_DEFINED
+
+#include "GrNoncopyable.h"
+
+template <typename T>
+class GrLess {
+public:
+    bool operator()(const T& a, const T& b) const { return a < b; }
+};
+
+template <typename T>
+class GrLess<T*> {
+public:
+    bool operator()(const T* a, const T* b) const { return *a < *b; }
+};
+
+/**
+ * In debug build this will cause full traversals of the tree when the validate
+ * is called on insert and remove. Useful for debugging but very slow.
+ */
+#define DEEP_VALIDATE 0
+
+/**
+ * A sorted tree that uses the red-black tree algorithm. Allows duplicate
+ * entries. Data is of type T and is compared using functor C. A single C object
+ * will be created and used for all comparisons.
+ */
+template <typename T, typename C = GrLess<T> >
+class GrRedBlackTree : public GrNoncopyable {
+public:
+    /**
+     * Creates an empty tree.
+     */
+    GrRedBlackTree();
+    virtual ~GrRedBlackTree();
+
+    /**
+     * Class used to iterater through the tree. The valid range of the tree
+     * is given by [begin(), end()). It is legal to dereference begin() but not
+     * end(). The iterator has preincrement and predecrement operators, it is
+     * legal to decerement end() if the tree is not empty to get the last
+     * element. However, a last() helper is provided.
+     */
+    class Iter;
+
+    /**
+     * Add an element to the tree. Duplicates are allowed.
+     * @param t     the item to add.
+     * @return  an iterator to the item.
+     */
+    Iter insert(const T& t);
+
+    /**
+     * Removes all items in the tree.
+     */
+    void reset();
+
+    /**
+     * @return true if there are no items in the tree, false otherwise.
+     */
+    bool empty() const {return 0 == fCount;}
+
+    /**
+     * @return the number of items in the tree.
+     */
+    int  count() const {return fCount;}
+
+    /**
+     * @return  an iterator to the first item in sorted order, or end() if empty
+     */
+    Iter begin();
+    /**
+     * Gets the last valid iterator. This is always valid, even on an empty.
+     * However, it can never be dereferenced. Useful as a loop terminator.
+     * @return  an iterator that is just beyond the last item in sorted order.
+     */
+    Iter end();
+    /**
+     * @return  an iterator that to the last item in sorted order, or end() if
+     * empty.
+     */
+    Iter last();
+
+    /**
+     * Finds an occurrence of an item.
+     * @param t     the item to find.
+     * @return an iterator to a tree element equal to t or end() if none exists.
+     */
+    Iter find(const T& t);
+    /**
+     * Finds the first of an item in iterator order.
+     * @param t     the item to find.
+     * @return  an iterator to the first element equal to t or end() if
+     *          none exists.
+     */
+    Iter findFirst(const T& t);
+    /**
+     * Finds the last of an item in iterator order.
+     * @param t     the item to find.
+     * @return  an iterator to the last element equal to t or end() if
+     *          none exists.
+     */
+    Iter findLast(const T& t);
+    /**
+     * Gets the number of items in the tree equal to t.
+     * @param t     the item to count.
+     * @return  number of items equal to t in the tree
+     */
+    int countOf(const T& t) const;
+
+    /**
+     * Removes the item indicated by an iterator. The iterator will not be valid
+     * afterwards.
+     *
+     * @param iter      iterator of item to remove. Must be valid (not end()).
+     */
+    void remove(const Iter& iter) { deleteAtNode(iter.fN); }
+
+    static void UnitTest();
+
+private:
+    enum Color {
+        kRed_Color,
+        kBlack_Color
+    };
+
+    enum Child {
+        kLeft_Child  = 0,
+        kRight_Child = 1
+    };
+
+    struct Node {
+        T       fItem;
+        Color   fColor;
+
+        Node*   fParent;
+        Node*   fChildren[2];
+    };
+
+    void rotateRight(Node* n);
+    void rotateLeft(Node* n);
+
+    static Node* SuccessorNode(Node* x);
+    static Node* PredecessorNode(Node* x);
+
+    void deleteAtNode(Node* x);
+    static void RecursiveDelete(Node* x);
+
+    int countOfHelper(const Node* n, const T& t) const;
+
+#if GR_DEBUG
+    void validate() const;
+    int checkNode(Node* n, int* blackHeight) const;
+    // checks relationship between a node and its children. allowRedRed means
+    // node may be in an intermediate state where a red parent has a red child.
+    bool validateChildRelations(const Node* n, bool allowRedRed) const;
+    // place to stick break point if validateChildRelations is failing.
+    bool validateChildRelationsFailed() const { return false; }
+#else
+    void validate() const {}
+#endif
+
+    int     fCount;
+    Node*   fRoot;
+    Node*   fFirst;
+    Node*   fLast;
+
+    const C fComp;
+};
+
+template <typename T, typename C>
+class GrRedBlackTree<T,C>::Iter {
+public:
+    Iter() {};
+    Iter(const Iter& i) {fN = i.fN; fTree = i.fTree;}
+    Iter& operator =(const Iter& i) {
+        fN = i.fN;
+        fTree = i.fTree;
+        return *this;
+    }
+    // altering the sort value of the item using this method will cause
+    // errors.
+    T& operator *() const { return fN->fItem; }
+    bool operator ==(const Iter& i) const {
+        return fN == i.fN && fTree == i.fTree;
+    }
+    bool operator !=(const Iter& i) const { return !(*this == i); }
+    Iter& operator ++() {
+        GrAssert(*this != fTree->end());
+        fN = SuccessorNode(fN);
+        return *this;
+    }
+    Iter& operator --() {
+        GrAssert(*this != fTree->begin());
+        if (NULL != fN) {
+            fN = PredecessorNode(fN);
+        } else {
+            *this = fTree->last();
+        }
+        return *this;
+    }
+
+private:
+    friend class GrRedBlackTree;
+    explicit Iter(Node* n, GrRedBlackTree* tree) {
+        fN = n;
+        fTree = tree;
+    }
+    Node* fN;
+    GrRedBlackTree* fTree;
+};
+
+template <typename T, typename C>
+GrRedBlackTree<T,C>::GrRedBlackTree() : fComp() {
+    fRoot = NULL;
+    fFirst = NULL;
+    fLast = NULL;
+    fCount = 0;
+    validate();
+}
+
+template <typename T, typename C>
+GrRedBlackTree<T,C>::~GrRedBlackTree() {
+    RecursiveDelete(fRoot);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::begin() {
+    return Iter(fFirst, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::end() {
+    return Iter(NULL, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::last() {
+    return Iter(fLast, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::find(const T& t) {
+    Node* n = fRoot;
+    while (NULL != n) {
+        if (fComp(t, n->fItem)) {
+            n = n->fChildren[kLeft_Child];
+        } else {
+            if (!fComp(n->fItem, t)) {
+                return Iter(n, this);
+            }
+            n = n->fChildren[kRight_Child];
+        }
+    }
+    return end();
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findFirst(const T& t) {
+    Node* n = fRoot;
+    Node* leftMost = NULL;
+    while (NULL != n) {
+        if (fComp(t, n->fItem)) {
+            n = n->fChildren[kLeft_Child];
+        } else {
+            if (!fComp(n->fItem, t)) {
+                // found one. check if another in left subtree.
+                leftMost = n;
+                n = n->fChildren[kLeft_Child];
+            } else {
+                n = n->fChildren[kRight_Child];
+            }
+        }
+    }
+    return Iter(leftMost, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findLast(const T& t) {
+    Node* n = fRoot;
+    Node* rightMost = NULL;
+    while (NULL != n) {
+        if (fComp(t, n->fItem)) {
+            n = n->fChildren[kLeft_Child];
+        } else {
+            if (!fComp(n->fItem, t)) {
+                // found one. check if another in right subtree.
+                rightMost = n;
+            }
+            n = n->fChildren[kRight_Child];
+        }
+    }
+    return Iter(rightMost, this);
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::countOf(const T& t) const {
+    return countOfHelper(fRoot, t);
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::countOfHelper(const Node* n, const T& t) const {
+    // this is count*log(n) :(
+    while (NULL != n) {
+        if (fComp(t, n->fItem)) {
+            n = n->fChildren[kLeft_Child];
+        } else {
+            if (!fComp(n->fItem, t)) {
+                int count = 1;
+                count += countOfHelper(n->fChildren[kLeft_Child], t);
+                count += countOfHelper(n->fChildren[kRight_Child], t);
+                return count;
+            }
+            n = n->fChildren[kRight_Child];
+        }
+    }
+    return 0;
+
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::reset() {
+    RecursiveDelete(fRoot);
+    fRoot = NULL;
+    fFirst = NULL;
+    fLast = NULL;
+    fCount = 0;
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::insert(const T& t) {
+    validate();
+
+    ++fCount;
+
+    Node* x = new Node;
+    x->fChildren[kLeft_Child] = NULL;
+    x->fChildren[kRight_Child] = NULL;
+    x->fItem = t;
+
+    Node* returnNode = x;
+
+    Node* gp = NULL;
+    Node* p = NULL;
+    Node* n = fRoot;
+    Child pc = kLeft_Child; // suppress uninit warning
+    Child gpc;
+
+    bool first = true;
+    bool last = true;
+    while (NULL != n) {
+        gpc = pc;
+        pc = fComp(x->fItem, n->fItem) ? kLeft_Child : kRight_Child;
+        first = first && kLeft_Child == pc;
+        last = last && kRight_Child == pc;
+        gp = p;
+        p = n;
+        n = p->fChildren[pc];
+    }
+    if (last) {
+        fLast = x;
+    }
+    if (first) {
+        fFirst = x;
+    }
+
+    if (NULL == p) {
+        fRoot = x;
+        x->fColor = kBlack_Color;
+        x->fParent = NULL;
+        GrAssert(1 == fCount);
+        return Iter(returnNode, this);
+    }
+    p->fChildren[pc] = x;
+    x->fColor = kRed_Color;
+    x->fParent = p;
+
+    do {
+        // assumptions at loop start.
+        GrAssert(NULL != x);
+        GrAssert(kRed_Color == x->fColor);
+        // can't have a grandparent but no parent.
+        GrAssert(!(NULL != gp && NULL == p));
+        // make sure pc and gpc are correct
+        GrAssert(NULL == p  || p->fChildren[pc] == x);
+        GrAssert(NULL == gp || gp->fChildren[gpc] == p);
+
+        // if x's parent is black then we didn't violate any of the
+        // red/black properties when we added x as red.
+        if (kBlack_Color == p->fColor) {
+            return Iter(returnNode, this);
+        }
+        // gp must be valid because if p was the root then it is black
+        GrAssert(NULL != gp);
+        // gp must be black since it's child, p, is red.
+        GrAssert(kBlack_Color == gp->fColor);
+
+
+        // x and its parent are red, violating red-black property.
+        Node* u = gp->fChildren[1-gpc];
+        // if x's uncle (p's sibling) is also red then we can flip
+        // p and u to black and make gp red. But then we have to recurse
+        // up to gp since it's parent may also be red.
+        if (NULL != u && kRed_Color == u->fColor) {
+            p->fColor = kBlack_Color;
+            u->fColor = kBlack_Color;
+            gp->fColor = kRed_Color;
+            x = gp;
+            p = x->fParent;
+            if (NULL == p) {
+                // x (prev gp) is the root, color it black and be done.
+                GrAssert(fRoot == x);
+                x->fColor = kBlack_Color;
+                validate();
+                return Iter(returnNode, this);
+            }
+            gp = p->fParent;
+            pc = (p->fChildren[kLeft_Child] == x) ? kLeft_Child :
+                                                    kRight_Child;
+            if (NULL != gp) {
+                gpc = (gp->fChildren[kLeft_Child] == p) ? kLeft_Child :
+                                                          kRight_Child;
+            }
+            continue;
+        } break;
+    } while (true);
+    // Here p is red but u is black and we still have to resolve the fact
+    // that x and p are both red.
+    GrAssert(NULL == gp->fChildren[1-gpc] || kBlack_Color == gp->fChildren[1-gpc]->fColor);
+    GrAssert(kRed_Color == x->fColor);
+    GrAssert(kRed_Color == p->fColor);
+    GrAssert(kBlack_Color == gp->fColor);
+
+    // make x be on the same side of p as p is of gp. If it isn't already
+    // the case then rotate x up to p and swap their labels.
+    if (pc != gpc) {
+        if (kRight_Child == pc) {
+            rotateLeft(p);
+            Node* temp = p;
+            p = x;
+            x = temp;
+            pc = kLeft_Child;
+        } else {
+            rotateRight(p);
+            Node* temp = p;
+            p = x;
+            x = temp;
+            pc = kRight_Child;
+        }
+    }
+    // we now rotate gp down, pulling up p to be it's new parent.
+    // gp's child, u, that is not affected we know to be black. gp's new
+    // child is p's previous child (x's pre-rotation sibling) which must be
+    // black since p is red.
+    GrAssert(NULL == p->fChildren[1-pc] ||
+             kBlack_Color == p->fChildren[1-pc]->fColor);
+    // Since gp's two children are black it can become red if p is made
+    // black. This leaves the black-height of both of p's new subtrees
+    // preserved and removes the red/red parent child relationship.
+    p->fColor = kBlack_Color;
+    gp->fColor = kRed_Color;
+    if (kLeft_Child == pc) {
+        rotateRight(gp);
+    } else {
+        rotateLeft(gp);
+    }
+    validate();
+    return Iter(returnNode, this);
+}
+
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::rotateRight(Node* n) {
+    /*            d?              d?
+     *           /               /
+     *          n               s
+     *         / \     --->    / \
+     *        s   a?          c?  n
+     *       / \                 / \
+     *      c?  b?              b?  a?
+     */
+    Node* d = n->fParent;
+    Node* s = n->fChildren[kLeft_Child];
+    GrAssert(NULL != s);
+    Node* b = s->fChildren[kRight_Child];
+
+    if (NULL != d) {
+        Child c = d->fChildren[kLeft_Child] == n ? kLeft_Child :
+                                             kRight_Child;
+        d->fChildren[c] = s;
+    } else {
+        GrAssert(fRoot == n);
+        fRoot = s;
+    }
+    s->fParent = d;
+    s->fChildren[kRight_Child] = n;
+    n->fParent = s;
+    n->fChildren[kLeft_Child] = b;
+    if (NULL != b) {
+        b->fParent = n;
+    }
+
+    GR_DEBUGASSERT(validateChildRelations(d, true));
+    GR_DEBUGASSERT(validateChildRelations(s, true));
+    GR_DEBUGASSERT(validateChildRelations(n, false));
+    GR_DEBUGASSERT(validateChildRelations(n->fChildren[kRight_Child], true));
+    GR_DEBUGASSERT(validateChildRelations(b, true));
+    GR_DEBUGASSERT(validateChildRelations(s->fChildren[kLeft_Child], true));
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::rotateLeft(Node* n) {
+
+    Node* d = n->fParent;
+    Node* s = n->fChildren[kRight_Child];
+    GrAssert(NULL != s);
+    Node* b = s->fChildren[kLeft_Child];
+
+    if (NULL != d) {
+        Child c = d->fChildren[kRight_Child] == n ? kRight_Child :
+                                                   kLeft_Child;
+        d->fChildren[c] = s;
+    } else {
+        GrAssert(fRoot == n);
+        fRoot = s;
+    }
+    s->fParent = d;
+    s->fChildren[kLeft_Child] = n;
+    n->fParent = s;
+    n->fChildren[kRight_Child] = b;
+    if (NULL != b) {
+        b->fParent = n;
+    }
+
+    GR_DEBUGASSERT(validateChildRelations(d, true));
+    GR_DEBUGASSERT(validateChildRelations(s, true));
+    GR_DEBUGASSERT(validateChildRelations(n, true));
+    GR_DEBUGASSERT(validateChildRelations(n->fChildren[kLeft_Child], true));
+    GR_DEBUGASSERT(validateChildRelations(b, true));
+    GR_DEBUGASSERT(validateChildRelations(s->fChildren[kRight_Child], true));
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::SuccessorNode(Node* x) {
+    GrAssert(NULL != x);
+    if (NULL != x->fChildren[kRight_Child]) {
+        x = x->fChildren[kRight_Child];
+        while (NULL != x->fChildren[kLeft_Child]) {
+            x = x->fChildren[kLeft_Child];
+        }
+        return x;
+    }
+    while (NULL != x->fParent && x == x->fParent->fChildren[kRight_Child]) {
+        x = x->fParent;
+    }
+    return x->fParent;
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::PredecessorNode(Node* x) {
+    GrAssert(NULL != x);
+    if (NULL != x->fChildren[kLeft_Child]) {
+        x = x->fChildren[kLeft_Child];
+        while (NULL != x->fChildren[kRight_Child]) {
+            x = x->fChildren[kRight_Child];
+        }
+        return x;
+    }
+    while (NULL != x->fParent && x == x->fParent->fChildren[kLeft_Child]) {
+        x = x->fParent;
+    }
+    return x->fParent;
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::deleteAtNode(Node* x) {
+    GrAssert(NULL != x);
+    validate();
+    --fCount;
+
+    bool hasLeft =  NULL != x->fChildren[kLeft_Child];
+    bool hasRight = NULL != x->fChildren[kRight_Child];
+    Child c = hasLeft ? kLeft_Child : kRight_Child;
+
+    if (hasLeft && hasRight) {
+        // first and last can't have two children.
+        GrAssert(fFirst != x);
+        GrAssert(fLast != x);
+        // if x is an interior node then we find it's successor
+        // and swap them.
+        Node* s = x->fChildren[kRight_Child];
+        while (NULL != s->fChildren[kLeft_Child]) {
+            s = s->fChildren[kLeft_Child];
+        }
+        GrAssert(NULL != s);
+        // this might be expensive relative to swapping node ptrs around.
+        // depends on T.
+        x->fItem = s->fItem;
+        x = s;
+        c = kRight_Child;
+    } else if (NULL == x->fParent) {
+        // if x was the root we just replace it with its child and make
+        // the new root (if the tree is not empty) black.
+        GrAssert(fRoot == x);
+        fRoot = x->fChildren[c];
+        if (NULL != fRoot) {
+            fRoot->fParent = NULL;
+            fRoot->fColor = kBlack_Color;
+            if (x == fLast) {
+                GrAssert(c == kLeft_Child);
+                fLast = fRoot;
+            } else if (x == fFirst) {
+                GrAssert(c == kRight_Child);
+                fFirst = fRoot;
+            }
+        } else {
+            GrAssert(fFirst == fLast && x == fFirst);
+            fFirst = NULL;
+            fLast = NULL;
+            GrAssert(0 == fCount);
+        }
+        delete x;
+        validate();
+        return;
+    }
+
+    Child pc;
+    Node* p = x->fParent;
+    pc = p->fChildren[kLeft_Child] == x ? kLeft_Child : kRight_Child;
+
+    if (NULL == x->fChildren[c]) {
+        if (fLast == x) {
+            fLast = p;
+            GrAssert(p == PredecessorNode(x));
+        } else if (fFirst == x) {
+            fFirst = p;
+            GrAssert(p == SuccessorNode(x));
+        }
+        // x has two implicit black children.
+        Color xcolor = x->fColor;
+        p->fChildren[pc] = NULL;
+        delete x;
+        x = NULL;
+        // when x is red it can be with an implicit black leaf without
+        // violating any of the red-black tree properties.
+        if (kRed_Color == xcolor) {
+            validate();
+            return;
+        }
+        // s is p's other child (x's sibling)
+        Node* s = p->fChildren[1-pc];
+
+        //s cannot be an implicit black node because the original
+        // black-height at x was >= 2 and s's black-height must equal the
+        // initial black height of x.
+        GrAssert(NULL != s);
+        GrAssert(p == s->fParent);
+
+        // assigned in loop
+        Node* sl;
+        Node* sr;
+        bool slRed;
+        bool srRed;
+
+        do {
+            // When we start this loop x may already be deleted it is/was
+            // p's child on its pc side. x's children are/were black. The
+            // first time through the loop they are implict children.
+            // On later passes we will be walking up the tree and they will
+            // be real nodes.
+            // The x side of p has a black-height that is one less than the
+            // s side. It must be rebalanced.
+            GrAssert(NULL != s);
+            GrAssert(p == s->fParent);
+            GrAssert(NULL == x || x->fParent == p);
+
+            //sl and sr are s's children, which may be implicit.
+            sl = s->fChildren[kLeft_Child];
+            sr = s->fChildren[kRight_Child];
+
+            // if the s is red we will rotate s and p, swap their colors so
+            // that x's new sibling is black
+            if (kRed_Color == s->fColor) {
+                // if s is red then it's parent must be black.
+                GrAssert(kBlack_Color == p->fColor);
+                // s's children must also be black since s is red. They can't
+                // be implicit since s is red and it's black-height is >= 2.
+                GrAssert(NULL != sl && kBlack_Color == sl->fColor);
+                GrAssert(NULL != sr && kBlack_Color == sr->fColor);
+                p->fColor = kRed_Color;
+                s->fColor = kBlack_Color;
+                if (kLeft_Child == pc) {
+                    rotateLeft(p);
+                    s = sl;
+                } else {
+                    rotateRight(p);
+                    s = sr;
+                }
+                sl = s->fChildren[kLeft_Child];
+                sr = s->fChildren[kRight_Child];
+            }
+            // x and s are now both black.
+            GrAssert(kBlack_Color == s->fColor);
+            GrAssert(NULL == x || kBlack_Color == x->fColor);
+            GrAssert(p == s->fParent);
+            GrAssert(NULL == x || p == x->fParent);
+
+            // when x is deleted its subtree will have reduced black-height.
+            slRed = (NULL != sl && kRed_Color == sl->fColor);
+            srRed = (NULL != sr && kRed_Color == sr->fColor);
+            if (!slRed && !srRed) {
+                // if s can be made red that will balance out x's removal
+                // to make both subtrees of p have the same black-height.
+                if (kBlack_Color == p->fColor) {
+                    s->fColor = kRed_Color;
+                    // now subtree at p has black-height of one less than
+                    // p's parent's other child's subtree. We move x up to
+                    // p and go through the loop again. At the top of loop
+                    // we assumed x and x's children are black, which holds
+                    // by above ifs.
+                    // if p is the root there is no other subtree to balance
+                    // against.
+                    x = p;
+                    p = x->fParent;
+                    if (NULL == p) {
+                        GrAssert(fRoot == x);
+                        validate();
+                        return;
+                    } else {
+                        pc = p->fChildren[kLeft_Child] == x ? kLeft_Child :
+                                                              kRight_Child;
+
+                    }
+                    s = p->fChildren[1-pc];
+                    GrAssert(NULL != s);
+                    GrAssert(p == s->fParent);
+                    continue;
+                } else if (kRed_Color == p->fColor) {
+                    // we can make p black and s red. This balance out p's
+                    // two subtrees and keep the same black-height as it was
+                    // before the delete.
+                    s->fColor = kRed_Color;
+                    p->fColor = kBlack_Color;
+                    validate();
+                    return;
+                }
+            }
+            break;
+        } while (true);
+        // if we made it here one or both of sl and sr is red.
+        // s and x are black. We make sure that a red child is on
+        // the same side of s as s is of p.
+        GrAssert(slRed || srRed);
+        if (kLeft_Child == pc && !srRed) {
+            s->fColor = kRed_Color;
+            sl->fColor = kBlack_Color;
+            rotateRight(s);
+            sr = s;
+            s = sl;
+            //sl = s->fChildren[kLeft_Child]; don't need this
+        } else if (kRight_Child == pc && !slRed) {
+            s->fColor = kRed_Color;
+            sr->fColor = kBlack_Color;
+            rotateLeft(s);
+            sl = s;
+            s = sr;
+            //sr = s->fChildren[kRight_Child]; don't need this
+        }
+        // now p is either red or black, x and s are red and s's 1-pc
+        // child is red.
+        // We rotate p towards x, pulling s up to replace p. We make
+        // p be black and s takes p's old color.
+        // Whether p was red or black, we've increased its pc subtree
+        // rooted at x by 1 (balancing the imbalance at the start) and
+        // we've also its subtree rooted at s's black-height by 1. This
+        // can be balanced by making s's red child be black.
+        s->fColor = p->fColor;
+        p->fColor = kBlack_Color;
+        if (kLeft_Child == pc) {
+            GrAssert(NULL != sr && kRed_Color == sr->fColor);
+            sr->fColor = kBlack_Color;
+            rotateLeft(p);
+        } else {
+            GrAssert(NULL != sl && kRed_Color == sl->fColor);
+            sl->fColor = kBlack_Color;
+            rotateRight(p);
+        }
+    }
+    else {
+        // x has exactly one implicit black child. x cannot be red.
+        // Proof by contradiction: Assume X is red. Let c0 be x's implicit
+        // child and c1 be its non-implicit child. c1 must be black because
+        // red nodes always have two black children. Then the two subtrees
+        // of x rooted at c0 and c1 will have different black-heights.
+        GrAssert(kBlack_Color == x->fColor);
+        // So we know x is black and has one implicit black child, c0. c1
+        // must be red, otherwise the subtree at c1 will have a different
+        // black-height than the subtree rooted at c0.
+        GrAssert(kRed_Color == x->fChildren[c]->fColor);
+        // replace x with c1, making c1 black, preserves all red-black tree
+        // props.
+        Node* c1 = x->fChildren[c];
+        if (x == fFirst) {
+            GrAssert(c == kRight_Child);
+            fFirst = c1;
+            while (NULL != fFirst->fChildren[kLeft_Child]) {
+                fFirst = fFirst->fChildren[kLeft_Child];
+            }
+            GrAssert(fFirst == SuccessorNode(x));
+        } else if (x == fLast) {
+            GrAssert(c == kLeft_Child);
+            fLast = c1;
+            while (NULL != fLast->fChildren[kRight_Child]) {
+                fLast = fLast->fChildren[kRight_Child];
+            }
+            GrAssert(fLast == PredecessorNode(x));
+        }
+        c1->fParent = p;
+        p->fChildren[pc] = c1;
+        c1->fColor = kBlack_Color;
+        delete x;
+        validate();
+    }
+    validate();
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::RecursiveDelete(Node* x) {
+    if (NULL != x) {
+        RecursiveDelete(x->fChildren[kLeft_Child]);
+        RecursiveDelete(x->fChildren[kRight_Child]);
+        delete x;
+    }
+}
+
+#if GR_DEBUG
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::validate() const {
+    if (fCount) {
+        GrAssert(NULL == fRoot->fParent);
+        GrAssert(NULL != fFirst);
+        GrAssert(NULL != fLast);
+
+        GrAssert(kBlack_Color == fRoot->fColor);
+        if (1 == fCount) {
+            GrAssert(fFirst == fRoot);
+            GrAssert(fLast == fRoot);
+            GrAssert(0 == fRoot->fChildren[kLeft_Child]);
+            GrAssert(0 == fRoot->fChildren[kRight_Child]);
+        }
+    } else {
+        GrAssert(NULL == fRoot);
+        GrAssert(NULL == fFirst);
+        GrAssert(NULL == fLast);
+    }
+#if DEEP_VALIDATE
+    int bh;
+    int count = checkNode(fRoot, &bh);
+    GrAssert(count == fCount);
+#endif
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::checkNode(Node* n, int* bh) const {
+    if (NULL != n) {
+        GrAssert(validateChildRelations(n, false));
+        if (kBlack_Color == n->fColor) {
+            *bh += 1;
+        }
+        GrAssert(!fComp(n->fItem, fFirst->fItem));
+        GrAssert(!fComp(fLast->fItem, n->fItem));
+        int leftBh = *bh;
+        int rightBh = *bh;
+        int cl = checkNode(n->fChildren[kLeft_Child], &leftBh);
+        int cr = checkNode(n->fChildren[kRight_Child], &rightBh);
+        GrAssert(leftBh == rightBh);
+        *bh = leftBh;
+        return 1 + cl + cr;
+    }
+    return 0;
+}
+
+template <typename T, typename C>
+bool GrRedBlackTree<T,C>::validateChildRelations(const Node* n,
+                                                 bool allowRedRed) const {
+    if (NULL != n) {
+        if (NULL != n->fChildren[kLeft_Child] ||
+            NULL != n->fChildren[kRight_Child]) {
+            if (n->fChildren[kLeft_Child] == n->fChildren[kRight_Child]) {
+                return validateChildRelationsFailed();
+            }
+            if (n->fChildren[kLeft_Child] == n->fParent &&
+                NULL != n->fParent) {
+                return validateChildRelationsFailed();
+            }
+            if (n->fChildren[kRight_Child] == n->fParent &&
+                NULL != n->fParent) {
+                return validateChildRelationsFailed();
+            }
+            if (NULL != n->fChildren[kLeft_Child]) {
+                if (!allowRedRed &&
+                    kRed_Color == n->fChildren[kLeft_Child]->fColor &&
+                    kRed_Color == n->fColor) {
+                    return validateChildRelationsFailed();
+                }
+                if (n->fChildren[kLeft_Child]->fParent != n) {
+                    return validateChildRelationsFailed();
+                }
+                if (!(fComp(n->fChildren[kLeft_Child]->fItem, n->fItem) ||
+                      (!fComp(n->fChildren[kLeft_Child]->fItem, n->fItem) &&
+                       !fComp(n->fItem, n->fChildren[kLeft_Child]->fItem)))) {
+                    return validateChildRelationsFailed();
+                }
+            }
+            if (NULL != n->fChildren[kRight_Child]) {
+                if (!allowRedRed &&
+                    kRed_Color == n->fChildren[kRight_Child]->fColor &&
+                    kRed_Color == n->fColor) {
+                    return validateChildRelationsFailed();
+                }
+                if (n->fChildren[kRight_Child]->fParent != n) {
+                    return validateChildRelationsFailed();
+                }
+                if (!(fComp(n->fItem, n->fChildren[kRight_Child]->fItem) ||
+                      (!fComp(n->fChildren[kRight_Child]->fItem, n->fItem) &&
+                       !fComp(n->fItem, n->fChildren[kRight_Child]->fItem)))) {
+                    return validateChildRelationsFailed();
+                }
+            }
+        }
+    }
+    return true;
+}
+#endif
+
+#include "GrRandom.h"
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::UnitTest() {
+    GrRedBlackTree<int> tree;
+    typedef GrRedBlackTree<int>::Iter iter;
+
+    GrRandom r;
+
+    int count[100] = {0};
+    // add 10K ints
+    for (int i = 0; i < 10000; ++i) {
+        int x = r.nextU()%100;
+        Iter xi = tree.insert(x);
+        GrAssert(*xi == x);
+        ++count[x];
+    }
+
+    tree.insert(0);
+    ++count[0];
+    tree.insert(99);
+    ++count[99];
+    GrAssert(*tree.begin() == 0);
+    GrAssert(*tree.last() == 99);
+    GrAssert(--(++tree.begin()) == tree.begin());
+    GrAssert(--tree.end() == tree.last());
+    GrAssert(tree.count() == 10002);
+
+    int c = 0;
+    // check that we iterate through the correct number of
+    // elements and they are properly sorted.
+    for (Iter a = tree.begin(); tree.end() != a; ++a) {
+        Iter b = a;
+        ++b;
+        ++c;
+        GrAssert(b == tree.end() || *a <= *b);
+    }
+    GrAssert(c == tree.count());
+
+    // check that the tree reports the correct number of each int
+    // and that we can iterate through them correctly both forward
+    // and backward.
+    for (int i = 0; i < 100; ++i) {
+        int c;
+        c = tree.countOf(i);
+        GrAssert(c == count[i]);
+        c = 0;
+        Iter iter = tree.findFirst(i);
+        while (iter != tree.end() && *iter == i) {
+            ++c;
+            ++iter;
+        }
+        GrAssert(count[i] == c);
+        c = 0;
+        iter = tree.findLast(i);
+        if (iter != tree.end()) {
+            do {
+                if (*iter == i) {
+                    ++c;
+                } else {
+                    break;
+                }
+                if (iter != tree.begin()) {
+                    --iter;
+                } else {
+                    break;
+                }
+            } while (true);
+        }
+        GrAssert(c == count[i]);
+    }
+    // remove all the ints between 25 and 74. Randomly chose to remove
+    // the first, last, or any entry for each.
+    for (int i = 25; i < 75; ++i) {
+        while (0 != tree.countOf(i)) {
+            --count[i];
+            int x = r.nextU() % 3;
+            Iter iter;
+            switch (x) {
+            case 0:
+                iter = tree.findFirst(i);
+                break;
+            case 1:
+                iter = tree.findLast(i);
+                break;
+            case 2:
+            default:
+                iter = tree.find(i);
+                break;
+            }
+            tree.remove(iter);
+        }
+        GrAssert(0 == count[i]);
+        GrAssert(tree.findFirst(i) == tree.end());
+        GrAssert(tree.findLast(i) == tree.end());
+        GrAssert(tree.find(i) == tree.end());
+    }
+    // remove all of the 0 entries. (tests removing begin())
+    GrAssert(*tree.begin() == 0);
+    GrAssert(*(--tree.end()) == 99);
+    while (0 != tree.countOf(0)) {
+        --count[0];
+        tree.remove(tree.find(0));
+    }
+    GrAssert(0 == count[0]);
+    GrAssert(tree.findFirst(0) == tree.end());
+    GrAssert(tree.findLast(0) == tree.end());
+    GrAssert(tree.find(0) == tree.end());
+    GrAssert(0 < *tree.begin());
+
+    // remove all the 99 entries (tests removing last()).
+    while (0 != tree.countOf(99)) {
+        --count[99];
+        tree.remove(tree.find(99));
+    }
+    GrAssert(0 == count[99]);
+    GrAssert(tree.findFirst(99) == tree.end());
+    GrAssert(tree.findLast(99) == tree.end());
+    GrAssert(tree.find(99) == tree.end());
+    GrAssert(99 > *(--tree.end()));
+    GrAssert(tree.last() == --tree.end());
+
+    // Make sure iteration still goes through correct number of entries
+    // and is still sorted correctly.
+    c = 0;
+    for (Iter a = tree.begin(); tree.end() != a; ++a) {
+        Iter b = a;
+        ++b;
+        ++c;
+        GrAssert(b == tree.end() || *a <= *b);
+    }
+    GrAssert(c == tree.count());
+
+    // repeat check that correct number of each entry is in the tree
+    // and iterates correctly both forward and backward.
+    for (int i = 0; i < 100; ++i) {
+        GrAssert(tree.countOf(i) == count[i]);
+        int c = 0;
+        Iter iter = tree.findFirst(i);
+        while (iter != tree.end() && *iter == i) {
+            ++c;
+            ++iter;
+        }
+        GrAssert(count[i] == c);
+        c = 0;
+        iter = tree.findLast(i);
+        if (iter != tree.end()) {
+            do {
+                if (*iter == i) {
+                    ++c;
+                } else {
+                    break;
+                }
+                if (iter != tree.begin()) {
+                    --iter;
+                } else {
+                    break;
+                }
+            } while (true);
+        }
+        GrAssert(count[i] == c);
+    }
+
+    // remove all entries
+    while (!tree.empty()) {
+        tree.remove(tree.begin());
+    }
+
+    // test reset on empty tree.
+    tree.reset();
+}
+
+#endif
diff --git a/gpu/src/GrStencil.cpp b/gpu/src/GrStencil.cpp
new file mode 100644
index 0000000..a1c8c09
--- /dev/null
+++ b/gpu/src/GrStencil.cpp
@@ -0,0 +1,376 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrStencil.h"
+
+const GrStencilSettings GrStencilSettings::gDisabled = {};
+GR_STATIC_ASSERT(0 == kKeep_StencilOp);
+GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
+
+////////////////////////////////////////////////////////////////////////////////
+// Stencil Rules for Merging user stencil space into clip
+
+// We can't include the clip bit in the ref or mask values because the division
+// between user and clip bits in the stencil depends on the number of stencil
+// bits in the runtime. Comments below indicate what the code should do to
+// incorporate the clip bit into these settings.
+
+///////
+// Replace
+
+// set the ref to be the clip bit, but mask it out for the test
+static const GrStencilSettings gUserToClipReplace = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+static const GrStencilSettings gInvUserToClipReplace = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kEqual_StencilFunc,  kEqual_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+///////
+// Intersect
+static const GrStencilSettings gUserToClipIsect = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+static const GrStencilSettings gInvUserToClipIsect = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kEqual_StencilFunc,  kEqual_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+///////
+// Difference
+static const GrStencilSettings gUserToClipDiff = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kEqual_StencilFunc,  kEqual_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+static const GrStencilSettings gInvUserToClipDiff = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x0,                 0x0,           // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+///////
+// Union
+
+// first pass makes all the passing cases >= just clip bit set.
+static const GrStencilSettings gUserToClipUnionPass0 = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kKeep_StencilOp,     kKeep_StencilOp,
+    kLEqual_StencilFunc, kLEqual_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x00000001,          0x00000001,    // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+// second pass allows anything greater than just clip bit set to pass
+static const GrStencilSettings gUserToClipUnionPass1 = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLEqual_StencilFunc, kLEqual_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,    // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+// for inverse first pass finds non-zerp user with clip bit set
+// and converts it to just clip bit set
+static const GrStencilSettings gInvUserToClipUnionPass0 = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kKeep_StencilOp,     kKeep_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,    // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+// second pass lets anything through with a nonzero user portion
+// and writes a ref value with just the clip bit set to it.
+static const GrStencilSettings gInvUserToClipUnionPass1 = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x00000000,          0x00000000,    // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+///////
+// Xor
+static const GrStencilSettings gUserToClipXorPass0 = {
+    kInvert_StencilOp,   kInvert_StencilOp,
+    kKeep_StencilOp,     kKeep_StencilOp,
+    kEqual_StencilFunc,  kEqual_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x00000000,          0x00000000,
+    0xffffffff,          0xffffffff
+};
+
+static const GrStencilSettings gUserToClipXorPass1 = {
+    kReplace_StencilOp,   kReplace_StencilOp,
+    kZero_StencilOp,      kZero_StencilOp,
+    kGreater_StencilFunc, kGreater_StencilFunc,
+    0xffffffff,           0xffffffff,
+    0x00000000,           0x00000000,   // set clip bit
+    0xffffffff,           0xffffffff
+};
+
+static const GrStencilSettings gInvUserToClipXorPass0 = {
+    kInvert_StencilOp,   kInvert_StencilOp,
+    kKeep_StencilOp,     kKeep_StencilOp,
+    kEqual_StencilFunc,  kEqual_StencilFunc,
+    0xffffffff,          0xffffffff,    // unset clip bit
+    0x00000000,          0x00000000,
+    0xffffffff,          0xffffffff
+};
+
+static const GrStencilSettings gInvUserToClipXorPass1 = {
+    kReplace_StencilOp,   kReplace_StencilOp,
+    kZero_StencilOp,      kZero_StencilOp,
+    kLess_StencilFunc,    kLess_StencilFunc,
+    0xffffffff,           0xffffffff,
+    0x00000000,           0x00000000,   // set clip bit
+    0xffffffff,           0xffffffff
+};
+
+///////
+// Reverse Diff
+static const GrStencilSettings gUserToClipRDiffPass0 = {
+    kInvert_StencilOp,   kInvert_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kLess_StencilFunc,   kLess_StencilFunc,
+    0xffffffff,          0xffffffff,  // unset clip bit
+    0x00000000,          0x00000000,  // set clip bit
+    0xffffffff,          0xffffffff
+};
+
+static const GrStencilSettings gUserToClipRDiffPass1 = {
+    kReplace_StencilOp,   kReplace_StencilOp,
+    kZero_StencilOp,      kZero_StencilOp,
+    kEqual_StencilFunc,   kEqual_StencilFunc,
+    0x00000000,           0x00000000,   // set clip bit
+    0x00000000,           0x00000000,   // set clip bit
+    0xffffffff,           0xffffffff
+};
+
+static const GrStencilSettings gInvUserToClipRDiff = {
+    kInvert_StencilOp,    kInvert_StencilOp,
+    kZero_StencilOp,      kZero_StencilOp,
+    kEqual_StencilFunc,   kEqual_StencilFunc,
+    0xffffffff,           0xffffffff,
+    0x00000000,           0x00000000, 
+    0x00000000,           0x00000000    // set clip bit
+};
+///////
+// Direct to Stencil
+
+// We can render a clip element directly without first writing to the client
+// portion of the clip when the fill is not inverse and the set operation will
+// only modify the in/out status of samples covered by the clip element.
+
+// this one only works if used right after stencil clip was cleared.
+// Our GrClip doesn't allow midstream replace ops.
+static const GrStencilSettings gReplaceClip = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kAlways_StencilFunc, kAlways_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,    // set clip bit
+    0x00000000,          0x00000000     // set clipBit
+};
+
+static const GrStencilSettings gUnionClip = {
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kReplace_StencilOp,  kReplace_StencilOp,
+    kAlways_StencilFunc, kAlways_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,    // set clip bit
+    0x00000000,          0x00000000     // set clip bit
+};
+
+static const GrStencilSettings gXorClip = {
+    kInvert_StencilOp,   kInvert_StencilOp,
+    kInvert_StencilOp,   kInvert_StencilOp,
+    kAlways_StencilFunc, kAlways_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,
+    0x00000000,          0x00000000     // set clip bit
+};
+
+static const GrStencilSettings gDiffClip = {
+    kZero_StencilOp,     kZero_StencilOp,
+    kZero_StencilOp,     kZero_StencilOp,
+    kAlways_StencilFunc, kAlways_StencilFunc,
+    0xffffffff,          0xffffffff,
+    0x00000000,          0x00000000,
+    0x00000000,          0x00000000     // set clip bit
+};
+
+bool GrStencilSettings::GetClipPasses(GrSetOp op, 
+                                      bool canBeDirect,
+                                      unsigned int stencilClipMask,
+                                      bool invertedFill,
+                                      int* numPasses,
+                                      GrStencilSettings settings[kMaxStencilClipPasses]) {
+    if (canBeDirect) {
+        *numPasses = 0;
+        switch (op) {
+            case kReplace_SetOp:
+                *numPasses = 1;
+                settings[0] = gReplaceClip;
+                break;
+            case kUnion_SetOp:
+                *numPasses = 1;
+                settings[0] = gUnionClip;
+                break;
+            case kXor_SetOp:
+                *numPasses = 1;
+                settings[0] = gXorClip;
+                break;
+            case kDifference_SetOp:
+                *numPasses = 1;
+                settings[0] = gDiffClip;
+                break;
+            default: // suppress warning
+                break;
+        }
+        if (1 == *numPasses) {
+            settings[0].fFrontFuncRef |= stencilClipMask;
+            settings[0].fFrontWriteMask |= stencilClipMask;
+            settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+            settings[0].fBackWriteMask = settings[0].fFrontWriteMask;
+            return true;
+        }
+    }
+    switch (op) {
+        // if we make the path renderer go to stencil we always give it a
+        // non-inverted fill and we use the stencil rules on the client->clipbit
+        // pass to select either the zeros or nonzeros.
+        case kReplace_SetOp:
+            *numPasses= 1;
+            settings[0] = invertedFill ? gInvUserToClipReplace : gUserToClipReplace;
+            settings[0].fFrontFuncMask &= ~stencilClipMask;
+            settings[0].fFrontFuncRef |= stencilClipMask;
+            settings[0].fBackFuncMask = settings[0].fFrontFuncMask;
+            settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+            break;
+        case kIntersect_SetOp:
+            *numPasses = 1;
+            settings[0] = invertedFill ? gInvUserToClipIsect : gUserToClipIsect;
+            settings[0].fFrontFuncRef = stencilClipMask;
+            settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+            break;
+        case kUnion_SetOp:
+            *numPasses = 2;
+            if (invertedFill) {
+                settings[0] = gInvUserToClipUnionPass0;
+                settings[0].fFrontFuncRef |= stencilClipMask;
+                settings[0].fBackFuncRef = settings[0].fFrontFuncMask;
+
+                settings[1] = gInvUserToClipUnionPass1;
+                settings[1].fFrontFuncMask &= ~stencilClipMask;
+                settings[1].fFrontFuncRef |= stencilClipMask;
+                settings[1].fBackFuncMask = settings[1].fFrontFuncMask;
+                settings[1].fBackFuncRef = settings[1].fFrontFuncRef;
+
+            } else {
+                settings[0] = gUserToClipUnionPass0;
+                settings[0].fFrontFuncMask &= ~stencilClipMask;
+                settings[0].fFrontFuncRef |= stencilClipMask;
+                settings[0].fBackFuncMask = settings[0].fFrontFuncMask;
+                settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+
+                settings[1] = gUserToClipUnionPass1;
+                settings[1].fFrontFuncRef |= stencilClipMask;
+                settings[1].fBackFuncRef = settings[1].fFrontFuncRef;
+            }
+            break;
+        case kXor_SetOp:
+            *numPasses = 2;
+            if (invertedFill) {
+                settings[0] = gInvUserToClipXorPass0;
+                settings[0].fFrontFuncMask &= ~stencilClipMask;
+                settings[0].fBackFuncMask = settings[0].fFrontFuncMask;
+
+                settings[1] = gInvUserToClipXorPass1;
+                settings[1].fFrontFuncRef |= stencilClipMask;
+                settings[1].fBackFuncRef = settings[1].fFrontFuncRef;
+            } else {
+                settings[0] = gUserToClipXorPass0;
+                settings[0].fFrontFuncMask &= ~stencilClipMask;
+                settings[0].fBackFuncMask = settings[0].fFrontFuncMask;
+
+                settings[1] = gUserToClipXorPass1;
+                settings[1].fFrontFuncRef |= stencilClipMask;
+                settings[1].fBackFuncRef = settings[1].fFrontFuncRef;
+            }
+            break;
+        case kDifference_SetOp:
+            *numPasses = 1;
+            settings[0] = invertedFill ? gInvUserToClipDiff : gUserToClipDiff;
+            settings[0].fFrontFuncRef |= stencilClipMask;
+            settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+            break;
+        case kReverseDifference_SetOp:
+            if (invertedFill) {
+                *numPasses = 1;
+                settings[0] = gInvUserToClipRDiff;
+                settings[0].fFrontWriteMask |= stencilClipMask;
+                settings[0].fBackWriteMask = settings[0].fFrontWriteMask;
+            } else {
+                *numPasses = 2;
+                settings[0] = gUserToClipRDiffPass0;
+                settings[0].fFrontFuncMask &= ~stencilClipMask;
+                settings[0].fBackFuncMask = settings[0].fFrontFuncMask;
+                settings[0].fFrontFuncRef |= stencilClipMask;
+                settings[0].fBackFuncRef = settings[0].fFrontFuncRef;
+
+                settings[1] = gUserToClipRDiffPass1;
+                settings[1].fFrontFuncMask |= stencilClipMask;
+                settings[1].fFrontFuncRef |= stencilClipMask;
+                settings[1].fBackFuncMask = settings[1].fFrontFuncMask;
+                settings[1].fBackFuncRef = settings[1].fFrontFuncRef;
+            }
+            break;
+        default:
+            GrCrash("Unknown set op");
+    }
+    return false;
+}
\ No newline at end of file
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
new file mode 100644
index 0000000..2230af2
--- /dev/null
+++ b/gpu/src/GrTextContext.cpp
@@ -0,0 +1,286 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTextContext.h"
+#include "GrAtlas.h"
+#include "GrContext.h"
+#include "GrTextStrike.h"
+#include "GrTextStrike_impl.h"
+#include "GrFontScaler.h"
+#include "GrIndexBuffer.h"
+#include "GrGpuVertex.h"
+#include "GrDrawTarget.h"
+
+static const int TEXT_STAGE = 1;
+
+static const GrVertexLayout BASE_VLAYOUT =
+                    GrDrawTarget::kTextFormat_VertexLayoutBit |
+                    GrDrawTarget::StageTexCoordVertexLayoutBit(TEXT_STAGE,0);
+
+void GrTextContext::flushGlyphs() {
+    if (fCurrVertex > 0) {
+        GrDrawTarget::AutoStateRestore asr(fDrawTarget);
+
+        // setup our sampler state for our text texture/atlas
+
+        GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
+                               GrSamplerState::kRepeat_WrapMode,
+                               !fExtMatrix.isIdentity());
+        fDrawTarget->setSamplerState(TEXT_STAGE, sampler);
+
+        GrAssert(GrIsALIGN4(fCurrVertex));
+        int nIndices = fCurrVertex + (fCurrVertex >> 1);
+        GrAssert(fCurrTexture);
+        fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture);
+
+        if (!GrTexture::PixelConfigIsAlphaOnly(fCurrTexture->config())) {
+            if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
+                kISA_BlendCoeff != fPaint.fDstBlendCoeff ||
+                NULL != fPaint.getTexture()) {
+                GrPrintf("LCD Text will not draw correctly.\n");
+            }
+            // setup blend so that we get mask * paintColor + (1-mask)*dstColor
+            fDrawTarget->setBlendConstant(fPaint.fColor);
+            fDrawTarget->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
+            // don't modulate by the paint's color in the frag since we're
+            // already doing it via the blend const.
+            fDrawTarget->setColor(0xffffffff);
+        } else {
+            // set back to normal in case we took LCD path previously.
+            fDrawTarget->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
+            fDrawTarget->setColor(fPaint.fColor);
+        }
+
+        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
+
+        fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
+                                 0, 0, fCurrVertex, nIndices);
+        fDrawTarget->releaseReservedGeometry();
+        fVertices = NULL;
+        fMaxVertices = 0;
+        fCurrVertex = 0;
+        fCurrTexture->unref();
+        fCurrTexture = NULL;
+    }
+}
+
+GrTextContext::GrTextContext(GrContext* context,
+                             const GrPaint& paint,
+                             const GrMatrix* extMatrix) : fPaint(paint) {
+    fContext = context;
+    fStrike = NULL;
+
+    fCurrTexture = NULL;
+    fCurrVertex = 0;
+
+    if (NULL != extMatrix) {
+        fExtMatrix = *extMatrix;
+    } else {
+        fExtMatrix = GrMatrix::I();
+    }
+    if (context->getClip().hasConservativeBounds()) {
+        if (!fExtMatrix.isIdentity()) {
+            GrMatrix inverse;
+            GrRect r = context->getClip().getConservativeBounds();
+            if (fExtMatrix.invert(&inverse)) {
+                inverse.mapRect(&r);
+                r.roundOut(&fClipRect);
+            }
+        } else {
+            context->getClip().getConservativeBounds().roundOut(&fClipRect);
+        }
+    } else {
+        fClipRect.setLargest();
+    }
+
+    // save the context's original matrix off and restore in destructor
+    // this must be done before getTextTarget.
+    fOrigViewMatrix = fContext->getMatrix();
+    fContext->setMatrix(fExtMatrix);
+
+    fVertexLayout = BASE_VLAYOUT;
+    if (NULL != paint.getTexture()) {
+        fVertexLayout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        GrMatrix inverseViewMatrix;
+        if (fOrigViewMatrix.invert(&inverseViewMatrix)) {
+            fPaint.fSampler.preConcatMatrix(inverseViewMatrix);
+        }
+    }
+
+    fVertices = NULL;
+    fMaxVertices = 0;
+    fDrawTarget = fContext->getTextTarget(fPaint);
+}
+
+GrTextContext::~GrTextContext() {
+    this->flushGlyphs();
+    fContext->setMatrix(fOrigViewMatrix);
+}
+
+void GrTextContext::flush() {
+    this->flushGlyphs();
+}
+
+static inline void setRectFan(GrGpuTextVertex v[4], int l, int t, int r, int b,
+                              int stride) {
+    v[0 * stride].setI(l, t);
+    v[1 * stride].setI(l, b);
+    v[2 * stride].setI(r, b);
+    v[3 * stride].setI(r, t);
+}
+
+void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
+                                    GrFixed vx, GrFixed vy,
+                                    GrFontScaler* scaler) {
+    if (NULL == fStrike) {
+        fStrike = fContext->getFontCache()->getStrike(scaler);
+    }
+
+    GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
+    if (NULL == glyph || glyph->fBounds.isEmpty()) {
+        return;
+    }
+
+    vx += GrIntToFixed(glyph->fBounds.fLeft);
+    vy += GrIntToFixed(glyph->fBounds.fTop);
+
+    // keep them as ints until we've done the clip-test
+    GrFixed width = glyph->fBounds.width();
+    GrFixed height = glyph->fBounds.height();
+
+    // check if we clipped out
+    if (true || NULL == glyph->fAtlas) {
+        int x = vx >> 16;
+        int y = vy >> 16;
+        if (fClipRect.quickReject(x, y, x + width, y + height)) {
+//            Gr_clz(3);    // so we can set a break-point in the debugger
+            return;
+        }
+    }
+
+    if (NULL == glyph->fAtlas) {
+        if (fStrike->getGlyphAtlas(glyph, scaler)) {
+            goto HAS_ATLAS;
+        }
+        // must do this to flush inorder buffering before we purge
+        fContext->flushText();
+
+        // try to purge
+        fContext->getFontCache()->purgeExceptFor(fStrike);
+        if (fStrike->getGlyphAtlas(glyph, scaler)) {
+            goto HAS_ATLAS;
+        }
+
+        // Draw as a path, so we flush any accumulated glyphs first
+        this->flushGlyphs();
+
+        if (NULL == glyph->fPath) {
+
+            GrPath* path = new GrPath;
+            if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
+                // flag the glyph as being dead?
+                delete path;
+                return;
+            }
+            glyph->fPath = path;
+        }
+        GrPath::Iter iter(*glyph->fPath);
+        GrPoint translate;
+        translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)),
+                      GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop)));
+        fContext->drawPath(fPaint, &iter, kWinding_PathFill,
+                           &translate);
+        return;
+    }
+
+HAS_ATLAS:
+    GrAssert(glyph->fAtlas);
+
+    // now promote them to fixed
+    width = GrIntToFixed(width);
+    height = GrIntToFixed(height);
+
+    GrTexture* texture = glyph->fAtlas->texture();
+    GrAssert(texture);
+
+    if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
+        this->flushGlyphs();
+        fCurrTexture = texture;
+        fCurrTexture->ref();
+    }
+
+    if (NULL == fVertices) {
+        // If we need to reserve vertices allow the draw target to suggest
+        // a number of verts to reserve and whether to perform a flush.
+        fMaxVertices = kMinRequestedVerts;
+        bool flush = fDrawTarget->geometryHints(fVertexLayout,
+                                               &fMaxVertices,
+                                               NULL);
+        if (flush) {
+            this->flushGlyphs();
+            fContext->flushText();
+            fDrawTarget = fContext->getTextTarget(fPaint);
+            fMaxVertices = kDefaultRequestedVerts;
+            // ignore return, no point in flushing again.
+            fDrawTarget->geometryHints(fVertexLayout,
+                                       &fMaxVertices,
+                                       NULL);
+        }
+
+        int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->size() / (6 * sizeof(uint16_t));
+        if (fMaxVertices < kMinRequestedVerts) {
+            fMaxVertices = kDefaultRequestedVerts;
+        } else if (fMaxVertices > maxQuadVertices) {
+            // don't exceed the limit of the index buffer
+            fMaxVertices = maxQuadVertices;
+        }
+        bool success = fDrawTarget->reserveAndLockGeometry(fVertexLayout,
+                                                           fMaxVertices, 0,
+                                                   GrTCast<void**>(&fVertices),
+                                                           NULL);
+        GrAlwaysAssert(success);
+    }
+
+    GrFixed tx = GrIntToFixed(glyph->fAtlasLocation.fX);
+    GrFixed ty = GrIntToFixed(glyph->fAtlasLocation.fY);
+
+#if GR_GL_TEXT_TEXTURE_NORMALIZED
+    int x = vx >> 16;
+    int y = vy >> 16;
+    int w = width >> 16;
+    int h = height >> 16;
+
+    setRectFan(&fVertices[2*fCurrVertex], x, y, x + w, y + h, 2);
+    setRectFan(&fVertices[2*fCurrVertex+1],
+               texture->normalizeFixedX(tx),
+               texture->normalizeFixedY(ty),
+               texture->normalizeFixedX(tx + width),
+               texture->normalizeFixedY(ty + height),
+               2);
+#else
+    fVertices[2*fCurrVertex].setXRectFan(vx, vy, vx + width, vy + height,
+                                        2 * sizeof(GrGpuTextVertex));
+    fVertices[2*fCurrVertex+1].setXRectFan(texture->normalizeFixedX(tx),
+                                          texture->normalizeFixedY(ty),
+                                          texture->normalizeFixedX(tx + width),
+                                          texture->normalizeFixedY(ty + height),
+                                          2 * sizeof(GrGpuTextVertex));
+#endif
+    fCurrVertex += 4;
+}
+
+
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
new file mode 100644
index 0000000..6cdb61c
--- /dev/null
+++ b/gpu/src/GrTextStrike.cpp
@@ -0,0 +1,211 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAtlas.h"
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrRectanizer.h"
+#include "GrTextStrike.h"
+#include "GrTextStrike_impl.h"
+#include "GrRect.h"
+
+GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
+    gpu->ref();
+    fAtlasMgr = NULL;
+
+    fHead = fTail = NULL;
+}
+
+GrFontCache::~GrFontCache() {
+    fCache.deleteAll();
+    delete fAtlasMgr;
+    fGpu->unref();
+}
+
+GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
+                                          const Key& key) {
+    if (NULL == fAtlasMgr) {
+        fAtlasMgr = new GrAtlasMgr(fGpu);
+    }
+    GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(),
+                                            scaler->getMaskFormat(), fAtlasMgr);
+    fCache.insert(key, strike);
+
+    if (fHead) {
+        fHead->fPrev = strike;
+    } else {
+        GrAssert(NULL == fTail);
+        fTail = strike;
+    }
+    strike->fPrev = NULL;
+    strike->fNext = fHead;
+    fHead = strike;
+
+    return strike;
+}
+
+void GrFontCache::abandonAll() {
+    fCache.deleteAll();
+    if (fAtlasMgr) {
+        fAtlasMgr->abandonAll();
+        delete fAtlasMgr;
+        fAtlasMgr = NULL;
+    }
+}
+
+void GrFontCache::freeAll() {
+    fCache.deleteAll();
+    delete fAtlasMgr;
+    fAtlasMgr = NULL;
+}
+
+void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
+    GrTextStrike* strike = fTail;
+    if (strike == preserveStrike) {
+        strike = strike->fPrev;
+    }
+    if (strike) {
+        int index = fCache.slowFindIndex(strike);
+        GrAssert(index >= 0);
+        fCache.removeAt(index, strike->fFontScalerKey->getHash());
+        this->detachStrikeFromList(strike);
+        delete strike;
+    }
+}
+
+#if GR_DEBUG
+void GrFontCache::validate() const {
+    int count = fCache.count();
+    if (0 == count) {
+        GrAssert(!fHead);
+        GrAssert(!fTail);
+    } else if (1 == count) {
+        GrAssert(fHead == fTail);
+    } else {
+        GrAssert(fHead != fTail);
+    }
+
+    int count2 = 0;
+    const GrTextStrike* strike = fHead;
+    while (strike) {
+        count2 += 1;
+        strike = strike->fNext;
+    }
+    GrAssert(count == count2);
+
+    count2 = 0;
+    strike = fTail;
+    while (strike) {
+        count2 += 1;
+        strike = strike->fPrev;
+    }
+    GrAssert(count == count2);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+    static int gCounter;
+#endif
+
+/*
+    The text strike is specific to a given font/style/matrix setup, which is
+    represented by the GrHostFontScaler object we are given in getGlyph().
+
+    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
+    atlas and a position within that texture.
+ */
+
+GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
+                           GrMaskFormat format,
+                           GrAtlasMgr* atlasMgr) : fPool(64) {
+    fFontScalerKey = key;
+    fFontScalerKey->ref();
+
+    fFontCache = cache;     // no need to ref, it won't go away before we do
+    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
+    fAtlas = NULL;
+
+    fMaskFormat = format;
+
+#if GR_DEBUG
+    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
+    gCounter += 1;
+#endif
+}
+
+static void FreeGlyph(GrGlyph*& glyph) { glyph->free(); }
+
+GrTextStrike::~GrTextStrike() {
+    GrAtlas::FreeLList(fAtlas);
+    fFontScalerKey->unref();
+    fCache.getArray().visit(FreeGlyph);
+
+#if GR_DEBUG
+    gCounter -= 1;
+    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
+#endif
+}
+
+GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
+                                     GrFontScaler* scaler) {
+    GrIRect bounds;
+    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
+        return NULL;
+    }
+
+    GrGlyph* glyph = fPool.alloc();
+    glyph->init(packed, bounds);
+    fCache.insert(packed, glyph);
+    return glyph;
+}
+
+bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
+    GrAssert(glyph);
+    GrAssert(scaler);
+    GrAssert(fCache.contains(glyph));
+    if (glyph->fAtlas) {
+        return true;
+    }
+
+    GrAutoRef ar(scaler);
+
+    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
+    size_t size = glyph->fBounds.area() * bytesPerPixel;
+    GrAutoSMalloc<1024> storage(size);
+    if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
+                                     glyph->height(),
+                                     glyph->width() * bytesPerPixel,
+                                     storage.get())) {
+        return false;
+    }
+
+    GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
+                                           glyph->height(), storage.get(),
+                                           fMaskFormat,
+                                           &glyph->fAtlasLocation);
+    if (NULL == atlas) {
+        return false;
+    }
+
+    // update fAtlas as well, since they may be chained in a linklist
+    glyph->fAtlas = fAtlas = atlas;
+    return true;
+}
+
+
diff --git a/gpu/src/GrTextStrike_impl.h b/gpu/src/GrTextStrike_impl.h
new file mode 100644
index 0000000..7e03e2a
--- /dev/null
+++ b/gpu/src/GrTextStrike_impl.h
@@ -0,0 +1,113 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextStrike_impl_DEFINED
+#define GrTextStrike_impl_DEFINED
+
+class GrFontCache::Key {
+public:
+    Key(GrFontScaler* scaler) {
+        fFontScalerKey = scaler->getKey();
+    }
+    
+    uint32_t getHash() const { return fFontScalerKey->getHash(); }
+    
+    static bool LT(const GrTextStrike& strike, const Key& key) {
+        return *strike.getFontScalerKey() < *key.fFontScalerKey;
+    }
+    static bool EQ(const GrTextStrike& strike, const Key& key) {
+        return *strike.getFontScalerKey() == *key.fFontScalerKey;
+    }
+    
+private:
+    const GrKey* fFontScalerKey;
+};
+
+void GrFontCache::detachStrikeFromList(GrTextStrike* strike) {
+    if (strike->fPrev) {
+        GrAssert(fHead != strike);
+        strike->fPrev->fNext = strike->fNext;
+    } else {
+        GrAssert(fHead == strike);
+        fHead = strike->fNext;
+    }
+
+    if (strike->fNext) {
+        GrAssert(fTail != strike);
+        strike->fNext->fPrev = strike->fPrev;
+    } else {
+        GrAssert(fTail == strike);
+        fTail = strike->fPrev;
+    }
+}
+
+GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler) {
+    this->validate();
+    
+    Key key(scaler);
+    GrTextStrike* strike = fCache.find(key);
+    if (NULL == strike) {
+        strike = this->generateStrike(scaler, key);
+    } else if (strike->fPrev) {
+        // Need to put the strike at the head of its dllist, since that is how
+        // we age the strikes for purging (we purge from the back of the list
+        this->detachStrikeFromList(strike);
+        // attach at the head
+        fHead->fPrev = strike;
+        strike->fNext = fHead;
+        strike->fPrev = NULL;
+        fHead = strike;
+    }
+
+    this->validate();
+    return strike;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  This Key just wraps a glyphID, and matches the protocol need for
+ *  GrTHashTable
+ */
+class GrTextStrike::Key {
+public:
+    Key(GrGlyph::PackedID id) : fPackedID(id) {}
+    
+    uint32_t getHash() const { return fPackedID; }
+    
+    static bool LT(const GrGlyph& glyph, const Key& key) {
+        return glyph.fPackedID < key.fPackedID;
+    }
+    static bool EQ(const GrGlyph& glyph, const Key& key) {
+        return glyph.fPackedID == key.fPackedID;
+    }
+    
+private:
+    GrGlyph::PackedID fPackedID;
+};
+
+GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed,
+                                GrFontScaler* scaler) {
+    GrGlyph* glyph = fCache.find(packed);
+    if (NULL == glyph) {
+        glyph = this->generateGlyph(packed, scaler);
+    }
+    return glyph;
+}
+
+#endif
+
diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp
new file mode 100644
index 0000000..fe3ff68
--- /dev/null
+++ b/gpu/src/GrTextureCache.cpp
@@ -0,0 +1,319 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTextureCache.h"
+#include "GrTexture.h"
+
+GrTextureEntry::GrTextureEntry(const GrTextureKey& key, GrTexture* texture)
+        : fKey(key), fTexture(texture) {
+    fLockCount = 0;
+    fPrev = fNext = NULL;
+
+    // we assume ownership of the texture, and will unref it when we die
+    GrAssert(texture);
+}
+
+GrTextureEntry::~GrTextureEntry() {
+    fTexture->unref();
+}
+
+#if GR_DEBUG
+void GrTextureEntry::validate() const {
+    GrAssert(fLockCount >= 0);
+    GrAssert(fTexture);
+    fTexture->validate();
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTextureCache::GrTextureCache(int maxCount, size_t maxBytes) :
+        fMaxCount(maxCount),
+        fMaxBytes(maxBytes) {
+    fEntryCount          = 0;
+    fEntryBytes          = 0;
+    fClientDetachedCount = 0;
+    fClientDetachedBytes = 0;
+
+    fHead = fTail = NULL;
+}
+
+GrTextureCache::~GrTextureCache() {
+    GrAutoTextureCacheValidate atcv(this);
+
+    this->deleteAll(kFreeTexture_DeleteMode);
+}
+
+void GrTextureCache::getLimits(int* maxTextures, size_t* maxTextureBytes) const{
+    if (maxTextures) {
+        *maxTextures = fMaxCount;
+    }
+    if (maxTextureBytes) {
+        *maxTextureBytes = fMaxBytes;
+    }
+}
+
+void GrTextureCache::setLimits(int maxTextures, size_t maxTextureBytes) {
+    bool smaller = (maxTextures < fMaxCount) || (maxTextureBytes < fMaxBytes);
+
+    fMaxCount = maxTextures;
+    fMaxBytes = maxTextureBytes;
+
+    if (smaller) {
+        this->purgeAsNeeded();
+    }
+}
+
+void GrTextureCache::internalDetach(GrTextureEntry* entry,
+                                    bool clientDetach) {
+    GrTextureEntry* prev = entry->fPrev;
+    GrTextureEntry* next = entry->fNext;
+
+    if (prev) {
+        prev->fNext = next;
+    } else {
+        fHead = next;
+    }
+    if (next) {
+        next->fPrev = prev;
+    } else {
+        fTail = prev;
+    }
+
+    // update our stats
+    if (clientDetach) {
+        fClientDetachedCount += 1;
+        fClientDetachedBytes += entry->texture()->sizeInBytes();
+    } else {
+        fEntryCount -= 1;
+        fEntryBytes -= entry->texture()->sizeInBytes();
+    }
+}
+
+void GrTextureCache::attachToHead(GrTextureEntry* entry,
+                                  bool clientReattach) {
+    entry->fPrev = NULL;
+    entry->fNext = fHead;
+    if (fHead) {
+        fHead->fPrev = entry;
+    }
+    fHead = entry;
+    if (NULL == fTail) {
+        fTail = entry;
+    }
+
+    // update our stats
+    if (clientReattach) {
+        fClientDetachedCount -= 1;
+        fClientDetachedBytes -= entry->texture()->sizeInBytes();
+    } else {
+        fEntryCount += 1;
+        fEntryBytes += entry->texture()->sizeInBytes();
+    }
+}
+
+class GrTextureCache::Key {
+    typedef GrTextureEntry T;
+
+    const GrTextureKey& fKey;
+public:
+    Key(const GrTextureKey& key) : fKey(key) {}
+
+    uint32_t getHash() const { return fKey.hashIndex(); }
+
+    static bool LT(const T& entry, const Key& key) {
+        return entry.key() < key.fKey;
+    }
+    static bool EQ(const T& entry, const Key& key) {
+        return entry.key() == key.fKey;
+    }
+#if GR_DEBUG
+    static uint32_t GetHash(const T& entry) {
+        return entry.key().hashIndex();
+    }
+    static bool LT(const T& a, const T& b) {
+        return a.key() < b.key();
+    }
+    static bool EQ(const T& a, const T& b) {
+        return a.key() == b.key();
+    }
+#endif
+};
+
+GrTextureEntry* GrTextureCache::findAndLock(const GrTextureKey& key) {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrTextureEntry* entry = fCache.find(key);
+    if (entry) {
+        this->internalDetach(entry, false);
+        this->attachToHead(entry, false);
+        // mark the entry as "busy" so it doesn't get purged
+        entry->lock();
+    }
+    return entry;
+}
+
+GrTextureEntry* GrTextureCache::createAndLock(const GrTextureKey& key,
+                                              GrTexture* texture) {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrTextureEntry* entry = new GrTextureEntry(key, texture);
+
+    this->attachToHead(entry, false);
+    fCache.insert(key, entry);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+    GrPrintf("--- add texture to cache %p, count=%d bytes= %d %d\n",
+             entry, fEntryCount, texture->sizeInBytes(), fEntryBytes);
+#endif
+
+    // mark the entry as "busy" so it doesn't get purged
+    entry->lock();
+    this->purgeAsNeeded();
+    return entry;
+}
+
+void GrTextureCache::detach(GrTextureEntry* entry) {
+    internalDetach(entry, true);
+    fCache.remove(entry->fKey, entry);
+}
+
+void GrTextureCache::reattachAndUnlock(GrTextureEntry* entry) {
+    attachToHead(entry, true);
+    fCache.insert(entry->key(), entry);
+    unlock(entry);
+}
+
+void GrTextureCache::unlock(GrTextureEntry* entry) {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrAssert(entry);
+    GrAssert(entry->isLocked());
+    GrAssert(fCache.find(entry->key()));
+
+    entry->unlock();
+    this->purgeAsNeeded();
+}
+
+void GrTextureCache::purgeAsNeeded() {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrTextureEntry* entry = fTail;
+    while (entry) {
+        if (fEntryCount <= fMaxCount && fEntryBytes <= fMaxBytes) {
+            break;
+        }
+
+        GrTextureEntry* prev = entry->fPrev;
+        if (!entry->isLocked()) {
+            // remove from our cache
+            fCache.remove(entry->fKey, entry);
+
+            // remove from our llist
+            this->internalDetach(entry, false);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+            GrPrintf("--- ~texture from cache %p [%d %d]\n", entry->texture(),
+                     entry->texture()->width(),
+                     entry->texture()->height());
+#endif
+            delete entry;
+        }
+        entry = prev;
+    }
+}
+
+void GrTextureCache::deleteAll(DeleteMode mode) {
+    GrAssert(!fClientDetachedCount);
+    GrAssert(!fClientDetachedBytes);
+
+    GrTextureEntry* entry = fHead;
+    while (entry) {
+        GrAssert(!entry->isLocked());
+
+        GrTextureEntry* next = entry->fNext;
+        if (kAbandonTexture_DeleteMode == mode) {
+            entry->texture()->abandon();
+        }
+        delete entry;
+        entry = next;
+    }
+
+    fCache.removeAll();
+    fHead = fTail = NULL;
+    fEntryCount = 0;
+    fEntryBytes = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+static int countMatches(const GrTextureEntry* head, const GrTextureEntry* target) {
+    const GrTextureEntry* entry = head;
+    int count = 0;
+    while (entry) {
+        if (target == entry) {
+            count += 1;
+        }
+        entry = entry->next();
+    }
+    return count;
+}
+
+#if GR_DEBUG
+static bool both_zero_or_nonzero(int count, size_t bytes) {
+    return (count == 0 && bytes == 0) || (count > 0 && bytes > 0);
+}
+#endif
+
+void GrTextureCache::validate() const {
+    GrAssert(!fHead == !fTail);
+    GrAssert(both_zero_or_nonzero(fEntryCount, fEntryBytes));
+    GrAssert(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes));
+    GrAssert(fClientDetachedBytes <= fEntryBytes);
+    GrAssert(fClientDetachedCount <= fEntryCount);
+    GrAssert((fEntryCount - fClientDetachedCount) == fCache.count());
+
+    fCache.validate();
+
+    GrTextureEntry* entry = fHead;
+    int count = 0;
+    size_t bytes = 0;
+    while (entry) {
+        entry->validate();
+        GrAssert(fCache.find(entry->key()));
+        count += 1;
+        bytes += entry->texture()->sizeInBytes();
+        entry = entry->fNext;
+    }
+    GrAssert(count == fEntryCount - fClientDetachedCount);
+    GrAssert(bytes == fEntryBytes  - fClientDetachedBytes);
+
+    count = 0;
+    for (entry = fTail; entry; entry = entry->fPrev) {
+        count += 1;
+    }
+    GrAssert(count == fEntryCount - fClientDetachedCount);
+
+    for (int i = 0; i < count; i++) {
+        int matches = countMatches(fHead, fCache.getArray()[i]);
+        GrAssert(1 == matches);
+    }
+}
+#endif
+
+
diff --git a/gpu/src/GrTouchGesture.cpp b/gpu/src/GrTouchGesture.cpp
new file mode 100644
index 0000000..0eaedc7
--- /dev/null
+++ b/gpu/src/GrTouchGesture.cpp
@@ -0,0 +1,243 @@
+#include "GrTouchGesture.h"
+#include "SkMatrix.h"
+#include "SkTime.h"
+
+#include <math.h>
+
+static const SkMSec MAX_DBL_TAP_INTERVAL = 300;
+static const float MAX_DBL_TAP_DISTANCE = 100;
+static const float MAX_JITTER_RADIUS = 2;
+
+// if true, then ignore the touch-move, 'cause its probably just jitter
+static bool close_enough_for_jitter(float x0, float y0, float x1, float y1) {
+    return  sk_float_abs(x0 - x1) <= MAX_JITTER_RADIUS &&
+            sk_float_abs(y0 - y1) <= MAX_JITTER_RADIUS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTouchGesture::GrTouchGesture() {
+    this->reset();
+}
+
+GrTouchGesture::~GrTouchGesture() {
+}
+
+void GrTouchGesture::reset() {
+    fTouches.reset();
+    fState = kEmpty_State;
+    fLocalM.reset();
+    fGlobalM.reset();
+
+    fLastUpT = SkTime::GetMSecs() - 2*MAX_DBL_TAP_INTERVAL;
+    fLastUpP.set(0, 0);
+}
+
+void GrTouchGesture::flushLocalM() {
+    fGlobalM.postConcat(fLocalM);
+    fLocalM.reset();
+}
+
+const SkMatrix& GrTouchGesture::localM() {
+    if (fFlinger.isActive()) {
+        if (!fFlinger.evaluateMatrix(&fLocalM)) {
+            this->flushLocalM();
+        }
+    }
+    return fLocalM;
+}
+
+void GrTouchGesture::appendNewRec(void* owner, float x, float y) {
+    Rec* rec = fTouches.append();
+    rec->fOwner = owner;
+    rec->fStartX = rec->fPrevX = rec->fLastX = x;
+    rec->fStartY = rec->fPrevY = rec->fLastY = y;
+    rec->fLastT = rec->fPrevT = SkTime::GetMSecs();
+}
+
+void GrTouchGesture::touchBegin(void* owner, float x, float y) {
+//    GrPrintf("--- %d touchBegin %p %g %g\n", fTouches.count(), owner, x, y);
+
+    int index = this->findRec(owner);
+    if (index >= 0) {
+        this->flushLocalM();
+        fTouches.removeShuffle(index);
+        GrPrintf("---- already exists, removing\n");
+    }
+
+    if (fTouches.count() == 2) {
+        return;
+    }
+
+    this->flushLocalM();
+    fFlinger.stop();
+
+    this->appendNewRec(owner, x, y);
+
+    switch (fTouches.count()) {
+        case 1:
+            fState = kTranslate_State;
+            break;
+        case 2:
+            fState = kZoom_State;
+            break;
+        default:
+            break;
+    }
+}
+
+int GrTouchGesture::findRec(void* owner) const {
+    for (int i = 0; i < fTouches.count(); i++) {
+        if (owner == fTouches[i].fOwner) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static float center(float pos0, float pos1) {
+    return (pos0 + pos1) * 0.5f;
+}
+
+static const float MAX_ZOOM_SCALE = 4;
+static const float MIN_ZOOM_SCALE = 0.25f;
+
+float GrTouchGesture::limitTotalZoom(float scale) const {
+    // this query works 'cause we know that we're square-scale w/ no skew/rotation
+    const float curr = fGlobalM[0];
+    
+    if (scale > 1 && curr * scale > MAX_ZOOM_SCALE) {
+        scale = MAX_ZOOM_SCALE / curr;
+    } else if (scale < 1 && curr * scale < MIN_ZOOM_SCALE) {
+        scale = MIN_ZOOM_SCALE / curr;
+    }
+    return scale;
+}
+
+void GrTouchGesture::touchMoved(void* owner, float x, float y) {
+//    GrPrintf("--- %d touchMoved %p %g %g\n", fTouches.count(), owner, x, y);
+
+    GrAssert(kEmpty_State != fState);
+
+    int index = this->findRec(owner);
+    if (index < 0) {
+        // not found, so I guess we should add it...
+        GrPrintf("---- add missing begin\n");
+        this->appendNewRec(owner, x, y);
+        index = fTouches.count() - 1;
+    }
+
+    Rec& rec = fTouches[index];
+
+    // not sure how valuable this is
+    if (fTouches.count() == 2) {
+        if (close_enough_for_jitter(rec.fLastX, rec.fLastY, x, y)) {
+//            GrPrintf("--- drop touchMove, withing jitter tolerance %g %g\n", rec.fLastX - x, rec.fLastY - y);
+            return;
+        }
+    }
+
+    rec.fPrevX = rec.fLastX; rec.fLastX = x;
+    rec.fPrevY = rec.fLastY; rec.fLastY = y;
+    rec.fPrevT = rec.fLastT; rec.fLastT = SkTime::GetMSecs();
+
+    switch (fTouches.count()) {
+        case 1: {
+            float dx = rec.fLastX - rec.fStartX;
+            float dy = rec.fLastY - rec.fStartY;
+            dx = (float)sk_float_round2int(dx);
+            dy = (float)sk_float_round2int(dy);
+            fLocalM.setTranslate(dx, dy);
+        } break;
+        case 2: {
+            GrAssert(kZoom_State == fState);
+            const Rec& rec0 = fTouches[0];
+            const Rec& rec1 = fTouches[1];
+            
+            float scale = this->computePinch(rec0, rec1);
+            scale = this->limitTotalZoom(scale);
+
+            fLocalM.setTranslate(-center(rec0.fStartX, rec1.fStartX),
+                                 -center(rec0.fStartY, rec1.fStartY));
+            fLocalM.postScale(scale, scale);
+            fLocalM.postTranslate(center(rec0.fLastX, rec1.fLastX),
+                                  center(rec0.fLastY, rec1.fLastY));
+        } break;
+        default:
+            break;
+    }
+}
+
+void GrTouchGesture::touchEnd(void* owner) {
+//    GrPrintf("--- %d touchEnd   %p\n", fTouches.count(), owner);
+
+    int index = this->findRec(owner);
+    if (index < 0) {
+        GrPrintf("--- not found\n");
+        return;
+    }
+
+    const Rec& rec = fTouches[index];
+    if (this->handleDblTap(rec.fLastX, rec.fLastY)) {
+        return;
+    }
+
+    // count() reflects the number before we removed the owner
+    switch (fTouches.count()) {
+        case 1: {
+            this->flushLocalM();
+            float dx = rec.fLastX - rec.fPrevX;
+            float dy = rec.fLastY - rec.fPrevY;
+            float dur = (rec.fLastT - rec.fPrevT) * 0.001f;
+            if (dur > 0) {
+                fFlinger.reset(dx / dur, dy / dur);
+            }
+            fState = kEmpty_State;
+        } break;
+        case 2:
+            this->flushLocalM();
+            GrAssert(kZoom_State == fState);
+            fState = kEmpty_State;
+            break;
+        default:
+            GrAssert(kZoom_State == fState);
+            break;
+    }
+
+    fTouches.removeShuffle(index);
+}
+
+float GrTouchGesture::computePinch(const Rec& rec0, const Rec& rec1) {
+    double dx = rec0.fStartX - rec1.fStartX;
+    double dy = rec0.fStartY - rec1.fStartY;
+    double dist0 = sqrt(dx*dx + dy*dy);
+
+    dx = rec0.fLastX - rec1.fLastX;
+    dy = rec0.fLastY - rec1.fLastY;
+    double dist1 = sqrt(dx*dx + dy*dy);
+
+    double scale = dist1 / dist0;
+    return (float)scale;
+}
+
+bool GrTouchGesture::handleDblTap(float x, float y) {
+    bool found = false;
+    SkMSec now = SkTime::GetMSecs();
+    if (now - fLastUpT <= MAX_DBL_TAP_INTERVAL) {
+        if (SkPoint::Length(fLastUpP.fX - x,
+                            fLastUpP.fY - y) <= MAX_DBL_TAP_DISTANCE) {
+            fFlinger.stop();
+            fLocalM.reset();
+            fGlobalM.reset();
+            fTouches.reset();
+            fState = kEmpty_State;
+            found = true;
+        }
+    }
+
+    fLastUpT = now;
+    fLastUpP.set(x, y);
+    return found;
+}
+
+
diff --git a/gpu/src/app-android.cpp b/gpu/src/app-android.cpp
new file mode 100644
index 0000000..eea9a4d
--- /dev/null
+++ b/gpu/src/app-android.cpp
@@ -0,0 +1,387 @@
+#include <jni.h>
+#include <sys/time.h>
+#include <time.h>
+#include <android/log.h>
+#include <stdint.h>
+
+#include "GrContext.h"
+#include "SkGpuCanvas.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTime.h"
+
+#include "GrGLConfig.h"
+
+static GrContext* make_context() {
+    SkDebugf("---- before create\n");
+    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+//    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
+    SkDebugf("---- after create %p\n", ctx);
+    return ctx;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void gr_run_unittests() {}
+
+#include "FlingState.h"
+#include "GrTouchGesture.h"
+#include "SkView.h"
+
+typedef SkView* (*SkViewFactory)();
+
+// these values must match those in Ganesh.java
+enum TouchState {
+    kUnknown_TouchState,
+    kDown_TouchState,
+    kMoved_TouchState,
+    kUp_TouchState
+};
+
+struct State {
+    State();
+    ~State();
+
+    int countSlides() const { return fFactory.count(); }
+    const char* getSlideTitle(int index) const;
+    void chooseSlide(int index) {
+        SkDebugf("----- index %d\n", index);
+        if (index < fFactory.count()) {
+            this->setView(fFactory[index]());
+        }
+    }
+
+    void setViewport(int w, int h);
+    int getWidth() const { return fViewport.fX; }
+    int getHeight() const { return fViewport.fY; }
+    
+    void handleTouch(void*, TouchState, float x, float y);
+    void applyMatrix(SkCanvas*);
+
+    SkView* getView() const { return fView; }
+
+private:
+    SkView*     fView;
+    SkIPoint    fViewport;
+    
+    GrTouchGesture fGesture;
+
+    SkTDArray<SkViewFactory> fFactory;
+
+    void setView(SkView* view) {
+        SkSafeUnref(fView);
+        fView = view;
+
+        view->setVisibleP(true);
+        view->setClipToBounds(false);
+        view->setSize(SkIntToScalar(fViewport.fX),
+                      SkIntToScalar(fViewport.fY));
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SampleCode.h"
+
+SkViewRegister* SkViewRegister::gHead;
+SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
+    static bool gOnce;
+    if (!gOnce) {
+        gHead = NULL;
+        gOnce = true;
+    }
+    
+    fChain = gHead;
+    gHead = this;
+}
+
+static const char gCharEvtName[] = "SampleCode_Char_Event";
+static const char gKeyEvtName[] = "SampleCode_Key_Event";
+static const char gTitleEvtName[] = "SampleCode_Title_Event";
+static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
+static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
+
+bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
+    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
+        if (outUni) {
+            *outUni = evt.getFast32();
+        }
+        return true;
+    }
+    return false;
+}
+
+bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
+    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
+        if (outKey) {
+            *outKey = (SkKey)evt.getFast32();
+        }
+        return true;
+    }
+    return false;
+}
+
+bool SampleCode::TitleQ(const SkEvent& evt) {
+    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
+}
+
+void SampleCode::TitleR(SkEvent* evt, const char title[]) {
+    GrAssert(evt && TitleQ(*evt));
+    evt->setString(gTitleEvtName, title);
+}
+
+bool SampleCode::PrefSizeQ(const SkEvent& evt) {
+    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
+}
+
+void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
+    GrAssert(evt && PrefSizeQ(*evt));
+    SkScalar size[2];
+    size[0] = width;
+    size[1] = height;
+    evt->setScalars(gPrefSizeEvtName, 2, size);
+}
+
+bool SampleCode::FastTextQ(const SkEvent& evt) {
+    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
+}
+
+static SkMSec gAnimTime;
+static SkMSec gAnimTimePrev;
+
+SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
+SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
+SkScalar SampleCode::GetAnimSecondsDelta() {
+    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
+}
+
+SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
+    // since gAnimTime can be up to 32 bits, we can't convert it to a float
+    // or we'll lose the low bits. Hence we use doubles for the intermediate
+    // calculations
+    double seconds = (double)gAnimTime / 1000.0;
+    double value = SkScalarToDouble(speed) * seconds;
+    if (period) {
+        value = ::fmod(value, SkScalarToDouble(period));
+    }
+    return SkDoubleToScalar(value);
+}
+
+static void drawIntoCanvas(State* state, SkCanvas* canvas) {
+    gAnimTime = SkTime::GetMSecs();
+    SkView* view = state->getView();
+    view->draw(canvas);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void resetGpuState();
+
+State::State() {
+    fViewport.set(0, 0);
+
+    const SkViewRegister* reg = SkViewRegister::Head();
+    while (reg) {
+        *fFactory.append() = reg->factory();
+        reg = reg->next();
+    }
+
+    SkDebugf("----- %d slides\n", fFactory.count());
+    fView = NULL;
+    this->chooseSlide(0);
+}
+
+State::~State() {
+    SkSafeUnref(fView);
+}
+
+void State::setViewport(int w, int h) {
+    fViewport.set(w, h);
+    if (fView) {
+        fView->setSize(SkIntToScalar(w), SkIntToScalar(h));
+    }
+    resetGpuState();
+}
+
+const char* State::getSlideTitle(int index) const {
+    SkEvent evt(gTitleEvtName);
+    evt.setFast32(index);
+    {
+        SkView* view = fFactory[index]();
+        view->doQuery(&evt);
+        view->unref();
+    }
+    return evt.findString(gTitleEvtName);
+}
+
+void State::handleTouch(void* owner, TouchState state, float x, float y) {
+    switch (state) {
+        case kDown_TouchState:
+            fGesture.touchBegin(owner, x, y);
+            break;
+        case kMoved_TouchState:
+            fGesture.touchMoved(owner, x, y);
+            break;
+        case kUp_TouchState:
+            fGesture.touchEnd(owner);
+            break;
+    }
+}
+
+void State::applyMatrix(SkCanvas* canvas) {
+    const SkMatrix& localM = fGesture.localM();
+    if (localM.getType() & SkMatrix::kScale_Mask) {
+        canvas->setExternalMatrix(&localM);
+    }
+    canvas->concat(localM);
+    canvas->concat(fGesture.globalM());
+}
+
+static State* get_state() {
+    static State* gState;
+    if (NULL == gState) {
+        gState = new State;
+    }
+    return gState;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static GrContext* gContext;
+static int gWidth;
+static int gHeight;
+static float gX, gY;
+
+static void resetGpuState() {
+    if (NULL == gContext) {
+        SkDebugf("creating context for first time\n");
+        gContext = make_context();
+    } else {
+        SkDebugf("------ gContext refcnt=%d\n", gContext->refcnt());
+        gContext->abandonAllTextures();
+        gContext->unref();
+        gContext = make_context();
+    }
+}
+
+static void doDraw() {
+    if (NULL == gContext) {
+        gContext = make_context();
+    }
+
+    State* state = get_state();
+    SkBitmap viewport;
+    viewport.setConfig(SkBitmap::kARGB_8888_Config,
+                       state->getWidth(), state->getHeight());
+
+    SkGpuCanvas canvas(gContext);
+
+    canvas.setBitmapDevice(viewport);
+    state->applyMatrix(&canvas);
+
+    drawIntoCanvas(state, &canvas);
+
+    GrGLCheckErr();
+    GrGLClearErr();
+//    gContext->checkError();
+//    gContext->clearError();
+
+    if (true) {
+        static const int FRAME_COUNT = 32;
+        static SkMSec gDuration;
+
+        static SkMSec gNow;
+        static int gFrameCounter;
+        if (++gFrameCounter == FRAME_COUNT) {
+            gFrameCounter = 0;
+            SkMSec now = SkTime::GetMSecs();
+
+            gDuration = now - gNow;
+            gNow = now;
+        }
+
+        int fps = (FRAME_COUNT * 1000) / gDuration;
+        SkString str;
+        str.printf("FPS=%3d MS=%3d", fps, gDuration / FRAME_COUNT);
+        
+        SkGpuCanvas c(gContext);
+        c.setBitmapDevice(viewport);
+
+        SkPaint p;
+        p.setAntiAlias(true);
+        SkRect r = { 0, 0, 110, 16 };
+        p.setColor(SK_ColorWHITE);
+        c.drawRect(r, p);
+        p.setColor(SK_ColorBLACK);
+        c.drawText(str.c_str(), str.size(), 4, 12, p);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
+                                                           JNIEnv*, jobject);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
+                                                                             jint w, jint h);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
+                                        jint id, jint type, jfloat x, jfloat y);
+
+    JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject);
+    JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv*, jobject, jint index);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index);
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
+                                                            JNIEnv*, jobject) {
+    SkDebugf("------ nativeSurfaceCreated\n");
+    resetGpuState();
+    SkDebugf("------ end nativeSurfaceCreated\n");
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
+                                                       jint w, jint h) {
+    State* state = get_state();
+    SkDebugf("---- state.setviewport %p %d %d\n", state, w, h);
+    state->setViewport(w, h);
+    SkDebugf("---- end setviewport\n");
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
+    doDraw();
+}
+
+union IntPtr {
+    jint    fInt;
+    void*   fPtr;
+};
+static void* int2ptr(jint n) {
+    IntPtr data;
+    data.fInt = n;
+    return data.fPtr;
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
+                                      jint id, jint type, jfloat x, jfloat y) {
+    get_state()->handleTouch(int2ptr(id), (TouchState)type, x, y);
+}
+
+////////////
+
+JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
+    return get_state()->countSlides();
+}
+
+JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
+    return env->NewStringUTF(get_state()->getSlideTitle(index));
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
+    get_state()->chooseSlide(index);
+}
+
+
+
+
+
diff --git a/gpu/src/gr_files.mk b/gpu/src/gr_files.mk
new file mode 100644
index 0000000..8aeddc9
--- /dev/null
+++ b/gpu/src/gr_files.mk
@@ -0,0 +1,27 @@
+SOURCE := \
+    GrAllocPool.cpp \
+    GrAtlas.cpp \
+    GrClip.cpp \
+    GrContext.cpp \
+    GrDrawTarget.cpp \
+    GrGLIndexBuffer.cpp	\
+    GrGLInterface.cpp \
+    GrGLTexture.cpp \
+    GrGLVertexBuffer.cpp \
+    GrGpu.cpp \
+    GrGpuGLShaders2.cpp \
+    GrGpuGLFixed.cpp \
+    GrGpuFactory.cpp \
+    GrGLUtil.cpp \
+    GrGpuGL.cpp \
+    GrInOrderDrawBuffer.cpp \
+    GrMatrix.cpp \
+    GrMemory.cpp \
+    GrPath.cpp \
+    GrRectanizer_fifo.cpp \
+    GrTextureCache.cpp \
+    GrTextContext.cpp \
+    GrTextStrike.cpp \
+    GrBufferAllocPool.cpp\
+    GrPathRenderer.cpp \
+    GrStencil.cpp
diff --git a/gpu/src/gr_hello_world.cpp b/gpu/src/gr_hello_world.cpp
new file mode 100644
index 0000000..5638e19
--- /dev/null
+++ b/gpu/src/gr_hello_world.cpp
@@ -0,0 +1,30 @@
+#include "SkGLCanvas.h"
+#include "SkBitmap.h"
+#include "SkPaint.h"
+#include "SkGpuGLShaders.h"
+
+extern "C" {
+    void gr_hello_world();
+}
+
+void gr_hello_world() {
+    static GrGpu* gGpu;
+    if (NULL == gGpu) {
+        gGpu = new SkGpuGLShaders;
+    }
+
+    SkGLCanvas canvas(gGpu);
+    SkBitmap bm;
+
+    bm.setConfig(SkBitmap::kARGB_8888_Config, WIDTH, HEIGHT);
+    canvas.setBitmapDevice(bm);
+
+    canvas.drawColor(SK_ColorWHITE);
+
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setTextSize(30);
+    canvas.drawText("Hello Kno", 9, 40, 40, paint);
+}
+
+
diff --git a/gpu/src/gr_unittests.cpp b/gpu/src/gr_unittests.cpp
new file mode 100644
index 0000000..16fd9dc
--- /dev/null
+++ b/gpu/src/gr_unittests.cpp
@@ -0,0 +1,86 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrDrawTarget.h"
+#include "GrTDArray.h"
+#include "GrTBSearch.h"
+#include "GrMatrix.h"
+#include "GrRedBlackTree.h"
+#include "GrPath.h"
+
+static void dump(const GrTDArray<int>& array) {
+#if 0
+    for (int i = 0; i < array.count(); i++) {
+        printf(" %d", array[i]);
+    }
+    printf("\n");
+#endif
+}
+
+static void test_tdarray() {
+    GrTDArray<int> array;
+
+    *array.append() = 0; dump(array);
+    *array.append() = 2; dump(array);
+    *array.append() = 4; dump(array);
+    *array.append() = 6; dump(array);
+    GrAssert(array.count() == 4);
+
+    *array.insert(0) = -1; dump(array);
+    *array.insert(2) = 1; dump(array);
+    *array.insert(4) = 3; dump(array);
+    *array.insert(7) = 7; dump(array);
+    GrAssert(array.count() == 8);
+    array.remove(3); dump(array);
+    array.remove(0); dump(array);
+    array.removeShuffle(4); dump(array);
+    array.removeShuffle(1); dump(array);
+    GrAssert(array.count() == 4);
+}
+
+static bool LT(const int& elem, int value) {
+    return elem < value;
+}
+static bool EQ(const int& elem, int value) {
+    return elem == value;
+}
+
+static void test_bsearch() {
+    const int array[] = {
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99
+    };
+
+    for (size_t n = 0; n < GR_ARRAY_COUNT(array); n++) {
+        for (size_t i = 0; i < n; i++) {
+            int index = GrTBSearch<int, int>(array, n, array[i]);
+            GrAssert(index == i);
+            index = GrTBSearch<int, int>(array, n, -array[i]);
+            GrAssert(index < 0);
+        }
+    }
+}
+
+void gr_run_unittests() {
+    test_tdarray();
+    test_bsearch();
+    GrMatrix::UnitTest();
+    GrRedBlackTree<int>::UnitTest();
+    GrPath::ConvexUnitTest();
+    GrDrawTarget::VertexLayoutUnitTest();
+}
+
+
diff --git a/gpu/src/skia/SkUIView.mm b/gpu/src/skia/SkUIView.mm
new file mode 100644
index 0000000..667a474
--- /dev/null
+++ b/gpu/src/skia/SkUIView.mm
@@ -0,0 +1,858 @@
+#import "SkUIView.h"
+#include <QuartzCore/QuartzCore.h>
+
+#include "SkGpuCanvas.h"
+#include "SkCGUtils.h"
+#include "GrContext.h"
+
+#define SKWIND_CONFIG       SkBitmap::kRGB_565_Config
+//#define SKWIND_CONFIG       SkBitmap::kARGB_8888_Config
+#define SKGL_CONFIG         kEAGLColorFormatRGB565
+//#define SKGL_CONFIG         kEAGLColorFormatRGBA8
+
+#define SHOW_FPS
+#define FORCE_REDRAW
+//#define DUMP_FPS_TO_PRINTF
+
+//#define USE_ACCEL_TO_ROTATE
+
+//#define SHOULD_COUNTER_INIT 334
+static int gShouldCounter;
+static bool should_draw() {
+    if (--gShouldCounter == 0) {
+   //     printf("\n");
+    }
+    return true;
+    return gShouldCounter >= 0;
+}
+#ifdef SHOULD_COUNTER_INIT
+    bool (*gShouldDrawProc)() = should_draw;
+#else
+    bool (*gShouldDrawProc)() = NULL;
+#endif
+
+//#define USE_GL_1
+#define USE_GL_2
+
+#if defined(USE_GL_1) || defined(USE_GL_2)
+    #define USE_GL
+#endif
+
+@implementation SkUIView
+
+
+@synthesize fWind;
+@synthesize fTitleLabel;
+@synthesize fBackend;
+@synthesize fComplexClip;
+@synthesize fUseWarp;
+
+#include "SkWindow.h"
+#include "SkEvent.h"
+
+static float gScreenScale = 1;
+
+extern SkOSWindow* create_sk_window(void* hwnd);
+
+#define kREDRAW_UIVIEW_GL "sk_redraw_uiview_gl_iOS"
+
+#define TITLE_HEIGHT  44
+
+static const float SCALE_FOR_ZOOM_LENS = 4.0;
+#define Y_OFFSET_FOR_ZOOM_LENS           200
+#define SIZE_FOR_ZOOM_LENS               250
+
+static const float MAX_ZOOM_SCALE = 4.0;
+static const float MIN_ZOOM_SCALE = 2.0 / MAX_ZOOM_SCALE;
+
+extern bool gDoTraceDraw;
+#define DO_TRACE_DRAW_MAX   100
+
+#ifdef SHOW_FPS
+struct FPSState {
+    static const int FRAME_COUNT = 60;
+
+    CFTimeInterval fNow0, fNow1;
+    CFTimeInterval fTime0, fTime1, fTotalTime;
+    int fFrameCounter;
+    int fDrawCounter;
+
+    FPSState() {
+        fTime0 = fTime1 = fTotalTime = 0;
+        fFrameCounter = 0;
+    }
+
+    void startDraw() {
+        fNow0 = CACurrentMediaTime();
+        
+        if (0 == fDrawCounter && false) {
+            gDoTraceDraw = true;
+            SkDebugf("\n");
+        }
+    }
+    
+    void endDraw() {
+        fNow1 = CACurrentMediaTime();
+
+        if (0 == fDrawCounter) {
+            gDoTraceDraw = true;
+        }
+        if (DO_TRACE_DRAW_MAX == ++fDrawCounter) {
+            fDrawCounter = 0;
+        }
+    }
+        
+    void flush(SkOSWindow* wind) {
+        CFTimeInterval now2 = CACurrentMediaTime();
+
+        fTime0 += fNow1 - fNow0;
+        fTime1 += now2 - fNow1;
+        
+        if (++fFrameCounter == FRAME_COUNT) {
+            CFTimeInterval totalNow = CACurrentMediaTime();
+            fTotalTime = totalNow - fTotalTime;
+            
+            SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
+            SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
+            
+            SkString str;
+            str.printf("ms: %d [%d], fps: %3.1f", msTotal, ms0,
+                       FRAME_COUNT / fTotalTime);
+#ifdef DUMP_FPS_TO_PRINTF
+            SkDebugf("%s\n", str.c_str());
+#else
+            wind->setTitle(str.c_str());
+#endif
+
+            fTotalTime = totalNow;
+            fTime0 = fTime1 = 0;
+            fFrameCounter = 0;
+        }
+    }
+};
+
+static FPSState gFPS;
+
+    #define FPS_StartDraw() gFPS.startDraw()
+    #define FPS_EndDraw()   gFPS.endDraw()
+    #define FPS_Flush(wind)     gFPS.flush(wind)
+#else
+    #define FPS_StartDraw()
+    #define FPS_EndDraw()
+    #define FPS_Flush(wind)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_GL
++ (Class) layerClass
+{
+	return [CAEAGLLayer class];
+}
+#endif
+
+- (id)initWithMyDefaults {
+    fBackend = kGL_Backend;
+    fUseWarp = false;
+    fRedrawRequestPending = false;
+    fWind = create_sk_window(self);
+    fWind->setConfig(SKWIND_CONFIG);
+    fMatrix.reset();
+    fLocalMatrix.reset();
+    fNeedGestureEnded = false;
+    fNeedFirstPinch = true;
+    fZoomAround = false;
+    fComplexClip = false;
+
+    [self initGestures];
+
+#ifdef USE_GL
+    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+    eaglLayer.opaque = TRUE;
+    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+                                        [NSNumber numberWithBool:NO],
+                                        kEAGLDrawablePropertyRetainedBacking,
+                                        SKGL_CONFIG,
+                                        kEAGLDrawablePropertyColorFormat,
+                                        nil];
+
+#ifdef USE_GL_1
+    fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+#else
+    fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+#endif
+
+    if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
+    {
+        [self release];
+        return nil;
+    }
+    
+    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
+    glGenFramebuffersOES(1, &fGL.fFramebuffer);
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fGL.fFramebuffer);
+
+    glGenRenderbuffersOES(1, &fGL.fRenderbuffer);
+    glGenRenderbuffersOES(1, &fGL.fStencilbuffer);
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+#endif
+
+#ifdef USE_ACCEL_TO_ROTATE
+    fRotateMatrix.reset();
+    [UIAccelerometer sharedAccelerometer].delegate = self;
+    [UIAccelerometer sharedAccelerometer].updateInterval = 1 / 30.0;
+#endif
+    return self;
+}
+
+- (id)initWithCoder:(NSCoder*)coder {
+    if ((self = [super initWithCoder:coder])) {
+        self = [self initWithMyDefaults];
+    }
+    return self;
+}
+
+- (id)initWithFrame:(CGRect)frame {
+    if (self = [super initWithFrame:frame]) {
+        self = [self initWithMyDefaults];
+    }
+    return self;
+}
+
+#include "SkImageDecoder.h"
+#include "SkStream_NSData.h"
+
+static void zoom_around(SkCanvas* canvas, float cx, float cy, float zoom) {
+    float clipW = SIZE_FOR_ZOOM_LENS;
+    float clipH = SIZE_FOR_ZOOM_LENS;
+
+    SkRect r;
+    r.set(0, 0, clipW, clipH);
+    r.offset(cx - clipW/2, cy - clipH/2);
+
+    SkPaint paint;
+    paint.setColor(0xFF66AAEE);
+    paint.setStyle(SkPaint::kStroke_Style);
+    paint.setStrokeWidth(10);
+
+    // draw our "frame" around the zoom lens
+    canvas->drawRect(r, paint);
+
+    // now clip and scale the lens
+    canvas->clipRect(r);
+    canvas->translate(cx, cy);
+    canvas->scale(zoom, zoom);
+    canvas->translate(-cx, -cy);
+}
+
+- (void)drawWithCanvas:(SkCanvas*)canvas {
+    if (fComplexClip) {
+        canvas->drawColor(SK_ColorBLUE);
+
+        SkPath path;
+        static const SkRect r[] = {
+            { 50, 50, 250, 250 },
+            { 150, 150, 500, 600 }
+        };
+        for (size_t i = 0; i < GR_ARRAY_COUNT(r); i++) {
+            path.addRect(r[i]);
+        }
+        canvas->clipPath(path);
+    }
+    
+    // This is to consolidate multiple inval requests
+    fRedrawRequestPending = false;
+
+    if (fFlingState.isActive()) {
+        if (!fFlingState.evaluateMatrix(&fLocalMatrix)) {
+            [self flushLocalMatrix];
+        }
+    }
+
+    SkMatrix localMatrix = fLocalMatrix;
+#ifdef USE_ACCEL_TO_ROTATE
+    localMatrix.preConcat(fRotateMatrix);
+#endif
+
+    SkMatrix matrix;
+    matrix.setConcat(localMatrix, fMatrix);
+
+    const SkMatrix* localM = NULL;
+    if (localMatrix.getType() & SkMatrix::kScale_Mask) {
+        localM = &localMatrix;
+    }
+#ifdef USE_ACCEL_TO_ROTATE
+    localM = &localMatrix;
+#endif
+    canvas->setExternalMatrix(localM);
+
+#ifdef SHOULD_COUNTER_INIT
+    gShouldCounter = SHOULD_COUNTER_INIT;
+#endif
+
+    {
+        int saveCount = canvas->save();
+        canvas->concat(matrix);
+//        SkRect r = { 10, 10, 500, 600 }; canvas->clipRect(r);
+        fWind->draw(canvas);
+        canvas->restoreToCount(saveCount);
+    }
+
+    if (fZoomAround) {
+        zoom_around(canvas, fZoomAroundX, fZoomAroundY, SCALE_FOR_ZOOM_LENS);
+        canvas->concat(matrix);
+        fWind->draw(canvas);
+    }
+    
+#ifdef FORCE_REDRAW
+    fWind->inval(NULL);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)layoutSubviews {
+    int W, H;
+
+    gScreenScale = [UIScreen mainScreen].scale;
+
+#ifdef USE_GL
+    
+    CAEAGLLayer* eaglLayer = (CAEAGLLayer*)self.layer;
+    if ([self respondsToSelector:@selector(setContentScaleFactor:)]) {
+        self.contentScaleFactor = gScreenScale;
+    }
+    // Allocate color buffer backing based on the current layer size
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    [fGL.fContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer];
+    
+    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &fGL.fWidth);
+    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &fGL.fHeight);
+
+    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
+    {
+        NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+    }
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_OES, fGL.fWidth, fGL.fHeight);
+
+    W = fGL.fWidth;
+    H = fGL.fHeight;
+#else
+    CGRect rect = [self bounds];
+    W = (int)CGRectGetWidth(rect);
+    H = (int)CGRectGetHeight(rect) - TITLE_HEIGHT;
+#endif
+
+    printf("---- layoutSubviews %d %d\n", W, H);
+    fWind->resize(W, H);
+    fWind->inval(NULL);
+}
+
+#ifdef USE_GL
+
+static GrContext* gCtx;
+static GrContext* get_global_grctx() {
+    // should be pthread-local at least
+    if (NULL == gCtx) {        
+#ifdef USE_GL_1
+        gCtx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
+#else
+        gCtx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+#endif
+    }
+    return gCtx;
+}
+
+#include "SkDevice.h"
+#include "SkShader.h"
+#include "SkGrTexturePixelRef.h"
+#include "GrMesh.h"
+#include "SkRandom.h"
+
+#include "GrAtlas.h"
+#include "GrTextStrike.h"
+
+static void show_fontcache(GrContext* ctx, SkCanvas* canvas) {
+#if 0
+    SkPaint paint;
+    const int SIZE = 64;
+    GrAtlas* plot[64][64];
+
+    paint.setAntiAlias(true);
+    paint.setTextSize(24);
+    paint.setTextAlign(SkPaint::kCenter_Align);
+
+    Gr_bzero(plot, sizeof(plot));
+
+    GrFontCache* cache = ctx->getFontCache();
+    GrTextStrike* strike = cache->getHeadStrike();
+    int count = 0;
+    while (strike) {
+        GrAtlas* atlas = strike->getAtlas();
+        while (atlas) {
+            int x = atlas->getPlotX();
+            int y = atlas->getPlotY();
+
+            SkRandom rand((intptr_t)strike);
+            SkColor c = rand.nextU() | 0x80808080;
+            paint.setColor(c);
+            paint.setAlpha(0x80);
+
+            SkRect r;
+            r.set(x * SIZE, y * SIZE, (x + 1)*SIZE, (y+1)*SIZE);
+            r.inset(1, 1);
+            canvas->drawRect(r, paint);
+            
+            paint.setColor(0xFF660000);
+            SkString label;
+            label.printf("%d", count);
+            canvas->drawText(label.c_str(), label.size(), r.centerX(),
+                             r.fTop + r.height() * 2 / 3, paint);
+            
+            atlas = atlas->nextAtlas();
+        }
+        strike = strike->fNext;
+        count += 1;
+    }
+#endif
+}
+
+void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale);
+
+static void draw_mesh(SkCanvas* canvas, const SkBitmap& bm) {
+    GrMesh fMesh;
+
+    SkRect r;
+    r.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()));
+    
+    //        fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, texture);
+    fMesh.init(r, bm.width()/16, bm.height()/16, r);
+
+    SkPaint paint;
+    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+    paint.setShader(s)->unref();
+    fMesh.draw(canvas, paint);
+}
+
+static void scale_about(SkCanvas* canvas, float sx, float sy, float px, float py) {
+    canvas->translate(px, py);
+    canvas->scale(sx, sy);
+    canvas->translate(-px, -py);
+}
+
+static float grInterp(float v0, float v1, float percent) {
+    return v0 + percent * (v1 - v0);
+}
+
+static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float warp) {
+    canvas->save();
+    float s = grInterp(1, 0.8, warp);
+    scale_about(canvas, s, s, w/2, h/2);
+    test_patch(canvas, dev->accessBitmap(false), warp);
+    canvas->restore();
+}
+
+- (void)drawInGL {
+//    printf("------ drawInGL\n");
+    // This application only creates a single context which is already set current at this point.
+    // This call is redundant, but needed if dealing with multiple contexts.
+    [EAGLContext setCurrentContext:fGL.fContext];
+    
+    // This application only creates a single default framebuffer which is already bound at this point.
+    // This call is redundant, but needed if dealing with multiple framebuffers.
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fGL.fFramebuffer);
+    
+    GLint scissorEnable;
+    glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
+    glDisable(GL_SCISSOR_TEST);
+    glClearColor(0,0,0,0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    if (scissorEnable) {
+        glEnable(GL_SCISSOR_TEST);
+    }
+    
+    GrContext* ctx = get_global_grctx();
+    SkGpuCanvas origCanvas(ctx);
+    origCanvas.setBitmapDevice(fWind->getBitmap());
+    
+    //    gl->reset();
+    SkGpuCanvas glCanvas(ctx);
+    SkCanvas   rasterCanvas;
+
+    SkCanvas* canvas;
+    SkDevice* dev = NULL;
+    
+    switch (fBackend) {
+        case kRaster_Backend:
+            canvas = &rasterCanvas;
+            break;
+        case kGL_Backend:
+            canvas = &glCanvas;
+            break;
+    }
+
+    if (fUseWarp || fWarpState.isActive()) {
+        if (kGL_Backend == fBackend) {
+            dev = origCanvas.createDevice(fWind->getBitmap(), true);
+            canvas->setDevice(dev)->unref();
+        } else {
+            canvas->setBitmapDevice(fWind->getBitmap());
+            dev = canvas->getDevice();
+        }
+    } else {
+        canvas->setBitmapDevice(fWind->getBitmap());
+        dev = NULL;
+    }
+    
+    canvas->translate(0, TITLE_HEIGHT);
+
+    // if we're not "retained", then we have to always redraw everything.
+    // This call forces us to ignore the fDirtyRgn, and draw everywhere.
+    // If we are "retained", we can skip this call (as the raster case does)
+    fWind->forceInvalAll();
+
+    FPS_StartDraw();
+    [self drawWithCanvas:canvas];
+    FPS_EndDraw();
+
+    if (dev) {
+        draw_device(&origCanvas, dev, fWind->width(), fWind->height(),
+                    fWarpState.evaluate());
+    } else {
+        if (kRaster_Backend == fBackend) {
+            origCanvas.drawBitmap(fWind->getBitmap(), 0, 0, NULL);
+        }
+        // else GL - we're already on screen
+    }
+
+    show_fontcache(ctx, canvas);
+    ctx->flush(false);
+        
+    // This application only creates a single color renderbuffer which is already bound at this point.
+    // This call is redundant, but needed if dealing with multiple renderbuffers.
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER_OES];
+    
+#if GR_COLLECT_STATS
+    static int frame = 0;
+    if (!(frame % 100)) {
+        get_global_grctx()->printStats();
+    }
+    get_global_grctx()->resetStats();
+    ++frame;
+#endif
+    
+    FPS_Flush(fWind);
+
+#if 0
+    gCtx->deleteAllTextures(GrTextureCache::kAbandonTexture_DeleteMode);
+    gCtx->unref();
+    gCtx = NULL;
+#endif
+}
+
+#else   // raster case
+
+- (void)drawRect:(CGRect)rect {
+    CGContextRef cg = UIGraphicsGetCurrentContext();
+    SkCanvas* canvas = NULL;
+
+    FPS_StartDraw();
+    [self drawWithCanvas:canvas];
+
+    FPS_EndDraw();
+    SkCGDrawBitmap(cg, fWind->getBitmap(), 0, TITLE_HEIGHT);
+
+    FPS_Flush(fWind);
+
+}
+#endif
+
+- (void)setWarpState:(bool)useWarp {
+    fWarpState.stop();  // we should reverse from where we are if active...
+
+    const float duration = 0.5;
+    fUseWarp = useWarp;
+    if (useWarp) {
+        fWarpState.start(0, 1, duration);
+    } else {
+        fWarpState.start(1, 0, duration);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)flushLocalMatrix {
+    fMatrix.postConcat(fLocalMatrix);
+    fLocalMatrix.reset();
+    fFlingState.stop();
+    fNeedGestureEnded = false;
+    fNeedFirstPinch = true;
+}
+
+- (void)localMatrixWithGesture:(UIGestureRecognizer*)gesture {
+    fNeedGestureEnded = true;
+
+    switch (gesture.state) {
+        case UIGestureRecognizerStateCancelled:
+        case UIGestureRecognizerStateEnded:
+            [self flushLocalMatrix];
+            break;
+        case UIGestureRecognizerStateChanged: {
+            SkMatrix matrix;
+            matrix.setConcat(fLocalMatrix, fMatrix);
+        } break;
+        default:
+            break;
+    }
+}
+
+- (void)commonHandleGesture:(UIGestureRecognizer*)sender {
+    if (fFlingState.isActive()) {
+        [self flushLocalMatrix];
+    }
+
+    switch (sender.state) {
+        case UIGestureRecognizerStateBegan:
+            [self flushLocalMatrix];
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)handleDTapGesture:(UIGestureRecognizer*)sender {
+    [self flushLocalMatrix];
+    fMatrix.reset();
+}
+
+static float discretize(float x) {
+    return (int)x;
+}
+
+- (void)handlePanGesture:(UIPanGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    CGPoint delta = [sender translationInView:self];
+    delta.x *= gScreenScale;
+    delta.y *= gScreenScale;
+    // avoid flickering where the drawing might toggle in and out of a pixel
+    // center if translated by a fractional value
+    delta.x = discretize(delta.x);
+    delta.y = discretize(delta.y);
+    fLocalMatrix.setTranslate(delta.x, delta.y);
+    [self localMatrixWithGesture:sender];
+
+    if (UIGestureRecognizerStateEnded == sender.state) {
+        CGPoint velocity = [sender velocityInView:self];
+        fFlingState.reset(velocity.x, velocity.y);
+        fNeedGestureEnded = true;
+    }
+}
+
+- (float)limitTotalZoom:(float)scale {
+    // this query works 'cause we know that we're square-scale w/ no skew/rotation
+    const float curr = fMatrix[0];
+
+    if (scale > 1 && curr * scale > MAX_ZOOM_SCALE) {
+        scale = MAX_ZOOM_SCALE / curr;
+    } else if (scale < 1 && curr * scale < MIN_ZOOM_SCALE) {
+        scale = MIN_ZOOM_SCALE / curr;
+    }
+    return scale;
+}
+
+- (void)handleScaleGesture:(UIPinchGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    if ([sender numberOfTouches] == 2) {
+        float scale = sender.scale;
+        CGPoint p0 = [sender locationOfTouch:0 inView:self];
+        CGPoint p1 = [sender locationOfTouch:0 inView:self];
+        float cx = (p0.x + p1.x) * 0.5;
+        float cy = (p0.y + p1.y) * 0.5;
+
+        if (fNeedFirstPinch) {
+            fFirstPinchX = cx;
+            fFirstPinchY = cy;
+            fNeedFirstPinch = false;
+        }
+
+        scale = [self limitTotalZoom:scale];
+
+        fLocalMatrix.setTranslate(-fFirstPinchX, -fFirstPinchY);
+        fLocalMatrix.postScale(scale, scale);
+        fLocalMatrix.postTranslate(cx, cy);
+        [self localMatrixWithGesture:sender];
+    } else {
+        [self flushLocalMatrix];
+    }
+}
+
+- (void)handleLongPressGesture:(UILongPressGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    if ([sender numberOfTouches] == 0) {
+        fZoomAround = false;
+        return;
+    }
+
+    CGPoint pt = [sender locationOfTouch:0 inView:self];
+    switch (sender.state) {
+        case UIGestureRecognizerStateBegan:
+        case UIGestureRecognizerStateChanged:
+            fZoomAround = true;
+            fZoomAroundX = pt.x;
+            fZoomAroundY = pt.y - Y_OFFSET_FOR_ZOOM_LENS;
+            break;
+        case UIGestureRecognizerStateEnded:
+        case UIGestureRecognizerStateCancelled:
+            fZoomAround = false;
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)addAndReleaseGesture:(UIGestureRecognizer*)gesture {
+    [self addGestureRecognizer:gesture];
+    [gesture release];
+}
+
+- (void)initGestures {
+    UITapGestureRecognizer* tapG = [UITapGestureRecognizer alloc];
+    [tapG initWithTarget:self action:@selector(handleDTapGesture:)];
+    tapG.numberOfTapsRequired = 2;
+    [self addAndReleaseGesture:tapG];
+
+    UIPanGestureRecognizer* panG = [UIPanGestureRecognizer alloc];
+    [panG initWithTarget:self action:@selector(handlePanGesture:)];
+    [self addAndReleaseGesture:panG];
+    
+    UIPinchGestureRecognizer* pinchG = [UIPinchGestureRecognizer alloc];
+    [pinchG initWithTarget:self action:@selector(handleScaleGesture:)];
+    [self addAndReleaseGesture:pinchG];
+
+    UILongPressGestureRecognizer* longG = [UILongPressGestureRecognizer alloc];
+    [longG initWithTarget:self action:@selector(handleLongPressGesture:)];
+    [self addAndReleaseGesture:longG];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static float abs(float x) { return x < 0 ? -x : x; }
+
+static bool normalize(UIAcceleration* acc, float xy[]) {
+    float mag2 = acc.x*acc.x + acc.y*acc.y + acc.z*acc.z;
+    if (mag2 < 0.000001) {
+        return false;
+    }
+    if (abs((float)acc.z) > 0.9 * sqrt(mag2)) {
+        return false;
+    }
+
+    mag2 = acc.x*acc.x + acc.y*acc.y;
+    if (mag2 < 0.000001) {
+        return false;
+    }
+    float scale = 1 / sqrt(mag2);
+    xy[0] = acc.x * scale;
+    xy[1] = acc.y * scale;
+    return true;
+}
+
+static void normalize(float xy[]) {
+    float scale = 1 / sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
+    xy[0] *= scale;
+    xy[1] *= scale;
+}
+
+static float weighted_average(float newv, float oldv) {
+    return newv * 0.25 + oldv * 0.75;
+}
+
+- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acc {
+
+    float norm[2];
+    if (normalize(acc, norm)) {
+        float sinv = -norm[0];
+        float cosv = -norm[1];
+        // smooth
+        norm[0] = weighted_average(sinv, -fRotateMatrix[1]);
+        norm[1] = weighted_average(cosv, fRotateMatrix[0]);
+        normalize(norm);
+        fRotateMatrix.setSinCos(norm[0], norm[1], 400, 400);
+    }
+#if 0
+    NSDate *now = [NSDate date];
+    NSTimeInterval intervalDate = [now timeIntervalSinceDate:now_prev];
+    
+    velX += (acceleration.x * intervalDate);
+    distX += (velX * intervalDate);
+    //do other axis here too
+    
+    // setup for next UIAccelerometer event
+    now_prev = now;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)setSkTitle:(const char *)title {
+    if (fTitleLabel) {
+        fTitleLabel.text = [NSString stringWithUTF8String:title];
+        [fTitleLabel setNeedsDisplay];
+    }
+}
+
+- (BOOL)onHandleEvent:(const SkEvent&)evt {
+    if (evt.isType(kREDRAW_UIVIEW_GL)) {
+        [self drawInGL];
+        return true;
+    }
+    return false;
+}
+
+- (void)postInvalWithRect:(const SkIRect*)r {
+#ifdef USE_GL
+
+#if 1
+    if (!fRedrawRequestPending) {
+        fRedrawRequestPending = true;
+        /*
+            performSelectorOnMainThread seems to starve updating other views
+            (e.g. our FPS view in the titlebar), so we use the afterDelay
+            version
+         */
+        if (0) {
+            [self performSelectorOnMainThread:@selector(drawInGL) withObject:nil waitUntilDone:NO];
+        } else {
+            [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
+        }
+    }
+#else
+    if (!fRedrawRequestPending) {
+        SkEvent* evt = new SkEvent(kREDRAW_UIVIEW_GL);
+        evt->post(fWind->getSinkID());
+        fRedrawRequestPending = true;
+    }
+#endif
+
+#else
+    if (r) {
+        [self setNeedsDisplayInRect:CGRectMake(r->fLeft, r->fTop,
+                                               r->width(), r->height())];
+    } else {
+        [self setNeedsDisplay];
+    }
+#endif
+}
+
+@end
diff --git a/include/config/SkUserConfig.h b/include/config/SkUserConfig.h
index c0bbb4b..13169ca 100644
--- a/include/config/SkUserConfig.h
+++ b/include/config/SkUserConfig.h
@@ -123,6 +123,11 @@
  */
 //#define SK_ZLIB_INCLUDE <zlib.h>
 
+/*  Define this to allow PDF scalars above 32k.  The PDF/A spec doesn't allow
+    them, but modern PDF interpreters should handle them just fine.
+ */
+//#define SK_ALLOW_LARGE_PDF_SCALARS
+
 /*  Define this to remove dimension checks on bitmaps. Not all blits will be
     correct yet, so this is mostly for debugging the implementation.
  */
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 64a2a5b..349489e 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -40,7 +40,7 @@
     Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target
     of a SkCanvas' drawing operations.
 */
-class SkBitmap {
+class SK_API SkBitmap {
 public:
     class Allocator;
 
@@ -401,6 +401,13 @@
     */
     void* getAddr(int x, int y) const;
 
+    /** Return the SkColor of the specified pixel.  In most cases this will
+        require un-premultiplying the color.  Alpha only configs (A1 and A8)
+        return black with the appropriate alpha set.  The value is undefined
+        for kNone_Config or if x or y are out of bounds.
+    */
+    SkColor getColor(int x, int y) const;
+
     /** Returns the address of the pixel specified by x,y for 32bit pixels.
     */
     inline uint32_t* getAddr32(int x, int y) const;
@@ -461,18 +468,18 @@
     */
     int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
 
-    void extractAlpha(SkBitmap* dst) const {
-        this->extractAlpha(dst, NULL, NULL, NULL);
+    bool extractAlpha(SkBitmap* dst) const {
+        return this->extractAlpha(dst, NULL, NULL, NULL);
     }
 
-    void extractAlpha(SkBitmap* dst, const SkPaint* paint,
+    bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
                       SkIPoint* offset) const {
-        this->extractAlpha(dst, paint, NULL, offset);
+        return this->extractAlpha(dst, paint, NULL, offset);
     }
 
     /** Set dst to contain alpha layer of this bitmap. If destination bitmap
         fails to be initialized, e.g. because allocator can't allocate pixels
-        for it, dst will be resetted (zero width and height, no pixels).
+        for it, dst will not be modified and false will be returned.
 
         @param dst The bitmap to be filled with alpha layer
         @param paint The paint to draw with
@@ -483,7 +490,7 @@
                       the returned bitmap so that it visually lines up with the
                       original
     */
-    void extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
+    bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
                       SkIPoint* offset) const;
 
     void flatten(SkFlattenableWriteBuffer&) const;
diff --git a/include/core/SkBlitRow.h b/include/core/SkBlitRow.h
index 2b652c2..bb8cbc2 100644
--- a/include/core/SkBlitRow.h
+++ b/include/core/SkBlitRow.h
@@ -18,9 +18,9 @@
     /** Function pointer that reads a scanline of src SkPMColors, and writes
         a corresponding scanline of 16bit colors (specific format based on the
         config passed to the Factory.
-     
+
         The x,y params are useful just for dithering
-     
+
         @param alpha A global alpha to be applied to all of the src colors
         @param x The x coordinate of the beginning of the scanline
         @param y THe y coordinate of the scanline
@@ -29,7 +29,7 @@
                          const SkPMColor* SK_RESTRICT src,
                          int count, U8CPU alpha, int x, int y);
 
-   /** Function pointer that blends a single color with a row of 32-bit colors 
+   /** Function pointer that blends a single color with a row of 32-bit colors
        onto a 32-bit destination
    */
    typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count,
@@ -56,12 +56,12 @@
                          int count, U8CPU alpha);
 
     static Proc32 Factory32(unsigned flags32);
-    
+
     /** Blend a single color onto a row of S32 pixels, writing the result
         into a row of D32 pixels. src and dst may be the same memory, but
         if they are not, they may not overlap.
      */
-    static void Color32(SkPMColor dst[], const SkPMColor src[], 
+    static void Color32(SkPMColor dst[], const SkPMColor src[],
                         int count, SkPMColor color);
 
     static ColorProc ColorProcFactory();
@@ -84,4 +84,29 @@
     };
 };
 
+/**
+ *  Factory for blitmask procs
+ */
+class SkBlitMask {
+public:
+    /**
+     *  Function pointer that blits the mask into a device (dst) colorized
+     *  by color. The number of pixels to blit is specified by width and height,
+     *  but each scanline is offset by dstRB (rowbytes) and srcRB respectively.
+     */
+    typedef void (*Proc)(void* dst, size_t dstRB, SkBitmap::Config dstConfig,
+                        const uint8_t* mask, size_t maskRB, SkColor color,
+                        int width, int height);
+
+    /* Public entry-point to return a blitmask function ptr
+     */
+    static Proc Factory(SkBitmap::Config dstConfig, SkColor color);
+
+    /* return either platform specific optimized blitmask function-ptr,
+     * or NULL if no optimized
+     */
+    static Proc PlatformProcs(SkBitmap::Config dstConfig, SkColor color);
+};
+
+
 #endif
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 103507c..0a1b393 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -51,7 +51,7 @@
     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
     etc.
 */
-class SkCanvas : public SkRefCnt {
+class SK_API SkCanvas : public SkRefCnt {
 public:
     /** Construct a canvas with the given device factory.
         @param factory  Specify the factory for generating additional devices.
@@ -626,6 +626,7 @@
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint& paint);
 
+#ifdef ANDROID
     /** Draw the text on path, with each character/glyph origin specified by the pos[]
         array. The origin is interpreted by the Align setting in the paint.
         @param text The text to be drawn
@@ -638,6 +639,7 @@
     void drawPosTextOnPath(const void* text, size_t byteLength,
                            const SkPoint pos[], const SkPaint& paint,
                            const SkPath& path, const SkMatrix* matrix);
+#endif
 
     /** Draw the picture into this canvas. This method effective brackets the
         playback of the picture's draw calls with save/restore, so the state
@@ -740,6 +742,12 @@
     */
     const SkRegion& getTotalClip() const;
 
+    /**
+     *  Return the current clipstack. This mirrors the result in getTotalClip()
+     *  but is represented as a stack of geometric clips + region-ops.
+     */
+    const SkClipStack& getTotalClipStack() const;
+
     void setExternalMatrix(const SkMatrix* = NULL);
 
     ///////////////////////////////////////////////////////////////////////////
@@ -750,7 +758,7 @@
         call made on the canvas. Ownership of all pointers in the iterator stays
         with the canvas, so none of them should be modified or deleted.
     */
-    class LayerIter /*: SkNoncopyable*/ {
+    class SK_API LayerIter /*: SkNoncopyable*/ {
     public:
         /** Initialize iterator with canvas, and set values for 1st device */
         LayerIter(SkCanvas*, bool skipEmptyClips);
@@ -801,7 +809,8 @@
     SkDevice*   fLastDeviceToGainFocus;
     SkDeviceFactory* fDeviceFactory;
 
-    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&);
+    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
+                              const SkClipStack& clipStack);
 
     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
     void updateDeviceCMCache();
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index fb94155..850a3f0 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -7,7 +7,7 @@
 struct SkRect;
 class SkPath;
 
-class SkClipStack {
+class SK_API SkClipStack {
 public:
     SkClipStack();
     ~SkClipStack() {}
@@ -29,6 +29,11 @@
 
     class B2FIter {
     public:
+        /**
+         * Creates an uninitialized iterator. Must be reset()
+         */
+        B2FIter();
+
         B2FIter(const SkClipStack& stack);
 
         struct Clip {
@@ -48,6 +53,11 @@
          */
         const Clip* next();
 
+        /**
+         * Restarts the iterator on a clip stack.
+         */
+        void reset(const SkClipStack& stack);
+
     private:
         Clip             fClip;
         SkDeque::F2BIter fIter;
diff --git a/include/core/SkColor.h b/include/core/SkColor.h
index c17068f..6b86e7e 100644
--- a/include/core/SkColor.h
+++ b/include/core/SkColor.h
@@ -152,12 +152,12 @@
 
 /** Return a SkPMColor value from unpremultiplied 8 bit component values
 */
-SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
 /** Return a SkPMColor value from a SkColor value. This is done by multiplying the color
     components by the color's alpha, and by arranging the bytes in a configuration
     dependent order, to match the format of kARGB32 bitmaps.
 */
-SkPMColor SkPreMultiplyColor(SkColor c);
+SK_API SkPMColor SkPreMultiplyColor(SkColor c);
 
 /** Define a function pointer type for combining two premultiplied colors
 */
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index bd407da..f9e02a2 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -234,7 +234,7 @@
            (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
 }
 
-extern const uint32_t gMask_00FF00FF;
+SK_API extern const uint32_t gMask_00FF00FF;
 
 static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
     uint32_t mask = gMask_00FF00FF;
diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h
index 44a6148..b7537e1 100644
--- a/include/core/SkColorShader.h
+++ b/include/core/SkColorShader.h
@@ -24,7 +24,7 @@
     accomplished by just using the color field on the paint, but if an
     actual shader object is needed, this provides that feature.
 */
-class SkColorShader : public SkShader {
+class SK_API SkColorShader : public SkShader {
 public:
     /** Create a ColorShader that will inherit its color from the Paint
         at draw time.
@@ -47,17 +47,20 @@
     virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
     virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
 
-    virtual BitmapType asABitmap(SkBitmap* outTexture, 
+    virtual BitmapType asABitmap(SkBitmap* outTexture,
                                  SkMatrix* outMatrix,
-                                 TileMode xy[2], 
-                                 SkScalar* twoPointRadialParams);
+                                 TileMode xy[2],
+                                 SkScalar* twoPointRadialParams) const;
+
+    virtual GradientType asAGradient(GradientInfo* info) const;
+
 protected:
     SkColorShader(SkFlattenableReadBuffer& );
     virtual void flatten(SkFlattenableWriteBuffer& );
     virtual Factory getFactory() { return CreateProc; }
 private:
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 
-        return SkNEW_ARGS(SkColorShader, (buffer)); 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+        return SkNEW_ARGS(SkColorShader, (buffer));
     }
     SkColor     fColor;         // ignored if fInheritColor is true
     SkPMColor   fPMColor;       // cached after setContext()
@@ -66,7 +69,7 @@
     SkBool8     fInheritColor;
 
     // deferred allocation, used for asABitmap()
-    SkPixelRef* fAsABitmapPixelRef;
+    mutable SkPixelRef* fAsABitmapPixelRef;
 
     typedef SkShader INHERITED;
 };
diff --git a/include/core/SkDeque.h b/include/core/SkDeque.h
index 99c8dd4..8bf8b5b 100644
--- a/include/core/SkDeque.h
+++ b/include/core/SkDeque.h
@@ -19,7 +19,7 @@
 
 #include "SkTypes.h"
 
-class SkDeque : SkNoncopyable {
+class SK_API SkDeque : SkNoncopyable {
 public:
     explicit SkDeque(size_t elemSize);
     SkDeque(size_t elemSize, void* storage, size_t storageSize);
@@ -52,9 +52,16 @@
 public:
     class F2BIter {
     public:
+        /**
+         * Creates an uninitialized iterator. Must be reset()
+         */
+        F2BIter();
+
         F2BIter(const SkDeque& d);
         void* next();
 
+        void reset(const SkDeque& d);
+
     private:
         SkDeque::Head*  fHead;
         char*           fPos;
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 7791f34..2f95015 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -49,7 +49,7 @@
                                 int height, bool isOpaque, bool isLayer);
 };
 
-class SkDevice : public SkRefCnt {
+class SK_API SkDevice : public SkRefCnt {
 public:
     SkDevice(SkCanvas*);
     /** Construct a new device, extracting the width/height/config/isOpaque values from
@@ -81,6 +81,13 @@
     /** Return the height of the device (in pixels).
     */
     virtual int height() const { return fBitmap.height(); }
+
+    /**
+     *  Return the device's origin: its offset in device coordinates from
+     *  the default origin in its canvas' matrix/clip
+     */
+    const SkIPoint& getOrigin() const { return fOrigin; }
+
     /** Return the bitmap config of the device's pixels
     */
     SkBitmap::Config config() const { return fBitmap.getConfig(); }
@@ -141,7 +148,8 @@
     /** Called when this device gains focus (i.e becomes the current device
         for drawing).
     */
-    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&) {}
+    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
+                           const SkClipStack&) {}
 
     /** Causes any deferred drawing to the device to be completed.
      */
@@ -189,9 +197,11 @@
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint& paint);
+#ifdef ANDROID
     virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
                                    const SkPoint pos[], const SkPaint& paint,
                                    const SkPath& path, const SkMatrix* matrix);
+#endif
     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
                               const SkPoint verts[], const SkPoint texs[],
                               const SkColor colors[], SkXfermode* xmode,
@@ -204,6 +214,21 @@
 
     SkRefDict& getRefDict() { return fRefDict; }
 
+    struct TextFlags {
+        uint32_t            fFlags;     // SkPaint::getFlags()
+        SkPaint::Hinting    fHinting;
+    };
+
+    /**
+     *  Device may filter the text flags for drawing text here. If it wants to
+     *  make a change to the specified values, it should write them into the
+     *  textflags parameter (output) and return true. If the paint is fine as
+     *  is, then ignore the textflags parameter and return false.
+     *
+     *  The baseclass SkDevice filters based on its depth and blitters.
+     */
+    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
+
 protected:
     /** Update as needed the pixel value in the bitmap, so that the caller can access
         the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
@@ -219,9 +244,14 @@
     }
 
 private:
+    friend class SkCanvas;
+    // just called by SkCanvas when built as a layer
+    void setOrigin(int x, int y) { fOrigin.set(x, y); }
+
     SkCanvas*   fCanvas;
     SkBitmap    fBitmap;
     SkRefDict   fRefDict;
+    SkIPoint    fOrigin;
 };
 
 #endif
diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h
index fb2f292..99ab342 100644
--- a/include/core/SkDraw.h
+++ b/include/core/SkDraw.h
@@ -26,6 +26,7 @@
 #include "SkAutoKern.h"
 
 class SkBounder;
+class SkClipStack;
 class SkDevice;
 class SkPath;
 class SkRegion;
@@ -54,15 +55,17 @@
                         int scalarsPerPosition, const SkPaint& paint) const;
     void    drawTextOnPath(const char text[], size_t byteLength,
                         const SkPath&, const SkMatrix*, const SkPaint&) const;
+#ifdef ANDROID
     void    drawPosTextOnPath(const char text[], size_t byteLength,
                               const SkPoint pos[], const SkPaint& paint,
                               const SkPath& path, const SkMatrix* matrix) const;
+#endif
     void    drawVertices(SkCanvas::VertexMode mode, int count,
                          const SkPoint vertices[], const SkPoint textures[],
                          const SkColor colors[], SkXfermode* xmode,
                          const uint16_t indices[], int ptCount,
                          const SkPaint& paint) const;
-        
+
     void drawPath(const SkPath& src, const SkPaint& paint) const {
         this->drawPath(src, paint, NULL, false);
     }
@@ -87,6 +90,7 @@
     const SkMatrix* fMatrix;        // required
     const SkRegion* fClip;          // required
 
+    const SkClipStack* fClipStack;  // optional
     SkDevice*       fDevice;        // optional
     SkBounder*      fBounder;       // optional
     SkDrawProcs*    fProcs;         // optional
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
index 333fb41..87eb5cb 100644
--- a/include/core/SkDrawLooper.h
+++ b/include/core/SkDrawLooper.h
@@ -32,7 +32,7 @@
     invoked multiple times (hence the name loop-er), allow it to perform effects
     like shadows or frame/fills, that require more than one pass.
 */
-class SkDrawLooper : public SkFlattenable {
+class SK_API SkDrawLooper : public SkFlattenable {
 public:
     /** Called right before something is being drawn to the specified canvas
         with the specified paint. Subclass that want to modify either parameter
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index 6958462..ad4062f 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -33,7 +33,7 @@
  into a data stream for either transport or as part of the key to the
  font cache.
  */
-class SkFlattenable : public SkRefCnt {
+class SK_API SkFlattenable : public SkRefCnt {
 public:
     typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
     
diff --git a/include/core/SkFloatBits.h b/include/core/SkFloatBits.h
index 1628f6e..288f2d8 100644
--- a/include/core/SkFloatBits.h
+++ b/include/core/SkFloatBits.h
@@ -51,17 +51,17 @@
 /** Given the bit representation of a float, return its floor as an int.
     If the value is out of range, or NaN, return return +/- SK_MaxS32
  */
-int32_t SkFloatBits_toIntFloor(int32_t floatBits);
+SK_API int32_t SkFloatBits_toIntFloor(int32_t floatBits);
 
 /** Given the bit representation of a float, return it rounded to an int.
     If the value is out of range, or NaN, return return +/- SK_MaxS32
  */
-int32_t SkFloatBits_toIntRound(int32_t floatBits);
+SK_API int32_t SkFloatBits_toIntRound(int32_t floatBits);
 
 /** Given the bit representation of a float, return its ceiling as an int.
     If the value is out of range, or NaN, return return +/- SK_MaxS32
  */
-int32_t SkFloatBits_toIntCeil(int32_t floatBits);
+SK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits);
 
 
 #ifdef SK_CAN_USE_FLOAT
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index d70ba65..3c69251 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -279,6 +279,7 @@
     static void SetSubpixelOrder(LCDOrder order);
     static LCDOrder GetSubpixelOrder();
 
+#ifdef ANDROID
     ///////////////////////////////////////////////////////////////////////////
 
     /**
@@ -288,6 +289,7 @@
      * @return the number of font units per em or 0 on error.
      */
     static uint32_t GetUnitsPerEm(SkFontID fontID);
+#endif
 };
 
 #endif
diff --git a/include/core/SkGeometry.h b/include/core/SkGeometry.h
index a209783..d4b13fb 100644
--- a/include/core/SkGeometry.h
+++ b/include/core/SkGeometry.h
@@ -90,7 +90,7 @@
     convert it into the cubic fitting the same curve. The new cubic
     curve is returned in dst[0..3].
 */
-void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]);
+SK_API void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]);
 
 ////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/include/core/SkMask.h b/include/core/SkMask.h
index 58a2493..ebb870f 100644
--- a/include/core/SkMask.h
+++ b/include/core/SkMask.h
@@ -47,6 +47,7 @@
         kHorizontalLCD_Format,  //!< 4 bytes/pixel: a/r/g/b
         kVerticalLCD_Format,    //!< 4 bytes/pixel: a/r/g/b
         kARGB32_Format,         //!< SkPMColor
+        kLCD16_Format           //!< 565 alpha for r/g/b
     };
 
     enum {
@@ -96,6 +97,19 @@
         return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
     }
 
+    /**
+     *  Return the address of the specified 16bit mask. In the debug build,
+     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
+     *  are contained in the mask's fBounds.
+     */
+    uint16_t* getAddrLCD16(int x, int y) const {
+        SkASSERT(kLCD16_Format == fFormat);
+        SkASSERT(fBounds.contains(x, y));
+        SkASSERT(fImage != NULL);
+        uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
+        return row + (x - fBounds.fLeft);
+    }
+
     /** Return an address into the 32-bit plane of an LCD or VerticalLCD mask
         for the given position.
     */
@@ -120,7 +134,7 @@
 
     static uint8_t* AllocImage(size_t bytes);
     static void FreeImage(void* image);
-    
+
     enum CreateMode {
         kJustComputeBounds_CreateMode,      //!< compute bounds and return
         kJustRenderImage_CreateMode,        //!< render into preallocate mask
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 5c82d78..5ba9223 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -28,7 +28,7 @@
     using either reset() - to construct an identity matrix, or one of the set
     functions (e.g. setTranslate, setRotate, etc.).
 */
-class SkMatrix {
+class SK_API SkMatrix {
 public:
     /** Enum of bit fields for the mask return by getType().
         Use this to identify the complexity of the matrix.
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 3c847de..eec11cf 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -48,7 +48,7 @@
     The SkPaint class holds the style and color information about how to draw
     geometries, text and bitmaps.
 */
-class SkPaint {
+class SK_API SkPaint {
 public:
     SkPaint();
     SkPaint(const SkPaint& paint);
@@ -56,12 +56,11 @@
 
     SkPaint& operator=(const SkPaint&);
 
-    friend int operator==(const SkPaint& a, const SkPaint& b);
-    friend int operator!=(const SkPaint& a, const SkPaint& b)
-    {
+    SK_API friend int operator==(const SkPaint& a, const SkPaint& b);
+    friend int operator!=(const SkPaint& a, const SkPaint& b) {
         return !(a == b);
     }
-    
+
     void flatten(SkFlattenableWriteBuffer&) const;
     void unflatten(SkFlattenableReadBuffer&);
 
@@ -86,13 +85,11 @@
         kFull_Hinting          = 3,
     };
 
-    Hinting getHinting() const
-    {
+    Hinting getHinting() const {
         return static_cast<Hinting>(fHinting);
     }
 
-    void setHinting(Hinting hintingLevel)
-    {
+    void setHinting(Hinting hintingLevel) {
         if ((unsigned) hintingLevel != fHinting) {
             fGenerationID++;
             fHinting = hintingLevel;
@@ -133,34 +130,31 @@
     /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
         @return true if the antialias bit is set in the paint's flags.
         */
-    bool isAntiAlias() const
-    {
+    bool isAntiAlias() const {
         return SkToBool(this->getFlags() & kAntiAlias_Flag);
     }
-    
+
     /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
         @param aa   true to enable antialiasing, false to disable it
         */
     void setAntiAlias(bool aa);
-    
+
     /** Helper for getFlags(), returning true if kDither_Flag bit is set
         @return true if the dithering bit is set in the paint's flags.
         */
-    bool isDither() const
-    {
+    bool isDither() const {
         return SkToBool(this->getFlags() & kDither_Flag);
     }
-    
+
     /** Helper for setFlags(), setting or clearing the kDither_Flag bit
         @param dither   true to enable dithering, false to disable it
         */
     void setDither(bool dither);
-    
+
     /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
         @return true if the lineartext bit is set in the paint's flags
     */
-    bool isLinearText() const
-    {
+    bool isLinearText() const {
         return SkToBool(this->getFlags() & kLinearText_Flag);
     }
 
@@ -173,19 +167,17 @@
     /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
         @return true if the lineartext bit is set in the paint's flags
     */
-    bool isSubpixelText() const
-    {
+    bool isSubpixelText() const {
         return SkToBool(this->getFlags() & kSubpixelText_Flag);
     }
-    
+
     /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag
        bit @param subpixelText true to set the subpixelText bit in the paint's flags,
                                false to clear it.
     */
     void setSubpixelText(bool subpixelText);
 
-    bool isLCDRenderText() const
-    {
+    bool isLCDRenderText() const {
         return SkToBool(this->getFlags() & kLCDRenderText_Flag);
     }
 
@@ -195,8 +187,7 @@
     */
     void setLCDRenderText(bool subpixelRender);
 
-    bool isEmbeddedBitmapText() const
-    {
+    bool isEmbeddedBitmapText() const {
         return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
     }
 
@@ -206,8 +197,7 @@
     */
     void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
 
-    bool isAutohinted() const
-    {
+    bool isAutohinted() const {
         return SkToBool(this->getFlags() & kAutoHinting_Flag);
     }
 
@@ -221,8 +211,7 @@
     /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
         @return true if the underlineText bit is set in the paint's flags.
     */
-    bool isUnderlineText() const
-    {
+    bool isUnderlineText() const {
         return SkToBool(this->getFlags() & kUnderlineText_Flag);
     }
 
@@ -235,8 +224,7 @@
     /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
         @return true if the strikeThruText bit is set in the paint's flags.
     */
-    bool    isStrikeThruText() const
-    {
+    bool isStrikeThruText() const {
         return SkToBool(this->getFlags() & kStrikeThruText_Flag);
     }
 
@@ -249,8 +237,7 @@
     /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
         @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
     */
-    bool isFakeBoldText() const
-    {
+    bool isFakeBoldText() const {
         return SkToBool(this->getFlags() & kFakeBoldText_Flag);
     }
 
@@ -263,8 +250,7 @@
     /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
         @return true if the kernText bit is set in the paint's flags.
     */
-    bool isDevKernText() const
-    {
+    bool isDevKernText() const {
         return SkToBool(this->getFlags() & kDevKernText_Flag);
     }
 
@@ -274,17 +260,16 @@
     */
     void setDevKernText(bool devKernText);
 
-    bool isFilterBitmap() const
-    {
+    bool isFilterBitmap() const {
         return SkToBool(this->getFlags() & kFilterBitmap_Flag);
     }
-    
+
     void setFilterBitmap(bool filterBitmap);
 
     /** Styles apply to rect, oval, path, and text.
         Bitmaps are always drawn in "fill", and lines are always drawn in
         "stroke".
-     
+
         Note: strokeandfill implicitly draws the result with
         SkPath::kWinding_FillType, so if the original path is even-odd, the
         results may not appear the same as if it was drawn twice, filled and
@@ -331,7 +316,7 @@
         @return the alpha component of the paint's color.
         */
     uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
-    
+
     /** Helper to setColor(), that only assigns the color's alpha value,
         leaving its r,g,b values unchanged.
         @param a    set the alpha component (0..255) of the paint's color.
@@ -347,7 +332,7 @@
     */
     void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
 
-    /** Return the width for stroking. 
+    /** Return the width for stroking.
         <p />
         A value of 0 strokes in hairline mode.
         Hairlines always draw 1-pixel wide, regardless of the matrix.
@@ -356,7 +341,7 @@
     */
     SkScalar getStrokeWidth() const { return fWidth; }
 
-    /** Set the width for stroking. 
+    /** Set the width for stroking.
         Pass 0 to stroke in hairline mode.
         Hairlines always draw 1-pixel wide, regardless of the matrix.
         @param width set the paint's stroke width, used whenever the paint's
@@ -457,12 +442,12 @@
         effects in the paint (e.g. stroking). If needed, it uses the storage
         rect parameter. It returns the adjusted bounds that can then be used
         for quickReject tests.
-     
+
         The returned rect will either be orig or storage, thus the caller
         should not rely on storage being set to the result, but should always
         use the retured value. It is legal for orig and storage to be the same
         rect.
-        
+
         e.g.
         if (paint.canComputeFastBounds()) {
             SkRect r, storage;
@@ -495,7 +480,7 @@
         @return         shader
     */
     SkShader* setShader(SkShader* shader);
-    
+
     /** Get the paint's colorfilter. If there is a colorfilter, its reference
         count is not changed.
         @return the paint's colorfilter (or NULL)
@@ -616,8 +601,24 @@
     */
     SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
 
+    /**
+     *  Return the paint's SkDrawLooper (if any). Does not affect the looper's
+     *  reference count.
+     */
     SkDrawLooper* getLooper() const { return fLooper; }
-    SkDrawLooper* setLooper(SkDrawLooper*);
+
+    /**
+     *  Set or clear the looper object.
+     *  <p />
+     *  Pass NULL to clear any previous looper.
+     *  As a convenience, the parameter passed is also returned.
+     *  If a previous looper exists in the paint, its reference count is
+     *  decremented. If looper is not NULL, its reference count is
+     *  incremented.
+     *  @param looper May be NULL. The new looper to be installed in the paint.
+     *  @return looper
+     */
+    SkDrawLooper* setLooper(SkDrawLooper* looper);
 
     enum Align {
         kLeft_Align,
@@ -626,10 +627,12 @@
 
         kAlignCount
     };
+
     /** Return the paint's Align value for drawing text.
         @return the paint's Align value for drawing text.
     */
     Align   getTextAlign() const { return (Align)fTextAlign; }
+
     /** Set the paint's text alignment.
         @param align set the paint's Align value for drawing text.
     */
@@ -679,11 +682,8 @@
         kUTF16_TextEncoding,    //!< the text parameters are UTF16
         kGlyphID_TextEncoding   //!< the text parameters are glyph indices
     };
-    
-    TextEncoding getTextEncoding() const
-    {
-        return (TextEncoding)fTextEncoding;
-    }
+
+    TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
 
     void setTextEncoding(TextEncoding encoding);
 
@@ -698,11 +698,11 @@
         SkScalar    fXMax;      //!< The maximum bounding box x value for all glyphs
         SkScalar    fXHeight;   //!< the height of an 'x' in px, or 0 if no 'x' in face
     };
-    
+
     /** Return the recommend spacing between lines (which will be
         fDescent - fAscent + fLeading).
         If metrics is not null, return in it the font metrics for the
-        typeface/pointsize/etc. currently set in the paint. 
+        typeface/pointsize/etc. currently set in the paint.
         @param metrics      If not null, returns the font metrics for the
                             current typeface/pointsize/etc setting in this
                             paint.
@@ -711,7 +711,7 @@
         @param return the recommended spacing between lines
     */
     SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
-    
+
     /** Return the recommend line spacing. This will be
         fDescent - fAscent + fLeading
     */
@@ -745,8 +745,7 @@
         want to have the text converted into glyph IDs, call textToGlyphs
         instead.
     */
-    int countText(const void* text, size_t byteLength) const
-    {
+    int countText(const void* text, size_t byteLength) const {
         return this->textToGlyphs(text, byteLength, NULL);
     }
 
@@ -759,19 +758,18 @@
                             by this value
         @return             The advance width of the text
     */
-    SkScalar    measureText(const void* text, size_t length,
-                            SkRect* bounds, SkScalar scale = 0) const;
+    SkScalar measureText(const void* text, size_t length,
+                         SkRect* bounds, SkScalar scale = 0) const;
 
     /** Return the width of the text.
         @param text         Address of the text
         @param length       Number of bytes of text to measure
         @return The width of the text
     */
-    SkScalar measureText(const void* text, size_t length) const
-    {
+    SkScalar measureText(const void* text, size_t length) const {
         return this->measureText(text, length, NULL, 0);
     }
-    
+
     /** Specify the direction the text buffer should be processed in breakText()
     */
     enum TextBufferDirection {
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index eb5ff6d..24e260b 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -30,7 +30,7 @@
     The SkPath class encapsulates compound (multiple contour) geometric paths
     consisting of straight line segments, quadratic curves, and cubic curves.
 */
-class SkPath {
+class SK_API SkPath {
 public:
     SkPath();
     SkPath(const SkPath&);
@@ -72,7 +72,10 @@
      
         @param ft The new fill type for this path
     */
-    void setFillType(FillType ft) { fFillType = SkToU8(ft); }
+    void setFillType(FillType ft) {
+        fFillType = SkToU8(ft);
+        fGenerationID++;
+    }
 
     /** Returns true if the filltype is one of the Inverse variants */
     bool isInverseFillType() const { return (fFillType & 2) != 0; }
@@ -80,7 +83,10 @@
     /** Toggle between inverse and normal filltypes. This reverse the return
         value of isInverseFillType()
     */
-    void toggleInverseFillType() { fFillType ^= 2; }
+    void toggleInverseFillType() {
+        fFillType ^= 2;
+        fGenerationID++;
+     }
 
     /** Returns true if the path is flagged as being convex. This is not a
         confirmed by any analysis, it is just the value set earlier.
@@ -92,7 +98,10 @@
         not convex can give undefined results when drawn. Paths default to
         isConvex == false
      */
-    void setIsConvex(bool isConvex) { fIsConvex = (isConvex != 0); }
+    void setIsConvex(bool isConvex) {
+        fIsConvex = (isConvex != 0);
+        fGenerationID++;
+    }
 
     /** Clear any lines and curves from the path, making it empty. This frees up
         internal storage associated with those segments.
@@ -514,7 +523,7 @@
     /** Iterate through all of the segments (lines, quadratics, cubics) of
         each contours in a path.
     */
-    class Iter {
+    class SK_API Iter {
     public:
                 Iter();
                 Iter(const SkPath&, bool forceClose);
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
index f97adb7..eb1cc23 100644
--- a/include/core/SkPathEffect.h
+++ b/include/core/SkPathEffect.h
@@ -29,7 +29,7 @@
 
     Dashing is implemented as a subclass of SkPathEffect.
 */
-class SkPathEffect : public SkFlattenable {
+class SK_API SkPathEffect : public SkFlattenable {
 public:
     //  This method is not exported to java.
     SkPathEffect() {}
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index c0259af..177ecec 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -39,7 +39,7 @@
 class SkPixelRef : public SkRefCnt {
 public:
     explicit SkPixelRef(SkMutex* mutex = NULL);
-    
+
     /** Return the pixel memory returned from lockPixels, or null if the
         lockCount is 0.
     */
@@ -63,13 +63,13 @@
         memory (if the subclass implements caching/deferred-decoding.)
     */
     void unlockPixels();
-    
+
     /** Returns a non-zero, unique value corresponding to the pixels in this
         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
         called), a different generation ID will be returned.
     */
     uint32_t getGenerationID() const;
-    
+
     /** Call this if you have changed the contents of the pixels. This will in-
         turn cause a different generation ID value to be returned from
         getGenerationID().
@@ -80,7 +80,7 @@
         contents of its pixels will not change for the lifetime of the pixelref.
     */
     bool isImmutable() const { return fIsImmutable; }
-    
+
     /** Marks this pixelref is immutable, meaning that the contents of its
         pixels will not change for the lifetime of the pixelref. This state can
         be set on a pixelref, but it cannot be cleared once it is set.
@@ -97,13 +97,13 @@
     void setURI(const char uri[]) {
         fURI.set(uri);
     }
-    
+
     /** Copy a URI string to this pixelref
      */
     void setURI(const char uri[], size_t len) {
         fURI.set(uri, len);
     }
-    
+
     /** Assign a URI string to this pixelref.
     */
     void setURI(const SkString& uri) { fURI = uri; }
@@ -119,22 +119,26 @@
     virtual Factory getFactory() const { return NULL; }
     virtual void flatten(SkFlattenableWriteBuffer&) const;
 
-    /** Acquire a "global" ref on this object.
-    * The default implementation just calls ref(), but subclasses can override
-    * this method to implement additional behavior.
-    */
+#ifdef ANDROID
+    /**
+     *  Acquire a "global" ref on this object.
+     *  The default implementation just calls ref(), but subclasses can override
+     *  this method to implement additional behavior.
+     */
     virtual void globalRef(void* data=NULL);
 
-    /** Release a "global" ref on this object.
-    * The default implementation just calls unref(), but subclasses can override
-    * this method to implement additional behavior.
-    */
+    /**
+     *  Release a "global" ref on this object.
+     *  The default implementation just calls unref(), but subclasses can override
+     *  this method to implement additional behavior.
+     */
     virtual void globalUnref();
+#endif
 
     static Factory NameToFactory(const char name[]);
     static const char* FactoryToName(Factory);
     static void Register(const char name[], Factory);
-    
+
     class Registrar {
     public:
         Registrar(const char name[], Factory factory) {
@@ -165,9 +169,9 @@
     void*           fPixels;
     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
     int             fLockCount;
-    
+
     mutable uint32_t fGenerationID;
-    
+
     SkString    fURI;
 
     // can go from false to true, but never from true to false
diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h
index bdb30d9..c89f080 100644
--- a/include/core/SkPoint.h
+++ b/include/core/SkPoint.h
@@ -26,13 +26,28 @@
 */
 struct SkIPoint {
     int32_t fX, fY;
-    
+
     static SkIPoint Make(int32_t x, int32_t y) {
         SkIPoint pt;
         pt.set(x, y);
         return pt;
     }
 
+    int32_t x() const { return fX; }
+    int32_t y() const { return fY; }
+    void setX(int32_t x) { fX = x; }
+    void setY(int32_t y) { fY = y; }
+
+    /**
+     *  Returns true iff fX and fY are both zero.
+     */
+    bool isZero() const { return (fX | fY) == 0; }
+
+    /**
+     *  Set both fX and fY to zero. Same as set(0, 0)
+     */
+    void setZero() { fX = fY = 0; }
+
     /** Set the x and y values of the point. */
     void set(int32_t x, int32_t y) { fX = x; fY = y; }
 
@@ -55,11 +70,11 @@
         the point
     */
     void rotateCCW() { this->rotateCCW(this); }
-    
+
     /** Negate the X and Y coordinates of the point.
     */
     void negate() { fX = -fX; fY = -fY; }
-    
+
     /** Return a new point whose X and Y coordinates are the negative of the
         original point's
     */
@@ -75,7 +90,7 @@
         fX += v.fX;
         fY += v.fY;
     }
-    
+
     /** Subtract v's coordinates from this point's */
     void operator-=(const SkIPoint& v) {
         fX -= v.fX;
@@ -90,7 +105,7 @@
     friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
         return a.fX == b.fX && a.fY == b.fY;
     }
-    
+
     friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
         return a.fX != b.fX || a.fY != b.fY;
     }
@@ -111,7 +126,7 @@
         v.set(a.fX + b.fX, a.fY + b.fY);
         return v;
     }
-    
+
     /** Returns the dot product of a and b, treating them as 2D vectors
     */
     static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
@@ -125,7 +140,7 @@
     }
 };
 
-struct SkPoint {
+struct SK_API SkPoint {
     SkScalar    fX, fY;
 
     static SkPoint Make(SkScalar x, SkScalar y) {
@@ -133,10 +148,10 @@
         pt.set(x, y);
         return pt;
     }
-    
+
     /** Set the point's X and Y coordinates */
     void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
-    
+
     /** Set the point's X and Y coordinates by automatically promoting (x,y) to
         SkScalar values.
     */
@@ -144,7 +159,7 @@
         fX = SkIntToScalar(x);
         fY = SkIntToScalar(y);
     }
-    
+
     /** Set the point's X and Y coordinates by automatically promoting p's
         coordinates to SkScalar values.
     */
@@ -163,19 +178,19 @@
         return true.
     */
     bool normalize();
-    
+
     /** Set the point (vector) to be unit-length in the same direction as the
         x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
         then return false and do nothing, otherwise return true.
     */
     bool setNormalize(SkScalar x, SkScalar y);
-    
+
     /** Scale the point (vector) to have the specified length, and return that
         length. If the original length is degenerately small (nearly zero),
         do nothing and return false, otherwise return true.
     */
     bool setLength(SkScalar length);
-    
+
     /** Set the point (vector) to have the specified length in the same
      direction as (x,y). If the vector (x,y) has a degenerate length
      (i.e. nearly 0) then return false and do nothing, otherwise return true.
@@ -186,7 +201,7 @@
         It is legal for dst == this.
     */
     void scale(SkScalar scale, SkPoint* dst) const;
-    
+
     /** Scale the point's coordinates by scale, writing the answer back into
         the point.
     */
@@ -196,29 +211,29 @@
         It is legal for dst == this.
     */
     void rotateCW(SkPoint* dst) const;
-    
+
     /** Rotate the point clockwise by 90 degrees, writing the answer back into
         the point.
     */
     void rotateCW() { this->rotateCW(this); }
-    
+
     /** Rotate the point counter-clockwise by 90 degrees, writing the answer
         into dst. It is legal for dst == this.
     */
     void rotateCCW(SkPoint* dst) const;
-    
+
     /** Rotate the point counter-clockwise by 90 degrees, writing the answer
         back into the point.
     */
     void rotateCCW() { this->rotateCCW(this); }
-    
+
     /** Negate the point's coordinates
     */
     void negate() {
         fX = -fX;
         fY = -fY;
     }
-    
+
     /** Returns a new point whose coordinates are the negative of the point's
     */
     SkPoint operator-() const {
@@ -234,7 +249,7 @@
         fX += v.fX;
         fY += v.fY;
     }
-    
+
     /** Subtract v's coordinates from the point's
     */
     void operator-=(const SkPoint& v) {
@@ -249,7 +264,7 @@
     friend bool operator==(const SkPoint& a, const SkPoint& b) {
         return a.fX == b.fX && a.fY == b.fY;
     }
-    
+
     friend bool operator!=(const SkPoint& a, const SkPoint& b) {
         return a.fX != b.fX || a.fY != b.fY;
     }
diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h
index f907578..daf2041 100644
--- a/include/core/SkPreConfig.h
+++ b/include/core/SkPreConfig.h
@@ -96,5 +96,21 @@
     #define SK_CPU_HAS_CONDITIONAL_INSTR
 #endif
 
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SKIA_IMPLEMENTATION)
+    #define SKIA_IMPLEMENTATION 0
+#endif
+ 
+#if defined(WIN32) && defined(SKIA_DLL)
+    #if SKIA_IMPLEMENTATION
+        #define SK_API __declspec(dllexport)
+    #else
+        #define SK_API __declspec(dllimport)
+    #endif
+#else
+    #define SK_API
+#endif
+
 #endif
 
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index b6caad5..53c61ea 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -24,7 +24,7 @@
 
     SkIRect holds four 32 bit integer coordinates for a rectangle
 */
-struct SkIRect {
+struct SK_API SkIRect {
     int32_t fLeft, fTop, fRight, fBottom;
 
     static SkIRect MakeEmpty() {
@@ -95,6 +95,13 @@
         fBottom = bottom;
     }
 
+    void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + width;
+        fBottom = y + height;
+    }
+    
     /** Offset set the rectangle by adding dx to its left and right,
         and adding dy to its top and bottom.
     */
@@ -260,7 +267,7 @@
 
 /** \struct SkRect
 */
-struct SkRect {
+struct SK_API SkRect {
     SkScalar    fLeft, fTop, fRight, fBottom;
 
     static SkRect MakeEmpty() {
@@ -348,6 +355,13 @@
     */
     void set(const SkPoint pts[], int count);
 
+    void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + width;
+        fBottom = y + height;
+    }
+
     /** Offset set the rectangle by adding dx to its left and right,
         and adding dy to its top and bottom.
     */
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index f109ead..36f4249 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -29,7 +29,7 @@
     explicitly (or via the object going out of scope on the stack or calling
     delete) if getRefCnt() > 1.
 */
-class SkRefCnt : SkNoncopyable {
+class SK_API SkRefCnt : SkNoncopyable {
 public:
     /** Default construct, initializing the reference count to 1.
     */
@@ -67,36 +67,35 @@
     mutable int32_t fRefCnt;
 };
 
-/** \class SkAutoUnref
-
-    SkAutoUnref is a stack-helper class that will automatically call unref() on
-    the object it points to when the SkAutoUnref object goes out of scope.
-    If obj is null, do nothing.
-*/
-class SkAutoUnref : SkNoncopyable {
+/**
+ *  Utility class that simply unref's its argument in the destructor.
+ */
+template <typename T> class SkAutoTUnref : SkNoncopyable {
 public:
-    SkAutoUnref(SkRefCnt* obj) : fObj(obj) {}
-    ~SkAutoUnref();
+    SkAutoTUnref(T* obj) : fObj(obj) {}
+    ~SkAutoTUnref() { SkSafeUnref(fObj); }
 
-    SkRefCnt*   get() const { return fObj; }
+    T* get() const { return fObj; }
 
-    /** If the hosted object is null, do nothing and return false, else call
-        ref() on it and return true
-    */
-    bool        ref();
-
-    /** If the hosted object is null, do nothing and return false, else call
-        unref() on it, set its reference to null, and return true
-    */
-    bool        unref();
-
-    /** If the hosted object is null, do nothing and return NULL, else call
-        unref() on it, set its reference to null, and return the object
-    */
-    SkRefCnt*   detach();
+    /**
+     *  Return the hosted object (which may be null), transferring ownership.
+     *  The reference count is not modified, and the internal ptr is set to NULL
+     *  so unref() will not be called in our destructor. A subsequent call to
+     *  detach() will do nothing and return null.
+     */
+    T* detach() {
+        T* obj = fObj;
+        fObj = NULL;
+        return obj;
+    }
 
 private:
-    SkRefCnt*   fObj;
+    T*  fObj;
+};
+
+class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {
+public:
+    SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {}
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -148,32 +147,18 @@
         return *this;
     }
 
-    bool operator==(const SkRefPtr& rp) const { return fObj == rp.fObj; }
-    bool operator==(const T* obj) const { return fObj == obj; }
-    bool operator!=(const SkRefPtr& rp) const { return fObj != rp.fObj; }
-    bool operator!=(const T* obj) const { return fObj != obj; }
-
     T* get() const { return fObj; }
     T& operator*() const { return *fObj; }
     T* operator->() const { return fObj; }
-    bool operator!() const { return !fObj; }
 
     typedef T* SkRefPtr::*unspecified_bool_type;
-    operator unspecified_bool_type() const { return fObj ? &SkRefPtr::fObj : NULL; }
+    operator unspecified_bool_type() const {
+        return fObj ? &SkRefPtr::fObj : NULL;
+    }
 
 private:
     T* fObj;
 };
 
-template <typename T>
-inline bool operator==(T* obj, const SkRefPtr<T>& rp) {
-    return obj == rp.get();
-}
-
-template <typename T>
-inline bool operator!=(T* obj, const SkRefPtr<T>& rp) {
-    return obj != rp.get();
-}
-
 #endif
 
diff --git a/include/core/SkRefDict.h b/include/core/SkRefDict.h
index 3ee27d9..0c4b025 100644
--- a/include/core/SkRefDict.h
+++ b/include/core/SkRefDict.h
@@ -23,7 +23,7 @@
  *  A dictionary of string,refcnt pairs. The dictionary is also an owner of the
  *  refcnt objects while they are contained.
  */
-class SkRefDict : SkNoncopyable {
+class SK_API SkRefDict : SkNoncopyable {
 public:
     SkRefDict();
     ~SkRefDict();
diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h
index d8c4e00..4cda2cd 100644
--- a/include/core/SkRegion.h
+++ b/include/core/SkRegion.h
@@ -34,7 +34,7 @@
     The SkRegion class encapsulates the geometric region used to specify
     clipping areas for drawing.
 */
-class SkRegion {
+class SK_API SkRegion {
 public:
     typedef int32_t RunType;
     enum {
@@ -249,14 +249,16 @@
     */
     bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
 
+#ifdef ANDROID
     /** Returns a new char* containing the list of rectangles in this region
      */
     char* toString();
+#endif
 
     /** Returns the sequence of rectangles, sorted in Y and X, that make up
         this region.
     */
-    class Iterator {
+    class SK_API Iterator {
     public:
         Iterator() : fRgn(NULL), fDone(true) {}
         Iterator(const SkRegion&);
@@ -264,7 +266,7 @@
         bool rewind();
         // reset the iterator, using the new region
         void reset(const SkRegion&);
-        bool done() { return fDone; }
+        bool done() const { return fDone; }
         void next();
         const SkIRect& rect() const { return fRect; }
         // may return null
@@ -279,7 +281,7 @@
     /** Returns the sequence of rectangles, sorted in Y and X, that make up
         this region intersected with the specified clip rectangle.
     */
-    class Cliperator {
+    class SK_API Cliperator {
     public:
         Cliperator(const SkRegion&, const SkIRect& clip);
         bool            done() { return fDone; }
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index 5937819..55dfcef 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -53,18 +53,27 @@
         fMaskFormat     = MASK_FORMAT_UNKNOWN;
     }
 
-    unsigned rowBytes() const {
-        unsigned rb = fWidth;
-        if (SkMask::kBW_Format == fMaskFormat) {
+    /**
+     *  Compute the rowbytes for the specified width and mask-format.
+     */
+    static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
+        unsigned rb = width;
+        if (SkMask::kBW_Format == format) {
             rb = (rb + 7) >> 3;
-		} else if (SkMask::kARGB32_Format == fMaskFormat) {
+		} else if (SkMask::kARGB32_Format == format) {
 			rb <<= 2;
+		} else if (SkMask::kLCD16_Format == format) {
+			rb = SkAlign4(rb << 1);
         } else {
             rb = SkAlign4(rb);
         }
         return rb;
     }
 
+    unsigned rowBytes() const {
+        return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
+    }
+
     bool isJustAdvance() const {
         return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
     }
@@ -213,6 +222,10 @@
     SkScalerContext(const SkDescriptor* desc);
     virtual ~SkScalerContext();
 
+    SkMask::Format getMaskFormat() const {
+        return (SkMask::Format)fRec.fMaskFormat;
+    }
+
     // remember our glyph offset/base
     void setBaseGlyphCount(unsigned baseGlyphCount) {
         fBaseGlyphCount = baseGlyphCount;
@@ -230,7 +243,7 @@
     */
     SkUnichar glyphIDToChar(uint16_t glyphID);
 
-    unsigned    getGlyphCount() const { return this->generateGlyphCount(); }
+    unsigned    getGlyphCount() { return this->generateGlyphCount(); }
     void        getAdvance(SkGlyph*);
     void        getMetrics(SkGlyph*);
     void        getImage(const SkGlyph&);
@@ -245,7 +258,7 @@
     Rec         fRec;
     unsigned    fBaseGlyphCount;
 
-    virtual unsigned generateGlyphCount() const = 0;
+    virtual unsigned generateGlyphCount() = 0;
     virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
     virtual void generateAdvance(SkGlyph*) = 0;
     virtual void generateMetrics(SkGlyph*) = 0;
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 1cdbf17..d837284 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -32,7 +32,7 @@
     any object (other than a bitmap) that is drawn with that paint will get its color(s) from the
     shader.
 */
-class SkShader : public SkFlattenable {
+class SK_API SkShader : public SkFlattenable {
 public:
             SkShader();
     virtual ~SkShader();
@@ -80,7 +80,7 @@
             shadeSpan().
          */
         kConstInY32_Flag = 0x08,
-        
+
         /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
             which may not always be the case, since shadeSpan16 may be
             predithered, which would mean it was not const in Y, even though
@@ -101,7 +101,7 @@
         kHasSpan16_Flag is not set, this value is meaningless.
     */
     virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
-    
+
     /** Called once before drawing, with the current paint and
         device matrix. Return true if your shader supports these
         parameters, or false if not. If false is returned, nothing
@@ -144,7 +144,7 @@
     */
     virtual void beginSession();
     virtual void endSession();
-    
+
     /**
      Gives method bitmap should be read to implement a shader.
      Also determines number and interpretation of "extra" parameters returned
@@ -152,34 +152,35 @@
      */
     enum BitmapType {
         kNone_BitmapType,   //<! Shader is not represented as a bitmap
-        kDefault_BitmapType,//<! Access bitmap using local coords transformed 
+        kDefault_BitmapType,//<! Access bitmap using local coords transformed
                             //   by matrix. No extras
-        kRadial_BitmapType, //<! Access bitmap by transforming local coordinates 
-                            //   by the matrix and taking the distance of result 
-                            //   from  (0,0) as bitmap column. Bitmap is 1 pixel 
+        kRadial_BitmapType, //<! Access bitmap by transforming local coordinates
+                            //   by the matrix and taking the distance of result
+                            //   from  (0,0) as bitmap column. Bitmap is 1 pixel
                             //   tall. No extras
-        kSweep_BitmapType,  //<! Access bitmap by transforming local coordinates 
+        kSweep_BitmapType,  //<! Access bitmap by transforming local coordinates
                             //   by the matrix and taking the angle of result
                             //   to (0,0) as bitmap x coord, where angle = 0 is
-                            //   bitmap left edge of bitmap = 2pi is the 
+                            //   bitmap left edge of bitmap = 2pi is the
                             //   right edge. Bitmap is 1 pixel tall. No extras
-        kTwoPointRadial_BitmapType
-                            //<! Matrix transforms to space where (0,0) is 
+        kTwoPointRadial_BitmapType,
+                            //<! Matrix transforms to space where (0,0) is
                             //   the center of the starting circle.  The second
-                            //   circle will be centered (x, 0) where x  may be 
-                            //   0. The post-matrix space is normalized such 
+                            //   circle will be centered (x, 0) where x  may be
+                            //   0. The post-matrix space is normalized such
                             //   that 1 is the second radius - first radius.
                             //   Three extra parameters are returned:
-                            //      0: x-offset of second circle center 
+                            //      0: x-offset of second circle center
                             //         to first.
-                            //      1: radius of first circle in post-matrix 
+                            //      1: radius of first circle in post-matrix
                             //         space
                             //      2: the second radius minus the first radius
-                            //         in pre-transformed space.        
-        
+                            //         in pre-transformed space.
+
+       kLast_BitmapType = kTwoPointRadial_BitmapType
     };
     /** Optional methods for shaders that can pretend to be a bitmap/texture
-        to play along with opengl. Default just returns kNone_BitmapType and 
+        to play along with opengl. Default just returns kNone_BitmapType and
         ignores the out parameters.
 
         @param outTexture if non-NULL will be the bitmap representing the shader
@@ -194,7 +195,60 @@
                                     about the first point.
     */
     virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
-                                 TileMode xy[2], SkScalar* twoPointRadialParams);
+                                 TileMode xy[2], SkScalar* twoPointRadialParams) const;
+
+    /**
+     *  If the shader subclass can be represented as a gradient, asAGradient
+     *  returns the matching GradientType enum (or kNone_GradientType if it
+     *  cannot). Also, if info is not null, asAGradient populates info with
+     *  the relevant (see below) parameters for the gradient.  fColorCount
+     *  is both an input and output parameter.  On input, it indicates how
+     *  many entries in fColors and fColorOffsets can be used, if they are
+     *  non-NULL.  After asAGradient has run, fColorCount indicates how
+     *  many color-offset pairs there are in the gradient.  If there is
+     *  insufficient space to store all of the color-offset pairs, fColors
+     *  and fColorOffsets will not be altered.  fColorOffsets specifies
+     *  where on the range of 0 to 1 to transition to the given color.
+     *  The meaning of fPoint and fRadius is dependant on the type of gradient.
+     *
+     *  None:
+     *      info is ignored.
+     *  Color:
+     *      fColorOffsets[0] is meaningless.
+     *  Linear:
+     *      fPoint[0] and fPoint[1] are the end-points of the gradient
+     *  Radial:
+     *      fPoint[0] and fRadius[0] are the center and radius
+     *  Radial2:
+     *      fPoint[0] and fRadius[0] are the center and radius of the 1st circle
+     *      fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
+     *  Sweep:
+     *      fPoint[0] is the center of the sweep.
+     */
+
+    enum GradientType {
+        kNone_GradientType,
+        kColor_GradientType,
+        kLinear_GradientType,
+        kRadial_GradientType,
+        kRadial2_GradientType,
+        kSweep_GradientType,
+        kLast_GradientType = kSweep_GradientType
+    };
+
+    struct GradientInfo {
+        int         fColorCount;    //!< In-out parameter, specifies passed size
+                                    //   of fColors/fColorOffsets on input, and
+                                    //   actual number of colors/offsets on
+                                    //   output.
+        SkColor*    fColors;        //!< The colors in the gradient.
+        SkScalar*   fColorOffsets;  //!< The unit offset for color transitions.
+        SkPoint     fPoint[2];      //!< Type specific, see above.
+        SkScalar    fRadius[2];     //!< Type specific, see above.
+        TileMode    fTileMode;      //!< The tile mode used.
+    };
+
+    virtual GradientType asAGradient(GradientInfo* info) const;
 
     //////////////////////////////////////////////////////////////////////////
     //  Factory methods for stock shaders
diff --git a/include/core/SkString.h b/include/core/SkString.h
index 4498bba..eb25e15 100644
--- a/include/core/SkString.h
+++ b/include/core/SkString.h
@@ -30,8 +30,33 @@
 char*   SkStrAppendS32(char buffer[], int32_t);
 #define SkStrAppendS64_MaxSize  20
 char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
-#define SkStrAppendScalar_MaxSize  11
-char*   SkStrAppendScalar(char buffer[], SkScalar);
+
+/**
+ *  Floats have at most 8 significant digits, so we limit our %g to that.
+ *  However, the total string could be 15 characters: -1.2345678e-005
+ *
+ *  In theory we should only expect up to 2 digits for the exponent, but on
+ *  some platforms we have seen 3 (as in the example above).
+ */
+#define SkStrAppendScalar_MaxSize  15
+
+/**
+ *  Write the scaler in decimal format into buffer, and return a pointer to
+ *  the next char after the last one written. Note: a terminating 0 is not
+ *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
+ *  Thus if the caller wants to add a 0 at the end, buffer must be at least
+ *  SkStrAppendScalar_MaxSize + 1 bytes large.
+ */
+#ifdef SK_SCALAR_IS_FLOAT
+    #define SkStrAppendScalar SkStrAppendFloat
+#else
+    #define SkStrAppendScalar SkStrAppendFixed
+#endif
+
+#ifdef SK_CAN_USE_FLOAT
+char* SkStrAppendFloat(char buffer[], float);
+#endif
+char* SkStrAppendFixed(char buffer[], SkFixed);
 
 /** \class SkString
 
@@ -127,7 +152,7 @@
         to never fail or throw.
     */
     void    swap(SkString& other);
-    
+
 private:
     struct Rec {
     public:
diff --git a/include/core/SkTDArray.h b/include/core/SkTDArray.h
index 954bcf8..c64d773 100644
--- a/include/core/SkTDArray.h
+++ b/include/core/SkTDArray.h
@@ -19,7 +19,7 @@
 
 #include "SkTypes.h"
 
-template <typename T> class SkTDArray {
+template <typename T> class SK_API SkTDArray {
 public:
     SkTDArray() {
         fReserve = fCount = 0;
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index 728ba31..c3b0f50 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -32,7 +32,7 @@
 
     Typeface objects are immutable, and so they can be shared between threads.
 */
-class SkTypeface : public SkRefCnt {
+class SK_API SkTypeface : public SkRefCnt {
 public:
     /** Style specifies the intrinsic style attributes of a given typeface
     */
@@ -58,7 +58,7 @@
     bool isItalic() const { return (fStyle & kItalic) != 0; }
 
     /** Returns true if the typeface is fixed-width
-    */
+     */
     bool isFixedWidth() const { return fIsFixedWidth; }
 
     /** Return a 32bit value for this typeface, unique for the underlying font
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 8dbd51b..1290935 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -59,7 +59,7 @@
     return null (if SK_MALLOC_TEMP bit is clear) or call sk_throw()
     (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
 */
-extern void* sk_malloc_flags(size_t size, unsigned flags);
+SK_API extern void* sk_malloc_flags(size_t size, unsigned flags);
 /** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag
 */
 extern void* sk_malloc_throw(size_t size);
@@ -69,7 +69,7 @@
 extern void* sk_realloc_throw(void* buffer, size_t size);
 /** Free memory returned by sk_malloc(). It is safe to pass null.
 */
-extern void  sk_free(void*);
+SK_API extern void  sk_free(void*);
 
 // bzero is safer than memset, but we can't rely on it, so... sk_bzero()
 static inline void sk_bzero(void* buffer, size_t size) {
@@ -152,12 +152,12 @@
 typedef uint8_t SkBool8;
 
 #ifdef SK_DEBUG
-    int8_t      SkToS8(long);
-    uint8_t     SkToU8(size_t);
-    int16_t     SkToS16(long);
-    uint16_t    SkToU16(size_t);
-    int32_t     SkToS32(long);
-    uint32_t    SkToU32(size_t);
+    SK_API int8_t      SkToS8(long);
+    SK_API uint8_t     SkToU8(size_t);
+    SK_API int16_t     SkToS16(long);
+    SK_API uint16_t    SkToU16(size_t);
+    SK_API int32_t     SkToS32(long);
+    SK_API uint32_t    SkToU32(size_t);
 #else
     #define SkToS8(x)   ((int8_t)(x))
     #define SkToU8(x)   ((uint8_t)(x))
@@ -337,7 +337,7 @@
 SkNoncopyable is the base class for objects that may do not want to
 be copied. It hides its copy-constructor and its assignment-operator.
 */
-class SkNoncopyable {
+class SK_API SkNoncopyable {
 public:
     SkNoncopyable() {}
 
@@ -403,21 +403,70 @@
     }
 };
 
+/**
+ *  Manage an allocated block of memory. If the requested size is <= kSize, then
+ *  the allocation will come from the stack rather than the heap. This object
+ *  is the sole manager of the lifetime of the block, so the caller must not
+ *  call sk_free() or delete on the block.
+ */
 template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
 public:
-    explicit SkAutoSMalloc(size_t size)
-    {
-        if (size <= kSize)
-            fPtr = fStorage;
-        else
-            fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
+    /**
+     *  Creates initially empty storage. get() returns a ptr, but it is to
+     *  a zero-byte allocation. Must call realloc(size) to return an allocated
+     *  block.
+     */
+    SkAutoSMalloc() {
+        fPtr = fStorage;
     }
-    ~SkAutoSMalloc()
-    {
-        if (fPtr != (void*)fStorage)
+
+    /**
+     *  Allocate a block of the specified size. If size <= kSize, then the
+     *  allocation will come from the stack, otherwise it will be dynamically
+     *  allocated.
+     */
+    explicit SkAutoSMalloc(size_t size) {
+        fPtr = fStorage;
+        this->realloc(size);
+    }
+
+    /**
+     *  Free the allocated block (if any). If the block was small enought to
+     *  have been allocated on the stack (size <= kSize) then this does nothing.
+     */
+    ~SkAutoSMalloc() {
+        if (fPtr != (void*)fStorage) {
             sk_free(fPtr);
+        }
     }
+
+    /**
+     *  Return the allocated block. May return non-null even if the block is
+     *  of zero size. Since this may be on the stack or dynamically allocated,
+     *  the caller must not call sk_free() on it, but must rely on SkAutoSMalloc
+     *  to manage it.
+     */
     void* get() const { return fPtr; }
+
+    /**
+     *  Return a new block of the requested size, freeing (as necessary) any
+     *  previously allocated block. As with the constructor, if size <= kSize
+     *  then the return block may be allocated locally, rather than from the
+     *  heap.
+     */
+    void* realloc(size_t size) {
+        if (fPtr != (void*)fStorage) {
+            sk_free(fPtr);
+        }
+
+        if (size <= kSize) {
+            fPtr = fStorage;
+        } else {
+            fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
+        }
+        return fPtr;
+    }
+
 private:
     void*       fPtr;
     uint32_t    fStorage[(kSize + 3) >> 2];
diff --git a/include/core/SkUnPreMultiply.h b/include/core/SkUnPreMultiply.h
index 4bdb980..44ea50e 100644
--- a/include/core/SkUnPreMultiply.h
+++ b/include/core/SkUnPreMultiply.h
@@ -22,7 +22,7 @@
 
 #include "SkColor.h"
 
-class SkUnPreMultiply {
+class SK_API SkUnPreMultiply {
 public:
     typedef uint32_t Scale;
     
diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h
index a72aa1a..2140a15 100644
--- a/include/core/SkUserConfig.h
+++ b/include/core/SkUserConfig.h
@@ -18,18 +18,18 @@
 #define SkUserConfig_DEFINED
 
 /*  SkTypes.h, the root of the public header files, does the following trick:
- 
+
     #include "SkPreConfig.h"
     #include "SkUserConfig.h"
     #include "SkPostConfig.h"
- 
+
     SkPreConfig.h runs first, and it is responsible for initializing certain
     skia defines.
- 
+
     SkPostConfig.h runs last, and its job is to just check that the final
     defines are consistent (i.e. that we don't have mutually conflicting
     defines).
- 
+
     SkUserConfig.h (this file) runs in the middle. It gets to change or augment
     the list of flags initially set in preconfig, and then postconfig checks
     that everything still makes sense.
@@ -85,7 +85,7 @@
     parameter checking, but sometimes it can be quite intrusive (e.g. check that
     each 32bit pixel is in premultiplied form). This code can be very useful
     during development, but will slow things down in a shipping product.
- 
+
     By default, these mutually exclusive flags are defined in SkPreConfig.h,
     based on the presence or absence of NDEBUG, but that decision can be changed
     here.
@@ -134,6 +134,26 @@
 void Android_SkDebugf(const char* file, int line, 
                       const char* function, const char* format, ...);
 
+/*  To enable additional blitters (and fontscaler code) to support separate
+    alpha channels for R G B channels, define SK_SUPPORT_LCDTEXT
+ */
+//#define SK_SUPPORT_LCDTEXT
+
+/*  If zlib is available and you want to support the flate compression
+    algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the
+    include path.
+ */
+//#define SK_ZLIB_INCLUDE <zlib.h>
+
+/*  Define this to allow PDF scalars above 32k.  The PDF/A spec doesn't allow
+    them, but modern PDF interpreters should handle them just fine.
+ */
+//#define SK_ALLOW_LARGE_PDF_SCALARS
+
+/*  Define this to remove dimension checks on bitmaps. Not all blits will be
+    correct yet, so this is mostly for debugging the implementation.
+ */
+//#define SK_ALLOW_OVER_32K_BITMAPS
 
 /*  If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST
     which will run additional self-tests at startup. These can take a long time,
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 714468c..e954633 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -28,7 +28,7 @@
     specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
     then objects drawn with that paint have the xfermode applied.
 */
-class SkXfermode : public SkFlattenable {
+class SK_API SkXfermode : public SkFlattenable {
 public:
     SkXfermode() {}
 
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
index e7af5c2..101d24e 100644
--- a/include/effects/SkBlurDrawLooper.h
+++ b/include/effects/SkBlurDrawLooper.h
@@ -28,7 +28,7 @@
     the original object in its original position.
     should there be an option to just draw the shadow/blur layer? webkit?
 */
-class SkBlurDrawLooper : public SkDrawLooper {
+class SK_API SkBlurDrawLooper : public SkDrawLooper {
 public:
     enum BlurFlags {
         kNone_BlurFlag = 0x00,
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
index a459478..823de3f 100644
--- a/include/effects/SkCornerPathEffect.h
+++ b/include/effects/SkCornerPathEffect.h
@@ -24,7 +24,7 @@
     SkCornerPathEffect is a subclass of SkPathEffect that can turn sharp corners
     into various treatments (e.g. rounded corners)
 */
-class SkCornerPathEffect : public SkPathEffect {
+class SK_API SkCornerPathEffect : public SkPathEffect {
 public:
     /** radius must be > 0 to have an effect. It specifies the distance from each corner
         that should be "rounded".
diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h
index cc414e3..145f67d 100644
--- a/include/effects/SkDashPathEffect.h
+++ b/include/effects/SkDashPathEffect.h
@@ -23,7 +23,7 @@
 
     SkDashPathEffect is a subclass of SkPathEffect that implements dashing
 */
-class SkDashPathEffect : public SkPathEffect {
+class SK_API SkDashPathEffect : public SkPathEffect {
 public:
     /** The intervals array must contain an even number of entries (>=2), with the even
         indices specifying the "on" intervals, and the odd indices specifying the "off"
diff --git a/include/effects/SkGradientShader.h b/include/effects/SkGradientShader.h
index c800c66..5623be4 100644
--- a/include/effects/SkGradientShader.h
+++ b/include/effects/SkGradientShader.h
@@ -26,7 +26,7 @@
     SkGradientShader hosts factories for creating subclasses of SkShader that
     render linear and radial gradients.
 */
-class SkGradientShader {
+class SK_API SkGradientShader {
 public:
     /** Returns a shader that generates a linear gradient between the two
         specified points.
diff --git a/include/effects/SkPorterDuff.h b/include/effects/SkPorterDuff.h
index 4d7fb31..54f81ea 100644
--- a/include/effects/SkPorterDuff.h
+++ b/include/effects/SkPorterDuff.h
@@ -52,7 +52,9 @@
         kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
         kScreen_Mode,   //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
         kAdd_Mode,      //!< Saturate(S + D)
+#ifdef ANDROID
         kOverlay_Mode,
+#endif
 
         kModeCount
     };
diff --git a/include/gpu/SkGpuCanvas.h b/include/gpu/SkGpuCanvas.h
new file mode 100644
index 0000000..57a4b1b
--- /dev/null
+++ b/include/gpu/SkGpuCanvas.h
@@ -0,0 +1,68 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGpuCanvas_DEFINED
+#define SkGpuCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+class GrContext;
+class GrRenderTarget;
+
+/**
+ *  Subclass of canvas that creates devices compatible with the GrContext pass
+ *  to the canvas' constructor.
+ */
+class SkGpuCanvas : public SkCanvas {
+public:
+    /**
+     *  The GrContext object is reference counted. When passed to our
+     *  constructor, its reference count is incremented. In our destructor, the
+     *  GrGpu's reference count will be decremented.
+     *  GrRenderTarget represents the rendering destination in the underlying
+     *  3D API. Its reference count is incremented in the constructor and
+     *  decremented in the destructor.
+     *  SkGpuDevice::Current3DApiRenderTarget() can be passed as a special
+     *  value that will cause the factory to create a render target object
+     *  that reflects the state of the underlying 3D API at the time of
+     *  construction.
+     */
+    explicit SkGpuCanvas(GrContext*, GrRenderTarget*);
+    virtual ~SkGpuCanvas();
+
+    /**
+     *  Override from SkCanvas. Returns true, and if not-null, sets size to
+     *  be the width/height of our viewport.
+     */
+    virtual bool getViewport(SkIPoint* size) const;
+
+#if 0
+    virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+                          SaveFlags flags = kARGB_ClipLayer_SaveFlag) {
+        return this->save(flags);
+    }
+#endif
+
+private:
+    GrContext* fContext;
+
+    typedef SkCanvas INHERITED;
+};
+
+#endif
+
+
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
new file mode 100644
index 0000000..8852803
--- /dev/null
+++ b/include/gpu/SkGpuDevice.h
@@ -0,0 +1,185 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGpuDevice_DEFINED
+#define SkGpuDevice_DEFINED
+
+#include "SkGr.h"
+#include "SkDevice.h"
+#include "SkRegion.h"
+
+struct SkDrawProcs;
+struct GrSkDrawProcs;
+class GrTextContext;
+
+/**
+ *  Subclass of SkDevice, which directs all drawing to the GrGpu owned by the
+ *  canvas.
+ */
+class SkGpuDevice : public SkDevice {
+public:
+    /**
+     * The SkGpuDevice will render to the GrRenderTarget, or if the paremeter is
+     * null it will create its own render target and manage that target's
+     * lifetime.
+     */
+    SkGpuDevice(GrContext*,
+                const SkBitmap& bitmap,
+                GrRenderTarget* renderTargetOrNull);
+
+    /**
+     * Magic value that can be passed to constructor. Causes
+     * the device to infer rendertarget from underlying 3D API (e.g. GL or D3D).
+     * This isn't a valid pointer, don't attempt to dereference.
+     */
+    static GrRenderTarget* Current3DApiRenderTarget();
+
+    virtual ~SkGpuDevice();
+
+    GrContext* context() const { return fContext; }
+
+    /**
+     *  If this device was built for rendering as a layer (i.e. offscreen),
+     *  then this will return the platform-specific handle to that GPU resource.
+     *  For example, in OpenGL, this will return the FBO's texture ID.
+     *  If this device was not built for rendering as a layer, then 0
+     *  is returned.
+     */
+    intptr_t getLayerTextureHandle() const;
+
+    // call to set the clip to the specified rect
+    void scissor(const SkIRect&);
+
+    /**
+     *  Override from SkGpuDevice, so we can set our FBO to be the render target
+     *  The canvas parameter must be a SkGpuCanvas
+     */
+    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
+                           const SkClipStack& clipStack);
+
+    virtual SkGpuTexture* accessTexture() { return (SkGpuTexture*)fTexture; }
+
+    // overrides from SkDevice
+
+    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
+    virtual void writePixels(const SkBitmap& bitmap, int x, int y);
+
+    virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
+                               const SkClipStack&);
+
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
+    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+                            const SkPoint[], const SkPaint& paint);
+    virtual void drawRect(const SkDraw&, const SkRect& r,
+                          const SkPaint& paint);
+    virtual void drawPath(const SkDraw&, const SkPath& path,
+                          const SkPaint& paint, const SkMatrix* prePathMatrix,
+                          bool pathIsMutable);
+    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+                            const SkIRect* srcRectOrNull,
+                            const SkMatrix& matrix, const SkPaint& paint);
+    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+                            int x, int y, const SkPaint& paint);
+    virtual void drawText(const SkDraw&, const void* text, size_t len,
+                          SkScalar x, SkScalar y, const SkPaint& paint);
+    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+                             const SkScalar pos[], SkScalar constY,
+                             int scalarsPerPos, const SkPaint& paint);
+    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+                                const SkPath& path, const SkMatrix* matrix,
+                                const SkPaint& paint);
+    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+                              const SkPoint verts[], const SkPoint texs[],
+                              const SkColor colors[], SkXfermode* xmode,
+                              const uint16_t indices[], int indexCount,
+                              const SkPaint& paint);
+    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
+                            const SkPaint&);
+    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
+
+    virtual void flush() { fContext->flush(false); }
+
+    /**
+     * Make's this device's rendertarget current in the underlying 3D API.
+     * Also implicitly flushes.
+     */
+    virtual void makeRenderTargetCurrent();
+
+protected:
+    class TexCache;
+    TexCache* lockCachedTexture(const SkBitmap& bitmap,
+                                const GrSamplerState& sampler,
+                                GrTexture** texture,
+                                bool forDeviceRenderTarget = false);
+    void unlockCachedTexture(TexCache*);
+
+    class SkAutoCachedTexture {
+    public:
+        SkAutoCachedTexture();
+        SkAutoCachedTexture(SkGpuDevice* device,
+                            const SkBitmap& bitmap,
+                            const GrSamplerState& sampler,
+                            GrTexture** texture);
+        ~SkAutoCachedTexture();
+
+        GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState&);
+
+    private:
+        SkGpuDevice*    fDevice;
+        TexCache*       fTex;
+    };
+    friend class SkAutoTexCache;
+
+private:
+    GrContext*      fContext;
+
+    GrSkDrawProcs*  fDrawProcs;
+
+    // state for our offscreen render-target
+    TexCache*       fCache;
+    GrTexture*      fTexture;
+    GrRenderTarget* fRenderTarget;
+    bool            fNeedClear;
+    bool            fNeedPrepareRenderTarget;
+
+    // doesn't set the texture/sampler/matrix state
+    // caller needs to null out GrPaint's texture if
+    // non-textured drawing is desired.
+    bool skPaint2GrPaintNoShader(const SkPaint& skPaint,
+                                 bool justAlpha,
+                                 GrPaint* grPaint);
+
+    // uses the SkShader to setup paint, act used to
+    // hold lock on cached texture and free it when
+    // destroyed.
+    bool skPaint2GrPaintShader(const SkPaint& skPaint,
+                               SkAutoCachedTexture* act,
+                               const SkMatrix& ctm,
+                               GrPaint* grPaint);
+
+    SkDrawProcs* initDrawForText(GrTextContext*);
+    bool bindDeviceAsTexture(GrPaint* paint);
+
+    void prepareRenderTarget(const SkDraw&);
+    void internalDrawBitmap(const SkDraw&, const SkBitmap&,
+                            const SkIRect&, const SkMatrix&, GrPaint* grPaint);
+
+    typedef SkDevice INHERITED;
+};
+
+#endif
+
diff --git a/include/gpu/SkGpuDeviceFactory.h b/include/gpu/SkGpuDeviceFactory.h
new file mode 100644
index 0000000..5dcba6a
--- /dev/null
+++ b/include/gpu/SkGpuDeviceFactory.h
@@ -0,0 +1,49 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef SkGpuDeviceFactory_DEFINED
+#define SkGpuDeviceFactory_DEFINED
+
+#include "SkDevice.h"
+
+class GrContext;
+
+class SkGpuDeviceFactory : public SkDeviceFactory {
+public:
+    /**
+     *  The constructor will ref() the context, passing it to each device
+     *  that it creates. It will be unref()'d in the destructor
+     *  Non-layered devices created by the factory will draw to the
+     *  rootRenderTarget. rootRenderTarget is ref-counted by the factory.
+     *  SkGpuDevice::Current3DApiRenderTarget() can be passed as a special
+     *  value that will cause the factory to create a render target object
+     *  that reflects the state of the underlying 3D API at the time of
+     *  construction.
+     */
+    SkGpuDeviceFactory(GrContext*, GrRenderTarget* rootRenderTarget);
+
+    virtual ~SkGpuDeviceFactory();
+
+    virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
+                                int height, bool isOpaque, bool isLayer);
+
+private:
+    GrContext* fContext;
+    GrRenderTarget* fRootRenderTarget;
+};
+
+#endif
+
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
new file mode 100644
index 0000000..7221213
--- /dev/null
+++ b/include/gpu/SkGr.h
@@ -0,0 +1,299 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGr_DEFINED
+#define SkGr_DEFINED
+
+#include <stddef.h>
+
+// Gr headers
+#include "GrConfig.h"
+#include "GrContext.h"
+#include "GrFontScaler.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+
+// skia headers
+#include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+#include "SkClipStack.h"
+
+#if (GR_DEBUG && defined(SK_RELEASE)) || (GR_RELEASE && defined(SK_DEBUG))
+//    #error "inconsistent GR_DEBUG and SK_DEBUG"
+#endif
+
+#if GR_SCALAR_IS_FIXED
+    #ifdef SK_SCALAR_IS_FIXED
+        #define SK_SCALAR_IS_GR_SCALAR  1
+    #else
+        #define SK_SCALAR_IS_GR_SCALAR  0
+    #endif
+    #define SkScalarToGrScalar(x)       SkScalarToFixed(x)
+
+#elif GR_SCALAR_IS_FLOAT
+
+    #ifdef SK_SCALAR_IS_FLOAT
+        #define SK_SCALAR_IS_GR_SCALAR  1
+    #else
+        #define SK_SCALAR_IS_GR_SCALAR  0
+    #endif
+    #define SkScalarToGrScalar(x)       SkScalarToFloat(x)
+
+#else
+    #error "Ganesh scalar type not defined"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Sk to Gr Type conversions
+
+// Verify that SkPoint and GrPoint are compatible if using the same scalar type
+#if 0/*SK_SCALAR_IS_GR_SCALAR*/
+    GR_STATIC_ASSERT(sizeof(SkPoint) == sizeof(GrPoint));
+    GR_STATIC_ASSERT(offsetof(SkPoint,fX) == offsetof(GrPoint,fX)));
+    GR_STATIC_ASSERT(offsetof(SkPoint,fY) == offsetof(GrPoint,fY)));
+#endif
+
+GR_STATIC_ASSERT((int)GrSamplerState::kClamp_WrapMode == (int)SkShader::kClamp_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kRepeat_WrapMode ==(
+                 int)SkShader::kRepeat_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode ==
+                 (int)SkShader::kMirror_TileMode);
+
+#define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X))
+
+GR_STATIC_ASSERT((int)kZero_BlendCoeff == (int)SkXfermode::kZero_Coeff);
+GR_STATIC_ASSERT((int)kOne_BlendCoeff  == (int)SkXfermode::kOne_Coeff);
+GR_STATIC_ASSERT((int)kSC_BlendCoeff   == (int)SkXfermode::kSC_Coeff);
+GR_STATIC_ASSERT((int)kISC_BlendCoeff  == (int)SkXfermode::kISC_Coeff);
+GR_STATIC_ASSERT((int)kDC_BlendCoeff   == (int)SkXfermode::kDC_Coeff);
+GR_STATIC_ASSERT((int)kIDC_BlendCoeff  == (int)SkXfermode::kIDC_Coeff);
+GR_STATIC_ASSERT((int)kSA_BlendCoeff   == (int)SkXfermode::kSA_Coeff);
+GR_STATIC_ASSERT((int)kISA_BlendCoeff  == (int)SkXfermode::kISA_Coeff);
+GR_STATIC_ASSERT((int)kDA_BlendCoeff   == (int)SkXfermode::kDA_Coeff);
+GR_STATIC_ASSERT((int)kIDA_BlendCoeff  == (int)SkXfermode::kIDA_Coeff);
+
+#define sk_blend_to_grblend(X) ((GrBlendCoeff)(X))
+
+GR_STATIC_ASSERT((int)SkPath::kMove_Verb  == (int)kMove_PathCmd);
+GR_STATIC_ASSERT((int)SkPath::kLine_Verb  == (int)kLine_PathCmd);
+GR_STATIC_ASSERT((int)SkPath::kQuad_Verb  == (int)kQuadratic_PathCmd);
+GR_STATIC_ASSERT((int)SkPath::kCubic_Verb == (int)kCubic_PathCmd);
+GR_STATIC_ASSERT((int)SkPath::kClose_Verb == (int)kClose_PathCmd);
+GR_STATIC_ASSERT((int)SkPath::kDone_Verb  == (int)kEnd_PathCmd);
+
+#define sk_path_verb_to_gr_path_command(X) ((GrPathCmd)(X))
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkColorPriv.h"
+
+static inline GrRect Sk2Gr(const SkRect& src) {
+    return GrRect(SkScalarToGrScalar(src.fLeft),
+                  SkScalarToGrScalar(src.fTop),
+                  SkScalarToGrScalar(src.fRight),
+                  SkScalarToGrScalar(src.fBottom));
+}
+
+class SkGr {
+public:
+    static inline SkIRect& SetIRect(SkIRect* dst, const GrIRect& src) {
+        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+        memcpy(dst, &src, sizeof(*dst));
+        return *dst;
+    }
+
+    static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
+        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+        memcpy(dst, &src, sizeof(*dst));
+        return *dst;
+    }
+
+    /**
+     *  Convert the SkBitmap::Config to the corresponding PixelConfig, or
+     *  kUnknown_PixelConfig if the conversion cannot be done.
+     */
+    static GrTexture::PixelConfig BitmapConfig2PixelConfig(SkBitmap::Config,
+                                                        bool isOpaque);
+
+    static GrTexture::PixelConfig Bitmap2PixelConfig(const SkBitmap& bm) {
+        return BitmapConfig2PixelConfig(bm.config(), bm.isOpaque());
+    }
+
+    static void SkMatrix2GrMatrix(const SkMatrix& m, GrMatrix* g) {
+        g->setAll(SkScalarToGrScalar(m[0]),
+                  SkScalarToGrScalar(m[1]),
+                  SkScalarToGrScalar(m[2]),
+                  SkScalarToGrScalar(m[3]),
+                  SkScalarToGrScalar(m[4]),
+                  SkScalarToGrScalar(m[5]),
+                  SkScalarToGrScalar(m[6]),
+                  SkScalarToGrScalar(m[7]),
+                  SkScalarToGrScalar(m[8]));
+    }
+
+    static GrColor SkColor2GrColor(SkColor c) {
+        SkPMColor pm = SkPreMultiplyColor(c);
+        unsigned r = SkGetPackedR32(pm);
+        unsigned g = SkGetPackedG32(pm);
+        unsigned b = SkGetPackedB32(pm);
+        unsigned a = SkGetPackedA32(pm);
+        return GrColorPackRGBA(r, g, b, a);
+    }
+
+    /**
+     *  This abandons all texture caches (for bitmaps and text) associated with
+     *  the gpu, and frees any associated skia caches. It differs from
+     *  deleteAllTextures in that it assumes that the gpu has lots its context,
+     *  and thus the associated HW textures are no longer valid
+     */
+    static void AbandonAllTextures(GrContext*);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+
+class SkGrPathIter : public GrPathIter {
+public:
+    SkGrPathIter() { fPath = NULL; }
+    SkGrPathIter(const SkPath& path) { reset(path); }
+    virtual GrPathCmd next(GrPoint pts[]);
+    virtual GrPathCmd next();
+    virtual void rewind();
+    virtual GrConvexHint convexHint() const;
+
+    void reset(const SkPath& path) {
+        fPath = &path;
+        fIter.setPath(path, false);
+    }
+private:
+
+#if !SK_SCALAR_IS_GR_SCALAR
+    SkPoint             fPoints[4];
+#endif
+    SkPath::Iter        fIter;
+    const SkPath*       fPath;
+};
+
+class SkGrClipIterator : public GrClipIterator {
+public:
+    SkGrClipIterator() { fClipStack = NULL;  fCurr = NULL; }
+    SkGrClipIterator(const SkClipStack& clipStack) { this->reset(clipStack); }
+
+    void reset(const SkClipStack& clipStack);
+
+    // overrides
+    virtual bool isDone() const { return NULL == fCurr; }
+    virtual void next() { fCurr = fIter.next(); }
+    virtual void rewind() { this->reset(*fClipStack); }
+    virtual GrClipType getType() const;
+
+    virtual GrSetOp getOp() const;
+
+    virtual void getRect(GrRect* rect) const {
+        *rect = Sk2Gr(*fCurr->fRect);
+    }
+
+    virtual GrPathIter* getPathIter() {
+        fPathIter.reset(*fCurr->fPath);
+        return &fPathIter;
+    }
+
+    virtual GrPathFill getPathFill() const;
+
+private:
+    const SkClipStack*                  fClipStack;
+    SkClipStack::B2FIter                fIter;
+    SkGrPathIter                        fPathIter;
+    // SkClipStack's auto advances on each get
+    // so we store the current pos here.
+    const SkClipStack::B2FIter::Clip*   fCurr;
+};
+
+class SkGrRegionIterator : public GrClipIterator {
+public:
+    SkGrRegionIterator() {}
+    SkGrRegionIterator(const SkRegion& region) { this->reset(region); }
+
+    void reset(const SkRegion& region) {
+        fRegion = &region;
+        fIter.reset(region);
+    }
+
+    // overrides
+    virtual bool isDone() const { return fIter.done(); }
+    virtual void next() { fIter.next(); }
+    virtual void rewind() { this->reset(*fRegion); }
+    virtual GrClipType getType() const { return kRect_ClipType; }
+
+    virtual GrSetOp getOp() const { return kUnion_SetOp; }
+
+    virtual void getRect(GrRect* rect) const {
+        const SkIRect& r = fIter.rect();
+        rect->fLeft   = GrIntToScalar(r.fLeft);
+        rect->fTop    = GrIntToScalar(r.fTop);
+        rect->fRight  = GrIntToScalar(r.fRight);
+        rect->fBottom = GrIntToScalar(r.fBottom);
+    }
+
+    virtual GrPathIter* getPathIter() {
+        SkASSERT(0);
+        return NULL;
+    }
+
+    virtual GrPathFill getPathFill() const {
+        SkASSERT(0);
+        return kWinding_PathFill;
+    }
+private:
+    const SkRegion*     fRegion;
+    SkRegion::Iterator  fIter;
+};
+
+class SkGlyphCache;
+
+class SkGrFontScaler : public GrFontScaler {
+public:
+    explicit SkGrFontScaler(SkGlyphCache* strike);
+    virtual ~SkGrFontScaler();
+
+    // overrides
+    virtual const GrKey* getKey();
+    virtual GrMaskFormat getMaskFormat();
+    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds);
+    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+                                     int rowBytes, void* image);
+    virtual bool getGlyphPath(uint16_t glyphID, GrPath*);
+
+private:
+    SkGlyphCache* fStrike;
+    GrKey*  fKey;
+//    DECLARE_INSTANCE_COUNTER(SkGrFontScaler);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper functions
+
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
+                                            GrTextureKey* key,
+                                            const GrSamplerState& sampler,
+                                            const SkBitmap& bitmap);
+
+
+#endif
diff --git a/include/gpu/SkGrTexturePixelRef.h b/include/gpu/SkGrTexturePixelRef.h
new file mode 100644
index 0000000..1f5133f
--- /dev/null
+++ b/include/gpu/SkGrTexturePixelRef.h
@@ -0,0 +1,50 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGrTexturePixelRef_DEFINED
+#define SkGrTexturePixelRef_DEFINED
+
+#include "SkPixelRef.h"
+#include "GrGpu.h"
+
+class SkGrTexturePixelRef : public SkPixelRef {
+public:
+            SkGrTexturePixelRef(GrTexture*);
+    virtual ~SkGrTexturePixelRef();
+
+    // override from SkPixelRef
+    virtual SkGpuTexture* getTexture() { return (SkGpuTexture*)fTexture; }
+
+protected:
+    // override from SkPixelRef
+    virtual void* onLockPixels(SkColorTable** ptr) {
+        if (ptr) {
+            *ptr = NULL;
+        }
+        return NULL;
+    }
+
+    // override from SkPixelRef
+    virtual void onUnlockPixels() {}
+
+private:
+    GrTexture*  fTexture;
+    typedef SkPixelRef INHERITED;
+};
+
+#endif
+
diff --git a/include/graphics/DoxygenMain.dox b/include/graphics/DoxygenMain.dox
deleted file mode 100644
index 9751862..0000000
--- a/include/graphics/DoxygenMain.dox
+++ /dev/null
@@ -1,3 +0,0 @@
-/** \mainpage notitle

-*   \htmlinclude "SGL Spec. rev 9.htm"

-*/
\ No newline at end of file
diff --git a/include/ports/SkTypeface_win.h b/include/ports/SkTypeface_win.h
new file mode 100644
index 0000000..88678d1
--- /dev/null
+++ b/include/ports/SkTypeface_win.h
@@ -0,0 +1,31 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkTypeface_win_DEFINED
+#define SkTypeface_win_DEFINED
+
+#include "SkTypeface.h"
+
+/**
+ *  Like the other Typeface create methods, this returns a new reference to the
+ *  corresponding typeface for the specified logfont. The caller is responsible
+ *  for calling unref() when it is finished.
+ */
+SK_API extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
+
+#endif
+
diff --git a/include/svg/SkSVGAttribute.h b/include/svg/SkSVGAttribute.h
deleted file mode 100644
index 810d11c..0000000
--- a/include/svg/SkSVGAttribute.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSVGAttribute_DEFINED
-#define SkSVGAttribute_DEFINED
-
-#include "SkTypes.h"
-
-struct SkSVGAttribute {
-    const char* fName;
-#ifdef SK_DEBUG
-    size_t fOffset;
-#endif
-};
-
-#ifndef SK_OFFSETOF
-#define SK_OFFSETOF(a, b) (((size_t) (&(((a*) 1)->b)))-1)
-#endif
-
-#ifdef SK_DEBUG
-#define SVG_ATTRIBUTE(attr) { #attr, SK_OFFSETOF(BASE_CLASS, f_##attr) }
-#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr, SK_OFFSETOF(BASE_CLASS, cAttr) }
-#else
-#define SVG_ATTRIBUTE(attr) { #attr }
-#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr }
-#endif
-
-#define SVG_ADD_ATTRIBUTE(attr) \
-    if (f_##attr.size() > 0) \
-        parser._addAttributeLen(#attr, f_##attr.c_str(), f_##attr.size())
-
-#define SVG_ADD_ATTRIBUTE_ALIAS(attr, alias) \
-    if (f_##alias.size() > 0) \
-        parser._addAttributeLen(#attr, f_##alias.c_str(), f_##alias.size())
-
-#endif // SkSVGAttribute_DEFINED
diff --git a/include/svg/SkSVGBase.h b/include/svg/SkSVGBase.h
deleted file mode 100644
index 4d24aed..0000000
--- a/include/svg/SkSVGBase.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSVGBase_DEFINED
-#define SkSVGBase_DEFINED
-
-#include "SkSVGAttribute.h"
-
-class SkSVGParser;
-
-class SkSVGBase {
-public:
-    virtual ~SkSVGBase();
-    virtual void addAttribute(SkSVGParser& parser, int attrIndex, 
-        const char* attrValue, size_t attrLength);
-    virtual int getAttributes(const SkSVGAttribute** attrPtr) = 0;
-};
-
-#endif // SkSVGBase_DEFINEDes(const SkSVGAttribute** attrPtr) = 0;
-
diff --git a/include/svg/SkSVGPaintState.h b/include/svg/SkSVGPaintState.h
deleted file mode 100644
index f3f74e1..0000000
--- a/include/svg/SkSVGPaintState.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSVGPaintState_DEFINED
-#define SkSVGPaintState_DEFINED
-
-#include "SkSVGBase.h"
-#include "SkString.h"
-
-class SkSVGPaint : public SkSVGBase {
-public:
-    enum Field {
-        kInitial = -1,
-        kClipPath,
-        kClipRule,
-        kEnableBackground,
-        kFill,
-        kFillRule,
-        kFilter,
-        kFontFamily,
-        kFontSize,
-        kLetterSpacing,
-        kMask,
-        kOpacity,
-        kStopColor,
-        kStopOpacity,
-        kStroke,
-        kStroke_Dasharray,
-        kStroke_Linecap,
-        kStroke_Linejoin,
-        kStroke_Miterlimit,
-        kStroke_Width,
-        kStyle,
-        kTransform,
-        kTerminal
-    };
-
-    SkSVGPaint();
-    virtual void addAttribute(SkSVGParser& parser, int attrIndex, 
-        const char* attrValue, size_t attrLength);
-    bool flush(SkSVGParser& , bool isFlushable, bool isDef);
-    virtual int getAttributes(const SkSVGAttribute** attrPtr); 
-    static void Push(SkSVGPaint** head, SkSVGPaint* add);
-    static void Pop(SkSVGPaint** head);
-    SkString* operator[](int index);
-    SkString fInitial;
-    SkString f_clipPath;
-    SkString f_clipRule;
-    SkString f_enableBackground;
-    SkString f_fill;
-    SkString f_fillRule;
-    SkString f_filter;
-    SkString f_fontFamily;
-    SkString f_fontSize;
-    SkString f_letterSpacing;
-    SkString f_mask;
-    SkString f_opacity;
-    SkString f_stopColor;
-    SkString f_stopOpacity;
-    SkString f_stroke;
-    SkString f_strokeDasharray;
-    SkString f_strokeLinecap;
-    SkString f_strokeLinejoin;
-    SkString f_strokeMiterlimit;
-    SkString f_strokeWidth;
-    SkString f_style; // unused, but allows array access to the rest
-    SkString f_transform;
-#ifdef SK_DEBUG
-    SkString fTerminal;
-#endif
-    SkString fTransformID;
-    static SkSVGAttribute gAttributes[];
-    static const int kAttributesSize;
-private:
-    void setSave(SkSVGParser& );
-    bool writeChangedAttributes(SkSVGParser& , SkSVGPaint& , bool* changed);
-    bool writeChangedElements(SkSVGParser& , SkSVGPaint& , bool* changed);
-    SkSVGPaint* fNext;
-    friend class SkSVGParser;
-    typedef SkSVGPaint BASE_CLASS;
-};
-
-#endif // SkSVGPaintState_DEFINED
diff --git a/include/svg/SkSVGParser.h b/include/svg/SkSVGParser.h
deleted file mode 100644
index 83b120d..0000000
--- a/include/svg/SkSVGParser.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSVGParser_DEFINED
-#define SkSVGParser_DEFINED
-
-#include "SkMatrix.h"
-#include "SkTDict.h"
-#include "SkTDStack.h"
-#include "SkSVGPaintState.h"
-#include "SkSVGTypes.h"
-#include "SkStream.h"
-#include "SkString.h"
-#include "SkXMLParser.h"
-#include "SkXMLWriter.h"
-
-class SkSVGBase;
-class SkSVGElement;
-
-class SkSVGParser : public SkXMLParser {
-public:
-    SkSVGParser(SkXMLParserError* err = NULL);
-    virtual ~SkSVGParser();
-    void _addAttribute(const char* attrName, const char* attrValue) {
-        fXMLWriter.addAttribute(attrName, attrValue); }
-    void _addAttribute(const char* attrName, SkString& attrValue) {
-        fXMLWriter.addAttribute(attrName, attrValue.c_str()); }
-    void _addAttributeLen(const char* attrName, const char* attrValue, size_t len) {
-        fXMLWriter.addAttributeLen(attrName, attrValue, len); }
-    void _endElement() { fXMLWriter.endElement(); }
-    int findAttribute(SkSVGBase* , const char* attrValue, size_t len, bool isPaint);
-    const char* getFinal();
-    SkTDict<SkSVGElement*>& getIDs() { return fIDs; }
-    SkString& getPaintLast(SkSVGPaint::Field field);
-    void _startElement(const char name[]) { fXMLWriter.startElement(name); }
-    void translate(SkSVGElement*, bool isDef);
-    void translateMatrix(SkString& , SkString* id);
-    static void ConvertToArray(SkString& vals);
-protected:
-    virtual bool onAddAttribute(const char name[], const char value[]);
-    bool onAddAttributeLen(const char name[], const char value[], size_t len);
-    virtual bool onEndElement(const char elem[]);
-    virtual bool onStartElement(const char elem[]);
-    bool onStartElementLen(const char elem[], size_t len);
-    virtual bool onText(const char text[], int len);
-private:
-    bool isStrokeAndFill(SkSVGPaint** stroke, SkSVGPaint** fill);
-    static SkSVGElement* CreateElement(SkSVGTypes type, SkSVGElement* parent);
-    static void Delete(SkTDArray<SkSVGElement*>& fChildren);
-    static SkSVGTypes GetType(const char name[], size_t len);
-    SkSVGPaint* fHead;
-    SkSVGPaint fEmptyPaint; 
-    SkSVGPaint fLastFlush;
-    SkString fLastColor;
-    SkMatrix fLastTransform;
-    SkTDArray<SkSVGElement*> fChildren;
-    SkTDict<SkSVGElement*> fIDs;
-    SkTDArray<SkSVGElement*> fParents;
-    SkDynamicMemoryWStream fStream;
-    SkXMLStreamWriter fXMLWriter;
-    SkSVGElement*   fCurrElement;
-    SkBool8 fInSVG;
-    SkBool8 fSuppressPaint;
-    friend class SkSVGPaint;
-    friend class SkSVGGradient;
-};
-
-#endif // SkSVGParser_DEFINED
diff --git a/include/svg/SkSVGTypes.h b/include/svg/SkSVGTypes.h
deleted file mode 100644
index 99d8ca1..0000000
--- a/include/svg/SkSVGTypes.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSVGTypes_DEFINED
-#define SkSVGTypes_DEFINED
-
-enum SkSVGTypes {
-    SkSVGType_Circle,
-    SkSVGType_ClipPath,
-    SkSVGType_Defs,
-    SkSVGType_Ellipse,
-    SkSVGType_FeColorMatrix,
-    SkSVGType_Filter,
-    SkSVGType_G,
-    SkSVGType_Image,
-    SkSVGType_Line,
-    SkSVGType_LinearGradient,
-    SkSVGType_Mask,
-    SkSVGType_Metadata,
-    SkSVGType_Path,
-    SkSVGType_Polygon,
-    SkSVGType_Polyline,
-    SkSVGType_RadialGradient,
-    SkSVGType_Rect,
-    SkSVGType_SVG,
-    SkSVGType_Stop,
-    SkSVGType_Symbol,
-    SkSVGType_Text,
-    SkSVGType_Tspan,
-	SkSVGType_Unknown,
-    SkSVGType_Use
-};
-
-#endif // SkSVGTypes_DEFINED
diff --git a/include/utils/SkCamera.h b/include/utils/SkCamera.h
index 96eacb3..6d76018 100644
--- a/include/utils/SkCamera.h
+++ b/include/utils/SkCamera.h
@@ -157,7 +157,9 @@
     void rotateY(SkScalar deg);
     void rotateZ(SkScalar deg);
 
+#ifdef ANDROID
     void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
+#endif
 
     void getMatrix(SkMatrix*) const;
     void applyToCanvas(SkCanvas*) const;
diff --git a/include/views/SkApplication.h b/include/views/SkApplication.h
deleted file mode 100644
index 4c4a4fb..0000000
--- a/include/views/SkApplication.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkApplication_DEFINED
-#define SkApplication_DEFINED
-
-class SkOSWindow;
-
-extern SkOSWindow* create_sk_window(void* hwnd);
-extern void application_init();
-extern void application_term();
-
-#endif // SkApplication_DEFINED
diff --git a/include/views/SkBGViewArtist.h b/include/views/SkBGViewArtist.h
deleted file mode 100644
index 1bca42f..0000000
--- a/include/views/SkBGViewArtist.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkBGViewArtist_DEFINED
-#define SkBGViewArtist_DEFINED
-
-#include "SkView.h"
-#include "SkPaint.h"
-
-class SkBGViewArtist : public SkView::Artist {
-public:
-            SkBGViewArtist(SkColor c = SK_ColorWHITE);
-    virtual ~SkBGViewArtist();
-
-    const SkPaint&  paint() const { return fPaint; }
-    SkPaint&        paint() { return fPaint; }
-
-protected:
-    // overrides
-    virtual void onDraw(SkView*, SkCanvas*);
-    virtual void onInflate(const SkDOM&, const SkDOM::Node*);
-
-private:
-    SkPaint fPaint;
-};
-
-#endif
-
diff --git a/include/views/SkBorderView.h b/include/views/SkBorderView.h
deleted file mode 100644
index 94ccc1f..0000000
--- a/include/views/SkBorderView.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkBorderView_DEFINED
-#define SkBorderView_DEFINED
-
-#include "SkView.h"
-#include "SkWidgetViews.h"
-#include "SkAnimator.h"
-
-class SkBorderView : public SkWidgetView {
-public:
-    SkBorderView();
-    ~SkBorderView();
-    void setSkin(const char skin[]);
-    SkScalar getLeft() const { return fLeft; }
-    SkScalar getRight() const { return fRight; }
-    SkScalar getTop() const { return fTop; }
-    SkScalar getBottom() const { return fBottom; }
-protected:
-    //overrides
-    virtual void onInflate(const SkDOM& dom,  const SkDOM::Node* node);
-    virtual void onSizeChange();
-    virtual void onDraw(SkCanvas* canvas);
-    virtual bool onEvent(const SkEvent& evt);
-private:
-    SkAnimator fAnim;
-    SkScalar fLeft, fRight, fTop, fBottom;  //margin on each side
-    SkRect fMargin;
-
-    typedef SkWidgetView INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkEvent.h b/include/views/SkEvent.h
deleted file mode 100644
index f6719d6..0000000
--- a/include/views/SkEvent.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkEvent_DEFINED
-#define SkEvent_DEFINED
-
-#include "SkDOM.h"
-#include "SkMetaData.h"
-#include "SkString.h"
-
-/** Unique 32bit id used to identify an instance of SkEventSink. When events are
-    posted, they are posted to a specific sinkID. When it is time to dispatch the
-    event, the sinkID is used to find the specific SkEventSink object. If it is found,
-    its doEvent() method is called with the event.
-*/
-typedef uint32_t SkEventSinkID;
-
-/** \class SkEvent
-
-    SkEvents are used to communicate type-safe information to SkEventSinks.
-    SkEventSinks (including SkViews) each have a unique ID, which is stored
-    in an event. This ID is used to target the event once it has been "posted".
-*/
-class SkEvent {
-public:
-    /** Default construct, creating an empty event.
-    */
-    SkEvent();
-    /** Construct a new event with the specified type.
-    */
-    explicit SkEvent(const SkString& type);
-    /** Construct a new event with the specified type.
-    */
-    explicit SkEvent(const char type[]);
-    /** Construct a new event by copying the fields from the src event.
-    */
-    SkEvent(const SkEvent& src);
-    ~SkEvent();
-
-//  /** Return the event's type (will never be null) */
-//  const char* getType() const;
-    /** Copy the event's type into the specified SkString parameter */
-    void    getType(SkString* str) const;
-    /** Returns true if the event's type matches exactly the specified type (case sensitive) */
-    bool    isType(const SkString& str) const;
-    /** Returns true if the event's type matches exactly the specified type (case sensitive) */
-    bool    isType(const char type[], size_t len = 0) const;
-    /** Set the event's type to the specified string.
-        In XML, use the "type" attribute.
-    */
-    void    setType(const SkString&);
-    /** Set the event's type to the specified string.
-        In XML, use the "type" attribute.
-    */
-    void    setType(const char type[], size_t len = 0);
-
-    /** Return the event's unnamed 32bit field. Default value is 0 */
-    uint32_t getFast32() const { return f32; }
-    /** Set the event's unnamed 32bit field. In XML, use
-        the subelement <data fast32=... />
-    */
-    void    setFast32(uint32_t x) { f32 = x; }
-
-    /** Return true if the event contains the named 32bit field, and return the field
-        in value (if value is non-null). If there is no matching named field, return false
-        and ignore the value parameter.
-    */
-    bool    findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); }
-    /** Return true if the event contains the named SkScalar field, and return the field
-        in value (if value is non-null). If there is no matching named field, return false
-        and ignore the value parameter.
-    */
-    bool    findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); }
-    /** Return true if the event contains the named SkScalar field, and return the fields
-        in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null).
-        If there is no matching named field, return false and ignore the value and count parameters.
-    */
-    const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const { return fMeta.findScalars(name, count, values); }
-    /** Return the value of the named string field, or if no matching named field exists, return null.
-    */
-    const char* findString(const char name[]) const { return fMeta.findString(name); }
-    /** Return true if the event contains the named pointer field, and return the field
-        in value (if value is non-null). If there is no matching named field, return false
-        and ignore the value parameter.
-    */
-    bool    findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
-    bool    findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
-    const void* findData(const char name[], size_t* byteCount = NULL) const {
-        return fMeta.findData(name, byteCount);
-    }
-
-    /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
-    bool    hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
-    /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
-    bool    hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
-    /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
-    bool    hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
-    /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
-    bool    hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
-    bool    hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
-    bool hasData(const char name[], const void* data, size_t byteCount) const {
-        return fMeta.hasData(name, data, byteCount);
-    }
-
-    /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */
-    void    setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
-    /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */
-    void    setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
-    /** Add/replace the named SkScalar[] field to the event. */
-    SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); }
-    /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
-    void    setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); }
-    /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
-    void    setString(const char name[], const char value[]) { fMeta.setString(name, value); }
-    /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */
-    void    setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
-    void    setBool(const char name[], bool value) { fMeta.setBool(name, value); }
-    void setData(const char name[], const void* data, size_t byteCount) {
-        fMeta.setData(name, data, byteCount);
-    }
-
-    /** Return the underlying metadata object */
-    SkMetaData&         getMetaData() { return fMeta; }
-    /** Return the underlying metadata object */
-    const SkMetaData&   getMetaData() const { return fMeta; }
-
-    void tron() { SkDEBUGCODE(fDebugTrace = true;) }
-    void troff() { SkDEBUGCODE(fDebugTrace = false;) }
-    bool isDebugTrace() const
-    {
-#ifdef SK_DEBUG
-        return fDebugTrace;
-#else
-        return false;
-#endif
-    }
-
-    /** Call this to initialize the event from the specified XML node */
-    void    inflate(const SkDOM&, const SkDOM::Node*);
-
-    SkDEBUGCODE(void dump(const char title[] = NULL);)
-
-    /** Post the specified event to the event queue, targeting the specified eventsink, with an optional
-        delay. The event must be dynamically allocated for this. It cannot be a global or on the stack.
-        After this call, ownership is transfered to the system, so the caller must not retain
-        the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
-    */
-    static bool Post(SkEvent* evt, SkEventSinkID targetID, SkMSec delay = 0);
-    /** Post the specified event to the event queue, targeting the specified eventsink, to be delivered on/after the
-        specified millisecond time. The event must be dynamically allocated for this. It cannot be a global or on the stack.
-        After this call, ownership is transfered to the system, so the caller must not retain
-        the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
-    */
-    static bool PostTime(SkEvent* evt, SkEventSinkID targetID, SkMSec time);
-
-    /** Helper method for calling SkEvent::PostTime(this, ...), where the caller specifies a delay.
-        The real "time" will be computed automatically by sampling the clock and adding its value
-        to delay.
-    */
-    bool post(SkEventSinkID sinkID, SkMSec delay = 0)
-    {
-        return SkEvent::Post(this, sinkID, delay);
-    }
-
-    void postTime(SkEventSinkID sinkID, SkMSec time)
-    {
-        SkEvent::PostTime(this, sinkID, time);
-    }
-
-    ///////////////////////////////////////////////
-    /** Porting layer must call these functions **/
-    ///////////////////////////////////////////////
-
-    /** Global initialization function for the SkEvent system. Should be called exactly
-        once before any other event method is called, and should be called after the
-        call to SkGraphics::Init().
-    */
-    static void     Init();
-    /** Global cleanup function for the SkEvent system. Should be called exactly once after
-        all event methods have been called, and should be called before calling SkGraphics::Term().
-    */
-    static void     Term();
-
-    /** Call this to process one event from the queue. If it returns true, there are more events
-        to process.
-    */
-    static bool     ProcessEvent();
-    /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer).
-        It will post any delayed events whose time as "expired" onto the event queue.
-        It may also call SignalQueueTimer() and SignalNonEmptyQueue().
-    */
-    static void     ServiceQueueTimer();
-
-    /** Return the number of queued events. note that this value may be obsolete
-        upon return, since another thread may have called ProcessEvent() or
-        Post() after the count was made.
-     */
-    static int CountEventsOnQueue();
-
-    ////////////////////////////////////////////////////
-    /** Porting layer must implement these functions **/
-    ////////////////////////////////////////////////////
-
-    /** Called whenever an SkEvent is posted to an empty queue, so that the OS
-        can be told to later call Dequeue().
-    */
-    static void SignalNonEmptyQueue();
-    /** Called whenever the delay until the next delayed event changes. If zero is
-        passed, then there are no more queued delay events.
-    */
-    static void SignalQueueTimer(SkMSec delay);
-
-#ifndef SK_USE_WXWIDGETS
-#ifdef SK_BUILD_FOR_WIN
-    static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-#elif defined(SK_BUILD_FOR_UNIXx)
-  static uint32_t HandleTimer(uint32_t, void*);
-  static bool WndProc(Display*, Window, XEvent&);
-#endif
-#else
-    // Don't know yet what this will be
-    //static bool CustomEvent();
-#endif
-
-private:
-    SkMetaData      fMeta;
-    mutable char*   fType;  // may be characters with low bit set to know that it is not a pointer
-    uint32_t        f32;
-    SkDEBUGCODE(bool fDebugTrace;)
-
-    // these are for our implementation of the event queue
-    SkEventSinkID   fTargetID;
-    SkMSec          fTime;
-    SkEvent*        fNextEvent; // either in the delay or normal event queue
-    void initialize(const char* type, size_t typeLen);
-
-    static bool Enqueue(SkEvent* evt);
-    static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
-    static SkEvent* Dequeue(SkEventSinkID* targetID);
-    static bool     QHasEvents();
-};
-
-#endif
-
diff --git a/include/views/SkEventSink.h b/include/views/SkEventSink.h
deleted file mode 100644
index 27a6743..0000000
--- a/include/views/SkEventSink.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkEventSink_DEFINED
-#define SkEventSink_DEFINED
-
-#include "SkRefCnt.h"
-#include "SkEvent.h"
-
-struct SkTagList;
-
-/** \class SkEventSink
-
-    SkEventSink is the base class for all objects that receive SkEvents.
-*/
-class SkEventSink : public SkRefCnt {
-public:
-            SkEventSink();
-    virtual ~SkEventSink();
-
-    /** Returns this eventsink's unique ID. Use this to post SkEvents to
-        this eventsink.
-    */
-    SkEventSinkID getSinkID() const { return fID; }
-
-    /** Call this to pass an event to this object for processing. Returns true if the
-        event was handled.
-    */
-    bool doEvent(const SkEvent&);
-    /** Returns true if the sink (or one of its subclasses) understands the event as a query.
-        If so, the sink may modify the event to communicate its "answer".
-    */
-    bool doQuery(SkEvent* query);
-
-    /** Add sinkID to the list of listeners, to receive events from calls to sendToListeners()
-        and postToListeners(). If sinkID already exists in the listener list, no change is made.
-    */
-    void    addListenerID(SkEventSinkID sinkID);
-    /** Copy listeners from one event sink to another, typically from parent to child.
-        @param from the event sink to copy the listeners from
-    */
-    void copyListeners(const SkEventSink& from);
-    /** Remove sinkID from the list of listeners. If sinkID does not appear in the list,
-        no change is made.
-    */
-    void    removeListenerID(SkEventSinkID);
-    /** Returns true if there are 1 or more listeners attached to this eventsink
-    */
-    bool    hasListeners() const;
-    /** Posts a copy of evt to each of the eventsinks in the lisener list.
-    */
-    void    postToListeners(const SkEvent& evt, SkMSec delay = 0);
-
-    enum EventResult {
-        kHandled_EventResult,       //!< the eventsink returned true from its doEvent method
-        kNotHandled_EventResult,    //!< the eventsink returned false from its doEvent method
-        kSinkNotFound_EventResult   //!< no matching eventsink was found for the event's getSink().
-    };
-    /** DoEvent handles searching for an eventsink object that matches the targetID.
-        If one is found, it calls the sink's doEvent method, returning
-        either kHandled_EventResult or kNotHandled_EventResult. If no matching
-        eventsink is found, kSinkNotFound_EventResult is returned.
-    */
-    static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID);
-
-    /** Returns the matching eventsink, or null if not found
-    */
-    static SkEventSink* FindSink(SkEventSinkID);
-
-protected:
-    /** Override this to handle events in your subclass. Be sure to call the inherited version
-        for events that you don't handle.
-    */
-    virtual bool onEvent(const SkEvent&);
-    virtual bool onQuery(SkEvent*);
-
-    SkTagList*  findTagList(U8CPU tag) const;
-    void        addTagList(SkTagList*);
-    void        removeTagList(U8CPU tag);
-
-private:
-    SkEventSinkID   fID;
-    SkTagList*      fTagHead;
-
-    // for our private link-list
-    SkEventSink*    fNextSink;
-};
-
-#endif
-
diff --git a/include/views/SkImageView.h b/include/views/SkImageView.h
deleted file mode 100644
index 57215c9..0000000
--- a/include/views/SkImageView.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkImageView_DEFINED
-#define SkImageView_DEFINED
-
-#include "SkView.h"
-#include "SkString.h"
-
-class SkAnimator;
-class SkBitmap;
-class SkMatrix;
-
-class SkImageView : public SkView {
-public:
-            SkImageView();
-    virtual ~SkImageView();
-
-    void    getUri(SkString*) const;
-    void    setUri(const char []);
-    void    setUri(const SkString&);
-    
-
-    enum ScaleType {
-        kMatrix_ScaleType,
-        kFitXY_ScaleType,
-        kFitStart_ScaleType,
-        kFitCenter_ScaleType,
-        kFitEnd_ScaleType
-    };
-    ScaleType   getScaleType() const { return (ScaleType)fScaleType; }
-    void        setScaleType(ScaleType);
-    
-    bool    getImageMatrix(SkMatrix*) const;
-    void    setImageMatrix(const SkMatrix*);
-
-protected:
-    // overrides
-    virtual bool    onEvent(const SkEvent&);
-    virtual void    onDraw(SkCanvas*);
-    virtual void    onInflate(const SkDOM&, const SkDOMNode*);
-    
-private:
-    SkString    fUri;
-    SkMatrix*   fMatrix;    // null or copy of caller's matrix ,,,,,
-    union {
-        SkAnimator* fAnim;
-        SkBitmap* fBitmap;
-    } fData;
-    uint8_t     fScaleType;
-    SkBool8     fDataIsAnim;    // as opposed to bitmap
-    SkBool8     fUriIsValid;
-    
-    void    onUriChange();
-    bool    getDataBounds(SkRect* bounds);
-    bool    freeData();
-    bool    ensureUriIsLoaded();
-
-    typedef SkView INHERITED;
-};
-
-#endif
diff --git a/include/views/SkKey.h b/include/views/SkKey.h
deleted file mode 100644
index 3fd5114..0000000
--- a/include/views/SkKey.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkKey_DEFINED
-#define SkKey_DEFINED
-
-#include "SkTypes.h"
-
-enum SkKey {
-    //reordering these to match android.app.KeyEvent 
-    kNONE_SkKey,    //corresponds to android's UNKNOWN
-    
-    kLeftSoftKey_SkKey,
-    kRightSoftKey_SkKey,
-
-    kHome_SkKey,    //!< the home key - added to match android
-    kBack_SkKey,    //!< (CLR)
-    kSend_SkKey,    //!< the green (talk) key
-    kEnd_SkKey,     //!< the red key
-    
-    k0_SkKey,
-    k1_SkKey,
-    k2_SkKey,
-    k3_SkKey,
-    k4_SkKey,
-    k5_SkKey,
-    k6_SkKey,
-    k7_SkKey,
-    k8_SkKey,
-    k9_SkKey,
-    kStar_SkKey,    //!< the * key
-    kHash_SkKey,    //!< the # key
-
-    kUp_SkKey,
-    kDown_SkKey,
-    kLeft_SkKey,
-    kRight_SkKey,
-
-    kOK_SkKey,      //!< the center key
-
-    kVolUp_SkKey,   //!< volume up - match android
-    kVolDown_SkKey, //!< volume down - same
-    kPower_SkKey,   //!< power button - same
-    kCamera_SkKey,  //!< camera         - same
-
-    kSkKeyCount
-};
-
-#endif
-
diff --git a/include/views/SkMetaData.h b/include/views/SkMetaData.h
deleted file mode 100644
index 9509710..0000000
--- a/include/views/SkMetaData.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkMetaData_DEFINED
-#define SkMetaData_DEFINED
-
-#include "SkScalar.h"
-
-class SkMetaData {
-public:
-    SkMetaData();
-    SkMetaData(const SkMetaData& src);
-    ~SkMetaData();
-
-    SkMetaData& operator=(const SkMetaData& src);
-
-    void    reset();
-
-    bool    findS32(const char name[], int32_t* value = NULL) const;
-    bool    findScalar(const char name[], SkScalar* value = NULL) const;
-    const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const;
-    const char* findString(const char name[]) const;
-    bool    findPtr(const char name[], void** value = NULL) const;
-    bool    findBool(const char name[], bool* value = NULL) const;
-    const void* findData(const char name[], size_t* byteCount = NULL) const;
-
-    bool    hasS32(const char name[], int32_t value) const
-    {
-        int32_t v;
-        return this->findS32(name, &v) && v == value;
-    }
-    bool    hasScalar(const char name[], SkScalar value) const
-    {
-        SkScalar    v;
-        return this->findScalar(name, &v) && v == value;
-    }
-    bool    hasString(const char name[], const char value[]) const
-    {
-        const char* v = this->findString(name);
-        return  v == NULL && value == NULL ||
-                v != NULL && value != NULL && !strcmp(v, value);
-    }
-    bool    hasPtr(const char name[], void* value) const
-    {
-        void*   v;
-        return this->findPtr(name, &v) && v == value;
-    }
-    bool    hasBool(const char name[], bool value) const
-    {
-        bool    v;
-        return this->findBool(name, &v) && v == value;
-    }
-    bool hasData(const char name[], const void* data, size_t byteCount) const {
-        size_t len;
-        const void* ptr = this->findData(name, &len);
-        return NULL != ptr && len == byteCount && !memcmp(ptr, data, len);
-    }
-
-    void    setS32(const char name[], int32_t value);
-    void    setScalar(const char name[], SkScalar value);
-    SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL);
-    void    setString(const char name[], const char value[]);
-    void    setPtr(const char name[], void* value);
-    void    setBool(const char name[], bool value);
-    // the data is copied from the input pointer.
-    void    setData(const char name[], const void* data, size_t byteCount);
-
-    bool    removeS32(const char name[]);
-    bool    removeScalar(const char name[]);
-    bool    removeString(const char name[]);
-    bool    removePtr(const char name[]);
-    bool    removeBool(const char name[]);
-    bool    removeData(const char name[]);
-
-    SkDEBUGCODE(static void UnitTest();)
-
-    enum Type {
-        kS32_Type,
-        kScalar_Type,
-        kString_Type,
-        kPtr_Type,
-        kBool_Type,
-        kData_Type,
-
-        kTypeCount
-    };
-
-    struct Rec;
-    class Iter;
-    friend class Iter;
-
-    class Iter {
-    public:
-        Iter() : fRec(NULL) {}
-        Iter(const SkMetaData&);
-
-        /** Reset the iterator, so that calling next() will return the first
-            data element. This is done implicitly in the constructor.
-        */
-        void    reset(const SkMetaData&);
-
-        /** Each time next is called, it returns the name of the next data element,
-            or null when there are no more elements. If non-null is returned, then the
-            element's type is returned (if not null), and the number of data values
-            is returned in count (if not null).
-        */
-        const char* next(Type*, int* count);
-
-    private:
-        Rec* fRec;
-    };
-
-public:
-    struct Rec {
-        Rec*        fNext;
-        uint16_t    fDataCount; // number of elements
-        uint8_t     fDataLen;   // sizeof a single element
-#ifdef SK_DEBUG
-        Type        fType;
-#else
-        uint8_t     fType;
-#endif
-
-#ifdef SK_DEBUG
-        const char* fName;
-        union {
-            int32_t     fS32;
-            SkScalar    fScalar;
-            const char* fString;
-            void*       fPtr;
-            bool        fBool;
-        } fData;
-#endif
-
-        const void* data() const { return (this + 1); }
-        void*       data() { return (this + 1); }
-        const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
-        char*       name() { return (char*)this->data() + fDataLen * fDataCount; }
-
-        static Rec* Alloc(size_t);
-        static void Free(Rec*);
-    };
-    Rec*    fRec;
-
-    const Rec* find(const char name[], Type) const;
-    void* set(const char name[], const void* data, size_t len, Type, int count);
-    bool remove(const char name[], Type);
-};
-
-#endif
-
diff --git a/include/views/SkOSMenu.h b/include/views/SkOSMenu.h
deleted file mode 100644
index 433a601..0000000
--- a/include/views/SkOSMenu.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkOSMenu_DEFINED
-#define SkOSMenu_DEFINED
-
-#include "SkEvent.h"
-#include "SkTDArray.h"
-
-class SkOSMenu {
-public:
-    explicit SkOSMenu(const char title[]);
-    ~SkOSMenu();
-
-    const char* getTitle() const { return fTitle; }
-
-    void    appendItem(const char title[], const char eventType[], int32_t eventData);
-
-    // called by SkOSWindow when it receives an OS menu event
-    int         countItems() const;
-    const char* getItem(int index, uint32_t* cmdID) const;
-
-    SkEvent* createEvent(uint32_t os_cmd);
-
-private:
-    const char* fTitle;
-
-    struct Item {
-        const char* fTitle;
-        const char* fEventType;
-        uint32_t    fEventData;
-        uint32_t    fOSCmd; // internal
-    };
-    SkTDArray<Item> fItems;
-
-    // illegal
-    SkOSMenu(const SkOSMenu&);
-    SkOSMenu& operator=(const SkOSMenu&);
-};
-
-#endif
-
diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h
deleted file mode 100644
index 3a26d5a..0000000
--- a/include/views/SkOSWindow_Mac.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkOSWindow_Mac_DEFINED
-#define SkOSWindow_Mac_DEFINED
-
-#include <Carbon/Carbon.h>
-#include "SkWindow.h"
-
-class SkOSWindow : public SkWindow {
-public:
-    SkOSWindow(void* hwnd);
-
-    void*   getHWND() const { return fHWND; }
-    void*   getHVIEW() const { return fHVIEW; }
-    void    updateSize();
-
-    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
-
-    static OSStatus EventHandler(EventHandlerCallRef inHandler,
-                                 EventRef inEvent, void* userData);
-
-    void   doPaint(void* ctx);
-
-
-    bool attachGL(const SkBitmap* offscreen);
-    void detachGL();
-    void presentGL();
-
-protected:
-    // overrides from SkEventSink
-    virtual bool onEvent(const SkEvent& evt);
-    // overrides from SkWindow
-    virtual void onHandleInval(const SkIRect&);
-    // overrides from SkView
-    virtual void onAddMenu(const SkOSMenu*);
-    virtual void onSetTitle(const char[]);
-    
-
-private:
-    void*   fHWND;
-    void*   fHVIEW;
-    void*   fAGLCtx;
-
-    typedef SkWindow INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkOSWindow_SDL.h b/include/views/SkOSWindow_SDL.h
deleted file mode 100644
index 0ff24f3..0000000
--- a/include/views/SkOSWindow_SDL.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkOSWindow_SDL_DEFINED
-#define SkOSWindow_SDL_DEFINED
-
-#include "SDL.h"
-#include "SkWindow.h"
-
-class SkGLCanvas;
-
-class SkOSWindow : public SkWindow {
-public:
-    SkOSWindow(void* screen);
-    virtual ~SkOSWindow();
-
-    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
-
-    void handleSDLEvent(const SDL_Event& event);
-
-protected:
-    // overrides from SkWindow
-    virtual void onHandleInval(const SkIRect&);
-    // overrides from SkView
-    virtual void onAddMenu(const SkOSMenu*);
-    virtual void onSetTitle(const char[]);
-
-private:
-    SDL_Surface* fScreen;
-    SDL_Surface* fSurface;
-    SkGLCanvas* fGLCanvas;
-
-    void doDraw();
-
-    typedef SkWindow INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkOSWindow_Unix.h b/include/views/SkOSWindow_Unix.h
deleted file mode 100644
index 26f51be..0000000
--- a/include/views/SkOSWindow_Unix.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkOSWindow_Unix_DEFINED
-#define SkOSWindow_Unix_DEFINED
-
-#include "SkWindow.h"
-#include <X11/Xlib.h>
-
-struct SkUnixWindow {
-  Display* fDisplay;
-  Window fWin;
-  size_t fOSWin;
-};
-
-class SkOSWindow : public SkWindow {
-public:
-    SkOSWindow(Display* display, Window win);
-
-    void*   getHWND() const { return (void*)fUnixWindow.fWin; }
-  void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
-  void* getUnixWindow() const { return (void*)&fUnixWindow; }
-  void  setSize(int width, int height);
-    void    updateSize();
-
-    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
-
-    static bool WndProc(SkUnixWindow* w,  XEvent &e);
-
-protected:
-    // overrides from SkWindow
-    virtual void onHandleInval(const SkIRect&);
-    // overrides from SkView
-    virtual void onAddMenu(const SkOSMenu*);
-
-private:
-    SkUnixWindow  fUnixWindow;
-
-    void    doPaint();
-
-    void*   fMBar;
-
-    typedef SkWindow INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h
deleted file mode 100644
index 09f0c5c..0000000
--- a/include/views/SkOSWindow_Win.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkOSWindow_Win_DEFINED
-#define SkOSWindow_Win_DEFINED
-
-#include "SkWindow.h"
-
-class SkOSWindow : public SkWindow {
-public:
-    SkOSWindow(void* hwnd);
-    virtual ~SkOSWindow();
-
-    void*   getHWND() const { return fHWND; }
-    void    setSize(int width, int height);
-    void    updateSize();
-
-    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
-    
-    bool attachGL(const SkBitmap* offscreen);
-    void detachGL();
-    void presentGL();
-
-    bool attachD3D9();
-    void detachD3D9();
-    void presentD3D9();
-
-    void* d3d9Device() { return fD3D9Device; }
-
-    bool wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-    static bool QuitOnDeactivate(HWND hWnd);
-
-    enum {
-        SK_WM_SkEvent = WM_APP + 1000,
-        SK_WM_SkTimerID = 0xFFFF    // just need a non-zero value
-    };
-
-protected:
-    virtual bool quitOnDeactivate() { return true; }
-
-    // overrides from SkWindow
-    virtual void onHandleInval(const SkIRect&);
-    // overrides from SkView
-    virtual void onAddMenu(const SkOSMenu*);
-
-    virtual void onSetTitle(const char title[]);
-
-private:
-    void*               fHWND;
-    
-    void                doPaint(void* ctx);
-
-    void*               fHGLRC;
-
-    bool                fGLAttached;
-
-    void*               fD3D9Device;
-    bool                fD3D9Attached;
-
-    HMENU               fMBar;
-
-    typedef SkWindow INHERITED; 
-};
-
-#endif
-
diff --git a/include/views/SkOSWindow_wxwidgets.h b/include/views/SkOSWindow_wxwidgets.h
deleted file mode 100644
index c5dfc7c..0000000
--- a/include/views/SkOSWindow_wxwidgets.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- *  SkOSWindow_wxwidgets.h
- *  wxwidgets
- *
- *  Copyright 2005 __MyCompanyName__. All rights reserved.
- *
- */
-
-#ifndef SkOSWindow_wxwidgets_DEFINED
-#define SkOSWindow_wxwidgets_DEFINED
-
-#include "SkWindow.h"
-#include "wx/frame.h"
-
-class SkOSWindow: public SkWindow
-{
-public:
-    SkOSWindow();
-    SkOSWindow(const wxString& title, int x, int y, int width, int height);
-    ~SkOSWindow();
-    
-    wxFrame* getWXFrame() const { return fFrame; }
-    
-    void updateSize();
-    
-protected:
-    virtual void onHandleInval(const SkIRect&);
-    virtual void onAddMenu(const SkOSMenu*);
-    
-private:
-    wxFrame* fFrame;
-    typedef SkWindow INHERITED;
-    
-};
-
-#endifpedef SkWindow INHERITED;
diff --git a/include/views/SkProgressBarView.h b/include/views/SkProgressBarView.h
deleted file mode 100644
index 6341fcb..0000000
--- a/include/views/SkProgressBarView.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkProgressBarView_DEFINED
-#define SkProgressBarView_DEFINED
-
-#include "SkView.h"
-#include "SkWidgetViews.h"
-#include "SkAnimator.h"
-
-class SkProgressBarView : public SkWidgetView {
-    public:
-        SkProgressBarView();
-        //SkProgressBarView(int max);
-                
-        //inflate: "sk-progress"
-    
-        void reset();   //reset progress to zero
-        void setProgress(int progress);
-        void changeProgress(int diff);
-        void setMax(int max);
-        
-        int getProgress() const { return fProgress; }
-        int getMax() const { return fMax; }
-    
-    protected:
-        //overrides
-        virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-        virtual void onSizeChange();
-        virtual void onDraw(SkCanvas* canvas);
-        virtual bool onEvent(const SkEvent& evt);
-    
-    private:
-        SkAnimator  fAnim;
-        int         fProgress;
-        int         fMax;
-        
-        typedef SkWidgetView INHERITED;
-};
-
-
-
-
-#endif
diff --git a/include/views/SkScrollBarView.h b/include/views/SkScrollBarView.h
deleted file mode 100644
index b8a5209..0000000
--- a/include/views/SkScrollBarView.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkScrollBarView_DEFINED
-#define SkScrollBarView_DEFINED
-
-#include "SkView.h"
-#include "SkWidgetViews.h"
-#include "SkAnimator.h"
-
-class SkScrollBarView : public SkWidgetView {
-public:
-    SkScrollBarView();
-
-    unsigned getStart() const { return fStartPoint; }
-    unsigned getShown() const { return fShownLength; }
-    unsigned getTotal() const { return fTotalLength; }
-
-    void setStart(unsigned start);  
-    void setShown(unsigned shown);
-    void setTotal(unsigned total);
-    
-protected:
-    //overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-    virtual void onSizeChange();
-    virtual void onDraw(SkCanvas* canvas);
-    virtual bool onEvent(const SkEvent& evt);
-
-private:
-    SkAnimator  fAnim;
-    unsigned    fTotalLength, fStartPoint, fShownLength;
-    
-    void adjust();
-    
-    typedef SkWidgetView INHERITED;
-};
-#endif
-
diff --git a/include/views/SkStackViewLayout.h b/include/views/SkStackViewLayout.h
deleted file mode 100644
index 8000319..0000000
--- a/include/views/SkStackViewLayout.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkStackViewLayout_DEFINED
-#define SkStackViewLayout_DEFINED
-
-#include "SkView.h"
-
-class SkStackViewLayout : public SkView::Layout {
-public:
-    SkStackViewLayout();
-
-    enum Orient {
-        kHorizontal_Orient,
-        kVertical_Orient,
-
-        kOrientCount
-    };
-    Orient  getOrient() const { return (Orient)fOrient; }
-    void    setOrient(Orient);
-
-    void        getMargin(SkRect*) const;
-    void        setMargin(const SkRect&);
-
-    SkScalar    getSpacer() const { return fSpacer; }
-    void        setSpacer(SkScalar);
-
-    /** Controls the posititioning in the same direction as the orientation
-    */
-    enum Pack {
-        kStart_Pack,
-        kCenter_Pack,
-        kEnd_Pack,
-        
-        kPackCount
-    };
-    Pack    getPack() const { return (Pack)fPack; }
-    void    setPack(Pack);
-
-    /** Controls the posititioning at right angles to the orientation
-    */
-    enum Align {
-        kStart_Align,
-        kCenter_Align,
-        kEnd_Align,
-        kStretch_Align,
-
-        kAlignCount
-    };
-    Align   getAlign() const { return (Align)fAlign; }
-    void    setAlign(Align);
-
-    bool    getRound() const { return SkToBool(fRound); }
-    void    setRound(bool);
-
-protected:
-    virtual void onLayoutChildren(SkView* parent);
-    virtual void onInflate(const SkDOM&, const SkDOM::Node*);
-
-private:
-    SkRect      fMargin;
-    SkScalar    fSpacer;
-    uint8_t     fOrient, fPack, fAlign, fRound;
-};
-
-class SkFillViewLayout : public SkView::Layout {
-public:
-            SkFillViewLayout();
-    void    getMargin(SkRect*) const;
-    void    setMargin(const SkRect&);
-
-protected:
-    // overrides;
-    virtual void onLayoutChildren(SkView* parent);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    SkRect  fMargin;
-    typedef SkView::Layout INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkSystemEventTypes.h b/include/views/SkSystemEventTypes.h
deleted file mode 100644
index 8dfe8be..0000000
--- a/include/views/SkSystemEventTypes.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkSystemEventTypes_DEFINED
-#define SkSystemEventTypes_DEFINED
-
-/*
-    The goal of these strings is two-fold:
-    1) make funny strings (containing at least one char < 32) to avoid colliding with "user" strings
-    2) keep them <= 4 bytes, so we can avoid an allocation in SkEvent::setType()
-*/
-#define SK_EventType_Delay      "\xd" "lay"
-#define SK_EventType_Inval      "nv" "\xa" "l"
-#define SK_EventType_Key        "key" "\x1" 
-#define SK_EventType_OnEnd "on" "\xe" "n"
-#define SK_EventType_Unichar    "\xc" "har"
-#define SK_EventType_KeyUp      "key" "\xf"
-
-#endif
diff --git a/include/views/SkView.h b/include/views/SkView.h
deleted file mode 100644
index d3633db..0000000
--- a/include/views/SkView.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkView_DEFINED
-#define SkView_DEFINED
-
-#include "SkEventSink.h"
-#include "SkRect.h"
-#include "SkDOM.h"
-#include "SkTDict.h"
-
-class SkCanvas;
-class SkLayerView;
-
-/** \class SkView
-
-    SkView is the base class for screen management. All widgets and controls inherit
-    from SkView.
-*/
-class SkView : public SkEventSink {
-public:
-    enum Flag_Shift {
-        kVisible_Shift,
-        kEnabled_Shift,
-        kFocusable_Shift,
-        kFlexH_Shift,
-        kFlexV_Shift,
-        kNoClip_Shift,
-
-        kFlagShiftCount
-    };
-    enum Flag_Mask {
-        kVisible_Mask   = 1 << kVisible_Shift,      //!< set if the view is visible
-        kEnabled_Mask   = 1 << kEnabled_Shift,      //!< set if the view is enabled
-        kFocusable_Mask = 1 << kFocusable_Shift,    //!< set if the view can receive focus
-        kFlexH_Mask     = 1 << kFlexH_Shift,        //!< set if the view's width is stretchable
-        kFlexV_Mask     = 1 << kFlexV_Shift,        //!< set if the view's height is stretchable
-        kNoClip_Mask    = 1 << kNoClip_Shift,        //!< set if the view is not clipped to its bounds
-
-        kAllFlagMasks   = (uint32_t)(0 - 1) >> (32 - kFlagShiftCount)
-    };
-
-                SkView(uint32_t flags = 0);
-    virtual     ~SkView();
-
-    /** Return the flags associated with the view
-    */
-    uint32_t    getFlags() const { return fFlags; }
-    /** Set the flags associated with the view
-    */
-    void        setFlags(uint32_t flags);
-
-    /** Helper that returns non-zero if the kVisible_Mask bit is set in the view's flags
-    */
-    int         isVisible() const { return fFlags & kVisible_Mask; }
-    int         isEnabled() const { return fFlags & kEnabled_Mask; }
-    int         isFocusable() const { return fFlags & kFocusable_Mask; }
-    int         isClipToBounds() const { return !(fFlags & kNoClip_Mask); }
-    /** Helper to set/clear the view's kVisible_Mask flag */
-    void        setVisibleP(bool);
-    void        setEnabledP(bool);
-    void        setFocusableP(bool);
-    void        setClipToBounds(bool);
-
-    /** Return the view's width */
-    SkScalar    width() const { return fWidth; }
-    /** Return the view's height */
-    SkScalar    height() const { return fHeight; }
-    /** Set the view's width and height. These must both be >= 0. This does not affect the view's loc */
-    void        setSize(SkScalar width, SkScalar height);
-    void        setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
-    void        setWidth(SkScalar width) { this->setSize(width, fHeight); }
-    void        setHeight(SkScalar height) { this->setSize(fWidth, height); }
-    /** Return a rectangle set to [0, 0, width, height] */
-    void        getLocalBounds(SkRect* bounds) const;
-
-    /** Return the view's left edge */
-    SkScalar    locX() const { return fLoc.fX; }
-    /** Return the view's top edge */
-    SkScalar    locY() const { return fLoc.fY; }
-    /** Set the view's left and top edge. This does not affect the view's size */
-    void        setLoc(SkScalar x, SkScalar y);
-    void        setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
-    void        setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
-    void        setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
-    /** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
-    void        offset(SkScalar dx, SkScalar dy);
-
-    /** Call this to have the view draw into the specified canvas. */
-    virtual void draw(SkCanvas* canvas);
-
-    /** Call this to invalidate part of all of a view, requesting that the view's
-        draw method be called. The rectangle parameter specifies the part of the view
-        that should be redrawn. If it is null, it specifies the entire view bounds.
-    */
-    void        inval(SkRect* rectOrNull);
-
-    //  Focus management
-
-    SkView* getFocusView() const;
-    bool    hasFocus() const;
-
-    enum FocusDirection {
-        kNext_FocusDirection,
-        kPrev_FocusDirection,
-
-        kFocusDirectionCount
-    };
-    bool    acceptFocus();
-    SkView* moveFocus(FocusDirection);
-
-    //  Click handling
-
-    class Click {
-    public:
-        Click(SkView* target);
-        virtual ~Click();
-
-        const char* getType() const { return fType; }
-        bool        isType(const char type[]) const;
-        void        setType(const char type[]);     // does NOT make a copy of the string
-        void        copyType(const char type[]);    // makes a copy of the string
-
-        enum State {
-            kDown_State,
-            kMoved_State,
-            kUp_State
-        };
-        SkPoint     fOrig, fPrev, fCurr;
-        SkIPoint    fIOrig, fIPrev, fICurr;
-        State       fState;
-    private:
-        SkEventSinkID   fTargetID;
-        char*           fType;
-        bool            fWeOwnTheType;
-
-        void resetType();
-
-        friend class SkView;
-    };
-    Click*  findClickHandler(SkScalar x, SkScalar y);
-
-    static void DoClickDown(Click*, int x, int y);
-    static void DoClickMoved(Click*, int x, int y);
-    static void DoClickUp(Click*, int x, int y);
-
-    /** Send the event to the view's parent, and its parent etc. until one of them
-        returns true from its onEvent call. This view is returned. If no parent handles
-        the event, null is returned.
-     */
-    SkView*     sendEventToParents(const SkEvent&);
-    /** Send the query to the view's parent, and its parent etc. until one of them
-        returns true from its onQuery call. This view is returned. If no parent handles
-        the query, null is returned.
-     */
-    SkView* sendQueryToParents(SkEvent*);
-
-    /** Depricated helper function. Just call event->post(sinkID, delay);
-    */
-    bool    postEvent(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) { return evt->post(sinkID, delay); }
-
-    //  View hierarchy management
-
-    /** Return the view's parent, or null if it has none. This does not affect the parent's reference count. */
-    SkView*     getParent() const { return fParent; }
-    SkView*     attachChildToFront(SkView* child);
-    /** Attach the child view to this view, and increment the child's reference count. The child view is added
-        such that it will be drawn before all other child views.
-        The child view parameter is returned.
-    */
-    SkView*     attachChildToBack(SkView* child);
-    /** If the view has a parent, detach the view from its parent and decrement the view's reference count.
-        If the parent was the only owner of the view, this will cause the view to be deleted.
-    */
-    void        detachFromParent();
-    /** Attach the child view to this view, and increment the child's reference count. The child view is added
-        such that it will be drawn after all other child views.
-        The child view parameter is returned.
-    */
-    /** Detach all child views from this view. */
-    void        detachAllChildren();
-
-    /** Convert the specified point from global coordinates into view-local coordinates
-    */
-    void        globalToLocal(SkPoint* pt) const { if (pt) this->globalToLocal(pt->fX, pt->fY, pt); }
-    /** Convert the specified x,y from global coordinates into view-local coordinates, returning
-        the answer in the local parameter.
-    */
-    void        globalToLocal(SkScalar globalX, SkScalar globalY, SkPoint* local) const;
-
-    /** \class F2BIter
-    
-        Iterator that will return each of this view's children, in
-        front-to-back order (the order used for clicking). The first
-        call to next() returns the front-most child view. When
-        next() returns null, there are no more child views.
-    */
-    class F2BIter {
-    public:
-        F2BIter(const SkView* parent);
-        SkView* next();
-    private:
-        SkView* fFirstChild, *fChild;
-    };
-
-    /** \class B2FIter
-    
-        Iterator that will return each of this view's children, in
-        back-to-front order (the order they are drawn). The first
-        call to next() returns the back-most child view. When
-        next() returns null, there are no more child views.
-    */
-    class B2FIter {
-    public:
-        B2FIter(const SkView* parent);
-        SkView* next();
-    private:
-        SkView* fFirstChild, *fChild;
-    };
-
-    /** \class Artist
-    
-        Install a subclass of this in a view (calling setArtist()), and then the
-        default implementation of that view's onDraw() will invoke this object
-        automatically.
-    */
-    class Artist : public SkRefCnt {
-    public:
-        void draw(SkView*, SkCanvas*);
-        void inflate(const SkDOM&, const SkDOM::Node*);
-    protected:
-        virtual void onDraw(SkView*, SkCanvas*) = 0;
-        virtual void onInflate(const SkDOM&, const SkDOM::Node*);
-    };
-    /** Return the artist attached to this view (or null). The artist's reference
-        count is not affected.
-    */
-    Artist* getArtist() const;
-    /** Attach the specified artist (or null) to the view, replacing any existing
-        artist. If the new artist is not null, its reference count is incremented.
-        The artist parameter is returned.
-    */
-    Artist* setArtist(Artist* artist);
-
-    /** \class Layout
-    
-        Install a subclass of this in a view (calling setLayout()), and then the
-        default implementation of that view's onLayoutChildren() will invoke
-        this object automatically.
-    */
-    class Layout : public SkRefCnt {
-    public:
-        void layoutChildren(SkView* parent);
-        void inflate(const SkDOM&, const SkDOM::Node*);
-    protected:
-        virtual void onLayoutChildren(SkView* parent) = 0;
-        virtual void onInflate(const SkDOM&, const SkDOM::Node*);
-    };
-
-    /** Return the layout attached to this view (or null). The layout's reference
-        count is not affected.
-    */
-    Layout* getLayout() const;
-    /** Attach the specified layout (or null) to the view, replacing any existing
-        layout. If the new layout is not null, its reference count is incremented.
-        The layout parameter is returned.
-    */
-    Layout* setLayout(Layout*, bool invokeLayoutNow = true);
-    /** If a layout is attached to this view, call its layoutChildren() method
-    */
-    void    invokeLayout();
-
-    /** Call this to initialize this view based on the specified XML node
-    */
-    void    inflate(const SkDOM& dom, const SkDOM::Node* node);
-    /** After a view hierarchy is inflated, this may be called with a dictionary
-        containing pairs of <name, view*>, where the name string was the view's
-        "id" attribute when it was inflated.
-
-        This will call the virtual onPostInflate for this view, and the recursively
-        call postInflate on all of the view's children.
-    */
-    void    postInflate(const SkTDict<SkView*>& ids);
-
-    SkDEBUGCODE(void dump(bool recurse) const;)
-
-protected:
-    /** Override this to draw inside the view. Be sure to call the inherited version too */
-    virtual void    onDraw(SkCanvas*);
-    /** Override this to be notified when the view's size changes. Be sure to call the inherited version too */
-    virtual void    onSizeChange();
-    /** Override this if you want to handle an inval request from this view or one of its children.
-        Tyically this is only overridden by the by the "window". If your subclass does handle the
-        request, return true so the request will not continue to propogate to the parent.
-    */
-    virtual bool    handleInval(const SkRect*);
-    //! called once before all of the children are drawn (or clipped/translated)
-    virtual SkCanvas* beforeChildren(SkCanvas* c) { return c; }
-    //! called once after all of the children are drawn (or clipped/translated)
-    virtual void afterChildren(SkCanvas* orig) {}
-
-    //! called right before this child's onDraw is called
-    virtual void beforeChild(SkView* child, SkCanvas* canvas) {}
-    //! called right after this child's onDraw is called
-    virtual void afterChild(SkView* child, SkCanvas* canvas) {}
-
-    /** Override this if you might handle the click
-    */
-    virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
-    /** Override this to decide if your children are targets for a click.
-        The default returns true, in which case your children views will be
-        candidates for onFindClickHandler. Returning false wil skip the children
-        and just call your onFindClickHandler.
-     */
-    virtual bool onSendClickToChildren(SkScalar x, SkScalar y);
-    /** Override this to track clicks, returning true as long as you want to track
-        the pen/mouse.
-    */
-    virtual bool    onClick(Click*);
-    /** Override this to initialize your subclass from the XML node. Be sure to call the inherited version too */
-    virtual void    onInflate(const SkDOM& dom, const SkDOM::Node* node);
-    /** Override this if you want to perform post initialization work based on the ID dictionary built
-        during XML parsing. Be sure to call the inherited version too.
-    */
-    virtual void    onPostInflate(const SkTDict<SkView*>&);
-
-public:
-    // default action is to inval the view
-    virtual void    onFocusChange(bool gainFocusP);
-protected:
-
-    // override these if you're acting as a layer/host
-    virtual bool    onGetFocusView(SkView**) const { return false; }
-    virtual bool    onSetFocusView(SkView*) { return false; }
-
-private:
-    SkScalar    fWidth, fHeight;
-    SkPoint     fLoc;
-    SkView*     fParent;
-    SkView*     fFirstChild;
-    SkView*     fNextSibling;
-    SkView*     fPrevSibling;
-    uint8_t     fFlags;
-    uint8_t     fContainsFocus;
-
-    friend class B2FIter;
-    friend class F2BIter;
-    
-    friend class SkLayerView;
-
-    bool    setFocusView(SkView* fvOrNull);
-    SkView* acceptFocus(FocusDirection);
-    void    detachFromParent_NoLayout();
-};
-
-#endif
-
diff --git a/include/views/SkViewInflate.h b/include/views/SkViewInflate.h
deleted file mode 100644
index 3ec65a6..0000000
--- a/include/views/SkViewInflate.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkViewInflate_DEFINED
-#define SkViewInflate_DEFINED
-
-#include "SkDOM.h"
-#include "SkTDict.h"
-#include "SkEvent.h"
-
-class SkView;
-
-class SkViewInflate {
-public: 
-            SkViewInflate();
-    virtual ~SkViewInflate();
-
-    /** Return the tree of inflated views. If root is null, create the root element
-        as a view, otherwise assume root is that view, and just "inflate" it.
-
-        Returns null if the tree cannot be built.
-    */
-    SkView* inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root = NULL);
-    SkView* inflate(const char xml[], size_t len, SkView* root = NULL);
-
-    /** Given an id attribute value, return the corresponding view, or null
-        if no match is found.
-    */
-    SkView* findViewByID(const char id[]) const;
-    
-    SkDEBUGCODE(void dump() const;)
-
-protected:
-    /*  Override this in your subclass to handle instantiating views
-        Call the inherited version for nodes you don't recognize.
-
-        Do not call "inflate" on the view, just return it. This will
-        get called automatically after createView returns.
-    */
-    virtual SkView* createView(const SkDOM& dom, const SkDOM::Node* node);
-    /** Base implementation calls view->inflate(dom, node). Subclasses may override this
-        to perform additional initializations to view, either before or after calling
-        the inherited version.
-    */
-    virtual void inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    enum {
-        kMinIDStrAlloc = 64
-    };
-    SkTDict<SkView*> fIDs;
-
-    struct IDStr {
-        SkView* fView;
-        char*   fStr;
-    };
-    SkTDArray<IDStr>    fListenTo, fBroadcastTo;
-    SkChunkAlloc        fStrings;
-
-    void addIDStr(SkTDArray<IDStr>* list, SkView*, const char* str);
-
-    void    rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent);
-};
-
-#endif
-
diff --git a/include/views/SkWidget.h b/include/views/SkWidget.h
deleted file mode 100644
index db85f01..0000000
--- a/include/views/SkWidget.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkWidget_DEFINED
-#define SkWidget_DEFINED
-
-#include "SkView.h"
-#include "SkBitmap.h"
-#include "SkDOM.h"
-#include "SkPaint.h"
-#include "SkString.h"
-#include "SkTDArray.h"
-
-//////////////////////////////////////////////////////////////////////////////
-
-class SkWidget : public SkView {
-public:
-    SkWidget(uint32_t flags = 0) : SkView(flags | kFocusable_Mask | kEnabled_Mask) {}
-
-    /** Call this to post the widget's event to its listeners */
-    void    postWidgetEvent();
-
-    static void Init();
-    static void Term();
-protected:
-    // override to add slots to an event before posting
-    virtual void prepareWidgetEvent(SkEvent*);
-    virtual void onEnabledChange();
-
-    // <event ...> to initialize the event from XML
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    SkEvent fEvent;
-    typedef SkView INHERITED;
-};
-
-class SkHasLabelWidget : public SkWidget {
-public:
-    SkHasLabelWidget(uint32_t flags = 0) : SkWidget(flags) {}
-
-    size_t  getLabel(SkString* label = NULL) const;
-    size_t  getLabel(char lable[] = NULL) const;
-    void    setLabel(const SkString&);
-    void    setLabel(const char label[]);
-    void    setLabel(const char label[], size_t len);
-
-protected:
-    // called when the label changes
-    virtual void onLabelChange();
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    SkString    fLabel;
-    typedef SkWidget INHERITED;
-};
-
-class SkButtonWidget : public SkHasLabelWidget {
-public:
-    SkButtonWidget(uint32_t flags = 0) : SkHasLabelWidget(flags), fState(kOff_State) {}
-
-    enum State {
-        kOff_State,     //!< XML: buttonState="off"
-        kOn_State,      //!< XML: buttonState="on"
-        kUnknown_State  //!< XML: buttonState="unknown"
-    };
-    State   getButtonState() const { return fState; }
-    void    setButtonState(State);
-
-protected:
-    /** called when the label changes. default behavior is to inval the widget */
-    virtual void onButtonStateChange();
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    State   fState;
-    typedef SkHasLabelWidget INHERITED;
-};
-
-class SkPushButtonWidget : public SkButtonWidget {
-public:
-    SkPushButtonWidget(uint32_t flags = 0) : SkButtonWidget(flags) {}
-
-protected:
-    virtual bool onEvent(const SkEvent&);
-    virtual void onDraw(SkCanvas*);
-    virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
-    virtual bool onClick(Click* click);
-
-private:
-    typedef SkButtonWidget INHERITED;
-};
-
-class SkCheckBoxWidget : public SkButtonWidget {
-public:
-    SkCheckBoxWidget(uint32_t flags = 0);
-
-protected:
-    virtual bool onEvent(const SkEvent&);
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    typedef SkButtonWidget INHERITED;
-};
-
-#include "SkTextBox.h"
-
-class SkStaticTextView : public SkView {
-public:
-            SkStaticTextView(uint32_t flags = 0);
-    virtual ~SkStaticTextView();
-
-    enum Mode {
-        kFixedSize_Mode,
-        kAutoWidth_Mode,
-        kAutoHeight_Mode,
-
-        kModeCount
-    };
-    Mode    getMode() const { return (Mode)fMode; }
-    void    setMode(Mode);
-
-    SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
-    void    setSpacingAlign(SkTextBox::SpacingAlign);
-
-    void    getMargin(SkPoint* margin) const;
-    void    setMargin(SkScalar dx, SkScalar dy);
-
-    size_t  getText(SkString* text = NULL) const;
-    size_t  getText(char text[] = NULL) const;
-    void    setText(const SkString&);
-    void    setText(const char text[]);
-    void    setText(const char text[], size_t len);
-
-    void    getPaint(SkPaint*) const;
-    void    setPaint(const SkPaint&);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    SkPoint     fMargin;
-    SkString    fText;
-    SkPaint     fPaint;
-    uint8_t     fMode;
-    uint8_t     fSpacingAlign;
-
-    void computeSize();
-
-    typedef SkView INHERITED;
-};
-
-class SkBitmapView : public SkView {
-public:
-            SkBitmapView(uint32_t flags = 0);
-    virtual ~SkBitmapView();
-
-    bool    getBitmap(SkBitmap*) const;
-    void    setBitmap(const SkBitmap*, bool viewOwnsPixels);
-    bool    loadBitmapFromFile(const char path[]);
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM&, const SkDOM::Node*);
-
-private:
-    SkBitmap    fBitmap;
-    typedef SkView INHERITED;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-class SkShader;
-class SkInterpolator;
-
-class SkWidgetView : public SkView {
-public:
-            SkWidgetView(uint32_t flags = 0);
-    virtual ~SkWidgetView();
-
-    static const char*  GetEventType();
-};
-
-class SkSliderView : public SkWidgetView {
-public:
-    SkSliderView(uint32_t flags = 0);
-
-    uint16_t    getValue() const { return fValue; }
-    uint16_t    getMax() const { return fMax; }
-
-    void    setMax(U16CPU max);
-    void    setValue(U16CPU value);
-
-protected:
-    virtual void    onDraw(SkCanvas*);
-    virtual Click*  onFindClickHandler(SkScalar x, SkScalar y);
-    virtual bool    onClick(Click*);
-
-private:
-    uint16_t fValue, fMax;
-
-    typedef SkWidgetView INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-class SkHasLabelView : public SkView {
-public:
-    void    getLabel(SkString*) const;
-    void    setLabel(const SkString&);
-    void    setLabel(const char label[]);
-
-protected:
-    SkString    fLabel;
-
-    // called when the label changes
-    virtual void onLabelChange();
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-};
-
-class SkPushButtonView : public SkHasLabelView {
-public:
-    SkPushButtonView(uint32_t flags = 0);
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-};
-
-class SkCheckBoxView : public SkHasLabelView {
-public:
-    SkCheckBoxView(uint32_t flags = 0);
-
-    enum State {
-        kOff_State,
-        kOn_State,
-        kMaybe_State
-    };
-    State   getState() const { return fState; }
-    void    setState(State);
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    State   fState;
-};
-
-class SkProgressView : public SkView {
-public:
-    SkProgressView(uint32_t flags = 0);
-    virtual ~SkProgressView();
-
-    uint16_t    getValue() const { return fValue; }
-    uint16_t    getMax() const { return fMax; }
-
-    void    setMax(U16CPU max);
-    void    setValue(U16CPU value);
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    uint16_t    fValue, fMax;
-    SkShader*   fOnShader, *fOffShader;
-    SkInterpolator* fInterp;
-    bool fDoInterp;
-
-    typedef SkView INHERITED;
-};
-
-class SkTextView : public SkView {
-public:
-            SkTextView(uint32_t flags = 0);
-    virtual ~SkTextView();
-
-    enum AnimaDir {
-        kNeutral_AnimDir,
-        kForward_AnimDir,
-        kBackward_AnimDir,
-        kAnimDirCount
-    };
-
-    void    getText(SkString*) const;
-    void    setText(const SkString&, AnimaDir dir = kNeutral_AnimDir);
-    void    setText(const char text[], AnimaDir dir = kNeutral_AnimDir);
-    void    setText(const char text[], size_t len, AnimaDir dir = kNeutral_AnimDir);
-
-    void    getMargin(SkPoint* margin) const;
-    void    setMargin(const SkPoint&);
-
-    SkPaint&    paint() { return fPaint; }
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    SkString fText;
-    SkPaint  fPaint;
-    SkPoint  fMargin;
-
-    class Interp;
-    Interp* fInterp;
-    bool    fDoInterp;
-    // called by the other setText methods. This guy does not check for !=
-    // before doing the assign, so the caller must check for us
-    void privSetText(const SkString&, AnimaDir dir);
-
-    typedef SkView INHERITED;
-};
-
-//////////////////////////////////////////////////////////
-
-class SkEvent;
-
-class SkListSource : public SkEventSink {
-public:
-    virtual int countRows() = 0;
-    virtual void getRow(int index, SkString* left, SkString* right) = 0;
-    virtual SkEvent* getEvent(int index);
-
-    static SkListSource* CreateFromDir(const char path[], const char suffix[],
-                                        const char targetPrefix[]);
-    static SkListSource* CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node);
-};
-
-class SkListView : public SkWidgetView {
-public:
-            SkListView(uint32_t flags = 0);
-    virtual ~SkListView();
-
-    SkScalar    getRowHeight() const { return fRowHeight; }
-    void        setRowHeight(SkScalar);
-
-    /** Return the index of the selected row, or -1 if none
-    */
-    int     getSelection() const { return fCurrIndex; }
-    /** Set the index of the selected row, or -1 for none
-    */
-    void    setSelection(int);
-
-    void    moveSelectionUp();
-    void    moveSelectionDown();
-
-    enum Attr {
-        kBG_Attr,
-        kNormalText_Attr,
-        kHiliteText_Attr,
-        kHiliteCell_Attr,
-        kAttrCount
-    };
-    SkPaint&    paint(Attr);
-
-    SkListSource*   getListSource() const { return fSource; }
-    SkListSource*   setListSource(SkListSource*);
-
-#if 0
-    enum Action {
-        kSelectionChange_Action,
-        kSelectionPicked_Action,
-        kActionCount
-    };
-    /** If event is not null, it is retained by the view, and a copy
-        of the event will be posted to its listeners when the specified
-        action occurs. If event is null, then no event will be posted for
-        the specified action.
-    */
-    void    setActionEvent(Action, SkEvent* event);
-#endif
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onSizeChange();
-    virtual bool onEvent(const SkEvent&);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    SkPaint         fPaint[kAttrCount];
-    SkListSource*   fSource;
-    SkScalar        fRowHeight;
-    int             fCurrIndex;     // logical index
-    int             fScrollIndex;   // logical index of top-most visible row
-    int             fVisibleRowCount;
-    SkString*       fStrCache;
-
-    void    dirtyStrCache();
-    void    ensureStrCache(int visibleCount);
-
-    int     logicalToVisualIndex(int index) const { return index - fScrollIndex; }
-    void    invalSelection();
-    bool    getRowRect(int index, SkRect*) const;
-    void    ensureSelectionIsVisible();
-
-    typedef SkWidgetView INHERITED;
-};
-
-//////////////////////////////////////////////////////////
-
-class SkGridView : public SkWidgetView {
-public:
-            SkGridView(uint32_t flags = 0);
-    virtual ~SkGridView();
-
-    void    getCellSize(SkPoint*) const;
-    void    setCellSize(SkScalar x, SkScalar y);
-
-    /** Return the index of the selected item, or -1 if none
-    */
-    int     getSelection() const { return fCurrIndex; }
-    /** Set the index of the selected row, or -1 for none
-    */
-    void    setSelection(int);
-
-    void    moveSelectionUp();
-    void    moveSelectionDown();
-
-    enum Attr {
-        kBG_Attr,
-        kHiliteCell_Attr,
-        kAttrCount
-    };
-    SkPaint&    paint(Attr);
-
-    SkListSource*   getListSource() const { return fSource; }
-    SkListSource*   setListSource(SkListSource*);
-
-protected:
-    virtual void onDraw(SkCanvas*);
-    virtual void onSizeChange();
-    virtual bool onEvent(const SkEvent&);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-
-private:
-    SkView*         fScrollBar;
-    SkPaint         fPaint[kAttrCount];
-    SkListSource*   fSource;
-    int             fCurrIndex;     // logical index
-
-    SkPoint         fCellSize;
-    SkIPoint        fVisibleCount;
-
-    int     logicalToVisualIndex(int index) const { return index; }
-    void    invalSelection();
-    bool    getCellRect(int index, SkRect*) const;
-    void    ensureSelectionIsVisible();
-
-    typedef SkWidgetView INHERITED;
-};
-
-#endif
-
diff --git a/include/views/SkWidgetViews.h b/include/views/SkWidgetViews.h
deleted file mode 100644
index 4dd8866..0000000
--- a/include/views/SkWidgetViews.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkWidgetViews_DEFINED
-#define SkWidgetViews_DEFINED
-
-#include "SkView.h"
-
-
-enum SkWidgetEnum {
-    kBorder_WidgetEnum,         //!< <sk-border>
-    kButton_WidgetEnum,         //!< <sk-button>
-    kImage_WidgetEnum,          //!< <sk-image>
-    kList_WidgetEnum,           //!< <sk-list>
-    kProgress_WidgetEnum,       //!< <sk-progress>
-    kScroll_WidgetEnum,         //!< <sk-scroll>
-    kText_WidgetEnum,           //!< <sk-text>
-    
-    kWidgetEnumCount
-};
-
-//determines which skin to use
-enum SkinEnum {
-    kBorder_SkinEnum,
-    kButton_SkinEnum,
-    kProgress_SkinEnum,
-    kScroll_SkinEnum,
-    kStaticText_SkinEnum,
-    
-    kSkinEnumCount
-};
-
-#include "SkAnimator.h"
-//used for inflates
-const char* get_skin_enum_path(SkinEnum se);
-void init_skin_anim(const char path[], SkAnimator* anim);
-void init_skin_anim(SkinEnum se, SkAnimator* anim);
-void init_skin_paint(SkinEnum se, SkPaint* paint);
-void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
-
-/** Given an enum value, return an instance of the specified widget.
-    If the enum is out of range, returns null
-*/
-SkView* SkWidgetFactory(SkWidgetEnum);
-/** Given the inflate/element name of a widget, return an instance of
-    the specified widget, or null if name does not match any known
-    widget type.
-*/
-SkView* SkWidgetFactory(const char name[]);
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkWidgetView : public SkView {
-public:
-    SkWidgetView();
-
-    const char* getLabel() const;
-    void        getLabel(SkString* label) const;
-
-    void        setLabel(const char[]);
-    void        setLabel(const char[], size_t len);
-    void        setLabel(const SkString&);
-
-    SkEvent&        event() { return fEvent; }
-    const SkEvent&  event() const { return fEvent; }
-
-    /** Returns true if the widget can post its event to its listeners.
-    */
-    bool    postWidgetEvent();
-    
-    /** Returns the sinkID of the widgetview that posted the event, or 0
-    */
-    static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
-
-protected:
-    /** called when the label changes. override in subclasses. default action invals the view's bounds.
-        called with the old and new labels, before the label has actually changed.
-    */
-    virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
-    /** called before posting the event to our listeners. Override to add slots to the event
-        before posting. Return true to proceed with posting, or false to not post the event to any
-        listener. Note: the event passed in may not be the same as calling this->event().
-        Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
-        at modifying the event (and possibly returning false to abort).
-    */
-    virtual bool onPrepareWidgetEvent(SkEvent* evt);
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-    
-private:
-    SkString    fLabel;
-    SkEvent     fEvent;
-    
-    typedef SkView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkButtonView : public SkWidgetView {
-public:
-    // inflate: "sk-button"
-    
-protected:
-    // overrides
-    virtual bool onEvent(const SkEvent&);
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkCheckButtonView : public SkWidgetView {
-public:
-    SkCheckButtonView();
-
-    // inflate: "sk-checkbutton"
-    
-    enum CheckState {
-        kOff_CheckState,        //!< inflate: check-state="off"
-        kOn_CheckState,         //!< inflate: check-state="on"
-        kUnknown_CheckState     //!< inflate: check-state="unknown"
-    };
-    CheckState  getCheckState() const { return (CheckState)fCheckState; }
-    void        setCheckState(CheckState);
-
-    /** use this to extract the CheckState from an event (i.e. one that as posted
-        by a SkCheckButtonView). Returns true if the proper slot was present in the event,
-        and sets state to that value. If no proper slot is found, returns false and does not
-        modify state.
-    */
-    static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
-
-protected:
-    // called when the check-state is about to change, but before it actually has
-    virtual void onCheckStateChange(CheckState oldState, CheckState newState);
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-    virtual bool onPrepareWidgetEvent(SkEvent* evt);
-    
-private:
-    uint8_t  fCheckState;
-    
-    typedef SkWidgetView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-#include "SkTextBox.h"
-
-class SkStaticTextView : public SkView {
-public:
-            SkStaticTextView();
-    virtual ~SkStaticTextView();
-
-    enum Mode {
-        kFixedSize_Mode,
-        kAutoWidth_Mode,
-        kAutoHeight_Mode,
-
-        kModeCount
-    };
-    Mode    getMode() const { return (Mode)fMode; }
-    void    setMode(Mode);
-
-    SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
-    void    setSpacingAlign(SkTextBox::SpacingAlign);
-
-    void    getMargin(SkPoint* margin) const;
-    void    setMargin(SkScalar dx, SkScalar dy);
-
-    size_t  getText(SkString* text = NULL) const;
-    size_t  getText(char text[] = NULL) const;
-    void    setText(const SkString&);
-    void    setText(const char text[]);
-    void    setText(const char text[], size_t len);
-
-    void    getPaint(SkPaint*) const;
-    void    setPaint(const SkPaint&);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    SkPoint     fMargin;
-    SkString    fText;
-    SkPaint     fPaint;
-    uint8_t     fMode;
-    uint8_t     fSpacingAlign;
-
-    void computeSize();
-
-    typedef SkView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkAnimator;
-class SkListSource;
-class SkScrollBarView;
-
-class SkListView : public SkWidgetView {
-public:
-            SkListView();
-    virtual ~SkListView();
-
-    bool    hasScrollBar() const { return fScrollBar != NULL; }
-    void    setHasScrollBar(bool);
-    
-    /** Return the number of visible rows
-    */
-    int     getVisibleRowCount() const { return fVisibleRowCount; }
-    /** Return the index of the selected row, or -1 if none
-    */
-    int     getSelection() const { return fCurrIndex; }
-    /** Set the index of the selected row, or -1 for none
-    */
-    void    setSelection(int);
-    /** If possible, move the selection up and return true,
-        else do nothing and return false
-        If nothing is selected, select the last item (unless there are no items).
-    */
-    bool    moveSelectionUp();
-    /** If possible, move the selection down and return true,
-        else do nothing and return false.
-        If nothing is selected, select the first item (unless there are no items).
-    */
-    bool    moveSelectionDown();
-
-    SkListSource*   getListSource() const { return fSource; }
-    SkListSource*   setListSource(SkListSource*);
-
-    /** Call this in your event handler. If the specified event is from a SkListView,
-        then it returns the index of the selected item in this list, otherwise it
-        returns -1
-    */
-    static int GetWidgetEventListIndex(const SkEvent&);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual void onSizeChange();
-    virtual bool onEvent(const SkEvent&);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-    virtual bool onPrepareWidgetEvent(SkEvent*);
-
-private:
-    enum DirtyFlags {
-        kAnimCount_DirtyFlag    = 0x01,
-        kAnimContent_DirtyFlag  = 0x02
-    };
-    void    dirtyCache(unsigned dirtyFlags);
-    bool    ensureCache();
-
-    int     logicalToVisualIndex(int index) const { return index - fScrollIndex; }
-    void    invalSelection();
-    SkScalar getContentWidth() const;
-    bool    getRowRect(int index, SkRect*) const;
-    void    ensureSelectionIsVisible();
-    void    ensureVisibleRowCount();
-
-    struct BindingRec;
-
-    enum Heights {
-        kNormal_Height,
-        kSelected_Height
-    };
-    SkListSource*   fSource;
-    SkScrollBarView*    fScrollBar;
-    SkAnimator*     fAnims;
-    BindingRec*     fBindings;
-    SkString        fSkinName;
-    SkScalar        fHeights[2];
-    int16_t         fScrollIndex, fCurrIndex;
-    uint16_t        fVisibleRowCount, fBindingCount;
-    SkBool8         fAnimContentDirty;
-    SkBool8         fAnimFocusDirty;
-
-    typedef SkWidgetView INHERITED;
-};
-
-class SkListSource : public SkRefCnt {
-public:
-    virtual int countFields();
-    virtual void getFieldName(int index, SkString* field);
-    /** Return the index of the named field, or -1 if not found */
-    virtual int findFieldIndex(const char field[]);
-
-    virtual int countRecords();
-    virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
-
-    virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
-    
-    static SkListSource* Factory(const char name[]);
-};
-
-#endif
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
deleted file mode 100644
index 5deefd5..0000000
--- a/include/views/SkWindow.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkWindow_DEFINED
-#define SkWindow_DEFINED
-
-#include "SkView.h"
-#include "SkBitmap.h"
-#include "SkMatrix.h"
-#include "SkRegion.h"
-#include "SkEvent.h"
-#include "SkKey.h"
-#include "SkTDArray.h"
-
-#ifdef SK_BUILD_FOR_WINCEx
-    #define SHOW_FPS
-#endif
-//#define USE_GX_SCREEN
-
-class SkCanvas;
-
-class SkOSMenu;
-
-class SkWindow : public SkView {
-public:
-            SkWindow();
-    virtual ~SkWindow();
-
-    const SkBitmap& getBitmap() const { return fBitmap; }
-
-    void    setConfig(SkBitmap::Config);
-    void    resize(int width, int height, SkBitmap::Config config = SkBitmap::kNo_Config);
-    void    eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
-    void    eraseRGB(U8CPU r, U8CPU g, U8CPU b);
-
-    bool    isDirty() const { return !fDirtyRgn.isEmpty(); }
-    bool    update(SkIRect* updateArea, SkCanvas* = NULL);
-    // does not call through to onHandleInval(), but does force the fDirtyRgn
-    // to be wide open. Call before update() to ensure we redraw everything.
-    void    forceInvalAll();
-    // return the bounds of the dirty/inval rgn, or [0,0,0,0] if none
-    const SkIRect& getDirtyBounds() const { return fDirtyRgn.getBounds(); }
-
-    bool    handleClick(int x, int y, Click::State);
-    bool    handleChar(SkUnichar);
-    bool    handleKey(SkKey);
-    bool    handleKeyUp(SkKey);
-    bool    handleMenu(uint32_t os_cmd);
-
-    void    addMenu(SkOSMenu*);
-    
-    const char* getTitle() const { return fTitle.c_str(); }
-    void    setTitle(const char title[]);
-
-    const SkMatrix& getMatrix() const { return fMatrix; }
-    void    setMatrix(const SkMatrix&);
-    void    preConcat(const SkMatrix&);
-    void    postConcat(const SkMatrix&);
-
-protected:
-    virtual bool onEvent(const SkEvent&);
-
-    // called if part of our bitmap is invalidated
-    virtual void onHandleInval(const SkIRect&);
-    virtual bool onHandleChar(SkUnichar);
-    virtual bool onHandleKey(SkKey);
-    virtual bool onHandleKeyUp(SkKey);
-    virtual void onAddMenu(const SkOSMenu*) {}
-    virtual void onSetTitle(const char title[]) {}
-
-    // overrides from SkView
-    virtual bool handleInval(const SkRect*);
-    virtual bool onGetFocusView(SkView** focus) const;
-    virtual bool onSetFocusView(SkView* focus);
-
-private:
-    SkBitmap::Config    fConfig;
-    SkBitmap    fBitmap;
-    SkRegion    fDirtyRgn;
-    Click*      fClick; // to track clicks
-
-    SkTDArray<SkOSMenu*>    fMenus;
-
-    SkView* fFocusView;
-    bool    fWaitingOnInval;
-    
-    SkString    fTitle;
-    SkMatrix    fMatrix;
-
-    typedef SkView INHERITED;
-};
-
-///////////////////////////////////////////////////////////
-
-#ifdef SK_USE_WXWIDGETS
-    #include "SkOSWindow_wxwidgets.h"
-#elif defined(SK_BUILD_FOR_MAC)
-    #include "SkOSWindow_Mac.h"
-#elif defined(SK_BUILD_FOR_WIN)
-    #include "SkOSWindow_Win.h"
-#elif defined(SK_BUILD_FOR_UNIXx)
-  #include "SkOSWindow_Unix.h"
-#elif defined(SK_BUILD_FOR_SDL)
-    #include "SkOSWindow_SDL.h"
-#elif defined(SK_BUILD_FOR_IOS)
-    #include "SkOSWindow_iOS.h"
-#endif
-
-#endif
-
diff --git a/src/core/SkAdvancedTypefaceMetrics.cpp b/src/core/SkAdvancedTypefaceMetrics.cpp
index 0c5ad8d..731478b 100644
--- a/src/core/SkAdvancedTypefaceMetrics.cpp
+++ b/src/core/SkAdvancedTypefaceMetrics.cpp
@@ -80,10 +80,7 @@
     int repeats = 0;
     for (int gId = 0; gId < num_glyphs; gId++) {
         Data advance;
-        if (!getAdvance(fontHandle, gId, &advance)) {
-            num_glyphs = (gId > 0) ? gId - 1 : 0;
-            break;
-        }
+        SkAssertResult(getAdvance(fontHandle, gId, &advance));
         if (advance == lastAdvance) {
             repeats++;
         } else if (curRange->fAdvance.count() == repeats + 1) {
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 9e6f993..a5f7d57 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -22,6 +22,7 @@
 #include "SkMask.h"
 #include "SkPixelRef.h"
 #include "SkThread.h"
+#include "SkUnPreMultiply.h"
 #include "SkUtils.h"
 #include "SkPackBits.h"
 #include <new>
@@ -598,6 +599,57 @@
     return base;
 }
 
+SkColor SkBitmap::getColor(int x, int y) const {
+    SkASSERT((unsigned)x < (unsigned)this->width());
+    SkASSERT((unsigned)y < (unsigned)this->height());
+
+    switch (this->config()) {
+        case SkBitmap::kA1_Config: {
+            uint8_t* addr = getAddr1(x, y);
+            uint8_t mask = 1 << (7  - (x % 8));
+            if (addr[0] & mask) {
+                return SK_ColorBLACK;
+            } else {
+                return 0;
+            }
+        }
+        case SkBitmap::kA8_Config: {
+            uint8_t* addr = getAddr8(x, y);
+            return SkColorSetA(0, addr[0]);
+        }
+        case SkBitmap::kIndex8_Config: {
+            SkPMColor c = getIndex8Color(x, y);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case SkBitmap::kRGB_565_Config: {
+            uint16_t* addr = getAddr16(x, y);
+            return SkPixel16ToColor(addr[0]);
+        }
+        case SkBitmap::kARGB_4444_Config: {
+            uint16_t* addr = getAddr16(x, y);
+            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case SkBitmap::kARGB_8888_Config: {
+            uint32_t* addr = getAddr32(x, y);
+            return SkUnPreMultiply::PMColorToColor(addr[0]);
+        }
+        case kRLE_Index8_Config: {
+            uint8_t dst;
+            const SkBitmap::RLEPixels* rle =
+                (const SkBitmap::RLEPixels*) getPixels();
+            SkPackBits::Unpack8(&dst, x, 1, rle->packedAtY(y));
+            return SkUnPreMultiply::PMColorToColor((*fColorTable)[dst]);
+        }
+        case kNo_Config:
+        case kConfigCount:
+            SkASSERT(false);
+            return 0;
+    }
+    SkASSERT(false);  // Not reached.
+    return 0;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -1185,10 +1237,11 @@
 #include "SkMaskFilter.h"
 #include "SkMatrix.h"
 
-void SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
+bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
                             Allocator *allocator, SkIPoint* offset) const {
     SkDEBUGCODE(this->validate();)
 
+    SkBitmap    tmpBitmap;
     SkMatrix    identity;
     SkMask      srcM, dstM;
 
@@ -1208,25 +1261,20 @@
         dstM.fRowBytes = SkAlign4(dstM.fBounds.width());
     } else {
     NO_FILTER_CASE:
-        dst->setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
+        tmpBitmap.setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
                        srcM.fRowBytes);
-        if (dst->allocPixels(allocator, NULL)) {
-            GetBitmapAlpha(*this, dst->getAddr8(0, 0), srcM.fRowBytes);
-            if (offset) {
-                offset->set(0, 0);
-            }
-            return;
+        if (!tmpBitmap.allocPixels(allocator, NULL)) {
+            // Allocation of pixels for alpha bitmap failed.
+            SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
+                    tmpBitmap.width(), tmpBitmap.height());
+            return false;
         }
-    ALLOC_ERR:
-        // Allocation of pixels for alpha bitmap failed.
-        SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
-                 dst->width(), dst->height());
-        // When pixels can't be allocated, reset destination bitmap
-        dst->reset();
+        GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes);
         if (offset) {
             offset->set(0, 0);
         }
-        return;
+        tmpBitmap.swap(*dst);
+        return true;
     }
 
     SkAutoMaskImage srcCleanup(&srcM, true);
@@ -1238,16 +1286,22 @@
 
     SkAutoMaskImage dstCleanup(&dstM, false);
 
-    dst->setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
+    tmpBitmap.setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
                    dstM.fBounds.height(), dstM.fRowBytes);
-    if (!dst->allocPixels(allocator, NULL)) {
-        goto ALLOC_ERR;
+    if (!tmpBitmap.allocPixels(allocator, NULL)) {
+        // Allocation of pixels for alpha bitmap failed.
+        SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
+                tmpBitmap.width(), tmpBitmap.height());
+        return false;
     }
-    memcpy(dst->getPixels(), dstM.fImage, dstM.computeImageSize());
+    memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize());
     if (offset) {
         offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
     }
-    SkDEBUGCODE(dst->validate();)
+    SkDEBUGCODE(tmpBitmap.validate();)
+
+    tmpBitmap.swap(*dst);
+    return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1436,3 +1490,4 @@
 #endif
 }
 #endif
+
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 1eaa46d..a16e96a 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -44,10 +44,10 @@
     this->INHERITED::endSession();
 }
 
-SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, 
-                                                   SkMatrix* texM, 
+SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
+                                                   SkMatrix* texM,
                                                    TileMode xy[],
-                                                   SkScalar* twoPointRadialParams) {
+                                       SkScalar* twoPointRadialParams) const {
     if (texture) {
         *texture = fRawBitmap;
     }
@@ -95,7 +95,7 @@
 
     const SkBitmap& bitmap = *fState.fBitmap;
     bool bitmapIsOpaque = bitmap.isOpaque();
-    
+
     // update fFlags
     uint32_t flags = 0;
     if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
@@ -182,7 +182,7 @@
         }
 #endif
         sproc(state, buffer, n, dstC);
-        
+
         if ((count -= n) == 0) {
             break;
         }
@@ -198,7 +198,7 @@
         state.fShaderProc16(state, x, y, dstC, count);
         return;
     }
-    
+
     uint32_t buffer[BUF_MAX];
     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16;
@@ -215,7 +215,7 @@
         }
         mproc(state, buffer, n, x, y);
         sproc(state, buffer, n, dstC);
-        
+
         if ((count -= n) == 0) {
             break;
         }
@@ -287,7 +287,7 @@
     str->printf("BitmapShader: [%d %d %d",
                 fRawBitmap.width(), fRawBitmap.height(),
                 fRawBitmap.bytesPerPixel());
-    
+
     // add the pixelref
     SkPixelRef* pr = fRawBitmap.pixelRef();
     if (pr) {
@@ -296,7 +296,7 @@
             str->appendf(" \"%s\"", uri);
         }
     }
-    
+
     // add the (optional) matrix
     {
         SkMatrix m;
@@ -306,7 +306,7 @@
             str->appendf(" %s", info.c_str());
         }
     }
-    
+
     str->appendf(" [%s %s]]",
                  gTileModeName[fState.fTileModeX],
                  gTileModeName[fState.fTileModeY]);
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 88598fc..bd19b75 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -32,12 +32,12 @@
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
     virtual void beginSession();
     virtual void endSession();
-    virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*, 
-                                 SkScalar* twoPointRadialParams);
+    virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*,
+                                 SkScalar* twoPointRadialParams) const;
 
     static bool CanDo(const SkBitmap&, TileMode tx, TileMode ty);
 
-    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 
+    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(SkBitmapProcShader, (buffer));
     }
 
@@ -53,7 +53,7 @@
     SkBitmapProcState fState;
     uint32_t          fFlags;
 
-private:    
+private:
     typedef SkShader INHERITED;
 };
 
diff --git a/src/core/SkBitmapProcState_filter.h b/src/core/SkBitmapProcState_filter.h
index 7b9b3e5..d187983 100644
--- a/src/core/SkBitmapProcState_filter.h
+++ b/src/core/SkBitmapProcState_filter.h
@@ -111,7 +111,7 @@
     SkASSERT((unsigned)y <= 0xF);
     
     int xy = x * y;
-    uint32_t mask = gMask_00FF00FF; //0xFF00FF;
+    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
     
     int scale = 256 - 16*y - 16*x + xy;
     uint32_t lo = (a00 & mask) * scale;
@@ -141,7 +141,7 @@
     SkASSERT(alphaScale <= 256);
     
     int xy = x * y;
-    uint32_t mask = gMask_00FF00FF; //0xFF00FF;
+    static const uint32_t mask = gMask_00FF00FF; //0xFF00FF;
     
     int scale = 256 - 16*y - 16*x + xy;
     uint32_t lo = (a00 & mask) * scale;
diff --git a/src/core/SkBlitRow_D32.cpp b/src/core/SkBlitRow_D32.cpp
index f500778..642fe7f 100644
--- a/src/core/SkBlitRow_D32.cpp
+++ b/src/core/SkBlitRow_D32.cpp
@@ -128,7 +128,7 @@
     SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
     // just so we don't crash
     flags &= kFlags32_Mask;
-    
+
     SkBlitRow::Proc32 proc = PlatformProcs32(flags);
     if (NULL == proc) {
         proc = gDefault_Procs32[flags];
@@ -146,7 +146,7 @@
     return proc;
 }
 
-void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], 
+void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[],
                         int count, SkPMColor color) {
     if (count > 0) {
         if (0 == color) {
@@ -168,5 +168,84 @@
     }
 }
 
+///////////////////////////////////////////////////////////////////////////////
 
+static void D32_Mask_Color(void* dst, size_t dstRB, SkBitmap::Config,
+                           const uint8_t* mask, size_t maskRB, SkColor color,
+                           int width, int height) {
+    SkPMColor pmc = SkPreMultiplyColor(color);
+    size_t dstOffset = dstRB - (width << 2);
+    size_t maskOffset = maskRB - width;
+    SkPMColor *device = (SkPMColor *)dst;
+    do {
+        int w = width;
+        do {
+            unsigned aa = *mask++;
+            *device = SkBlendARGB32(pmc, *device, aa);
+            device += 1;
+        } while (--w != 0);
+        device = (uint32_t*)((char*)device + dstOffset);
+        mask += maskOffset;
+    } while (--height != 0);
+}
+
+static void D32_Mask_Opaque(void* dst, size_t dstRB, SkBitmap::Config,
+                            const uint8_t* mask, size_t maskRB, SkColor color,
+                            int width, int height) {
+    SkPMColor pmc = SkPreMultiplyColor(color);
+    uint32_t* device = (uint32_t*)dst;
+
+    maskRB -= width;
+    dstRB -= (width << 2);
+    do {
+        int w = width;
+        do {
+            unsigned aa = *mask++;
+            *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
+            device += 1;
+        } while (--w != 0);
+        device = (uint32_t*)((char*)device + dstRB);
+        mask += maskRB;
+    } while (--height != 0);
+}
+
+static void D32_Mask_Black(void* dst, size_t dstRB, SkBitmap::Config,
+                           const uint8_t* mask, size_t maskRB, SkColor,
+                           int width, int height) {
+    uint32_t* device = (uint32_t*)dst;
+
+    maskRB -= width;
+    dstRB -= (width << 2);
+    do {
+        int w = width;
+        do {
+            unsigned aa = *mask++;
+            *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
+            device += 1;
+        } while (--w != 0);
+        device = (uint32_t*)((char*)device + dstRB);
+        mask += maskRB;
+    } while (--height != 0);
+}
+
+SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config, SkColor color) {
+    SkBlitMask::Proc proc = PlatformProcs(config, color);
+    proc = NULL;
+    if (NULL == proc) {
+        switch (config) {
+            case SkBitmap::kARGB_8888_Config:
+                if (SK_ColorBLACK == color) {
+                    proc = D32_Mask_Black;
+                } else if (0xFF == SkColorGetA(color)) {
+                    proc = D32_Mask_Opaque;
+                } else {
+                    proc = D32_Mask_Color;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    return proc;
+}
 
diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp
index a775adb..d923315 100644
--- a/src/core/SkBlitter_ARGB32.cpp
+++ b/src/core/SkBlitter_ARGB32.cpp
@@ -38,6 +38,74 @@
 using namespace skia_blitter_support;
 #endif
 
+///////////////////////////////////////////////////////////////////////////////
+
+static int upscale31To256(int value) {
+    SkASSERT((unsigned)value <= 31);
+    // 0..31 -> 0..255
+    value = (value << 3) | (value >> 2);
+    // 0..255 -> 0..256
+    value += (value >> 7);
+    SkASSERT((unsigned)value <= 256);
+    return value;
+}
+
+static void blit_lcd16_opaque(SkPMColor dst[], const uint16_t src[],
+                              SkPMColor color, int width) {
+    int srcR = SkGetPackedR32(color);
+    int srcG = SkGetPackedG32(color);
+    int srcB = SkGetPackedB32(color);
+
+    for (int i = 0; i < width; i++) {
+        uint16_t mask = src[i];
+        if (0 == mask) {
+            continue;
+        }
+
+        /*  We want all of these in 5bits, hence the shifts in case one of them
+         *  (green) is 6bits.
+         */
+        int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+        int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+        int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+
+        // Now upscale them to 0..256, so we can use SkAlphaBlend
+        maskR = upscale31To256(maskR);
+        maskG = upscale31To256(maskG);
+        maskB = upscale31To256(maskB);
+
+        int maskA = SkMax32(SkMax32(maskR, maskG), maskB);
+
+        SkPMColor d = dst[i];
+        int dstA = SkGetPackedA32(d);
+        int dstR = SkGetPackedR32(d);
+        int dstG = SkGetPackedG32(d);
+        int dstB = SkGetPackedB32(d);
+
+        dst[i] = SkPackARGB32(SkAlphaBlend(0xFF, dstA, maskA),
+                              SkAlphaBlend(srcR, dstR, maskR),
+                              SkAlphaBlend(srcG, dstG, maskG),
+                              SkAlphaBlend(srcB, dstB, maskB));
+    }
+}
+
+static void blitmask_lcd16(const SkBitmap& device, const SkMask& mask,
+                           const SkIRect& clip, SkPMColor srcColor) {
+    int x = clip.fLeft;
+    int y = clip.fTop;
+    int width = clip.width();
+    int height = clip.height();
+
+    SkPMColor*		dstRow = device.getAddr32(x, y);
+    const uint16_t* srcRow = mask.getAddrLCD16(x, y);
+
+    do {
+        blit_lcd16_opaque(dstRow, srcRow, srcColor, width);
+        dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
+        srcRow = (const uint16_t*)((const char*)srcRow + mask.fRowBytes);
+    } while (--height != 0);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////
 
 static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
@@ -68,7 +136,8 @@
 
 SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
         : INHERITED(device) {
-    uint32_t color = paint.getColor();
+    SkColor color = paint.getColor();
+    fColor = color;
 
     fSrcA = SkColorGetA(color);
     unsigned scale = SkAlpha255To256(fSrcA);
@@ -78,6 +147,9 @@
 
     fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
     fColor32Proc = SkBlitRow::ColorProcFactory();
+
+    // init the pro for blitmask
+    fBlitMaskProc = SkBlitMask::Factory(SkBitmap::kARGB_8888_Config, color);
 }
 
 const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
@@ -185,29 +257,18 @@
     } else if (SkMask::kARGB32_Format == mask.fFormat) {
 		SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
 		return;
+    } else if (SkMask::kLCD16_Format == mask.fFormat) {
+        blitmask_lcd16(fDevice, mask, clip, fPMColor);
+        return;
     }
 
     int x = clip.fLeft;
     int y = clip.fTop;
-    int width = clip.width();
-    int height = clip.height();
 
-    uint32_t*       device = fDevice.getAddr32(x, y);
-    const uint8_t*  alpha = mask.getAddr(x, y);
-    uint32_t        srcColor = fPMColor;
-    unsigned        devRB = fDevice.rowBytes() - (width << 2);
-    unsigned        maskRB = mask.fRowBytes - width;
-
-    do {
-        int w = width;
-        do {
-            unsigned aa = *alpha++;
-            *device = SkBlendARGB32(srcColor, *device, aa);
-            device += 1;
-        } while (--w != 0);
-        device = (uint32_t*)((char*)device + devRB);
-        alpha += maskRB;
-    } while (--height != 0);
+    fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
+                  SkBitmap::kARGB_8888_Config,
+                  mask.getAddr(x, y), mask.fRowBytes,
+                  fColor, clip.width(), clip.height());
 }
 
 void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
@@ -220,6 +281,9 @@
     } else if (SkMask::kARGB32_Format == mask.fFormat) {
 		SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
 		return;
+    } else if (SkMask::kLCD16_Format == mask.fFormat) {
+        blitmask_lcd16(fDevice, mask, clip, fPMColor);
+        return;
 	}
 
     int x = clip.fLeft;
@@ -233,7 +297,7 @@
 #endif
 
     // In LCD mode the masks have either an extra couple of rows or columns on the edges.
-    uint32_t        srcColor = fPMColor;
+    SkPMColor srcColor = fPMColor;
 
 #if defined(SK_SUPPORT_LCDTEXT)
     if (lcdMode || verticalLCDMode) {
@@ -262,20 +326,9 @@
     }
 #endif
 
-    uint32_t*      device = fDevice.getAddr32(x, y);
-    const uint8_t* alpha = mask.getAddr(x, y);
-    unsigned       maskRB = mask.fRowBytes - width;
-    unsigned       devRB = fDevice.rowBytes() - (width << 2);
-    do {
-        int w = width;
-        do {
-            unsigned aa = *alpha++;
-            *device = SkAlphaMulQ(srcColor, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
-            device += 1;
-        } while (--w != 0);
-        device = (uint32_t*)((char*)device + devRB);
-        alpha += maskRB;
-    } while (--height != 0);
+    fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
+                  SkBitmap::kARGB_8888_Config,
+                  mask.getAddr(x, y), mask.fRowBytes, fColor, width, height);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
@@ -340,6 +393,8 @@
         SkARGB32_BlitBW(fDevice, mask, clip, black);
     } else if (SkMask::kARGB32_Format == mask.fFormat) {
 		SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
+    } else if (SkMask::kLCD16_Format == mask.fFormat) {
+        blitmask_lcd16(fDevice, mask, clip, fPMColor);
     } else {
 #if defined(SK_SUPPORT_LCDTEXT)
         const bool      lcdMode = mask.fFormat == SkMask::kHorizontalLCD_Format;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 43634ef..a31623e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -72,8 +72,7 @@
     SkDevice*           fDevice;
     SkRegion            fClip;
     const SkMatrix*     fMatrix;
-	SkPaint*			fPaint;	// may be null (in the future)
-    int16_t             fX, fY; // relative to base matrix/clip
+    SkPaint*            fPaint; // may be null (in the future)
     // optional, related to canvas' external matrix
     const SkMatrix*     fMVMatrix;
     const SkMatrix*     fExtMatrix;
@@ -85,8 +84,6 @@
             device->lockPixels();
         }
         fDevice = device;
-        fX = SkToS16(x);
-        fY = SkToS16(y);
         fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
 	}
 
@@ -100,8 +97,8 @@
 
     void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip,
                   const SkClipStack& clipStack, SkRegion* updateClip) {
-        int x = fX;
-        int y = fY;
+        int x = fDevice->getOrigin().x();
+        int y = fDevice->getOrigin().y();
         int width = fDevice->width();
         int height = fDevice->height();
 
@@ -147,12 +144,6 @@
         fExtMatrix = &extM; // assumes extM has long life-time (owned by canvas)
     }
 
-    void translateClip() {
-        if (fX | fY) {
-            fClip.translate(fX, fY);
-        }
-    }
-
 private:
     SkMatrix    fMatrixStorage, fMVMatrixStorage;
 };
@@ -230,6 +221,7 @@
         fCanvas = canvas;
         canvas->updateDeviceCMCache();
 
+        fClipStack = &canvas->getTotalClipStack();
         fBounder = canvas->getBounder();
         fCurrLayer = canvas->fMCRec->fTopLayer;
         fSkipEmptyClips = skipEmptyClips;
@@ -250,8 +242,6 @@
             fClip   = &rec->fClip;
             fDevice = rec->fDevice;
             fBitmap = &fDevice->accessBitmap(true);
-            fLayerX = rec->fX;
-            fLayerY = rec->fY;
             fPaint  = rec->fPaint;
             fMVMatrix = rec->fMVMatrix;
             fExtMatrix = rec->fExtMatrix;
@@ -263,24 +253,23 @@
             }
             // fCurrLayer may be NULL now
 
-            fCanvas->prepareForDeviceDraw(fDevice, *fMatrix, *fClip);
+            fCanvas->prepareForDeviceDraw(fDevice, *fMatrix, *fClip, *fClipStack);
             return true;
         }
         return false;
     }
 
-    int getX() const { return fLayerX; }
-    int getY() const { return fLayerY; }
     SkDevice* getDevice() const { return fDevice; }
+    int getX() const { return fDevice->getOrigin().x(); }
+    int getY() const { return fDevice->getOrigin().y(); }
     const SkMatrix& getMatrix() const { return *fMatrix; }
     const SkRegion& getClip() const { return *fClip; }
     const SkPaint* getPaint() const { return fPaint; }
+
 private:
     SkCanvas*       fCanvas;
     const DeviceCM* fCurrLayer;
     const SkPaint*  fPaint;     // May be null.
-    int             fLayerX;
-    int             fLayerY;
     SkBool8         fSkipEmptyClips;
 
     typedef SkDraw INHERITED;
@@ -631,10 +620,11 @@
 }
 
 void SkCanvas::prepareForDeviceDraw(SkDevice* device, const SkMatrix& matrix,
-                                    const SkRegion& clip) {
+                                    const SkRegion& clip,
+                                    const SkClipStack& clipStack) {
     SkASSERT(device);
     if (fLastDeviceToGainFocus != device) {
-        device->gainFocus(this, matrix, clip);
+        device->gainFocus(this, matrix, clip, clipStack);
         fLastDeviceToGainFocus = device;
     }
 }
@@ -746,6 +736,7 @@
 
     SkDevice* device = this->createDevice(config, ir.width(), ir.height(),
                                           isOpaque, true);
+    device->setOrigin(ir.fLeft, ir.fTop);
     DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint));
     device->unref();
 
@@ -798,7 +789,8 @@
     */
     if (NULL != layer) {
         if (layer->fNext) {
-            this->drawDevice(layer->fDevice, layer->fX, layer->fY,
+            const SkIPoint& origin = layer->fDevice->getOrigin();
+            this->drawDevice(layer->fDevice, origin.x(), origin.y(),
                              layer->fPaint);
             // reset this, since drawDevice will have set it to true
             fDeviceCMDirty = true;
@@ -952,10 +944,23 @@
 
 static bool clipPathHelper(const SkCanvas* canvas, SkRegion* currRgn,
                            const SkPath& devPath, SkRegion::Op op) {
+    // base is used to limit the size (and therefore memory allocation) of the
+    // region that results from scan converting devPath.
+    SkRegion base;
+
     if (SkRegion::kIntersect_Op == op) {
-        return currRgn->setPath(devPath, *currRgn);
+        // since we are intersect, we can do better (tighter) with currRgn's
+        // bounds, than just using the device. However, if currRgn is complex,
+        // our region blitter may hork, so we do that case in two steps.
+        if (currRgn->isRect()) {
+            return currRgn->setPath(devPath, *currRgn);
+        } else {
+            base.setRect(currRgn->getBounds());
+            SkRegion rgn;
+            rgn.setPath(devPath, base);
+            return currRgn->op(rgn, op);
+        }
     } else {
-        SkRegion base;
         const SkBitmap& bm = canvas->getDevice()->accessBitmap(false);
         base.setRect(0, 0, bm.width(), bm.height());
 
@@ -1016,13 +1021,15 @@
             clip->fRect->round(&ir);
             clipRgn.op(ir, clip->fOp);
         } else {
-            break;
+            clipRgn.setEmpty();
         }
     }
 
+#if 0   // enable this locally for testing
     // now compare against the current rgn
     const SkRegion& rgn = this->getTotalClip();
     SkASSERT(rgn == clipRgn);
+#endif
 }
 #endif
 
@@ -1149,6 +1156,10 @@
     return *fMCRec->fRegion;
 }
 
+const SkClipStack& SkCanvas::getTotalClipStack() const {
+    return fClipStack;
+}
+
 void SkCanvas::setExternalMatrix(const SkMatrix* matrix) {
     if (NULL == matrix || matrix->isIdentity()) {
         if (fUseExternalMatrix) {
@@ -1341,12 +1352,42 @@
     ITER_END
 }
 
+class SkDeviceFilteredPaint {
+public:
+    SkDeviceFilteredPaint(SkDevice* device, const SkPaint& paint) {
+        SkDevice::TextFlags flags;
+        if (device->filterTextFlags(paint, &flags)) {
+            SkPaint* newPaint = new (fStorage) SkPaint(paint);
+            newPaint->setFlags(flags.fFlags);
+            newPaint->setHinting(flags.fHinting);
+            fPaint = newPaint;
+        } else {
+            fPaint = &paint;
+        }
+    }
+
+    ~SkDeviceFilteredPaint() {
+        if (reinterpret_cast<SkPaint*>(fStorage) == fPaint) {
+            fPaint->~SkPaint();
+        }
+    }
+
+    const SkPaint& paint() const { return *fPaint; }
+
+private:
+    // points to either fStorage or the caller's paint
+    const SkPaint*  fPaint;
+    // we rely on the fPaint above to ensure proper alignment of fStorage
+    char            fStorage[sizeof(SkPaint)];
+};
+
 void SkCanvas::drawText(const void* text, size_t byteLength,
                         SkScalar x, SkScalar y, const SkPaint& paint) {
     ITER_BEGIN(paint, SkDrawFilter::kText_Type)
 
     while (iter.next()) {
-        iter.fDevice->drawText(iter, text, byteLength, x, y, paint);
+        SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+        iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
     }
 
     ITER_END
@@ -1357,8 +1398,9 @@
     ITER_BEGIN(paint, SkDrawFilter::kText_Type)
 
     while (iter.next()) {
+        SkDeviceFilteredPaint dfp(iter.fDevice, paint);
         iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2,
-                                  paint);
+                                  dfp.paint());
     }
 
     ITER_END
@@ -1370,8 +1412,9 @@
     ITER_BEGIN(paint, SkDrawFilter::kText_Type)
 
     while (iter.next()) {
+        SkDeviceFilteredPaint dfp(iter.fDevice, paint);
         iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1,
-                                  paint);
+                                  dfp.paint());
     }
 
     ITER_END
@@ -1390,6 +1433,7 @@
     ITER_END
 }
 
+#ifdef ANDROID
 void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength,
                                  const SkPoint pos[], const SkPaint& paint,
                                  const SkPath& path, const SkMatrix* matrix) {
@@ -1403,6 +1447,7 @@
 
     ITER_END
 }
+#endif
 
 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
                             const SkPoint verts[], const SkPoint texs[],
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 2b63aea..864f23a 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -116,7 +116,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkClipStack::B2FIter::B2FIter(const SkClipStack& stack) : fIter(stack.fDeque) {
+SkClipStack::B2FIter::B2FIter() {
+}
+
+SkClipStack::B2FIter::B2FIter(const SkClipStack& stack) {
+    this->reset(stack);
 }
 
 const SkClipStack::B2FIter::Clip* SkClipStack::B2FIter::next() {
@@ -142,3 +146,7 @@
     fClip.fOp = rec->fOp;
     return &fClip;
 }
+
+void SkClipStack::B2FIter::reset(const SkClipStack& stack) {
+    fIter.reset(stack.fDeque);
+}
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 32e8035..b8724c2 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -101,8 +101,10 @@
     virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
 
 protected:
-    SkColor                fPMColor;
+    SkColor                fColor;
+    SkPMColor              fPMColor;
     SkBlitRow::ColorProc   fColor32Proc;
+    SkBlitMask::Proc       fBlitMaskProc;
 
 private:
     unsigned fSrcA, fSrcR, fSrcG, fSrcB;
@@ -165,7 +167,7 @@
 
     // illegal
     SkA1_Blitter& operator=(const SkA1_Blitter&);
-    
+
     typedef SkRasterBlitter INHERITED;
 };
 
@@ -175,7 +177,7 @@
 
     Currently, they make the following assumptions about the state of the
     paint:
- 
+
     1. If there is an xfermode, there will also be a shader
     2. If there is a colorfilter, there will be a shader that itself handles
        calling the filter, so the blitter can always ignore the colorfilter obj
diff --git a/src/core/SkDeque.cpp b/src/core/SkDeque.cpp
index 2c6ce64..9d685ee 100644
--- a/src/core/SkDeque.cpp
+++ b/src/core/SkDeque.cpp
@@ -225,12 +225,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkDeque::F2BIter::F2BIter(const SkDeque& d) : fElemSize(d.fElemSize) {
-    fHead = d.fFront;
-    while (fHead != NULL && fHead->fBegin == NULL) {
-        fHead = fHead->fNext;
-    }
-    fPos = fHead ? fHead->fBegin : NULL;
+SkDeque::F2BIter::F2BIter() {
+    fPos = NULL;
+}
+
+SkDeque::F2BIter::F2BIter(const SkDeque& d) {
+    this->reset(d);
 }
 
 void* SkDeque::F2BIter::next() {
@@ -250,3 +250,11 @@
     return pos;
 }
 
+void SkDeque::F2BIter::reset(const SkDeque& d) {
+    fElemSize = d.fElemSize;
+    fHead = d.fFront;
+    while (fHead != NULL && fHead->fBegin == NULL) {
+        fHead = fHead->fNext;
+    }
+    fPos = fHead ? fHead->fBegin : NULL;
+}
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 2921be0..8231848 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -4,10 +4,13 @@
 
 SkDeviceFactory::~SkDeviceFactory() {}
 
-SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {}
+SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {
+    fOrigin.setZero();
+}
 
 SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
         : fCanvas(canvas), fBitmap(bitmap) {
+    fOrigin.setZero();
     // auto-allocate if we're for offscreen drawing
     if (isForLayer) {
         if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) {
@@ -150,11 +153,13 @@
     draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
 }
 
+#ifdef ANDROID
 void SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
                                      const SkPoint pos[], const SkPaint& paint,
                                      const SkPath& path, const SkMatrix* matrix) {
     draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
 }
+#endif
 
 void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
                                 int vertexCount,
@@ -173,6 +178,32 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
+    if (!paint.isLCDRenderText()) {
+        // we're cool with the paint as is
+        return false;
+    }
+
+    if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
+        paint.getShader() ||
+        paint.getXfermode() || // unless its srcover
+        paint.getMaskFilter() ||
+        paint.getRasterizer() ||
+        paint.getColorFilter() ||
+        paint.getPathEffect() ||
+        paint.isFakeBoldText() ||
+        paint.getStyle() != SkPaint::kFill_Style) {
+        // turn off lcd
+        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
+        flags->fHinting = paint.getHinting();
+        return true;
+    }
+    // we're cool with the paint as is
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 SkDevice* SkRasterDeviceFactory::newDevice(SkCanvas* canvas,
                                            SkBitmap::Config config, int width,
                                            int height, bool isOpaque,
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 05e249a..ce0fa9b 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1940,6 +1940,7 @@
     }
 }
 
+#ifdef ANDROID
 void SkDraw::drawPosTextOnPath(const char text[], size_t byteLength,
                                const SkPoint pos[], const SkPaint& paint,
                                const SkPath& path, const SkMatrix* matrix) const {
@@ -2001,6 +2002,7 @@
     // re-attach cache
     SkGlyphCache::AttachCache(cache);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index 199ac14..b97699c 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -37,7 +37,7 @@
     static void RecordHashCollisionIf(bool pred) {
         if (pred) {
             gHashCollision += 1;
-            
+
             uint32_t total = gHashSuccess + gHashCollision;
             SkDebugf("Font Cache Hash success rate: %d%%\n",
                      100 * gHashSuccess / total);
@@ -68,9 +68,9 @@
     memset(fGlyphHash, 0, sizeof(fGlyphHash));
     // init with 0xFF so that the charCode field will be -1, which is invalid
     memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash));
-    
+
     fMemoryUsed = sizeof(*this) + kMinGlphAlloc + kMinImageAlloc;
-    
+
     fGlyphArray.setReserve(METRICS_RESERVE_COUNT);
 
     fMetricsCount = 0;
@@ -105,7 +105,7 @@
     VALIDATE();
     uint32_t id = SkGlyph::MakeID(charCode);
     const CharGlyphRec& rec = fCharToGlyphHash[ID2HashIndex(id)];
-    
+
     if (rec.fID == id) {
         return rec.fGlyph->getGlyphID();
     } else {
@@ -117,13 +117,17 @@
     return fScalerContext->glyphIDToChar(glyphID);
 }
 
+unsigned SkGlyphCache::getGlyphCount() {
+    return fScalerContext->getGlyphCount();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
     VALIDATE();
     uint32_t id = SkGlyph::MakeID(charCode);
     CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)];
-    
+
     if (rec->fID != id) {
         // this ID is based on the UniChar
         rec->fID = id;
@@ -153,7 +157,7 @@
     VALIDATE();
     uint32_t id = SkGlyph::MakeID(charCode);
     CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)];
-    
+
     if (rec->fID != id) {
         RecordHashCollisionIf(rec->fGlyph != NULL);
         // this ID is based on the UniChar
@@ -176,7 +180,7 @@
     VALIDATE();
     uint32_t id = SkGlyph::MakeID(charCode, x, y);
     CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)];
-    
+
     if (rec->fID != id) {
         RecordHashCollisionIf(rec->fGlyph != NULL);
         // this ID is based on the UniChar
@@ -199,7 +203,7 @@
     uint32_t id = SkGlyph::MakeID(glyphID);
     unsigned index = ID2HashIndex(id);
     SkGlyph* glyph = fGlyphHash[index];
-    
+
     if (NULL == glyph || glyph->fID != id) {
         RecordHashCollisionIf(glyph != NULL);
         glyph = this->lookupMetrics(glyphID, kFull_MetricsType);
@@ -275,7 +279,7 @@
                                         SkChunkAlloc::kThrow_AllocFailType);
     glyph->init(id);
     *fGlyphArray.insert(hi) = glyph;
-    
+
     if (kJustAdvance_MetricsType == mtype) {
         fScalerContext->getAdvance(glyph);
         fAdvanceCount += 1;
@@ -294,8 +298,11 @@
             size_t  size = glyph.computeImageSize();
             const_cast<SkGlyph&>(glyph).fImage = fImageAlloc.alloc(size,
                                         SkChunkAlloc::kReturnNil_AllocFailType);
-            fScalerContext->getImage(glyph);
-            fMemoryUsed += size;
+            // check that alloc() actually succeeded
+            if (glyph.fImage) {
+                fScalerContext->getImage(glyph);
+                fMemoryUsed += size;
+            }
         }
     }
     return glyph.fImage;
@@ -391,7 +398,7 @@
     #define HASH_BITCOUNT   6
     #define HASH_COUNT      (1 << HASH_BITCOUNT)
     #define HASH_MASK       (HASH_COUNT - 1)
-    
+
     static unsigned desc_to_hashindex(const SkDescriptor* desc)
     {
         SkASSERT(HASH_MASK < 256);  // since our munging reduces to 8 bits
@@ -446,9 +453,9 @@
     SkGlyphCache_Globals& globals = FIND_GC_GLOBALS();
     SkAutoMutexAcquire    ac(globals.fMutex);
     SkGlyphCache*         cache;
-    
+
     globals.validate();
-    
+
     for (cache = globals.fHead; cache != NULL; cache = cache->fNext) {
         if (proc(cache, context)) {
             break;
@@ -560,7 +567,7 @@
 size_t SkGlyphCache::GetCacheUsed() {
     SkGlyphCache_Globals& globals = FIND_GC_GLOBALS();
     SkAutoMutexAcquire  ac(globals.fMutex);
-    
+
     return SkGlyphCache::ComputeMemoryUsed(globals.fHead);
 }
 
@@ -570,7 +577,7 @@
     if (curr > bytesUsed) {
         SkGlyphCache_Globals& globals = FIND_GC_GLOBALS();
         SkAutoMutexAcquire  ac(globals.fMutex);
-    
+
         return InternalFreeCache(&globals, curr - bytesUsed) > 0;
     }
     return false;
@@ -589,7 +596,7 @@
 
 size_t SkGlyphCache::ComputeMemoryUsed(const SkGlyphCache* head) {
     size_t size = 0;
-    
+
     while (head != NULL) {
         size += head->fMemoryUsed;
         head = head->fNext;
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 16330f8..92e3795 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -47,17 +47,17 @@
     */
     const SkGlyph& getUnicharAdvance(SkUnichar);
     const SkGlyph& getGlyphIDAdvance(uint16_t);
-    
+
     /** Returns a glyph with all fields valid except fImage and fPath, which
         may be null. If they are null, call findImage or findPath for those.
         If they are not null, then they are valid.
-        
+
         This call is potentially slower than the matching ...Advance call. If
         you only need the fAdvance/fDevKern fields, call those instead.
     */
     const SkGlyph& getUnicharMetrics(SkUnichar);
     const SkGlyph& getGlyphIDMetrics(uint16_t);
-    
+
     /** These are variants that take the device position of the glyph. Call
         these only if you are drawing in subpixel mode. Passing 0, 0 is
         effectively the same as calling the variants w/o the extra params, tho
@@ -65,18 +65,22 @@
     */
     const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
     const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
-    
+
     /** Return the glyphID for the specified Unichar. If the char has already
         been seen, use the existing cache entry. If not, ask the scalercontext
         to compute it for us.
     */
     uint16_t unicharToGlyph(SkUnichar);
-    
+
     /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to
         a character code of zero.
     */
     SkUnichar glyphToUnichar(uint16_t);
 
+    /** Returns the number of glyphs for this strike.
+    */
+    unsigned getGlyphCount();
+
     /** Return the image associated with the glyph. If it has not been generated
         this will trigger that.
     */
@@ -94,6 +98,10 @@
 
     const SkDescriptor& getDescriptor() const { return *fDesc; }
 
+    SkMask::Format getMaskFormat() const {
+        return fScalerContext->getMaskFormat();
+    }
+
     /*  AuxProc/Data allow a client to associate data with this cache entry.
         Multiple clients can use this, as their data is keyed with a function
         pointer. In addition to serving as a key, the function pointer is called
@@ -102,7 +110,7 @@
         this glyphcache in any way, since it may be in the process of being
         deleted.
     */
-    
+
     //! If the proc is found, return true and set *dataPtr to its data
     bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const;
     //! Add a proc/data pair to the glyphcache. proc should be non-null
@@ -116,7 +124,7 @@
         deadlock.
     */
     static void VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), void* ctx);
-    
+
     /** Find a matching cache entry, and call proc() with it. If none is found
         create a new one. If the proc() returns true, detach the cache and
         return it, otherwise leave it and return NULL.
@@ -124,7 +132,7 @@
     static SkGlyphCache* VisitCache(const SkDescriptor* desc,
                                     bool (*proc)(const SkGlyphCache*, void*),
                                     void* context);
-    
+
     /** Given a strike that was returned by either VisitCache() or DetachCache()
         add it back into the global cache list (after which the caller should
         not reference it anymore.
@@ -180,11 +188,11 @@
     private:
         const SkGlyphCache* fCache;
     };
-        
+
 private:
     SkGlyphCache(const SkDescriptor*);
     ~SkGlyphCache();
-    
+
     enum MetricsType {
         kJustAdvance_MetricsType,
         kFull_MetricsType
@@ -204,7 +212,7 @@
         }
         fPrev = fNext = NULL;
     }
-    
+
     void attachToHead(SkGlyphCache** head) {
         SkASSERT(NULL == fPrev && NULL == fNext);
         if (*head) {
@@ -228,7 +236,7 @@
     SkTDArray<SkGlyph*> fGlyphArray;
     SkChunkAlloc        fGlyphAlloc;
     SkChunkAlloc        fImageAlloc;
-    
+
     int fMetricsCount, fAdvanceCount;
 
     struct CharGlyphRec {
@@ -237,7 +245,7 @@
     };
     // no reason to use the same kHashCount as fGlyphHash, but we do for now
     CharGlyphRec    fCharToGlyphHash[kHashCount];
-    
+
     enum {
         // shift so that the top bits fall into kHashBits region
         kShiftForHashIndex = SkGlyph::kSubShift +
@@ -248,7 +256,7 @@
     static inline unsigned ID2HashIndex(uint32_t id) {
         return (id ^ (id >> kShiftForHashIndex)) & kHashMask;
     }
-    
+
     // used to track (approx) how much ram is tied-up in this cache
     size_t  fMemoryUsed;
 
@@ -298,7 +306,7 @@
     }
 private:
     SkGlyphCache*   fCache;
-    
+
     static bool DetachProc(const SkGlyphCache*, void*);
 };
 
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 845896a..5c0f922 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -246,8 +246,9 @@
         }
     }
 #ifdef SK_DEBUG
-    else
+    else {
         SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
+    }
 #endif
 }
 
@@ -286,8 +287,9 @@
         }
     }
 #ifdef SK_DEBUG
-    else
+    else {
         SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
+    }
 #endif
 }
 
@@ -300,8 +302,9 @@
         }
     }
 #ifdef SK_DEBUG
-    else
+    else {
         SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
+    }
 #endif
 }
 
@@ -1255,14 +1258,19 @@
     uint32_t flags = paint.getFlags();
 
     // Antialiasing being disabled trumps all other settings.
-    if (!(flags & SkPaint::kAntiAlias_Flag))
+    if (!(flags & SkPaint::kAntiAlias_Flag)) {
         return SkMask::kBW_Format;
+    }
 
 #if defined(SK_SUPPORT_LCDTEXT)
     if (flags & SkPaint::kLCDRenderText_Flag) {
         return SkFontHost::GetSubpixelOrientation() == SkFontHost::kHorizontal_LCDOrientation ?
                    SkMask::kHorizontalLCD_Format : SkMask::kVerticalLCD_Format;
     }
+#else
+    if (flags & SkPaint::kLCDRenderText_Flag) {
+        return SkMask::kLCD16_Format;
+    }
 #endif
 
     return SkMask::kA8_Format;
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 4962239..a01d8e1 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -102,7 +102,9 @@
 
 SkPath::SkPath(const SkPath& src) {
     SkDEBUGCODE(src.validate();)
+    uint32_t currentGenID = fGenerationID;
     *this = src;
+    fGenerationID = currentGenID;
 }
 
 SkPath::~SkPath() {
@@ -157,6 +159,7 @@
     fVerbs.reset();
     fGenerationID++;
     fBoundsIsDirty = true;
+    fIsConvex = false;  // really should be kUnknown
 }
 
 void SkPath::rewind() {
@@ -166,6 +169,7 @@
     fVerbs.rewind();
     fGenerationID++;
     fBoundsIsDirty = true;
+    fIsConvex = false;  // really should be kUnknown
 }
 
 bool SkPath::isEmpty() const {
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index c376412..f558f52 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -35,7 +35,7 @@
 
 void SkPixelRef::lockPixels() {
     SkAutoMutexAcquire  ac(*fMutex);
-    
+
     if (1 == ++fLockCount) {
         fPixels = this->onLockPixels(&fColorTable);
     }
@@ -43,7 +43,7 @@
 
 void SkPixelRef::unlockPixels() {
     SkAutoMutexAcquire  ac(*fMutex);
-    
+
     SkASSERT(fLockCount > 0);
     if (0 == --fLockCount) {
         this->onUnlockPixels();
@@ -94,15 +94,15 @@
 void SkPixelRef::Register(const char name[], Factory factory) {
     SkASSERT(name);
     SkASSERT(factory);
-    
+
     static bool gOnce;
     if (!gOnce) {
         gCount = 0;
         gOnce = true;
     }
-    
+
     SkASSERT(gCount < MAX_PAIR_COUNT);
-    
+
     gPairs[gCount].fName = name;
     gPairs[gCount].fFactory = factory;
     gCount += 1;
@@ -128,6 +128,9 @@
     return NULL;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef ANDROID
 void SkPixelRef::globalRef(void* data) {
     this->ref();
 }
@@ -135,3 +138,4 @@
 void SkPixelRef::globalUnref() {
     this->unref();
 }
+#endif
diff --git a/src/core/SkRefCnt.cpp b/src/core/SkRefCnt.cpp
deleted file mode 100644
index fea1005..0000000
--- a/src/core/SkRefCnt.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/* libs/graphics/sgl/SkRefCnt.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkRefCnt.h"
-
-SkAutoUnref::~SkAutoUnref() {
-    if (fObj) {
-        fObj->unref();
-    }
-}
-
-bool SkAutoUnref::ref() {
-    if (fObj) {
-        fObj->ref();
-        return true;
-    }
-    return false;
-}
-
-bool SkAutoUnref::unref() {
-    if (fObj) {
-        fObj->unref();
-        fObj = NULL;
-        return true;
-    }
-    return false;
-}
-
-SkRefCnt* SkAutoUnref::detach() {
-    SkRefCnt* obj = fObj;
-    fObj = NULL;
-    return obj;
-}
-
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index dfb3aa0..18dafb0 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -18,7 +18,10 @@
 #include "SkRegionPriv.h"
 #include "SkTemplates.h"
 #include "SkThread.h"
+
+#ifdef ANDROID
 #include <stdio.h>
+#endif
 
 SkDEBUGCODE(int32_t gRgnAllocCounter;)
 
@@ -191,6 +194,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////
 
+#ifdef ANDROID
 char* SkRegion::toString()
 {
     Iterator iter(*this);
@@ -215,6 +219,7 @@
     count += sprintf(result+count, ")");
     return result;
 }
+#endif
 
 //////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 697917a..ff8e168 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -497,6 +497,7 @@
 
     if (NULL == fMaskFilter &&
         fRec.fMaskFormat != SkMask::kBW_Format &&
+        fRec.fMaskFormat != SkMask::kLCD16_Format &&
         (fRec.fFlags & (kGammaForBlack_Flag | kGammaForWhite_Flag)) != 0)
     {
         const uint8_t* table = (fRec.fFlags & kGammaForBlack_Flag) ? gBlackGammaTable : gWhiteGammaTable;
@@ -645,7 +646,7 @@
     SkScalerContext_Empty(const SkDescriptor* desc) : SkScalerContext(desc) {}
 
 protected:
-    virtual unsigned generateGlyphCount() const {
+    virtual unsigned generateGlyphCount() {
         return 0;
     }
     virtual uint16_t generateCharToGlyph(SkUnichar uni) {
diff --git a/src/core/SkScanPriv.h b/src/core/SkScanPriv.h
index 74c2ee7..e78feed 100644
--- a/src/core/SkScanPriv.h
+++ b/src/core/SkScanPriv.h
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -40,9 +40,9 @@
                   SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
                   const SkRegion& clipRgn);
 
-// blit the rects above and below avoid, clipped to clp
-void sk_blit_above_and_below(SkBlitter* blitter, const SkIRect& avoid,
-                             const SkRegion& clip);
+// blit the rects above and below avoid, clipped to clip
+void sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
+void sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
 
 #endif
 
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index fb33ab0..90a1f68 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -56,12 +56,12 @@
 BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
                                    const SkRegion& clip) {
     fRealBlitter = realBlitter;
-    
+
     // take the union of the ir bounds and clip, since we may be called with an
     // inverse filltype
     const int left = SkMin32(ir.fLeft, clip.getBounds().fLeft);
     const int right = SkMax32(ir.fRight, clip.getBounds().fRight);
-    
+
     fLeft = left;
     fSuperLeft = left << SHIFT;
     fWidth = right - left;
@@ -153,7 +153,7 @@
 //  int maxValue = (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT);
 
 #if 0
-    SkAntiRun<SHIFT>    arun;   
+    SkAntiRun<SHIFT>    arun;
     arun.set(x, x + width);
     fRuns.add(x >> SHIFT, arun.getStartAlpha(), arun.getMiddleCount(), arun.getStopAlpha(), maxValue);
 #else
@@ -215,11 +215,11 @@
     {
         int width = bounds.width();
         int rb = SkAlign4(width);
-        
+
         return (width <= MaskSuperBlitter::kMAX_WIDTH) &&
         (rb * bounds.height() <= MaskSuperBlitter::kMAX_STORAGE);
     }
-    
+
 private:
     enum {
         kMAX_WIDTH = 32,    // so we don't try to do very wide things, where the RLE blitter would be faster
@@ -242,10 +242,10 @@
     fMask.fBounds   = ir;
     fMask.fRowBytes = ir.width();
     fMask.fFormat   = SkMask::kA8_Format;
-    
+
     fClipRect = ir;
     fClipRect.intersect(clip.getBounds());
-    
+
     // For valgrind, write 1 extra byte at the end so we don't read
     // uninitialized memory. See comment in add_aa_span and fStorage[].
     memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
@@ -292,7 +292,7 @@
 void MaskSuperBlitter::blitH(int x, int y, int width)
 {
     int iy = (y >> SHIFT);
-    
+
     SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
     iy -= fMask.fBounds.fTop;   // make it relative to 0
 
@@ -309,7 +309,7 @@
         SkASSERT(ix >= fMask.fBounds.fLeft && ix < fMask.fBounds.fRight);
     }
 #endif
-    
+
     x -= (fMask.fBounds.fLeft << SHIFT);
 
     // hack, until I figure out why my cubics (I think) go beyond the bounds
@@ -397,12 +397,12 @@
         }
         return;
     }
-    
+
     // now use the (possibly wrapped) blitter
     blitter = clipper.getBlitter();
 
     if (path.isInverseFillType()) {
-        sk_blit_above_and_below(blitter, ir, clip);
+        sk_blit_above(blitter, ir, clip);
     }
 
     SkIRect superRect, *superClipRect = NULL;
@@ -429,4 +429,8 @@
         SuperBlitter    superBlit(blitter, ir, clip);
         sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
     }
+
+    if (path.isInverseFillType()) {
+        sk_blit_below(blitter, ir, clip);
+    }
 }
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index b1ba7df..c5088a1 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -75,7 +75,7 @@
     for (;;)
     {
         SkEdge* prev = edge->fPrev;
-        
+
         // add 1 to curr_y since we may have added new edges (built from curves)
         // that start on the next scanline
         SkASSERT(prev && prev->fFirstY <= curr_y + 1);
@@ -145,11 +145,11 @@
         SkFixed prevX = prevHead->fX;
 
         validate_edges_for_y(currE, curr_y);
-        
+
         if (proc) {
             proc(blitter, curr_y, PREPOST_START);    // pre-proc
         }
-        
+
         while (currE->fFirstY <= curr_y)
         {
             SkASSERT(currE->fLastY >= curr_y);
@@ -181,7 +181,7 @@
                     if (((SkCubicEdge*)currE)->updateCubic())
                     {
                         SkASSERT(currE->fFirstY == curr_y + 1);
-                        
+
                         newX = currE->fX;
                         goto NEXT_X;
                     }
@@ -210,7 +210,7 @@
             currE = next;
             SkASSERT(currE);
         }
-        
+
         if (proc) {
             proc(blitter, curr_y, PREPOST_END);    // post-proc
         }
@@ -257,7 +257,7 @@
         }
         fPrevX = x + width;
     }
-    
+
     // we do not expect to get called with these entrypoints
     virtual void blitAntiH(int, int, const SkAlpha[], const int16_t runs[]) {
         SkASSERT(!"blitAntiH unexpected");
@@ -275,7 +275,7 @@
         SkASSERT(!"justAnOpaqueColor unexpected");
         return NULL;
     }
-    
+
 private:
     SkBlitter*  fBlitter;
     int         fFirstX, fLastX, fPrevX;
@@ -313,7 +313,7 @@
     SkPath::Iter    iter(path, true);
     SkPoint         pts[4];
     SkPath::Verb    verb;
-    
+
     SkQuadClipper qclipper;
     if (clipRect) {
         SkIRect r;
@@ -355,7 +355,7 @@
             case SkPath::kCubic_Verb: {
                 SkPoint tmp[10];
                 SkPoint* p = tmp;
-                int     count = SkChopCubicAtYExtrema(pts, tmp);                
+                int     count = SkChopCubicAtYExtrema(pts, tmp);
                 SkASSERT(count >= 0 && count <= 2);
 
                 do {
@@ -417,7 +417,7 @@
 */
 static int cheap_worst_case_edge_count(const SkPath& path, size_t* storage) {
     int ptCount = path.getPoints(NULL, 0);
-    // worst case is curve, close, curve, close, as that is 
+    // worst case is curve, close, curve, close, as that is
     //     2 lines per pt, or             : pts * 2
     //     2 quads + 1 line per 2 pts, or : pts * 3 / 2
     //     3 cubics + 1 line per 3 pts    : pts * 4 / 3
@@ -442,15 +442,15 @@
     static int edge_compare(const void* a, const void* b) {
         const SkEdge* edgea = *(const SkEdge**)a;
         const SkEdge* edgeb = *(const SkEdge**)b;
-        
+
         int valuea = edgea->fFirstY;
         int valueb = edgeb->fFirstY;
-        
+
         if (valuea == valueb) {
             valuea = edgea->fX;
             valueb = edgeb->fX;
         }
-        
+
         // this overflows if valuea >>> valueb or vice-versa
         //     return valuea - valueb;
         // do perform the slower but safe compares
@@ -460,13 +460,13 @@
 
 static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
     qsort(list, count, sizeof(SkEdge*), edge_compare);
-    
+
     // now make the edges linked in sorted order
     for (int i = 1; i < count; i++) {
         list[i - 1]->fNext = list[i];
         list[i]->fPrev = list[i - 1];
     }
-    
+
     *last = list[count - 1];
     return list[0];
 }
@@ -483,7 +483,7 @@
 
 #ifdef USE_NEW_BUILDER
     SkEdgeBuilder   builder;
-    
+
     int count = builder.build(path, clipRect, shiftEdgesUp);
     SkEdge**    list = builder.edgeList();
 #else
@@ -494,7 +494,7 @@
     {
         size_t  size2;
         int     maxCount2 = worst_case_edge_count(path, &size2);
-        
+
         SkASSERT(maxCount >= maxCount2 && size >= size2);
     }
 #endif
@@ -557,20 +557,25 @@
     walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc);
 }
 
-void sk_blit_above_and_below(SkBlitter* blitter, const SkIRect& ir,
-                             const SkRegion& clip) {
+void sk_blit_above(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip) {
     const SkIRect& cr = clip.getBounds();
     SkIRect tmp;
-    
+
     tmp.fLeft = cr.fLeft;
     tmp.fRight = cr.fRight;
-
     tmp.fTop = cr.fTop;
     tmp.fBottom = ir.fTop;
     if (!tmp.isEmpty()) {
         blitter->blitRectRegion(tmp, clip);
     }
+}
 
+void sk_blit_below(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip) {
+    const SkIRect& cr = clip.getBounds();
+    SkIRect tmp;
+
+    tmp.fLeft = cr.fLeft;
+    tmp.fRight = cr.fRight;
     tmp.fTop = ir.fBottom;
     tmp.fBottom = cr.fBottom;
     if (!tmp.isEmpty()) {
@@ -635,10 +640,15 @@
 
     blitter = clipper.getBlitter();
     if (blitter) {
+        // we have to keep our calls to blitter in sorted order, so we
+        // must blit the above section first, then the middle, then the bottom.
         if (path.isInverseFillType()) {
-            sk_blit_above_and_below(blitter, ir, clip);
+            sk_blit_above(blitter, ir, clip);
         }
         sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom, 0, clip);
+        if (path.isInverseFillType()) {
+            sk_blit_below(blitter, ir, clip);
+        }
     } else {
         // what does it mean to not have a blitter if path.isInverseFillType???
     }
@@ -649,7 +659,7 @@
 static int build_tri_edges(SkEdge edge[], const SkPoint pts[],
                            const SkIRect* clipRect, SkEdge* list[]) {
     SkEdge** start = list;
-    
+
     if (edge->setLine(pts[0], pts[1], clipRect, 0)) {
         *list++ = edge;
         edge = (SkEdge*)((char*)edge + sizeof(SkEdge));
@@ -668,7 +678,7 @@
 static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect,
                              SkBlitter* blitter, const SkIRect& ir) {
     SkASSERT(pts && blitter);
-    
+
     SkEdge edgeStorage[3];
     SkEdge* list[3];
 
@@ -681,18 +691,18 @@
 
     // this returns the first and last edge after they're sorted into a dlink list
     SkEdge* edge = sort_edges(list, count, &last);
-    
+
     headEdge.fPrev = NULL;
     headEdge.fNext = edge;
     headEdge.fFirstY = kEDGE_HEAD_Y;
     headEdge.fX = SK_MinS32;
     edge->fPrev = &headEdge;
-    
+
     tailEdge.fPrev = last;
     tailEdge.fNext = NULL;
     tailEdge.fFirstY = kEDGE_TAIL_Y;
     last->fNext = &tailEdge;
-    
+
     // now edge is the head of the sorted linklist
     int stop_y = ir.fBottom;
     if (clipRect && stop_y > clipRect->fBottom) {
@@ -710,7 +720,7 @@
     if (clip && clip->isEmpty()) {
         return;
     }
-    
+
     SkRect  r;
     SkIRect ir;
     r.set(pts, 3);
@@ -718,9 +728,9 @@
     if (ir.isEmpty()) {
         return;
     }
-    
+
     SkScanClipper   clipper(blitter, clip, ir);
-    
+
     blitter = clipper.getBlitter();
     if (NULL != blitter) {
         sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir);
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 7b3a024..8e469f2 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -2,19 +2,20 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
+#include "SkScalar.h"
 #include "SkShader.h"
 #include "SkPaint.h"
 #include "SkMallocPixelRef.h"
@@ -119,7 +120,7 @@
 }
 
 #define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
-#define kTempColorCount     (kTempColorQuadCount << 2)  
+#define kTempColorCount     (kTempColorQuadCount << 2)
 
 #ifdef SK_CPU_BENDIAN
     #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
@@ -196,11 +197,15 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 
-                                         TileMode*, SkScalar*) {
+SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*,
+                                         TileMode*, SkScalar*) const {
     return kNone_BitmapType;
 }
 
+SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
+    return kNone_GradientType;
+}
+
 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
                                        TileMode tmx, TileMode tmy) {
     return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0);
@@ -258,20 +263,18 @@
         return false;
     }
 
-    SkColor c;
     unsigned a;
-    
+
     if (fInheritColor) {
-        c = paint.getColor();
-        a = SkColorGetA(c);
+        fColor = paint.getColor();
+        a = SkColorGetA(fColor);
     } else {
-        c = fColor;
-        a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
+        a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha()));
     }
 
-    unsigned r = SkColorGetR(c);
-    unsigned g = SkColorGetG(c);
-    unsigned b = SkColorGetB(c);
+    unsigned r = SkColorGetR(fColor);
+    unsigned g = SkColorGetG(fColor);
+    unsigned b = SkColorGetB(fColor);
 
     // we want this before we apply any alpha
     fColor16 = SkPack888ToRGB16(r, g, b);
@@ -308,8 +311,8 @@
 
 // if we had a asAColor method, that would be more efficient...
 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
-                                              TileMode modes[], 
-                                              SkScalar* twoPointRadialParams) {
+                                              TileMode modes[],
+                                      SkScalar* twoPointRadialParams) const {
     // we cache the pixelref, since its generateID is used in the texture cache
     if (NULL == fAsABitmapPixelRef) {
         SkPMColor* storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor));
@@ -317,7 +320,7 @@
         fAsABitmapPixelRef = new SkMallocPixelRef(storage, sizeof(SkPMColor),
                                                   NULL);
     }
-        
+
     if (bitmap) {
         bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
         bitmap->setPixelRef(fAsABitmapPixelRef);
@@ -331,3 +334,13 @@
     return kDefault_BitmapType;
 }
 
+SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
+    if (info) {
+        if (info->fColors && info->fColorCount >= 1) {
+            info->fColors[0] = fColor;
+        }
+        info->fColorCount = 1;
+        info->fTileMode = SkShader::kRepeat_TileMode;
+    }
+    return kColor_GradientType;
+}
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index cdce160..b8f99c7 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -19,6 +19,28 @@
 #include "SkFixed.h"
 #include "SkUtils.h"
 #include <stdarg.h>
+#include <stdio.h>
+
+// number of bytes (on the stack) to receive the printf result
+static const size_t kBufferSize = 256;
+
+#ifdef SK_BUILD_FOR_WIN
+    #define VSNPRINTF   _vsnprintf
+    #define SNPRINTF    _snprintf
+#else
+    #define VSNPRINTF   vsnprintf
+    #define SNPRINTF    snprintf
+#endif
+
+#define ARGS_TO_BUFFER(format, buffer, size)        \
+    do {                                            \
+        va_list args;                               \
+        va_start(args, format);                     \
+        VSNPRINTF(buffer, size, format, args);      \
+        va_end(args);                               \
+    } while (0)
+
+///////////////////////////////////////////////////////////////////////////////
 
 bool SkStrStartsWith(const char string[], const char prefix[])
 {
@@ -112,12 +134,23 @@
     return string;
 }
 
-char* SkStrAppendScalar(char string[], SkScalar value)
+#ifdef SK_CAN_USE_FLOAT
+char* SkStrAppendFloat(char string[], float value)
+{
+    // since floats have at most 8 significant digits, we limit our %g to that.
+    static const char gFormat[] = "%.8g";
+    // make it 1 larger for the terminating 0
+    char buffer[SkStrAppendScalar_MaxSize + 1];
+    int len = SNPRINTF(buffer, sizeof(buffer), gFormat, value);
+    memcpy(string, buffer, len);
+    SkASSERT(len <= SkStrAppendScalar_MaxSize);
+    return string + len;
+}
+#endif
+
+char* SkStrAppendFixed(char string[], SkFixed x)
 {
     SkDEBUGCODE(char* start = string;)
-
-    SkFixed x = SkScalarToFixed(value);
-
     if (x < 0)
     {
         *string++ = '-';
@@ -151,7 +184,7 @@
             x %= powerOfTen;
         } while (x != 0);
     }
-    
+
     SkASSERT(string - start <= SkStrAppendScalar_MaxSize);
     return string;
 }
@@ -483,7 +516,7 @@
 void SkString::insertHex(size_t offset, uint32_t hex, int minDigits)
 {
     minDigits = SkPin32(minDigits, 0, 8);
-    
+
     static const char gHex[] = "0123456789ABCDEF";
 
     char    buffer[8];
@@ -508,27 +541,6 @@
     this->insert(offset, buffer, stop - buffer);
 }
 
-///////////////////////////////////////////////////////////////////////////
-
-#include <stdio.h>
-
-// number of bytes (on the stack) to receive the printf result
-static const size_t kBufferSize = 256;
-
-#ifdef SK_BUILD_FOR_WIN
-    #define VSNPRINTF   _vsnprintf
-#else
-    #define VSNPRINTF   vsnprintf
-#endif
-
-#define ARGS_TO_BUFFER(format, buffer, size)        \
-    do {                                            \
-        va_list args;                               \
-        va_start(args, format);                     \
-        VSNPRINTF(buffer, size, format, args);      \
-        va_end(args);                               \
-    } while (0)
-
 void SkString::printf(const char format[], ...) {
     char    buffer[kBufferSize];
     ARGS_TO_BUFFER(format, buffer, kBufferSize);
@@ -539,20 +551,20 @@
 void SkString::appendf(const char format[], ...) {
     char    buffer[kBufferSize];
     ARGS_TO_BUFFER(format, buffer, kBufferSize);
-    
+
     this->append(buffer, strlen(buffer));
 }
 
 void SkString::prependf(const char format[], ...) {
     char    buffer[kBufferSize];
     ARGS_TO_BUFFER(format, buffer, kBufferSize);
-    
+
     this->prepend(buffer, strlen(buffer));
 }
 
 #undef VSNPRINTF
 
-///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 
 void SkString::remove(size_t offset, size_t length)
 {
diff --git a/src/core/core_files.mk b/src/core/core_files.mk
new file mode 100644
index 0000000..252644e
--- /dev/null
+++ b/src/core/core_files.mk
@@ -0,0 +1,99 @@
+SOURCE := \
+    Sk64.cpp \
+    SkAdvancedTypefaceMetrics.cpp \
+    SkAlphaRuns.cpp \
+    SkBitmap.cpp \
+    SkBitmapProcShader.cpp \
+    SkBitmapProcState.cpp \
+    SkBitmapProcState_matrixProcs.cpp \
+    SkBitmapSampler.cpp \
+    SkBitmap_scroll.cpp \
+    SkBlitRow_D16.cpp \
+    SkBlitRow_D32.cpp \
+    SkBlitRow_D4444.cpp \
+    SkBlitter.cpp \
+    SkBlitter_4444.cpp \
+    SkBlitter_A1.cpp \
+    SkBlitter_A8.cpp \
+    SkBlitter_ARGB32.cpp \
+    SkBlitter_ARGB32_Subpixel.cpp \
+    SkBlitter_RGB16.cpp \
+    SkBlitter_Sprite.cpp \
+    SkBuffer.cpp \
+    SkCanvas.cpp \
+    SkChunkAlloc.cpp \
+    SkClipStack.cpp \
+    SkColor.cpp \
+    SkColorFilter.cpp \
+    SkColorTable.cpp \
+    SkConcaveToTriangles.cpp \
+    SkComposeShader.cpp \
+    SkCordic.cpp \
+    SkCubicClipper.cpp \
+    SkDebug.cpp \
+    SkDeque.cpp \
+    SkDevice.cpp \
+    SkDither.cpp \
+    SkDraw.cpp \
+    SkEdge.cpp \
+    SkEdgeBuilder.cpp \
+    SkEdgeClipper.cpp \
+    SkFilterProc.cpp \
+    SkFlate.cpp \
+    SkFlattenable.cpp \
+    SkFloat.cpp \
+    SkFloatBits.cpp \
+    SkFontHost.cpp \
+    SkGeometry.cpp \
+    SkGlobals.cpp \
+    SkGlyphCache.cpp \
+    SkGraphics.cpp \
+    SkLineClipper.cpp \
+    SkMMapStream.cpp \
+    SkMallocPixelRef.cpp \
+    SkMask.cpp \
+    SkMaskFilter.cpp \
+    SkMath.cpp \
+    SkMatrix.cpp \
+    SkMemory_stdlib.cpp \
+    SkPackBits.cpp \
+    SkPaint.cpp \
+    SkPath.cpp \
+    SkPathEffect.cpp \
+    SkPathHeap.cpp \
+    SkPathMeasure.cpp \
+    SkPicture.cpp \
+    SkPictureFlat.cpp \
+    SkPicturePlayback.cpp \
+    SkPictureRecord.cpp \
+    SkPixelRef.cpp \
+    SkPoint.cpp \
+    SkPtrRecorder.cpp \
+    SkQuadClipper.cpp \
+    SkRasterizer.cpp \
+    SkRect.cpp \
+    SkRefDict.cpp \
+    SkRegion.cpp \
+    SkRegion_rects.cpp \
+    SkRegion_path.cpp \
+    SkScalar.cpp \
+    SkScalerContext.cpp \
+    SkScan.cpp \
+    SkScan_AntiPath.cpp \
+    SkScan_Antihair.cpp \
+    SkScan_Hairline.cpp \
+    SkScan_Path.cpp \
+    SkShader.cpp \
+    SkShape.cpp \
+    SkSpriteBlitter_ARGB32.cpp \
+    SkSpriteBlitter_RGB16.cpp \
+    SkStream.cpp \
+    SkString.cpp \
+    SkStroke.cpp \
+    SkStrokerPriv.cpp \
+    SkTSearch.cpp \
+    SkTypeface.cpp \
+    SkUnPreMultiply.cpp \
+    SkUtils.cpp \
+    SkWriter32.cpp \
+    SkXfermode.cpp
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index 901a4d3..9585112 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -31,8 +31,11 @@
 
     if (flags & kOverrideColor_BlurFlag)
     {
+        // Set alpha to 1 for the override since transparency will already
+        // be baked into the blurred mask.
+        SkColor opaqueColor = SkColorSetA(color, 255);
         //The SrcIn xfer mode will multiply 'color' by the incoming alpha
-        fColorFilter = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode);
+        fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, SkXfermode::kSrcIn_Mode);
     }
     else
     {
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 64a78c7..3452212 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -123,12 +123,11 @@
         kCache32Count   = 1 << kCache32Bits
     };
     virtual void flatten(SkFlattenableWriteBuffer& );
-    const uint16_t*     getCache16();
-    const SkPMColor*    getCache32();
+    const uint16_t*     getCache16() const;
+    const SkPMColor*    getCache32() const;
 
-    SkMallocPixelRef* fCache32PixelRef;
-
-    void commonAsABitmap(SkBitmap*);
+    void commonAsABitmap(SkBitmap*) const;
+    void commonAsAGradient(GradientInfo*) const;
 
 private:
     enum {
@@ -139,10 +138,11 @@
     SkColor     fStorage[(kStorageSize + 3) >> 2];
     SkColor*    fOrigColors;
 
-    uint16_t*   fCache16;   // working ptr. If this is NULL, we need to recompute the cache values
-    SkPMColor*  fCache32;   // working ptr. If this is NULL, we need to recompute the cache values
+    mutable uint16_t*   fCache16;   // working ptr. If this is NULL, we need to recompute the cache values
+    mutable SkPMColor*  fCache32;   // working ptr. If this is NULL, we need to recompute the cache values
 
-    uint16_t*   fCache16Storage;    // storage for fCache16, allocated on demand
+    mutable uint16_t*   fCache16Storage;    // storage for fCache16, allocated on demand
+    mutable SkMallocPixelRef* fCache32PixelRef;
     unsigned    fCacheAlpha;        // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value
 
     static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
@@ -535,7 +535,7 @@
     return 0;
 }
 
-const uint16_t* Gradient_Shader::getCache16() {
+const uint16_t* Gradient_Shader::getCache16() const {
     if (fCache16 == NULL) {
         // double the count for dither entries
         const int entryCount = kCache16Count * 2;
@@ -578,7 +578,7 @@
     return fCache16;
 }
 
-const SkPMColor* Gradient_Shader::getCache32() {
+const SkPMColor* Gradient_Shader::getCache32() const {
     if (fCache32 == NULL) {
         // double the count for dither entries
         const int entryCount = kCache32Count * 2;
@@ -635,7 +635,7 @@
  *  colors and positions. Note: we don't try to flatten the fMapper, so if one
  *  is present, we skip the cache for now.
  */
-void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) {
+void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) const {
     // don't have a way to put the mapper into our cache-key yet
     if (fMapper) {
         // force our cahce32pixelref to be built
@@ -687,6 +687,28 @@
     }
 }
 
+void Gradient_Shader::commonAsAGradient(GradientInfo* info) const {
+    if (info) {
+        if (info->fColorCount >= fColorCount) {
+            if (info->fColors) {
+                memcpy(info->fColors, fOrigColors,
+                       fColorCount * sizeof(SkColor));
+            }
+            if (info->fColorOffsets) {
+                if (fColorCount == 2) {
+                    info->fColorOffsets[0] = 0;
+                    info->fColorOffsets[1] = SK_Scalar1;
+                } else if (fColorCount > 2) {
+                    for (int i = 0; i < fColorCount; i++)
+                        info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos);
+                }
+            }
+        }
+        info->fColorCount = fColorCount;
+        info->fTileMode = fTileMode;
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 
 static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) {
@@ -707,7 +729,9 @@
     Linear_Gradient(const SkPoint pts[2],
                     const SkColor colors[], const SkScalar pos[], int colorCount,
                     SkShader::TileMode mode, SkUnitMapper* mapper)
-        : Gradient_Shader(colors, pos, colorCount, mode, mapper)
+        : Gradient_Shader(colors, pos, colorCount, mode, mapper),
+          fStart(pts[0]),
+          fEnd(pts[1])
     {
         pts_to_unit_matrix(pts, &fPtsToUnit);
     }
@@ -716,18 +740,33 @@
     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*,
-                                 TileMode*, SkScalar* twoPointRadialParams);
+                             TileMode*, SkScalar* twoPointRadialParams) const;
+    virtual GradientType asAGradient(GradientInfo* info) const;
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(Linear_Gradient, (buffer));
     }
 
+    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
+        this->INHERITED::flatten(buffer);
+        buffer.writeScalar(fStart.fX);
+        buffer.writeScalar(fStart.fY);
+        buffer.writeScalar(fEnd.fX);
+        buffer.writeScalar(fEnd.fY);
+    }
+
 protected:
-    Linear_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {}
+    Linear_Gradient(SkFlattenableReadBuffer& buffer)
+        : Gradient_Shader(buffer),
+          fStart(SkPoint::Make(buffer.readScalar(), buffer.readScalar())),
+          fEnd(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) {
+    }
     virtual Factory getFactory() { return CreateProc; }
 
 private:
     typedef Gradient_Shader INHERITED;
+    const SkPoint fStart;
+    const SkPoint fEnd;
 };
 
 bool Linear_Gradient::setContext(const SkBitmap& device, const SkPaint& paint,
@@ -835,7 +874,7 @@
 SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap,
                                                 SkMatrix* matrix,
                                                 TileMode xy[],
-                                                SkScalar* twoPointRadialParams) {
+                                        SkScalar* twoPointRadialParams) const {
     if (bitmap) {
         this->commonAsABitmap(bitmap);
     }
@@ -850,6 +889,15 @@
     return kDefault_BitmapType;
 }
 
+SkShader::GradientType Linear_Gradient::asAGradient(GradientInfo* info) const {
+    if (info) {
+        commonAsAGradient(info);
+        info->fPoint[0] = fStart;
+        info->fPoint[1] = fEnd;
+    }
+    return kLinear_GradientType;
+}
+
 static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
                             int count) {
     if (reinterpret_cast<uintptr_t>(dst) & 2) {
@@ -989,7 +1037,9 @@
     Radial_Gradient(const SkPoint& center, SkScalar radius,
                     const SkColor colors[], const SkScalar pos[], int colorCount,
                     SkShader::TileMode mode, SkUnitMapper* mapper)
-        : Gradient_Shader(colors, pos, colorCount, mode, mapper)
+        : Gradient_Shader(colors, pos, colorCount, mode, mapper),
+          fCenter(center),
+          fRadius(radius)
     {
         // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
         SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
@@ -1185,7 +1235,7 @@
     virtual BitmapType asABitmap(SkBitmap* bitmap,
                                  SkMatrix* matrix,
                                  TileMode* xy,
-                                 SkScalar* twoPointRadialParams) {
+                                 SkScalar* twoPointRadialParams) const {
         if (bitmap) {
             this->commonAsABitmap(bitmap);
         }
@@ -1199,17 +1249,38 @@
         }
         return kRadial_BitmapType;
     }
+    virtual GradientType asAGradient(GradientInfo* info) const {
+        if (info) {
+            commonAsAGradient(info);
+            info->fPoint[0] = fCenter;
+            info->fRadius[0] = fRadius;
+        }
+        return kRadial_GradientType;
+    }
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(Radial_Gradient, (buffer));
     }
 
+    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
+        this->INHERITED::flatten(buffer);
+        buffer.writeScalar(fCenter.fX);
+        buffer.writeScalar(fCenter.fY);
+        buffer.writeScalar(fRadius);
+    }
+
 protected:
-    Radial_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {};
+    Radial_Gradient(SkFlattenableReadBuffer& buffer)
+        : Gradient_Shader(buffer),
+          fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())),
+          fRadius(buffer.readScalar()) {
+    }
     virtual Factory getFactory() { return CreateProc; }
 
 private:
     typedef Gradient_Shader INHERITED;
+    const SkPoint fCenter;
+    const SkScalar fRadius;
 };
 
 /* Two-point radial gradients are specified by two circles, each with a center
@@ -1305,26 +1376,18 @@
                               const SkColor colors[], const SkScalar pos[],
                               int colorCount, SkShader::TileMode mode,
                               SkUnitMapper* mapper)
-        : Gradient_Shader(colors, pos, colorCount, mode, mapper)
-    {
-        fDiff = start - end;
-        fDiffRadius = endRadius - startRadius;
-        SkScalar inv = SkScalarInvert(fDiffRadius);
-        fDiff.fX = SkScalarMul(fDiff.fX, inv);
-        fDiff.fY = SkScalarMul(fDiff.fY, inv);
-        fStartRadius = SkScalarMul(startRadius, inv);
-        fSr2D2 = SkScalarSquare(fStartRadius);
-        fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
-        fOneOverTwoA = SkScalarInvert(fA * 2);
-
-        fPtsToUnit.setTranslate(-start.fX, -start.fY);
-        fPtsToUnit.postScale(inv, inv);
+            : Gradient_Shader(colors, pos, colorCount, mode, mapper),
+              fCenter1(start),
+              fCenter2(end),
+              fRadius1(startRadius),
+              fRadius2(endRadius) {
+        init();
     }
 
     virtual BitmapType asABitmap(SkBitmap* bitmap,
                                  SkMatrix* matrix,
                                  TileMode* xy,
-                                 SkScalar* twoPointRadialParams) {
+                                 SkScalar* twoPointRadialParams) const {
         if (bitmap) {
             this->commonAsABitmap(bitmap);
         }
@@ -1351,6 +1414,17 @@
         return kTwoPointRadial_BitmapType;
     }
 
+    virtual GradientType asAGradient(GradientInfo* info) const {
+        if (info) {
+            commonAsAGradient(info);
+            info->fPoint[0] = fCenter1;
+            info->fPoint[1] = fCenter2;
+            info->fRadius[0] = fRadius1;
+            info->fRadius[1] = fRadius2;
+        }
+        return kRadial2_GradientType;
+    }
+
     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
     {
         SkASSERT(count > 0);
@@ -1468,32 +1542,48 @@
 
     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
         this->INHERITED::flatten(buffer);
-        buffer.writeScalar(fDiff.fX);
-        buffer.writeScalar(fDiff.fY);
-        buffer.writeScalar(fStartRadius);
-        buffer.writeScalar(fDiffRadius);
-        buffer.writeScalar(fSr2D2);
-        buffer.writeScalar(fA);
-        buffer.writeScalar(fOneOverTwoA);
+        buffer.writeScalar(fCenter1.fX);
+        buffer.writeScalar(fCenter1.fY);
+        buffer.writeScalar(fCenter2.fX);
+        buffer.writeScalar(fCenter2.fY);
+        buffer.writeScalar(fRadius1);
+        buffer.writeScalar(fRadius2);
     }
 
 protected:
     Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
-            : Gradient_Shader(buffer) {
-        fDiff.fX = buffer.readScalar();
-        fDiff.fY = buffer.readScalar();
-        fStartRadius = buffer.readScalar();
-        fDiffRadius = buffer.readScalar();
-        fSr2D2 = buffer.readScalar();
-        fA = buffer.readScalar();
-        fOneOverTwoA = buffer.readScalar();
+            : Gradient_Shader(buffer),
+              fCenter1(SkPoint::Make(buffer.readScalar(), buffer.readScalar())),
+              fCenter2(SkPoint::Make(buffer.readScalar(), buffer.readScalar())),
+              fRadius1(buffer.readScalar()),
+              fRadius2(buffer.readScalar()) {
+        init();
     };
     virtual Factory getFactory() { return CreateProc; }
 
 private:
     typedef Gradient_Shader INHERITED;
+    const SkPoint fCenter1;
+    const SkPoint fCenter2;
+    const SkScalar fRadius1;
+    const SkScalar fRadius2;
     SkPoint fDiff;
     SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
+
+    void init() {
+        fDiff = fCenter1 - fCenter2;
+        fDiffRadius = fRadius2 - fRadius1;
+        SkScalar inv = SkScalarInvert(fDiffRadius);
+        fDiff.fX = SkScalarMul(fDiff.fX, inv);
+        fDiff.fY = SkScalarMul(fDiff.fY, inv);
+        fStartRadius = SkScalarMul(fRadius1, inv);
+        fSr2D2 = SkScalarSquare(fStartRadius);
+        fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
+        fOneOverTwoA = SkScalarInvert(fA * 2);
+
+        fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
+        fPtsToUnit.postScale(inv, inv);
+    }
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1502,7 +1592,8 @@
 public:
     Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[],
                    const SkScalar pos[], int count, SkUnitMapper* mapper)
-    : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper)
+    : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper),
+      fCenter(SkPoint::Make(cx, cy))
     {
         fPtsToUnit.setTranslate(-cx, -cy);
     }
@@ -1512,7 +1603,7 @@
     virtual BitmapType asABitmap(SkBitmap* bitmap,
                                  SkMatrix* matrix,
                                  TileMode* xy,
-                                 SkScalar* twoPointRadialParams) {
+                                 SkScalar* twoPointRadialParams) const {
         if (bitmap) {
             this->commonAsABitmap(bitmap);
         }
@@ -1526,16 +1617,35 @@
         return kSweep_BitmapType;
     }
 
+    virtual GradientType asAGradient(GradientInfo* info) const {
+        if (info) {
+            commonAsAGradient(info);
+            info->fPoint[0] = fCenter;
+        }
+        return kSweep_GradientType;
+    }
+
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
         return SkNEW_ARGS(Sweep_Gradient, (buffer));
     }
 
+    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
+        this->INHERITED::flatten(buffer);
+        buffer.writeScalar(fCenter.fX);
+        buffer.writeScalar(fCenter.fY);
+    }
+
 protected:
-    Sweep_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {}
+    Sweep_Gradient(SkFlattenableReadBuffer& buffer)
+        : Gradient_Shader(buffer),
+          fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) {
+    }
+
     virtual Factory getFactory() { return CreateProc; }
 
 private:
     typedef Gradient_Shader INHERITED;
+    const SkPoint fCenter;
 };
 
 #ifdef COMPUTE_SWEEP_TABLE
diff --git a/src/effects/SkPorterDuff.cpp b/src/effects/SkPorterDuff.cpp
index d0264ba..980ce29 100644
--- a/src/effects/SkPorterDuff.cpp
+++ b/src/effects/SkPorterDuff.cpp
@@ -30,7 +30,9 @@
     MAKE_PAIR(Multiply),
     MAKE_PAIR(Screen),
     { SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode },
+#ifdef ANDROID
     MAKE_PAIR(Overlay),
+#endif
 };
 
 static bool find_pdmode(SkXfermode::Mode src, SkPorterDuff::Mode* dst) {
diff --git a/src/effects/effects_files.mk b/src/effects/effects_files.mk
new file mode 100644
index 0000000..00d9e7d
--- /dev/null
+++ b/src/effects/effects_files.mk
@@ -0,0 +1,25 @@
+SOURCE := \
+	Sk1DPathEffect.cpp \
+	Sk2DPathEffect.cpp \
+    SkBitmapCache.cpp \
+	SkTransparentShader.cpp \
+	SkAvoidXfermode.cpp \
+	SkBlurDrawLooper.cpp \
+	SkBlurMask.cpp \
+	SkBlurMaskFilter.cpp \
+	SkColorFilters.cpp \
+	SkColorMatrixFilter.cpp \
+	SkCornerPathEffect.cpp \
+	SkDashPathEffect.cpp \
+	SkDiscretePathEffect.cpp \
+	SkEmbossMask.cpp \
+	SkEmbossMaskFilter.cpp \
+	SkGradientShader.cpp \
+    SkGroupShape.cpp \
+	SkKernel33MaskFilter.cpp \
+	SkLayerDrawLooper.cpp \
+	SkLayerRasterizer.cpp \
+	SkPaintFlagsDrawFilter.cpp \
+	SkPixelXorXfermode.cpp \
+	SkPorterDuff.cpp \
+    SkRectShape.cpp
diff --git a/src/gpu/GrPrintf_skia.cpp b/src/gpu/GrPrintf_skia.cpp
new file mode 100644
index 0000000..fa8b6a7
--- /dev/null
+++ b/src/gpu/GrPrintf_skia.cpp
@@ -0,0 +1,39 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "SkTypes.h"
+
+void GrPrintf(const char format[], ...) {
+    const size_t MAX_BUFFER_SIZE = 512;
+
+    char buffer[MAX_BUFFER_SIZE + 1];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buffer, MAX_BUFFER_SIZE, format, args);
+    va_end(args);
+
+    // skia has already mapped this to do the "right thing"
+    SkDebugf("%s", buffer);
+}
+
+
diff --git a/src/gpu/SkGpuCanvas.cpp b/src/gpu/SkGpuCanvas.cpp
new file mode 100644
index 0000000..9513bbd
--- /dev/null
+++ b/src/gpu/SkGpuCanvas.cpp
@@ -0,0 +1,59 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrContext.h"
+
+#include "SkGpuCanvas.h"
+#include "SkGpuDevice.h"
+#include "SkGpuDeviceFactory.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkDeviceFactory* make_df(GrContext* context, 
+                                GrRenderTarget* renderTarget) {
+    return SkNEW_ARGS(SkGpuDeviceFactory, (context, renderTarget));
+}
+
+SkGpuCanvas::SkGpuCanvas(GrContext* context,
+                         GrRenderTarget* renderTarget) 
+      : SkCanvas(make_df(context, renderTarget)) {
+    SkASSERT(context);
+    fContext = context;
+    fContext->ref();
+}
+
+SkGpuCanvas::~SkGpuCanvas() {
+    // call this now, while our override of restore() is in effect
+    this->restoreToCount(1);
+    fContext->flush(false);
+    fContext->unref();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkGpuCanvas::getViewport(SkIPoint* size) const {
+    if (size) {
+        SkDevice* device = this->getDevice();
+        if (device) {
+            size->set(device->width(), device->height());
+        } else {
+            size->set(0, 0);
+        }
+    }
+    return true;
+}
+
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
new file mode 100644
index 0000000..3707b67
--- /dev/null
+++ b/src/gpu/SkGpuDevice.cpp
@@ -0,0 +1,1300 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrContext.h"
+#include "GrTextContext.h"
+
+#include "SkGpuDevice.h"
+#include "SkGpuDeviceFactory.h"
+#include "SkGrTexturePixelRef.h"
+
+#include "SkDrawProcs.h"
+#include "SkGlyphCache.h"
+
+#define CACHE_LAYER_TEXTURES 1
+
+#if 0
+    extern bool (*gShouldDrawProc)();
+    #define CHECK_SHOULD_DRAW(draw)                             \
+        do {                                                    \
+            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
+            this->prepareRenderTarget(draw);                    \
+        } while (0)
+#else
+    #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw)
+#endif
+
+class SkAutoExtMatrix {
+public:
+    SkAutoExtMatrix(const SkMatrix* extMatrix) {
+        if (extMatrix) {
+            SkGr::SkMatrix2GrMatrix(*extMatrix, &fMatrix);
+            fExtMatrix = &fMatrix;
+        } else {
+            fExtMatrix = NULL;
+        }
+    }
+    const GrMatrix* extMatrix() const { return fExtMatrix; }
+
+private:
+    GrMatrix    fMatrix;
+    GrMatrix*   fExtMatrix; // NULL or &fMatrix
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDevice::SkAutoCachedTexture::
+             SkAutoCachedTexture(SkGpuDevice* device,
+                                 const SkBitmap& bitmap,
+                                 const GrSamplerState& sampler,
+                                 GrTexture** texture) {
+    GrAssert(texture);
+    fTex = NULL;
+    *texture = this->set(device, bitmap, sampler);
+}
+
+SkGpuDevice::SkAutoCachedTexture::SkAutoCachedTexture() {
+    fTex = NULL;
+}
+
+GrTexture* SkGpuDevice::SkAutoCachedTexture::set(SkGpuDevice* device,
+                                                 const SkBitmap& bitmap,
+                                                 const GrSamplerState& sampler) {
+    if (fTex) {
+        fDevice->unlockCachedTexture(fTex);
+    }
+    fDevice = device;
+    GrTexture* texture = (GrTexture*)bitmap.getTexture();
+    if (texture) {
+        // return the native texture
+        fTex = NULL;
+    } else {
+        // look it up in our cache
+        fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
+    }
+    return texture;
+}
+
+SkGpuDevice::SkAutoCachedTexture::~SkAutoCachedTexture() {
+    if (fTex) {
+        fDevice->unlockCachedTexture(fTex);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool gDoTraceDraw;
+
+struct GrSkDrawProcs : public SkDrawProcs {
+public:
+    GrContext* fContext;
+    GrTextContext* fTextContext;
+    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRenderTarget* SkGpuDevice::Current3DApiRenderTarget() {
+    return (GrRenderTarget*) -1;
+}
+
+SkGpuDevice::SkGpuDevice(GrContext* context,
+                         const SkBitmap& bitmap,
+                         GrRenderTarget* renderTargetOrNull)
+        : SkDevice(NULL, bitmap, (NULL == renderTargetOrNull)) {
+
+    fNeedPrepareRenderTarget = false;
+    fDrawProcs = NULL;
+
+    fContext = context;
+    fContext->ref();
+
+    fCache = NULL;
+    fTexture = NULL;
+    fRenderTarget = NULL;
+    fNeedClear = false;
+
+    if (NULL == renderTargetOrNull) {
+        SkBitmap::Config c = bitmap.config();
+        if (c != SkBitmap::kRGB_565_Config) {
+            c = SkBitmap::kARGB_8888_Config;
+        }
+        SkBitmap bm;
+        bm.setConfig(c, this->width(), this->height());
+
+#if CACHE_LAYER_TEXTURES
+
+        fCache = this->lockCachedTexture(bm, GrSamplerState::ClampNoFilter(),
+                       &fTexture, true);
+        if (fCache) {
+            SkASSERT(NULL != fTexture);
+            SkASSERT(NULL != fTexture->asRenderTarget());
+        }
+#else
+        const GrGpu::TextureDesc desc = {
+            GrGpu::kRenderTarget_TextureFlag,
+            GrGpu::kNone_AALevel,
+            this->width(),
+            this->height(),
+            SkGr::Bitmap2PixelConfig(bm)
+        };
+
+        fTexture = fContext->createUncachedTexture(desc, NULL, 0);
+#endif
+        if (NULL != fTexture) {
+            fRenderTarget = fTexture->asRenderTarget();
+
+            GrAssert(NULL != fRenderTarget);
+
+            // we defer the actual clear until our gainFocus()
+            fNeedClear = true;
+
+            // wrap the bitmap with a pixelref to expose our texture
+            SkGrTexturePixelRef* pr = new SkGrTexturePixelRef(fTexture);
+            this->setPixelRef(pr, 0)->unref();
+        } else {
+            GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
+                     this->width(), this->height());
+            GrAssert(false);
+        }
+    } else if (Current3DApiRenderTarget() == renderTargetOrNull) {
+        fRenderTarget = fContext->createRenderTargetFrom3DApiState();
+    } else {
+        fRenderTarget = renderTargetOrNull;
+        fRenderTarget->ref();
+    }
+}
+
+SkGpuDevice::~SkGpuDevice() {
+    if (fDrawProcs) {
+        delete fDrawProcs;
+    }
+
+    if (fCache) {
+        GrAssert(NULL != fTexture);
+        GrAssert(fRenderTarget == fTexture->asRenderTarget());
+        // IMPORTANT: reattach the rendertarget/tex back to the cache.
+        fContext->reattachAndUnlockCachedTexture((GrTextureEntry*)fCache);
+    } else if (NULL != fTexture) {
+        GrAssert(!CACHE_LAYER_TEXTURES);
+        GrAssert(fRenderTarget == fTexture->asRenderTarget());
+        fTexture->unref();
+    } else if (NULL != fRenderTarget) {
+        fRenderTarget->unref();
+    }
+    fContext->unref();
+}
+
+intptr_t SkGpuDevice::getLayerTextureHandle() const {
+    if (fTexture) {
+        return fTexture->getTextureHandle();
+    } else {
+        return 0;
+    }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGpuDevice::makeRenderTargetCurrent() {
+    fContext->setRenderTarget(fRenderTarget);
+    fContext->flush(true);
+    fNeedPrepareRenderTarget = true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkGpuDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
+    SkIRect bounds;
+    bounds.set(0, 0, this->width(), this->height());
+    if (!bounds.intersect(srcRect)) {
+        return false;
+    }
+
+    const int w = bounds.width();
+    const int h = bounds.height();
+    SkBitmap tmp;
+    // note we explicitly specify our rowBytes to be snug (no gap between rows)
+    tmp.setConfig(SkBitmap::kARGB_8888_Config, w, h, w * 4);
+    if (!tmp.allocPixels()) {
+        return false;
+    }
+
+    SkAutoLockPixels alp(tmp);
+    fContext->setRenderTarget(fRenderTarget);
+    // we aren't setting the clip or matrix, so mark as dirty
+    // we don't need to set them for this call and don't have them anyway
+    fNeedPrepareRenderTarget = true;
+
+    if (!fContext->readPixels(bounds.fLeft, bounds.fTop,
+                              bounds.width(), bounds.height(),
+                              GrTexture::kRGBA_8888_PixelConfig,
+                              tmp.getPixels())) {
+        return false;
+    }
+
+    tmp.swap(*bitmap);
+    return true;
+}
+
+void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.readyToDraw()) {
+        return;
+    }
+    GrTexture::PixelConfig config = SkGr::BitmapConfig2PixelConfig(bitmap.config(),
+                                                                   bitmap.isOpaque());
+    fContext->setRenderTarget(fRenderTarget);
+    // we aren't setting the clip or matrix, so mark as dirty
+    // we don't need to set them for this call and don't have them anyway
+    fNeedPrepareRenderTarget = true;
+
+    fContext->writePixels(x, y, bitmap.width(), bitmap.height(),
+                          config, bitmap.getPixels(), bitmap.rowBytes());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
+                               const SkClipStack& clipStack,
+                               const SkRegion& clipRegion,
+                               const SkIPoint& origin) {
+    GrMatrix grmat;
+    SkGr::SkMatrix2GrMatrix(matrix, &grmat);
+    context->setMatrix(grmat);
+
+    SkGrClipIterator iter;
+    iter.reset(clipStack);
+    const SkIRect& skBounds = clipRegion.getBounds();
+    GrRect bounds;
+    bounds.setLTRB(GrIntToScalar(skBounds.fLeft),
+                   GrIntToScalar(skBounds.fTop),
+                   GrIntToScalar(skBounds.fRight),
+                   GrIntToScalar(skBounds.fBottom));
+    GrClip grc(&iter, GrIntToScalar(-origin.x()), GrIntToScalar(-origin.y()),
+               &bounds);
+    context->setClip(grc);
+}
+
+// call this ever each draw call, to ensure that the context reflects our state,
+// and not the state from some other canvas/device
+void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
+    if (fNeedPrepareRenderTarget ||
+        fContext->getRenderTarget() != fRenderTarget) {
+
+        fContext->setRenderTarget(fRenderTarget);
+        SkASSERT(draw.fClipStack);
+        convert_matrixclip(fContext, *draw.fMatrix,
+                           *draw.fClipStack, *draw.fClip, this->getOrigin());
+        fNeedPrepareRenderTarget = false;
+    }
+}
+
+void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
+                                const SkClipStack& clipStack) {
+    this->INHERITED::setMatrixClip(matrix, clip, clipStack);
+
+    convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
+}
+
+void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
+                            const SkRegion& clip, const SkClipStack& clipStack) {
+
+    fContext->setRenderTarget(fRenderTarget);
+
+    this->INHERITED::gainFocus(canvas, matrix, clip, clipStack);
+
+    convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
+
+    if (fNeedClear) {
+        fContext->eraseColor(0x0);
+        fNeedClear = false;
+    }
+}
+
+bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) {
+    if (NULL != fTexture) {
+        paint->setTexture(fTexture);
+        return true;
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
+SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
+SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
+SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
+SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
+                  shader_type_mismatch);
+SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 4, shader_type_mismatch);
+
+static const GrSamplerState::SampleMode sk_bmp_type_to_sample_mode[] = {
+    (GrSamplerState::SampleMode) -1,                    // kNone_BitmapType
+    GrSamplerState::kNormal_SampleMode,                 // kDefault_BitmapType
+    GrSamplerState::kRadial_SampleMode,                 // kRadial_BitmapType
+    GrSamplerState::kSweep_SampleMode,                  // kSweep_BitmapType
+    GrSamplerState::kRadial2_SampleMode,                // kTwoPointRadial_BitmapType
+};
+
+bool SkGpuDevice::skPaint2GrPaintNoShader(const SkPaint& skPaint,
+                                          bool justAlpha,
+                                          GrPaint* grPaint) {
+
+    grPaint->fDither    = skPaint.isDither();
+    grPaint->fAntiAlias = skPaint.isAntiAlias();
+
+    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
+    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
+
+    SkXfermode* mode = skPaint.getXfermode();
+    if (mode) {
+        if (!mode->asCoeff(&sm, &dm)) {
+            SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");)
+#if 0
+            return false;
+#endif
+        }
+    }
+    grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
+    grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
+
+    if (justAlpha) {
+        uint8_t alpha = skPaint.getAlpha();
+        grPaint->fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
+    } else {
+        grPaint->fColor = SkGr::SkColor2GrColor(skPaint.getColor());
+        grPaint->setTexture(NULL);
+    }
+    return true;
+}
+
+bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
+                                        SkAutoCachedTexture* act,
+                                        const SkMatrix& ctm,
+                                        GrPaint* grPaint) {
+
+    SkASSERT(NULL != act);
+
+    SkShader* shader = skPaint.getShader();
+    if (NULL == shader) {
+        return this->skPaint2GrPaintNoShader(skPaint, false, grPaint);
+        grPaint->setTexture(NULL);
+        return true;
+    } else if (!this->skPaint2GrPaintNoShader(skPaint, true, grPaint)) {
+        return false;
+    }
+
+    SkPaint noAlphaPaint(skPaint);
+    noAlphaPaint.setAlpha(255);
+    shader->setContext(this->accessBitmap(false), noAlphaPaint, ctm);
+
+    SkBitmap bitmap;
+    SkMatrix matrix;
+    SkShader::TileMode tileModes[2];
+    SkScalar twoPointParams[3];
+    SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, &matrix,
+                                                     tileModes, twoPointParams);
+
+    GrSamplerState::SampleMode sampleMode = sk_bmp_type_to_sample_mode[bmptype];
+    if (-1 == sampleMode) {
+        SkDebugf("shader->asABitmap() == kNone_BitmapType\n");
+        return false;
+    }
+    grPaint->fSampler.setSampleMode(sampleMode);
+    grPaint->fSampler.setFilter(skPaint.isFilterBitmap());
+    grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
+    grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
+    if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
+        grPaint->fSampler.setRadial2Params(twoPointParams[0],
+                                           twoPointParams[1],
+                                           twoPointParams[2] < 0);
+    }
+
+    GrTexture* texture = act->set(this, bitmap, grPaint->fSampler);
+    if (NULL == texture) {
+        SkDebugf("Couldn't convert bitmap to texture.\n");
+        return false;
+    }
+    grPaint->setTexture(texture);
+
+    // since our texture coords will be in local space, we wack the texture
+    // matrix to map them back into 0...1 before we load it
+    SkMatrix localM;
+    if (shader->getLocalMatrix(&localM)) {
+        SkMatrix inverse;
+        if (localM.invert(&inverse)) {
+            matrix.preConcat(inverse);
+        }
+    }
+    if (SkShader::kDefault_BitmapType == bmptype) {
+        GrScalar sx = GrFixedToScalar(GR_Fixed1 / bitmap.width());
+        GrScalar sy = GrFixedToScalar(GR_Fixed1 / bitmap.height());
+        matrix.postScale(sx, sy);
+    } else if (SkShader::kRadial_BitmapType == bmptype) {
+        GrScalar s = GrFixedToScalar(GR_Fixed1 / bitmap.width());
+        matrix.postScale(s, s);
+    }
+    GrMatrix grMat;
+    SkGr::SkMatrix2GrMatrix(matrix, &grMat);
+    grPaint->fSampler.setMatrix(grMat);
+
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkPositionSource {
+public:
+    SkPositionSource(const SkPoint* points, int count)
+        : fPoints(points), fCount(count) {}
+
+    int count() const { return fCount; }
+
+    void writeValue(int i, GrPoint* dstPosition) const {
+        SkASSERT(i < fCount);
+        dstPosition->fX = SkScalarToGrScalar(fPoints[i].fX);
+        dstPosition->fY = SkScalarToGrScalar(fPoints[i].fY);
+    }
+private:
+    const SkPoint*  fPoints;
+    int             fCount;
+};
+
+class SkTexCoordSource {
+public:
+    SkTexCoordSource(const SkPoint* coords)
+        : fCoords(coords) {}
+
+    void writeValue(int i, GrPoint* dstCoord) const {
+        dstCoord->fX = SkScalarToGrScalar(fCoords[i].fX);
+        dstCoord->fY = SkScalarToGrScalar(fCoords[i].fY);
+    }
+private:
+    const SkPoint*  fCoords;
+};
+
+class SkColorSource {
+public:
+    SkColorSource(const SkColor* colors) : fColors(colors) {}
+
+    void writeValue(int i, GrColor* dstColor) const {
+        *dstColor = SkGr::SkColor2GrColor(fColors[i]);
+    }
+private:
+    const SkColor* fColors;
+};
+
+class SkIndexSource {
+public:
+    SkIndexSource(const uint16_t* indices, int count)
+        : fIndices(indices), fCount(count) {
+    }
+
+    int count() const { return fCount; }
+
+    void writeValue(int i, uint16_t* dstIndex) const {
+        *dstIndex = fIndices[i];
+    }
+
+private:
+    const uint16_t* fIndices;
+    int             fCount;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if 0 // not currently being used so don't compile,
+
+// can be used for positions or texture coordinates
+
+class SkRectFanSource {
+public:
+    SkRectFanSource(const SkRect& rect) : fRect(rect) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+        dstPoint->fX = SkScalarToGrScalar((i % 3) ? fRect.fRight :
+                                                    fRect.fLeft);
+        dstPoint->fY = SkScalarToGrScalar((i < 2) ? fRect.fTop  :
+                                                    fRect.fBottom);
+    }
+private:
+    const SkRect&   fRect;
+};
+
+class SkIRectFanSource {
+public:
+    SkIRectFanSource(const SkIRect& rect) : fRect(rect) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+        dstPoint->fX = (i % 3) ? GrIntToScalar(fRect.fRight) :
+                                 GrIntToScalar(fRect.fLeft);
+        dstPoint->fY = (i < 2) ? GrIntToScalar(fRect.fTop)  :
+                                 GrIntToScalar(fRect.fBottom);
+    }
+private:
+    const SkIRect&   fRect;
+};
+
+class SkMatRectFanSource {
+public:
+    SkMatRectFanSource(const SkRect& rect, const SkMatrix& matrix)
+        : fRect(rect), fMatrix(matrix) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+
+#if SK_SCALAR_IS_GR_SCALAR
+        fMatrix.mapXY((i % 3) ? fRect.fRight : fRect.fLeft,
+                      (i < 2) ? fRect.fTop   : fRect.fBottom,
+                      (SkPoint*)dstPoint);
+#else
+        SkPoint dst;
+        fMatrix.mapXY((i % 3) ? fRect.fRight : fRect.fLeft,
+                      (i < 2) ? fRect.fTop   : fRect.fBottom,
+                      &dst);
+        dstPoint->fX = SkScalarToGrScalar(dst.fX);
+        dstPoint->fY = SkScalarToGrScalar(dst.fY);
+#endif
+    }
+private:
+    const SkRect&   fRect;
+    const SkMatrix& fMatrix;
+};
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+        return;
+    }
+
+    fContext->drawPaint(grPaint);
+}
+
+// must be in SkCanvas::PointMode order
+static const GrPrimitiveType gPointMode2PrimtiveType[] = {
+    kPoints_PrimitiveType,
+    kLines_PrimitiveType,
+    kLineStrip_PrimitiveType
+};
+
+void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
+                             size_t count, const SkPoint pts[], const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkScalar width = paint.getStrokeWidth();
+    if (width < 0) {
+        return;
+    }
+
+    // we only handle hairlines here, else we let the SkDraw call our drawPath()
+    if (width > 0) {
+        draw.drawPoints(mode, count, pts, paint, true);
+        return;
+    }
+
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+        return;
+    }
+
+#if SK_SCALAR_IS_GR_SCALAR
+    fContext->drawVertices(grPaint,
+                           gPointMode2PrimtiveType[mode],
+                           count,
+                           (GrPoint*)pts,
+                           NULL,
+                           NULL,
+                           NULL,
+                           0);
+#else
+    fContext->drawCustomVertices(grPaint,
+                                 gPointMode2PrimtiveType[mode],
+                                 SkPositionSource(pts, count));
+#endif
+}
+
+void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
+                          const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    bool doStroke = paint.getStyle() == SkPaint::kStroke_Style;
+    SkScalar width = paint.getStrokeWidth();
+
+    /*
+        We have special code for hairline strokes, miter-strokes, and fills.
+        Anything else we just call our path code.
+     */
+    bool usePath = doStroke && width > 0 &&
+                    paint.getStrokeJoin() != SkPaint::kMiter_Join;
+    // another reason we might need to call drawPath...
+    if (paint.getMaskFilter()) {
+        usePath = true;
+    }
+
+    if (usePath) {
+        SkPath path;
+        path.addRect(rect);
+        this->drawPath(draw, path, paint, NULL, true);
+        return;
+    }
+
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix,  &grPaint)) {
+        return;
+    }
+    fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1);
+}
+
+#include "SkMaskFilter.h"
+#include "SkBounder.h"
+
+static bool drawWithMaskFilter(GrContext* context, const SkPath& path,
+                               SkMaskFilter* filter, const SkMatrix& matrix,
+                               const SkRegion& clip, SkBounder* bounder,
+                               GrPaint* grp) {
+    SkMask  srcM, dstM;
+
+    if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
+                            SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
+        return false;
+    }
+
+    SkAutoMaskImage autoSrc(&srcM, false);
+
+    if (!filter->filterMask(&dstM, srcM, matrix, NULL)) {
+        return false;
+    }
+    // this will free-up dstM when we're done (allocated in filterMask())
+    SkAutoMaskImage autoDst(&dstM, false);
+
+    if (clip.quickReject(dstM.fBounds)) {
+        return false;
+    }
+    if (bounder && !bounder->doIRect(dstM.fBounds)) {
+        return false;
+    }
+
+    // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
+    // the current clip (and identity matrix) and grpaint settings
+
+    GrAutoMatrix avm(context, GrMatrix::I());
+
+    const GrGpu::TextureDesc desc = {
+        0,
+        GrGpu::kNone_AALevel,
+        dstM.fBounds.width(),
+        dstM.fBounds.height(),
+        GrTexture::kAlpha_8_PixelConfig
+    };
+
+    GrTexture* texture = context->createUncachedTexture(desc, dstM.fImage,
+                                                        dstM.fRowBytes);
+    if (NULL == texture) {
+        return false;
+    }
+
+    grp->setTexture(texture);
+    texture->unref();
+    grp->fSampler.setClampNoFilter();
+
+    GrRect d;
+    d.setLTRB(GrIntToScalar(dstM.fBounds.fLeft),
+              GrIntToScalar(dstM.fBounds.fTop),
+              GrIntToScalar(dstM.fBounds.fRight),
+              GrIntToScalar(dstM.fBounds.fBottom));
+    GrRect s;
+    s.setLTRB(0, 0, GR_Scalar1, GR_Scalar1);
+    context->drawRectToRect(*grp, d, s);
+    return true;
+}
+
+void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
+                           const SkPaint& paint, const SkMatrix* prePathMatrix,
+                           bool pathIsMutable) {
+    CHECK_SHOULD_DRAW(draw);
+
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+        return;
+    }
+
+    // BEGIN lift from SkDraw::drawPath()
+
+    SkPath*         pathPtr = const_cast<SkPath*>(&origSrcPath);
+    bool            doFill = true;
+    SkPath          tmpPath;
+
+    if (prePathMatrix) {
+        SkPath* result = pathPtr;
+
+        if (!pathIsMutable) {
+            result = &tmpPath;
+            pathIsMutable = true;
+        }
+        // should I push prePathMatrix on our MV stack temporarily, instead
+        // of applying it here? See SkDraw.cpp
+        pathPtr->transform(*prePathMatrix, result);
+        pathPtr = result;
+    }
+    // at this point we're done with prePathMatrix
+    SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
+
+    if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
+        doFill = paint.getFillPath(*pathPtr, &tmpPath);
+        pathPtr = &tmpPath;
+    }
+
+    // END lift from SkDraw::drawPath()
+
+    if (paint.getMaskFilter()) {
+        // avoid possibly allocating a new path in transform if we can
+        SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
+
+        // transform the path into device space
+        pathPtr->transform(*draw.fMatrix, devPathPtr);
+
+        drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
+                           *draw.fMatrix, *draw.fClip, draw.fBounder, &grPaint);
+        return;
+    }
+
+    GrPathFill fill = kHairLine_PathFill;
+
+    if (doFill) {
+        switch (pathPtr->getFillType()) {
+            case SkPath::kWinding_FillType:
+                fill = kWinding_PathFill;
+                break;
+            case SkPath::kEvenOdd_FillType:
+                fill = kEvenOdd_PathFill;
+                break;
+            case SkPath::kInverseWinding_FillType:
+                fill = kInverseWinding_PathFill;
+                break;
+            case SkPath::kInverseEvenOdd_FillType:
+                fill = kInverseEvenOdd_PathFill;
+                break;
+            default:
+                SkDebugf("Unsupported path fill type\n");
+                return;
+        }
+    }
+
+    SkGrPathIter iter(*pathPtr);
+    fContext->drawPath(grPaint, &iter, fill);
+}
+
+void SkGpuDevice::drawBitmap(const SkDraw& draw,
+                             const SkBitmap& bitmap,
+                             const SkIRect* srcRectPtr,
+                             const SkMatrix& m,
+                             const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkIRect srcRect;
+    if (NULL == srcRectPtr) {
+        srcRect.set(0, 0, bitmap.width(), bitmap.height());
+    } else {
+        srcRect = *srcRectPtr;
+    }
+
+    GrPaint grPaint;
+    if (!this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
+    }
+    grPaint.fSampler.setFilter(paint.isFilterBitmap());
+
+    const int maxTextureDim = fContext->getMaxTextureDimension();
+    if (bitmap.getTexture() || (bitmap.width() <= maxTextureDim &&
+                                bitmap.height() <= maxTextureDim)) {
+        // take the fast case
+        this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint);
+        return;
+    }
+
+    // undo the translate done by SkCanvas
+    int DX = SkMax32(0, srcRect.fLeft);
+    int DY = SkMax32(0, srcRect.fTop);
+    // compute clip bounds in local coordinates
+    SkIRect clipRect;
+    {
+        SkRect r;
+        r.set(draw.fClip->getBounds());
+        SkMatrix matrix, inverse;
+        matrix.setConcat(*draw.fMatrix, m);
+        if (!matrix.invert(&inverse)) {
+            return;
+        }
+        inverse.mapRect(&r);
+        r.roundOut(&clipRect);
+        // apply the canvas' translate to our local clip
+        clipRect.offset(DX, DY);
+    }
+
+    int nx = bitmap.width() / maxTextureDim;
+    int ny = bitmap.height() / maxTextureDim;
+    for (int x = 0; x <= nx; x++) {
+        for (int y = 0; y <= ny; y++) {
+            SkIRect tileR;
+            tileR.set(x * maxTextureDim, y * maxTextureDim,
+                      (x + 1) * maxTextureDim, (y + 1) * maxTextureDim);
+            if (!SkIRect::Intersects(tileR, clipRect)) {
+                continue;
+            }
+
+            SkIRect srcR = tileR;
+            if (!srcR.intersect(srcRect)) {
+                continue;
+            }
+
+            SkBitmap tmpB;
+            if (bitmap.extractSubset(&tmpB, tileR)) {
+                // now offset it to make it "local" to our tmp bitmap
+                srcR.offset(-tileR.fLeft, -tileR.fTop);
+
+                SkMatrix tmpM(m);
+                {
+                    int dx = tileR.fLeft - DX + SkMax32(0, srcR.fLeft);
+                    int dy = tileR.fTop -  DY + SkMax32(0, srcR.fTop);
+                    tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy));
+                }
+                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, &grPaint);
+            }
+        }
+    }
+}
+
+/*
+ *  This is called by drawBitmap(), which has to handle images that may be too
+ *  large to be represented by a single texture.
+ *
+ *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
+ *  and that non-texture portion of the GrPaint has already been setup.
+ */
+void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
+                                     const SkBitmap& bitmap,
+                                     const SkIRect& srcRect,
+                                     const SkMatrix& m,
+                                     GrPaint* grPaint) {
+    SkASSERT(bitmap.width() <= fContext->getMaxTextureDimension() &&
+             bitmap.height() <= fContext->getMaxTextureDimension());
+
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
+        return;
+    }
+
+    grPaint->fSampler.setWrapX(GrSamplerState::kClamp_WrapMode);
+    grPaint->fSampler.setWrapY(GrSamplerState::kClamp_WrapMode);
+    grPaint->fSampler.setSampleMode(GrSamplerState::kNormal_SampleMode);
+    grPaint->fSampler.setMatrix(GrMatrix::I());
+
+    GrTexture* texture;
+    SkAutoCachedTexture act(this, bitmap, grPaint->fSampler, &texture);
+    if (NULL == texture) {
+        return;
+    }
+
+    grPaint->setTexture(texture);
+
+    GrRect dstRect(0, 0, GrIntToScalar(srcRect.width()), GrIntToScalar(srcRect.height()));
+    GrRect paintRect;
+    paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16)   / bitmap.width()),
+                      GrFixedToScalar((srcRect.fTop << 16)    / bitmap.height()),
+                      GrFixedToScalar((srcRect.fRight << 16)  / bitmap.width()),
+                      GrFixedToScalar((srcRect.fBottom << 16) / bitmap.height()));
+
+    GrMatrix grMat;
+    SkGr::SkMatrix2GrMatrix(m, &grMat);
+
+    fContext->drawRectToRect(*grPaint, dstRect, paintRect, &grMat);
+}
+
+void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+                            int left, int top, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
+        return;
+    }
+
+    GrPaint grPaint;
+    if(!this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
+    }
+
+    GrAutoMatrix avm(fContext, GrMatrix::I());
+
+    GrTexture* texture;
+    grPaint.fSampler.setClampNoFilter();
+    SkAutoCachedTexture act(this, bitmap, grPaint.fSampler, &texture);
+
+    grPaint.setTexture(texture);
+
+    fContext->drawRectToRect(grPaint,
+                             GrRect(GrIntToScalar(left), GrIntToScalar(top),
+                                    GrIntToScalar(left + bitmap.width()),
+                                    GrIntToScalar(top + bitmap.height())),
+                             GrRect(0, 0, GR_Scalar1, GR_Scalar1));
+}
+
+void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
+                            int x, int y, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    GrPaint grPaint;
+    if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint) ||
+        !this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
+    }
+
+    SkASSERT(NULL != grPaint.getTexture());
+
+    const SkBitmap& bm = dev->accessBitmap(false);
+    int w = bm.width();
+    int h = bm.height();
+
+    GrAutoMatrix avm(fContext, GrMatrix::I());
+
+    grPaint.fSampler.setClampNoFilter();
+
+    fContext->drawRectToRect(grPaint,
+                             GrRect(GrIntToScalar(x),
+                                    GrIntToScalar(y),
+                                    GrIntToScalar(x + w),
+                                    GrIntToScalar(y + h)),
+                             GrRect(0, 0, GR_Scalar1, GR_Scalar1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// must be in SkCanvas::VertexMode order
+static const GrPrimitiveType gVertexMode2PrimitiveType[] = {
+    kTriangles_PrimitiveType,
+    kTriangleStrip_PrimitiveType,
+    kTriangleFan_PrimitiveType,
+};
+
+void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+                              int vertexCount, const SkPoint vertices[],
+                              const SkPoint texs[], const SkColor colors[],
+                              SkXfermode* xmode,
+                              const uint16_t indices[], int indexCount,
+                              const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    // we ignore the shader if texs is null.
+    if (NULL == texs) {
+        if (!this->skPaint2GrPaintNoShader(paint, false, &grPaint)) {
+            return;
+        }
+    } else {
+        if (!this->skPaint2GrPaintShader(paint, &act,
+                                         *draw.fMatrix,
+                                         &grPaint)) {
+            return;
+        }
+    }
+
+    if (NULL != xmode && NULL != texs && NULL != colors) {
+        SkXfermode::Mode mode;
+        if (!SkXfermode::IsMode(xmode, &mode) ||
+            SkXfermode::kMultiply_Mode != mode) {
+            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
+#if 0
+            return
+#endif
+        }
+    }
+
+#if SK_SCALAR_IS_GR_SCALAR
+    // even if GrColor and SkColor byte offsets match we need
+    // to perform pre-multiply.
+    if (NULL == colors) {
+        fContext->drawVertices(grPaint,
+                               gVertexMode2PrimitiveType[vmode],
+                               vertexCount,
+                               (GrPoint*) vertices,
+                               (GrPoint*) texs,
+                               NULL,
+                               indices,
+                               indexCount);
+    } else
+#endif
+    {
+        SkTexCoordSource texSrc(texs);
+        SkColorSource colSrc(colors);
+        SkIndexSource idxSrc(indices, indexCount);
+
+        fContext->drawCustomVertices(grPaint,
+                                     gVertexMode2PrimitiveType[vmode],
+                                     SkPositionSource(vertices, vertexCount),
+                                     (NULL == texs) ? NULL : &texSrc,
+                                     (NULL == colors) ? NULL : &colSrc,
+                                     (NULL == indices) ? NULL : &idxSrc);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void GlyphCacheAuxProc(void* data) {
+    delete (GrFontScaler*)data;
+}
+
+static GrFontScaler* get_gr_font_scaler(SkGlyphCache* cache) {
+    void* auxData;
+    GrFontScaler* scaler = NULL;
+    if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
+        scaler = (GrFontScaler*)auxData;
+    }
+    if (NULL == scaler) {
+        scaler = new SkGrFontScaler(cache);
+        cache->setAuxProc(GlyphCacheAuxProc, scaler);
+    }
+    return scaler;
+}
+
+static void SkGPU_Draw1Glyph(const SkDraw1Glyph& state,
+                             SkFixed fx, SkFixed fy,
+                             const SkGlyph& glyph) {
+    SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
+
+    GrSkDrawProcs* procs = (GrSkDrawProcs*)state.fDraw->fProcs;
+
+    if (NULL == procs->fFontScaler) {
+        procs->fFontScaler = get_gr_font_scaler(state.fCache);
+    }
+    procs->fTextContext->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), fx, 0),
+                                         SkIntToFixed(SkFixedFloor(fx)), fy,
+                                         procs->fFontScaler);
+}
+
+SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) {
+
+    // deferred allocation
+    if (NULL == fDrawProcs) {
+        fDrawProcs = new GrSkDrawProcs;
+        fDrawProcs->fD1GProc = SkGPU_Draw1Glyph;
+        fDrawProcs->fContext = fContext;
+    }
+
+    // init our (and GL's) state
+    fDrawProcs->fTextContext = context;
+    fDrawProcs->fFontScaler = NULL;
+    return fDrawProcs;
+}
+
+void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
+                          size_t byteLength, SkScalar x, SkScalar y,
+                          const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
+        // this guy will just call our drawPath()
+        draw.drawText((const char*)text, byteLength, x, y, paint);
+    } else {
+        SkAutoExtMatrix aem(draw.fExtMatrix);
+        SkDraw myDraw(draw);
+
+        GrPaint grPaint;
+        SkAutoCachedTexture act;
+
+        if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+            return;
+        }
+        GrTextContext context(fContext, grPaint, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(&context);
+        this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
+    }
+}
+
+void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
+                             size_t byteLength, const SkScalar pos[],
+                             SkScalar constY, int scalarsPerPos,
+                             const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
+        // this guy will just call our drawPath()
+        draw.drawPosText((const char*)text, byteLength, pos, constY,
+                         scalarsPerPos, paint);
+    } else {
+        SkAutoExtMatrix aem(draw.fExtMatrix);
+        SkDraw myDraw(draw);
+
+        GrPaint grPaint;
+        SkAutoCachedTexture act;
+        if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+            return;
+        }
+
+        GrTextContext context(fContext, grPaint, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(&context);
+        this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
+                                     scalarsPerPos, paint);
+    }
+}
+
+void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
+                                size_t len, const SkPath& path,
+                                const SkMatrix* m, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkASSERT(draw.fDevice == this);
+    draw.drawTextOnPath((const char*)text, len, path, m, paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
+    if (!paint.isLCDRenderText()) {
+        // we're cool with the paint as is
+        return false;
+    }
+
+    if (paint.getShader() ||
+        paint.getXfermode() || // unless its srcover
+        paint.getMaskFilter() ||
+        paint.getRasterizer() ||
+        paint.getColorFilter() ||
+        paint.getPathEffect() ||
+        paint.isFakeBoldText() ||
+        paint.getStyle() != SkPaint::kFill_Style) {
+        // turn off lcd
+        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
+        flags->fHinting = paint.getHinting();
+        return true;
+    }
+    // we're cool with the paint as is
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
+                                                  const GrSamplerState& sampler,
+                                                  GrTexture** texture,
+                                                  bool forDeviceRenderTarget) {
+    GrContext* ctx = this->context();
+    uint32_t p0, p1;
+    if (forDeviceRenderTarget) {
+        p0 = p1 = -1;
+    } else {
+        p0 = bitmap.getGenerationID();
+        p1 = bitmap.pixelRefOffset();
+    }
+
+    GrTexture* newTexture = NULL;
+    GrTextureKey key(p0, p1, bitmap.width(), bitmap.height());
+    GrTextureEntry* entry = ctx->findAndLockTexture(&key, sampler);
+
+    if (NULL == entry) {
+
+        if (forDeviceRenderTarget) {
+            const GrGpu::TextureDesc desc = {
+                GrGpu::kRenderTarget_TextureFlag,
+                GrGpu::kNone_AALevel,
+                bitmap.width(),
+                bitmap.height(),
+                SkGr::Bitmap2PixelConfig(bitmap)
+            };
+            entry = ctx->createAndLockTexture(&key, sampler, desc, NULL, 0);
+
+        } else {
+            entry = sk_gr_create_bitmap_texture(ctx, &key, sampler, bitmap);
+        }
+        if (NULL == entry) {
+            GrPrintf("---- failed to create texture for cache [%d %d]\n",
+                     bitmap.width(), bitmap.height());
+        }
+    }
+
+    if (NULL != entry) {
+        newTexture = entry->texture();
+        if (texture) {
+            *texture = newTexture;
+        }
+        // IMPORTANT: We can't allow another SkGpuDevice to get this
+        // cache entry until this one is destroyed!
+        if (forDeviceRenderTarget) {
+            ctx->detachCachedTexture(entry);
+        }
+    }
+    return (TexCache*)entry;
+}
+
+void SkGpuDevice::unlockCachedTexture(TexCache* cache) {
+    this->context()->unlockTexture((GrTextureEntry*)cache);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
+                                       GrRenderTarget* rootRenderTarget)
+        : fContext(context) {
+
+    GrAssert(NULL != context);
+    GrAssert(NULL != rootRenderTarget);
+
+    // check this now rather than passing this value to SkGpuDevice cons.
+    // we want the rt that is bound *now* in the 3D API, not the one
+    // at the time of newDevice.
+    if (SkGpuDevice::Current3DApiRenderTarget() == rootRenderTarget) {
+        fRootRenderTarget = context->createRenderTargetFrom3DApiState();
+    } else {
+        fRootRenderTarget = rootRenderTarget;
+        rootRenderTarget->ref();
+    }
+    context->ref();
+
+}
+
+SkGpuDeviceFactory::~SkGpuDeviceFactory() {
+    fContext->unref();
+    fRootRenderTarget->unref();
+}
+
+SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
+                                        int width, int height,
+                                        bool isOpaque, bool isLayer) {
+    SkBitmap bm;
+    bm.setConfig(config, width, height);
+    bm.setIsOpaque(isOpaque);
+    return new SkGpuDevice(fContext, bm, isLayer ?  NULL : fRootRenderTarget);
+}
+
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
new file mode 100644
index 0000000..e57f88a
--- /dev/null
+++ b/src/gpu/SkGr.cpp
@@ -0,0 +1,243 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGr.h"
+
+/*  Fill out buffer with the compressed format Ganesh expects from a colortable
+ based bitmap. [palette (colortable) + indices].
+
+ At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
+ we could detect that the colortable.count is <= 16, and then repack the
+ indices as nibbles to save RAM, but it would take more time (i.e. a lot
+ slower than memcpy), so skipping that for now.
+
+ Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
+ as the colortable.count says it is.
+ */
+static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
+    SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());
+
+    SkAutoLockPixels apl(bitmap);
+    if (!bitmap.readyToDraw()) {
+        SkASSERT(!"bitmap not ready to draw!");
+        return;
+    }
+
+    SkColorTable* ctable = bitmap.getColorTable();
+    char* dst = (char*)buffer;
+
+    memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
+    ctable->unlockColors(false);
+
+    // always skip a full 256 number of entries, even if we memcpy'd fewer
+    dst += GrGpu::kColorTableSize;
+
+    if (bitmap.width() == bitmap.rowBytes()) {
+        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
+    } else {
+        // need to trim off the extra bytes per row
+        size_t width = bitmap.width();
+        size_t rowBytes = bitmap.rowBytes();
+        const char* src = (const char*)bitmap.getPixels();
+        for (int y = 0; y < bitmap.height(); y++) {
+            memcpy(dst, src, width);
+            src += rowBytes;
+            dst += width;
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
+                                            GrTextureKey* key,
+                                            const GrSamplerState& sampler,
+                                            const SkBitmap& origBitmap) {
+    SkAutoLockPixels alp(origBitmap);
+    if (!origBitmap.readyToDraw()) {
+        return NULL;
+    }
+
+    SkBitmap tmpBitmap;
+
+    const SkBitmap* bitmap = &origBitmap;
+
+    GrGpu::TextureDesc desc = {
+        0,
+        GrGpu::kNone_AALevel,
+        bitmap->width(),
+        bitmap->height(),
+        SkGr::Bitmap2PixelConfig(*bitmap)
+    };
+
+    if (SkBitmap::kIndex8_Config == bitmap->config()) {
+        // build_compressed_data doesn't do npot->pot expansion
+        // and paletted textures can't be sub-updated
+        if (ctx->supportsIndex8PixelConfig(sampler,
+                                           bitmap->width(), bitmap->height())) {
+            size_t imagesize = bitmap->width() * bitmap->height() +
+                                GrGpu::kColorTableSize;
+            SkAutoMalloc storage(imagesize);
+
+            build_compressed_data(storage.get(), origBitmap);
+
+            // our compressed data will be trimmed, so pass width() for its
+            // "rowBytes", since they are the same now.
+            return ctx->createAndLockTexture(key, sampler, desc, storage.get(),
+                                             bitmap->width());
+
+        } else {
+            origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
+            // now bitmap points to our temp, which has been promoted to 32bits
+            bitmap = &tmpBitmap;
+        }
+    }
+
+    desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
+    return ctx->createAndLockTexture(key, sampler, desc, bitmap->getPixels(),
+                                     bitmap->rowBytes());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+GrPathCmd SkGrPathIter::next(GrPoint pts[]) {
+    GrAssert(NULL != pts);
+#if SK_SCALAR_IS_GR_SCALAR
+    return sk_path_verb_to_gr_path_command(fIter.next((SkPoint*)pts));
+#else
+    Command cmd = sk_path_verb_to_gr_path_command(fIter.next(fPoints));
+    int n = NumCommandPoints(cmd);
+    for (int i = 0; i < n; ++i) {
+        pts[i].fX = SkScalarToGrScalar(fPoints[i].fX);
+        pts[i].fY = SkScalarToGrScalar(fPoints[i].fY);
+    }
+    return cmd;
+#endif
+}
+
+GrPathCmd SkGrPathIter::next() {
+    return sk_path_verb_to_gr_path_command(fIter.next(NULL));
+}
+
+void SkGrPathIter::rewind() {
+    fIter.setPath(*fPath, false);
+}
+
+GrConvexHint SkGrPathIter::convexHint() const {
+    return fPath->isConvex() ? kConvex_ConvexHint :
+                               kNone_ConvexHint;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGrClipIterator::reset(const SkClipStack& clipStack) {
+    fClipStack = &clipStack;
+    fIter.reset(clipStack);
+    // Gr has no notion of replace, skip to the
+    // last replace in the clip stack.
+    int lastReplace = 0;
+    int curr = 0;
+    while (NULL != (fCurr = fIter.next())) {
+        if (SkRegion::kReplace_Op == fCurr->fOp) {
+            lastReplace = curr;
+        }
+        ++curr;
+    }
+    fIter.reset(clipStack);
+    for (int i = 0; i < lastReplace+1; ++i) {
+        fCurr = fIter.next();
+    }
+}
+
+GrClipType SkGrClipIterator::getType() const {
+    GrAssert(!this->isDone());
+    if (NULL != fCurr->fRect) {
+        return kRect_ClipType;
+    } else {
+        GrAssert(NULL != fCurr->fPath);
+        return kPath_ClipType;
+    }
+}
+
+GrSetOp SkGrClipIterator::getOp() const {
+    // we skipped to the last "replace" op
+    // when this iter was reset.
+    // GrClip doesn't allow replace, so treat it as
+    // intersect.
+    GrSetOp skToGrOps[] = {
+        kDifference_SetOp,         // kDifference_Op
+        kIntersect_SetOp,          // kIntersect_Op
+        kUnion_SetOp,              // kUnion_Op
+        kXor_SetOp,                // kXOR_Op
+        kReverseDifference_SetOp,  // kReverseDifference_Op
+        kIntersect_SetOp           // kReplace_op
+    };
+    GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
+    GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
+    GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
+    GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
+    GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
+    GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
+    return skToGrOps[fCurr->fOp];
+}
+
+GrPathFill SkGrClipIterator::getPathFill() const {
+    switch (fCurr->fPath->getFillType()) {
+        case SkPath::kWinding_FillType:
+            return kWinding_PathFill;
+        case SkPath::kEvenOdd_FillType:
+            return  kEvenOdd_PathFill;
+        case SkPath::kInverseWinding_FillType:
+            return kInverseWinding_PathFill;
+        case SkPath::kInverseEvenOdd_FillType:
+            return kInverseEvenOdd_PathFill;
+        default:
+            GrCrash("Unsupported path fill in clip.");
+            return kWinding_PathFill; // suppress warning
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTexture::PixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
+                                                    bool isOpaque) {
+    switch (config) {
+        case SkBitmap::kA8_Config:
+            return GrTexture::kAlpha_8_PixelConfig;
+        case SkBitmap::kIndex8_Config:
+            return GrTexture::kIndex_8_PixelConfig;
+        case SkBitmap::kRGB_565_Config:
+            return GrTexture::kRGB_565_PixelConfig;
+        case SkBitmap::kARGB_4444_Config:
+            return GrTexture::kRGBA_4444_PixelConfig;
+        case SkBitmap::kARGB_8888_Config:
+            if (isOpaque) {
+                return GrTexture::kRGBX_8888_PixelConfig;
+            } else {
+                return GrTexture::kRGBA_8888_PixelConfig;
+            }
+        default:
+            return GrTexture::kUnknown_PixelConfig;
+    }
+}
+
+void SkGr::AbandonAllTextures(GrContext* ctx) {
+    ctx->abandonAllTextures();
+}
+
+
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp
new file mode 100644
index 0000000..16e44b9
--- /dev/null
+++ b/src/gpu/SkGrFontScaler.cpp
@@ -0,0 +1,156 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGr.h"
+#include "SkDescriptor.h"
+#include "SkGlyphCache.h"
+
+class SkGrDescKey : public GrKey {
+public:
+    explicit SkGrDescKey(const SkDescriptor& desc);
+    virtual ~SkGrDescKey();
+
+protected:
+    // overrides
+    virtual bool lt(const GrKey& rh) const;
+    virtual bool eq(const GrKey& rh) const;
+
+private:
+    SkDescriptor* fDesc;
+    enum {
+        kMaxStorageInts = 16
+    };
+    uint32_t fStorage[kMaxStorageInts];
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
+    size_t size = desc.getLength();
+    if (size <= sizeof(fStorage)) {
+        fDesc = GrTCast<SkDescriptor*>(fStorage);
+    } else {
+        fDesc = SkDescriptor::Alloc(size);
+    }
+    memcpy(fDesc, &desc, size);
+}
+
+SkGrDescKey::~SkGrDescKey() {
+    if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
+        SkDescriptor::Free(fDesc);
+    }
+}
+
+bool SkGrDescKey::lt(const GrKey& rh) const {
+    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+    size_t lenLH = fDesc->getLength();
+    size_t lenRH = srcDesc->getLength();
+    int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
+    if (0 == cmp) {
+        return lenLH < lenRH;
+    } else {
+        return cmp < 0;
+    }
+}
+
+bool SkGrDescKey::eq(const GrKey& rh) const {
+    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+    return fDesc->equals(*srcDesc);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
+    fStrike = strike;
+    fKey = NULL;
+}
+
+SkGrFontScaler::~SkGrFontScaler() {
+    GrSafeUnref(fKey);
+}
+
+GrMaskFormat SkGrFontScaler::getMaskFormat() {
+    SkMask::Format format = fStrike->getMaskFormat();
+    switch (format) {
+        case SkMask::kA8_Format:
+            return kA8_GrMaskFormat;
+        case SkMask::kLCD16_Format:
+            return kA565_GrMaskFormat;
+        default:
+            GrAssert(!"unsupported SkMask::Format");
+            return kA8_GrMaskFormat;
+    }
+}
+
+const GrKey* SkGrFontScaler::getKey() {
+    if (NULL == fKey) {
+        fKey = new SkGrDescKey(fStrike->getDescriptor());
+    }
+    return fKey;
+}
+
+bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
+                                          GrIRect* bounds) {
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
+                                              GrGlyph::UnpackFixedX(packed),
+                                              GrGlyph::UnpackFixedY(packed));
+    bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
+    return true;
+
+}
+
+bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
+                                         int width, int height,
+                                         int dstRB, void* dst) {
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
+                                              GrGlyph::UnpackFixedX(packed),
+                                              GrGlyph::UnpackFixedY(packed));
+    GrAssert(glyph.fWidth == width);
+    GrAssert(glyph.fHeight == height);
+    const void* src = fStrike->findImage(glyph);
+    if (NULL == src) {
+        return false;
+    }
+
+    int srcRB = glyph.rowBytes();
+    if (srcRB == dstRB) {
+        memcpy(dst, src, dstRB * height);
+    } else {
+        const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
+        for (int y = 0; y < height; y++) {
+            memcpy(dst, src, width * bbp);
+            src = (const char*)src + srcRB;
+            dst = (char*)dst + dstRB;
+        }
+    }
+    return true;
+}
+
+bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
+
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
+    const SkPath* skPath = fStrike->findPath(glyph);
+    if (skPath) {
+        SkGrPathIter iter(*skPath);
+        path->resetFromIter(&iter);
+        return true;
+    }
+    return false;
+}
+
+
+
diff --git a/src/gpu/SkGrTexturePixelRef.cpp b/src/gpu/SkGrTexturePixelRef.cpp
new file mode 100644
index 0000000..da9ac1a
--- /dev/null
+++ b/src/gpu/SkGrTexturePixelRef.cpp
@@ -0,0 +1,30 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGrTexturePixelRef.h"
+#include "GrTexture.h"
+
+SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) {
+    fTexture = tex;
+    GrSafeRef(tex);
+}
+
+SkGrTexturePixelRef::~SkGrTexturePixelRef() {
+    GrSafeUnref(fTexture);
+}
+
+
diff --git a/src/gpu/skgr_files.mk b/src/gpu/skgr_files.mk
new file mode 100644
index 0000000..7623fca
--- /dev/null
+++ b/src/gpu/skgr_files.mk
@@ -0,0 +1,8 @@
+SOURCE := \
+    SkGpuCanvas.cpp	\
+    SkGpuDevice.cpp \
+    SkGr.cpp \
+    SkGrTexturePixelRef.cpp \
+    SkGrFontScaler.cpp \
+    GrPrintf_skia.cpp
+
diff --git a/src/images/fpdfemb.h b/src/images/fpdfemb.h
deleted file mode 100644
index 3c77116..0000000
--- a/src/images/fpdfemb.h
+++ /dev/null
@@ -1,1765 +0,0 @@
-// FPDFEMB.H - Header file for FPDFEMB SDK
-// Copyright (c) 2007-2008 Foxit Software Company, All Right Reserved.
-
-// Date: 2008-04-07
-
-// Embedded platforms have many different aspects from desktop platforms,
-// among them, the followings are most important for PDF processing:
-//
-// 1.	Embedded platforms have only limited memory, and there is no virtual memory.
-//		PDF is a very complicated format, processing PDF may consumes quite
-//		large amount of memory, even for some smaller PDFs. And, in order to 
-//		increase the performance of PDF parsing and rendering, cache memory
-//		is often used. For some big PDFs with many pages, the cache may grow
-//		while user browing through pages, eventually, for some PDFs, the memory
-//		on the device may run out.
-//
-//		FPDFEMB SDK allows graceful out-of-memory (OOM) handling by returning 
-//		OOM error code for all functions that may involve memory allocation. 
-//		When an application detects OOM situation, it can do one of the followings:
-//
-//			a) Give user some prompt and quit the application or close the document;
-//			b) Or better, try to recover from the error. Sometimes OOM can be caused
-//				by ever-growing cache. For example, when user browses a 1000-page 
-//				document, let's say OOM happen at page #300. In this case, the
-//				application might close the whole document (cache will be gone with
-//				it), reopen the document, then go directly to page #300. It's likely
-//				the process will go through this time. This is called "OOM recovery".
-//				If OOM happens again during a recovery, then, it's not possible to finish
-//				the process, the application must quit of close the document.
-//
-// 2.	Embedded platforms has only limited computing power. Since some PDFs
-//		can be very complicated and require a lot of processing to be displayed,
-//		it may take a lot of time for the process to finish. This may cause
-//		some problem with user experience, especially for devices like mobile
-//		phones, when an application may need to be put on hold any time. Therefore, 
-//		it's important to break lengthy process into small steps which can be 
-//		stopped or resumed at any time. We call this kind of process as 
-//		"progressive process".
-//
-//		FPDFEMB SDK allows progressive page parsing and rendering, the most time-
-//		consuming part of PDF processing.
-//
-// IMPORTANT:
-//		FPDFEMB module is not intended to run in multi-threaded environment.
-
-// Components inside FPDFEMB:
-//		* Library Memory Management
-//		* Document Operations
-//		* Page Basic Operations
-//		* Page Parsing
-//		* Page Rendering
-//		* Coordination Conversion
-//		* Text Search
-//		* Text Information
-//		* Device Independant Bitmap
-//		* Custom Font Handler and CJK Support
-//		* Bookmark Information
-//		* Hyperlink Information
-//		* Graphic Output
-
-#ifndef _FPDFEMB_H_
-#define _FPDFEMB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Standard return type for many FPDFEMB functions: FPDFERR_SUCCESS for success, otherwise error code
-typedef int FPDFEMB_RESULT;
-
-// Standard boolean type: 0 for false, non-zero for true
-typedef int FPDFEMB_BOOL;
-
-// Unicode character. FPDFEMB uses UTF16LE format for unicode string.
-typedef unsigned short FPDFEMB_WCHAR;
-
-// Error codes
-#define FPDFERR_SUCCESS		0
-#define FPDFERR_MEMORY		1		// Out of memory
-#define FPDFERR_ERROR		2		// Error of any kind, without specific reason
-#define FPDFERR_PASSWORD	3		// Incorrect password
-#define FPDFERR_FORMAT		4		// Not PDF format
-#define FPDFERR_FILE		5		// File access error
-#define FPDFERR_PARAM		6		// Parameter error
-#define FPDFERR_STATUS		7		// Not in correct status
-#define FPDFERR_TOBECONTINUED	8	// To be continued
-#define FPDFERR_NOTFOUND	9		// Search result not found
-
-/********************************************************************************************
-****
-****		Library Memory Management
-****
-********************************************************************************************/
-
-// Structure: FPDFEMB_MEMMGR
-//			Including interfaces implemented by host application, providing memory allocation
-//			facilities. All members are required.
-//			A memory manager structure is required to be valid during the entire period
-//			when an application using FPDFEMB module.
-//
-//			IMPORTANT NOTE: using of this interface is strongly not recommended, because
-//			FPDFEMB now internally use FPDFEMB_MEMMGR_EX interface, which allows more
-//			advanced memory management. This interface is retained for backward compatibility
-//			only, and maybe discontinued in the future.
-//
-struct FPDFEMB_MEMMGR {
-	// Interface: Alloc
-	//		Allocate a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		size		-	Number of bytes for the memory block.
-	// Return Value:
-	//		The pointer to allocated memory block. NULL if no memory available.
-	// Comments:
-	//		In order to handle OOM situation, application can use longjmp() inside 
-	//		implementation of this function. If underlying memory manager fails to 
-	//		allocate enough memory, then application can use longjmp() to jump to
-	//		OOM handling codes.
-	//
-	void*	(*Alloc)(struct FPDFEMB_MEMMGR* pMgr, unsigned int size);
-
-	// Interface: AllocNL
-	//		Allocate a memory block, without leaving
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		size		-	Number of bytes for the memory block.
-	// Return Value:
-	//		The pointer to allocated memory block. NULL if no memory available.
-	// Comments:
-	//		Implementation MUST return NULL if no memory available, no exception
-	//		or longjmp() can be used.
-	//
-	void*	(*AllocNL)(struct FPDFEMB_MEMMGR* pMgr, unsigned int size);
-
-	// Interfce: Realloc
-	//		Reallocate a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		pointer		-	An existing memory block, or NULL.
-	//		new_size	-	New size (number of bytes) of the memory block. Can be zero.
-	// Return value:
-	//		The pointer of reallocated memory block, it could be a new block, or just
-	//		the previous block with size modified.
-	// Comments:
-	//		If an existing memory block specified, the data in the memory block will
-	//		be copied to the new block, if reallocated.
-	//
-	//		In order to handle OOM situation, application can use longjmp() inside 
-	//		implementation of this function. If underlying memory manager fails to 
-	//		allocate enough memory, then application can use longjmp() to jump to
-	//		OOM handling codes.
-	//
-	void*	(*Realloc)(struct FPDFEMB_MEMMGR* pMgr, void* pointer, unsigned int new_size);
-
-	// Interface: Free
-	//		Free a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		pointer		-	An existing memory block.
-	// Return Value:
-	//		None.
-	//
-	void	(*Free)(struct FPDFEMB_MEMMGR* pMgr, void* pointer);
-};
-
-// Function: FPDFEMB_Init
-//			Initialize the FPDFEMB module
-// Parameters:
-//			mem_mgr		-	Pointer to memory manager structure
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			This function will allocate necessary internal data structure for
-//			the whole module to operate.
-FPDFEMB_RESULT FPDFEMB_Init(FPDFEMB_MEMMGR* mem_mgr);
-
-typedef void (*FPDFEMB_FIXED_OOM_HANDLER)(void* memory, int size);
-
-// Function: FPDFEMB_InitFixedMemory
-//			Initialize the FPDFEMB module, providing a fixed memory heap
-// Parameters:
-//			memory		-	Pointer to a pre-allocated memory block
-//			size		-	Number of bytes in the memory block
-//			oom_handler	-	Pointer to a function which will be called when OOM happens. Can be
-//							NULL if application doesn't want to be notified om OOM.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			In many embedded system, memory usage are predetermined. The application
-//			is assigned with fixed size of available memory, then it can pre-allocate
-//			a memory block with maximum size and pass to this function to initialize
-//			FPDFEMB module. In this case, FPDFEMB won't need any additional memory
-//			allocation.
-//
-//			In case the pre-allocated memory has run out, the "oom_proc" callback
-//			function will be called to notify the application that an OOM recovery
-//			procedure needs to be performed.
-//
-FPDFEMB_RESULT FPDFEMB_InitFixedMemory(void* memory, int size, FPDFEMB_FIXED_OOM_HANDLER oom_handler);
-
-// Memory Management Flags
-#define FPDFEMB_NONLEAVE		1
-#define FPDFEMB_MOVABLE			2
-#define FPDFEMB_DISCARDABLE		4
-
-// Structure: FPDFEMB_MEMMGR_EX
-//			This is an extended version of memory manager interface, allowing advanced
-//			memory management, including movable and discardable memory blocks.
-//
-//			Use this interface with FPDFEMB_InitExt function.
-//
-struct FPDFEMB_MEMMGR_EX {
-	// Interface: Alloc
-	//		Allocate a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		size		-	Number of bytes for the memory block.
-	//		flags		-	A combination of flags defined above.
-	// Return Value:
-	//		The pointer to allocated memory block. NULL if no memory available.
-	//		If FPDFEMB_MOVABLE flag is used, implementation should return a handle
-	//		to the memory block, if it supports movable block allocation.
-	// Comments:
-	//		The implementation should not do any action if no memory available,
-	//		just return NULL. OOM handling can be done in OOM_Handler interface.
-	//
-	void*	(*Alloc)(struct FPDFEMB_MEMMGR_EX* pMgr, unsigned int size, int flags);
-
-	// Interface: OOM_Handler
-	//		OOM (out-of-memory) situation handler
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	// Return Value:
-	//		None.
-	// Comments:
-	//		In order to handle OOM situation, application can use longjmp() inside 
-	//		implementation of this function.
-	//
-	void	(*OOM_Handler)(struct FPDFEMB_MEMMGR_EX* pMgr);
-
-	// Interfce: Realloc
-	//		Reallocate a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		pointer		-	Pointer to an existing memory block, or handle to a movable
-	//						block. Can not be NULL.
-	//		new_size	-	New size (number of bytes) of the memory block. Can not be zero.
-	// Return value:
-	//		The pointer of reallocated memory block, it could be a new block, or just
-	//		the previous block with size modified.
-	//		If FPDFEMB_MOVABLE flag is used, implementation should return a handle
-	//		to the memory block, if it supports movable block allocation.
-	// Comments:
-	//		If an existing memory block specified, the data in the memory block should
-	//		be copied to the new block, if reallocated.
-	//
-	//		The implementation should not do any action if no memory available,
-	//		just return NULL. OOM handling can be done in OOM_Handler interface.
-	//
-	void*	(*Realloc)(struct FPDFEMB_MEMMGR_EX* pMgr, void* pointer, unsigned int new_size, int flags);
-
-	// Interface: Lock
-	//		Lock a movable memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		handle		-	Handle to movable memory block, returned by Alloc or Realloc.
-	// Return Value:
-	//		The pointer of the memory block. NULL if the block was discarded.
-	// Comments:
-	//		This interface is optional, if implementation doesn't support movable memory
-	//		block, then this interface can be set to NULL.
-	//
-	void*	(*Lock)(struct FPDFEMB_MEMMGR_EX* pMgr, void* handle);
-
-	// Interface: Unlock
-	//		Unlock a locked movable memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		handle		-	Handle to movable memory block, returned by Alloc or Realloc.
-	// Return Value:
-	//		None.
-	// Comments:
-	//		This interface is optional, if implementation doesn't support movable memory
-	//		block, then this interface can be set to NULL.
-	//
-	void	(*Unlock)(struct FPDFEMB_MEMMGR_EX* pMgr, void* handle);
-
-	// Interface: Free
-	//		Free a memory block
-	// Parameters:
-	//		pMgr		-	Pointer to the memory manager.
-	//		pointer		-	Pointer to an existing memory block, or handle to a movable block.
-	// Return Value:
-	//		None.
-	//
-	void	(*Free)(struct FPDFEMB_MEMMGR_EX* pMgr, void* pointer, int flags);
-
-	void*	user;		// A user pointer, used by the application
-};
-
-// Function: FPDFEMB_LoadJbig2Decoder
-// Function: FPDFEMB_LoadJpeg2000Decoder
-//			Enable JBIG2 or JPEG2000 image decoder 
-// Parameters:
-//			None.
-// Return Value:
-//			None.
-// Comments:
-//			If you want to display JBIG2 or JPEG2000 encoded images, you need to call 
-//			these functions after FPDFEMB initialized.
-//
-//			Calling these functions will increase code size by about 200K-400K bytes.
-//			Also JPEG2000 decoder may not be available on some platforms.
-//
-void FPDFEMB_LoadJbig2Decoder();
-void FPDFEMB_LoadJpeg2000Decoder();
-
-// Function: FPDFEMB_InitEx
-//			Initialize the FPDFEMB module with the extended memory manager
-// Parameters:
-//			mem_mgr		-	Pointer to memory manager structure
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			This function will allocate necessary internal data structure for
-//			the whole module to operate.
-FPDFEMB_RESULT FPDFEMB_InitEx(FPDFEMB_MEMMGR_EX* mem_mgr);
-
-// Function: FPDFEMB_Exit
-//			Stop using FPDFEMB module and release all resources
-// Parameters:
-//			None.
-// Return Value:
-//			None.
-// Comments:
-//			All loaded documents and pages will become invalid after this call.
-//
-//			This function is useful for OOM recovery: when your application hits
-//			an OOM situation, calling this function will clear all memory allocated
-//			by FPDFEMB module, then you can call one of the initialization functions,
-//			reopen the document and recovery from OOM.
-//
-void FPDFEMB_Exit();
-
-// Function: FPDFEMB_AllocMemory
-//			Allocate memory
-// Parameters:
-//			size		-	Number of bytes
-// Return Value:
-//			The allocated buffer pointer. NULL for out of memory.
-//
-void* FPDFEMB_AllocMemory(unsigned int size);
-
-// Function: FPDFEMB_FreeMemory
-//			Free allocated memory
-// Parameters:
-//			pointer		-	Pointer returned by FPDFEMB_AllocMemory
-// Return Value:
-//			None.
-//
-void FPDFEMB_FreeMemory(void* pointer);
-
-// Function: FPDFEMB_FreeCaches
-//			Free all expendable caches used by FPDFEMB in order to save memory
-// Parameters:
-//			None.
-// Return Value:
-//			None.
-// Comments:
-//			When an application memory manager runs out of memory, before an OOM situation 
-//			is raised, the application can try this 
-//
-void FPDFEMB_FreeCaches();
-
-/********************************************************************************************
-****
-****		Document Operations
-****
-********************************************************************************************/
-
-// Structure: FPDFEMB_FILE_ACCESS
-//		Describe the way to access a file (readonly).
-struct FPDFEMB_FILE_ACCESS {
-	// Inteface: GetSize
-	//		Get total size of the file
-	// Parameters:
-	//		file		-	Pointer to this file access structure
-	// Return Value:
-	//		File size, in bytes. Implementation can return 0 for any error.
-	// 
-	unsigned int	(*GetSize)(struct FPDFEMB_FILE_ACCESS* file);
-
-	// Interface: ReadBlock
-	//		Read a data block from the file
-	// Parameters:
-	//		file		-	Pointer to this file access structure
-	//		buffer		-	Pointer to a buffer receiving read data
-	//		offset		-	Byte offset for the block, from beginning of the file
-	//		size		-	Number of bytes for the block.
-	// Return Value:
-	//		Error code, or FPDFERR_SUCCESS for success.
-	//
-	FPDFEMB_RESULT	(*ReadBlock)(struct FPDFEMB_FILE_ACCESS* file, void* buffer, 
-									unsigned int offset, unsigned int size);
-
-	void*		user;		// A user pointer, used by the application
-};
-
-// Structure: FPDFEMB_PAUSE
-//			An interface for pausing a progressive process.
-struct FPDFEMB_PAUSE {
-	// Interface: NeedPauseNow
-	//		Check if we need to pause a progressive proccess now
-	// Parameters:
-	//		pause		-	Pointer to the pause structure
-	// Return Value:
-	//		Non-zero for pause now, 0 for continue.
-	// Comments:
-	//		Typically implementation of this interface compares the current system tick
-	//		with the previous one, if the time elapsed exceeds certain threshold, then
-	//		the implementation returns TRUE, indicating a pause is needed.
-	//
-	FPDFEMB_BOOL (*NeedPauseNow)(struct FPDFEMB_PAUSE* pause);
-
-	void*		user;		// A user pointer, used by the application
-};
-
-typedef void* FPDFEMB_DOCUMENT;
-
-// Function: FPDFEMB_StartLoadDocument
-//			Start loading a PDF document
-// Parameters:
-//			file		-	Pointer to file access structure.
-//							This structure must be kept valid as long as the document is open.
-//			password	-	Pointer to a zero-terminated byte string, for the password.
-//							Or NULL for no password.
-//			document	-	Receiving the document handle
-//			pause		-	A callback mechanism allowing the document loading process
-//							to be paused before it's finished. This can be NULL if you
-//							don't want to pause.
-// Return Value:
-//			FPDFERR_SUCCESS: document successfully loaded.
-//			FPDFERR_TOBECONTINUED: The document loading can't be finished now.
-//					See comments below.
-//			FPDFERR_PASSWORD: incorrect password.
-//			FPDFERR_FORMAT: not a PDF or corrupted PDF.
-//			FPDFERR_FILE: file access error.
-//			FPDFERR_MEMORY: out of memory.
-// Comments:
-//			Document loading is a progressive process. It might take a long time to
-//			load a document, especiall when a file is corrupted, FPDFEMB will try to
-//			recover the document contents by scanning the whole file. If "pause" parameter
-//			is provided, this function may return FPDFERR_TOBECONTINUED any time during
-//			the document loading.
-//
-//			When FPDFERR_TOBECONTINUED is returned, the "document" parameter will
-//			still receive a valid document handle, however, no further operations can
-//			be performed on the document, except the "FPDFEMB_ContineLoadDocument" function
-//			call, which resume the document loading.
-//
-FPDFEMB_RESULT FPDFEMB_StartLoadDocument(FPDFEMB_FILE_ACCESS* file, const char* password, 
-									FPDFEMB_DOCUMENT* document, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_ContinueLoadDocument
-//			Continue loading a PDF document
-// Parameters:
-//			document	-	Document handle returned by FPDFEMB_StartLoadDocument function
-//			pause		-	A callback mechanism allowing the document loading process
-//							to be paused before it's finished. This can be NULL if you
-//							don't want to pause.
-// Return Value:
-//			FPDFERR_SUCCESS: document successfully loaded.
-//			FPDFERR_TOBECONTINUED: The document loading can't be finished now.
-//					Further call to this function is needed.
-//			FPDFERR_PASSWORD: incorrect password.
-//			FPDFERR_FORMAT: not a PDF or corrupted PDF.
-//			FPDFERR_FILE: file access error.
-//			FPDFERR_MEMORY: out of memory.
-//			FPDFERR_STATUS: document already loaded.
-//			FPDFERR_PARAM: invalid parameter (like NULL document handle)
-//
-FPDFEMB_RESULT FPDFEMB_ContinueLoadDocument(FPDFEMB_DOCUMENT document, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_CloseDocument
-//			Close a PDF document and free all associated resources
-// Parameters:
-//			document	-	Document handle
-// Return Value:
-//			Error code. FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_CloseDocument(FPDFEMB_DOCUMENT document);
-
-// Function: Get page count
-//			Get number of pages in the document
-// Parameters:
-//			document	-	Document handle
-// Return Value:
-//			Number of pages.
-//
-int FPDFEMB_GetPageCount(FPDFEMB_DOCUMENT document);
-
-// Function: FPDFEMB_SetFileBufferSize
-//			Set size of internal buffer used to read from source file.
-// Parameters:
-//			size		-	Number of bytes
-// Return Value:
-//			None.
-// Comments:
-//			Currently FPDFEMB uses 512 bytes as default buffer size. The new buffer size 
-//			takes effect next time you call FPDFEMB_StartLoadDocument.
-//
-void FPDFEMB_SetFileBufferSize(int size);
-
-/********************************************************************************************
-****
-****		Page Basic Operations
-****
-********************************************************************************************/
-
-typedef void* FPDFEMB_PAGE;
-
-// Function: FPDFEMB_LoadPage
-//			Load a page
-// Parameters:
-//			document	-	Document handle
-//			index		-	Page index, starting from zero
-//			page		-	Receiving the loaded page handler
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_LoadPage(FPDFEMB_DOCUMENT document, int index, FPDFEMB_PAGE* page);
-
-// Function: FPDFEMB_ClosePage
-//			Close a page and release all related resources
-// Parameters:
-//			page		-	Page handle
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_ClosePage(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_GetPageSize
-//			Get size of a page
-// Parameters:
-//			page		-	Page handle
-//			width		-	Receiving page width, in hundredth of points
-//			height		-	Receiving page height, in hundredth of points
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_GetPageSize(FPDFEMB_PAGE page, int* width, int* height);
-
-// Structure: FPDFEMB_RECT
-//			Rectangle area in device or page coordination system
-//
-struct FPDFEMB_RECT
-{
-	// For device system, coordinations are measured in pixels;
-	// For page system, coordinations are measured in hundredth of points.
-	int		left;
-	int		top;
-	int		right;
-	int		bottom;
-};
-
-// Function: FPDFEMB_GetPageBBox
-//			Get displayable area (bounding box) of a page
-// Parameters:
-//			page		-	Page handle
-//			rect		-	Pointer to a structure receiving the rectangle
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_GetPageBBox(FPDFEMB_PAGE page, FPDFEMB_RECT* rect);
-
-/********************************************************************************************
-****
-****		Page Parsing
-****
-********************************************************************************************/
-
-// Function: FPDFEMB_StartParse
-//			Start parsing a page, so it can get rendered or searched
-// Parameters:
-//			page		-	Page handle
-//			text_only	-	flag for parsing texts only (used for searching)
-//			pause		-	A structure that can pause the parsing process.
-//							Or NULL if you don't want to pause the process.
-// Return Value:
-//			FPDFERR_SUCCESS: parsing successfully finished;
-//			FPDFERR_TOBECONTINUED: parsing started successfully, but not finished;
-//			FPDFERR_STATUS: page already parsed, or parsing already started. 
-//			Other return value: error code.
-// Comments:
-//			Parsing is a progressive process. This function starts the parsing process,
-//			and may return before parsing is finished, if a pause structure is provided.
-//
-//			Application should call FPDFEMB_ContinueParse repeatedly to finish the parsing
-//			when return value is FPDFERR_TOBECONTINUED.
-//
-//			There can be only one parsing procedure active for a page, and if a page
-//			has already been parsed, you can't start a parsing again.
-//
-FPDFEMB_RESULT FPDFEMB_StartParse(FPDFEMB_PAGE page, FPDFEMB_BOOL text_only, 
-												FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_ContinueParse
-//			Continue the page parsing
-// Parameters:
-//			page		-	Page handle
-//			pause		-	A structure that can pause the parsing process.
-//							Or NULL if you don't want to pause the process.
-// Return Value:
-//			FPDFERR_SUCCESS: parsing successfully finished;
-//			FPDFERR_TOBECONTINUED: parsing performed successfully, but not finished;
-//			FPDFERR_STATUS: page already parsed (or parsing not started). 
-//			Other return value: error code.
-// Comments:
-//			FPDFEMB_StartParse should be called before on the page.
-//
-//			Application should call FPDFEMB_ContinueParse repeatedly to finish the parsing
-//			when return value is FPDFERR_TOBECONTINUED.
-//
-FPDFEMB_RESULT FPDFEMB_ContinueParse(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_GetParseProgress
-//			Get an estimated parsing progress in percentage
-// Parameters:
-//			page		-	Page handle
-// Return Value:
-//			An integer between 0 and 100 (inclusive) indicating the parsing progress.
-//			The result is just a rough estimation.
-//
-int FPDFEMB_GetParseProgress(FPDFEMB_PAGE page);
-
-/********************************************************************************************
-****
-****		Page Rendering
-****
-********************************************************************************************/
-
-typedef void* FPDFEMB_BITMAP;
-
-// Function: FPDFEMB_StartQuickDraw
-//			Start drawing a quick preview of a page
-// Parameters:
-//			dib			-	DIB handle, as the rendering device
-//			page		-	Page handle. The page has to be parsed first.
-//			start_x		-	Left pixel position of the display area in the device coordination
-//			start_y		-	Top pixel position of the display area in the device coordination
-//			size_x		-	Horizontal size (in pixels) for displaying the page
-//			size_y		-	Vertical size (in pixels) for displaying the page
-//			rotate		-	Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise),
-//								2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise).
-//			flags		-	Reserved, must be zero.
-//			pause		-	Pointer to a structure that can pause the rendering process.
-//							Can be NULL if no pausing is needed.
-// Return Value:
-//			FPDFERR_SUCCESS: quickdraw successly finished;
-//			FPDFERR_TOBECONTINUED: quickdraw started successfully, but not finished.
-//							FPDFEMB_ContinueQuickDraw needs to be called to finish the quickdraw;
-//			FPDFERR_STATUS: quickdraw already in progress, or page not parsed;
-//			Other return value: error code.
-// Comments:
-//			It's often useful to present user a quick preview of a page, right after the
-//			page is parsed. This preview renders only a limited set of easy features in the
-//			page, so it'll be rather quick to finish this process.
-//
-FPDFEMB_RESULT FPDFEMB_StartQuickDraw(FPDFEMB_BITMAP dib, FPDFEMB_PAGE page,
-							int start_x, int start_y, int size_x, int size_y, int rotate,
-							int flags, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_ContinueQuickDraw
-//			Continue a quick draw processing
-// Parameters:
-//			page		-	Page handle. The page has to be parsed first.
-//			pause		-	Pointer to a structure that can pause the rendering process.
-//							Can be NULL if no pausing is needed.
-// Return Value:
-//			FPDFERR_SUCCESS: quickdraw successly finished;
-//			FPDFERR_TOBECONTINUED: quickdraw started successfully, but not finished.
-//							more calls to this function needed to finish the quickdraw;
-//			FPDFERR_STATUS: quickdraw not started yet; 
-//			Other return value: error code.
-//
-FPDFEMB_RESULT FPDFEMB_ContinueQuickDraw(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause);
-
-#define FPDFEMB_ANNOT			0x01		// Set if annotations are to be rendered
-#define FPDFEMB_LCD_TEXT		0x02		// Set if using text rendering optimized for LCD display
-#define FPDFEMB_BGR_STRIPE		0x04		// Set if the device is using BGR LCD stripe
-
-// Function: FPDFEMB_StartRender
-//			Start rendering of a page.
-// Parameter:
-//			dib			-	DIB handle, as the rendering device
-//			page		-	Page handle. The page has to be parsed first.
-//			start_x		-	Left pixel position of the display area in the device coordination
-//			start_y		-	Top pixel position of the display area in the device coordination
-//			size_x		-	Horizontal size (in pixels) for displaying the page
-//			size_y		-	Vertical size (in pixels) for displaying the page
-//			rotate		-	Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise),
-//								2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise).
-//			flags		-	0 for normal display, or combination of flags defined above
-//			clip		-	Pointer to clip rectangle (in DIB device coordinations),
-//							or NULL if no clipping needed.
-//			pause		-	Pointer to a structure that can pause the rendering process.
-//							Can be NULL if no pausing is needed.
-// Return Value:
-//			FPDFERR_SUCCESS: rendering successfully finished;
-//			FPDFERR_TOBECONTINUED: rendering started successfully, but not finished;
-//			Other return value: error code.
-// Comments:
-//			Rendering is a progressive process. This function starts the rendering process,
-//			and may return before rendering is finished, if a pause structure is provided.
-//
-//			Application should call FPDFEMB_ContinueRender repeatedly to finish the rendering 
-//			when return value is FPDFERR_TOBECONTINUED.
-//
-//			There can be only one rendering procedure for a page at any time. And rendering
-//			can be started over and over again for the same page. If a page rendering is already
-//			active, starting another one will cancel the previous rendering.
-//
-//			Rendering of a page doesn't draw the page background, therefore, you usually need
-//			to draw the background in the DIB yourself.
-//
-FPDFEMB_RESULT FPDFEMB_StartRender(FPDFEMB_BITMAP dib, FPDFEMB_PAGE page,
-						int start_x, int start_y, int size_x, int size_y, int rotate, int flags,
-						FPDFEMB_RECT* clip, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_ContinueRender
-//			Continue the page rendering
-// Parameters:
-//			page		-	Page handle
-//			pause		-	Pointer to a structure that can pause the rendering process.
-//							Can be NULL if no pausing is needed.
-// Return Value:
-//			FPDFERR_SUCCESS: rendering successfully finished.
-//			FPDFERR_TOBECONTINUED: rendering needs to be continued;
-//			Other return value: error code.
-// Comments:
-//			This function may return any time when the pause interface indicates 
-//			a pause is needed. Application can call FPDFEMB_ContinueRender any number
-//			of times, until FPDFERR_TOBECONTINUED is not returned.
-//
-FPDFEMB_RESULT FPDFEMB_ContinueRender(FPDFEMB_PAGE page, FPDFEMB_PAUSE* pause);
-
-// Function: FPDFEMB_GetRenderProgress
-//			Get an estimated rendering progress in percentage
-// Parameters:
-//			page		-	Page handle
-// Return Value:
-//			An integer between 0 and 100 (inclusive) indicating the rendering progress.
-//			The result is just a rough estimation.
-//			If the rendering just finished, this function will return 0.
-//
-int FPDFEMB_GetRenderProgress(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_SetHalftoneLimit
-//			Set pixel count limit for using halftone when display image
-// Parameter:
-//			limit		-	Number of pixels for the limit
-// Return Value:
-//			None.
-// Comments:
-//			By default, FPDFEMB displays all bitmaps using downsamping, which means
-//			if the image is shrinked onto screen, only part of pixels will be picked
-//			and displayed. This saves a lot of calculation, especially for big images
-//			with millions of pixels. However the display quality can be bad. In order to
-//			reach a balance between performance and quality, application can use this
-//			function to set a limit, if number of pixels in an image is more than this
-//			limit, then FPDFEMB will use downsampling for quick drawing, otherwise, if
-//			the image has less pixels, FPDFEMB will use halftoning for better quality.
-//
-void FPDFEMB_SetHalftoneLimit(int limit);
-
-/********************************************************************************************
-****
-****		Coordination Conversion
-****
-********************************************************************************************/
-
-// Structure: FPDFEMB_POINT
-//			A point in device or page coordination system
-//
-struct FPDFEMB_POINT
-{
-	// For device system, coordinations are measured in pixels;
-	// For page system, coordinations are measured hundredth of points.
-	int		x;
-	int		y;
-};
-
-// Function: FPDFEMB_DeviceToPagePoint, FPDFEMB_DeviceToPageRect
-//			Convert the device coordinations of a point or a rectangle to page coordinations.
-// Parameters:
-//			page		-	Handle to the page. Returned by FPDFEMB_LoadPage function.
-//			start_x		-	Left pixel position of the display area in the device coordination
-//			start_y		-	Top pixel position of the display area in the device coordination
-//			size_x		-	Horizontal size (in pixels) for displaying the page
-//			size_y		-	Vertical size (in pixels) for displaying the page
-//			rotate		-	Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise),
-//								2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise).
-//			point		-	A point structure with device coordinations upon the call,
-//							also receiving the result page coordinations.
-//			rect		-	A rectangle structure with device coordinations upon the call,
-//							also receiving the result page coordinations.
-// Return value:
-//			None.
-// Comments:
-//			The page coordination system has its origin at left-bottom corner of the page, 
-//			with X axis goes along the bottom side to the right, and Y axis goes along the 
-//			left side upward. No matter how you zoom, scroll, or rotate a page, a particular
-//			element (like text or image) on the page should always have the same coordination 
-//			values in the page coordination system. 
-//
-//			The device coordination system is device dependant. For bitmap device, its origin 
-//			is at left-top corner of the window. You must make sure the start_x, start_y, size_x, 
-//			size_y and rotate parameters have exactly same values as you used in 
-//			FPDFEMB_StartRender() function call.
-//
-//			For rectangle conversion, the result rectangle is always "normalized", meaning for
-//			page coordinations, left is always smaller than right, bottom is smaller than top.
-//
-void FPDFEMB_DeviceToPagePoint(FPDFEMB_PAGE page, 
-						int start_x, int start_y, int size_x, int size_y, int rotate, 
-						FPDFEMB_POINT* point);
-
-void FPDFEMB_DeviceToPageRect(FPDFEMB_PAGE page, 
-						int start_x, int start_y, int size_x, int size_y, int rotate, 
-						FPDFEMB_RECT* rect);
-
-// Function: FPDFEMB_PageToDevicePoint, FPDFEMB_PageToDeviceRect
-//			Convert the page coordinations of a point or a rectangle to device coordinations.
-// Parameters:
-//			page		-	Handle to the page. Returned by FPDFEMB_LoadPage function.
-//			start_x		-	Left pixel position of the display area in the device coordination
-//			start_y		-	Top pixel position of the display area in the device coordination
-//			size_x		-	Horizontal size (in pixels) for displaying the page
-//			size_y		-	Vertical size (in pixels) for displaying the page
-//			rotate		-	Page orientation: 0 (normal), 1 (rotated 90 degrees clockwise),
-//								2 (rotated 180 degrees), 3 (rotated 90 degrees counter-clockwise).
-//			point		-	A point structure with page coordinations upon the call,
-//							also receiving the result device coordinations.
-//			rect		-	A rectangle structure with page coordinations upon the call,
-//							also receiving the result device coordinations.
-// Return value:
-//			None
-// Comments:
-//			For rectangle conversion, the result rectangle is always "normalized", meaning for
-//			device coordinations, left is always smaller than right, top is smaller than bottom.
-//
-void FPDFEMB_PageToDevicePoint(FPDFEMB_PAGE page, 
-						int start_x, int start_y, int size_x, int size_y, int rotate, 
-						FPDFEMB_POINT* point);
-
-void FPDFEMB_PageToDeviceRect(FPDFEMB_PAGE page, 
-						int start_x, int start_y, int size_x, int size_y, int rotate, 
-						FPDFEMB_RECT* rect);
-
-/********************************************************************************************
-****
-****		Text Search
-****
-********************************************************************************************/
-
-// Search flags for FPDFEMB_FindFirst function
-#define FPDFEMB_MATCHCASE		1		// whether matching case
-#define FPDFEMB_MATCHWHOLEWORD	2		// whether matching whole word
-#define FPDFEMB_CONSECUTIVE		4		// whether matching consecutively (for example, "CC" will
-										// match twice in "CCC").
-
-// Function: FPDFEMB_FindFirst
-//			Find first occurance of a pattern string in a page
-// Parameters:
-//			page		-	Page handle.
-//			pattern		-	A zero-terminated unicode string to be found. 
-//			from_last	-	Whether we start from the end of page
-//			flags		-	Search flags, see above defined constants
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//			Is not found, FPDFERR_NOTFOUND is returned.
-// Comments:
-//			A page must be parsed first before it can be searched.
-//			There can be only one search in progress for a page. A new search will 
-//			cancel the previous one.
-//
-//			IMPORTANT: this function is now obsolete and kept for back compatibility
-//			only, please use FPDFEMB_FindFrom function below.
-//
-FPDFEMB_RESULT FPDFEMB_FindFirst(FPDFEMB_PAGE page, const FPDFEMB_WCHAR* pattern, 
-								 FPDFEMB_BOOL from_last, unsigned int flags);
-
-// Function: FPDFEMB_FindFrom
-//			Find first occurance of a pattern string in a page, from a particular position
-// Parameters:
-//			page		-	Page handle.
-//			pattern		-	A zero-terminated unicode string to be found. 
-//			pos			-	The position, returned from FPDFEMB_GetSearchPos.
-//							Or 0 from the beginning of page, -1 from the end of page.
-//			flags		-	Search flags, see above defined constants
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//			Is not found, FPDFERR_NOTFOUND is returned.
-// Comments:
-//			A page must be parsed first before it can be searched.
-//			There can be only one search in progress for a page. A new search will 
-//			cancel the previous one.
-//
-FPDFEMB_RESULT FPDFEMB_FindFrom(FPDFEMB_PAGE page, const FPDFEMB_WCHAR* pattern, 
-								 int pos, unsigned int flags);
-
-// Function: FPDFEMB_FindNext
-//			Find next occurance of a search
-// Parameters:
-//			page		-	Page handle. 
-//							FPDFEMB_FindFirst must be called for this page first.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//			Is not found, FPDFERR_NOTFOUND is returned.
-//
-FPDFEMB_RESULT FPDFEMB_FindNext(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_FindPrev
-//			Find previous occurance of a search
-// Parameters:
-//			page		-	Page handle.
-//							FPDFEMB_FindFirst must be called for this page first.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//			Is not found, FPDFERR_NOTFOUND is returned.
-//
-FPDFEMB_RESULT FPDFEMB_FindPrev(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_CountFoundRects
-//			Get number of rectangles for last found result
-// Parameters:
-//			page		-	Page handle.
-// Return Value:
-//			Number of rectangles for last found result. 0 for not found or failure.
-//
-int FPDFEMB_CountFoundRects(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_GetFoundRect
-//			Get a particular found rectangle
-// Parameters:
-//			page		-	Page handle.
-//			index		-	Zero-based index for the rectangle.
-//			rect		-	Receiving the result rectangle, in hundredth of points
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			Application should always call FPDFEMB_CountFoundRects first to get
-//			number of rectangles, then use this function to get each rectangle.
-//
-//			The returned rectangle uses page coordination system.
-//
-FPDFEMB_RESULT FPDFEMB_GetFoundRect(FPDFEMB_PAGE page, int index, FPDFEMB_RECT* rect);
-
-// Function: FPDFEMB_GetSearchPos
-//			Return position of current search result
-// Parameters:
-//			page		-	Page handle.
-// Return Value:
-//			Zero based character index for the current search result. -1 if not found.
-//
-int FPDFEMB_GetSearchPos(FPDFEMB_PAGE page);
-
-// Function: FPDFEMB_QuickSearch
-//			Search a pattern in a page quickly, without the page to be parsed
-// Parameters:
-//			document	-	Document handle returned by FPDFEMB_StartLoadDocument function
-//			page_index	-	Zero-based index of the page
-//			pattern		-	A zero-terminated unicode string to be found. 
-//			case_sensitive	-	Non-zero for case-sensitive searching, zero for case-insensitive
-// Return Value:
-//			FPDFERR_SUCCESS if pattern found, FPDFERR_NOTFOUND if pattern not found.
-//			Otherwise error code is returned.
-// Comments:
-//			This function does a rough and quick search in a page, before the page is loaded. 
-//			The quick search will not generate an exact result saying where the pattern is
-//			found, and, it might be possible if a quick search result is "pattern found", and
-//			a real search for the same pattern, in the same page, will result in "not found".
-//
-//			However, if quick search doesn't find a pattern in a page, then we can be sure the
-//			pattern won't be found in this page when we do a real search. So, this function is 
-//			very useful when we search in a multiple-page document, and we want to quickly skip
-//			those pages in which the pattern can't possibly be found.
-//
-FPDFEMB_RESULT FPDFEMB_QuickSearch(FPDFEMB_DOCUMENT document, int page_index, 
-								   const FPDFEMB_WCHAR* pattern, int case_sensitive);
-
-/********************************************************************************************
-****
-****		Text Information
-****
-********************************************************************************************/
-
-// Function: FPDFEMB_GetCharCount
-//			Get number of characters in the page
-// Parameters:
-//			page		-	Page handle
-//			count		-	Receiving number of characters
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_GetCharCount(FPDFEMB_PAGE page, int* count);
-
-// Structure: FPDFEMB_CHAR_INFO
-//			Character information.
-struct FPDFEMB_CHAR_INFO {
-	int		unicode;		// Unicode for the character. 0 if not available.
-							// Space and new line charcters (U+0020 and U+000A) may be generated
-							// according to the text formatting.
-	FPDFEMB_POINT	origin;	// X/Y position for the character origin, in hundredth of points
-	FPDFEMB_RECT	bbox;	// Bounding box of the character, in hundredth of points
-							// Maybe an empty box (left == right or top == bottom).
-};
-
-// Function: FPDFEMB_GetCharInfo
-//			Get character information
-// Parameters:
-//			page		-	Page handle
-//			index		-	Character index, starting from zero
-//			char_info	-	Receiving the character info
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			Application must call FPDFEMB_GetCharCount first before it can call this function
-//			for any particular characters.
-//			
-FPDFEMB_RESULT FPDFEMB_GetCharInfo(FPDFEMB_PAGE page, int index, FPDFEMB_CHAR_INFO* char_info);
-
-// Function: FPDFEMB_GetCharIndexAtPos()
-//			Get index of character nearest to a certain position on the page
-// Parameters:
-//			page		-	Page handle
-//			x			-	X position in PDF page coordination system
-//			y			-	Y position in PDF page coordination system
-//			index		-	Pointer to an integer receiving zero-based character index.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			This function finds the character that's nearest to the particular page position.
-//			If there is no character, the output index will be -1.
-//			
-FPDFEMB_RESULT FPDFEMB_GetCharIndexAtPos(FPDFEMB_PAGE page, double x, double y, int* index);
-
-/********************************************************************************************
-****
-****		Device Independant Bitmap
-****
-********************************************************************************************/
-
-#define FPDFDIB_BGR		1	// 3 bytes per pixel, byte order: Blue, Green, Red
-#define FPDFDIB_BGRx	2	// 4 bytes per pixel, byte order: Blue, Green, Red, not used
-#define FPDFDIB_BGRA	3	// 4 bytes per pixel, byte order: Blue, Green, Red, Alpha
-#define FPDFDIB_GRAY	4	// 1 byte per pixel (grayscale)
-
-// Function: FPDFEMB_CreateDIB
-//			Create a DIB (Device Independant Bitmap)
-// Parameters:
-//			width		-	Width pixels;
-//			height		-	Height pixels;
-//			format		-	Format type. See FPDFDIB_xxx constants
-//			buffer		-	External buffer provided for the DIB,
-//							or NULL if new buffer is to be allocated.
-//			stride		-	Number of bytes for each scan line, for external buffer only.
-//							If not specified, 4-byte alignment assumed.
-//			dib			-	Receiving the created DIB handle
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			If "buffer" parameter is not NULL, then the provided buffer must conform
-//			to standard DIB format (see comments of FPDFEMB_GetDIBData function below).
-//
-//			This function doesn't initialize the pixels inside the DIB buffer. So if you
-//			want to use the DIB to display a PDF page, you usually need to initialize
-//			the DIB to white background by youself.
-//
-FPDFEMB_RESULT FPDFEMB_CreateDIB(int width, int height, int format, 
-									   void* buffer, int stride, FPDFEMB_BITMAP* dib);
-
-// Function: FPDFEMB_DestroyDIB
-//			Destroy a DIB
-// Parameters:
-//			dib			-	DIB handle
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			If external buffer is used (specified in "buffer" parameter when calling
-//			FPDFEMB_CreateDIB), the buffer will not be destroyed.
-//
-FPDFEMB_RESULT FPDFEMB_DestroyDIB(FPDFEMB_BITMAP dib);
-
-// Function: FPDFEMB_GetDIBWidth
-//			Get width (in pixels) of a DIB
-// Parameters:
-//			dib			-	DIB handle
-// Return Value:
-//			DIB width in pixels.
-//
-int FPDFEMB_GetDIBWidth(FPDFEMB_BITMAP dib);
-
-// Function: FPDFEMB_GetDIBHeight
-//			Get height (in pixels) of a DIB
-// Parameters:
-//			dib			-	DIB handle
-// Return Value:
-//			DIB height in pixels.
-//
-int FPDFEMB_GetDIBHeight(FPDFEMB_BITMAP dib);
-
-// Function: FPDFEMB_GetDIBData
-//			Get data pointer to a DIB
-// Parameters:
-//			dib			-	DIB handle
-// Return Value:
-//			Pointer to the DIB data.
-// Comments:
-//			DIB data are organized in scanlines, from top down.
-//
-void* FPDFEMB_GetDIBData(FPDFEMB_BITMAP dib);
-
-// Function: FPDFEMB_GetDIBStride
-//			Get scan line stride of a DIB
-// Parameters:
-//			dib			-	DIB handle
-// Return Value:
-//			Number of bytes occupied by a scanline
-//
-int FPDFEMB_GetDIBStride(FPDFEMB_BITMAP dib);
-
-// Function: FPDFEMB_GetRotatedDIB
-//			Swap X/Y dimensions of a DIB to generate a rotated new DIB
-// Parameters:
-//			dib			-	DIB handle
-//			flip_x		-	Whether flip pixels on the destination X dimension (left/right)
-//			flip_y		-	Whether flip pixels on the destination Y dimension (up/down)
-//			result_dib	-	Receiving the result DIB handle
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_GetRotatedDIB(FPDFEMB_BITMAP dib, 
-									 FPDFEMB_BOOL bFlipX, FPDFEMB_BOOL bFlipY,
-									 FPDFEMB_BITMAP* result_dib);
-
-// Function: FPDFEMB_StretchDIB
-//			Stretch a source DIB into another destination DIB
-// Parameters:
-//			dest_dib	-	The destination DIB handle
-//			dest_left	-	Left position in the destination DIB
-//			dest_top	-	Top position in the destination DIB
-//			dest_width	-	Destination width, in pixels. Can be negative for horizontal flipping
-//			dest_height	-	Destination height, in pixels. Can be negative for vertical flipping
-//			clip		-	Destination clipping rectangle, or NULL for no clipping.
-//							The coordinations are measured in destination bitmap.
-//			src_dib		-	Source DIB handle.
-//			interpol	-	Whether we use interpolation to improve the result quality
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_StretchDIB(FPDFEMB_BITMAP dest_dib, int dest_left, int dest_top,
-								  int dest_width, int dest_height, FPDFEMB_RECT* clip_rect, 
-								  FPDFEMB_BITMAP src_dib, FPDFEMB_BOOL interpol);
-
-// Function: FPDFEMB_TransformDIB
-//			Transform a source DIB into another destination DIB
-// Parameters:
-//			dest_dib	-	The destination DIB handle
-//			clip		-	Destination clipping rectangle, or NULL for no clipping.
-//							The coordinations are measured in destination bitmap.
-//			src_dib		-	Source DIB handle.
-//			x			-	X coordination of the dest origin
-//			y			-	Y coordination of the dest origin
-//			xx			-	X distance of the dest X vector
-//			yx			-	Y distance of the dest X vector
-//			xy			-	X distance of the dest Y vector
-//			yy			-	Y distance of the dest Y vector
-//			interpol	-	Whether we use interpolation to improve the result quality
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			All coordinations and distances are measured in destination bitmap system.
-//
-//			This function places the bottom-left pixel of the image at the destination
-//			origin, then the bottom sideline along the destination X vector, and left 
-//			sideline along the destination Y vector.
-//			
-FPDFEMB_RESULT FPDFEMB_TransformDIB(FPDFEMB_BITMAP dest_dib, FPDFEMB_RECT* clip_rect, 
-								  FPDFEMB_BITMAP src_dib, int x, int y, int xx, int yx,
-								  int xy, int yy, FPDFEMB_BOOL interpol);
-
-/********************************************************************************************
-****
-****		Custom Font Handler and CJK Support
-****
-********************************************************************************************/
-
-// FPDFEMB comes with standard fonts for Latin characters. If your device is targeted to
-// Eastern Asian markets, then system fonts must be provided and registered with FPDFEMB.
-// Depending on your device configuration, those system fonts might be in TrueType or Type1
-// format, or some other non-standard compact format. For the first case, you should register
-// a font mapper so FPDFEMB can pick the right font file, and for the second case, you
-// should register a glyph provider so FPDFEMB can get glyph bitmap for each character.
-
-#define FPDFEMB_CHARSET_DEFAULT		0
-#define FPDFEMB_CHARSET_GB			936
-#define FPDFEMB_CHARSET_BIG5		950
-#define FPDFEMB_CHARSET_JIS			932
-#define FPDFEMB_CHARSET_KOREA		949
-#define FPDFEMB_CHARSET_UNICODE		1200
-
-#define FPDFEMB_FONT_FIXEDPITCH		1
-#define FPDFEMB_FONT_SERIF			2
-#define FPDFEMB_FONT_SYMBOLIC		4
-#define FPDFEMB_FONT_SCRIPT			8
-#define FPDFEMB_FONT_NONSYMBOLIC	32
-#define FPDFEMB_FONT_ITALIC			64
-#define FPDFEMB_FONT_ALLCAP			0x10000
-#define FPDFEMB_FONT_SMALLCAP		0x20000
-#define FPDFEMB_FONT_FORCEBOLD		0x40000
-
-// Structure: FPDFEMB_FONT_MAPPER
-//			Defines interface for system font mapper.
-//
-struct FPDFEMB_FONT_MAPPER
-{
-	// Interface: MapFont
-	//		Find font file path for a particular PDF font
-	// Parameters:
-	//		mapper		-	Pointer to the FPDFEMB_FONT_MAPPER structure
-	//		name		-	Font name
-	//		charset		-	Charset ID (see above FPDFEMB_CHARSET_xxx constants)
-	//		flags		-	Font flags (see above FPDFEMB_FONT_xxx constants)
-	//		weight		-	Weight of the font. Range from 100 to 900. 400 is normal,
-	//						700 is bold.
-	//		path		-	Receiving the full file path. The buffer size is 512 bytes.
-	//		face_index	-	Receiving an zero-based index value for the font face, if the 
-	//						mapped font file is a "collection" (meaning a number of faces 
-	//						are stored in the same file). If the font file is not a 
-	//						collection, the index value should be zero.
-	// Return Value:
-	//		Non-zero for success, 0 for failure.
-	//
-	FPDFEMB_BOOL	(*MapFont)(struct FPDFEMB_FONT_MAPPER* mapper, const char* name, int charset,
-									unsigned int flags,	int weight,
-									char* path, int* face_index);
-
-	void*		user;		// A user pointer, used by the application
-};
-
-// Function: FPDFEMB_SetFontMapper
-//			Use a system font mapper (typically for Chinese/Japanese/Korean charsets)
-// Parameters:
-//			mapper		-	Pointer to FPDFEMB_FONT_MAPPER structure.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			This function is used with devices that come with one or more system fonts,
-//			and those fonts are in standard TT or T1 format.
-//
-FPDFEMB_RESULT FPDFEMB_SetFontMapper(FPDFEMB_FONT_MAPPER* mapper);
-
-// Structure: FPDFEMB_GLYPH_PROVIDER
-//			Interface for providing glyph bitmap of non-latin characters.
-//			This is usually used for embedded devices with Chinese/Japanese/Korean 
-//			fonts installed, but those fonts are not in TrueType or Type1 format.
-//
-struct FPDFEMB_GLYPH_PROVIDER
-{
-	// Interface: MapFont
-	//		Return an internal handle for a font
-	// Parameters:
-	//		provider	-	Pointer to this structure
-	//		name		-	Font name
-	//		charset		-	Charset ID (see above FPDFEMB_CHARSET_xxx constants)
-	//		flags		-	Font flags (see above FPDFEMB_FONT_xxx constants)
-	//		weight		-	Weight of the font. Range from 100 to 900. 400 is normal,
-	//						700 is bold.
-	// Return Value:
-	//		An internal handle to the mapped font. If the embedded device supports
-	//		multiple fonts, then this value can serve as an identifier to differentiate
-	//		among them. If the device supports only one font, then implementation of
-	//		this function can simply return NULL.
-	//
-	void*	(*MapFont)(struct FPDFEMB_GLYPH_PROVIDER* provider, const char* name, int charset,
-									unsigned int flags,	int weight);
-	// Interface: GetGlyphBBox
-	//		Get glyph bounding box
-	// Parameters:
-	//		provider	-	Pointer to this structure
-	//		font		-	Internal handle to the font. Returned by MapFont interface.
-	//		unicode		-	Unicode of the character
-	//		CID			-	Adobe CID for this character. Or zero if not available.
-	//		bbox		-	Receiving the result bounding box. See comments below.
-	// Return Value:
-	//		None.
-	// Comments:
-	//		The bounding box is measure in a glyph coordination system, in which the
-	//		origin is set to character origin, and unit is set to one-thousandth of
-	//		"em size" (representing the font size).
-	//
-	//		In most CJK fonts, all CJK characters (except some symbols or western 
-	//		characters) have same glyph bounding box:
-	//		left = 0, right = 1000, bottom = -220, top = 780.
-	//
-	//		It's OK to return a box that's larger than the actual glyph box.
-	//
-	void	(*GetGlyphBBox)(struct FPDFEMB_GLYPH_PROVIDER* provider, void* font,
-									FPDFEMB_WCHAR unicode, unsigned short CID,
-									FPDFEMB_RECT* bbox);
-
-	// Interface: GetGlyphBitmap
-	//		Get bitmap of a glyph
-	// Parameters:
-	//		provider	-	Pointer to this structure
-	//		font		-	Internal handle to the font. Returned by MapFont interface.
-	//		unicode		-	Unicode of the character
-	//		CID			-	Adobe CID for this character. Or zero if not available.
-	//		font_width	-	Width of the font em square, measured in device units.
-	//		font_height	-	Height of the font em square, measured in device units.
-	//		left		-	Receiving the left offset, from the character origin, of the
-	//						result glyph bitmap. Positive value will move the bitmap to
-	//						the right side, negative to the left.
-	//		top			-	Receiving the top offset, from the character origin, of the
-	//						result glyph bitmap. Positive value will move the bitmap upward,
-	//						negative downward.
-	//		bitmap_width -	Receiving number of width pixels in the result bitmap
-	//		bitmap_height -	Receiving number of height pixels in the result bitmap
-	//		buffer		-	Receiving a data buffer pointer, allocated by the implementation.
-	//						See comments below.
-	//		stride		-	Receiving number of bytes per scanline, in the data buffer.
-	//		pdf_width	-	Width of the character specified in PDF. It is measured in one-
-	//						thousandth of the font width. It can be 0 if width not specified
-	//						in PDF. See comments below.
-	// Return Value:
-	//		Non-zero for success. 0 for failure. In this case the glyph can not be displayed.
-	// Comments:
-	//		The buffer should be allocated by implemenation. And it must be allocated
-	//		using FPDFEMB_AllocMemory function. The result buffer will be destroyed by
-	//		FPDFEMB SDK, so implementation should not destroy it.
-	//
-	//		The implementation should write "coverage" data into allocated buffer, one byte 
-	//		for each pixel, from top scanline to bottom scanline, within each scan line, 
-	//		from left pixel to right. Coverage 0 means the pixel is outside the glyph, 
-	//		coverage 255 means the pixel is inside the glyph.
-	//
-	//		The "pdf_width" parameter can be used to scale the character in system font
-	//		horizontally to match the font width specified in PDF. For example, if we have
-	//		a PDF file which requires a character in half-width (pdf_width is 500), but
-	//		in the system font the character has full-width (1000), then the glyph provider
-	//		implementation should scale the font horizontally to half of its original width.
-	//
-	FPDFEMB_BOOL (*GetGlyphBitmap)(struct FPDFEMB_GLYPH_PROVIDER* provider, void* font,
-									FPDFEMB_WCHAR unicode, unsigned short CID,
-									double font_width, double font_height, int* left, int* top,
-									int* bitmap_width, int* bitmap_height, 
-									void** buffer, int* stride, int pdf_width);
-
-	void*		user;		// A user pointer, used by the application
-};
-
-// Function: FPDFEMB_SetGlyphProvider
-//			Make use of a glyph provider: generating glyph bitmap for non-Latin characters
-// Parameters:
-//			provider	-	Pointer to the glyph provider structure.
-//							This structure must stay valid throughout usage of FPDFEMB module.
-// Return Value:
-//			None.
-// Comments:
-//			FPDFEMB embeds some standard fonts for Latin characters and symbols, like
-//			Times, Courier and Helvetica (Arial). For non-Latin characters, however,
-//			FPDFEMB has to ask glyph provide for help.
-//
-//			If an embedded device carries fonts for non-Latin character sets, especially
-//			those for CJK markets, then the application can implement a glyph provider,
-//			allowing PDFs using non-embedded CJK fonts to be properly displayed.
-//
-void FPDFEMB_SetGlyphProvider(FPDFEMB_GLYPH_PROVIDER* provider);
-
-// Function: FPDFEMB_LoadCMap_GB
-// Function: FPDFEMB_LoadCMap_GB_Ext
-// Function: FPDFEMB_LoadCMap_CNS
-// Function: FPDFEMB_LoadCMap_Korean
-// Function: FPDFEMB_LoadCMap_Japan
-// Function: FPDFEMB_LoadCMap_Japan_Ext
-//			Make use of character encoding maps embedded with FPDFEMB
-// Parameters:
-//			None.
-// Return Value:
-//			None.
-// Comments:
-//			These functions add character encoding data to your application. Each call
-//			will increase the code size of your application. Total data size for all
-//			character sets is 151K bytes.
-void FPDFEMB_LoadCMap_GB();
-void FPDFEMB_LoadCMap_GB_Ext();		// Load full code table for GB
-void FPDFEMB_LoadCMap_CNS();
-void FPDFEMB_LoadCMap_Korea();
-void FPDFEMB_LoadCMap_Japan();
-void FPDFEMB_LoadCMap_Japan_Ext();	// Load full code table for Japan
-
-/********************************************************************************************
-****
-****		Document Information
-****
-********************************************************************************************/
-
-// Function: PDFEMB_GetDocInfoString
-//			Get information string about the document, like creator, modifcation date, etc.
-// Parameters:
-//			document	-	Handle to the document
-//			key			-	A byte string for the information key. Currently can be one of the followings:
-//							"Title", "Author", "Subject", "Keywords", "Creator", "Producer", "CreationDate",
-//							"ModDate", or some custom information key, if supported by the PDF file.
-//			buffer		-	A buffer allocated by the application, or NULL.
-//			bufsize		-	[IN/OUT] A pointer to a number indicating the buffer size (number of bytes),
-//							before this function call. After return, this place will store
-//							number of bytes used by the output (including terminator).
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			The string is output in Unicode, using UTF-16LE format. It's terminated by
-//			two consecutive zero bytes.
-//
-//			If the "buffer" parameter is NULL, then the "bufsize" parameter will receive
-//			number of bytes required to store the string (including the two-byte terminator).
-//
-FPDFEMB_RESULT FPDFEMB_GetDocInfoString(FPDFEMB_DOCUMENT document, const char* key, void* buffer, unsigned int* bufsize);
-
-/********************************************************************************************
-****
-****		Action (Destination) Information
-****
-********************************************************************************************/
-
-typedef void* FPDFEMB_ACTION;
-
-// Action types supported by FPDFEMB
-#define FPDFEMB_DEST_NONE			0		// No or unsupported destination
-#define FPDFEMB_DEST_PAGE			1		// A page inside the same document
-#define FPDFEMB_DEST_DOC			2		// An external PDF document
-#define FPDFEMB_DEST_URL			3		// An external URL
-#define FPDFEMB_ACTION_LAUNCH		4		// Launch an external file or command
-
-// Zoom mode for destination
-#define FPDFEMB_ZOOM_NONE			0		// Zoom mode not specified
-#define FPDFEMB_ZOOM_FACTOR			1		// Specific zoom factor is used
-#define FPDFEMB_ZOOM_FITPAGE		2		// Fit the whole page on screen
-#define FPDFEMB_ZOOM_FITWIDTH		3		// Fit width of the page on screen
-#define FPDFEMB_ZOOM_FITHEIGHT		4		// Fit height of the page on screen
-#define FPDFEMB_ZOOM_FITRECT		5		// Fit a particular rectangle on screen
-#define FPDFEMB_ZOOM_FITCONTENT		6		// Fit whole content of page on screen
-#define FPDFEMB_ZOOM_FITCONTENTW	7		// Fit content width of page on screen
-#define FPDFEMB_ZOOM_FITCONTENTH	8		// Fit content height of page on screen
-
-// Data structure for page destination
-struct FPDFEMB_PAGEDEST
-{
-	int				page_index;		// Zero based index for the page
-	int				zoom_mode;		// See FPDFEMB_ZOOM_xxx definition above
-	int				zoom_factor;	// For FPDFEMB_ZOOM_FACTOR only: the zoom factor (in percentage)
-	FPDFEMB_RECT	position;		// Specify position inside the page. Depends on the zoom mode,
-									// different members of the rectangle are used:
-									// FPDFEMB_ZOOM_NONE:			left, top
-									// FPDFEMB_ZOOM_FACTOR:			left, top
-									// FPDFEMB_ZOOM_FITPAGE:		none
-									// FPDFEMB_ZOOM_FITWIDTH:		top
-									// FPDFEMB_ZOOM_FITHEIGHT:		left
-									// FPDFEMB_ZOOM_FITRECT:		left, top, bottom, right
-									// FPDFEMB_ZOOM_FITCONTENT:		none
-									// FPDFEMB_ZOOM_FITCONTENTW:	top
-									// FPDFEMB_ZOOM_FITCONTENTH:	left
-};
-
-// Data structure for document destination
-struct FPDFEMB_DOCDEST
-{
-	FPDFEMB_PAGEDEST	page_data;	// page data
-	char*				file_name;	// The file name, encoded in original charset (maybe MBCS)
-};
-
-// Data structure for URL destination
-struct FPDFEMB_URLDEST
-{
-	char*				url;		// URL encoded in 7-bit ASCII
-};
-
-// Data structure for Launch action
-struct FPDFEMB_LAUNCHACTION
-{
-	int					new_window;	// Whether a new window should be opened
-	char*				file_name;	// The file name, encoded in original charset (maybe MBCS)
-};
-
-// Function: FPDFEMB_Action_GetType
-//			Get type of an action
-// Parameters:
-//			document	-	Handle to the document
-//			action		-	Handle to the action
-//			dest_type	-	Pointer to an integer receiving type of the destination. See the above
-//							FPDFEMB_DEST_xxx definitions
-//			data_size	-	Pointer to an integer receiving data block size for the destination.
-//							If this parameter is NULL, then data size won't be retrieved.
-// Comments:
-//			Each different type of destination has different data structure. The "data_size" result
-//			indicates how many bytes is required to hold the destination data structure. The application
-//			can then allocate sufficient buffer and then call FPDFEMB_Bookmark_GetDest function to
-//			get the real data.
-//
-FPDFEMB_RESULT FPDFEMB_Action_GetType(FPDFEMB_DOCUMENT document, FPDFEMB_ACTION action, int* dest_type, int* data_size);
-
-// Function: FPDFEMB_Action_GetData
-//			Get detailed data of a particular action
-// Parameters:
-//			document	-	Handle to the document
-//			action		-	Handle to the action
-//			buffer		-	Application allocated buffer receiving the destination data
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			See data structure definition for different action type above. Please note
-//			the actual action data might use more space than the structure definition
-//			shows, to store things like file name or URL. So you should always call
-//			FPDFEMB_Action_GetType first to get data size then allocate enough buffer
-//			for this call.
-//
-FPDFEMB_RESULT FPDFEMB_Action_GetData(FPDFEMB_DOCUMENT document, FPDFEMB_ACTION action, void* buffer);
-
-// Function: FPDFEMB_Action_GetNext
-//			Get next action in an action chain
-// Parameters:
-//			document	-	Handle to the document
-//			action		-	Handle to current action
-//			next		-	Receiving handle to next action.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			If there is no next action, the "next" parameter will be set to NULL after the function returns.
-//
-FPDFEMB_RESULT FPDFEMB_Action_GetNext(FPDFEMB_ACTION action, FPDFEMB_ACTION* next);
-
-/********************************************************************************************
-****
-****		Bookmark Information
-****
-********************************************************************************************/
-
-typedef void* FPDFEMB_BOOKMARK;
-
-// Function: FPDFEMB_Bookmark_GetFirstChild
-//			Get first child of a bookmark item, or first top level bookmark item
-// Parameters: 
-//			document	-	Handle to the document
-//			parent		-	Handle to the parent bookmark. 
-//							Can be NULL if you want to get the first top level item.
-//			bookmark	-	Receiving handle to the first child or top level bookmark item. 
-//							If result is NULL, then bookmark not found.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_Bookmark_GetFirstChild(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK parent,
-											  FPDFEMB_BOOKMARK* bookmark);
-
-// Function: FPDFEMB_Bookmark_GetFirstChild
-//			Get next sibling of a bookmark item
-// Parameters: 
-//			document	-	Handle to the document
-//			bookmark	-	Handle to the bookmark 
-//			sibling		-	Receiving the handle of next sibling.
-//							If result is NULL, then this is the last bookmark in this level.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-//
-FPDFEMB_RESULT FPDFEMB_Bookmark_GetNextSibling(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark,
-											  FPDFEMB_BOOKMARK* sibling);
-
-// Function: FPDFEMB_Bookmark_GetTitle
-//			Get title of a bookmark
-// Parameters: 
-//			bookmark	-	Handle to the bookmark 
-//			buffer		-	A buffer allocated by the application, or NULL.
-//			bufsize		-	[IN/OUT] A pointer to a number indicating the buffer size,
-//							before this function call. After return, this place will store
-//							number of bytes used by the output (including terminator).
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			The title is output in Unicode, using UTF-16LE format. It's terminated by
-//			two consecutive zero bytes.
-//
-//			If the "buffer" parameter is NULL, then the "bufsize" parameter will receive
-//			number of bytes required to store the bookmark title (including the two-
-//			byte terminator).
-//
-//			If the buffer provided is smaller than the required size, then this function
-//			will not copy any data, return FPDFEMB_PARAM, and the required buffer size will 
-//			also be put in "bufsize" parameter.
-//
-FPDFEMB_RESULT FPDFEMB_Bookmark_GetTitle(FPDFEMB_BOOKMARK bookmark, void* buffer, unsigned int* bufsize);
-
-// Function: FPDFEMB_Bookmark_GetPage
-//			Get page number of a bookmark pointing to
-// Parameters:
-//			document	-	Handle to the document
-//			bookmark	-	Handle to the bookmark 
-//			page		-	Receiving the page number. -1 if this bookmark doesn't actually
-//							point to a page inside the document.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success
-// Comments:
-//			Some bookmark might not point to a page, some bookmark might have more than one destination
-//			(action), for detailed information about a bookmark, you should call FPDFEMB_Bookmark_GetAction.
-//
-FPDFEMB_RESULT FPDFEMB_Bookmark_GetPage(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark, int* page);
-
-// Function: FPDFEMB_Bookmark_GetAction
-//			Get action(s) associated with a particular bookmark
-// Parameters:
-//			document	-	Handle to the document
-//			bookmark	-	Handle to the bookmark 
-//			action		-	Receiving handle of first action
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_Bookmark_GetAction(FPDFEMB_DOCUMENT document, FPDFEMB_BOOKMARK bookmark, FPDFEMB_ACTION* action);
-
-/********************************************************************************************
-****
-****		Hyperlink Information
-****
-********************************************************************************************/
-
-// Function: FPDFEMB_Link_GetCount
-//			Get number of hyperlinks inside a page
-// Parameters:
-//			page		-	Page handle.
-//			link_count	-	Pointer to an integer receiving the number of links
-//			reserved	-	Must be zero now.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			This function must be called before any other link related function can
-//			be called for the page.
-//
-FPDFEMB_RESULT FPDFEMB_Link_GetCount(FPDFEMB_PAGE page, int* link_count, int reserved);
-
-// Function: FPDFEMB_Link_GetAction
-//			Get action(s) associated with a particular hyperlink
-// Parameters:
-//			page		-	Page handle
-//			link_index	-	Zero-based index for the link
-//			action		-	Receiving handle of first action
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_Link_GetAction(FPDFEMB_PAGE page, int link_index, FPDFEMB_ACTION* action);
-
-// Function: FPDFEMB_Link_GetAreaCount
-//			Get number of area (quadrilaterals) for a link
-// Parameters:
-//			page		-	Page handle
-//			link_index	-	Zero-based index for the link
-//			count		-	Pointer to an integer receiving number of quadrilaterals
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_Link_GetAreaCount(FPDFEMB_PAGE page, int link_index, int* count);
-
-// Function: FPDFEMB_Link_GetArea
-//			Get a particular quadrilateral for a link
-// Parameters:
-//			page		-	Page handle
-//			link_index	-	Zero-based index for the link
-//			area_index	-	Zero-based index for the quadrilateral
-//			points		-	Pointer to an array consists 4 points, receiving coordinations
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			The result in "points" array are the X/Y coordinations for the four vertices
-//			of the quadrilateral. Vertices are in the following order: lower left, lower
-//			right, upper right, upper left.
-//
-FPDFEMB_RESULT FPDFEMB_Link_GetArea(FPDFEMB_PAGE page, int link_index, int area_index, 
-									FPDFEMB_POINT* points);
-
-/********************************************************************************************
-****
-****		Graphic Output (onto DIB)
-****
-********************************************************************************************/
-
-typedef void* FPDFEMB_FONT;
-
-// Function: FPDFEMB_OpenStandardFont
-//			Get ready to use a standard PDF font
-// Parameters:
-//			font_name	-	Name of the font. See a list of supported fonts below.
-//			font_handle	-	Receiving the font handle.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			Currently supported standard fonts:
-//			Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
-//			Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
-//			Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic,
-//			Symbol, ZapfDingbats.
-//
-FPDFEMB_RESULT FPDFEMB_OpenStandardFont(const char* font_name, FPDFEMB_FONT* font_handle);
-
-// Function: FPDFEMB_OpenSystemFont
-//			Get ready to use a system font
-// Parameters:
-//			font_name	-	Font name
-//			charset		-	Charset ID (see above FPDFEMB_CHARSET_xxx constants)
-//			flags		-	Font flags (see above FPDFEMB_FONT_xxx constants)
-//			weight		-	Weight of the font. Range from 100 to 900. 400 is normal,
-//							700 is bold.
-//			font_handle	-	Receiving the font handle.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-// Comments:
-//			System font is supported only if either FPDFEMB_SetFontMapper or
-//			FPDFEMB_SetGlyphProvider is called.
-//			Font attributes (name, charset, flags and weight) can be all optional, if the
-//			font mapper or glyph provider doesn't make use of them.
-//
-FPDFEMB_RESULT FPDFEMB_OpenSystemFont(const char* font_name, int charset, unsigned int flags, int weight,
-									  FPDFEMB_FONT* font_handle);
-
-// Function: FPDFEMB_CloseFont
-//			Close a font handle.
-// Parameters:
-//			font_handle	-	Handle to the font.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_CloseFont(FPDFEMB_FONT font_handle);
-
-struct FPDFEMB_TEXTMATRIX
-{
-	double	a, b, c, d;
-};
-
-// Function: FPDFEMB_OutputText
-//			Output text string onto a DIB device.
-// Parameters:
-//			dib			-	DIB handle, as the output device
-//			x, y		-	DIB coordinations for the origin point of the first character.
-//			font_handle	-	Handle to the font
-//			font_size	-	Font size in pixels
-//			matrix		-	Matrix for the text output. Can be NULL.
-//			text		-	Zero-terminated unicode text string
-//			argb		-	Color of the text, in 0xaarrggbb format.
-// Return Value:
-//			Error code, or FPDFERR_SUCCESS for success.
-//
-FPDFEMB_RESULT FPDFEMB_OutputText(FPDFEMB_BITMAP dib, int x, int y, FPDFEMB_FONT font_handle, double font_size,
-								  FPDFEMB_TEXTMATRIX* matrix, const FPDFEMB_WCHAR* text, unsigned long argb);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif	// #ifdef _FPDFEMB_H_
diff --git a/src/images/fpdfemb_ext.h b/src/images/fpdfemb_ext.h
deleted file mode 100644
index d82c4df..0000000
--- a/src/images/fpdfemb_ext.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Extended interfaces for JPEG, JPEG2000 and JBIG2 decoders **/
-typedef struct
-{
-	/** Initialize the decoding context, with memory allocator provided by FPDFEMB.
-	   Implementation should return a pointer to the decoding context.
-	*/
-	void*	(*Init)(void* (*alloc_func)(unsigned int), void (*free_func)(void*));
-
-	/** Finish with the decoding. */
-	void	(*Finish)(void* pContext);
-
-	/** Input JPEG encoded data from the source.
-		This function may be called multiple times during decoding progress.
-	*/
-	void	(*Input)(void* pContext, const unsigned char* src_buf, unsigned long src_size);
-
-	/** Read the header information. Return non-zero for success, 0 for failure */
-	int		(*ReadHeader)(void* pContext);
-
-	/** Get info from the decoder, including image width, height and number of components */
-	void	(*GetInfo)(void* pContext, int* width, int* height, int* nComps);
-
-	/** Read one scanline from decoded image */
-	int		(*ReadScanline)(void* pContext, unsigned char* dest_buf);
-
-	/** Get number of available source bytes left in the input stream */
-	unsigned long	(*GetAvailInput)(void* pContext);
-} FPDFEMB_JPEG_DECODER;
-
-void FPDFEMB_SetJpegDecoder(FPDFEMB_JPEG_DECODER* pDecoder);
-
-typedef struct 
-{
-	/** Initialize the decoder with the full source data.
-		Implementation should return a pointer to the context.
-	*/
-	void*	(*Init)(const unsigned char* src_buf, unsigned long src_size);
-
-	/** Destroy the context */
-	void	(*Finish)(void* context);
-
-	/** Get image info from the context, including width, height, number of components
-		in original codestream, and number of components in output image. For some
-		particular type of encoded image, like paletted image, these two numbers of 
-		components may vary.
-	*/
-	void	(*GetInfo)(void* context, unsigned long* width, unsigned long* height, 
-				unsigned long* codestream_nComps, unsigned long* output_nComps);
-
-	/** Do the real data decoding, output to a pre-allocated buffer.
-		bTranslateColor indicates whether the decoder should use JPEG2000 embedded
-		color space info to translate image into sRGB color space.
-		"offsets" array describes the byte order of all components. For example,
-		{2,1,0} means the first components is output to last byte.
-	*/
-	void	(*Decode)(void* context, unsigned char* dest_buf, int pitch, 
-				int bTranslateColor, unsigned char* offsets);
-} FPDFEMB_JPEG2000_DECODER;
-
-void FPDFEMB_SetJpeg2000Decoder(FPDFEMB_JPEG2000_DECODER* pDecoder);
-
-typedef struct
-{
-	/** Do the whole decoding process. Supplied parameters include width, height, source image
-		data and size, global data and size (can be shared among different images), destination
-		buffer and scanline pitch in dest buffer.
-	*/
-	void	(*Decode)(unsigned long width, unsigned long height, const unsigned char* src_buf,
-				unsigned long src_size, const unsigned char* global_buf, unsigned long global_size, 
-				unsigned char* dest_buf, int dest_pitch);
-} FPDFEMB_JBIG2_DECODER;
-
-void FPDFEMB_SetJbig2Decoder(FPDFEMB_JBIG2_DECODER* pDecoder);
-
-#ifdef __cplusplus
-};
-#endif
diff --git a/src/opts/SkBlitRow_opts_SSE2.cpp b/src/opts/SkBlitRow_opts_SSE2.cpp
index 244dbb4..4f69fdd 100644
--- a/src/opts/SkBlitRow_opts_SSE2.cpp
+++ b/src/opts/SkBlitRow_opts_SSE2.cpp
@@ -2,16 +2,16 @@
  **
  ** Copyright 2009, The Android Open Source Project
  **
- ** Licensed under the Apache License, Version 2.0 (the "License"); 
- ** you may not use this file except in compliance with the License. 
- ** You may obtain a copy of the License at 
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
  **
- **     http://www.apache.org/licenses/LICENSE-2.0 
+ **     http://www.apache.org/licenses/LICENSE-2.0
  **
- ** Unless required by applicable law or agreed to in writing, software 
- ** distributed under the License is distributed on an "AS IS" BASIS, 
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- ** See the License for the specific language governing permissions and 
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
  ** limitations under the License.
  */
 
@@ -354,7 +354,7 @@
 
                 // Get red and blue pixels into lower byte of each word.
                 __m128i src_rb = _mm_and_si128(rb_mask, src_pixel);
-    
+
                 // Get alpha and green into lower byte of each word.
                 __m128i src_ag = _mm_srli_epi16(src_pixel, 8);
 
@@ -387,6 +387,105 @@
             src += 1;
             dst += 1;
             count--;
-        } 
+        }
     }
 }
+
+void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB,
+                            SkBitmap::Config dstConfig, const uint8_t* mask,
+                            size_t maskRB, SkColor origColor,
+                            int width, int height)
+{
+    SkPMColor color = SkPreMultiplyColor(origColor);
+    size_t dstOffset = dstRB - (width << 2);
+    size_t maskOffset = maskRB - width;
+    SkPMColor* dst = (SkPMColor *)device;
+    do {
+        int count = width;
+        if (count >= 4) {
+            while (((size_t)dst & 0x0F) != 0 && (count > 0)) {
+                *dst = SkBlendARGB32(color, *dst, *mask);
+                mask++;
+                dst++;
+                count--;
+            }
+            __m128i *d = reinterpret_cast<__m128i*>(dst);
+            __m128i rb_mask = _mm_set1_epi32(0x00FF00FF);
+            __m128i c_256 = _mm_set1_epi16(256);
+            __m128i c_1 = _mm_set1_epi16(1);
+            __m128i src_pixel = _mm_set1_epi32(color);
+            while (count >= 4) {
+                // Load 4 pixels each of src and dest.
+                __m128i dst_pixel = _mm_load_si128(d);
+
+                //set the aphla value
+                __m128i src_scale_wide =  _mm_set_epi8(0, *(mask+3),\
+                                0, *(mask+3),0, \
+                                *(mask+2),0, *(mask+2),\
+                                0,*(mask+1), 0,*(mask+1),\
+                                0, *mask,0,*mask);
+
+                //call SkAlpha255To256()
+                src_scale_wide = _mm_add_epi16(src_scale_wide, c_1);
+
+                // Get red and blue pixels into lower byte of each word.
+                __m128i dst_rb = _mm_and_si128(rb_mask, dst_pixel);
+                __m128i src_rb = _mm_and_si128(rb_mask, src_pixel);
+
+                // Get alpha and green into lower byte of each word.
+                __m128i dst_ag = _mm_srli_epi16(dst_pixel, 8);
+                __m128i src_ag = _mm_srli_epi16(src_pixel, 8);
+
+                // Put per-pixel alpha in low byte of each word.
+                __m128i dst_alpha = _mm_shufflehi_epi16(src_ag, 0xF5);
+                dst_alpha = _mm_shufflelo_epi16(dst_alpha, 0xF5);
+
+                // dst_alpha = dst_alpha * src_scale
+                dst_alpha = _mm_mullo_epi16(dst_alpha, src_scale_wide);
+
+                // Divide by 256.
+                dst_alpha = _mm_srli_epi16(dst_alpha, 8);
+
+                // Subtract alphas from 256, to get 1..256
+                dst_alpha = _mm_sub_epi16(c_256, dst_alpha);
+                // Multiply red and blue by dst pixel alpha.
+                dst_rb = _mm_mullo_epi16(dst_rb, dst_alpha);
+                // Multiply alpha and green by dst pixel alpha.
+                dst_ag = _mm_mullo_epi16(dst_ag, dst_alpha);
+
+                // Multiply red and blue by global alpha.
+                src_rb = _mm_mullo_epi16(src_rb, src_scale_wide);
+                // Multiply alpha and green by global alpha.
+                src_ag = _mm_mullo_epi16(src_ag, src_scale_wide);
+                // Divide by 256.
+                dst_rb = _mm_srli_epi16(dst_rb, 8);
+                src_rb = _mm_srli_epi16(src_rb, 8);
+
+                // Mask out low bits (goodies already in the right place; no need to divide)
+                dst_ag = _mm_andnot_si128(rb_mask, dst_ag);
+                src_ag = _mm_andnot_si128(rb_mask, src_ag);
+
+                // Combine back into RGBA.
+                dst_pixel = _mm_or_si128(dst_rb, dst_ag);
+                __m128i tmp_src_pixel = _mm_or_si128(src_rb, src_ag);
+
+                // Add two pixels into result.
+                __m128i result = _mm_add_epi8(tmp_src_pixel, dst_pixel);
+                _mm_store_si128(d, result);
+                // load the next 4 pixel
+                mask = mask + 4;
+                d++;
+                count -= 4;
+            }
+            dst = reinterpret_cast<SkPMColor *>(d);
+        }
+        while(count > 0) {
+            *dst= SkBlendARGB32(color, *dst, *mask);
+            dst += 1;
+            mask++;
+            count --;
+        }
+        dst = (SkPMColor *)((char*)dst + dstOffset);
+        mask += maskOffset;
+    } while (--height != 0);
+}
diff --git a/src/opts/SkBlitRow_opts_SSE2.h b/src/opts/SkBlitRow_opts_SSE2.h
index c22edd8..d861bc5 100644
--- a/src/opts/SkBlitRow_opts_SSE2.h
+++ b/src/opts/SkBlitRow_opts_SSE2.h
@@ -28,3 +28,7 @@
 void S32A_Blend_BlitRow32_SSE2(SkPMColor* SK_RESTRICT dst,
                                const SkPMColor* SK_RESTRICT src,
                                int count, U8CPU alpha);
+void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB, 
+                            SkBitmap::Config dstConfig, const uint8_t* mask,
+                            size_t maskRB, SkColor color,
+                            int width, int height);
diff --git a/src/opts/SkBlitRow_opts_arm.cpp b/src/opts/SkBlitRow_opts_arm.cpp
index 2ad7ba7..60b4d64 100644
--- a/src/opts/SkBlitRow_opts_arm.cpp
+++ b/src/opts/SkBlitRow_opts_arm.cpp
@@ -770,7 +770,7 @@
 
 	    /* calculate 'd', which will be 0..7 */
 	    /* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */
-#if 1
+#if ANDROID
 	    /* SkAlpha255To256() semantic a+1 vs a+a>>7 */
 	    alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1));
 #else
@@ -1086,3 +1086,10 @@
 SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
     return NULL;
 }
+
+
+SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
+                                           SkColor color)
+{
+   return NULL;
+}
diff --git a/src/opts/SkBlitRow_opts_none.cpp b/src/opts/SkBlitRow_opts_none.cpp
index 0eb1185..0fa098e 100644
--- a/src/opts/SkBlitRow_opts_none.cpp
+++ b/src/opts/SkBlitRow_opts_none.cpp
@@ -17,3 +17,10 @@
 SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
     return NULL;
 }
+
+
+SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
+                                           SkColor color)
+{
+   return NULL;
+}
diff --git a/src/opts/opts_check_SSE2.cpp b/src/opts/opts_check_SSE2.cpp
index fa7b17a..749117a 100644
--- a/src/opts/opts_check_SSE2.cpp
+++ b/src/opts/opts_check_SSE2.cpp
@@ -2,16 +2,16 @@
  **
  ** Copyright 2009, The Android Open Source Project
  **
- ** Licensed under the Apache License, Version 2.0 (the "License"); 
- ** you may not use this file except in compliance with the License. 
- ** You may obtain a copy of the License at 
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
  **
- **     http://www.apache.org/licenses/LICENSE-2.0 
+ **     http://www.apache.org/licenses/LICENSE-2.0
  **
- ** Unless required by applicable law or agreed to in writing, software 
- ** distributed under the License is distributed on an "AS IS" BASIS, 
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- ** See the License for the specific language governing permissions and 
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
  ** limitations under the License.
  */
 
@@ -105,6 +105,27 @@
     }
 }
 
+
+SkBlitMask::Proc SkBlitMask::PlatformProcs(SkBitmap::Config dstConfig,
+                                           SkColor color)
+{
+
+    SkBlitMask::Proc proc = NULL;
+    if (hasSSE2()) {
+        switch (dstConfig) {
+            case SkBitmap::kARGB_8888_Config:
+                // TODO: is our current SSE2 faster than the portable, even in
+                // the case of black or opaque? If so, no need for this check.
+                if ( SK_ColorBLACK != color && 0xFF != SkColorGetA(color))
+                    proc = SkARGB32_BlitMask_SSE2;
+                break;
+            default:
+                 break;
+        }
+    }
+    return proc;
+}
+
 SkMemset16Proc SkMemset16GetPlatformProc() {
     if (hasSSE2()) {
         return sk_memset16_SSE2;
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 043f0df..7cecb7f 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -39,10 +39,7 @@
 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
 #include FT_SYNTHESIS_H
 #include FT_XFREE86_H
-
-#if defined(SK_SUPPORT_LCDTEXT)
 #include FT_LCD_FILTER_H
-#endif
 
 #ifdef   FT_ADVANCES_H
 #include FT_ADVANCES_H
@@ -95,15 +92,18 @@
 static bool
 InitFreetype() {
     FT_Error err = FT_Init_FreeType(&gFTLibrary);
-    if (err)
+    if (err) {
         return false;
+    }
 
-#if defined(SK_SUPPORT_LCDTEXT)
     // Setup LCD filtering. This reduces colour fringes for LCD rendered
     // glyphs.
+//#ifdef ANDROID
+//    gLCDSupport = false;
+//#else
     err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT);
     gLCDSupport = err == 0;
-#endif
+//#endif
     gLCDSupportValid = true;
 
     return true;
@@ -121,7 +121,7 @@
     }
 
 protected:
-    virtual unsigned generateGlyphCount() const;
+    virtual unsigned generateGlyphCount();
     virtual uint16_t generateCharToGlyph(SkUnichar uni);
     virtual void generateAdvance(SkGlyph* glyph);
     virtual void generateMetrics(SkGlyph* glyph);
@@ -346,7 +346,7 @@
 // static
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID, bool perGlyphInfo) {
-#ifdef ANDROID
+#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
     return NULL;
 #else
     SkAutoMutexAcquire ac(gFTMutex);
@@ -523,7 +523,7 @@
         FT_Done_FreeType(gFTLibrary);
     }
 
-    if (!gLCDSupport && rec->isLCD()) {
+    if (!gLCDSupport && (rec->isLCD() || SkMask::kLCD16_Format == rec->fMaskFormat)) {
         // If the runtime Freetype library doesn't support LCD mode, we disable
         // it here.
         rec->fMaskFormat = SkMask::kA8_Format;
@@ -541,6 +541,7 @@
     rec->setHinting(h);
 }
 
+#ifdef ANDROID
 uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
     SkAutoMutexAcquire ac(gFTMutex);
     SkFaceRec *rec = ref_ft_face(fontID);
@@ -553,6 +554,7 @@
 
     return (uint32_t)unitsPerEm;
 }
+#endif
 
 SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
         : SkScalerContext(desc) {
@@ -644,10 +646,12 @@
                     break;
                 }
                 loadFlags = FT_LOAD_TARGET_NORMAL;
-                if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat)
+                if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat ||
+                        SkMask::kLCD16_Format == fRec.fMaskFormat) {
                     loadFlags = FT_LOAD_TARGET_LCD;
-                else if (SkMask::kVerticalLCD_Format == fRec.fMaskFormat)
+                } else if (SkMask::kVerticalLCD_Format == fRec.fMaskFormat) {
                     loadFlags = FT_LOAD_TARGET_LCD_V;
+                }
                 break;
             default:
                 SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
@@ -748,7 +752,7 @@
     FT_Outline_Embolden(outline, strength);
 }
 
-unsigned SkScalerContext_FreeType::generateGlyphCount() const {
+unsigned SkScalerContext_FreeType::generateGlyphCount() {
     return fFace->num_glyphs;
 }
 
@@ -913,6 +917,26 @@
 using namespace skia_freetype_support;
 #endif
 
+static void copyFT2LCD16(const SkGlyph& glyph, const FT_Bitmap& bitmap) {
+    SkASSERT(glyph.fWidth * 3 == bitmap.width - 6);
+    SkASSERT(glyph.fHeight == bitmap.rows);
+
+    const uint8_t* src = bitmap.buffer + 3;
+    uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
+    size_t dstRB = glyph.rowBytes();
+    int width = glyph.fWidth;
+
+    for (int y = 0; y < glyph.fHeight; y++) {
+        const uint8_t* triple = src;
+        for (int x = 0; x < width; x++) {
+            dst[x] = SkPackRGB16(triple[0] >> 3, triple[1] >> 2, triple[2] >> 3);
+            triple += 3;
+        }
+        src += bitmap.pitch;
+        dst = (uint16_t*)((char*)dst + dstRB);
+    }
+}
+
 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
     SkAutoMutexAcquire  ac(gFTMutex);
 
@@ -980,16 +1004,21 @@
             }
 #endif
 
-            target.width = glyph.fWidth;
-            target.rows = glyph.fHeight;
-            target.pitch = glyph.rowBytes();
-            target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
-            target.pixel_mode = compute_pixel_mode(
-                                            (SkMask::Format)fRec.fMaskFormat);
-            target.num_grays = 256;
+            if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
+                FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_LCD);
+                copyFT2LCD16(glyph, fFace->glyph->bitmap);
+            } else {
+                target.width = glyph.fWidth;
+                target.rows = glyph.fHeight;
+                target.pitch = glyph.rowBytes();
+                target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
+                target.pixel_mode = compute_pixel_mode(
+                                                (SkMask::Format)fRec.fMaskFormat);
+                target.num_grays = 256;
 
-            memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
-            FT_Outline_Get_Bitmap(gFTLibrary, outline, &target);
+                memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
+                FT_Outline_Get_Bitmap(gFTLibrary, outline, &target);
+            }
         } break;
 
         case FT_GLYPH_FORMAT_BITMAP: {
diff --git a/src/ports/SkFontHost_ascender.cpp b/src/ports/SkFontHost_ascender.cpp
index 88cde38..6f5cf0b 100644
--- a/src/ports/SkFontHost_ascender.cpp
+++ b/src/ports/SkFontHost_ascender.cpp
@@ -22,7 +22,7 @@
     virtual ~SkScalerContext_Ascender();
 
 protected:
-    virtual unsigned generateGlyphCount() const;
+    virtual unsigned generateGlyphCount();
     virtual uint16_t generateCharToGlyph(SkUnichar uni);
     virtual void generateMetrics(SkGlyph* glyph);
     virtual void generateImage(const SkGlyph& glyph);
@@ -102,7 +102,7 @@
     sk_free(fHandle);
 }
 
-unsigned SkScalerContext_Ascender::generateGlyphCount() const
+unsigned SkScalerContext_Ascender::generateGlyphCount()
 {
     return 1000;
 }
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index 5183730..1d40a42 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -87,7 +87,7 @@
     virtual ~SkScalerContext_Mac();
 
 protected:
-    virtual unsigned generateGlyphCount() const;
+    virtual unsigned generateGlyphCount();
     virtual uint16_t generateCharToGlyph(SkUnichar uni);
     virtual void generateAdvance(SkGlyph* glyph);
     virtual void generateMetrics(SkGlyph* glyph);
@@ -184,7 +184,7 @@
 
 // man, we need to consider caching this, since it is just dependent on
 // fFontID, and not on any of the other settings like matrix or flags
-unsigned SkScalerContext_Mac::generateGlyphCount() const {
+unsigned SkScalerContext_Mac::generateGlyphCount() {
     // The 'maxp' table stores the number of glyphs a offset 4, in 2 bytes
     uint16_t numGlyphs;
     if (SkFontHost::GetTableData(fRec.fFontID,
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index 4b5c36d..ae39361 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -1,16 +1,16 @@
 /*
  ** Copyright 2006, The Android Open Source Project
  **
- ** Licensed under the Apache License, Version 2.0 (the "License"); 
- ** you may not use this file except in compliance with the License. 
- ** You may obtain a copy of the License at 
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
  **
- **     http://www.apache.org/licenses/LICENSE-2.0 
+ **     http://www.apache.org/licenses/LICENSE-2.0
  **
- ** Unless required by applicable law or agreed to in writing, software 
- ** distributed under the License is distributed on an "AS IS" BASIS, 
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- ** See the License for the specific language governing permissions and 
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
  ** limitations under the License.
 */
 #include <vector>
@@ -21,7 +21,7 @@
 #include "SkString.h"
 #include "SkPaint.h"
 #include "SkFloatingPoint.h"
-
+#include "SkUtils.h"
 
 
 
@@ -88,13 +88,13 @@
 
     // Is a font ID valid?
     bool                                IsValid(SkFontID fontID);
-    
-    
+
+
     // Get a font
     CTFontRef                           GetFont(SkFontID fontID);
     SkNativeFontInfo                    GetFontInfo(const SkString &theName, SkTypeface::Style theStyle);
-    
-    
+
+
     // Create a font
     SkNativeFontInfo                    CreateFont(const SkString &theName, SkTypeface::Style theStyle);
 
@@ -132,7 +132,7 @@
     fontInfo.style   = SkTypeface::kNormal;
     fontInfo.fontID  = kSkInvalidFontID;
     fontInfo.fontRef = NULL;
-        
+
     mFonts.push_back(fontInfo);
 }
 
@@ -190,7 +190,7 @@
         if (theIter->name == theName && theIter->style == theStyle)
             return(*theIter);
         }
-    
+
     return(fontInfo);
 }
 
@@ -314,7 +314,7 @@
 
 
 protected:
-    unsigned                            generateGlyphCount(void) const;
+    unsigned                            generateGlyphCount(void);
     uint16_t                            generateCharToGlyph(SkUnichar uni);
     void                                generateAdvance(SkGlyph* glyph);
     void                                generateMetrics(SkGlyph* glyph);
@@ -328,7 +328,8 @@
 
 
 private:
-    CGColorSpaceRef                     mColorSpace;
+    CGColorSpaceRef                     mColorSpaceGray;
+    CGColorSpaceRef                     mColorSpaceRGB;
     CGAffineTransform                   mTransform;
 
     CTFontRef                           mFont;
@@ -352,7 +353,11 @@
 
 
     // Initialise ourselves
-    mColorSpace = CGColorSpaceCreateDeviceGray();
+//    mColorSpaceRGB = CGColorSpaceCreateDeviceRGB();
+//    mColorSpaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+    mColorSpaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+    mColorSpaceGray = CGColorSpaceCreateDeviceGray();
+
     const float inv = 1.0f / FONT_CANONICAL_POINTSIZE;
     mTransform  = CGAffineTransformMake(SkScalarToFloat(skMatrix[SkMatrix::kMScaleX]) * inv,
                                         -SkScalarToFloat(skMatrix[SkMatrix::kMSkewY]) * inv,
@@ -369,11 +374,12 @@
 {
 
     // Clean up
-    CFSafeRelease(mColorSpace);
+    CFSafeRelease(mColorSpaceGray);
+    CFSafeRelease(mColorSpaceRGB);
     CFSafeRelease(mFont);
 }
 
-unsigned SkScalerContext_Mac::generateGlyphCount(void) const
+unsigned SkScalerContext_Mac::generateGlyphCount(void)
 {
     return(mGlyphCount);
 }
@@ -437,8 +443,27 @@
     glyph->fLeft     =  sk_float_round2int(CGRectGetMinX(theBounds));
 }
 
-void SkScalerContext_Mac::generateImage(const SkGlyph& glyph)
-{   CGContextRef        cgContext;
+#include "SkColorPriv.h"
+
+static inline uint16_t rgb_to_lcd16(uint32_t rgb) {
+    int r = (rgb >> 16) & 0xFF;
+    int g = (rgb >>  8) & 0xFF;
+    int b = (rgb >>  0) & 0xFF;
+
+    // invert, since we draw black-on-white, but we want the original
+    // src mask values.
+    r = 255 - r;
+    g = 255 - g;
+    b = 255 - b;
+
+    return SkPackRGB16(SkR32ToR16(r), SkG32ToG16(g), SkB32ToB16(b));
+}
+
+#define BITMAP_INFO_RGB     (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
+#define BITMAP_INFO_GRAY    (kCGImageAlphaNone)
+
+void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
+    CGContextRef        cgContext;
     CGGlyph             cgGlyph;
     CGFontRef           cgFont;
 
@@ -447,17 +472,61 @@
 
     cgGlyph   = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
     cgFont    = CTFontCopyGraphicsFont(mFont, NULL);
-    cgContext = CGBitmapContextCreate(  glyph.fImage, glyph.fWidth, glyph.fHeight, 8,
-                                        glyph.rowBytes(), mColorSpace, kCGImageAlphaNone);
+
+    SkAutoSMalloc<1024> storage;
+
+    CGColorSpaceRef colorspace = mColorSpaceGray;
+    uint32_t info = BITMAP_INFO_GRAY;
+    void* image = glyph.fImage;
+    size_t rowBytes = glyph.rowBytes();
+    float grayColor = 1; // white
+
+    /*  For LCD16, we first create a temp offscreen cg-context in 32bit,
+     *  erase to white, and then draw a black glyph into it. Then we can
+     *  extract the r,g,b values, invert-them, and now we have the original
+     *  src mask components, which we pack into our 16bit mask.
+     */
+    if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
+        colorspace = mColorSpaceRGB;
+        info = BITMAP_INFO_RGB;
+        // need tmp storage for 32bit RGB offscreen
+        rowBytes = glyph.fWidth << 2;
+        size_t size = glyph.fHeight * rowBytes;
+        image = storage.realloc(size);
+        // we draw black-on-white (and invert in rgb_to_lcd16)
+        sk_memset32((uint32_t*)image, 0xFFFFFFFF, size >> 2);
+        grayColor = 0;  // black
+    }
+
+    cgContext = CGBitmapContextCreate(image, glyph.fWidth, glyph.fHeight, 8,
+                                      rowBytes, colorspace, info);
 
     // Draw the glyph
     if (cgFont != NULL && cgContext != NULL) {
-        CGContextSetGrayFillColor(  cgContext, 1.0, 1.0);
+        CGContextSetAllowsFontSubpixelQuantization(cgContext, true);
+        CGContextSetShouldSubpixelQuantizeFonts(cgContext, true);
+
+        CGContextSetGrayFillColor(  cgContext, grayColor, 1.0);
         CGContextSetTextDrawingMode(cgContext, kCGTextFill);
         CGContextSetFont(           cgContext, cgFont);
         CGContextSetFontSize(       cgContext, FONT_CANONICAL_POINTSIZE);
         CGContextSetTextMatrix(     cgContext, mTransform);
         CGContextShowGlyphsAtPoint( cgContext, -glyph.fLeft, glyph.fTop + glyph.fHeight, &cgGlyph, 1);
+
+        if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
+            // downsample from rgba to rgb565
+            int width = glyph.fWidth;
+            const uint32_t* src = (const uint32_t*)image;
+            uint16_t* dst = (uint16_t*)glyph.fImage;
+            size_t dstRB = glyph.rowBytes();
+            for (int y = 0; y < glyph.fHeight; y++) {
+                for (int i = 0; i < width; i++) {
+                    dst[i] = rgb_to_lcd16(src[i]);
+                }
+                src = (const uint32_t*)((const char*)src + rowBytes);
+                dst = (uint16_t*)((char*)dst + dstRB);
+            }
+        }
     }
 
     // Clean up
@@ -539,7 +608,7 @@
         case kCGPathElementCloseSubpath:
             skPath->close();
             break;
-        
+
         default:
             SkASSERT("Unknown path element!");
             break;
@@ -783,7 +852,7 @@
         theSize = CFDataGetLength(cfData);
         CFSafeRelease(cfData);
         }
-    
+
     return(theSize);
 }
 
diff --git a/src/ports/SkFontHost_simple.cpp b/src/ports/SkFontHost_simple.cpp
index 6df6c44..60334e7 100644
--- a/src/ports/SkFontHost_simple.cpp
+++ b/src/ports/SkFontHost_simple.cpp
@@ -26,9 +26,14 @@
 
 #define FONT_CACHE_MEMORY_BUDGET    (768 * 1024)
 
-#define SK_FONT_FILE_PREFIX          "/skimages/"
+#ifdef SK_BUILD_FOR_MAC
+    #define SK_FONT_FILE_PREFIX     "/Library/Fonts/"
+#else
+    #define SK_FONT_FILE_PREFIX          "/skimages/"
+#endif
 
-SkTypeface::Style find_name_and_style(SkStream* stream, SkString* name);
+SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
+                                           bool* isFixedWidth);
 
 static void GetFullPathForSysFonts(SkString* full, const char name[]) {
     full->set(SK_FONT_FILE_PREFIX);
@@ -47,7 +52,7 @@
 struct NameFamilyPair {
     const char* fName;      // we own this
     FamilyRec*  fFamily;    // we don't own this, we just reference it
-    
+
     void construct(const char name[], FamilyRec* family) {
         fName = strdup(name);
         fFamily = family;   // we don't own this, so just record the referene
@@ -70,7 +75,7 @@
 struct FamilyRec {
     FamilyRec*  fNext;
     SkTypeface* fFaces[4];
-    
+
     FamilyRec()
     {
         fNext = gFamilyHead;
@@ -143,7 +148,7 @@
     FamilyRec* family = find_family(face);
     SkASSERT(family->fFaces[face->style()] == face);
     family->fFaces[face->style()] = NULL;
-    
+
     for (int i = 0; i < 4; i++) {
         if (family->fFaces[i] != NULL) {    // family is non-empty
             return NULL;
@@ -177,7 +182,7 @@
 static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
     NameFamilyPair* list = gNameList.begin();
     int             count = gNameList.count();
-    
+
     int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
 
     if (index >= 0) {
@@ -198,7 +203,7 @@
 
     NameFamilyPair* list = gNameList.begin();
     int             count = gNameList.count();
-    
+
     int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
 
     if (index < 0) {
@@ -216,7 +221,7 @@
 #endif
 
     SkTDArray<NameFamilyPair>& list = gNameList;
-    
+
     // must go backwards when removing
     for (int i = list.count() - 1; i >= 0; --i) {
         NameFamilyPair* pair = &list[i];
@@ -234,9 +239,9 @@
     FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember)
     : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
         fIsSysFont = sysFont;
-        
+
         SkAutoMutexAcquire  ac(gFamilyMutex);
-        
+
         FamilyRec* rec = NULL;
         if (familyMember) {
             rec = find_family(familyMember);
@@ -246,10 +251,10 @@
         }
         rec->fFaces[style] = this;
     }
-    
+
     virtual ~FamilyTypeface() {
         SkAutoMutexAcquire  ac(gFamilyMutex);
-        
+
         // remove us from our family. If the family is now empty, we return
         // that and then remove that family from the name list
         FamilyRec* family = remove_from_family(this);
@@ -258,16 +263,16 @@
             detach_and_delete_family(family);
         }
     }
-    
+
     bool isSysFont() const { return fIsSysFont; }
-    
+
     virtual SkStream* openStream() = 0;
     virtual const char* getUniqueString() const = 0;
     virtual const char* getFilePath() const = 0;
-    
+
 private:
     bool    fIsSysFont;
-    
+
     typedef SkTypeface INHERITED;
 };
 
@@ -285,7 +290,7 @@
     virtual ~StreamTypeface() {
         fStream->unref();
     }
-    
+
     // overrides
     virtual SkStream* openStream() {
         // we just ref our existing stream, since the caller will call unref()
@@ -298,7 +303,7 @@
 
 private:
     SkStream* fStream;
-    
+
     typedef FamilyTypeface INHERITED;
 };
 
@@ -308,14 +313,14 @@
                  const char path[])
     : INHERITED(style, sysFont, familyMember) {
         SkString fullpath;
-        
+
         if (sysFont) {
             GetFullPathForSysFonts(&fullpath, path);
             path = fullpath.c_str();
         }
         fPath.set(path);
     }
-    
+
     // overrides
     virtual SkStream* openStream() {
         SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
@@ -345,7 +350,7 @@
 
 private:
     SkString fPath;
-    
+
     typedef FamilyTypeface INHERITED;
 };
 
@@ -354,18 +359,19 @@
 
 static bool get_name_and_style(const char path[], SkString* name,
                                SkTypeface::Style* style, bool isExpected) {
+    bool            isFixedWidth;
     SkString        fullpath;
     GetFullPathForSysFonts(&fullpath, path);
 
     SkMMAPStream stream(fullpath.c_str());
     if (stream.getLength() > 0) {
-        *style = find_name_and_style(&stream, name);
+        *style = find_name_and_attributes(&stream, name, &isFixedWidth);
         return true;
     }
     else {
         SkFILEStream stream(fullpath.c_str());
         if (stream.getLength() > 0) {
-            *style = find_name_and_style(&stream, name);
+            *style = find_name_and_attributes(&stream, name, &isFixedWidth);
             return true;
         }
     }
@@ -403,6 +409,8 @@
     null for the list. The names list must be NULL-terminated
 */
 static const FontInitRec gSystemFonts[] = {
+    { "Arial.ttf",              gSansNames  },
+    { "Times.ttf",              gSerifNames  },
     { "samplefont.ttf",              gSansNames  },
 };
 
@@ -429,7 +437,7 @@
     if (NULL != gDefaultNormal) {
         return;
     }
-    
+
     const FontInitRec* rec = gSystemFonts;
     SkTypeface* firstInFamily = NULL;
     int fallbackCount = 0;
@@ -439,7 +447,7 @@
         if (rec[i].fNames != NULL) {
             firstInFamily = NULL;
         }
-        
+
         SkString name;
         SkTypeface::Style style;
 
@@ -515,7 +523,7 @@
         SkString str;
         str.resize(len);
         stream->read(str.writable_str(), len);
-        
+
         const FontInitRec* rec = gSystemFonts;
         for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
             if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
@@ -541,10 +549,10 @@
     load_system_fonts();
 
     SkAutoMutexAcquire  ac(gFamilyMutex);
-    
+
     // clip to legal style bits
     style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-    
+
     SkTypeface* tf = NULL;
 
     if (NULL != familyFace) {
@@ -565,13 +573,13 @@
 
 bool SkFontHost::ValidFontID(uint32_t fontID) {
     SkAutoMutexAcquire  ac(gFamilyMutex);
-    
+
     return find_from_uniqueID(fontID) != NULL;
 }
 
 SkStream* SkFontHost::OpenStream(uint32_t fontID) {
     SkAutoMutexAcquire  ac(gFamilyMutex);
-    
+
     FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
     SkStream* stream = tf ? tf->openStream() : NULL;
 
@@ -582,12 +590,13 @@
     return stream;
 }
 
-// static
+#if 0
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID, bool perGlyphInfo) {
     SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
     return NULL;
 }
+#endif
 
 size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
                                int32_t* index) {
@@ -633,9 +642,11 @@
     if (NULL == stream || stream->getLength() <= 0) {
         return NULL;
     }
-    
+
+    bool     isFixedWidth;
     SkString name;
-    SkTypeface::Style style = find_name_and_style(stream, &name);
+    SkTypeface::Style style = find_name_and_attributes(stream, &name,
+                                                       &isFixedWidth);
 
     return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream));
 }
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index c2055aa..a4f430c 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -1,780 +1,894 @@
-/*

- ** Copyright 2006, The Android Open Source Project

- **

- ** Licensed under the Apache License, Version 2.0 (the "License");

- ** you may not use this file except in compliance with the License.

- ** You may obtain a copy of the License at

- **

- **     http://www.apache.org/licenses/LICENSE-2.0

- **

- ** Unless required by applicable law or agreed to in writing, software

- ** distributed under the License is distributed on an "AS IS" BASIS,

- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- ** See the License for the specific language governing permissions and

- ** limitations under the License.

- */

-

-#include "SkString.h"

-//#include "SkStream.h"

-

-#include "SkFontHost.h"

-#include "SkDescriptor.h"

-#include "SkAdvancedTypefaceMetrics.h"

-#include "SkStream.h"

-#include "SkThread.h"

-#include "SkUtils.h"

-

-#ifdef WIN32

-#include "windows.h"

-#include "tchar.h"

-#include "Usp10.h"

-

-// client3d has to undefine this for now

-#define CAN_USE_LOGFONT_NAME

-

-using namespace skia_advanced_typeface_metrics_utils;

-

-static SkMutex gFTMutex;

-

-static const uint16_t BUFFERSIZE = (16384 - 32);

-static uint8_t glyphbuf[BUFFERSIZE];

-

-// Give 1MB font cache budget

-#define FONT_CACHE_MEMORY_BUDGET    (1024 * 1024)

-

-static inline FIXED SkFixedToFIXED(SkFixed x) {

-    return *(FIXED*)(&x);

-}

-

-static inline FIXED SkScalarToFIXED(SkScalar x) {

-    return SkFixedToFIXED(SkScalarToFixed(x));

-}

-

-static SkTypeface::Style GetFontStyle(const LOGFONT& lf) {

-    int style = SkTypeface::kNormal;

-    if (lf.lfWeight == FW_SEMIBOLD || lf.lfWeight == FW_DEMIBOLD || lf.lfWeight == FW_BOLD)

-        style |= SkTypeface::kBold;

-    if (lf.lfItalic)

-        style |= SkTypeface::kItalic;

-

-    return (SkTypeface::Style)style;

-}

-

-// have to do this because SkTypeface::SkTypeface() is protected

-class LogFontTypeface : public SkTypeface {

-private:

-    static SkMutex                  gMutex;

-    static LogFontTypeface*         gHead;

-    static int32_t                  gCurrId;

-

-    LogFontTypeface*                fNext;

-    LOGFONT                         fLogFont;

-

-public:

-

-    LogFontTypeface(Style style, const LOGFONT& logFont) : 

-      SkTypeface(style, sk_atomic_inc(&gCurrId)+1), // 0 id is reserved so add 1

-      fLogFont(logFont)

-    {

-        SkAutoMutexAcquire am(gMutex);

-        fNext = gHead;

-        gHead = this;

-    }

-    

-    const LOGFONT& logFont() const { return fLogFont; }

-

-    virtual ~LogFontTypeface() {

-        SkAutoMutexAcquire am(gMutex);

-        if (gHead == this) {

-            gHead = fNext;

-            return;

-        }

-

-        LogFontTypeface* prev = gHead;

-        SkASSERT(prev);

-        while (prev->fNext != this) {

-            prev = prev->fNext;

-            SkASSERT(prev);

-        }

-        prev->fNext = fNext;

-    }

-

-    static LogFontTypeface* FindById(uint32_t id){

-        SkASSERT(gHead);

-        LogFontTypeface* curr = gHead;

-        while (curr->uniqueID() != id) {

-            curr = curr->fNext;

-            SkASSERT(curr);

-        }

-        return curr;

-    }

-   

-    static LogFontTypeface* FindByLogFont(const LOGFONT& lf)

-    {

-        LogFontTypeface* curr = gHead;

-        while (curr && memcmp(&curr->fLogFont, &lf, sizeof(LOGFONT))) {

-            curr = curr->fNext;

-        }

-        return curr;

-    }

-};

-

-LogFontTypeface* LogFontTypeface::gHead;

-int32_t LogFontTypeface::gCurrId;

-SkMutex LogFontTypeface::gMutex;

-

-static const LOGFONT& get_default_font() {

-    static LOGFONT gDefaultFont;

-    // don't hardcode on Windows, Win2000, XP, Vista, and international all have different default

-    // and the user could change too

-

-

-//  lfMessageFont is garbage on my XP, so skip for now

-#if 0

-    if (gDefaultFont.lfFaceName[0] != 0) {

-        return gDefaultFont;

-    }

-

-    NONCLIENTMETRICS ncm;

-    ncm.cbSize = sizeof(NONCLIENTMETRICS);

-    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);

-

-    //memcpy(&gDefaultFont, &(ncm.lfMessageFont), sizeof(LOGFONT));

-#endif

-

-    return gDefaultFont;

-}

-

-static SkTypeface* CreateTypeface_(const LOGFONT& lf) {

-       

-    LogFontTypeface* ptypeface = LogFontTypeface::FindByLogFont(lf);

-    

-    if (NULL == ptypeface) {

-        SkTypeface::Style style = GetFontStyle(lf);

-        ptypeface = new LogFontTypeface(style, lf);

-    } else {

-        ptypeface->ref();

-    }

-    return ptypeface;

-}

-

-uint32_t SkFontHost::NextLogicalFont(uint32_t fontID) {

-  // Zero means that we don't have any fallback fonts for this fontID.

-  // This function is implemented on Android, but doesn't have much

-  // meaning here.

-  return 0;

-}

-

-class SkScalerContext_Windows : public SkScalerContext {

-public:

-    SkScalerContext_Windows(const SkDescriptor* desc);

-    virtual ~SkScalerContext_Windows();

-

-protected:

-    virtual unsigned generateGlyphCount() const;

-    virtual uint16_t generateCharToGlyph(SkUnichar uni);

-    virtual void generateAdvance(SkGlyph* glyph);

-    virtual void generateMetrics(SkGlyph* glyph);

-    virtual void generateImage(const SkGlyph& glyph);

-    virtual void generatePath(const SkGlyph& glyph, SkPath* path);

-    virtual void generateLineHeight(SkPoint* ascent, SkPoint* descent);

-    virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY);

-    //virtual SkDeviceContext getDC() {return ddc;}

-private:

-    LOGFONT      lf;

-    MAT2         mat22;

-    HDC          ddc;

-    HFONT        savefont;

-    HFONT        font;

-    SCRIPT_CACHE sc;

-};

-

-SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)

-        : SkScalerContext(desc), ddc(0), font(0), savefont(0), sc(0) {

-    SkAutoMutexAcquire  ac(gFTMutex);

-

-    lf = LogFontTypeface::FindById(fRec.fFontID)->logFont();

-

-    mat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]);

-    mat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[0][1]);

-    mat22.eM21 = SkScalarToFIXED(fRec.fPost2x2[1][0]);

-    mat22.eM22 = SkScalarToFIXED(-fRec.fPost2x2[1][1]);

-

-    ddc = ::CreateCompatibleDC(NULL);

-    SetBkMode(ddc, TRANSPARENT);

-

-    // Scaling by the DPI is inconsistent with how Skia draws elsewhere

-    //SkScalar height = -(fRec.fTextSize * GetDeviceCaps(ddc, LOGPIXELSY) / 72);

-    SkScalar height = -fRec.fTextSize;

-    lf.lfHeight = SkScalarRound(height);

-    font = CreateFontIndirect(&lf);

-    savefont = (HFONT)SelectObject(ddc, font);

-}

-

-SkScalerContext_Windows::~SkScalerContext_Windows() {

-    if (ddc) {

-        ::SelectObject(ddc, savefont);

-        ::DeleteDC(ddc);

-        ddc = NULL;

-    }

-    if (font) {

-        ::DeleteObject(font);

-    }

-    if (sc) {

-        ::ScriptFreeCache(&sc);

-    }

-}

-

-unsigned SkScalerContext_Windows::generateGlyphCount() const {

-    return 0xFFFF;

-    //    return fFace->num_glyphs;

-}

-

-uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {

-    uint16_t index = 0;

-    WCHAR c[2];

-    // TODO(ctguil): Support characters that generate more than one glyph.

-    if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) {

-        // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.

-        SkAssertResult(GetGlyphIndicesW(ddc, c, 1, &index, 0));

-    } else {

-        // Use uniscribe to detemine glyph index for non-BMP characters.

-        // Need to add extra item to SCRIPT_ITEM to work around a bug in older

-        // windows versions. https://bugzilla.mozilla.org/show_bug.cgi?id=366643

-        SCRIPT_ITEM si[2 + 1];

-        int items;

-        SkAssertResult(

-            SUCCEEDED(ScriptItemize(c, 2, 2, NULL, NULL, si, &items)));

-

-        WORD log[2];

-        SCRIPT_VISATTR vsa;

-        int glyphs;

-        SkAssertResult(SUCCEEDED(ScriptShape(

-            ddc, &sc, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs)));

-    }

-    return index;

-}

-

-void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {

-    this->generateMetrics(glyph);

-}

-

-void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {

-

-    SkASSERT(ddc);

-

-    GLYPHMETRICS gm;

-    memset(&gm, 0, sizeof(gm));

-

-    glyph->fRsbDelta = 0;

-    glyph->fLsbDelta = 0;

-

-    // Note: need to use GGO_GRAY8_BITMAP instead of GGO_METRICS because GGO_METRICS returns a smaller

-    // BlackBlox; we need the bigger one in case we need the image.  fAdvance is the same.

-    uint32_t ret = GetGlyphOutlineW(ddc, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &mat22);

-

-    if (GDI_ERROR != ret) {

-        if (ret == 0) {

-            // for white space, ret is zero and gmBlackBoxX, gmBlackBoxY are 1 incorrectly!

-            gm.gmBlackBoxX = gm.gmBlackBoxY = 0;

-        }

-        glyph->fWidth   = gm.gmBlackBoxX;

-        glyph->fHeight  = gm.gmBlackBoxY;

-        glyph->fTop     = SkToS16(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY);

-        glyph->fLeft    = SkToS16(gm.gmptGlyphOrigin.x);

-        glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX);

-        glyph->fAdvanceY = -SkIntToFixed(gm.gmCellIncY);

-    } else {

-        glyph->fWidth = 0;

-    }

-

-#if 0

-    char buf[1024];

-    sprintf(buf, "generateMetrics: id:%d, w=%d, h=%d, font:%s, fh:%d\n", glyph->fID, glyph->fWidth, glyph->fHeight, lf.lfFaceName, lf.lfHeight);

-    OutputDebugString(buf);

-#endif

-}

-

-void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {

-// Note: This code was borrowed from generateLineHeight, which has a note

-// stating that it may be incorrect.

-    if (!(mx || my))

-      return;

-

-    SkASSERT(ddc);

-

-    OUTLINETEXTMETRIC otm;

-

-    uint32_t ret = GetOutlineTextMetrics(ddc, sizeof(otm), &otm);

-    if (sizeof(otm) != ret) {

-      return;

-    }

-

-    if (mx) {

-      mx->fTop = -SkIntToScalar(otm.otmTextMetrics.tmAscent);  // Actually a long.

-      mx->fAscent = -SkIntToScalar(otm.otmAscent);

-      mx->fDescent = -SkIntToScalar(otm.otmDescent);

-      mx->fBottom = SkIntToScalar(otm.otmTextMetrics.tmDescent);  // Long

-      mx->fLeading = SkIntToScalar(otm.otmTextMetrics.tmInternalLeading

-          + otm.otmTextMetrics.tmExternalLeading);  // Long

-    }

-

-    if (my) {

-      my->fTop = -SkIntToScalar(otm.otmTextMetrics.tmAscent);  // Actually a long.

-      my->fAscent = -SkIntToScalar(otm.otmAscent);

-      my->fDescent = -SkIntToScalar(otm.otmDescent);

-      my->fBottom = SkIntToScalar(otm.otmTextMetrics.tmDescent);  // Long

-      my->fLeading = SkIntToScalar(otm.otmTextMetrics.tmInternalLeading

-          + otm.otmTextMetrics.tmExternalLeading);  // Long

-    }

-}

-

-void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {

-

-    SkAutoMutexAcquire  ac(gFTMutex);

-

-    SkASSERT(ddc);

-

-    GLYPHMETRICS gm;

-    memset(&gm, 0, sizeof(gm));

-

-#if 0

-    char buf[1024];

-    sprintf(buf, "generateImage: id:%d, w=%d, h=%d, font:%s,fh:%d\n", glyph.fID, glyph.fWidth, glyph.fHeight, lf.lfFaceName, lf.lfHeight);

-    OutputDebugString(buf);

-#endif

-

-    uint32_t bytecount = 0;

-    uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &mat22);

-    if (GDI_ERROR != total_size && total_size > 0) {

-        uint8_t *pBuff = new uint8_t[total_size];

-        if (NULL != pBuff) {

-            total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, total_size, pBuff, &mat22);

-

-            SkASSERT(total_size != GDI_ERROR);

-

-            SkASSERT(glyph.fWidth == gm.gmBlackBoxX);

-            SkASSERT(glyph.fHeight == gm.gmBlackBoxY);

-

-            uint8_t* dst = (uint8_t*)glyph.fImage;

-            uint32_t pitch = (gm.gmBlackBoxX + 3) & ~0x3;

-            if (pitch != glyph.rowBytes()) {

-                SkASSERT(false); // glyph.fImage has different rowsize!?

-            }

-

-            for (int32_t y = gm.gmBlackBoxY - 1; y >= 0; y--) {

-                uint8_t* src = pBuff + pitch * y;

-

-                for (uint32_t x = 0; x < gm.gmBlackBoxX; x++) {

-                    if (*src > 63) {

-                        *dst = 0xFF;

-                    }

-                    else {

-                        *dst = *src << 2; // scale to 0-255

-                    }

-                    dst++;

-                    src++;

-                    bytecount++;

-                }

-                memset(dst, 0, glyph.rowBytes() - glyph.fWidth);

-                dst += glyph.rowBytes() - glyph.fWidth;

-            }

-

-            delete[] pBuff;

-        }

-    }

-

-    SkASSERT(GDI_ERROR != total_size && total_size >= 0);

-

-}

-

-void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {

-

-    SkAutoMutexAcquire  ac(gFTMutex);

-

-    SkASSERT(&glyph && path);

-    SkASSERT(ddc);

-

-    path->reset();

-

-#if 0

-    char buf[1024];

-    sprintf(buf, "generatePath: id:%d, w=%d, h=%d, font:%s,fh:%d\n", glyph.fID, glyph.fWidth, glyph.fHeight, lf.lfFaceName, lf.lfHeight);

-    OutputDebugString(buf);

-#endif

-

-    GLYPHMETRICS gm;

-    uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &mat22);

-

-    if (GDI_ERROR != total_size) {

-

-        const uint8_t* cur_glyph = glyphbuf;

-        const uint8_t* end_glyph = glyphbuf + total_size;

-

-        while(cur_glyph < end_glyph) {

-            const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;

-

-            const uint8_t* end_poly = cur_glyph + th->cb;

-            const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);

-

-            path->moveTo(SkFixedToScalar(*(SkFixed*)(&th->pfxStart.x)), SkFixedToScalar(*(SkFixed*)(&th->pfxStart.y)));

-

-            while(cur_poly < end_poly) {

-                const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;

-

-                if (pc->wType == TT_PRIM_LINE) {

-                    for (uint16_t i = 0; i < pc->cpfx; i++) {

-                        path->lineTo(SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].x)), SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].y)));

-                    }

-                }

-

-                if (pc->wType == TT_PRIM_QSPLINE) {

-                    for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline

-                        POINTFX pnt_b = pc->apfx[u];    // B is always the current point

-                        POINTFX pnt_c = pc->apfx[u+1];

-

-                        if (u < pc->cpfx - 2) {          // If not on last spline, compute C

-                            pnt_c.x = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.x), *(SkFixed*)(&pnt_c.x)));

-                            pnt_c.y = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.y), *(SkFixed*)(&pnt_c.y)));

-                        }

-

-                        path->quadTo(SkFixedToScalar(*(SkFixed*)(&pnt_b.x)), SkFixedToScalar(*(SkFixed*)(&pnt_b.y)), SkFixedToScalar(*(SkFixed*)(&pnt_c.x)), SkFixedToScalar(*(SkFixed*)(&pnt_c.y)));

-                    }

-                }

-                cur_poly += sizeof(uint16_t) * 2 + sizeof(POINTFX) * pc->cpfx;

-            }

-            cur_glyph += th->cb;

-            path->close();

-        }

-    }

-    else {

-        SkASSERT(false);

-    }

-    //char buf[1024];

-    //sprintf(buf, "generatePath: count:%d\n", count);

-    //OutputDebugString(buf);

-}

-

-

-// Note:  not sure this is the correct implementation

-void SkScalerContext_Windows::generateLineHeight(SkPoint* ascent, SkPoint* descent) {

-

-    SkASSERT(ddc);

-

-    OUTLINETEXTMETRIC otm;

-

-    uint32_t ret = GetOutlineTextMetrics(ddc, sizeof(otm), &otm);

-

-    if (sizeof(otm) == ret) {

-        if (ascent)

-            ascent->iset(0, otm.otmAscent);

-        if (descent)

-            descent->iset(0, otm.otmDescent);

-    }

-

-    return;

-}

-

-void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {

-    SkASSERT(!"SkFontHost::Serialize unimplemented");

-}

-

-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {

-    SkASSERT(!"SkFontHost::Deserialize unimplemented");

-    return NULL;

-}

-

-static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {

-    // Initialize the MAT2 structure to the identify transformation matrix.

-    static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),

-                        SkScalarToFIXED(0), SkScalarToFIXED(1)};

-    int flags = GGO_METRICS | GGO_GLYPH_INDEX;

-    GLYPHMETRICS gm;

-    if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) {

-        return false;

-    }

-    SkASSERT(advance);

-    *advance = gm.gmCellIncX;

-    return true;

-}

-

-// static

-SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(

-        uint32_t fontID, bool perGlyphInfo) {

-    SkAutoMutexAcquire ac(gFTMutex);

-    LogFontTypeface* rec = LogFontTypeface::FindById(fontID);

-    LOGFONT lf = rec->logFont();

-    SkAdvancedTypefaceMetrics* info = NULL;

-

-    HDC hdc = CreateCompatibleDC(NULL);

-    HFONT font = CreateFontIndirect(&lf);

-    HFONT savefont = (HFONT)SelectObject(hdc, font);

-    HFONT designFont = NULL;

-

-    // To request design units, create a logical font whose height is specified

-    // as unitsPerEm.

-    OUTLINETEXTMETRIC otm;

-    if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm) ||

-        !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {

-        goto Error;

-    }

-    lf.lfHeight = -SkToS32(otm.otmEMSquare);

-    designFont = CreateFontIndirect(&lf);

-    SelectObject(hdc, designFont);

-    if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {

-        goto Error;

-    }

-

-    info = new SkAdvancedTypefaceMetrics;

-#ifdef UNICODE

-    // Get the buffer size needed first.

-    size_t str_len = WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, NULL,

-                                         0, NULL, NULL);

-    // Allocate a buffer (str_len already has terminating null accounted for).

-    char *familyName = new char[str_len];

-    // Now actually convert the string.

-    WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, familyName, str_len,

-                          NULL, NULL);

-    info->fFontName.set(familyName);

-    delete [] familyName;

-#else

-    info->fFontName.set(lf.lfFaceName);

-#endif

-

-    if (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE) {

-        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;

-    } else {

-        info->fType = SkAdvancedTypefaceMetrics::kOther_Font;

-    }

-    info->fEmSize = otm.otmEMSquare;

-    info->fMultiMaster = false;

-    info->fLastGlyphID = 0;

-

-    info->fStyle = 0;

-    // If this bit is clear the font is a fixed pitch font.

-    if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {

-        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;

-    }

-    if (otm.otmTextMetrics.tmItalic) {

-        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;

-    }

-    // Setting symbolic style by default for now.

-    info->fStyle |= SkAdvancedTypefaceMetrics::kSymbolic_Style;

-    if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {

-        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;

-    } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {

-            info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;

-    }

-

-    // The main italic angle of the font, in tenths of a degree counterclockwise

-    // from vertical.

-    info->fItalicAngle = otm.otmItalicAngle / 10;

-    info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);

-    info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);

-    // TODO(ctguil): Use alternate cap height calculation.

-    // MSDN says otmsCapEmHeight is not support but it is returning a value on

-    // my Win7 box.

-    info->fCapHeight = otm.otmsCapEmHeight;

-    info->fBBox =

-        SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,

-                          otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);

-

-    // Figure out a good guess for StemV - Min width of i, I, !, 1.

-    // This probably isn't very good with an italic font.

-    int16_t min_width = SHRT_MAX;

-    info->fStemV = 0;

-    char stem_chars[] = {'i', 'I', '!', '1'};

-    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {

-        ABC abcWidths;

-        if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {

-            int16_t width = abcWidths.abcB;

-            if (width > 0 && width < min_width) {

-                min_width = width;

-                info->fStemV = min_width;

-            }

-        }

-    }

-

-    // If bit 1 is set, the font may not be embedded in a document.

-    // If bit 1 is clear, the font can be embedded.

-    // If bit 2 is set, the embedding is read-only.

-    if (otm.otmfsType & 0x1) {

-        info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;

-    } else if (perGlyphInfo) {

-        info->fGlyphWidths.reset(

-            getAdvanceData(hdc, SHRT_MAX, &getWidthAdvance));

-

-        // Obtain the last glyph index.

-        SkAdvancedTypefaceMetrics::WidthRange* last = info->fGlyphWidths.get();

-        if (last) {

-            while (last->fNext.get()) {

-                last = last->fNext.get();

-            }

-            info->fLastGlyphID = last->fEndId;

-        }

-    }

-

-Error:

-    SelectObject(hdc, savefont);

-    DeleteObject(designFont);

-    DeleteObject(font);

-    DeleteDC(hdc);

-

-    return info;

-}

-

-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {

-

-    //Should not be used on Windows, keep linker happy

-    SkASSERT(false);    

-    return CreateTypeface_(get_default_font());

-}

-

-SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {

-    SkAutoMutexAcquire ac(gFTMutex);

-    LogFontTypeface* rec = LogFontTypeface::FindById(uniqueID);

-

-    HDC hdc = ::CreateCompatibleDC(NULL);

-    HFONT font = CreateFontIndirect(&rec->logFont());

-    HFONT savefont = (HFONT)SelectObject(hdc, font);

-

-    size_t bufferSize = GetFontData(hdc, 0, 0, NULL, 0);

-    SkMemoryStream* stream = new SkMemoryStream(bufferSize);

-    if (!GetFontData(hdc, 0, 0, (void*)stream->getMemoryBase(), bufferSize)) {

-        delete stream;

-        stream = NULL;

-    }

-

-    SelectObject(hdc, savefont);

-    DeleteObject(font);

-    DeleteDC(hdc);

-

-    return stream;

-}

-

-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {

-    return SkNEW_ARGS(SkScalerContext_Windows, (desc));

-}

-

-/** Return the closest matching typeface given either an existing family

- (specified by a typeface in that family) or by a familyName, and a

- requested style.

- 1) If familyFace is null, use famillyName.

- 2) If famillyName is null, use familyFace.

- 3) If both are null, return the default font that best matches style

- This MUST not return NULL.

- */

-

-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,

-                                       const char familyName[],

-                                       const void* data, size_t bytelength,

-                                       SkTypeface::Style style) {

-

-    static SkTypeface* gDefaultTypeface;

-    SkAutoMutexAcquire  ac(gFTMutex);

-

-#ifndef CAN_USE_LOGFONT_NAME

-    familyName = NULL;

-    familyFace = NULL;

-#endif

-

-    // clip to legal style bits

-    style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);

-

-    SkTypeface* tf = NULL;

-    if (NULL == familyFace && NULL == familyName) {

-        LOGFONT lf = get_default_font();

-        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;

-        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);

-        // hack until we figure out if SkTypeface should cache this itself

-        if (style == SkTypeface::kNormal) {

-            if (NULL == gDefaultTypeface) {

-                gDefaultTypeface = CreateTypeface_(lf);

-            }

-            tf = gDefaultTypeface;

-            tf->ref();

-        } else {

-            tf = CreateTypeface_(lf);

-        }

-    } else {

-#ifdef CAN_USE_LOGFONT_NAME

-        LOGFONT lf;

-        if (NULL != familyFace) {

-            uint32_t id = familyFace->uniqueID();

-            LogFontTypeface* rec = LogFontTypeface::FindById(id);

-            if (!rec) {

-                SkASSERT(false);

-                lf = get_default_font();

-            }

-            else {

-                lf = rec->logFont();

-            }

-        }

-        else {

-            memset(&lf, 0, sizeof(LOGFONT));

-

-            lf.lfHeight = -11; // default

-            lf.lfQuality = PROOF_QUALITY;

-            lf.lfCharSet = DEFAULT_CHARSET;

-

-#ifdef UNICODE

-            // Get the buffer size needed first.

-            size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName,

-                                                   -1, NULL, 0);

-            // Allocate a buffer (str_len already has terminating null

-            // accounted for).

-            wchar_t *wideFamilyName = new wchar_t[str_len];

-            // Now actually convert the string.

-            ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,

-                                  wideFamilyName, str_len);

-            ::wcsncpy(lf.lfFaceName, wideFamilyName, LF_FACESIZE);

-            delete [] wideFamilyName;

-#else

-            ::strncpy(lf.lfFaceName, familyName, LF_FACESIZE);

-#endif

-            lf.lfFaceName[LF_FACESIZE-1] = '\0';

-        }

-

-        // use the style desired

-        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;

-        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);

-        tf = CreateTypeface_(lf);

-#endif

-    }

-

-    if (NULL == tf) {        

-        tf = CreateTypeface_(get_default_font());

-    }

-    return tf;

-}

-

-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {

-    if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)

-        return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;

-    else

-        return 0;   // nothing to do

-}

-

-int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {

-    return 0;

-}

-

-void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {

-    tables[0] = NULL;   // black gamma (e.g. exp=1.4)

-    tables[1] = NULL;   // white gamma (e.g. exp= 1/1.4)

-}

-

-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {

-    printf("SkFontHost::CreateTypefaceFromFile unimplemented");

-    return NULL;

-}

-

-void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {

-    // We don't control the hinting nor ClearType settings here

-    rec->setHinting(SkPaint::kNormal_Hinting);

-    if (SkMask::FormatIsLCD((SkMask::Format)rec->fMaskFormat)) {

-        rec->fMaskFormat = SkMask::kA8_Format;

-    }

-}

-

-#endif // WIN32

+/*
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "SkString.h"
+//#include "SkStream.h"
+
+#include "SkEndian.h"
+#include "SkFontHost.h"
+#include "SkDescriptor.h"
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkStream.h"
+#include "SkThread.h"
+#include "SkTypeface_win.h"
+#include "SkUtils.h"
+
+#ifdef WIN32
+#include "windows.h"
+#include "tchar.h"
+#include "Usp10.h"
+
+// client3d has to undefine this for now
+#define CAN_USE_LOGFONT_NAME
+
+using namespace skia_advanced_typeface_metrics_utils;
+
+static SkMutex gFTMutex;
+
+static const uint16_t BUFFERSIZE = (16384 - 32);
+static uint8_t glyphbuf[BUFFERSIZE];
+
+// Give 1MB font cache budget
+#define FONT_CACHE_MEMORY_BUDGET    (1024 * 1024)
+
+/**
+ *	Since LOGFONT wants its textsize as an int, and we support fractional sizes,
+ *  and since we have a cache of LOGFONTs for our tyepfaces, we always set the
+ *  lfHeight to a canonical size, and then we use the 2x2 matrix to achieve the
+ *  actual requested size.
+ */
+static const int gCanonicalTextSize = 64;
+
+static void make_canonical(LOGFONT* lf) {
+	lf->lfHeight = -gCanonicalTextSize;
+}
+
+static inline FIXED SkFixedToFIXED(SkFixed x) {
+    return *(FIXED*)(&x);
+}
+
+static inline FIXED SkScalarToFIXED(SkScalar x) {
+    return SkFixedToFIXED(SkScalarToFixed(x));
+}
+
+static unsigned calculateGlyphCount(HDC hdc) {
+    // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
+    const DWORD maxpTag = *(DWORD*) "maxp";
+    uint16_t glyphs;
+    if (GetFontData(hdc, maxpTag, 4, &glyphs, sizeof(glyphs)) != GDI_ERROR) {
+        return SkEndian_SwapBE16(glyphs);
+    }
+    
+    // Binary search for glyph count.
+    static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
+    int32_t max = SK_MaxU16 + 1;
+    int32_t min = 0;
+    GLYPHMETRICS gm;
+    while (min < max) {
+        int32_t mid = min + ((max - min) / 2);
+        if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
+                             NULL, &mat2) == GDI_ERROR) {
+            max = mid;
+        } else {
+            min = mid + 1;
+        }
+    }
+    SkASSERT(min == max);
+    return min;
+}
+
+static SkTypeface::Style GetFontStyle(const LOGFONT& lf) {
+    int style = SkTypeface::kNormal;
+    if (lf.lfWeight == FW_SEMIBOLD || lf.lfWeight == FW_DEMIBOLD || lf.lfWeight == FW_BOLD)
+        style |= SkTypeface::kBold;
+    if (lf.lfItalic)
+        style |= SkTypeface::kItalic;
+
+    return (SkTypeface::Style)style;
+}
+
+// have to do this because SkTypeface::SkTypeface() is protected
+class LogFontTypeface : public SkTypeface {
+private:
+    static SkMutex                  gMutex;
+    static LogFontTypeface*         gHead;
+    static int32_t                  gCurrId;
+
+    LogFontTypeface*                fNext;
+    LOGFONT                         fLogFont;
+
+public:
+
+    LogFontTypeface(Style style, const LOGFONT& logFont) :
+      SkTypeface(style, sk_atomic_inc(&gCurrId)+1), // 0 id is reserved so add 1
+      fLogFont(logFont)
+    {
+		make_canonical(&fLogFont);
+
+        SkAutoMutexAcquire am(gMutex);
+        fNext = gHead;
+        gHead = this;
+    }
+
+    const LOGFONT& logFont() const { return fLogFont; }
+
+    virtual ~LogFontTypeface() {
+        SkAutoMutexAcquire am(gMutex);
+        if (gHead == this) {
+            gHead = fNext;
+            return;
+        }
+
+        LogFontTypeface* prev = gHead;
+        SkASSERT(prev);
+        while (prev->fNext != this) {
+            prev = prev->fNext;
+            SkASSERT(prev);
+        }
+        prev->fNext = fNext;
+    }
+
+    static LogFontTypeface* FindById(uint32_t id){
+        SkASSERT(gHead);
+        LogFontTypeface* curr = gHead;
+        while (curr->uniqueID() != id) {
+            curr = curr->fNext;
+            SkASSERT(curr);
+        }
+        return curr;
+    }
+
+    static LogFontTypeface* FindByLogFont(const LOGFONT& lf)
+    {
+		LOGFONT canonical = lf;
+		make_canonical(&canonical);
+
+        LogFontTypeface* curr = gHead;
+        while (curr && memcmp(&curr->fLogFont, &canonical, sizeof(LOGFONT))) {
+            curr = curr->fNext;
+        }
+        return curr;
+    }
+};
+
+LogFontTypeface* LogFontTypeface::gHead;
+int32_t LogFontTypeface::gCurrId;
+SkMutex LogFontTypeface::gMutex;
+
+static const LOGFONT& get_default_font() {
+    static LOGFONT gDefaultFont;
+    // don't hardcode on Windows, Win2000, XP, Vista, and international all have different default
+    // and the user could change too
+
+
+//  lfMessageFont is garbage on my XP, so skip for now
+#if 0
+    if (gDefaultFont.lfFaceName[0] != 0) {
+        return gDefaultFont;
+    }
+
+    NONCLIENTMETRICS ncm;
+    ncm.cbSize = sizeof(NONCLIENTMETRICS);
+    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
+
+    //memcpy(&gDefaultFont, &(ncm.lfMessageFont), sizeof(LOGFONT));
+#endif
+
+    return gDefaultFont;
+}
+
+SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& lf) {
+    LogFontTypeface* ptypeface = LogFontTypeface::FindByLogFont(lf);
+
+    if (NULL == ptypeface) {
+        SkTypeface::Style style = GetFontStyle(lf);
+        ptypeface = new LogFontTypeface(style, lf);
+    } else {
+	    ptypeface->ref();
+	}
+    return ptypeface;
+}
+
+uint32_t SkFontHost::NextLogicalFont(uint32_t fontID) {
+  // Zero means that we don't have any fallback fonts for this fontID.
+  // This function is implemented on Android, but doesn't have much
+  // meaning here.
+  return 0;
+}
+
+class SkScalerContext_Windows : public SkScalerContext {
+public:
+    SkScalerContext_Windows(const SkDescriptor* desc);
+    virtual ~SkScalerContext_Windows();
+
+protected:
+    virtual unsigned generateGlyphCount();
+    virtual uint16_t generateCharToGlyph(SkUnichar uni);
+    virtual void generateAdvance(SkGlyph* glyph);
+    virtual void generateMetrics(SkGlyph* glyph);
+    virtual void generateImage(const SkGlyph& glyph);
+    virtual void generatePath(const SkGlyph& glyph, SkPath* path);
+    virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY);
+    //virtual SkDeviceContext getDC() {return ddc;}
+private:
+	SkScalar	 fScale;	// to get from canonical size to real size
+    MAT2         fMat22;
+    XFORM        fXform;
+    HDC          fDDC;
+    HFONT        fSavefont;
+    HFONT        fFont;
+    SCRIPT_CACHE fSC;
+    int          fGlyphCount;
+};
+
+static float mul2float(SkScalar a, SkScalar b) {
+    return SkScalarToFloat(SkScalarMul(a, b));
+}
+
+static FIXED float2FIXED(float x) {
+    return SkFixedToFIXED(SkFloatToFixed(x));
+}
+
+SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)
+        : SkScalerContext(desc), fDDC(0), fFont(0), fSavefont(0), fSC(0)
+        , fGlyphCount(-1) {
+    SkAutoMutexAcquire  ac(gFTMutex);
+
+	fScale = fRec.fTextSize / gCanonicalTextSize;
+
+    fXform.eM11 = mul2float(fScale, fRec.fPost2x2[0][0]);
+    fXform.eM12 = mul2float(fScale, fRec.fPost2x2[1][0]);
+    fXform.eM21 = mul2float(fScale, fRec.fPost2x2[0][1]);
+    fXform.eM22 = mul2float(fScale, fRec.fPost2x2[1][1]);
+    fXform.eDx = 0;
+    fXform.eDy = 0;
+
+    fMat22.eM11 = float2FIXED(fXform.eM11);
+    fMat22.eM12 = float2FIXED(fXform.eM12);
+    fMat22.eM21 = float2FIXED(-fXform.eM21);
+    fMat22.eM22 = float2FIXED(-fXform.eM22);
+
+    fDDC = ::CreateCompatibleDC(NULL);
+    SetBkMode(fDDC, TRANSPARENT);
+
+    // Scaling by the DPI is inconsistent with how Skia draws elsewhere
+    //SkScalar height = -(fRec.fTextSize * GetDeviceCaps(ddc, LOGPIXELSY) / 72);
+    LOGFONT lf = LogFontTypeface::FindById(fRec.fFontID)->logFont();
+    lf.lfHeight = -gCanonicalTextSize;
+    fFont = CreateFontIndirect(&lf);
+    fSavefont = (HFONT)SelectObject(fDDC, fFont);
+}
+
+SkScalerContext_Windows::~SkScalerContext_Windows() {
+    if (fDDC) {
+        ::SelectObject(fDDC, fSavefont);
+        ::DeleteDC(fDDC);
+    }
+    if (fFont) {
+        ::DeleteObject(fFont);
+    }
+    if (fSC) {
+        ::ScriptFreeCache(&fSC);
+    }
+}
+
+unsigned SkScalerContext_Windows::generateGlyphCount() {
+    if (fGlyphCount < 0) {
+        fGlyphCount = calculateGlyphCount(fDDC);
+    }
+    return fGlyphCount;
+}
+
+uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
+    uint16_t index = 0;
+    WCHAR c[2];
+    // TODO(ctguil): Support characters that generate more than one glyph.
+    if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) {
+        // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.
+        SkAssertResult(GetGlyphIndicesW(fDDC, c, 1, &index, 0));
+    } else {
+        // Use uniscribe to detemine glyph index for non-BMP characters.
+        // Need to add extra item to SCRIPT_ITEM to work around a bug in older
+        // windows versions. https://bugzilla.mozilla.org/show_bug.cgi?id=366643
+        SCRIPT_ITEM si[2 + 1];
+        int items;
+        SkAssertResult(
+            SUCCEEDED(ScriptItemize(c, 2, 2, NULL, NULL, si, &items)));
+
+        WORD log[2];
+        SCRIPT_VISATTR vsa;
+        int glyphs;
+        SkAssertResult(SUCCEEDED(ScriptShape(
+            fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs)));
+    }
+    return index;
+}
+
+void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
+    this->generateMetrics(glyph);
+}
+
+void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
+
+    SkASSERT(fDDC);
+
+    GLYPHMETRICS gm;
+    memset(&gm, 0, sizeof(gm));
+
+    glyph->fRsbDelta = 0;
+    glyph->fLsbDelta = 0;
+
+    // Note: need to use GGO_GRAY8_BITMAP instead of GGO_METRICS because GGO_METRICS returns a smaller
+    // BlackBlox; we need the bigger one in case we need the image.  fAdvance is the same.
+    uint32_t ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
+
+    if (GDI_ERROR != ret) {
+        if (ret == 0) {
+            // for white space, ret is zero and gmBlackBoxX, gmBlackBoxY are 1 incorrectly!
+            gm.gmBlackBoxX = gm.gmBlackBoxY = 0;
+        }
+        glyph->fWidth   = gm.gmBlackBoxX;
+        glyph->fHeight  = gm.gmBlackBoxY;
+        glyph->fTop     = SkToS16(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY);
+        glyph->fLeft    = SkToS16(gm.gmptGlyphOrigin.x);
+        glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX);
+        glyph->fAdvanceY = -SkIntToFixed(gm.gmCellIncY);
+
+        // we outset by 1 in all dimensions, since the lcd image may bleed outside
+        // of the computed bounds returned by GetGlyphOutline.
+        // This was deduced by trial and error for small text (e.g. 8pt), so there
+        // maybe a more precise way to make this adjustment...
+        if (SkMask::kLCD16_Format == fRec.fMaskFormat) {
+            glyph->fWidth += 2;
+            glyph->fHeight += 2;
+            glyph->fTop -= 1;
+            glyph->fLeft -= 1;
+        }
+    } else {
+        glyph->fWidth = 0;
+    }
+}
+
+void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
+// Note: This code was borrowed from generateLineHeight, which has a note
+// stating that it may be incorrect.
+    if (!(mx || my))
+      return;
+
+    SkASSERT(fDDC);
+
+    OUTLINETEXTMETRIC otm;
+
+    uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
+    if (sizeof(otm) != ret) {
+      return;
+    }
+
+    if (mx) {
+        mx->fTop = -fScale * otm.otmTextMetrics.tmAscent;
+		mx->fAscent = -fScale * otm.otmAscent;
+		mx->fDescent = -fScale * otm.otmDescent;
+		mx->fBottom = fScale * otm.otmTextMetrics.tmDescent;
+		mx->fLeading = fScale * (otm.otmTextMetrics.tmInternalLeading
+								 + otm.otmTextMetrics.tmExternalLeading);
+    }
+
+    if (my) {
+		my->fTop = -fScale * otm.otmTextMetrics.tmAscent;
+		my->fAscent = -fScale * otm.otmAscent;
+		my->fDescent = -fScale * otm.otmDescent;
+		my->fBottom = fScale * otm.otmTextMetrics.tmDescent;
+		my->fLeading = fScale * (otm.otmTextMetrics.tmInternalLeading
+								 + otm.otmTextMetrics.tmExternalLeading);
+    }
+}
+
+#include "SkColorPriv.h"
+
+static inline uint16_t rgb_to_lcd16(uint32_t rgb) {
+    int r = (rgb >> 16) & 0xFF;
+    int g = (rgb >>  8) & 0xFF;
+    int b = (rgb >>  0) & 0xFF;
+
+    // invert, since we draw black-on-white, but we want the original
+    // src mask values.
+    r = 255 - r;
+    g = 255 - g;
+    b = 255 - b;
+    return SkPackRGB16(SkR32ToR16(r), SkG32ToG16(g), SkB32ToB16(b));
+}
+
+void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
+
+    SkAutoMutexAcquire  ac(gFTMutex);
+
+    SkASSERT(fDDC);
+
+    if (SkMask::kLCD16_Format == fRec.fMaskFormat) {
+        HDC dc = CreateCompatibleDC(0);
+        void* bits = 0;
+        BITMAPINFO info;
+        sk_bzero(&info, sizeof(info));
+        info.bmiHeader.biSize = sizeof(info.bmiHeader);
+        info.bmiHeader.biWidth = glyph.fWidth;
+        info.bmiHeader.biHeight = glyph.fHeight;
+        info.bmiHeader.biPlanes = 1;
+        info.bmiHeader.biBitCount = 32;
+        info.bmiHeader.biCompression = BI_RGB;
+        HBITMAP bm = CreateDIBSection(dc, &info, DIB_RGB_COLORS, &bits, 0, 0);
+        SelectObject(dc, bm);
+
+        // erase to white
+        size_t srcRB = glyph.fWidth << 2;
+        size_t size = glyph.fHeight * srcRB;
+        memset(bits, 0xFF, size);
+
+        SetBkMode(dc, TRANSPARENT);
+        SetTextAlign(dc, TA_LEFT | TA_BASELINE);
+        SetGraphicsMode(dc, GM_ADVANCED);
+
+        XFORM xform = fXform;
+        xform.eDx = (float)-glyph.fLeft;
+        xform.eDy = (float)-glyph.fTop;
+        SetWorldTransform(dc, &xform);
+
+        HGDIOBJ prevFont = SelectObject(dc, fFont);
+        COLORREF color = SetTextColor(dc, 0); // black
+        SkASSERT(color != CLR_INVALID);
+        uint16_t glyphID = glyph.getGlyphID();
+        ExtTextOut(dc, 0, 0, ETO_GLYPH_INDEX, NULL, (LPCWSTR)&glyphID, 1, NULL);
+        GdiFlush();
+
+        // downsample from rgba to rgb565
+        int width = glyph.fWidth;
+        size_t dstRB = glyph.rowBytes();
+        const uint32_t* src = (const uint32_t*)bits;
+        // gdi's bitmap is upside-down, so we reverse dst walking in Y
+        uint16_t* dst = (uint16_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
+        for (int y = 0; y < glyph.fHeight; y++) {
+            for (int i = 0; i < width; i++) {
+                dst[i] = rgb_to_lcd16(src[i]);
+            }
+            src = (const uint32_t*)((const char*)src + srcRB);
+            dst = (uint16_t*)((char*)dst - dstRB);
+        }
+
+        DeleteDC(dc);
+        DeleteObject(bm);
+        return;
+    }
+
+    GLYPHMETRICS gm;
+    memset(&gm, 0, sizeof(gm));
+    uint32_t bytecount = 0;
+    uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
+    if (GDI_ERROR != total_size && total_size > 0) {
+        uint8_t *pBuff = new uint8_t[total_size];
+        if (NULL != pBuff) {
+            total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, total_size, pBuff, &fMat22);
+
+            SkASSERT(total_size != GDI_ERROR);
+
+            SkASSERT(glyph.fWidth == gm.gmBlackBoxX);
+            SkASSERT(glyph.fHeight == gm.gmBlackBoxY);
+
+            uint8_t* dst = (uint8_t*)glyph.fImage;
+            uint32_t pitch = (gm.gmBlackBoxX + 3) & ~0x3;
+            if (pitch != glyph.rowBytes()) {
+                SkASSERT(false); // glyph.fImage has different rowsize!?
+            }
+
+            for (int32_t y = gm.gmBlackBoxY - 1; y >= 0; y--) {
+                uint8_t* src = pBuff + pitch * y;
+
+                for (uint32_t x = 0; x < gm.gmBlackBoxX; x++) {
+                    if (*src > 63) {
+                        *dst = 0xFF;
+                    }
+                    else {
+                        *dst = *src << 2; // scale to 0-255
+                    }
+                    dst++;
+                    src++;
+                    bytecount++;
+                }
+                memset(dst, 0, glyph.rowBytes() - glyph.fWidth);
+                dst += glyph.rowBytes() - glyph.fWidth;
+            }
+
+            delete[] pBuff;
+        }
+    }
+
+    SkASSERT(GDI_ERROR != total_size && total_size >= 0);
+
+}
+
+void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
+
+    SkAutoMutexAcquire  ac(gFTMutex);
+
+    SkASSERT(&glyph && path);
+    SkASSERT(fDDC);
+
+    path->reset();
+
+#if 0
+    char buf[1024];
+    sprintf(buf, "generatePath: id:%d, w=%d, h=%d, font:%s,fh:%d\n", glyph.fID, glyph.fWidth, glyph.fHeight, lf.lfFaceName, lf.lfHeight);
+    OutputDebugString(buf);
+#endif
+
+    GLYPHMETRICS gm;
+    uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &fMat22);
+
+    if (GDI_ERROR != total_size) {
+
+        const uint8_t* cur_glyph = glyphbuf;
+        const uint8_t* end_glyph = glyphbuf + total_size;
+
+        while(cur_glyph < end_glyph) {
+            const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
+
+            const uint8_t* end_poly = cur_glyph + th->cb;
+            const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
+
+            path->moveTo(SkFixedToScalar(*(SkFixed*)(&th->pfxStart.x)), SkFixedToScalar(*(SkFixed*)(&th->pfxStart.y)));
+
+            while(cur_poly < end_poly) {
+                const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
+
+                if (pc->wType == TT_PRIM_LINE) {
+                    for (uint16_t i = 0; i < pc->cpfx; i++) {
+                        path->lineTo(SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].x)), SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].y)));
+                    }
+                }
+
+                if (pc->wType == TT_PRIM_QSPLINE) {
+                    for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
+                        POINTFX pnt_b = pc->apfx[u];    // B is always the current point
+                        POINTFX pnt_c = pc->apfx[u+1];
+
+                        if (u < pc->cpfx - 2) {          // If not on last spline, compute C
+                            pnt_c.x = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.x), *(SkFixed*)(&pnt_c.x)));
+                            pnt_c.y = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.y), *(SkFixed*)(&pnt_c.y)));
+                        }
+
+                        path->quadTo(SkFixedToScalar(*(SkFixed*)(&pnt_b.x)), SkFixedToScalar(*(SkFixed*)(&pnt_b.y)), SkFixedToScalar(*(SkFixed*)(&pnt_c.x)), SkFixedToScalar(*(SkFixed*)(&pnt_c.y)));
+                    }
+                }
+                cur_poly += sizeof(uint16_t) * 2 + sizeof(POINTFX) * pc->cpfx;
+            }
+            cur_glyph += th->cb;
+            path->close();
+        }
+    }
+    else {
+        SkASSERT(false);
+    }
+    //char buf[1024];
+    //sprintf(buf, "generatePath: count:%d\n", count);
+    //OutputDebugString(buf);
+}
+
+void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
+    SkASSERT(!"SkFontHost::Serialize unimplemented");
+}
+
+SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
+    SkASSERT(!"SkFontHost::Deserialize unimplemented");
+    return NULL;
+}
+
+static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
+    // Initialize the MAT2 structure to the identify transformation matrix.
+    static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),
+                        SkScalarToFIXED(0), SkScalarToFIXED(1)};
+    int flags = GGO_METRICS | GGO_GLYPH_INDEX;
+    GLYPHMETRICS gm;
+    if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) {
+        return false;
+    }
+    SkASSERT(advance);
+    *advance = gm.gmCellIncX;
+    return true;
+}
+
+// static
+SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
+        uint32_t fontID, bool perGlyphInfo) {
+    SkAutoMutexAcquire ac(gFTMutex);
+    LogFontTypeface* rec = LogFontTypeface::FindById(fontID);
+    LOGFONT lf = rec->logFont();
+    SkAdvancedTypefaceMetrics* info = NULL;
+
+    HDC hdc = CreateCompatibleDC(NULL);
+    HFONT font = CreateFontIndirect(&lf);
+    HFONT savefont = (HFONT)SelectObject(hdc, font);
+    HFONT designFont = NULL;
+
+    // To request design units, create a logical font whose height is specified
+    // as unitsPerEm.
+    OUTLINETEXTMETRIC otm;
+    if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm) ||
+        !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
+        goto Error;
+    }
+    lf.lfHeight = -SkToS32(otm.otmEMSquare);
+    designFont = CreateFontIndirect(&lf);
+    SelectObject(hdc, designFont);
+    if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
+        goto Error;
+    }
+    const unsigned glyphCount = calculateGlyphCount(hdc);
+
+    info = new SkAdvancedTypefaceMetrics;
+    info->fEmSize = otm.otmEMSquare;
+    info->fMultiMaster = false;
+    info->fLastGlyphID = SkToU16(glyphCount - 1);
+    info->fStyle = 0;
+#ifdef UNICODE
+    // Get the buffer size needed first.
+    size_t str_len = WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, NULL,
+                                         0, NULL, NULL);
+    // Allocate a buffer (str_len already has terminating null accounted for).
+    char *familyName = new char[str_len];
+    // Now actually convert the string.
+    WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, familyName, str_len,
+                          NULL, NULL);
+    info->fFontName.set(familyName);
+    delete [] familyName;
+#else
+    info->fFontName.set(lf.lfFaceName);
+#endif
+
+    if (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE) {
+        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
+    } else {
+        info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
+        info->fItalicAngle = 0;
+        info->fAscent = 0;
+        info->fDescent = 0;
+        info->fStemV = 0;
+        info->fCapHeight = 0;
+        info->fBBox = SkIRect::MakeEmpty();
+        return info;
+    }
+    
+    // If this bit is clear the font is a fixed pitch font.
+    if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
+        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
+    }
+    if (otm.otmTextMetrics.tmItalic) {
+        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
+    }
+    // Setting symbolic style by default for now.
+    info->fStyle |= SkAdvancedTypefaceMetrics::kSymbolic_Style;
+    if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {
+        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
+    } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {
+            info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
+    }
+
+    // The main italic angle of the font, in tenths of a degree counterclockwise
+    // from vertical.
+    info->fItalicAngle = otm.otmItalicAngle / 10;
+    info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);
+    info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);
+    // TODO(ctguil): Use alternate cap height calculation.
+    // MSDN says otmsCapEmHeight is not support but it is returning a value on
+    // my Win7 box.
+    info->fCapHeight = otm.otmsCapEmHeight;
+    info->fBBox =
+        SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,
+                          otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);
+
+    // Figure out a good guess for StemV - Min width of i, I, !, 1.
+    // This probably isn't very good with an italic font.
+    int16_t min_width = SHRT_MAX;
+    info->fStemV = 0;
+    char stem_chars[] = {'i', 'I', '!', '1'};
+    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
+        ABC abcWidths;
+        if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
+            int16_t width = abcWidths.abcB;
+            if (width > 0 && width < min_width) {
+                min_width = width;
+                info->fStemV = min_width;
+            }
+        }
+    }
+
+    // If bit 1 is set, the font may not be embedded in a document.
+    // If bit 1 is clear, the font can be embedded.
+    // If bit 2 is set, the embedding is read-only.
+    if (otm.otmfsType & 0x1) {
+        info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
+    } else if (perGlyphInfo) {
+        info->fGlyphWidths.reset(
+            getAdvanceData(hdc, glyphCount, &getWidthAdvance));
+    }
+
+Error:
+    SelectObject(hdc, savefont);
+    DeleteObject(designFont);
+    DeleteObject(font);
+    DeleteDC(hdc);
+
+    return info;
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+
+    //Should not be used on Windows, keep linker happy
+    SkASSERT(false);
+    return SkCreateTypefaceFromLOGFONT(get_default_font());
+}
+
+SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {
+    SkAutoMutexAcquire ac(gFTMutex);
+    LogFontTypeface* rec = LogFontTypeface::FindById(uniqueID);
+
+    HDC hdc = ::CreateCompatibleDC(NULL);
+    HFONT font = CreateFontIndirect(&rec->logFont());
+    HFONT savefont = (HFONT)SelectObject(hdc, font);
+
+    size_t bufferSize = GetFontData(hdc, 0, 0, NULL, 0);
+    SkMemoryStream* stream = new SkMemoryStream(bufferSize);
+    if (!GetFontData(hdc, 0, 0, (void*)stream->getMemoryBase(), bufferSize)) {
+        delete stream;
+        stream = NULL;
+    }
+
+    SelectObject(hdc, savefont);
+    DeleteObject(font);
+    DeleteDC(hdc);
+
+    return stream;
+}
+
+SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
+    return SkNEW_ARGS(SkScalerContext_Windows, (desc));
+}
+
+/** Return the closest matching typeface given either an existing family
+ (specified by a typeface in that family) or by a familyName, and a
+ requested style.
+ 1) If familyFace is null, use famillyName.
+ 2) If famillyName is null, use familyFace.
+ 3) If both are null, return the default font that best matches style
+ This MUST not return NULL.
+ */
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                                       const char familyName[],
+                                       const void* data, size_t bytelength,
+                                       SkTypeface::Style style) {
+
+    static SkTypeface* gDefaultTypeface;
+    SkAutoMutexAcquire  ac(gFTMutex);
+
+#ifndef CAN_USE_LOGFONT_NAME
+    familyName = NULL;
+    familyFace = NULL;
+#endif
+
+    // clip to legal style bits
+    style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
+
+    SkTypeface* tf = NULL;
+    if (NULL == familyFace && NULL == familyName) {
+        LOGFONT lf = get_default_font();
+        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
+        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
+        // hack until we figure out if SkTypeface should cache this itself
+        if (style == SkTypeface::kNormal) {
+            if (NULL == gDefaultTypeface) {
+                gDefaultTypeface = SkCreateTypefaceFromLOGFONT(lf);
+            }
+            tf = gDefaultTypeface;
+            tf->ref();
+        } else {
+            tf = SkCreateTypefaceFromLOGFONT(lf);
+        }
+    } else {
+#ifdef CAN_USE_LOGFONT_NAME
+        LOGFONT lf;
+        if (NULL != familyFace) {
+            uint32_t id = familyFace->uniqueID();
+            LogFontTypeface* rec = LogFontTypeface::FindById(id);
+            if (!rec) {
+                SkASSERT(false);
+                lf = get_default_font();
+            }
+            else {
+                lf = rec->logFont();
+            }
+        }
+        else {
+            memset(&lf, 0, sizeof(LOGFONT));
+
+            lf.lfHeight = -11; // default
+            lf.lfQuality = PROOF_QUALITY;
+            lf.lfCharSet = DEFAULT_CHARSET;
+
+#ifdef UNICODE
+            // Get the buffer size needed first.
+            size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName,
+                                                   -1, NULL, 0);
+            // Allocate a buffer (str_len already has terminating null
+            // accounted for).
+            wchar_t *wideFamilyName = new wchar_t[str_len];
+            // Now actually convert the string.
+            ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,
+                                  wideFamilyName, str_len);
+            ::wcsncpy(lf.lfFaceName, wideFamilyName, LF_FACESIZE);
+            delete [] wideFamilyName;
+#else
+            ::strncpy(lf.lfFaceName, familyName, LF_FACESIZE);
+#endif
+            lf.lfFaceName[LF_FACESIZE-1] = '\0';
+        }
+
+        // use the style desired
+        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
+        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
+        tf = SkCreateTypefaceFromLOGFONT(lf);
+#endif
+    }
+
+    if (NULL == tf) {
+        tf = SkCreateTypefaceFromLOGFONT(get_default_font());
+    }
+    return tf;
+}
+
+size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
+    if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
+        return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
+    else
+        return 0;   // nothing to do
+}
+
+int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
+    return 0;
+}
+
+void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
+    tables[0] = NULL;   // black gamma (e.g. exp=1.4)
+    tables[1] = NULL;   // white gamma (e.g. exp= 1/1.4)
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+    printf("SkFontHost::CreateTypefaceFromFile unimplemented");
+    return NULL;
+}
+
+void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
+    // We don't control the hinting nor ClearType settings here
+    rec->setHinting(SkPaint::kNormal_Hinting);
+
+    // we do support LCD16
+    if (SkMask::kLCD16_Format == rec->fMaskFormat) {
+        return;
+    }
+
+    if (SkMask::FormatIsLCD((SkMask::Format)rec->fMaskFormat)) {
+        rec->fMaskFormat = SkMask::kA8_Format;
+    }
+}
+
+#endif // WIN32
diff --git a/src/utils/SkCamera.cpp b/src/utils/SkCamera.cpp
index c70c4c0..87d2aad 100644
--- a/src/utils/SkCamera.cpp
+++ b/src/utils/SkCamera.cpp
@@ -400,6 +400,7 @@
     fRec = next;
 }
 
+#ifdef ANDROID
 void Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z)
 {
     // the camera location is passed in inches, set in pt
@@ -409,6 +410,7 @@
     fCamera.update();
     
 }
+#endif
 
 void Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z)
 {
diff --git a/src/utils/SkCullPoints.cpp b/src/utils/SkCullPoints.cpp
index 03bfa99..c8d58c1 100644
--- a/src/utils/SkCullPoints.cpp
+++ b/src/utils/SkCullPoints.cpp
@@ -27,7 +27,7 @@
     tmp0.setMul(v.fX, dy);
     tmp1.setMul(dx, v.fY);
     tmp0.sub(tmp1);
-    return tmp0.isNeg();
+    return tmp0.isNeg() != 0;
 #endif
 }
 
diff --git a/src/utils/SkParsePath.cpp b/src/utils/SkParsePath.cpp
index 6b3afca..e08e84c 100644
--- a/src/utils/SkParsePath.cpp
+++ b/src/utils/SkParsePath.cpp
@@ -184,7 +184,7 @@
 #ifdef SK_SCALAR_IS_FLOAT
     char buffer[64];
 #ifdef SK_BUILD_FOR_WIN32
-	int len = sprintf(buffer, "%g", value);
+	int len = _snprintf(buffer, sizeof(buffer), "%g", value);
 #else
     int len = snprintf(buffer, sizeof(buffer), "%g", value);
 #endif
diff --git a/src/utils/utils_files.mk b/src/utils/utils_files.mk
new file mode 100644
index 0000000..68cc587
--- /dev/null
+++ b/src/utils/utils_files.mk
@@ -0,0 +1,15 @@
+SOURCE := \
+	SkCamera.cpp \
+	SkColorMatrix.cpp \
+	SkCullPoints.cpp \
+	SkDumpCanvas.cpp \
+	SkInterpolator.cpp \
+    SkLayer.cpp \
+	SkNinePatch.cpp \
+    SkNWayCanvas.cpp \
+    SkParse.cpp \
+    SkParseColor.cpp \
+    SkParsePath.cpp \
+	SkProxyCanvas.cpp \
+	SkSfntUtils.cpp \
+	SkUnitMappers.cpp
diff --git a/src/views/SkBGViewArtist.cpp b/src/views/SkBGViewArtist.cpp
deleted file mode 100644
index 07da123..0000000
--- a/src/views/SkBGViewArtist.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "SkBGViewArtist.h"
-#include "SkCanvas.h"
-#include "SkParsePaint.h"
-
-SkBGViewArtist::SkBGViewArtist(SkColor c)
-{
-	fPaint.setColor(c);
-}
-
-SkBGViewArtist::~SkBGViewArtist()
-{
-}
-
-void SkBGViewArtist::onDraw(SkView*, SkCanvas* canvas)
-{
-	// only works for views that are clipped their bounds.
-	canvas->drawPaint(fPaint);
-}
-
-void SkBGViewArtist::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	SkPaint_Inflate(&fPaint, dom, node);
-}
-
diff --git a/src/views/SkBorderView.cpp b/src/views/SkBorderView.cpp
deleted file mode 100644
index 3a9c449..0000000
--- a/src/views/SkBorderView.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "SkBorderView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-#include "SkStackViewLayout.h"
-
-SkBorderView::SkBorderView() : fTop(SkIntToScalar(0)), fLeft(SkIntToScalar(0)),
-					fRight(SkIntToScalar(0)), fBottom(SkIntToScalar(0))
-{
-	fAnim.setHostEventSink(this);
-	init_skin_anim(kBorder_SkinEnum, &fAnim);
-}
-
-SkBorderView::~SkBorderView()
-{
-	
-}
-
-void SkBorderView::setSkin(const char skin[])
-{
-	init_skin_anim(skin, &fAnim);
-}
-
-/* virtual */ void SkBorderView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-}
-
-/*virtual*/ void SkBorderView::onSizeChange()
-{
-	this->INHERITED::onSizeChange();
-	SkEvent evt("user");
-	evt.setString("id", "setDim");
-	evt.setScalar("dimX", this->width());
-	evt.setScalar("dimY", this->height());
-	fAnim.doUserEvent(evt);
-}
-
-/*virtual*/ void SkBorderView::onDraw(SkCanvas* canvas)
-{
-	SkPaint						paint;		
-	SkAnimator::DifferenceType	diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-	
-	if (diff == SkAnimator::kDifferent)
-		this->inval(NULL);
-	else if (diff == SkAnimator::kPartiallyDifferent)
-	{
-		SkRect	bounds;
-		fAnim.getInvalBounds(&bounds);
-		this->inval(&bounds);
-	}
-}
-
-/*virtual*/ bool SkBorderView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Inval))
-	{
-		this->inval(NULL);
-		return true;
-	}
-	if (evt.isType("recommendDim"))
-	{
-		evt.findScalar("leftMargin", &fLeft);
-		evt.findScalar("rightMargin", &fRight);
-		evt.findScalar("topMargin", &fTop);
-		evt.findScalar("bottomMargin", &fBottom);
-	
-		//setup_views.cpp uses SkView::Layout instead of SkStackViewLayout
-		//but that gives me an error
-		SkStackViewLayout* layout;
-		fMargin.set(fLeft, fTop, fRight, fBottom);
-		if (this->getLayout())
-		{
-			layout = (SkStackViewLayout*)this->getLayout();
-			layout->setMargin(fMargin);
-		}
-		else
-		{
-			layout = new SkStackViewLayout;
-			layout->setMargin(fMargin);
-			this->setLayout(layout)->unref();
-		}
-		this->invokeLayout();
-	}
-	return this->INHERITED::onEvent(evt);
-}
diff --git a/src/views/SkEvent.cpp b/src/views/SkEvent.cpp
deleted file mode 100644
index ec4a7b4..0000000
--- a/src/views/SkEvent.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-/* libs/graphics/views/SkEvent.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkEvent.h"
-
-void SkEvent::initialize(const char* type, size_t typeLen) {
-    fType = NULL;
-    setType(type, typeLen);
-    f32 = 0;
-#ifdef SK_DEBUG
-    fTargetID = 0;
-    fTime = 0;
-    fNextEvent = NULL;
-#endif
-    SkDEBUGCODE(fDebugTrace = false;)
-}
-
-SkEvent::SkEvent()
-{
-    initialize("", 0);
-}
-
-SkEvent::SkEvent(const SkEvent& src)
-{
-    *this = src;
-    if (((size_t) fType & 1) == 0)
-        setType(src.fType);
-}
-
-SkEvent::SkEvent(const SkString& type)
-{
-    initialize(type.c_str(), type.size());
-}
-
-SkEvent::SkEvent(const char type[])
-{
-    SkASSERT(type);
-    initialize(type, strlen(type));
-}
-
-SkEvent::~SkEvent()
-{
-    if (((size_t) fType & 1) == 0)
-        sk_free((void*) fType);
-}
-
-static size_t makeCharArray(char* buffer, size_t compact)
-{
-    size_t bits = (size_t) compact >> 1;
-    memcpy(buffer, &bits, sizeof(compact));
-    buffer[sizeof(compact)] = 0;
-    return strlen(buffer);
-}
-
-#if 0
-const char* SkEvent::getType() const 
-{ 
-    if ((size_t) fType & 1) {   // not a pointer
-        char chars[sizeof(size_t) + 1];
-        size_t len = makeCharArray(chars, (size_t) fType);
-        fType = (char*) sk_malloc_throw(len);
-        SkASSERT(((size_t) fType & 1) == 0);
-        memcpy(fType, chars, len);
-    }
-    return fType; 
-}
-#endif
-
-void SkEvent::getType(SkString* str) const 
-{ 
-    if (str) 
-    {
-        if ((size_t) fType & 1) // not a pointer
-        {
-            char chars[sizeof(size_t) + 1];
-            size_t len = makeCharArray(chars, (size_t) fType);
-            str->set(chars, len);
-        }
-        else
-            str->set(fType);
-    }
-}
-
-bool SkEvent::isType(const SkString& str) const 
-{
-    return this->isType(str.c_str(), str.size()); 
-}
-
-bool SkEvent::isType(const char type[], size_t typeLen) const 
-{ 
-    if (typeLen == 0)
-        typeLen = strlen(type);
-    if ((size_t) fType & 1) {   // not a pointer
-        char chars[sizeof(size_t) + 1];
-        size_t len = makeCharArray(chars, (size_t) fType);
-        return len == typeLen && strncmp(chars, type, typeLen) == 0;
-    }
-    return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0; 
-}
-
-void SkEvent::setType(const char type[], size_t typeLen)
-{
-    if (typeLen == 0)
-        typeLen = strlen(type);
-    if (typeLen <= sizeof(fType)) {
-        size_t slot = 0;
-        memcpy(&slot, type, typeLen);
-        if (slot << 1 >> 1 != slot)
-            goto useCharStar;
-        slot <<= 1;
-        slot |= 1;
-        fType = (char*) slot;
-    } else {
-useCharStar:
-        fType = (char*) sk_malloc_throw(typeLen + 1);
-        SkASSERT(((size_t) fType & 1) == 0);
-        memcpy(fType, type, typeLen);
-        fType[typeLen] = 0;
-    }
-}
-
-void SkEvent::setType(const SkString& type)
-{
-    setType(type.c_str());
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-#include "SkParse.h"
-
-void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-    const char* name = dom.findAttr(node, "type");
-    if (name)
-        this->setType(name);
-
-    const char* value;
-    if ((value = dom.findAttr(node, "fast32")) != NULL)
-    {
-        int32_t n;
-        if (SkParse::FindS32(value, &n))
-            this->setFast32(n);
-    }
-
-    for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node))
-    {
-        if (strcmp(dom.getName(node), "data"))
-        {
-            SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));)
-            continue;
-        }
-
-        name = dom.findAttr(node, "name");
-        if (name == NULL)
-        {
-            SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");)
-            continue;
-        }
-
-        if ((value = dom.findAttr(node, "s32")) != NULL)
-        {
-            int32_t n;
-            if (SkParse::FindS32(value, &n))
-                this->setS32(name, n);
-        }
-        else if ((value = dom.findAttr(node, "scalar")) != NULL)
-        {
-            SkScalar x;
-            if (SkParse::FindScalar(value, &x))
-                this->setScalar(name, x);
-        }
-        else if ((value = dom.findAttr(node, "string")) != NULL)
-            this->setString(name, value);
-#ifdef SK_DEBUG
-        else
-        {
-            SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name);
-        }
-#endif
-    }
-}
-
-#ifdef SK_DEBUG
-
-    #ifndef SkScalarToFloat
-        #define SkScalarToFloat(x)  ((x) / 65536.f)
-    #endif
-
-    void SkEvent::dump(const char title[])
-    {
-        if (title)
-            SkDebugf("%s ", title);
-            
-        SkString    etype;
-        this->getType(&etype);
-        SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32());
-
-        const SkMetaData&   md = this->getMetaData();
-        SkMetaData::Iter    iter(md);
-        SkMetaData::Type    mtype;
-        int                 count;
-        const char*         name;
-        
-        while ((name = iter.next(&mtype, &count)) != NULL)
-        {
-            SkASSERT(count > 0);
-
-            SkDebugf(" <%s>=", name);
-            switch (mtype) {
-            case SkMetaData::kS32_Type:     // vector version???
-                {
-                    int32_t value;
-                    md.findS32(name, &value);
-                    SkDebugf("%d ", value);
-                }
-                break;
-            case SkMetaData::kScalar_Type:
-                {
-                    const SkScalar* values = md.findScalars(name, &count, NULL);
-                    SkDebugf("%f", SkScalarToFloat(values[0]));
-                    for (int i = 1; i < count; i++)
-                        SkDebugf(", %f", SkScalarToFloat(values[i]));
-                    SkDebugf(" ");
-                }
-                break;
-            case SkMetaData::kString_Type:
-                {
-                    const char* value = md.findString(name);
-                    SkASSERT(value);
-                    SkDebugf("<%s> ", value);
-                }
-                break;
-            case SkMetaData::kPtr_Type:     // vector version???
-                {
-                    void*   value;
-                    md.findPtr(name, &value);
-                    SkDebugf("%p ", value);
-                }
-                break;
-            case SkMetaData::kBool_Type:    // vector version???
-                {
-                    bool    value;
-                    md.findBool(name, &value);
-                    SkDebugf("%s ", value ? "true" : "false");
-                }
-                break;
-            default:
-                SkASSERT(!"unknown metadata type returned from iterator");
-                break;
-            }
-        }
-        SkDebugf("\n");
-    }
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-// #define SK_TRACE_EVENTSx
-#endif
-
-#ifdef SK_TRACE_EVENTS
-    static void event_log(const char s[])
-    {
-        SkDEBUGF(("%s\n", s));
-    }
-
-    #define EVENT_LOG(s)        event_log(s)
-    #define EVENT_LOGN(s, n)    do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0)
-#else
-    #define EVENT_LOG(s)
-    #define EVENT_LOGN(s, n)
-#endif
-
-#include "SkGlobals.h"
-#include "SkThread.h"
-#include "SkTime.h"
-
-#define SK_Event_GlobalsTag     SkSetFourByteTag('e', 'v', 'n', 't')
-
-class SkEvent_Globals : public SkGlobals::Rec {
-public:
-    SkMutex     fEventMutex;
-    SkEvent*    fEventQHead, *fEventQTail;
-    SkEvent*    fDelayQHead;
-    SkDEBUGCODE(int fEventCounter;)
-};
-
-static SkGlobals::Rec* create_globals()
-{
-    SkEvent_Globals* rec = new SkEvent_Globals;
-    rec->fEventQHead = NULL;
-    rec->fEventQTail = NULL;
-    rec->fDelayQHead = NULL;
-    SkDEBUGCODE(rec->fEventCounter = 0;)
-    return rec;
-}
-
-bool SkEvent::Post(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay)
-{
-    if (delay)
-        return SkEvent::PostTime(evt, sinkID, SkTime::GetMSecs() + delay);
-
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-
-    evt->fTargetID = sinkID;
-
-#ifdef SK_TRACE_EVENTS
-    {
-        SkString    str("SkEvent::Post(");
-        str.append(evt->getType());
-        str.append(", 0x");
-        str.appendHex(sinkID);
-        str.append(", ");
-        str.appendS32(delay);
-        str.append(")");
-        event_log(str.c_str());
-    }
-#endif
-
-    globals.fEventMutex.acquire();
-    bool wasEmpty = SkEvent::Enqueue(evt);
-    globals.fEventMutex.release();
-
-    // call outside of us holding the mutex
-    if (wasEmpty)
-        SkEvent::SignalNonEmptyQueue();
-    return true;
-}
-
-#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS)
-SkMSec gMaxDrawTime;
-#endif
-
-bool SkEvent::PostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time)
-{
-#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS)
-    gMaxDrawTime = time;
-#endif
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-
-    evt->fTargetID = sinkID;
-
-#ifdef SK_TRACE_EVENTS
-    {
-        SkString    str("SkEvent::Post(");
-        str.append(evt->getType());
-        str.append(", 0x");
-        str.appendHex(sinkID);
-        str.append(", ");
-        str.appendS32(time);
-        str.append(")");
-        event_log(str.c_str());
-    }
-#endif
-
-    globals.fEventMutex.acquire();
-    SkMSec queueDelay = SkEvent::EnqueueTime(evt, time);
-    globals.fEventMutex.release();
-
-    // call outside of us holding the mutex
-    if ((int32_t)queueDelay != ~0)
-        SkEvent::SignalQueueTimer(queueDelay);
-    return true;
-}
-
-bool SkEvent::Enqueue(SkEvent* evt)
-{
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-    //  gEventMutex acquired by caller
-
-    SkASSERT(evt);
-
-    bool wasEmpty = globals.fEventQHead == NULL;
-
-    if (globals.fEventQTail)
-        globals.fEventQTail->fNextEvent = evt;
-    globals.fEventQTail = evt;
-    if (globals.fEventQHead == NULL)
-        globals.fEventQHead = evt;
-    evt->fNextEvent = NULL;
-
-    SkDEBUGCODE(++globals.fEventCounter);
-//  SkDebugf("Enqueue: count=%d\n", gEventCounter);
-
-    return wasEmpty;
-}
-
-SkEvent* SkEvent::Dequeue(SkEventSinkID* sinkID)
-{
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-    globals.fEventMutex.acquire();
-
-    SkEvent* evt = globals.fEventQHead;
-    if (evt)
-    {
-        SkDEBUGCODE(--globals.fEventCounter);
-
-        if (sinkID)
-            *sinkID = evt->fTargetID;
-
-        globals.fEventQHead = evt->fNextEvent;
-        if (globals.fEventQHead == NULL)
-            globals.fEventQTail = NULL;
-    }
-    globals.fEventMutex.release();
-
-//  SkDebugf("Dequeue: count=%d\n", gEventCounter);
-
-    return evt;
-}
-
-bool SkEvent::QHasEvents()
-{
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-
-    // this is not thread accurate, need a semaphore for that
-    return globals.fEventQHead != NULL;
-}
-
-#ifdef SK_TRACE_EVENTS
-    static int gDelayDepth;
-#endif
-
-SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time)
-{
-#ifdef SK_TRACE_EVENTS
-    SkDebugf("enqueue-delay %s %d (%d)", evt->getType(), time, gDelayDepth);
-    const char* idStr = evt->findString("id");
-    if (idStr)
-        SkDebugf(" (%s)", idStr);
-    SkDebugf("\n");
-    ++gDelayDepth;
-#endif
-
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-    //  gEventMutex acquired by caller
-
-    SkEvent* curr = globals.fDelayQHead;
-    SkEvent* prev = NULL;
-
-    while (curr)
-    {
-        if (SkMSec_LT(time, curr->fTime))
-            break;
-        prev = curr;
-        curr = curr->fNextEvent;
-    }
-
-    evt->fTime = time;
-    evt->fNextEvent = curr;
-    if (prev == NULL)
-        globals.fDelayQHead = evt;
-    else
-        prev->fNextEvent = evt;
-
-    SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs();
-    if ((int32_t)delay <= 0)
-        delay = 1;
-    return delay;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-#include "SkEventSink.h"
-
-bool SkEvent::ProcessEvent()
-{
-    SkEventSinkID   sinkID;
-    SkEvent*        evt = SkEvent::Dequeue(&sinkID);
-    SkAutoTDelete<SkEvent>  autoDelete(evt);
-    bool            again = false;
-
-    EVENT_LOGN("ProcessEvent", (int32_t)evt);
-
-    if (evt)
-    {
-        (void)SkEventSink::DoEvent(*evt, sinkID);
-        again = SkEvent::QHasEvents();
-    }
-    return again;
-}
-
-void SkEvent::ServiceQueueTimer()
-{
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-
-    globals.fEventMutex.acquire();
-
-    bool        wasEmpty = false;
-    SkMSec      now = SkTime::GetMSecs();
-    SkEvent*    evt = globals.fDelayQHead;
-
-    while (evt)
-    {
-        if (SkMSec_LT(now, evt->fTime))
-            break;
-
-#ifdef SK_TRACE_EVENTS
-        --gDelayDepth;
-        SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth);
-        const char* idStr = evt->findString("id");
-        if (idStr)
-            SkDebugf(" (%s)", idStr);
-        SkDebugf("\n");
-#endif
-
-        SkEvent* next = evt->fNextEvent;
-        if (SkEvent::Enqueue(evt))
-            wasEmpty = true;
-        evt = next;
-    }
-    globals.fDelayQHead = evt;
-
-    SkMSec time = evt ? evt->fTime - now : 0;
-
-    globals.fEventMutex.release();
-
-    if (wasEmpty)
-        SkEvent::SignalNonEmptyQueue();
-
-    SkEvent::SignalQueueTimer(time);
-}
-
-int SkEvent::CountEventsOnQueue() {
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-    globals.fEventMutex.acquire();
-    
-    int count = 0;
-    const SkEvent* evt = globals.fEventQHead;
-    while (evt) {
-        count += 1;
-        evt = evt->fNextEvent;
-    }
-    globals.fEventMutex.release();
-
-    return count;
-}
-
-////////////////////////////////////////////////////////////////
-
-void SkEvent::Init()
-{
-}
-
-void SkEvent::Term()
-{
-    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
-
-    SkEvent* evt = globals.fEventQHead;
-    while (evt)
-    {
-        SkEvent* next = evt->fNextEvent;
-        delete evt;
-        evt = next;
-    }
-
-    evt = globals.fDelayQHead;
-    while (evt)
-    {
-        SkEvent* next = evt->fNextEvent;
-        delete evt;
-        evt = next;
-    }
-}
-
diff --git a/src/views/SkEventSink.cpp b/src/views/SkEventSink.cpp
deleted file mode 100644
index c8fe35c..0000000
--- a/src/views/SkEventSink.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/* libs/graphics/views/SkEventSink.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkEventSink.h"
-#include "SkTagList.h"
-#include "SkThread.h"
-
-#include "SkGlobals.h"
-#include "SkThread.h"
-#include "SkTime.h"
-
-#define SK_EventSink_GlobalsTag     SkSetFourByteTag('e', 'v', 's', 'k')
-
-class SkEventSink_Globals : public SkGlobals::Rec {
-public:
-    SkMutex         fSinkMutex;
-    SkEventSinkID   fNextSinkID;
-    SkEventSink*    fSinkHead;
-};
-
-static SkGlobals::Rec* create_globals()
-{
-    SkEventSink_Globals* rec = new SkEventSink_Globals;
-    rec->fNextSinkID = 0;
-    rec->fSinkHead = NULL;
-    return rec;
-}
-
-SkEventSink::SkEventSink() : fTagHead(NULL)
-{
-    SkEventSink_Globals& globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
-
-    globals.fSinkMutex.acquire();
-
-    fID = ++globals.fNextSinkID;
-    fNextSink = globals.fSinkHead;
-    globals.fSinkHead = this;
-
-    globals.fSinkMutex.release();
-}
-
-SkEventSink::~SkEventSink()
-{
-    SkEventSink_Globals& globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
-
-    if (fTagHead)
-        SkTagList::DeleteAll(fTagHead);
-
-    globals.fSinkMutex.acquire();
-
-    SkEventSink* sink = globals.fSinkHead;
-    SkEventSink* prev = NULL;
-
-    for (;;)
-    {
-        SkEventSink* next = sink->fNextSink;
-        if (sink == this)
-        {
-            if (prev)
-                prev->fNextSink = next;
-            else
-                globals.fSinkHead = next;
-            break;
-        }
-        prev = sink;
-        sink = next;
-    }
-    globals.fSinkMutex.release();
-}
-
-bool SkEventSink::doEvent(const SkEvent& evt)
-{
-    return this->onEvent(evt);
-}
-
-bool SkEventSink::doQuery(SkEvent* evt)
-{
-    SkASSERT(evt);
-    return this->onQuery(evt);
-}
-
-bool SkEventSink::onEvent(const SkEvent&)
-{
-    return false;
-}
-
-bool SkEventSink::onQuery(SkEvent*)
-{
-    return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkTagList* SkEventSink::findTagList(U8CPU tag) const
-{
-    return fTagHead ? SkTagList::Find(fTagHead, tag) : NULL;
-}
-
-void SkEventSink::addTagList(SkTagList* rec)
-{
-    SkASSERT(rec);
-    SkASSERT(fTagHead == NULL || SkTagList::Find(fTagHead, rec->fTag) == NULL);
-
-    rec->fNext = fTagHead;
-    fTagHead = rec;
-}
-
-void SkEventSink::removeTagList(U8CPU tag)
-{
-    if (fTagHead)
-        SkTagList::DeleteTag(&fTagHead, tag);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-struct SkListenersTagList : SkTagList {
-    SkListenersTagList(U16CPU count) : SkTagList(kListeners_SkTagList)
-    {
-        fExtra16 = SkToU16(count);
-        fIDs = (SkEventSinkID*)sk_malloc_throw(count * sizeof(SkEventSinkID));
-    }
-    virtual ~SkListenersTagList()
-    {
-        sk_free(fIDs);
-    }
-
-    int countListners() const { return fExtra16; }
-
-    int find(SkEventSinkID id) const
-    {
-        const SkEventSinkID* idptr = fIDs;
-        for (int i = fExtra16 - 1; i >= 0; --i)
-            if (idptr[i] == id)
-                return i;
-        return -1;
-    }
-
-    SkEventSinkID*  fIDs;
-};
-
-void SkEventSink::addListenerID(SkEventSinkID id)
-{
-    if (id == 0)
-        return;
-
-    SkListenersTagList* prev = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
-    int                 count = 0;
-
-    if (prev)
-    {
-        if (prev->find(id) >= 0)
-            return;
-        count = prev->countListners();
-    }
-
-    SkListenersTagList* next = SkNEW_ARGS(SkListenersTagList, (count + 1));
-
-    if (prev)
-    {
-        memcpy(next->fIDs, prev->fIDs, count * sizeof(SkEventSinkID));
-        this->removeTagList(kListeners_SkTagList);
-    }
-    next->fIDs[count] = id;
-    this->addTagList(next);
-}
-
-void SkEventSink::copyListeners(const SkEventSink& sink) 
-{
-    SkListenersTagList* sinkList = (SkListenersTagList*)sink.findTagList(kListeners_SkTagList);
-    if (sinkList == NULL)
-        return;
-    SkASSERT(sinkList->countListners() > 0);
-    const SkEventSinkID* iter = sinkList->fIDs;
-    const SkEventSinkID* stop = iter + sinkList->countListners();
-    while (iter < stop)
-        addListenerID(*iter++);
-}
-
-void SkEventSink::removeListenerID(SkEventSinkID id)
-{
-    if (id == 0)
-        return;
-
-    SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
-
-    if (list == NULL)
-        return;
-
-    int index = list->find(id);
-    if (index >= 0)
-    {
-        int count = list->countListners();
-        SkASSERT(count > 0);
-        if (count == 1)
-            this->removeTagList(kListeners_SkTagList);
-        else
-        {
-            // overwrite without resize/reallocating our struct (for speed)
-            list->fIDs[index] = list->fIDs[count - 1];
-            list->fExtra16 = SkToU16(count - 1);
-        }
-    }
-}
-
-bool SkEventSink::hasListeners() const
-{
-    return this->findTagList(kListeners_SkTagList) != NULL;
-}
-
-void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay)
-{
-    SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
-    if (list)
-    {
-        SkASSERT(list->countListners() > 0);
-        const SkEventSinkID* iter = list->fIDs;
-        const SkEventSinkID* stop = iter + list->countListners();
-        while (iter < stop)
-            (SkNEW_ARGS(SkEvent, (evt)))->post(*iter++, delay);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt, SkEventSinkID sinkID)
-{
-    SkEventSink* sink = SkEventSink::FindSink(sinkID);
-
-    if (sink)
-    {
-#ifdef SK_DEBUG
-        if (evt.isDebugTrace())
-        {
-            SkString    etype;
-            evt.getType(&etype);
-            SkDebugf("SkEventTrace: dispatching event <%s> to 0x%x", etype.c_str(), sinkID);
-            const char* idStr = evt.findString("id");
-            if (idStr)
-                SkDebugf(" (%s)", idStr);
-            SkDebugf("\n");
-        }
-#endif
-        return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult;
-    }
-    else
-    {
-#ifdef SK_DEBUG
-        if (sinkID)
-            SkDebugf("DoEvent: Can't find sink for ID(%x)\n", sinkID);
-        else
-            SkDebugf("Event sent to 0 sinkID\n");
-
-        if (evt.isDebugTrace())
-        {
-            SkString    etype;
-            evt.getType(&etype);
-            SkDebugf("SkEventTrace: eventsink not found <%s> for 0x%x\n", etype.c_str(), sinkID);
-        }
-#endif
-        return kSinkNotFound_EventResult;
-    }
-}
-
-SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
-{
-    if (sinkID == 0)
-        return 0;
-
-    SkEventSink_Globals&    globals = *(SkEventSink_Globals*)SkGlobals::Find(SK_EventSink_GlobalsTag, create_globals);
-    SkAutoMutexAcquire      ac(globals.fSinkMutex);
-    SkEventSink*            sink = globals.fSinkHead;
-
-    while (sink)
-    {
-        if (sink->getSinkID() == sinkID)
-            return sink;
-        sink = sink->fNextSink;
-    }
-    return NULL;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////
-
-#if 0   // experimental, not tested
-
-#include "SkThread.h"
-#include "SkTDict.h"
-
-#define kMinStringBufferSize    128
-static SkMutex                  gNamedSinkMutex;
-static SkTDict<SkEventSinkID>   gNamedSinkIDs(kMinStringBufferSize);
-
-/** Register a name/id pair with the system. If the name already exists,
-    replace its ID with the new id. This pair will persist until UnregisterNamedSink()
-    is called.
-*/
-void SkEventSink::RegisterNamedSinkID(const char name[], SkEventSinkID id)
-{
-    if (id && name && *name)
-    {
-        SkAutoMutexAcquire  ac(gNamedSinkMutex);
-        gNamedSinkIDs.set(name, id);
-    }
-}
-
-/** Return the id that matches the specified name (from a previous call to
-    RegisterNamedSinkID(). If no match is found, return 0
-*/
-SkEventSinkID SkEventSink::FindNamedSinkID(const char name[])
-{
-    SkEventSinkID id = 0;
-
-    if (name && *name)
-    {
-        SkAutoMutexAcquire  ac(gNamedSinkMutex);
-        (void)gNamedSinkIDs.find(name, &id);
-    }
-    return id;
-}
-
-/** Remove all name/id pairs from the system. This is call internally
-    on shutdown, to ensure no memory leaks. It should not be called
-    before shutdown.
-*/
-void SkEventSink::RemoveAllNamedSinkIDs()
-{
-    SkAutoMutexAcquire  ac(gNamedSinkMutex);
-    (void)gNamedSinkIDs.reset();
-}
-#endif
diff --git a/src/views/SkImageView.cpp b/src/views/SkImageView.cpp
deleted file mode 100644
index 9c358c7..0000000
--- a/src/views/SkImageView.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-#include "SkImageView.h"
-#include "SkAnimator.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkImageDecoder.h"
-#include "SkMatrix.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-SkImageView::SkImageView()
-{
-	fMatrix		= NULL;
-	fScaleType	= kMatrix_ScaleType;
-
-	fData.fAnim	= NULL;		// handles initializing the other union values
-	fDataIsAnim	= true;
-	
-	fUriIsValid	= false;	// an empty string is not valid
-}
-
-SkImageView::~SkImageView()
-{
-	if (fMatrix)
-		sk_free(fMatrix);
-		
-	this->freeData();
-}
-
-void SkImageView::getUri(SkString* uri) const
-{
-	if (uri)
-		*uri = fUri;
-}
-
-void SkImageView::setUri(const char uri[])
-{
-	if (!fUri.equals(uri))
-	{
-		fUri.set(uri);
-		this->onUriChange();
-	}
-}
-
-void SkImageView::setUri(const SkString& uri)
-{
-	if (fUri != uri)
-	{
-		fUri = uri;
-		this->onUriChange();
-	}
-}
-
-void SkImageView::setScaleType(ScaleType st)
-{
-	SkASSERT((unsigned)st <= kFitEnd_ScaleType);
-
-	if ((ScaleType)fScaleType != st)
-	{
-		fScaleType = SkToU8(st);
-		if (fUriIsValid)
-			this->inval(NULL);
-	}
-}
-
-bool SkImageView::getImageMatrix(SkMatrix* matrix) const
-{
-	if (fMatrix)
-	{
-		SkASSERT(!fMatrix->isIdentity());
-		if (matrix)
-			*matrix = *fMatrix;
-		return true;
-	}
-	else
-	{
-		if (matrix)
-			matrix->reset();
-		return false;
-	}
-}
-
-void SkImageView::setImageMatrix(const SkMatrix* matrix)
-{
-	bool changed = false;
-
-	if (matrix && !matrix->isIdentity())
-	{
-		if (fMatrix == NULL)
-			fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
-		*fMatrix = *matrix;
-		changed = true;
-	}
-	else	// set us to identity
-	{
-		if (fMatrix)
-		{
-			SkASSERT(!fMatrix->isIdentity());
-			sk_free(fMatrix);
-			fMatrix = NULL;
-			changed = true;
-		}
-	}
-
-	// only redraw if we changed our matrix and we're not in scaleToFit mode
-	if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
-		this->inval(NULL);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-bool SkImageView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Inval))
-	{
-		if (fUriIsValid)
-			this->inval(NULL);
-		return true;
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-static inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
-{
-	SkASSERT(st != SkImageView::kMatrix_ScaleType);
-	SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);
-
-	SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
-	SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
-	SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
-	SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
-	
-	return (SkMatrix::ScaleToFit)(st - 1);
-}
-
-void SkImageView::onDraw(SkCanvas* canvas)
-{
-	SkRect	src;
-	if (!this->getDataBounds(&src))
-	{
-		SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
-		return;		// nothing to draw
-	}
-		
-	SkAutoCanvasRestore	restore(canvas, true);
-	SkMatrix			matrix;
-	
-	if (this->getScaleType() == kMatrix_ScaleType)
-		(void)this->getImageMatrix(&matrix);
-	else
-	{
-		SkRect	dst;		
-		dst.set(0, 0, this->width(), this->height());
-		matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
-	}
-	canvas->concat(matrix);
-
-	SkPaint	paint;
-	
-	paint.setAntiAlias(true);
-
-	if (fDataIsAnim)
-	{
-		SkMSec	now = SkTime::GetMSecs();
-		
-		SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
-		
-SkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));
-
-		if (diff == SkAnimator::kDifferent)
-			this->inval(NULL);
-		else if (diff == SkAnimator::kPartiallyDifferent)
-		{
-			SkRect	bounds;
-			fData.fAnim->getInvalBounds(&bounds);
-			matrix.mapRect(&bounds);	// get the bounds into view coordinates
-			this->inval(&bounds);
-		}
-	}
-	else
-		canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
-}
-
-void SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	
-	const char* src = dom.findAttr(node, "src");
-	if (src)
-		this->setUri(src);
-
-	int	index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
-	if (index >= 0)
-		this->setScaleType((ScaleType)index);
-		
-	// need inflate syntax/reader for matrix
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-void SkImageView::onUriChange()
-{
-	if (this->freeData())
-		this->inval(NULL);
-	fUriIsValid = true;		// give ensureUriIsLoaded() a shot at the new uri
-}
-
-bool SkImageView::freeData()
-{
-	if (fData.fAnim)	// test is valid for all union values
-	{
-		if (fDataIsAnim)
-			delete fData.fAnim;
-		else
-			delete fData.fBitmap;
-
-		fData.fAnim = NULL;	// valid for all union values
-		return true;
-	}
-	return false;
-}
-
-bool SkImageView::getDataBounds(SkRect* bounds)
-{
-	SkASSERT(bounds);
-
-	if (this->ensureUriIsLoaded())
-	{
-		SkScalar width, height;
-
-		if (fDataIsAnim)
-		{			
-			if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
-				SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
-			{
-				// cons up fake bounds
-				width = this->width();
-				height = this->height();
-			}
-		}
-		else
-		{
-			width = SkIntToScalar(fData.fBitmap->width());
-			height = SkIntToScalar(fData.fBitmap->height());
-		}
-		bounds->set(0, 0, width, height);
-		return true;
-	}
-	return false;
-}
-
-bool SkImageView::ensureUriIsLoaded()
-{
-	if (fData.fAnim)	// test is valid for all union values
-	{
-		SkASSERT(fUriIsValid);
-		return true;
-	}
-	if (!fUriIsValid)
-		return false;
-
-	// try to load the url
-	if (fUri.endsWith(".xml"))	// assume it is screenplay
-	{
-		SkAnimator* anim = new SkAnimator;
-		
-		if (!anim->decodeURI(fUri.c_str()))
-		{
-			delete anim;
-			fUriIsValid = false;
-			return false;
-		}
-		anim->setHostEventSink(this);
-
-		fData.fAnim = anim;
-		fDataIsAnim = true;
-	}
-	else	// assume it is an image format
-	{
-    #if 0
-		SkBitmap* bitmap = new SkBitmap;
-
-		if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
-		{
-			delete bitmap;
-			fUriIsValid = false;
-			return false;
-		}
-		fData.fBitmap = bitmap;
-		fDataIsAnim = false;
-    #else
-        return false;
-    #endif
-	}
-	return true;
-}
-
diff --git a/src/views/SkListView.cpp b/src/views/SkListView.cpp
deleted file mode 100644
index ba4f02a..0000000
--- a/src/views/SkListView.cpp
+++ /dev/null
@@ -1,895 +0,0 @@
-#include "SkWidget.h"
-#include "SkCanvas.h"
-#include "SkEvent.h"
-#include "SkKey.h"
-#include "SkParsePaint.h"
-#include "SkSystemEventTypes.h"
-
-#if 0
-
-SkEvent* SkListSource::getEvent(int index)
-{
-	return NULL;
-}
-
-#include "SkOSFile.h"
-
-class SkDirListSource : public SkListSource {
-public:
-	SkDirListSource(const char path[], const char suffix[], const char target[])
-		: fPath(path), fSuffix(suffix), fTarget(target)
-	{
-		fCount = -1;
-	}
-	virtual int	countRows()
-	{
-		if (fCount < 0)
-		{
-			fCount = 0;
-			fIter.reset(fPath.c_str(), fSuffix.c_str());
-			while (fIter.next(NULL))
-				fCount += 1;
-			fIter.reset(fPath.c_str(), fSuffix.c_str());
-			fIndex = 0;
-		}
-		return fCount;
-	}
-	virtual void getRow(int index, SkString* left, SkString* right)
-	{
-		(void)this->countRows();
-		SkASSERT((unsigned)index < (unsigned)fCount);
-
-		if (fIndex > index)
-		{
-			fIter.reset(fPath.c_str(), fSuffix.c_str());
-			fIndex = 0;
-		}
-
-		while (fIndex < index)
-		{
-			fIter.next(NULL);
-			fIndex += 1;
-		}
-
-		if (fIter.next(left))
-		{
-			if (left)
-				left->remove(left->size() - fSuffix.size(), fSuffix.size());
-		}
-		else
-		{
-			if (left)
-				left->reset();
-		}
-		if (right)	// only set to ">" if we know we're on a sub-directory
-			right->reset();
-
-		fIndex += 1;
-	}
-	virtual SkEvent* getEvent(int index)
-	{
-		SkASSERT((unsigned)index < (unsigned)fCount);
-
-		SkEvent*	evt = new SkEvent();
-		SkString	label;
-
-		this->getRow(index, &label, NULL);
-		evt->setString("name", label.c_str());
-
-		int c = fPath.c_str()[fPath.size() - 1];
-		if (c != '/' && c != '\\')
-			label.prepend("/");
-		label.prepend(fPath);
-		label.append(fSuffix);
-		evt->setString("path", label.c_str());
-		evt->setS32("index", index);
-		evt->setS32("duration", 22);
-		evt->setType(fTarget);
-		return evt;
-	}
-
-private:
-	SkString		fPath, fSuffix;
-	SkString		fTarget;
-	SkOSFile::Iter	fIter;
-	int				fCount;
-	int				fIndex;
-};
-
-SkListSource* SkListSource::CreateFromDir(const char path[], const char suffix[], const char target[])
-{
-	return new SkDirListSource(path, suffix, target);
-}
-
-//////////////////////////////////////////////////////////////////
-
-class SkDOMListSource : public SkListSource {
-public:
-	enum Type {
-		kUnknown_Type,
-		kDir_Type,
-		kToggle_Type
-	};
-	struct ItemRec {
-		SkString	fLabel;
-		SkString	fTail, fAltTail;
-		SkString	fTarget;
-		Type		fType;
-	};
-
-	SkDOMListSource(const SkDOM& dom, const SkDOM::Node* node) : fDirTail(">")
-	{
-		const SkDOM::Node* child = dom.getFirstChild(node, "item");
-		int	count = 0;
-
-		while (child)
-		{
-			count += 1;
-			child = dom.getNextSibling(child, "item");
-		}
-
-		fCount = count;
-		fList = NULL;
-		if (count)
-		{
-			ItemRec* rec = fList = new ItemRec[count];
-
-			child = dom.getFirstChild(node, "item");
-			while (child)
-			{
-				rec->fLabel.set(dom.findAttr(child, "label"));
-				rec->fTail.set(dom.findAttr(child, "tail"));
-				rec->fAltTail.set(dom.findAttr(child, "alt-tail"));
-				rec->fTarget.set(dom.findAttr(child, "target"));
-				rec->fType = kUnknown_Type;
-
-				int	index = dom.findList(child, "type", "dir,toggle");
-				if (index >= 0)
-					rec->fType = (Type)(index + 1);
-
-				child = dom.getNextSibling(child, "item");
-				rec += 1;
-			}
-		}
-	}
-	virtual ~SkDOMListSource()
-	{
-		delete[] fList;
-	}
-	virtual int	countRows()
-	{
-		return fCount;
-	}
-	virtual void getRow(int index, SkString* left, SkString* right)
-	{
-		SkASSERT((unsigned)index < (unsigned)fCount);
-
-		if (left)
-			*left = fList[index].fLabel;
-		if (right)
-			*right = fList[index].fType == kDir_Type ? fDirTail : fList[index].fTail;
-	}
-	virtual SkEvent* getEvent(int index)
-	{
-		SkASSERT((unsigned)index < (unsigned)fCount);
-
-		if (fList[index].fType == kDir_Type)
-		{
-			SkEvent* evt = new SkEvent();
-			evt->setType(fList[index].fTarget);
-			evt->setFast32(index);
-			return evt;
-		}
-		if (fList[index].fType == kToggle_Type)
-			fList[index].fTail.swap(fList[index].fAltTail);
-
-		return NULL;
-	}
-
-private:
-	int			fCount;
-	ItemRec*	fList;
-	SkString	fDirTail;
-};
-
-SkListSource* SkListSource::CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node)
-{
-	return new SkDOMListSource(dom, node);
-}
-
-//////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////
-
-SkListView::SkListView(U32 flags) : SkWidgetView(flags)
-{
-	fSource = NULL;
-	fScrollIndex = 0;
-	fCurrIndex = -1;
-	fRowHeight = SkIntToScalar(16);
-	fVisibleRowCount = 0;
-	fStrCache = NULL;
-
-	fPaint[kBG_Attr].setColor(0);
-	fPaint[kNormalText_Attr].setTextSize(SkIntToScalar(14));
-	fPaint[kHiliteText_Attr].setTextSize(SkIntToScalar(14));
-	fPaint[kHiliteText_Attr].setColor(SK_ColorWHITE);
-	fPaint[kHiliteCell_Attr].setColor(SK_ColorBLUE);
-}
-
-SkListView::~SkListView()
-{
-	delete[] fStrCache;
-	fSource->safeUnref();
-}
-
-void SkListView::setRowHeight(SkScalar height)
-{
-	SkASSERT(height >= 0);
-
-	if (fRowHeight != height)
-	{
-		fRowHeight = height;
-		this->inval(NULL);
-		this->onSizeChange();
-	}
-}
-
-void SkListView::setSelection(int index)
-{
-	if (fCurrIndex != index)
-	{
-		this->invalSelection();
-		fCurrIndex = index;
-		this->invalSelection();
-		this->ensureSelectionIsVisible();
-
-		{
-			SkEvent	evt;
-			evt.setType("listview-selection");
-			evt.setFast32(index);
-			this->sendEventToParents(evt);
-		}
-	}
-}
-
-void SkListView::moveSelectionUp()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = fSource->countRows() - 1;
-		else
-			index = SkMax32(index - 1, 0);
-		this->setSelection(index);
-	}
-}
-
-void SkListView::moveSelectionDown()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = 0;
-		else
-			index = SkMin32(index + 1, fSource->countRows() - 1);
-		this->setSelection(index);
-	}
-}
-
-void SkListView::invalSelection()
-{
-	SkRect	r;
-	if (this->getRowRect(fCurrIndex, &r))
-		this->inval(&r);
-}
-
-void SkListView::ensureSelectionIsVisible()
-{
-	if (fSource == NULL)
-		return;
-
-	if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
-	{
-		int index = this->logicalToVisualIndex(fCurrIndex);
-
-		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
-		{
-			if (index < 0)	// too high
-				fScrollIndex = fCurrIndex;
-			else
-				fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
-			SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());
-
-			this->dirtyStrCache();
-			this->inval(NULL);
-		}
-	}
-}
-
-bool SkListView::getRowRect(int index, SkRect* r) const
-{
-	SkASSERT(r);
-	index = this->logicalToVisualIndex(index);
-	if (index >= 0)
-	{
-		SkScalar top = index * fRowHeight;
-
-		if (top < this->height())
-		{
-			if (r)
-				r->set(0, top, this->width(), top + fRowHeight);
-			return true;
-		}
-	}
-	return false;
-}
-
-SkPaint& SkListView::paint(Attr attr)
-{
-	SkASSERT((unsigned)attr < kAttrCount);
-	return fPaint[attr];
-}
-
-SkListSource* SkListView::setListSource(SkListSource* src)
-{
-	if (fSource != src)
-	{
-		SkRefCnt_SafeAssign(fSource, src);
-		this->dirtyStrCache();
-		this->ensureSelectionIsVisible();
-		this->inval(NULL);
-	}
-	return src;
-}
-
-void SkListView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	canvas->drawPaint(fPaint[kBG_Attr]);
-
-	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
-	if (visibleCount == 0)
-		return;
-
-	this->ensureStrCache(visibleCount);
-	int currIndex = this->logicalToVisualIndex(fCurrIndex);
-
-	if ((unsigned)currIndex < (unsigned)visibleCount)
-	{
-		SkAutoCanvasRestore	restore(canvas, true);
-		SkRect	r;
-
-		canvas->translate(0, currIndex * fRowHeight);
-		(void)this->getRowRect(fScrollIndex, &r);
-		canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
-	}
-
-	SkPaint*	p;
-	SkScalar	y, x = SkIntToScalar(6);
-	SkScalar	rite = this->width() - x;
-
-	{
-		SkScalar ascent, descent;
-		fPaint[kNormalText_Attr].measureText(0, NULL, &ascent, &descent);
-		y = SkScalarHalf(fRowHeight - descent + ascent) - ascent;
-	}
-
-	for (int i = 0; i < visibleCount; i++)
-	{
-		if (i == currIndex)
-			p = &fPaint[kHiliteText_Attr];
-		else
-			p = &fPaint[kNormalText_Attr];
-
-		p->setTextAlign(SkPaint::kLeft_Align);
-		canvas->drawText(fStrCache[i].c_str(), fStrCache[i].size(), x, y, *p);
-		p->setTextAlign(SkPaint::kRight_Align);
-		canvas->drawText(fStrCache[i + visibleCount].c_str(), fStrCache[i + visibleCount].size(), rite, y, *p);
-		canvas->translate(0, fRowHeight);
-	}
-}
-
-void SkListView::onSizeChange()
-{
-	SkScalar count = SkScalarDiv(this->height(), fRowHeight);
-	int		 n = SkScalarFloor(count);
-
-	// only want to show rows that are mostly visible
-	if (n == 0 || count - SkIntToScalar(n) > SK_Scalar1*75/100)
-		n += 1;
-
-	if (fVisibleRowCount != n)
-	{
-		fVisibleRowCount = n;
-		this->ensureSelectionIsVisible();
-		this->dirtyStrCache();
-	}
-}
-
-void SkListView::dirtyStrCache()
-{
-	if (fStrCache)
-	{
-		delete[] fStrCache;
-		fStrCache = NULL;
-	}
-}
-
-void SkListView::ensureStrCache(int count)
-{
-	if (fStrCache == NULL)
-	{
-		fStrCache = new SkString[count << 1];
-
-		if (fSource)
-			for (int i = 0; i < count; i++)
-				fSource->getRow(i + fScrollIndex, &fStrCache[i], &fStrCache[i + count]);
-	}
-}
-
-bool SkListView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Key))
-	{
-		switch (evt.getFast32()) {
-		case kUp_SkKey:
-			this->moveSelectionUp();
-			return true;
-		case kDown_SkKey:
-			this->moveSelectionDown();
-			return true;
-		case kRight_SkKey:
-		case kOK_SkKey:
-			if (fSource && fCurrIndex >= 0)
-			{
-				SkEvent* evt = fSource->getEvent(fCurrIndex);
-				if (evt)
-				{
-					SkView* view = this->sendEventToParents(*evt);
-					delete evt;
-					return view != NULL;
-				}
-				else	// hack to make toggle work
-				{
-					this->dirtyStrCache();
-					this->inval(NULL);
-				}
-			}
-			break;
-		}
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	SkScalar			x;
-	const SkDOM::Node*	child;
-
-	if (dom.findScalar(node, "row-height", &x))
-		this->setRowHeight(x);
-
-	if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
-		SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);
-
-	// look for a listsource
-	{
-		SkListSource* src = NULL;
-
-		if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
-		{
-			const char* path = dom.findAttr(child, "path");
-			if (path)
-				src = SkListSource::CreateFromDir(	path,
-													dom.findAttr(child, "filter"),
-													dom.findAttr(child, "target"));
-		}
-		else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
-		{
-			src = SkListSource::CreateFromDOM(dom, child);
-		}
-
-		if (src)
-		{
-			this->setListSource(src)->unref();
-			this->setSelection(0);
-		}
-	}
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkImageDecoder.h"
-#include "SkShader.h"
-
-class SkScrollBarView : public SkView {
-public:
-	SkScrollBarView(const char bg[], const char fg[])
-	{
-		fBGRef = SkBitmapRef::Decode(bg, true);
-		fFGRef = SkBitmapRef::Decode(fg, true);
-
-		if (fBGRef)
-			this->setWidth(SkIntToScalar(fBGRef->bitmap().width()));
-	}
-	~SkScrollBarView()
-	{
-		delete fBGRef;
-		delete fFGRef;
-	}
-protected:
-	virtual void onDraw(SkCanvas* canvas)
-	{
-		if (fBGRef == NULL) return;
-
-		SkPaint	paint;
-
-		SkShader* shader = SkShader::CreateBitmapShader(fBGRef->bitmap(), false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
-		paint.setShader(shader)->unref();
-
-		canvas->drawPaint(paint);
-	}
-private:
-	SkBitmapRef*	fBGRef, *fFGRef;
-};
-
-SkGridView::SkGridView(U32 flags) : SkWidgetView(flags)
-{
-	fSource = NULL;
-	fCurrIndex = -1;
-	fVisibleCount.set(0, 0);
-
-	fPaint[kBG_Attr].setColor(SK_ColorWHITE);
-	fPaint[kHiliteCell_Attr].setColor(SK_ColorYELLOW);
-	fPaint[kHiliteCell_Attr].setStyle(SkPaint::kStroke_Style);
-	fPaint[kHiliteCell_Attr].setAntiAliasOn(true);
-	fPaint[kHiliteCell_Attr].setStrokeWidth(SK_Scalar1*3);
-
-	fScrollBar = new SkScrollBarView("icons/scrollbarGrey.jpg", "icons/scrollbarBlue.jpg");
-	this->attachChildToFront(fScrollBar)->unref();
-	fScrollBar->setVisibleP(true);
-}
-
-SkGridView::~SkGridView()
-{
-	fSource->safeUnref();
-}
-
-void SkGridView::getCellSize(SkPoint* size) const
-{
-	if (size)
-		*size = fCellSize;
-}
-
-void SkGridView::setCellSize(SkScalar x, SkScalar y)
-{
-	SkASSERT(x >= 0 && y >= 0);
-
-	if (!fCellSize.equals(x, y))
-	{
-		fCellSize.set(x, y);
-		this->inval(NULL);
-	}
-}
-
-void SkGridView::setSelection(int index)
-{
-	if (fCurrIndex != index)
-	{
-		this->invalSelection();
-		fCurrIndex = index;
-		this->invalSelection();
-		this->ensureSelectionIsVisible();
-
-		// this generates the click
-		{
-			SkEvent	evt;
-			evt.setType("listview-selection");
-			evt.setFast32(index);
-			this->sendEventToParents(evt);
-		}
-	}
-}
-
-void SkGridView::moveSelectionUp()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = fSource->countRows() - 1;
-		else
-			index = SkMax32(index - 1, 0);
-		this->setSelection(index);
-	}
-}
-
-void SkGridView::moveSelectionDown()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = 0;
-		else
-			index = SkMin32(index + 1, fSource->countRows() - 1);
-		this->setSelection(index);
-	}
-}
-
-void SkGridView::invalSelection()
-{
-	SkRect	r;
-	if (this->getCellRect(fCurrIndex, &r))
-	{
-		SkScalar inset = 0;
-		if (fPaint[kHiliteCell_Attr].getStyle() != SkPaint::kFill_Style)
-			inset += fPaint[kHiliteCell_Attr].getStrokeWidth() / 2;
-		if (fPaint[kHiliteCell_Attr].isAntiAliasOn())
-			inset += SK_Scalar1;
-		r.inset(-inset, -inset);
-		this->inval(&r);
-	}
-}
-
-void SkGridView::ensureSelectionIsVisible()
-{
-	if (fSource == NULL)
-		return;
-#if 0
-	if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
-	{
-		int index = this->logicalToVisualIndex(fCurrIndex);
-
-		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
-		{
-			if (index < 0)	// too high
-				fScrollIndex = fCurrIndex;
-			else
-				fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
-			SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());
-
-			this->dirtyStrCache();
-			this->inval(NULL);
-		}
-	}
-#endif
-}
-
-bool SkGridView::getCellRect(int index, SkRect* r) const
-{
-	if (fVisibleCount.fY == 0)
-		return false;
-
-	index = this->logicalToVisualIndex(index);
-	if (index >= 0)
-	{
-		SkRect	bounds;
-		int row = index / fVisibleCount.fY;
-		int col = index % fVisibleCount.fY;
-
-		bounds.set(0, 0, fCellSize.fX, fCellSize.fY);
-		bounds.offset(col * (fCellSize.fX + SkIntToScalar(col > 0)),
-					  row * (fCellSize.fY + SkIntToScalar(row > 0)));
-
-		if (bounds.fTop < this->height())
-		{
-			if (r)
-				*r = bounds;
-			return true;
-		}
-	}
-	return false;
-}
-
-SkPaint& SkGridView::paint(Attr attr)
-{
-	SkASSERT((unsigned)attr < kAttrCount);
-	return fPaint[attr];
-}
-
-SkListSource* SkGridView::setListSource(SkListSource* src)
-{
-	if (fSource != src)
-	{
-		SkRefCnt_SafeAssign(fSource, src);
-	//	this->dirtyStrCache();
-		this->ensureSelectionIsVisible();
-		this->inval(NULL);
-	}
-	return src;
-}
-
-#include "SkShader.h"
-
-static void copybits(SkCanvas* canvas, const SkBitmap& bm, const SkRect& dst, const SkPaint& paint)
-{
-	SkRect		src;
-	SkMatrix	matrix;
-
-	src.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()));
-	if (matrix.setRectToRect(src, dst))
-	{
-		SkPaint	  p(paint);
-		SkShader* shader = SkShader::CreateBitmapShader(bm, false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
-		p.setShader(shader)->unref();
-
-		shader->setLocalMatrix(matrix);
-		canvas->drawRect(dst, p);
-	}
-}
-
-#include "SkImageDecoder.h"
-
-void SkGridView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	canvas->drawPaint(fPaint[kBG_Attr]);
-
-	if (fSource == NULL)
-		return;
-
-#if 0
-	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
-	if (visibleCount == 0)
-		return;
-
-	this->ensureStrCache(visibleCount);
-	int currIndex = this->logicalToVisualIndex(fCurrIndex);
-#endif
-
-	SkPaint	p;
-	for (int i = 0; i < fSource->countRows(); i++)
-	{
-		bool	 forced = false;
-		SkEvent* evt = fSource->getEvent(i);
-		SkASSERT(evt);
-		SkString path(evt->findString("path"));
-		delete evt;
-
-		SkBitmapRef* bmr = SkBitmapRef::Decode(path.c_str(), false);
-		if (bmr == NULL)
-		{
-			bmr = SkBitmapRef::Decode(path.c_str(), true);
-			if (bmr)
-				forced = true;
-		}
-
-		if (bmr)
-		{
-			SkAutoTDelete<SkBitmapRef>	autoRef(bmr);
-			SkRect	r;
-			if (!this->getCellRect(i, &r))
-				break;
-			copybits(canvas, bmr->bitmap(), r, p);
-		}
-		// only draw one forced bitmap at a time
-		if (forced)
-		{
-			this->inval(NULL);	// could inval only the remaining visible cells...
-			break;
-		}
-	}
-
-	// draw the hilite
-	{
-		SkRect	r;
-		if (fCurrIndex >= 0 && this->getCellRect(fCurrIndex, &r))
-			canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
-	}
-}
-
-static int check_count(int n, SkScalar s)
-{
-	// only want to show cells that are mostly visible
-	if (n == 0 || s - SkIntToScalar(n) > SK_Scalar1*75/100)
-		n += 1;
-	return n;
-}
-
-void SkGridView::onSizeChange()
-{
-	fScrollBar->setHeight(this->height());
-	fScrollBar->setLoc(this->locX() + this->width() - fScrollBar->width(), 0);
-
-	if (fCellSize.equals(0, 0))
-	{
-		fVisibleCount.set(0, 0);
-		return;
-	}
-
-	SkScalar rows = SkScalarDiv(this->height(), fCellSize.fY);
-	SkScalar cols = SkScalarDiv(this->width(), fCellSize.fX);
-	int		 y = SkScalarFloor(rows);
-	int		 x = SkScalarFloor(cols);
-
-	y = check_count(y, rows);
-	x = check_count(x, cols);
-
-	if (!fVisibleCount.equals(x, y))
-	{
-		fVisibleCount.set(x, y);
-		this->ensureSelectionIsVisible();
-	//	this->dirtyStrCache();
-	}
-}
-
-bool SkGridView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Key))
-	{
-		switch (evt.getFast32()) {
-		case kUp_SkKey:
-			this->moveSelectionUp();
-			return true;
-		case kDown_SkKey:
-			this->moveSelectionDown();
-			return true;
-		case kRight_SkKey:
-		case kOK_SkKey:
-			if (fSource && fCurrIndex >= 0)
-			{
-				SkEvent* evt = fSource->getEvent(fCurrIndex);
-				if (evt)
-				{
-					// augment the event with our local rect
-					(void)this->getCellRect(fCurrIndex, (SkRect*)evt->setScalars("local-rect", 4, NULL));
-
-					SkView* view = this->sendEventToParents(*evt);
-					delete evt;
-					return view != NULL;
-				}
-			}
-			break;
-		}
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-void SkGridView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	SkScalar			x[2];
-	const SkDOM::Node*	child;
-
-	if (dom.findScalars(node, "cell-size", x, 2))
-		this->setCellSize(x[0], x[1]);
-
-	if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
-		SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);
-
-	// look for a listsource
-	{
-		SkListSource* src = NULL;
-
-		if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
-		{
-			const char* path = dom.findAttr(child, "path");
-			if (path)
-				src = SkListSource::CreateFromDir(	path,
-													dom.findAttr(child, "filter"),
-													dom.findAttr(child, "target"));
-		}
-		else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
-		{
-			src = SkListSource::CreateFromDOM(dom, child);
-		}
-
-		if (src)
-		{
-			this->setListSource(src)->unref();
-			this->setSelection(0);
-		}
-	}
-	this->onSizeChange();
-}
-
-#endif
diff --git a/src/views/SkListWidget.cpp b/src/views/SkListWidget.cpp
deleted file mode 100644
index f693ebe..0000000
--- a/src/views/SkListWidget.cpp
+++ /dev/null
@@ -1,623 +0,0 @@
-#include "SkWidgetViews.h"
-
-#include "SkAnimator.h"
-#include "SkScrollBarView.h"
-
-extern void init_skin_anim(const char name[], SkAnimator*);
-
-struct SkListView::BindingRec {
-	SkString	fSlotName;
-	int			fFieldIndex;
-};
-
-SkListView::SkListView()
-{
-	fSource = NULL;				// our list-source
-	fScrollBar = NULL;
-	fAnims = NULL;				// array of animators[fVisibleRowCount]
-	fBindings = NULL;			// our fields->slot array
-	fBindingCount = 0;			// number of entries in fSlots array
-	fScrollIndex = 0;			// number of cells to skip before first visible cell
-	fCurrIndex = -1;			// index of "selected" cell
-	fVisibleRowCount = 0;		// number of cells that can fit in our bounds
-	fAnimContentDirty = true;	// true if fAnims[] have their correct content
-	fAnimFocusDirty = true;
-
-	fHeights[kNormal_Height] = SkIntToScalar(16);
-	fHeights[kSelected_Height] = SkIntToScalar(16);
-	
-	this->setFlags(this->getFlags() | kFocusable_Mask);
-}
-
-SkListView::~SkListView()
-{
-	fScrollBar->safeUnref();
-	fSource->safeUnref();
-	delete[] fAnims;
-	delete[] fBindings;
-}
-
-void SkListView::setHasScrollBar(bool hasSB)
-{
-	if (hasSB != this->hasScrollBar())
-	{
-		if (hasSB)
-		{
-			SkASSERT(fScrollBar == NULL);
-			fScrollBar = (SkScrollBarView*)SkWidgetFactory(kScroll_WidgetEnum);
-			fScrollBar->setVisibleP(true);
-			this->attachChildToFront(fScrollBar);
-			fScrollBar->setHeight(this->height());	// assume it auto-sets its width
-		//	fScrollBar->setLoc(this->getContentWidth(), 0);
-			fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
-		}
-		else
-		{
-			SkASSERT(fScrollBar);
-			fScrollBar->detachFromParent();
-			fScrollBar->unref();
-			fScrollBar = NULL;
-		}
-		this->dirtyCache(kAnimContent_DirtyFlag);
-	}
-}
-
-void SkListView::setSelection(int index)
-{
-	if (fCurrIndex != index)
-	{
-		fAnimFocusDirty = true;
-		this->inval(NULL);
-
-		this->invalSelection();
-		fCurrIndex = index;
-		this->invalSelection();
-		this->ensureSelectionIsVisible();
-	}
-}
-
-bool SkListView::moveSelectionUp()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = fSource->countRecords() - 1;
-		else
-			index = SkMax32(index - 1, 0);
-		
-		if (fCurrIndex != index)
-		{
-			this->setSelection(index);
-			return true;
-		}
-	}
-	return false;
-}
-
-bool SkListView::moveSelectionDown()
-{
-	if (fSource)
-	{
-		int	index = fCurrIndex;
-		if (index < 0)	// no selection
-			index = 0;
-		else
-			index = SkMin32(index + 1, fSource->countRecords() - 1);
-		
-		if (fCurrIndex != index)
-		{
-			this->setSelection(index);
-			return true;
-		}
-	}
-	return false;
-}
-
-void SkListView::invalSelection()
-{
-	SkRect	r;
-	if (this->getRowRect(fCurrIndex, &r))
-		this->inval(&r);
-}
-
-void SkListView::ensureSelectionIsVisible()
-{
-	if (fSource && (unsigned)fCurrIndex < (unsigned)fSource->countRecords())
-	{
-		int index = this->logicalToVisualIndex(fCurrIndex);
-
-		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
-		{
-			int newIndex;
-			
-			if (index < 0)	// too high
-				newIndex = fCurrIndex;
-			else
-				newIndex = fCurrIndex - fVisibleRowCount + 1;
-			SkASSERT((unsigned)newIndex < (unsigned)fSource->countRecords());
-			this->inval(NULL);
-			
-			if (fScrollIndex != newIndex)
-			{
-				fScrollIndex = newIndex;
-				if (fScrollBar)
-					fScrollBar->setStart(newIndex);
-				this->dirtyCache(kAnimContent_DirtyFlag);
-			}
-		}
-	}
-}
-
-SkScalar SkListView::getContentWidth() const
-{
-	SkScalar width = this->width();
-	
-	if (fScrollBar)
-	{
-		width -= fScrollBar->width();
-		if (width < 0)
-			width = 0;
-	}
-	return width;
-}
-
-bool SkListView::getRowRect(int index, SkRect* r) const
-{
-	SkASSERT(r);
-
-	index = this->logicalToVisualIndex(index);
-	if (index >= 0)
-	{
-		int	selection = this->logicalToVisualIndex(fCurrIndex);
-		
-		SkScalar height = fHeights[index == selection ? kSelected_Height : kNormal_Height];
-		SkScalar top = index * fHeights[kNormal_Height];
-
-		if (index > selection && selection >= 0)
-			top += fHeights[kSelected_Height] - fHeights[kNormal_Height];	
-
-		if (top < this->height())
-		{
-			if (r)
-				r->set(0, top, this->getContentWidth(), top + height);
-			return true;
-		}
-	}
-	return false;
-}
-
-SkListSource* SkListView::setListSource(SkListSource* src)
-{
-	if (fSource != src)
-	{
-		SkRefCnt_SafeAssign(fSource, src);
-		this->ensureSelectionIsVisible();
-		this->inval(NULL);
-		
-		if (fScrollBar)
-			fScrollBar->setTotal(fSource->countRecords());
-	}
-	return src;
-}
-
-void SkListView::dirtyCache(unsigned dirtyFlags)
-{
-	if (dirtyFlags & kAnimCount_DirtyFlag)
-	{
-		delete fAnims;
-		fAnims = NULL;
-		fAnimContentDirty = true;
-		fAnimFocusDirty = true;
-	}
-	if (dirtyFlags & kAnimContent_DirtyFlag)
-	{
-		if (!fAnimContentDirty)
-		{
-			this->inval(NULL);
-			fAnimContentDirty = true;
-		}
-		fAnimFocusDirty = true;
-	}
-}
-
-bool SkListView::ensureCache()
-{
-	if (fSkinName.size() == 0)
-		return false;
-
-	if (fAnims == NULL)
-	{
-		int n = SkMax32(1, fVisibleRowCount);
-
-		SkASSERT(fAnimContentDirty);
-		fAnims = new SkAnimator[n];
-		for (int i = 0; i < n; i++)
-		{
-			fAnims[i].setHostEventSink(this);
-			init_skin_anim(fSkinName.c_str(), &fAnims[i]);
-		}
-		
-		fHeights[kNormal_Height] = fAnims[0].getScalar("idleHeight", "value");
-		fHeights[kSelected_Height] = fAnims[0].getScalar("focusedHeight", "value");
-
-		fAnimFocusDirty = true;
-	}
-
-	if (fAnimContentDirty && fSource)
-	{
-		fAnimContentDirty = false;
-
-		SkString	str;
-		SkEvent		evt("user");
-		evt.setString("id", "setFields");
-		evt.setS32("rowCount", fVisibleRowCount);
-		
-		SkEvent	dimEvt("user");
-		dimEvt.setString("id", "setDim");
-		dimEvt.setScalar("dimX", this->getContentWidth());
-		dimEvt.setScalar("dimY", this->height());
-
-		for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
-		{
-			evt.setS32("relativeIndex", i - fScrollIndex);
-			for (int j = 0; j < fBindingCount; j++)
-			{
-				fSource->getRecord(i, fBindings[j].fFieldIndex, &str);
-//SkDEBUGF(("getRecord(%d,%d,%s) slot(%s)\n", i, fBindings[j].fFieldIndex, str.c_str(), fBindings[j].fSlotName.c_str()));
-				evt.setString(fBindings[j].fSlotName.c_str(), str.c_str());
-			}
-			(void)fAnims[i % fVisibleRowCount].doUserEvent(evt);
-			(void)fAnims[i % fVisibleRowCount].doUserEvent(dimEvt);
-		}
-		fAnimFocusDirty = true;
-	}
-
-	if (fAnimFocusDirty)
-	{
-//SkDEBUGF(("service fAnimFocusDirty\n"));
-		fAnimFocusDirty = false;
-
-		SkEvent		focusEvt("user");
-		focusEvt.setString("id", "setFocus");
-
-		for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
-		{
-			focusEvt.setS32("FOCUS", i == fCurrIndex);
-			(void)fAnims[i % fVisibleRowCount].doUserEvent(focusEvt);
-		}
-	}
-
-	return true;
-}
-
-void SkListView::ensureVisibleRowCount()
-{
-	SkScalar	height = this->height();
-	int			n = 0;
-	
-	if (height > 0)
-	{
-		n = 1;
-		height -= fHeights[kSelected_Height];
-		if (height > 0)
-		{
-			SkScalar count = SkScalarDiv(height, fHeights[kNormal_Height]);
-			n += SkScalarFloor(count);
-			if (count - SkIntToScalar(n) > SK_Scalar1*3/4)
-				n += 1;
-				
-		//	SkDebugf("count %g, n %d\n", count/65536., n);
-		}
-	}
-
-	if (fVisibleRowCount != n)
-	{
-		if (fScrollBar)
-			fScrollBar->setShown(n);
-
-		fVisibleRowCount = n;
-		this->ensureSelectionIsVisible();
-		this->dirtyCache(kAnimCount_DirtyFlag | kAnimContent_DirtyFlag);
-	}
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-void SkListView::onSizeChange()
-{
-	this->INHERITED::onSizeChange();
-
-	if (fScrollBar)
-		fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
-
-	this->ensureVisibleRowCount();
-}
-
-void SkListView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	this->ensureVisibleRowCount();
-
-	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRecords() - fScrollIndex);
-	if (visibleCount == 0 || !this->ensureCache())
-		return;
-
-//SkDebugf("visibleCount %d scrollIndex %d currIndex %d\n", visibleCount, fScrollIndex, fCurrIndex);
-
-	SkAutoCanvasRestore	ar(canvas, true);
-	SkMSec				now = SkTime::GetMSecs();
-	SkRect				bounds;
-
-	bounds.fLeft	= 0;
-	bounds.fRight	= this->getContentWidth();
-	bounds.fBottom	= 0;
-	// assign bounds.fTop inside the loop
-
-	// hack to reveal our bounds for debugging
-	if (this->hasFocus())
-		canvas->drawARGB(0x11, 0, 0, 0xFF);
-	else
-		canvas->drawARGB(0x11, 0x88, 0x88, 0x88);
-
-	for (int i = fScrollIndex; i < fScrollIndex + visibleCount; i++)
-	{
-		SkPaint	 paint;
-		SkScalar height = fHeights[i == fCurrIndex ? kSelected_Height : kNormal_Height];
-
-		bounds.fTop = bounds.fBottom;
-		bounds.fBottom += height;
-		
-		canvas->save();
-		if (fAnims[i % fVisibleRowCount].draw(canvas, &paint, now) != SkAnimator::kNotDifferent)
-			this->inval(&bounds);
-		canvas->restore();
-
-		canvas->translate(0, height);
-	}
-}
-
-bool SkListView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Key))
-	{
-		switch (evt.getFast32()) {
-		case kUp_SkKey:
-			return this->moveSelectionUp();
-		case kDown_SkKey:
-			return this->moveSelectionDown();
-		case kRight_SkKey:
-		case kOK_SkKey:
-			this->postWidgetEvent();
-			return true;
-		default:
-			break;
-		}
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-static const char gListViewEventSlot[] = "sk-listview-slot-name";
-
-/*virtual*/ bool SkListView::onPrepareWidgetEvent(SkEvent* evt)
-{
-	if (fSource && fCurrIndex >= 0 && this->INHERITED::onPrepareWidgetEvent(evt) &&
-		fSource->prepareWidgetEvent(evt, fCurrIndex))
-	{
-		evt->setS32(gListViewEventSlot, fCurrIndex);
-		return true;
-	}
-	return false;
-}
-
-int SkListView::GetWidgetEventListIndex(const SkEvent& evt)
-{
-	int32_t	index;
-
-	return evt.findS32(gListViewEventSlot, &index) ? index : -1;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	
-	{
-		bool hasScrollBar;
-		if (dom.findBool(node, "scrollBar", &hasScrollBar))
-			this->setHasScrollBar(hasScrollBar);
-	}
-
-	const SkDOM::Node*	child;
-
-	if ((child = dom.getFirstChild(node, "bindings")) != NULL)
-	{
-		delete[] fBindings;
-		fBindings = NULL;
-		fBindingCount = 0;
-
-		SkListSource* listSrc = SkListSource::Factory(dom.findAttr(child, "data-fields"));
-		SkASSERT(listSrc);
-		fSkinName.set(dom.findAttr(child, "skin-slots"));
-		SkASSERT(fSkinName.size());
-
-		this->setListSource(listSrc)->unref();
-			
-		int count = dom.countChildren(child, "bind");
-		if (count > 0)
-		{
-			fBindings = new BindingRec[count];
-			count = 0;	// reuse this to count up to the number of valid bindings
-
-			child = dom.getFirstChild(child, "bind");
-			SkASSERT(child);
-			do {
-				const char* fieldName = dom.findAttr(child, "field");
-				const char* slotName = dom.findAttr(child, "slot");
-				if (fieldName && slotName)
-				{
-					fBindings[count].fFieldIndex = listSrc->findFieldIndex(fieldName);
-					if (fBindings[count].fFieldIndex >= 0)
-						fBindings[count++].fSlotName.set(slotName);
-				}
-			} while ((child = dom.getNextSibling(child, "bind")) != NULL);
-
-			fBindingCount = SkToU16(count);
-			if (count == 0)
-			{
-				SkDEBUGF(("SkListView::onInflate: no valid <bind> elements in <listsource>\n"));
-				delete[] fBindings;
-			}
-		}
-		this->dirtyCache(kAnimCount_DirtyFlag);
-		this->setSelection(0);
-	}
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkXMLListSource : public SkListSource {
-public:
-	SkXMLListSource(const char doc[], size_t len);
-	virtual ~SkXMLListSource()
-	{
-		delete[] fFields;
-		delete[] fRecords;
-	}
-
-	virtual int countFields() { return fFieldCount; }
-	virtual void getFieldName(int index, SkString* field)
-	{
-		SkASSERT((unsigned)index < (unsigned)fFieldCount);
-		if (field)
-			*field = fFields[index];
-	}
-	virtual int findFieldIndex(const char field[])
-	{
-		for (int i = 0; i < fFieldCount; i++)
-			if (fFields[i].equals(field))
-				return i;
-		return -1;
-	}
-
-	virtual int	countRecords() { return fRecordCount; }
-	virtual void getRecord(int rowIndex, int fieldIndex, SkString* data)
-	{
-		SkASSERT((unsigned)rowIndex < (unsigned)fRecordCount);
-		SkASSERT((unsigned)fieldIndex < (unsigned)fFieldCount);
-		if (data)
-			*data = fRecords[rowIndex * fFieldCount + fieldIndex];
-	}
-
-	virtual bool prepareWidgetEvent(SkEvent* evt, int rowIndex)
-	{
-		// hack, for testing right now. Need the xml to tell us what to jam in and where
-		SkString	data;
-		
-		this->getRecord(rowIndex, 0, &data);
-		evt->setString("xml-listsource", data.c_str());
-		return true;
-	}
-	
-private:
-	SkString*	fFields;	// [fFieldCount]
-	SkString*	fRecords;	// [fRecordCount][fFieldCount]
-	int			fFieldCount, fRecordCount;
-};
-
-#include "SkDOM.h"
-
-SkXMLListSource::SkXMLListSource(const char doc[], size_t len)
-{
-	fFieldCount = fRecordCount = 0;
-	fFields = fRecords = NULL;
-
-	SkDOM	dom;
-
-	const SkDOM::Node* node = dom.build(doc, len);
-	SkASSERT(node);
-	const SkDOM::Node*	child;	
-
-	child = dom.getFirstChild(node, "fields");
-	if (child)
-	{
-		fFieldCount = dom.countChildren(child, "field");
-		fFields = new SkString[fFieldCount];
-
-		int n = 0;
-		child = dom.getFirstChild(child, "field");
-		while (child)
-		{
-			fFields[n].set(dom.findAttr(child, "name"));
-			child = dom.getNextSibling(child, "field");
-			n += 1;
-		}
-		SkASSERT(n == fFieldCount);
-	}
-	
-	child = dom.getFirstChild(node, "records");
-	if (child)
-	{
-		fRecordCount = dom.countChildren(child, "record");
-		fRecords = new SkString[fRecordCount * fFieldCount];
-
-		int n = 0;
-		child = dom.getFirstChild(child, "record");
-		while (child)
-		{
-			for (int i = 0; i < fFieldCount; i++)
-				fRecords[n * fFieldCount + i].set(dom.findAttr(child, fFields[i].c_str()));
-			child = dom.getNextSibling(child, "record");
-			n += 1;
-		}
-		SkASSERT(n == fRecordCount);
-	}
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-SkListSource* SkListSource::Factory(const char name[])
-{
-	static const char gDoc[] =
-		"<db name='contacts.db'>"
-			"<fields>"
-				"<field name='name'/>"
-				"<field name='work-num'/>"
-				"<field name='home-num'/>"
-				"<field name='type'/>"
-			"</fields>"
-			"<records>"
-				"<record name='Andy McFadden' work-num='919 357-1234' home-num='919 123-4567' type='0'/>"
-				"<record name='Brian Swetland' work-num='919 123-1234' home-num='929 123-4567' type='1' />"
-				"<record name='Chris Desalvo' work-num='919 345-1234' home-num='949 123-4567' type='1' />"
-				"<record name='Chris White' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-				"<record name='Dan Bornstein' work-num='919 357-1234' home-num='919 123-4567' type='0' />"
-				"<record name='Don Cung' work-num='919 123-1234' home-num='929 123-4567' type='2' />"
-				"<record name='Eric Fischer' work-num='919 345-1234' home-num='949 123-4567' type='2' />"
-				"<record name='Ficus Kirkpatric' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-				"<record name='Jack Veenstra' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-				"<record name='Jeff Yaksick' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-				"<record name='Joe Onorato' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-				"<record name='Mathias Agopian' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-				"<record name='Mike Fleming' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-				"<record name='Nick Sears' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-				"<record name='Rich Miner' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-				"<record name='Tracey Cole' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-				"<record name='Wei Huang' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-			"</records>"
-		"</db>";
-		
-//SkDebugf("doc size %d\n", sizeof(gDoc)-1);
-	return new SkXMLListSource(gDoc, sizeof(gDoc) - 1);
-}
-
-
-
diff --git a/src/views/SkMetaData.cpp b/src/views/SkMetaData.cpp
deleted file mode 100644
index c871efb..0000000
--- a/src/views/SkMetaData.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/* libs/graphics/views/SkMetaData.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkMetaData.h"
-
-SkMetaData::SkMetaData() : fRec(NULL)
-{
-}
-
-SkMetaData::SkMetaData(const SkMetaData& src) : fRec(NULL)
-{
-    *this = src;
-}
-
-SkMetaData::~SkMetaData()
-{
-    this->reset();
-}
-
-void SkMetaData::reset()
-{
-    Rec* rec = fRec;
-    while (rec)
-    {
-        Rec* next = rec->fNext;
-        Rec::Free(rec);
-        rec = next;
-    }
-    fRec = NULL;
-}
-
-SkMetaData& SkMetaData::operator=(const SkMetaData& src)
-{
-    this->reset();
-
-    const Rec* rec = src.fRec;
-    while (rec)
-    {
-        this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount);
-        rec = rec->fNext;
-    }
-    return *this;
-}
-
-void SkMetaData::setS32(const char name[], int32_t value)
-{
-    (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1);
-}
-
-void SkMetaData::setScalar(const char name[], SkScalar value)
-{
-    (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1);
-}
-
-SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[])
-{
-    SkASSERT(count > 0);
-    if (count > 0)
-        return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count);
-    return NULL;
-}
-
-void SkMetaData::setString(const char name[], const char value[])
-{
-    (void)this->set(name, value, sizeof(char), kString_Type, strlen(value) + 1);
-}
-
-void SkMetaData::setPtr(const char name[], void* ptr)
-{
-    (void)this->set(name, &ptr, sizeof(void*), kPtr_Type, 1);
-}
-
-void SkMetaData::setBool(const char name[], bool value)
-{
-    (void)this->set(name, &value, sizeof(bool), kBool_Type, 1);
-}
-
-void SkMetaData::setData(const char name[], const void* data, size_t byteCount) {
-    (void)this->set(name, data, sizeof(char), kData_Type, byteCount);
-}
-
-void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count)
-{
-    SkASSERT(name);
-    SkASSERT(dataSize);
-    SkASSERT(count > 0);
-
-    (void)this->remove(name, type);
-
-    size_t  len = strlen(name);
-    Rec*    rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1);
-
-#ifndef SK_DEBUG
-    rec->fType = SkToU8(type);
-#else
-    rec->fType = type;
-#endif
-    rec->fDataLen = SkToU8(dataSize);
-    rec->fDataCount = SkToU16(count);
-    if (data)
-        memcpy(rec->data(), data, dataSize * count);
-    memcpy(rec->name(), name, len + 1);
-
-#ifdef SK_DEBUG
-    rec->fName = rec->name();
-    switch (type) {
-    case kS32_Type:
-        rec->fData.fS32 = *(const int32_t*)rec->data();
-        break;
-    case kScalar_Type:
-        rec->fData.fScalar = *(const SkScalar*)rec->data();
-        break;
-    case kString_Type:
-        rec->fData.fString = (const char*)rec->data();
-        break;
-    case kPtr_Type:
-        rec->fData.fPtr = *(void**)rec->data();
-        break;
-    case kBool_Type:
-        rec->fData.fBool = *(const bool*)rec->data();
-        break;
-    case kData_Type:
-        rec->fData.fPtr = rec->data();
-        break;
-    default:
-        SkASSERT(!"bad type");
-        break;
-    }
-#endif
-
-    rec->fNext = fRec;
-    fRec = rec;
-    return rec->data();
-}
-
-bool SkMetaData::findS32(const char name[], int32_t* value) const
-{
-    const Rec* rec = this->find(name, kS32_Type);
-    if (rec)
-    {
-        SkASSERT(rec->fDataCount == 1);
-        if (value)
-            *value = *(const int32_t*)rec->data();
-        return true;
-    }
-    return false;
-}
-
-bool SkMetaData::findScalar(const char name[], SkScalar* value) const
-{
-    const Rec* rec = this->find(name, kScalar_Type);
-    if (rec)
-    {
-        SkASSERT(rec->fDataCount == 1);
-        if (value)
-            *value = *(const SkScalar*)rec->data();
-        return true;
-    }
-    return false;
-}
-
-const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const
-{
-    const Rec* rec = this->find(name, kScalar_Type);
-    if (rec)
-    {
-        if (count)
-            *count = rec->fDataCount;
-        if (values)
-            memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen);
-        return (const SkScalar*)rec->data();
-    }
-    return NULL;
-}
-
-bool SkMetaData::findPtr(const char name[], void** value) const
-{
-    const Rec* rec = this->find(name, kPtr_Type);
-    if (rec)
-    {
-        SkASSERT(rec->fDataCount == 1);
-        if (value)
-            *value = *(void**)rec->data();
-        return true;
-    }
-    return false;
-}
-
-const char* SkMetaData::findString(const char name[]) const
-{
-    const Rec* rec = this->find(name, kString_Type);
-    SkASSERT(rec == NULL || rec->fDataLen == sizeof(char));
-    return rec ? (const char*)rec->data() : NULL;
-}
-
-bool SkMetaData::findBool(const char name[], bool* value) const
-{
-    const Rec* rec = this->find(name, kBool_Type);
-    if (rec)
-    {
-        SkASSERT(rec->fDataCount == 1);
-        if (value)
-            *value = *(const bool*)rec->data();
-        return true;
-    }
-    return false;
-}
-
-const void* SkMetaData::findData(const char name[], size_t* length) const {
-    const Rec* rec = this->find(name, kData_Type);
-    if (rec) {
-        SkASSERT(rec->fDataLen == sizeof(char));
-        if (length) {
-            *length = rec->fDataCount;
-        }
-        return rec->data();
-    }
-    return NULL;
-}
-
-const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const
-{
-    const Rec* rec = fRec;
-    while (rec)
-    {
-        if (rec->fType == type && !strcmp(rec->name(), name))
-            return rec;
-        rec = rec->fNext;
-    }
-    return NULL;
-}
-
-bool SkMetaData::remove(const char name[], Type type)
-{
-    Rec* rec = fRec;
-    Rec* prev = NULL;
-    while (rec)
-    {
-        Rec* next = rec->fNext;
-        if (rec->fType == type && !strcmp(rec->name(), name))
-        {
-            if (prev)
-                prev->fNext = next;
-            else
-                fRec = next;
-            Rec::Free(rec);
-            return true;
-        }
-        prev = rec;
-        rec = next;
-    }
-    return false;
-}
-
-bool SkMetaData::removeS32(const char name[])
-{
-    return this->remove(name, kS32_Type);
-}
-
-bool SkMetaData::removeScalar(const char name[])
-{
-    return this->remove(name, kScalar_Type);
-}
-
-bool SkMetaData::removeString(const char name[])
-{
-    return this->remove(name, kString_Type);
-}
-
-bool SkMetaData::removePtr(const char name[])
-{
-    return this->remove(name, kPtr_Type);
-}
-
-bool SkMetaData::removeBool(const char name[])
-{
-    return this->remove(name, kBool_Type);
-}
-
-bool SkMetaData::removeData(const char name[]) {
-    return this->remove(name, kData_Type);
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-
-SkMetaData::Iter::Iter(const SkMetaData& metadata)
-{
-    fRec = metadata.fRec;
-}
-
-void SkMetaData::Iter::reset(const SkMetaData& metadata)
-{
-    fRec = metadata.fRec;
-}
-
-const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count)
-{
-    const char* name = NULL;
-
-    if (fRec)
-    {
-        if (t)
-            *t = (SkMetaData::Type)fRec->fType;
-        if (count)
-            *count = fRec->fDataCount;
-        name = fRec->name();
-
-        fRec = fRec->fNext;
-    }
-    return name;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-
-SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size)
-{
-    return (Rec*)sk_malloc_throw(size);
-}
-
-void SkMetaData::Rec::Free(Rec* rec)
-{
-    sk_free(rec);
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-
-void SkMetaData::UnitTest()
-{
-#ifdef SK_SUPPORT_UNITTEST
-    SkMetaData  m1;
-
-    SkASSERT(!m1.findS32("int"));
-    SkASSERT(!m1.findScalar("scalar"));
-    SkASSERT(!m1.findString("hello"));
-    SkASSERT(!m1.removeS32("int"));
-    SkASSERT(!m1.removeScalar("scalar"));
-    SkASSERT(!m1.removeString("hello"));
-    SkASSERT(!m1.removeString("true"));
-    SkASSERT(!m1.removeString("false"));
-
-    m1.setS32("int", 12345);
-    m1.setScalar("scalar", SK_Scalar1 * 42);
-    m1.setString("hello", "world");
-    m1.setPtr("ptr", &m1);
-    m1.setBool("true", true);
-    m1.setBool("false", false);
-
-    int32_t     n;
-    SkScalar    s;
-
-    m1.setScalar("scalar", SK_Scalar1/2);
-
-    SkASSERT(m1.findS32("int", &n) && n == 12345);
-    SkASSERT(m1.findScalar("scalar", &s) && s == SK_Scalar1/2);
-    SkASSERT(!strcmp(m1.findString("hello"), "world"));
-    SkASSERT(m1.hasBool("true", true));
-    SkASSERT(m1.hasBool("false", false));
-
-    Iter    iter(m1);
-    const char* name;
-
-    static const struct {
-        const char*         fName;
-        SkMetaData::Type    fType;
-        int                 fCount;
-    } gElems[] = {
-        { "int",    SkMetaData::kS32_Type,      1 },
-        { "scalar", SkMetaData::kScalar_Type,   1 },
-        { "ptr",    SkMetaData::kPtr_Type,      1 },
-        { "hello",  SkMetaData::kString_Type,   sizeof("world") },
-        { "true",   SkMetaData::kBool_Type,     1 },
-        { "false",  SkMetaData::kBool_Type,     1 }
-    };
-
-    int                 loop = 0;
-    int count;
-    SkMetaData::Type    t;
-    while ((name = iter.next(&t, &count)) != NULL)
-    {
-        int match = 0;
-        for (unsigned i = 0; i < SK_ARRAY_COUNT(gElems); i++)
-        {
-            if (!strcmp(name, gElems[i].fName))
-            {
-                match += 1;
-                SkASSERT(gElems[i].fType == t);
-                SkASSERT(gElems[i].fCount == count);
-            }
-        }
-        SkASSERT(match == 1);
-        loop += 1;
-    }
-    SkASSERT(loop == SK_ARRAY_COUNT(gElems));
-
-    SkASSERT(m1.removeS32("int"));
-    SkASSERT(m1.removeScalar("scalar"));
-    SkASSERT(m1.removeString("hello"));
-    SkASSERT(m1.removeBool("true"));
-    SkASSERT(m1.removeBool("false"));
-
-    SkASSERT(!m1.findS32("int"));
-    SkASSERT(!m1.findScalar("scalar"));
-    SkASSERT(!m1.findString("hello"));
-    SkASSERT(!m1.findBool("true"));
-    SkASSERT(!m1.findBool("false"));
-#endif
-}
-
-#endif
-
-
diff --git a/src/views/SkOSMenu.cpp b/src/views/SkOSMenu.cpp
deleted file mode 100644
index 3760ddd..0000000
--- a/src/views/SkOSMenu.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "SkOSMenu.h"
-
-static int gOSMenuCmd = 7000;
-
-SkOSMenu::SkOSMenu(const char title[])
-{
-	fTitle = title;
-}
-
-SkOSMenu::~SkOSMenu()
-{
-}
-
-int SkOSMenu::countItems() const
-{
-	return fItems.count();
-}
-
-void SkOSMenu::appendItem(const char title[], const char eventType[], int32_t eventData)
-{
-	Item* item = fItems.append();
-
-	item->fTitle	 = title;
-	item->fEventType = eventType;
-	item->fEventData = eventData;
-	item->fOSCmd	 = ++gOSMenuCmd;
-}
-
-SkEvent* SkOSMenu::createEvent(uint32_t os_cmd)
-{
-	const Item* iter = fItems.begin();
-	const Item*	stop = fItems.end();
-
-	while (iter < stop)
-	{
-		if (iter->fOSCmd == os_cmd)
-		{
-			SkEvent* evt = new SkEvent(iter->fEventType);
-			evt->setFast32(iter->fEventData);
-			return evt;
-		}
-		iter++;
-	}
-	return NULL;
-}
-
-const char* SkOSMenu::getItem(int index, uint32_t* cmdID) const
-{
-	if (cmdID)
-		*cmdID = fItems[index].fOSCmd;
-	return fItems[index].fTitle;
-}
-
diff --git a/src/views/SkParsePaint.cpp b/src/views/SkParsePaint.cpp
deleted file mode 100644
index a79f30c..0000000
--- a/src/views/SkParsePaint.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "SkParsePaint.h"
-#include "SkTSearch.h"
-#include "SkParse.h"
-#include "SkImageDecoder.h"
-#include "SkGradientShader.h"
-
-static SkShader* inflate_shader(const SkDOM& dom, const SkDOM::Node* node)
-{
-	if ((node = dom.getFirstChild(node, "shader")) == NULL)
-		return NULL;
-
-	const char* str;
-
-	if (dom.hasAttr(node, "type", "linear-gradient"))
-	{
-		SkColor		colors[2];
-		SkPoint		pts[2];
-
-		colors[0] = colors[1] = SK_ColorBLACK;	// need to initialized the alpha to opaque, since FindColor doesn't set it
-		if ((str = dom.findAttr(node, "c0")) != NULL &&
-			SkParse::FindColor(str, &colors[0]) &&
-			(str = dom.findAttr(node, "c1")) != NULL &&
-			SkParse::FindColor(str, &colors[1]) &&
-			dom.findScalars(node, "p0", &pts[0].fX, 2) &&
-			dom.findScalars(node, "p1", &pts[1].fX, 2))
-		{
-			SkShader::TileMode	mode = SkShader::kClamp_TileMode;
-			int					index;
-
-			if ((index = dom.findList(node, "tile-mode", "clamp,repeat,mirror")) >= 0)
-				mode = (SkShader::TileMode)index;
-			return SkGradientShader::CreateLinear(pts, colors, NULL, 2, mode);
-		}
-	}
-	else if (dom.hasAttr(node, "type", "bitmap"))
-	{
-		if ((str = dom.findAttr(node, "src")) == NULL)
-			return NULL;
-
-		SkBitmap	bm;
-
-		if (SkImageDecoder::DecodeFile(str, &bm))
-		{
-			SkShader::TileMode	mode = SkShader::kRepeat_TileMode;
-			int					index;
-
-			if ((index = dom.findList(node, "tile-mode", "clamp,repeat,mirror")) >= 0)
-				mode = (SkShader::TileMode)index;
-
-			return SkShader::CreateBitmapShader(bm, mode, mode);
-		}
-	}
-	return NULL;
-}
-
-void SkPaint_Inflate(SkPaint* paint, const SkDOM& dom, const SkDOM::Node* node)
-{
-	SkASSERT(paint);
-	SkASSERT(&dom);
-	SkASSERT(node);
-
-	SkScalar x;
-
-	if (dom.findScalar(node, "stroke-width", &x))
-		paint->setStrokeWidth(x);
-	if (dom.findScalar(node, "text-size", &x))
-		paint->setTextSize(x);
-	
-	bool	b;
-
-	SkASSERT("legacy: use is-stroke" && !dom.findBool(node, "is-frame", &b));
-
-	if (dom.findBool(node, "is-stroke", &b))
-		paint->setStyle(b ? SkPaint::kStroke_Style : SkPaint::kFill_Style);
-	if (dom.findBool(node, "is-antialias", &b))
-		paint->setAntiAlias(b);
-	if (dom.findBool(node, "is-lineartext", &b))
-		paint->setLinearText(b);
-
-	const char* str = dom.findAttr(node, "color");
-	if (str)
-	{
-		SkColor	c = paint->getColor();
-		if (SkParse::FindColor(str, &c))
-			paint->setColor(c);
-	}
-
-	// do this AFTER parsing for the color
-	if (dom.findScalar(node, "opacity", &x))
-	{
-		x = SkMaxScalar(0, SkMinScalar(x, SK_Scalar1));
-		paint->setAlpha(SkScalarRound(x * 255));
-	}
-
-	int	index = dom.findList(node, "text-anchor", "left,center,right");
-	if (index >= 0)
-		paint->setTextAlign((SkPaint::Align)index);
-
-	SkShader* shader = inflate_shader(dom, node);
-	if (shader)
-		paint->setShader(shader)->unref();
-}
-
diff --git a/src/views/SkProgressBarView.cpp b/src/views/SkProgressBarView.cpp
deleted file mode 100644
index a9fd516..0000000
--- a/src/views/SkProgressBarView.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "SkProgressBarView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkTime.h"
-#include "SkSystemEventTypes.h"
-
-SkProgressBarView::SkProgressBarView()
-{
-	init_skin_anim(kProgress_SkinEnum, &fAnim);
-	fAnim.setHostEventSink(this);
-	fProgress = 0;
-	fMax = 100;
-	
-}
-
-void SkProgressBarView::changeProgress(int diff)
-{
-	int newProg = fProgress + diff;
-	if (newProg > 0 && newProg < fMax)
-		this->setProgress(newProg);
-	//otherwise i'll just leave it as it is
-	//this implies that if a new max and progress are set, max must be set first
-}
-
-/*virtual*/ void SkProgressBarView::onDraw(SkCanvas* canvas)
-{
-	SkPaint						paint;		
-	SkAnimator::DifferenceType	diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-	
-	if (diff == SkAnimator::kDifferent)
-		this->inval(NULL);
-	else if (diff == SkAnimator::kPartiallyDifferent)
-	{
-		SkRect	bounds;
-		fAnim.getInvalBounds(&bounds);
-		this->inval(&bounds);
-	}
-}
-	
-/*virtual*/ bool SkProgressBarView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Inval))
-	{
-		this->inval(NULL);
-		return true;
-	}
-	if (evt.isType("recommendDim"))
-	{
-		SkScalar	height;
-		
-		if (evt.findScalar("y", &height))
-			this->setHeight(height);
-		return true;
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-/*virtual*/ void SkProgressBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	int32_t temp;
-	if (dom.findS32(node, "max", &temp))
-		this->setMax(temp);
-	if (dom.findS32(node, "progress", &temp))
-		this->setProgress(temp);
-}
-
-/*virtual*/ void SkProgressBarView::onSizeChange()
-{
-	this->INHERITED::onSizeChange();
-	SkEvent evt("user");
-	evt.setString("id", "setDim");
-	evt.setScalar("dimX", this->width());
-	evt.setScalar("dimY", this->height());
-	fAnim.doUserEvent(evt);
-}
-
-void SkProgressBarView::reset()
-{
-	fProgress = 0;
-	SkEvent e("user");
-	e.setString("id", "reset");
-	fAnim.doUserEvent(e);
-}
-
-void SkProgressBarView::setMax(int max)
-{
-	fMax = max;
-	SkEvent e("user");
-	e.setString("id", "setMax");
-	e.setS32("newMax", max);
-	fAnim.doUserEvent(e);
-}
-
-void SkProgressBarView::setProgress(int progress)
-{
-	fProgress = progress;
-	SkEvent e("user");
-	e.setString("id", "setProgress");
-	e.setS32("newProgress", progress);
-	fAnim.doUserEvent(e);
-}
diff --git a/src/views/SkProgressView.cpp b/src/views/SkProgressView.cpp
deleted file mode 100644
index a34c284..0000000
--- a/src/views/SkProgressView.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "SkWidget.h"
-#include "SkCanvas.h"
-#include "SkShader.h"
-#include "SkInterpolator.h"
-#include "SkTime.h"
-
-SkProgressView::SkProgressView(uint32_t flags) : SkView(flags), fOnShader(NULL), fOffShader(NULL)
-{
-	fValue = 0;
-	fMax = 0;
-	fInterp = NULL;
-	fDoInterp = false;
-}
-
-SkProgressView::~SkProgressView()
-{
-	delete fInterp;
-	fOnShader->safeUnref();
-	fOffShader->safeUnref();
-}
-
-void SkProgressView::setMax(U16CPU max)
-{
-	if (fMax != max)
-	{
-		fMax = SkToU16(max);
-		if (fValue > 0)
-			this->inval(NULL);
-	}
-}
-
-void SkProgressView::setValue(U16CPU value)
-{
-	if (fValue != value)
-	{
-		if (fDoInterp)
-		{
-			if (fInterp)
-				delete fInterp;
-			fInterp = new SkInterpolator(1, 2);
-			SkScalar x = (SkScalar)(fValue << 8);
-			fInterp->setKeyFrame(0, SkTime::GetMSecs(), &x, 0);
-			x = (SkScalar)(value << 8);
-			fInterp->setKeyFrame(1, SkTime::GetMSecs() + 333, &x);
-		}
-		fValue = SkToU16(value);
-		this->inval(NULL);
-	}
-}
-
-void SkProgressView::onDraw(SkCanvas* canvas)
-{
-	if (fMax == 0)
-		return;
-
-	SkFixed	percent;
-
-	if (fInterp)
-	{
-		SkScalar x;
-		if (fInterp->timeToValues(SkTime::GetMSecs(), &x) == SkInterpolator::kFreezeEnd_Result)
-		{
-			delete fInterp;
-			fInterp = NULL;
-		}
-		percent = (SkFixed)x;	// now its 16.8
-		percent = SkMax32(0, SkMin32(percent, fMax << 8));	// now its pinned
-		percent = SkFixedDiv(percent, fMax << 8);	// now its 0.16
-		this->inval(NULL);
-	}
-	else
-	{
-		U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
-		percent = SkFixedDiv(value, fMax);
-	}
-
-
-	SkRect	r;
-	SkPaint	p;
-
-	r.set(0, 0, this->width(), this->height());
-	p.setAntiAlias(true);
-	
-	r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
-	p.setStyle(SkPaint::kFill_Style);
-
-	p.setColor(SK_ColorDKGRAY);
-	p.setShader(fOnShader);
-	canvas->drawRect(r, p);
-
-	p.setColor(SK_ColorWHITE);
-	p.setShader(fOffShader);
-	r.fLeft = r.fRight;
-	r.fRight = this->width() - SK_Scalar1;
-	if (r.width() > 0)
-		canvas->drawRect(r, p);
-}
-
-#include "SkImageDecoder.h"
-
-static SkShader* inflate_shader(const char file[])
-{
-	SkBitmap	bm;
-
-	return SkImageDecoder::DecodeFile(file, &bm) ?
-			SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode) :
-			NULL;
-}
-
-void SkProgressView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	const char* s;
-
-	SkASSERT(fOnShader == NULL);
-	SkASSERT(fOffShader == NULL);
-
-	if ((s = dom.findAttr(node, "src-on")) != NULL)
-		fOnShader = inflate_shader(s);
-	if ((s = dom.findAttr(node, "src-off")) != NULL)
-		fOffShader = inflate_shader(s);
-	(void)dom.findBool(node, "do-interp", &fDoInterp);
-}
-
diff --git a/src/views/SkScrollBarView.cpp b/src/views/SkScrollBarView.cpp
deleted file mode 100644
index 2e087bd..0000000
--- a/src/views/SkScrollBarView.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "SkScrollBarView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-//see SkProgressBarView.cpp
-//#include "SkWidgetViews.cpp"
-
-SkScrollBarView::SkScrollBarView()
-{
-	fAnim.setHostEventSink(this);
-	init_skin_anim(kScroll_SkinEnum, &fAnim);
-
-	fTotalLength = 0;
-	fStartPoint = 0;
-	fShownLength = 0;
-
-	this->adjust();
-}
-
-void SkScrollBarView::setStart(unsigned start)
-{
-	if ((int)start < 0)
-		start = 0;
-	
-	if (fStartPoint != start)
-	{
-		fStartPoint = start;
-		this->adjust();
-	}
-}
-
-void SkScrollBarView::setShown(unsigned shown)
-{
-	if ((int)shown < 0)
-		shown = 0;
-
-	if (fShownLength != shown)
-	{
-		fShownLength = shown;
-		this->adjust();
-	}
-}
-
-void SkScrollBarView::setTotal(unsigned total)
-{
-	if ((int)total < 0)
-		total = 0;
-
-	if (fTotalLength != total)
-	{
-		fTotalLength = total;
-		this->adjust();
-	}
-}
-
-/* virtual */ void SkScrollBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	
-	int32_t value;
-	if (dom.findS32(node, "total", &value))
-		this->setTotal(value);
-	if (dom.findS32(node, "shown", &value))
-		this->setShown(value);
-}
-
-/*virtual*/ void SkScrollBarView::onSizeChange()
-{
-	this->INHERITED::onSizeChange();
-	SkEvent evt("user");
-	evt.setString("id", "setDim");
-	evt.setScalar("dimX", this->width());
-	evt.setScalar("dimY", this->height());
-	fAnim.doUserEvent(evt);
-}
-
-/*virtual*/ void SkScrollBarView::onDraw(SkCanvas* canvas)
-{
-	SkPaint						paint;		
-	SkAnimator::DifferenceType	diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-	
-	if (diff == SkAnimator::kDifferent)
-		this->inval(NULL);
-	else if (diff == SkAnimator::kPartiallyDifferent)
-	{
-		SkRect	bounds;
-		fAnim.getInvalBounds(&bounds);
-		this->inval(&bounds);
-	}
-}
-
-/*virtual*/ bool SkScrollBarView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Inval))
-	{
-		this->inval(NULL);
-		return true;
-	}
-	if (evt.isType("recommendDim"))
-	{
-		SkScalar	width;
-		
-		if (evt.findScalar("x", &width))
-			this->setWidth(width);
-		return true;
-	}
-
-	return this->INHERITED::onEvent(evt);
-}
-
-void SkScrollBarView::adjust()
-{
-	int total = fTotalLength;
-	int start = fStartPoint;
-	int shown = fShownLength;
-	int hideBar = 0;
-	
-	if (total <= 0 || shown <= 0 || shown >= total)	// no bar to show
-	{
-		total = 1;		// avoid divide-by-zero. should be done by skin/script
-		hideBar = 1;	// signal we don't want a thumb
-	}
-	else
-	{
-		if (start + shown > total)
-			start = total - shown;
-	}
-	
-	SkEvent e("user");
-	e.setString("id", "adjustScrollBar");
-	e.setScalar("_totalLength", SkIntToScalar(total));
-	e.setScalar("_startPoint", SkIntToScalar(start));
-	e.setScalar("_shownLength", SkIntToScalar(shown));
-//	e.setS32("hideBar", hideBar);
-	fAnim.doUserEvent(e);
-}
-
diff --git a/src/views/SkStackViewLayout.cpp b/src/views/SkStackViewLayout.cpp
deleted file mode 100644
index ae2e9e8..0000000
--- a/src/views/SkStackViewLayout.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-#include "SkStackViewLayout.h"
-
-SkStackViewLayout::SkStackViewLayout()
-{
-	fMargin.set(0, 0, 0, 0);
-	fSpacer	= 0;
-	fOrient	= kHorizontal_Orient;
-	fPack	= kStart_Pack;
-	fAlign	= kStart_Align;
-	fRound	= false;
-}
-
-void SkStackViewLayout::setOrient(Orient ori)
-{
-	SkASSERT((unsigned)ori < kOrientCount);
-	fOrient = SkToU8(ori);
-}
-
-void SkStackViewLayout::getMargin(SkRect* margin) const
-{
-	if (margin)
-		*margin = fMargin;
-}
-
-void SkStackViewLayout::setMargin(const SkRect& margin)
-{
-	fMargin = margin;
-}
-
-void SkStackViewLayout::setSpacer(SkScalar spacer)
-{
-	fSpacer = spacer;
-}
-
-void SkStackViewLayout::setPack(Pack pack)
-{
-	SkASSERT((unsigned)pack < kPackCount);
-	fPack = SkToU8(pack);
-}
-
-void SkStackViewLayout::setAlign(Align align)
-{
-	SkASSERT((unsigned)align < kAlignCount);
-	fAlign = SkToU8(align);
-}
-
-void SkStackViewLayout::setRound(bool r)
-{
-	fRound = SkToU8(r);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-typedef SkScalar (*AlignProc)(SkScalar childLimit, SkScalar parentLimit);
-typedef SkScalar (SkView::*GetSizeProc)() const;
-typedef void (SkView::*SetLocProc)(SkScalar coord);
-typedef void (SkView::*SetSizeProc)(SkScalar coord);
-
-static SkScalar left_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }
-static SkScalar center_align_proc(SkScalar childLimit, SkScalar parentLimit) { return SkScalarHalf(parentLimit - childLimit); }
-static SkScalar right_align_proc(SkScalar childLimit, SkScalar parentLimit) { return parentLimit - childLimit; }
-static SkScalar fill_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }
-
-/*	Measure the main-dimension for all the children. If a child is marked flex in that direction
-	ignore its current value but increment the counter for flexChildren
-*/
-static SkScalar compute_children_limit(SkView* parent, GetSizeProc sizeProc, int* count,
-									   uint32_t flexMask, int* flexCount)
-{
-	SkView::B2FIter	iter(parent);
-	SkView*			child;
-	SkScalar		limit = 0;
-	int				n = 0, flex = 0;
-
-	while ((child = iter.next()) != NULL)
-	{
-		n += 1;
-		if (child->getFlags() & flexMask)
-			flex += 1;
-		else
-			limit += (child->*sizeProc)();
-	}
-	if (count)
-		*count = n;
-	if (flexCount)
-		*flexCount = flex;
-	return limit;
-}
-
-void SkStackViewLayout::onLayoutChildren(SkView* parent)
-{
-	static AlignProc gAlignProcs[] = {
-		left_align_proc,
-		center_align_proc,
-		right_align_proc,
-		fill_align_proc
-	};
-
-	SkScalar			startM, endM, crossStartM, crossLimit;
-	GetSizeProc			mainGetSizeP, crossGetSizeP;
-	SetLocProc			mainLocP, crossLocP;
-	SetSizeProc			mainSetSizeP, crossSetSizeP;
-	SkView::Flag_Mask	flexMask;
-
-	if (fOrient == kHorizontal_Orient)
-	{
-		startM		= fMargin.fLeft;
-		endM		= fMargin.fRight;
-		crossStartM	= fMargin.fTop;
-		crossLimit	= -fMargin.fTop - fMargin.fBottom;
-
-		mainGetSizeP	= &SkView::width;
-		crossGetSizeP	= &SkView::height;
-		mainLocP	= &SkView::setLocX;
-		crossLocP	= &SkView::setLocY;
-
-		mainSetSizeP  = &SkView::setWidth;
-		crossSetSizeP = &SkView::setHeight;
-
-		flexMask	= SkView::kFlexH_Mask;
-	}
-	else
-	{
-		startM		= fMargin.fTop;
-		endM		= fMargin.fBottom;
-		crossStartM	= fMargin.fLeft;
-		crossLimit	= -fMargin.fLeft - fMargin.fRight;
-
-		mainGetSizeP	= &SkView::height;
-		crossGetSizeP	= &SkView::width;
-		mainLocP	= &SkView::setLocY;
-		crossLocP	= &SkView::setLocX;
-
-		mainSetSizeP  = &SkView::setHeight;
-		crossSetSizeP = &SkView::setWidth;
-
-		flexMask	= SkView::kFlexV_Mask;
-	}
-	crossLimit += (parent->*crossGetSizeP)();
-	if (fAlign != kStretch_Align)
-		crossSetSizeP = NULL;
-
-	int			childCount, flexCount;
-	SkScalar	childLimit = compute_children_limit(parent, mainGetSizeP, &childCount, flexMask, &flexCount);
-
-	if (childCount == 0)
-		return;
-
-	childLimit += (childCount - 1) * fSpacer;
-
-	SkScalar		parentLimit = (parent->*mainGetSizeP)() - startM - endM;
-	SkScalar		pos = startM + gAlignProcs[fPack](childLimit, parentLimit);
-	SkScalar		flexAmount = 0;
-	SkView::B2FIter	iter(parent);
-	SkView*			child;
-
-	if (flexCount > 0 && parentLimit > childLimit)
-		flexAmount = (parentLimit - childLimit) / flexCount;
-
-	while ((child = iter.next()) != NULL)
-	{
-		if (fRound)
-			pos = SkIntToScalar(SkScalarRound(pos));
-		(child->*mainLocP)(pos);
-		SkScalar crossLoc = crossStartM + gAlignProcs[fAlign]((child->*crossGetSizeP)(), crossLimit);
-		if (fRound)
-			crossLoc = SkIntToScalar(SkScalarRound(crossLoc));
-		(child->*crossLocP)(crossLoc);
-
-		if (crossSetSizeP)
-			(child->*crossSetSizeP)(crossLimit);
-		if (child->getFlags() & flexMask)
-			(child->*mainSetSizeP)(flexAmount);
-		pos += (child->*mainGetSizeP)() + fSpacer;
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-	{
-		const char* value = dom.findAttr(node, attr);
-		if (value)
-			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-	}
-#else
-	#define assert_no_attr(dom, node, attr)
-#endif
-
-void SkStackViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	int			index;
-	SkScalar	value[4];
-
-	if ((index = dom.findList(node, "orient", "horizontal,vertical")) >= 0)
-		this->setOrient((Orient)index);
-	else
-		assert_no_attr(dom, node, "orient");
-
-	if (dom.findScalars(node, "margin", value, 4))
-	{
-		SkRect	margin;
-		margin.set(value[0], value[1], value[2], value[3]);
-		this->setMargin(margin);
-	}
-	else
-		assert_no_attr(dom, node, "margin");
-
-	if (dom.findScalar(node, "spacer", value))
-		this->setSpacer(value[0]);
-	else
-		assert_no_attr(dom, node, "spacer");
-
-	if ((index = dom.findList(node, "pack", "start,center,end")) >= 0)
-		this->setPack((Pack)index);
-	else
-		assert_no_attr(dom, node, "pack");
-
-	if ((index = dom.findList(node, "align", "start,center,end,stretch")) >= 0)
-		this->setAlign((Align)index);
-	else
-		assert_no_attr(dom, node, "align");
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-SkFillViewLayout::SkFillViewLayout()
-{
-	fMargin.setEmpty();
-}
-
-void SkFillViewLayout::getMargin(SkRect* r) const
-{
-	if (r)
-		*r = fMargin;
-}
-
-void SkFillViewLayout::setMargin(const SkRect& margin)
-{
-	fMargin = margin;
-}
-
-void SkFillViewLayout::onLayoutChildren(SkView* parent)
-{
-	SkView::B2FIter	iter(parent);
-	SkView*			child;
-
-	while ((child = iter.next()) != NULL)
-	{
-		child->setLoc(fMargin.fLeft, fMargin.fTop);
-		child->setSize(	parent->width() - fMargin.fRight - fMargin.fLeft,
-						parent->height() - fMargin.fBottom - fMargin.fTop);
-	}
-}
-
-void SkFillViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	(void)dom.findScalars(node, "margin", (SkScalar*)&fMargin, 4);
-}
-
diff --git a/src/views/SkStaticTextView.cpp b/src/views/SkStaticTextView.cpp
deleted file mode 100644
index 8fb8bc1..0000000
--- a/src/views/SkStaticTextView.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-#include "SkWidgetViews.h"
-#include "SkTextBox.h"
-
-#ifdef SK_DEBUG
-static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-{
-    const char* value = dom.findAttr(node, attr);
-    if (value)
-        SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-}
-#else
-    #define assert_no_attr(dom, node, attr)
-#endif
-
-SkStaticTextView::SkStaticTextView()
-{
-	fMargin.set(0, 0);
-	fMode = kFixedSize_Mode;
-	fSpacingAlign = SkTextBox::kStart_SpacingAlign;
-	
-//	init_skin_paint(kStaticText_SkinEnum, &fPaint);
-}
-
-SkStaticTextView::~SkStaticTextView()
-{
-}
-
-void SkStaticTextView::computeSize()
-{
-	if (fMode == kAutoWidth_Mode)
-	{
-		SkScalar width = fPaint.measureText(fText.c_str(), fText.size());
-		this->setWidth(width + fMargin.fX * 2);
-	}
-	else if (fMode == kAutoHeight_Mode)
-	{
-		SkScalar width = this->width() - fMargin.fX * 2;
-		int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
-
-		this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2);
-	}
-}
-
-void SkStaticTextView::setMode(Mode mode)
-{
-	SkASSERT((unsigned)mode < kModeCount);
-
-	if (fMode != mode)
-	{
-		fMode = SkToU8(mode);
-		this->computeSize();
-	}
-}
-
-void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
-{
-	fSpacingAlign = SkToU8(align);
-	this->inval(NULL);
-}
-
-void SkStaticTextView::getMargin(SkPoint* margin) const
-{
-	if (margin)
-		*margin = fMargin;
-}
-
-void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
-{
-	if (fMargin.fX != dx || fMargin.fY != dy)
-	{
-		fMargin.set(dx, dy);
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-size_t SkStaticTextView::getText(SkString* text) const
-{
-	if (text)
-		*text = fText;
-	return fText.size();
-}
-
-size_t SkStaticTextView::getText(char text[]) const
-{
-	if (text)
-		memcpy(text, fText.c_str(), fText.size());
-	return fText.size();
-}
-
-void SkStaticTextView::setText(const SkString& text)
-{
-	this->setText(text.c_str(), text.size());
-}
-
-void SkStaticTextView::setText(const char text[])
-{
-	if (text == NULL)
-		text = "";
-	this->setText(text, strlen(text));
-}
-
-void SkStaticTextView::setText(const char text[], size_t len)
-{
-	if (!fText.equals(text, len))
-	{
-		fText.set(text, len);
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-void SkStaticTextView::getPaint(SkPaint* paint) const
-{
-	if (paint)
-		*paint = fPaint;
-}
-
-void SkStaticTextView::setPaint(const SkPaint& paint)
-{
-	if (fPaint != paint)
-	{
-		fPaint = paint;
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-void SkStaticTextView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	if (fText.isEmpty())
-		return;
-
-	SkTextBox	box;
-
-	box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
-	box.setSpacingAlign(this->getSpacingAlign());
-	box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
-	box.draw(canvas, fText.c_str(), fText.size(), fPaint);
-}
-
-void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-#if 0
-	this->INHERITED::onInflate(dom, node);
-
-	int	index;
-	if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
-		this->setMode((Mode)index);
-	else
-		assert_no_attr(dom, node, "mode");
-
-	if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
-		this->setSpacingAlign((SkTextBox::SpacingAlign)index);
-	else
-		assert_no_attr(dom, node, "spacing-align");
-
-	SkScalar s[2];
-	if (dom.findScalars(node, "margin", s, 2))
-		this->setMargin(s[0], s[1]);
-	else
-		assert_no_attr(dom, node, "margin");
-
-	const char* text = dom.findAttr(node, "text");
-	if (text)
-		this->setText(text);
-
-	if ((node = dom.getFirstChild(node, "paint")) != NULL &&
-		(node = dom.getFirstChild(node, "screenplay")) != NULL)
-	{
-		inflate_paint(dom, node, &fPaint);
-	}
-#endif
-}
-
diff --git a/src/views/SkTagList.cpp b/src/views/SkTagList.cpp
deleted file mode 100644
index 4576ce6..0000000
--- a/src/views/SkTagList.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* libs/graphics/views/SkTagList.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkTagList.h"
-
-SkTagList::~SkTagList()
-{
-}
-
-SkTagList* SkTagList::Find(SkTagList* rec, U8CPU tag)
-{
-    SkASSERT(tag < kSkTagListCount);
-
-    while (rec != NULL)
-    {
-        if (rec->fTag == tag)
-            break;
-        rec = rec->fNext;
-    }
-    return rec;
-}
-
-void SkTagList::DeleteTag(SkTagList** head, U8CPU tag)
-{
-    SkASSERT(tag < kSkTagListCount);
-
-    SkTagList* rec = *head;
-    SkTagList* prev = NULL;
-
-    while (rec != NULL)
-    {
-        SkTagList* next = rec->fNext;
-
-        if (rec->fTag == tag)
-        {
-            if (prev)
-                prev->fNext = next;
-            else
-                *head = next;
-            delete rec;
-            break;
-        }
-        prev = rec;
-        rec = next;
-    }
-}
-
-void SkTagList::DeleteAll(SkTagList* rec)
-{
-    while (rec)
-    {
-        SkTagList* next = rec->fNext;
-        delete rec;
-        rec = next;
-    }
-}
-
diff --git a/src/views/SkTagList.h b/src/views/SkTagList.h
deleted file mode 100644
index 5f428e4..0000000
--- a/src/views/SkTagList.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* libs/graphics/views/SkTagList.h
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#ifndef SkTagList_DEFINED
-#define SkTagList_DEFINED
-
-#include "SkTypes.h"
-
-enum SkTagListEnum {
-    kListeners_SkTagList,
-    kViewLayout_SkTagList,
-    kViewArtist_SkTagList,
-
-    kSkTagListCount
-};
-
-struct SkTagList {
-    SkTagList*  fNext;
-    uint16_t    fExtra16;
-    uint8_t     fExtra8;
-    uint8_t     fTag;
-
-    SkTagList(U8CPU tag) : fTag(SkToU8(tag))
-    {
-        SkASSERT(tag < kSkTagListCount);
-        fNext       = NULL;
-        fExtra16    = 0;
-        fExtra8     = 0;
-    }
-    virtual ~SkTagList();
-
-    static SkTagList*   Find(SkTagList* head, U8CPU tag);
-    static void         DeleteTag(SkTagList** headptr, U8CPU tag);
-    static void         DeleteAll(SkTagList* head);
-};
-
-#endif
diff --git a/src/views/SkTextBox.cpp b/src/views/SkTextBox.cpp
deleted file mode 100644
index 0e31ac6..0000000
--- a/src/views/SkTextBox.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* libs/graphics/views/SkTextBox.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include "SkTextBox.h"
-#include "../core/SkGlyphCache.h"
-#include "SkUtils.h"
-#include "SkAutoKern.h"
-
-static inline int is_ws(int c)
-{
-    return !((c - 1) >> 5);
-}
-
-static size_t linebreak(const char text[], const char stop[], const SkPaint& paint, SkScalar margin)
-{
-    const char* start = text;
-
-    SkAutoGlyphCache    ac(paint, NULL);
-    SkGlyphCache*       cache = ac.getCache();
-    SkFixed             w = 0;
-    SkFixed             limit = SkScalarToFixed(margin);
-    SkAutoKern          autokern;
-
-    const char* word_start = text;
-    int         prevWS = true;
-
-    while (text < stop)
-    {
-        const char* prevText = text;
-        SkUnichar   uni = SkUTF8_NextUnichar(&text);
-        int         currWS = is_ws(uni);
-        const SkGlyph&  glyph = cache->getUnicharMetrics(uni);
-
-        if (!currWS && prevWS)
-            word_start = prevText;
-        prevWS = currWS;
-
-        w += autokern.adjust(glyph) + glyph.fAdvanceX;
-        if (w > limit)
-        {
-            if (currWS) // eat the rest of the whitespace
-            {
-                while (text < stop && is_ws(SkUTF8_ToUnichar(text)))
-                    text += SkUTF8_CountUTF8Bytes(text);
-            }
-            else    // backup until a whitespace (or 1 char)
-            {
-                if (word_start == start)
-                {
-                    if (prevText > start)
-                        text = prevText;
-                }
-                else
-                    text = word_start;
-            }
-            break;
-        }
-    }
-    return text - start;
-}
-
-int SkTextLineBreaker::CountLines(const char text[], size_t len, const SkPaint& paint, SkScalar width)
-{
-    const char* stop = text + len;
-    int         count = 0;
-
-    if (width > 0)
-    {
-        do {
-            count += 1;
-            text += linebreak(text, stop, paint, width);
-        } while (text < stop);
-    }
-    return count;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-SkTextBox::SkTextBox()
-{
-    fBox.setEmpty();
-    fSpacingMul = SK_Scalar1;
-    fSpacingAdd = 0;
-    fMode = kLineBreak_Mode;
-    fSpacingAlign = kStart_SpacingAlign;
-}
-
-void SkTextBox::setMode(Mode mode)
-{
-    SkASSERT((unsigned)mode < kModeCount);
-    fMode = SkToU8(mode);
-}
-
-void SkTextBox::setSpacingAlign(SpacingAlign align)
-{
-    SkASSERT((unsigned)align < kSpacingAlignCount);
-    fSpacingAlign = SkToU8(align);
-}
-
-void SkTextBox::getBox(SkRect* box) const
-{
-    if (box)
-        *box = fBox;
-}
-
-void SkTextBox::setBox(const SkRect& box)
-{
-    fBox = box;
-}
-
-void SkTextBox::setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
-{
-    fBox.set(left, top, right, bottom);
-}
-
-void SkTextBox::getSpacing(SkScalar* mul, SkScalar* add) const
-{
-    if (mul)
-        *mul = fSpacingMul;
-    if (add)
-        *add = fSpacingAdd;
-}
-
-void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
-{
-    fSpacingMul = mul;
-    fSpacingAdd = add;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint)
-{
-    SkASSERT(canvas && &paint && (text || len == 0));
-
-    SkScalar marginWidth = fBox.width();
-
-    if (marginWidth <= 0 || len == 0)
-        return;
-
-    const char* textStop = text + len;
-
-    SkScalar                x, y, scaledSpacing, height, fontHeight;
-    SkPaint::FontMetrics    metrics;
-
-    switch (paint.getTextAlign()) {
-    case SkPaint::kLeft_Align:
-        x = 0;
-        break;
-    case SkPaint::kCenter_Align:
-        x = SkScalarHalf(marginWidth);
-        break;
-    default:
-        x = marginWidth;
-        break;
-    }
-    x += fBox.fLeft;
-
-    fontHeight = paint.getFontMetrics(&metrics);
-    scaledSpacing = SkScalarMul(fontHeight, fSpacingMul) + fSpacingAdd;
-    height = fBox.height();
-
-    //  compute Y position for first line
-    {
-        SkScalar textHeight = fontHeight;
-
-        if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign)
-        {
-            int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
-            SkASSERT(count > 0);
-            textHeight += scaledSpacing * (count - 1);
-        }
-
-        switch (fSpacingAlign) {
-        case kStart_SpacingAlign:
-            y = 0;
-            break;
-        case kCenter_SpacingAlign:
-            y = SkScalarHalf(height - textHeight);
-            break;
-        default:
-            SkASSERT(fSpacingAlign == kEnd_SpacingAlign);
-            y = height - textHeight;
-            break;
-        }
-        y += fBox.fTop - metrics.fAscent;
-    }
-
-    for (;;)
-    {
-        len = linebreak(text, textStop, paint, marginWidth);
-        if (y + metrics.fDescent + metrics.fLeading > 0)
-            canvas->drawText(text, len, x, y, paint);
-        text += len;
-        if (text >= textStop)
-            break;
-        y += scaledSpacing;
-        if (y + metrics.fAscent >= height)
-            break;
-    } 
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
-    fText = text;
-    fLen = len;
-    fPaint = &paint;
-}
-
-void SkTextBox::draw(SkCanvas* canvas) {
-    this->draw(canvas, fText, fLen, *fPaint);
-}
-
-int SkTextBox::countLines() const {
-    return SkTextLineBreaker::CountLines(fText, fLen, *fPaint, fBox.width());
-}
-
-SkScalar SkTextBox::getTextHeight() const {
-    SkScalar spacing = SkScalarMul(fPaint->getTextSize(), fSpacingMul) + fSpacingAdd;
-    return this->countLines() * spacing;
-}
-
diff --git a/src/views/SkView.cpp b/src/views/SkView.cpp
deleted file mode 100644
index 7969d3d..0000000
--- a/src/views/SkView.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-#include "SkView.h"
-#include "SkCanvas.h"
-
-////////////////////////////////////////////////////////////////////////
-
-SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
-{
-	fWidth = fHeight = 0;
-	fLoc.set(0, 0);
-	fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
-	
-	fContainsFocus = 0;
-}
-
-SkView::~SkView()
-{
-	this->detachAllChildren();
-}
-
-void SkView::setFlags(uint32_t flags)
-{
-	SkASSERT((flags & ~kAllFlagMasks) == 0);
-
-	uint32_t diff = fFlags ^ flags;
-
-	if (diff & kVisible_Mask)
-		this->inval(NULL);
-
-	fFlags = SkToU8(flags);
-
-	if (diff & kVisible_Mask)
-	{
-		this->inval(NULL);
-	}
-}
-
-void SkView::setVisibleP(bool pred)
-{
-	this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
-}
-
-void SkView::setEnabledP(bool pred)
-{
-	this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
-}
-
-void SkView::setFocusableP(bool pred)
-{
-	this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
-}
-
-void SkView::setClipToBounds(bool pred) {
-    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
-}
-
-void SkView::setSize(SkScalar width, SkScalar height)
-{
-	width = SkMaxScalar(0, width);
-	height = SkMaxScalar(0, height);
-
-	if (fWidth != width || fHeight != height)
-	{
-		this->inval(NULL);
-		fWidth = width;
-		fHeight = height;
-		this->inval(NULL);
-		this->onSizeChange();
-		this->invokeLayout();
-	}
-}
-
-void SkView::setLoc(SkScalar x, SkScalar y)
-{
-	if (fLoc.fX != x || fLoc.fY != y)
-	{
-		this->inval(NULL);
-		fLoc.set(x, y);
-		this->inval(NULL);
-	}
-}
-
-void SkView::offset(SkScalar dx, SkScalar dy)
-{
-	if (dx || dy)
-		this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
-}
-
-void SkView::draw(SkCanvas* canvas)
-{
-	if (fWidth && fHeight && this->isVisible())
-	{
-		SkRect	r;
-		r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
-		if (this->isClipToBounds() &&
-            canvas->quickReject(r, SkCanvas::kBW_EdgeType)) {
-                return;
-        }
-
-		SkAutoCanvasRestore	as(canvas, true);
-
-        if (this->isClipToBounds()) {
-            canvas->clipRect(r);
-        }
-		canvas->translate(fLoc.fX, fLoc.fY);
-
-        if (fParent) {
-            fParent->beforeChild(this, canvas);
-        }
-
-        int sc = canvas->save();
-		this->onDraw(canvas);
-        canvas->restoreToCount(sc);
-
-        if (fParent) {
-            fParent->afterChild(this, canvas);
-        }
-        
-		B2FIter	iter(this);
-		SkView*	child;
-
-        SkCanvas* childCanvas = this->beforeChildren(canvas);
-
-		while ((child = iter.next()) != NULL)
-			child->draw(childCanvas);
-        
-        this->afterChildren(canvas);
-	}
-}
-
-void SkView::inval(SkRect* rect) {
-	SkView*	view = this;
-    SkRect storage;
-
-	for (;;) {
-        if (!view->isVisible()) {
-            return;
-        }
-        if (view->isClipToBounds()) {
-            SkRect bounds;
-            view->getLocalBounds(&bounds);
-            if (rect && !bounds.intersect(*rect)) {
-                return;
-            }
-            storage = bounds;
-            rect = &storage;
-        }
-        if (view->handleInval(rect)) {
-            return;
-        }
-
-		SkView* parent = view->fParent;
-        if (parent == NULL) {
-            return;
-        }
-
-        if (rect) {
-            rect->offset(view->fLoc.fX, view->fLoc.fY);
-        }
-        view = parent;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-bool SkView::setFocusView(SkView* fv)
-{
-	SkView* view = this;
-	
-	do {
-		if (view->onSetFocusView(fv))
-			return true;
-	} while ((view = view->fParent) != NULL);
-	return false;
-}
-
-SkView* SkView::getFocusView() const
-{
-	SkView*			focus = NULL;
-	const SkView*	view = this;
-	do {
-		if (view->onGetFocusView(&focus))
-			break;
-	} while ((view = view->fParent) != NULL);
-	return focus;
-}
-
-bool SkView::hasFocus() const
-{
-	return this == this->getFocusView();
-}
-
-bool SkView::acceptFocus()
-{
-	return this->isFocusable() && this->setFocusView(this);
-}
-
-/*
-	Try to give focus to this view, or its children
-*/
-SkView* SkView::acceptFocus(FocusDirection dir)
-{
-	if (dir == kNext_FocusDirection)
-	{
-		if (this->acceptFocus())
-			return this;
-
-		B2FIter	iter(this);
-		SkView*	child, *focus;
-		while ((child = iter.next()) != NULL)
-			if ((focus = child->acceptFocus(dir)) != NULL)
-				return focus;
-	}
-	else // prev
-	{
-		F2BIter	iter(this);
-		SkView*	child, *focus;
-		while ((child = iter.next()) != NULL)
-			if ((focus = child->acceptFocus(dir)) != NULL)
-				return focus;
-
-		if (this->acceptFocus())
-			return this;
-	}
-
-	return NULL;
-}
-
-SkView* SkView::moveFocus(FocusDirection dir)
-{
-	SkView* focus = this->getFocusView();
-
-	if (focus == NULL)
-	{	// start with the root
-		focus = this;
-		while (focus->fParent)
-			focus = focus->fParent;
-	}
-
-	SkView*	child, *parent;
-
-	if (dir == kNext_FocusDirection)
-	{
-		parent = focus;
-		child = focus->fFirstChild;
-		if (child)
-			goto FIRST_CHILD;
-		else
-			goto NEXT_SIB;
-
-		do {
-			while (child != parent->fFirstChild)
-			{
-	FIRST_CHILD:
-				if ((focus = child->acceptFocus(dir)) != NULL)
-					return focus;
-				child = child->fNextSibling;
-			}
-	NEXT_SIB:
-			child = parent->fNextSibling;
-			parent = parent->fParent;
-		} while (parent != NULL);
-	}
-	else	// prevfocus
-	{
-		parent = focus->fParent;
-		if (parent == NULL)	// we're the root
-			return focus->acceptFocus(dir);
-		else
-		{
-			child = focus;
-			while (parent)
-			{
-				while (child != parent->fFirstChild)
-				{
-					child = child->fPrevSibling;
-					if ((focus = child->acceptFocus(dir)) != NULL)
-						return focus;
-				}
-				if (parent->acceptFocus())
-					return parent;
-
-				child = parent;
-				parent = parent->fParent;
-			}
-		}
-	}
-	return NULL;
-}
-
-void SkView::onFocusChange(bool gainFocusP)
-{
-	this->inval(NULL);
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-SkView::Click::Click(SkView* target)
-{
-	SkASSERT(target);
-	fTargetID = target->getSinkID();
-	fType = NULL;
-	fWeOwnTheType = false;
-}
-
-SkView::Click::~Click()
-{
-	this->resetType();
-}
-
-void SkView::Click::resetType()
-{
-	if (fWeOwnTheType)
-	{
-		sk_free(fType);
-		fWeOwnTheType = false;
-	}
-	fType = NULL;
-}
-
-bool SkView::Click::isType(const char type[]) const
-{
-	const char* t = fType;
-
-	if (type == t)
-		return true;
-
-	if (type == NULL)
-		type = "";
-	if (t == NULL)
-		t = "";
-	return !strcmp(t, type);
-}
-
-void SkView::Click::setType(const char type[])
-{
-	this->resetType();
-	fType = (char*)type;
-}
-
-void SkView::Click::copyType(const char type[])
-{
-	if (fType != type)
-	{
-		this->resetType();
-		if (type)
-		{
-			size_t	len = strlen(type) + 1;
-			fType = (char*)sk_malloc_throw(len);
-			memcpy(fType, type, len);
-			fWeOwnTheType = true;
-		}
-	}
-}
-
-SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y)
-{
-	if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
-		return false;
-    }
-
-    if (this->onSendClickToChildren(x, y)) {
-        F2BIter	iter(this);
-        SkView*	child;
-
-        while ((child = iter.next()) != NULL)
-        {
-            Click* click = child->findClickHandler(x - child->fLoc.fX,
-                                                   y - child->fLoc.fY);
-            if (click) {
-                return click;
-            }
-        }
-    }
-	return this->onFindClickHandler(x, y);
-}
-
-void SkView::DoClickDown(Click* click, int x, int y)
-{
-	SkASSERT(click);
-
-	SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
-	if (target == NULL)
-		return;
-
-	click->fIOrig.set(x, y);
-	click->fICurr = click->fIPrev = click->fIOrig;
-
-	click->fOrig.iset(x, y);
-	target->globalToLocal(&click->fOrig);
-	click->fPrev = click->fCurr = click->fOrig;
-
-	click->fState = Click::kDown_State;
-	target->onClick(click);
-}
-
-void SkView::DoClickMoved(Click* click, int x, int y)
-{
-	SkASSERT(click);
-
-	SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
-	if (target == NULL)
-		return;
-
-	click->fIPrev = click->fICurr;
-	click->fICurr.set(x, y);
-
-	click->fPrev = click->fCurr;
-	click->fCurr.iset(x, y);
-	target->globalToLocal(&click->fCurr);
-
-	click->fState = Click::kMoved_State;
-	target->onClick(click);
-}
-
-void SkView::DoClickUp(Click* click, int x, int y)
-{
-	SkASSERT(click);
-
-	SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
-	if (target == NULL)
-		return;
-
-	click->fIPrev = click->fICurr;
-	click->fICurr.set(x, y);
-
-	click->fPrev = click->fCurr;
-	click->fCurr.iset(x, y);
-	target->globalToLocal(&click->fCurr);
-
-	click->fState = Click::kUp_State;
-	target->onClick(click);
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void SkView::invokeLayout() {
-	SkView::Layout* layout = this->getLayout();
-
-	if (layout) {
-		layout->layoutChildren(this);
-    }
-}
-
-void SkView::onDraw(SkCanvas* canvas) {
-	Artist* artist = this->getArtist();
-
-	if (artist) {
-		artist->draw(this, canvas);
-    }
-}
-
-void SkView::onSizeChange() {}
-
-bool SkView::onSendClickToChildren(SkScalar x, SkScalar y) {
-    return true;
-}
-
-SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y) {
-	return NULL;
-}
-
-bool SkView::onClick(Click*) {
-	return false;
-}
-
-bool SkView::handleInval(const SkRect*) {
-	return false;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void SkView::getLocalBounds(SkRect* bounds) const
-{
-	if (bounds)
-		bounds->set(0, 0, fWidth, fHeight);
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-void SkView::detachFromParent_NoLayout()
-{
-	if (fParent == NULL)
-		return;
-
-	if (fContainsFocus)
-		(void)this->setFocusView(NULL);
-
-	this->inval(NULL);
-
-	SkView*	next = NULL;
-
-	if (fNextSibling != this)	// do we have any siblings
-	{
-		fNextSibling->fPrevSibling = fPrevSibling;
-		fPrevSibling->fNextSibling = fNextSibling;
-		next = fNextSibling;
-	}
-
-	if (fParent->fFirstChild == this)
-		fParent->fFirstChild = next;
-
-	fParent = fNextSibling = fPrevSibling = NULL;
-
-	this->unref();
-}
-
-void SkView::detachFromParent()
-{
-	SkView* parent = fParent;
-
-	if (parent)
-	{
-		this->detachFromParent_NoLayout();
-		parent->invokeLayout();
-	}
-}
-
-SkView* SkView::attachChildToBack(SkView* child)
-{
-	SkASSERT(child != this);
-
-	if (child == NULL || fFirstChild == child)
-		goto DONE;
-
-	child->ref();
-	child->detachFromParent_NoLayout();
-
-	if (fFirstChild == NULL)
-	{
-		child->fNextSibling = child;
-		child->fPrevSibling = child;
-	}
-	else
-	{
-		child->fNextSibling = fFirstChild;
-		child->fPrevSibling = fFirstChild->fPrevSibling;
-		fFirstChild->fPrevSibling->fNextSibling = child;
-		fFirstChild->fPrevSibling = child;
-	}
-
-	fFirstChild = child;
-	child->fParent = this;
-	child->inval(NULL);
-
-	this->invokeLayout();
-DONE:
-	return child;
-}
-
-SkView* SkView::attachChildToFront(SkView* child)
-{
-	SkASSERT(child != this);
-
-	if (child == NULL || fFirstChild && fFirstChild->fPrevSibling == child)
-		goto DONE;
-
-	child->ref();
-	child->detachFromParent_NoLayout();
-
-	if (fFirstChild == NULL)
-	{
-		fFirstChild = child;
-		child->fNextSibling = child;
-		child->fPrevSibling = child;
-	}
-	else
-	{
-		child->fNextSibling = fFirstChild;
-		child->fPrevSibling = fFirstChild->fPrevSibling;
-		fFirstChild->fPrevSibling->fNextSibling = child;
-		fFirstChild->fPrevSibling = child;
-	}
-
-	child->fParent = this;
-	child->inval(NULL);
-
-	this->invokeLayout();
-DONE:
-	return child;
-}
-
-void SkView::detachAllChildren()
-{
-	while (fFirstChild)
-		fFirstChild->detachFromParent_NoLayout();
-}
-
-void SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
-{
-	SkASSERT(this);
-
-	if (local)
-	{
-		const SkView* view = this;
-		while (view)
-		{
-			x -= view->fLoc.fX;
-			y -= view->fLoc.fY;
-			view = view->fParent;
-		}
-		local->set(x, y);
-	}
-}
-
-//////////////////////////////////////////////////////////////////
-
-/*	Even if the subclass overrides onInflate, they should always be
-	sure to call the inherited method, so that we get called.
-*/
-void SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	SkScalar x, y;
-
-	x = this->locX();
-	y = this->locY();
-	(void)dom.findScalar(node, "x", &x);
-	(void)dom.findScalar(node, "y", &y);
-	this->setLoc(x, y);
-
-	x = this->width();
-	y = this->height();
-	(void)dom.findScalar(node, "width", &x);
-	(void)dom.findScalar(node, "height", &y);
-	this->setSize(x, y);
-
-	// inflate the flags
-
-	static const char* gFlagNames[] = {
-		"visible", "enabled", "focusable", "flexH", "flexV"
-	};
-	SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
-
-	bool     b;
-	uint32_t flags = this->getFlags();
-	for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
-		if (dom.findBool(node, gFlagNames[i], &b))
-			flags = SkSetClearShift(flags, b, i);
-	this->setFlags(flags);
-}
-
-void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->onInflate(dom, node);
-}
-
-void SkView::onPostInflate(const SkTDict<SkView*>&)
-{
-	// override in subclass as needed
-}
-
-void SkView::postInflate(const SkTDict<SkView*>& dict)
-{
-	this->onPostInflate(dict);
-
-	B2FIter	iter(this);
-	SkView*	child;
-	while ((child = iter.next()) != NULL)
-		child->postInflate(dict);
-}
-
-//////////////////////////////////////////////////////////////////
-
-SkView* SkView::sendEventToParents(const SkEvent& evt)
-{
-	SkView* parent = fParent;
-    
-	while (parent)
-	{
-		if (parent->doEvent(evt))
-			return parent;
-		parent = parent->fParent;
-	}
-	return NULL;
-}
-
-SkView* SkView::sendQueryToParents(SkEvent* evt) {
-	SkView* parent = fParent;
-    
-	while (parent) {
-		if (parent->doQuery(evt)) {
-			return parent;
-        }
-		parent = parent->fParent;
-	}
-	return NULL;
-}
-
-//////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////
-
-SkView::F2BIter::F2BIter(const SkView* parent)
-{
-	fFirstChild = parent ? parent->fFirstChild : NULL;
-	fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
-}
-
-SkView*	SkView::F2BIter::next()
-{
-	SkView* curr = fChild;
-
-	if (fChild)
-	{
-		if (fChild == fFirstChild)
-			fChild = NULL;
-		else
-			fChild = fChild->fPrevSibling;
-	}
-	return curr;
-}
-
-SkView::B2FIter::B2FIter(const SkView* parent)
-{
-	fFirstChild = parent ? parent->fFirstChild : NULL;
-	fChild = fFirstChild;
-}
-
-SkView*	SkView::B2FIter::next()
-{
-	SkView* curr = fChild;
-
-	if (fChild)
-	{
-		SkView* next = fChild->fNextSibling;
-		if (next == fFirstChild)
-			next = NULL;
-		fChild = next;
-	}
-	return curr;
-}
-
-//////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-
-static inline void show_if_nonzero(const char name[], SkScalar value)
-{
-	if (value)
-		SkDebugf("%s=\"%g\"", name, value/65536.);
-}
-
-static void tab(int level)
-{
-	for (int i = 0; i < level; i++)
-		SkDebugf("    ");
-}
-
-static void dumpview(const SkView* view, int level, bool recurse)
-{
-	tab(level);
-
-	SkDebugf("<view");
-	show_if_nonzero(" x", view->locX());
-	show_if_nonzero(" y", view->locY());
-	show_if_nonzero(" width", view->width());
-	show_if_nonzero(" height", view->height());
-
-	if (recurse)
-	{
-		SkView::B2FIter	iter(view);
-		SkView*			child;
-		bool			noChildren = true;
-
-		while ((child = iter.next()) != NULL)
-		{
-			if (noChildren)
-				SkDebugf(">\n");
-			noChildren = false;
-			dumpview(child, level + 1, true);
-		}
-
-		if (!noChildren)
-		{
-			tab(level);
-			SkDebugf("</view>\n");
-		}
-		else
-			goto ONELINER;
-	}
-	else
-	{
-	ONELINER:
-		SkDebugf(" />\n");
-	}
-}
-
-void SkView::dump(bool recurse) const
-{
-	dumpview(this, 0, recurse);
-}
-
-#endif
diff --git a/src/views/SkViewInflate.cpp b/src/views/SkViewInflate.cpp
deleted file mode 100644
index 8f5489d..0000000
--- a/src/views/SkViewInflate.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "SkViewInflate.h"
-#include "SkView.h"
-#include <stdio.h>
-
-SkViewInflate::SkViewInflate() : fIDs(kMinIDStrAlloc), fStrings(kMinIDStrAlloc)
-{
-}
-
-SkViewInflate::~SkViewInflate()
-{
-}
-
-void SkViewInflate::rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent)
-{
-	const char* str = dom.findAttr(node, "id");
-	if (str)
-		fIDs.set(str, parent);
-
-	const SkDOM::Node* child = dom.getFirstChild(node);
-	while (child)
-	{
-		SkView* view = this->createView(dom, child);
-		if (view)
-		{
-			this->rInflate(dom, child, view);
-			parent->attachChildToFront(view)->unref();
-		}
-		else
-		{
-			const char* name = dom.getName(child);
-			const char* target;
-
-			if (!strcmp(name, "listenTo") && (target = dom.findAttr(child, "target")) != NULL)
-				this->addIDStr(&fListenTo, parent, target);
-
-			if (!strcmp(name, "broadcastTo") && (target = dom.findAttr(child, "target")) != NULL)
-				this->addIDStr(&fBroadcastTo, parent, target);
-		}
-		child = dom.getNextSibling(child);
-	}
-
-	parent->setVisibleP(true);
-	this->inflateView(parent, dom, node);
-}
-
-void SkViewInflate::inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node)
-{
-	// called after all of view's children have been instantiated.
-	// this may be overridden by a subclass, to load in layout or other helpers
-	// they should call through to us (INHERITED) before or after their patch
-	view->inflate(dom, node);
-}
-
-SkView* SkViewInflate::inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root)
-{
-	fIDs.reset();
-
-	if (root == NULL)
-	{
-		root = this->createView(dom, node);
-		if (root == NULL)
-		{
-			printf("createView returned NULL on <%s>\n", dom.getName(node));
-			return NULL;
-		}
-	}
-	this->rInflate(dom, node, root);
-
-	// resolve listeners and broadcasters
-	{
-		SkView*			target;
-		const IDStr*	iter = fListenTo.begin();
-		const IDStr*	stop = fListenTo.end();
-		for (; iter < stop; iter++)
-		{
-			if (fIDs.find(iter->fStr, &target))
-				target->addListenerID(iter->fView->getSinkID());
-		}
-
-		iter = fBroadcastTo.begin();
-		stop = fBroadcastTo.end();
-		for (; iter < stop; iter++)
-		{
-			if (fIDs.find(iter->fStr, &target))
-				iter->fView->addListenerID(target->getSinkID());
-		}
-	}
-
-	// now that the tree is built, give everyone a shot at the ID dict
-	root->postInflate(fIDs);
-	return root;
-}
-
-SkView* SkViewInflate::inflate(const char xml[], size_t len, SkView* root)
-{
-	SkDOM				dom;
-	const SkDOM::Node*	node = dom.build(xml, len);
-
-	return node ? this->inflate(dom, node, root) : NULL;
-}
-
-SkView* SkViewInflate::findViewByID(const char id[]) const
-{
-	SkASSERT(id);
-	SkView* view;
-	return fIDs.find(id, &view) ? view : NULL;
-}
-
-SkView* SkViewInflate::createView(const SkDOM& dom, const SkDOM::Node* node)
-{
-	if (!strcmp(dom.getName(node), "view"))
-		return new SkView;
-	return NULL;
-}
-
-void SkViewInflate::addIDStr(SkTDArray<IDStr>* list, SkView* view, const char* str)
-{
-	size_t len = strlen(str) + 1;
-	IDStr* pair = list->append();
-	pair->fView = view;
-	pair->fStr = (char*)fStrings.alloc(len, SkChunkAlloc::kThrow_AllocFailType);
-	memcpy(pair->fStr, str, len);
-}
-
-#ifdef SK_DEBUG
-void SkViewInflate::dump() const
-{
-	const IDStr* iter = fListenTo.begin();
-	const IDStr* stop = fListenTo.end();
-	for (; iter < stop; iter++)
-		SkDebugf("inflate: listenTo(\"%s\")\n", iter->fStr);
-
-	iter = fBroadcastTo.begin();
-	stop = fBroadcastTo.end();
-	for (; iter < stop; iter++)
-		SkDebugf("inflate: broadcastFrom(\"%s\")\n", iter->fStr);
-}
-#endif
-
diff --git a/src/views/SkViewPriv.cpp b/src/views/SkViewPriv.cpp
deleted file mode 100644
index b03ca8c..0000000
--- a/src/views/SkViewPriv.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "SkViewPriv.h"
-
-//////////////////////////////////////////////////////////////////////
-
-void SkView::Artist::draw(SkView* view, SkCanvas* canvas)
-{
-	SkASSERT(view && canvas);
-	this->onDraw(view, canvas);
-}
-
-void SkView::Artist::inflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	SkASSERT(&dom && node);
-	this->onInflate(dom, node);
-}
-
-void SkView::Artist::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	// subclass should override this as needed
-}
-
-SkView::Artist* SkView::getArtist() const
-{
-	Artist_SkTagList* rec = (Artist_SkTagList*)this->findTagList(kViewArtist_SkTagList);
-	SkASSERT(rec == NULL || rec->fArtist != NULL);
-
-	return rec ? rec->fArtist : NULL;
-}
-
-SkView::Artist* SkView::setArtist(Artist* obj)
-{
-	if (obj == NULL)
-	{
-		this->removeTagList(kViewArtist_SkTagList);
-	}
-	else	// add/replace
-	{
-		Artist_SkTagList* rec = (Artist_SkTagList*)this->findTagList(kViewArtist_SkTagList);
-
-		if (rec)
-			SkRefCnt_SafeAssign(rec->fArtist, obj);
-		else
-			this->addTagList(new Artist_SkTagList(obj));
-	}
-	return obj;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void SkView::Layout::layoutChildren(SkView* parent)
-{
-	SkASSERT(parent);
-	if (parent->width() > 0 && parent->height() > 0)
-		this->onLayoutChildren(parent);
-}
-
-void SkView::Layout::inflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	SkASSERT(&dom && node);
-	this->onInflate(dom, node);
-}
-
-void SkView::Layout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	// subclass should override this as needed
-}
-
-SkView::Layout* SkView::getLayout() const
-{
-	Layout_SkTagList* rec = (Layout_SkTagList*)this->findTagList(kViewLayout_SkTagList);
-	SkASSERT(rec == NULL || rec->fLayout != NULL);
-
-	return rec ? rec->fLayout : NULL;
-}
-
-SkView::Layout* SkView::setLayout(Layout* obj, bool invokeLayoutNow)
-{
-	if (obj == NULL)
-	{
-		this->removeTagList(kViewLayout_SkTagList);
-	}
-	else	// add/replace
-	{
-		Layout_SkTagList* rec = (Layout_SkTagList*)this->findTagList(kViewLayout_SkTagList);
-
-		if (rec)
-			SkRefCnt_SafeAssign(rec->fLayout, obj);
-		else
-			this->addTagList(new Layout_SkTagList(obj));
-	}
-	
-	if (invokeLayoutNow)
-		this->invokeLayout();
-
-	return obj;
-}
-
diff --git a/src/views/SkViewPriv.h b/src/views/SkViewPriv.h
deleted file mode 100644
index 06ce59b..0000000
--- a/src/views/SkViewPriv.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef SkViewPriv_DEFINED
-#define SkViewPriv_DEFINED
-
-#include "SkView.h"
-#include "SkTagList.h"
-
-struct Layout_SkTagList : SkTagList {
-	SkView::Layout*	fLayout;
-
-	Layout_SkTagList(SkView::Layout* layout)
-		: SkTagList(kViewLayout_SkTagList), fLayout(layout)
-	{
-		SkASSERT(layout);
-		layout->ref();
-	}
-	virtual ~Layout_SkTagList()
-	{
-		fLayout->unref();
-	}
-};
-
-struct Artist_SkTagList : SkTagList {
-	SkView::Artist*	fArtist;
-
-	Artist_SkTagList(SkView::Artist* artist)
-		: SkTagList(kViewArtist_SkTagList), fArtist(artist)
-	{
-		SkASSERT(artist);
-		artist->ref();
-	}
-	virtual ~Artist_SkTagList()
-	{
-		fArtist->unref();
-	}
-};
-
-#endif
-
diff --git a/src/views/SkWidget.cpp b/src/views/SkWidget.cpp
deleted file mode 100644
index 4d055c4..0000000
--- a/src/views/SkWidget.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-#include "SkWidget.h"
-#include "SkCanvas.h"
-#include "SkInterpolator.h"
-#include "SkTime.h"
-#include "SkParsePaint.h"
-
-#if 0
-SkWidgetView::SkWidgetView(U32 flags) : SkView(flags)
-{
-}
-
-SkWidgetView::~SkWidgetView()
-{
-}
-
-const char* SkWidgetView::GetEventType()
-{
-	return "SkWidgetView";
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-class SkTextView::Interp {
-public:
-	Interp(const SkString& old, SkMSec now, SkMSec dur, AnimaDir dir) : fOldText(old), fInterp(1, 2)
-	{
-		SkScalar x = 0;
-		fInterp.setKeyFrame(0, now, &x, 0);
-		x = SK_Scalar1;
-		if (dir == kBackward_AnimDir)
-			x = -x;
-		fInterp.setKeyFrame(1, now + dur, &x);
-	}
-	bool draw(SkCanvas* canvas, const SkString& newText, SkScalar x, SkScalar y, SkPaint& paint)
-	{
-		SkScalar scale;
-
-		if (fInterp.timeToValues(SkTime::GetMSecs(), &scale) == SkInterpolator::kFreezeEnd_Result)
-		{
-			canvas->drawText(newText.c_str(), newText.size(), x, y, paint);
-			return false;
-		}
-		else
-		{
-			U8 alpha = paint.getAlpha();
-			SkScalar above, below;
-			(void)paint.measureText(NULL, 0, &above, &below);
-			SkScalar height = below - above;
-			SkScalar dy = SkScalarMul(height, scale);
-			if (scale < 0)
-				height = -height;
-
-			// draw the old
-			paint.setAlpha((U8)SkScalarMul(alpha, SK_Scalar1 - SkScalarAbs(scale)));
-			canvas->drawText(fOldText.c_str(), fOldText.size(), x, y - dy, paint);
-			// draw the new
-			paint.setAlpha((U8)SkScalarMul(alpha, SkScalarAbs(scale)));
-			canvas->drawText(newText.c_str(), newText.size(), x, y + height - dy, paint);
-			// restore the paint
-			paint.setAlpha(alpha);
-			return true;
-		}
-	}
-
-private:
-	SkString		fOldText;
-	SkInterpolator	fInterp;
-};
-
-SkTextView::SkTextView(U32 flags) : SkView(flags), fInterp(NULL), fDoInterp(false)
-{
-	fMargin.set(0, 0);
-}
-
-SkTextView::~SkTextView()
-{
-	delete fInterp;
-}
-
-void SkTextView::getText(SkString* str) const
-{
-	if (str)
-		str->set(fText);
-}
-
-void SkTextView::setText(const char text[], AnimaDir dir)
-{
-	if (!fText.equals(text))
-	{
-		SkString tmp(text);
-		this->privSetText(tmp, dir);
-	}
-}
-
-void SkTextView::setText(const char text[], size_t len, AnimaDir dir)
-{
-	if (!fText.equals(text))
-	{
-		SkString tmp(text, len);
-		this->privSetText(tmp, dir);
-	}
-}
-
-void SkTextView::setText(const SkString& src, AnimaDir dir)
-{
-	if (fText != src)
-		this->privSetText(src, dir);
-}
-
-void SkTextView::privSetText(const SkString& src, AnimaDir dir)
-{
-	SkASSERT(fText != src);
-
-	if (fDoInterp)
-	{
-		if (fInterp)
-			delete fInterp;
-		fInterp = new Interp(fText, SkTime::GetMSecs(), 500, dir);
-	}
-	fText = src;
-	this->inval(NULL);
-}
-
-/////////////////////////////////////////////////////////////////
-
-void SkTextView::getMargin(SkPoint* margin) const
-{
-	if (margin)
-		*margin = fMargin;
-}
-
-void SkTextView::setMargin(const SkPoint& margin)
-{
-	if (fMargin != margin)
-	{
-		fMargin = margin;
-		this->inval(NULL);
-	}
-}
-
-void SkTextView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	if (fText.size() == 0)
-		return;
-
-	SkPaint::Align	align = fPaint.getTextAlign();
-	SkScalar		x, y;
-
-	switch (align) {
-	case SkPaint::kLeft_Align:
-		x = fMargin.fX;
-		break;
-	case SkPaint::kCenter_Align:
-		x = SkScalarHalf(this->width());
-		break;
-	default:
-		SkASSERT(align == SkPaint::kRight_Align);
-		x = this->width() - fMargin.fX;
-		break;
-	}
-
-	fPaint.measureText(NULL, 0, &y, NULL);
-	y = fMargin.fY - y;
-
-	if (fInterp)
-	{
-		if (fInterp->draw(canvas, fText, x, y, fPaint))
-			this->inval(NULL);
-		else
-		{
-			delete fInterp;
-			fInterp = NULL;
-		}
-	}
-	else
-		canvas->drawText(fText.c_str(), fText.size(), x, y, fPaint);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-
-void SkTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	const char* text = dom.findAttr(node, "text");
-	if (text)
-		this->setText(text);
-
-	SkPoint	margin;
-	if (dom.findScalars(node, "margin", (SkScalar*)&margin, 2))
-		this->setMargin(margin);
-	(void)dom.findBool(node, "do-interp", &fDoInterp);
-
-	SkPaint_Inflate(&fPaint, dom, node);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-
-SkSliderView::SkSliderView(U32 flags) : SkWidgetView(flags)
-{
-	fValue = 0;
-	fMax = 0;
-}
-
-static U16 actual_value(U16CPU value, U16CPU max)
-{
-	return SkToU16(SkMax32(0, SkMin32(value, max)));
-}
-
-void SkSliderView::setMax(U16CPU max)
-{
-	if (fMax != max)
-	{
-		fMax = SkToU16(max);
-		if (fValue > 0)
-			this->inval(NULL);
-	}
-}
-
-void SkSliderView::setValue(U16CPU value)
-{
-	if (fValue != value)
-	{
-		U16 prev = actual_value(fValue, fMax);
-		U16 next = actual_value(value, fMax);
-
-		fValue = SkToU16(value);
-		if (prev != next)
-		{
-			this->inval(NULL);
-
-			if (this->hasListeners())
-			{
-				SkEvent	evt;
-				
-				evt.setType(SkWidgetView::GetEventType());
-				evt.setFast32(this->getSinkID());
-				evt.setS32("sliderValue", next);
-				this->postToListeners(evt);
-			}
-		}
-	}
-}
-
-#include "SkGradientShader.h"
-
-static void setgrad(SkPaint* paint, const SkRect& r)
-{
-	SkPoint	pts[2];
-	SkColor	colors[2];
-
-#if 0
-	pts[0].set(r.fLeft, r.fTop);
-	pts[1].set(r.fLeft + r.height(), r.fBottom);
-#else
-	pts[0].set(r.fRight, r.fBottom);
-	pts[1].set(r.fRight - r.height(), r.fTop);
-#endif
-	colors[0] = SK_ColorBLUE;
-	colors[1] = SK_ColorWHITE;
-
-	paint->setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kMirror_TileMode))->unref();
-}
-
-void SkSliderView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
-
-	SkRect	r;
-	SkPaint	p;
-
-	r.set(0, 0, this->width(), this->height());
-
-	p.setAntiAliasOn(true);
-	p.setStyle(SkPaint::kStroke_Style);
-	p.setStrokeWidth(SK_Scalar1);
-	r.inset(SK_Scalar1/2, SK_Scalar1/2);
-	canvas->drawRect(r, p);
-
-	if (fMax)
-	{
-		SkFixed percent = SkFixedDiv(value, fMax);
-		
-		r.inset(SK_Scalar1/2, SK_Scalar1/2);
-		r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
-		p.setStyle(SkPaint::kFill_Style);
-		setgrad(&p, r);
-		canvas->drawRect(r, p);
-	}
-
-#if 0
-	r.set(0, 0, this->width(), this->height());
-	r.inset(SK_Scalar1, SK_Scalar1);
-	r.inset(r.width()/2, 0);
-	p.setColor(SK_ColorBLACK);
-	canvas->drawLine(*(SkPoint*)&r.fLeft, *(SkPoint*)&r.fRight, p);
-#endif
-}
-
-SkView::Click* SkSliderView::onFindClickHandler(SkScalar x, SkScalar y)
-{
-	return new Click(this);
-}
-
-bool SkSliderView::onClick(Click* click)
-{
-	if (fMax)
-	{
-		SkScalar percent = SkScalarDiv(click->fCurr.fX + SK_Scalar1, this->width() - SK_Scalar1*2);
-		percent = SkMaxScalar(0, SkMinScalar(percent, SK_Scalar1));
-		this->setValue(SkScalarRound(percent * fMax));
-		return true;
-	}
-	return false;
-}
-
-#endif
-
diff --git a/src/views/SkWidgetViews.cpp b/src/views/SkWidgetViews.cpp
deleted file mode 100644
index 109e620..0000000
--- a/src/views/SkWidgetViews.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-#include "SkWidgetViews.h"
-#include "SkAnimator.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-#include "SkStream.h"
-#include "SkSystemEventTypes.h"
-
-#ifdef SK_DEBUG
-	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-	{
-		const char* value = dom.findAttr(node, attr);
-		if (value)
-			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-	}
-#else
-	#define assert_no_attr(dom, node, attr)
-#endif
-/*
-I have moved this to SkWidgetViews.h
-enum SkinEnum {
-	kButton_SkinEnum,
-	kProgress_SkinEnum,
-	kScroll_SkinEnum,
-	kStaticText_SkinEnum,
-	
-	kSkinEnumCount
-};
-*/
-
-const char* get_skin_enum_path(SkinEnum se)
-{
-	SkASSERT((unsigned)se < kSkinEnumCount);
-
-	static const char* gSkinPaths[] = {
-            "common/default/default/skins/border3.xml",
-            "common/default/default/skins/button.xml",
-            "common/default/default/skins/progressBar.xml",
-            "common/default/default/skins/scrollBar.xml",
-            "common/default/default/skins/statictextpaint.xml"
-	};
-
-	return gSkinPaths[se];
-}
-
-void init_skin_anim(const char path[], SkAnimator* anim)
-{
-	SkASSERT(path && anim);
-
-	SkFILEStream	stream(path);
-
-	if (!stream.isValid())
-	{
-		SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path));
-		sk_throw();
-	}
-
-	if (!anim->decodeStream(&stream))
-	{
-		SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path));
-		sk_throw();
-	}
-}
-
-void init_skin_anim(SkinEnum se, SkAnimator* anim)
-{
-	init_skin_anim(get_skin_enum_path(se), anim);
-}
-
-void init_skin_paint(SkinEnum se, SkPaint* paint)
-{
-	SkASSERT(paint);
-
-	SkAnimator	anim;
-	SkCanvas	canvas;
-	
-	init_skin_anim(se, &anim);
-	anim.draw(&canvas, paint, 0);
-}
-
-void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint)
-{
-	SkASSERT(paint);
-
-	SkAnimator	anim;
-	SkCanvas	canvas;
-	
-	if (!anim.decodeDOM(dom, node))
-	{
-		SkDEBUGF(("inflate_paint: decoding dom failed\n"));
-		SkDEBUGCODE(dom.dump(node);)
-		sk_throw();
-	}	
-	anim.draw(&canvas, paint, 0);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-SkWidgetView::SkWidgetView() : SkView(SkView::kFocusable_Mask | SkView::kEnabled_Mask)
-{
-}
-
-const char* SkWidgetView::getLabel() const
-{
-	return fLabel.c_str();
-}
-	
-void SkWidgetView::getLabel(SkString* label) const
-{
-	if (label)
-		*label = fLabel;
-}
-
-void SkWidgetView::setLabel(const char label[])
-{
-	this->setLabel(label, label ? strlen(label) : 0);
-}
-
-void SkWidgetView::setLabel(const char label[], size_t len)
-{
-	if (label == NULL && fLabel.size() != 0 || !fLabel.equals(label, len))
-	{
-		SkString	tmp(label, len);
-
-		this->onLabelChange(fLabel.c_str(), tmp.c_str());
-		fLabel.swap(tmp);
-	}
-}
-
-void SkWidgetView::setLabel(const SkString& label)
-{
-	if (fLabel != label)
-	{
-		this->onLabelChange(fLabel.c_str(), label.c_str());
-		fLabel = label;
-	}
-}
-
-bool SkWidgetView::postWidgetEvent()
-{
-	if (!fEvent.isType(""))
-	{
-		SkEvent	evt(fEvent);	// make a copy since onPrepareWidgetEvent may edit the event
-
-		if (this->onPrepareWidgetEvent(&evt))
-		{
-			SkDEBUGCODE(evt.dump("SkWidgetView::postWidgetEvent");)
-
-			this->postToListeners(evt);	// wonder if this should return true if there are > 0 listeners...
-			return true;
-		}
-	}
-	return false;
-}
-
-/*virtual*/ void SkWidgetView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	const char* label = dom.findAttr(node, "label");
-	if (label)
-		this->setLabel(label);
-		
-	if ((node = dom.getFirstChild(node, "event")) != NULL)
-		fEvent.inflate(dom, node);
-}
-
-/*virtual*/ void SkWidgetView::onLabelChange(const char oldLabel[], const char newLabel[])
-{
-	this->inval(NULL);
-}
-
-static const char gWidgetEventSinkIDSlotName[] = "sk-widget-sinkid-slot";
-
-/*virtual*/ bool SkWidgetView::onPrepareWidgetEvent(SkEvent* evt)
-{
-	evt->setS32(gWidgetEventSinkIDSlotName, this->getSinkID());
-	return true;
-}
-
-SkEventSinkID SkWidgetView::GetWidgetEventSinkID(const SkEvent& evt)
-{
-	int32_t	sinkID;
-	
-	return evt.findS32(gWidgetEventSinkIDSlotName, &sinkID) ? (SkEventSinkID)sinkID : 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*virtual*/ bool SkButtonView::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
-	{
-		this->postWidgetEvent();
-		return true;
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-SkCheckButtonView::SkCheckButtonView() : fCheckState(kOff_CheckState)
-{
-}
-
-void SkCheckButtonView::setCheckState(CheckState state)
-{
-	SkASSERT((unsigned)state <= kUnknown_CheckState);
-	
-	if (fCheckState != state)
-	{
-		this->onCheckStateChange(this->getCheckState(), state);
-		fCheckState = SkToU8(state);
-	}
-}
-	
-/*virtual*/ void SkCheckButtonView::onCheckStateChange(CheckState oldState, CheckState newState)
-{
-	this->inval(NULL);
-}
-
-/*virtual*/ void SkCheckButtonView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-	
-	int index = dom.findList(node, "check-state", "off,on,unknown");
-	if (index >= 0)
-		this->setCheckState((CheckState)index);
-}
-
-static const char gCheckStateSlotName[] = "sk-checkbutton-check-slot";
-
-/*virtual*/ bool SkCheckButtonView::onPrepareWidgetEvent(SkEvent* evt)
-{
-	// could check if we're "disabled", and return false...
-
-	evt->setS32(gCheckStateSlotName, this->getCheckState());
-	return true;
-}
-
-bool SkCheckButtonView::GetWidgetEventCheckState(const SkEvent& evt, CheckState* state)
-{
-	int32_t	state32;
-	
-	if (evt.findS32(gCheckStateSlotName, &state32))
-	{
-		if (state)
-			*state = (CheckState)state32;
-		return true;
-	}
-	return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkTime.h"
-#include <stdio.h>
-
-class SkAnimButtonView : public SkButtonView {
-public:
-	SkAnimButtonView()
-	{
-		fAnim.setHostEventSink(this);
-		init_skin_anim(kButton_SkinEnum, &fAnim);
-	}
-
-protected:
-	virtual void onLabelChange(const char oldLabel[], const char newLabel[])
-	{
-		this->INHERITED::onLabelChange(oldLabel, newLabel);
-
-		SkEvent evt("user");
-		evt.setString("id", "setLabel");
-		evt.setString("LABEL", newLabel);
-		fAnim.doUserEvent(evt);
-	}
-	
-	virtual void onFocusChange(bool gainFocus)
-	{
-		this->INHERITED::onFocusChange(gainFocus);
-
-		SkEvent evt("user");
-		evt.setString("id", "setFocus");
-		evt.setS32("FOCUS", gainFocus);
-		fAnim.doUserEvent(evt);
-	}
-
-	virtual void onSizeChange()
-	{
-		this->INHERITED::onSizeChange();
-
-		SkEvent evt("user");
-		evt.setString("id", "setDim");
-		evt.setScalar("dimX", this->width());
-		evt.setScalar("dimY", this->height());
-		fAnim.doUserEvent(evt);
-	}
-
-	virtual void onDraw(SkCanvas* canvas)
-	{
-		SkPaint						paint;		
-		SkAnimator::DifferenceType	diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-		
-		if (diff == SkAnimator::kDifferent)
-			this->inval(NULL);
-		else if (diff == SkAnimator::kPartiallyDifferent)
-		{
-			SkRect	bounds;
-			fAnim.getInvalBounds(&bounds);
-			this->inval(&bounds);
-		}
-	}
-	
-	virtual bool onEvent(const SkEvent& evt)
-	{
-		if (evt.isType(SK_EventType_Inval))
-		{
-			this->inval(NULL);
-			return true;
-		}
-		if (evt.isType("recommendDim"))
-		{
-			SkScalar	height;
-			
-			if (evt.findScalar("y", &height))
-				this->setHeight(height);
-			return true;
-		}
-		return this->INHERITED::onEvent(evt);
-	}
-	
-	virtual bool onPrepareWidgetEvent(SkEvent* evt)
-	{
-		if (this->INHERITED::onPrepareWidgetEvent(evt))
-		{
-			SkEvent	e("user");
-			e.setString("id", "handlePress");
-			(void)fAnim.doUserEvent(e);
-			return true;
-		}
-		return false;
-	}
-
-private:
-	SkAnimator	fAnim;
-	
-	typedef SkButtonView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////
-
-SkView* SkWidgetFactory(const char name[])
-{
-	if (name == NULL)
-		return NULL;
-	
-	// must be in the same order as the SkSkinWidgetEnum is declared
-	static const char* gNames[] = {
-		"sk-border",
-		"sk-button",
-		"sk-image",
-		"sk-list",
-		"sk-progress",
-		"sk-scroll",
-		"sk-text"
-		
-	};
-
-	for (int i = 0; i < SK_ARRAY_COUNT(gNames); i++)
-		if (!strcmp(gNames[i], name))
-			return SkWidgetFactory((SkWidgetEnum)i);
-
-	return NULL;
-}
-
-#include "SkImageView.h"
-#include "SkProgressBarView.h"
-#include "SkScrollBarView.h"
-#include "SkBorderView.h"
-
-SkView* SkWidgetFactory(SkWidgetEnum sw)
-{
-	switch (sw) {
-	case kBorder_WidgetEnum:
-		return new SkBorderView;
-	case kButton_WidgetEnum:
-		return new SkAnimButtonView;
-	case kImage_WidgetEnum:
-		return new SkImageView;
-	case kList_WidgetEnum:
-		return new SkListView;
-	case kProgress_WidgetEnum:
-		return new SkProgressBarView;
-	case kScroll_WidgetEnum:
-		return new SkScrollBarView;
-	case kText_WidgetEnum:
-		return new SkStaticTextView;
-	default:
-		SkASSERT(!"unknown enum passed to SkWidgetFactory");
-		break;
-	}
-	return NULL;
-}
diff --git a/src/views/SkWidgets.cpp b/src/views/SkWidgets.cpp
deleted file mode 100644
index dba9ab3..0000000
--- a/src/views/SkWidgets.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-#include "SkWidget.h"
-#include "SkCanvas.h"
-#include "SkKey.h"
-#include "SkParsePaint.h"
-#include "SkSystemEventTypes.h"
-#include "SkTextBox.h"
-
-#if 0
-
-#ifdef SK_DEBUG
-	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-	{
-		const char* value = dom.findAttr(node, attr);
-		if (value)
-			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-	}
-#else
-	#define assert_no_attr(dom, node, attr)
-#endif
-
-#include "SkAnimator.h"
-#include "SkTime.h"
-
-///////////////////////////////////////////////////////////////////////////////
-
-enum SkinType {
-	kPushButton_SkinType,
-	kStaticText_SkinType,
-
-	kSkinTypeCount
-};
-
-struct SkinSuite {
-	SkinSuite();
-	~SkinSuite()
-	{
-		for (int i = 0; i < kSkinTypeCount; i++)
-			delete fAnimators[i];
-	}
-
-	SkAnimator*	get(SkinType);
-
-private:
-	SkAnimator*	fAnimators[kSkinTypeCount];
-};
-
-SkinSuite::SkinSuite()
-{
-	static const char kSkinPath[] = "skins/";
-
-	static const char* gSkinNames[] = {
-		"pushbutton_skin.xml",
-		"statictext_skin.xml"
-	};
-
-	for (unsigned i = 0; i < SK_ARRAY_COUNT(gSkinNames); i++)
-	{
-		size_t		len = strlen(gSkinNames[i]);
-		SkString	path(sizeof(kSkinPath) - 1 + len);
-
-		memcpy(path.writable_str(), kSkinPath, sizeof(kSkinPath) - 1);
-		memcpy(path.writable_str() + sizeof(kSkinPath) - 1, gSkinNames[i], len);
-
-		fAnimators[i] = new SkAnimator;
-		if (!fAnimators[i]->decodeURI(path.c_str()))
-		{
-			delete fAnimators[i];
-			fAnimators[i] = NULL;
-		}
-	}
-}
-
-SkAnimator* SkinSuite::get(SkinType st)
-{
-	SkASSERT((unsigned)st < kSkinTypeCount);
-	return fAnimators[st];
-}
-
-static SkinSuite* gSkinSuite;
-
-static SkAnimator* get_skin_animator(SkinType st)
-{
-#if 0
-	if (gSkinSuite == NULL)
-		gSkinSuite = new SkinSuite;
-	return gSkinSuite->get(st);
-#else
-	return NULL;
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkWidget::Init()
-{
-}
-
-void SkWidget::Term()
-{
-	delete gSkinSuite;
-}
-
-void SkWidget::onEnabledChange()
-{
-	this->inval(NULL);
-}
-
-void SkWidget::postWidgetEvent()
-{
-	if (!fEvent.isType("") && this->hasListeners())
-	{
-		this->prepareWidgetEvent(&fEvent);
-		this->postToListeners(fEvent);
-	}
-}
-
-void SkWidget::prepareWidgetEvent(SkEvent*)
-{
-	// override in subclass to add any additional fields before posting
-}
-
-void SkWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	if ((node = dom.getFirstChild(node, "event")) != NULL)
-		fEvent.inflate(dom, node);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-size_t SkHasLabelWidget::getLabel(SkString* str) const
-{
-	if (str)
-		*str = fLabel;
-	return fLabel.size();
-}
-
-size_t SkHasLabelWidget::getLabel(char buffer[]) const
-{
-	if (buffer)
-		memcpy(buffer, fLabel.c_str(), fLabel.size());
-	return fLabel.size();
-}
-
-void SkHasLabelWidget::setLabel(const SkString& str)
-{
-	this->setLabel(str.c_str(), str.size());
-}
-
-void SkHasLabelWidget::setLabel(const char label[])
-{
-	this->setLabel(label, strlen(label));
-}
-
-void SkHasLabelWidget::setLabel(const char label[], size_t len)
-{
-	if (!fLabel.equals(label, len))
-	{
-		fLabel.set(label, len);
-		this->onLabelChange();
-	}
-}
-
-void SkHasLabelWidget::onLabelChange()
-{
-	// override in subclass
-}
-
-void SkHasLabelWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	const char* text = dom.findAttr(node, "label");
-	if (text)
-		this->setLabel(text);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-void SkButtonWidget::setButtonState(State state)
-{
-	if (fState != state)
-	{
-		fState = state;
-		this->onButtonStateChange();
-	}
-}
-
-void SkButtonWidget::onButtonStateChange()
-{
-	this->inval(NULL);
-}
-
-void SkButtonWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	int	index;
-	if ((index = dom.findList(node, "buttonState", "off,on,unknown")) >= 0)
-		this->setButtonState((State)index);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-bool SkPushButtonWidget::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
-	{
-		this->postWidgetEvent();
-		return true;
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget::State state)
-{
-	if (!enabled)
-		return "disabled";
-	if (state == SkButtonWidget::kOn_State)
-	{
-		SkASSERT(focused);
-		return "enabled-pressed";
-	}
-	if (focused)
-		return "enabled-focused";
-	return "enabled";
-}
-
-#include "SkBlurMaskFilter.h"
-#include "SkEmbossMaskFilter.h"
-
-static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pressed)
-{
-	SkEmbossMaskFilter::Light	light;
-
-	light.fDirection[0] = SK_Scalar1/2;
-	light.fDirection[1] = SK_Scalar1/2;
-	light.fDirection[2] = SK_Scalar1/3;
-	light.fAmbient		= 0x48;
-	light.fSpecular		= 0x80;
-
-	if (pressed)
-	{
-		light.fDirection[0] = -light.fDirection[0];
-		light.fDirection[1] = -light.fDirection[1];
-	}
-	if (focus)
-		light.fDirection[2] += SK_Scalar1/4;
-
-	paint->setMaskFilter(new SkEmbossMaskFilter(light, radius))->unref();
-}
-
-void SkPushButtonWidget::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	SkString label;
-	this->getLabel(&label);
-
-	SkAnimator* anim = get_skin_animator(kPushButton_SkinType);
-
-	if (anim)
-	{
-		SkEvent	evt("user");
-
-		evt.setString("id", "prime");
-		evt.setScalar("prime-width", this->width());
-		evt.setScalar("prime-height", this->height());
-		evt.setString("prime-text", label);
-		evt.setString("prime-state", computeAnimatorState(this->isEnabled(), this->hasFocus(), this->getButtonState()));
-
-		(void)anim->doUserEvent(evt);
-		SkPaint paint;
-		anim->draw(canvas, &paint, SkTime::GetMSecs());
-	}
-	else
-	{
-		SkRect	r;
-		SkPaint	p;
-
-		r.set(0, 0, this->width(), this->height());
-		p.setAntiAliasOn(true);
-		p.setColor(SK_ColorBLUE);
-		create_emboss(&p, SkIntToScalar(12)/5, this->hasFocus(), this->getButtonState() == kOn_State);
-		canvas->drawRoundRect(r, SkScalarHalf(this->height()), SkScalarHalf(this->height()), p);
-		p.setMaskFilter(NULL);
-
-		p.setTextAlign(SkPaint::kCenter_Align);
-
-		SkTextBox	box;
-		box.setMode(SkTextBox::kOneLine_Mode);
-		box.setSpacingAlign(SkTextBox::kCenter_SpacingAlign);
-		box.setBox(0, 0, this->width(), this->height());
-
-//		if (this->getButtonState() == kOn_State)
-//			p.setColor(SK_ColorRED);
-//		else
-			p.setColor(SK_ColorWHITE);
-
-		box.draw(canvas, label.c_str(), label.size(), p);
-	}
-}
-
-SkView::Click* SkPushButtonWidget::onFindClickHandler(SkScalar x, SkScalar y)
-{
-	this->acceptFocus();
-	return new Click(this);
-}
-
-bool SkPushButtonWidget::onClick(Click* click)
-{
-	SkRect	r;
-	State	state = kOff_State;
-
-	this->getLocalBounds(&r);
-	if (r.contains(click->fCurr))
-	{
-		if (click->fState == Click::kUp_State)
-			this->postWidgetEvent();
-		else
-			state = kOn_State;
-	}
-	this->setButtonState(state);
-	return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-SkStaticTextView::SkStaticTextView(U32 flags) : SkView(flags)
-{
-	fMargin.set(0, 0);
-	fMode = kFixedSize_Mode;
-	fSpacingAlign = SkTextBox::kStart_SpacingAlign;
-}
-
-SkStaticTextView::~SkStaticTextView()
-{
-}
-
-void SkStaticTextView::computeSize()
-{
-	if (fMode == kAutoWidth_Mode)
-	{
-		SkScalar width = fPaint.measureText(fText.c_str(), fText.size(), NULL, NULL);
-		this->setWidth(width + fMargin.fX * 2);
-	}
-	else if (fMode == kAutoHeight_Mode)
-	{
-		SkScalar width = this->width() - fMargin.fX * 2;
-		int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
-
-		SkScalar	before, after;
-		(void)fPaint.measureText(0, NULL, &before, &after);
-
-		this->setHeight(lines * (after - before) + fMargin.fY * 2);
-	}
-}
-
-void SkStaticTextView::setMode(Mode mode)
-{
-	SkASSERT((unsigned)mode < kModeCount);
-
-	if (fMode != mode)
-	{
-		fMode = SkToU8(mode);
-		this->computeSize();
-	}
-}
-
-void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
-{
-	fSpacingAlign = SkToU8(align);
-	this->inval(NULL);
-}
-
-void SkStaticTextView::getMargin(SkPoint* margin) const
-{
-	if (margin)
-		*margin = fMargin;
-}
-
-void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
-{
-	if (fMargin.fX != dx || fMargin.fY != dy)
-	{
-		fMargin.set(dx, dy);
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-size_t SkStaticTextView::getText(SkString* text) const
-{
-	if (text)
-		*text = fText;
-	return fText.size();
-}
-
-size_t SkStaticTextView::getText(char text[]) const
-{
-	if (text)
-		memcpy(text, fText.c_str(), fText.size());
-	return fText.size();
-}
-
-void SkStaticTextView::setText(const SkString& text)
-{
-	this->setText(text.c_str(), text.size());
-}
-
-void SkStaticTextView::setText(const char text[])
-{
-	this->setText(text, strlen(text));
-}
-
-void SkStaticTextView::setText(const char text[], size_t len)
-{
-	if (!fText.equals(text, len))
-	{
-		fText.set(text, len);
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-void SkStaticTextView::getPaint(SkPaint* paint) const
-{
-	if (paint)
-		*paint = fPaint;
-}
-
-void SkStaticTextView::setPaint(const SkPaint& paint)
-{
-	if (fPaint != paint)
-	{
-		fPaint = paint;
-		this->computeSize();
-		this->inval(NULL);
-	}
-}
-
-void SkStaticTextView::onDraw(SkCanvas* canvas)
-{
-	this->INHERITED::onDraw(canvas);
-
-	if (fText.isEmpty())
-		return;
-
-	SkTextBox	box;
-
-	box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
-	box.setSpacingAlign(this->getSpacingAlign());
-	box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
-	box.draw(canvas, fText.c_str(), fText.size(), fPaint);
-}
-
-void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	int	index;
-	if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
-		this->setMode((Mode)index);
-	else
-		assert_no_attr(dom, node, "mode");
-
-	if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
-		this->setSpacingAlign((SkTextBox::SpacingAlign)index);
-	else
-		assert_no_attr(dom, node, "mode");
-
-	SkScalar s[2];
-	if (dom.findScalars(node, "margin", s, 2))
-		this->setMargin(s[0], s[1]);
-	else
-		assert_no_attr(dom, node, "margin");
-
-	const char* text = dom.findAttr(node, "text");
-	if (text)
-		this->setText(text);
-
-	if ((node = dom.getFirstChild(node, "paint")) != NULL)
-		SkPaint_Inflate(&fPaint, dom, node);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkImageDecoder.h"
-
-SkBitmapView::SkBitmapView(U32 flags) : SkView(flags)
-{
-}
-
-SkBitmapView::~SkBitmapView()
-{
-}
-
-bool SkBitmapView::getBitmap(SkBitmap* bitmap) const
-{
-	if (bitmap)
-		*bitmap = fBitmap;
-	return fBitmap.getConfig() != SkBitmap::kNo_Config;
-}
-
-void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels)
-{
-	if (bitmap)
-	{
-		fBitmap = *bitmap;
-		fBitmap.setOwnsPixels(viewOwnsPixels);
-	}
-}
-
-bool SkBitmapView::loadBitmapFromFile(const char path[])
-{
-	SkBitmap	bitmap;
-
-	if (SkImageDecoder::DecodeFile(path, &bitmap))
-	{
-		this->setBitmap(&bitmap, true);
-		bitmap.setOwnsPixels(false);
-		return true;
-	}
-	return false;
-}
-
-void SkBitmapView::onDraw(SkCanvas* canvas)
-{
-	if (fBitmap.getConfig() != SkBitmap::kNo_Config &&
-		fBitmap.width() && fBitmap.height())
-	{
-		SkAutoCanvasRestore	restore(canvas, true);
-		SkPaint				p;
-
-		p.setFilterType(SkPaint::kBilinear_FilterType);
-		canvas->scale(	this->width() / fBitmap.width(),
-						this->height() / fBitmap.height(),
-						0, 0);
-		canvas->drawBitmap(fBitmap, 0, 0, p);
-	}
-}
-
-void SkBitmapView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-	this->INHERITED::onInflate(dom, node);
-
-	const char* src = dom.findAttr(node, "src");
-	if (src)
-		(void)this->loadBitmapFromFile(src);
-}
-
-#endif
-
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
deleted file mode 100644
index dbc1eea..0000000
--- a/src/views/SkWindow.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-#include "SkWindow.h"
-#include "SkCanvas.h"
-#include "SkDevice.h"
-#include "SkOSMenu.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-#define SK_EventDelayInval "\xd" "n" "\xa" "l"
-
-#define TEST_BOUNDERx
-
-#include "SkBounder.h"
-class test_bounder : public SkBounder {
-public:
-	test_bounder(const SkBitmap& bm) : fCanvas(bm) {}
-protected:
-	virtual bool onIRect(const SkIRect& r)
-	{
-		SkRect	rr;
-
-		rr.set(SkIntToScalar(r.fLeft), SkIntToScalar(r.fTop),
-				SkIntToScalar(r.fRight), SkIntToScalar(r.fBottom));
-
-		SkPaint	p;
-
-		p.setStyle(SkPaint::kStroke_Style);
-		p.setColor(SK_ColorYELLOW);
-
-#if 0
-		rr.inset(SK_ScalarHalf, SK_ScalarHalf);
-#else
-		rr.inset(-SK_ScalarHalf, -SK_ScalarHalf);
-#endif
-
-		fCanvas.drawRect(rr, p);
-		return true;
-	}
-private:
-	SkCanvas	fCanvas;
-};
-
-SkWindow::SkWindow() : fFocusView(NULL)
-{
-	fClick = NULL;
-	fWaitingOnInval = false;
-
-#ifdef SK_BUILD_FOR_WINCE
-	fConfig = SkBitmap::kRGB_565_Config;
-#else
-	fConfig = SkBitmap::kARGB_8888_Config;
-#endif
-
-    fMatrix.reset();
-}
-
-SkWindow::~SkWindow()
-{
-	delete fClick;
-
-	fMenus.deleteAll();
-}
-
-void SkWindow::setMatrix(const SkMatrix& matrix) {
-    if (fMatrix != matrix) {
-        fMatrix = matrix;
-        this->inval(NULL);
-    }
-}
-
-void SkWindow::preConcat(const SkMatrix& matrix) {
-    SkMatrix m;
-    m.setConcat(fMatrix, matrix);
-    this->setMatrix(m);
-}
-
-void SkWindow::postConcat(const SkMatrix& matrix) {
-    SkMatrix m;
-    m.setConcat(matrix, fMatrix);
-    this->setMatrix(m);
-}
-
-void SkWindow::setConfig(SkBitmap::Config config)
-{
-	this->resize(fBitmap.width(), fBitmap.height(), config);
-}
-
-void SkWindow::resize(int width, int height, SkBitmap::Config config)
-{
-	if (config == SkBitmap::kNo_Config)
-		config = fConfig;
-
-	if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig)
-	{
-		fConfig = config;
-		fBitmap.setConfig(config, width, height);
-		fBitmap.allocPixels();
-        fBitmap.setIsOpaque(true);
-
-		this->setSize(SkIntToScalar(width), SkIntToScalar(height));
-		this->inval(NULL);
-	}
-}
-
-void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
-{
-	fBitmap.eraseARGB(a, r, g, b);
-}
-
-void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b)
-{
-	fBitmap.eraseRGB(r, g, b);
-}
-
-bool SkWindow::handleInval(const SkRect* localR)
-{
-	SkIRect	ir;
-
-    if (localR) {
-        SkRect devR;
-        SkMatrix inverse;
-        if (!fMatrix.invert(&inverse)) {
-            return false;
-        }
-        fMatrix.mapRect(&devR, *localR);
-        devR.round(&ir);
-    } else {
-        ir.set(0, 0, this->width(), this->height());
-    }
-	fDirtyRgn.op(ir, SkRegion::kUnion_Op);
-
-	this->onHandleInval(ir);
-	return true;
-}
-
-void SkWindow::forceInvalAll() {
-    fDirtyRgn.setRect(0, 0, this->width(), this->height());
-}
-
-#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
-	#include <windows.h>
-	#include <gx.h>
-	extern GXDisplayProperties gDisplayProps;
-#endif
-
-#ifdef SK_SIMULATE_FAILED_MALLOC
-extern bool gEnableControlledThrow;
-#endif
-
-bool SkWindow::update(SkIRect* updateArea, SkCanvas* canvas)
-{
-	if (!fDirtyRgn.isEmpty())
-	{
-		SkBitmap bm = this->getBitmap();
-
-#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
-		char* buffer = (char*)GXBeginDraw();
-		SkASSERT(buffer);
-
-		RECT	rect;
-		GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
-		buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;
-
-		bm.setPixels(buffer);
-#endif
-
-		SkCanvas	rasterCanvas;
-        SkDevice*   device;
-
-        if (NULL == canvas) {
-            canvas = &rasterCanvas;
-            device = new SkDevice(canvas, bm, false);
-            canvas->setDevice(device)->unref();
-        } else {
-            canvas->setBitmapDevice(bm);
-        }
-
-		canvas->clipRegion(fDirtyRgn);
-		if (updateArea)
-			*updateArea = fDirtyRgn.getBounds();
-
-        SkAutoCanvasRestore acr(canvas, true);
-        canvas->concat(fMatrix);
-
-		// empty this now, so we can correctly record any inval calls that
-		// might be made during the draw call.
-		fDirtyRgn.setEmpty();
-
-#ifdef TEST_BOUNDER
-		test_bounder	b(bm);
-		canvas->setBounder(&b);
-#endif
-#ifdef SK_SIMULATE_FAILED_MALLOC
-		gEnableControlledThrow = true;
-#endif
-#ifdef SK_BUILD_FOR_WIN32
-		//try {
-			this->draw(canvas);
-		//}
-		//catch (...) {
-		//}
-#else
-		this->draw(canvas);
-#endif
-#ifdef SK_SIMULATE_FAILED_MALLOC
-		gEnableControlledThrow = false;
-#endif
-#ifdef TEST_BOUNDER
-		canvas->setBounder(NULL);
-#endif
-
-#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
-		GXEndDraw();
-#endif
-
-		return true;
-	}
-	return false;
-}
-
-bool SkWindow::handleChar(SkUnichar uni)
-{
-	if (this->onHandleChar(uni))
-		return true;
-
-	SkView* focus = this->getFocusView();
-	if (focus == NULL)
-		focus = this;
-
-	SkEvent evt(SK_EventType_Unichar);
-	evt.setFast32(uni);
-	return focus->doEvent(evt);
-}
-
-bool SkWindow::handleKey(SkKey key)
-{
-	if (key == kNONE_SkKey)
-		return false;
-
-	if (this->onHandleKey(key))
-		return true;
-
-	// send an event to the focus-view
-	{
-		SkView* focus = this->getFocusView();
-		if (focus == NULL)
-			focus = this;
-
-		SkEvent evt(SK_EventType_Key);
-		evt.setFast32(key);
-		if (focus->doEvent(evt))
-			return true;
-	}
-
-	if (key == kUp_SkKey || key == kDown_SkKey)
-	{
-		if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
-			this->onSetFocusView(NULL);
-		return true;
-	}
-	return false;
-}
-
-bool SkWindow::handleKeyUp(SkKey key)
-{
-    if (key == kNONE_SkKey)
-        return false;
-        
-    if (this->onHandleKeyUp(key))
-        return true;
-    
-    //send an event to the focus-view
-    {
-        SkView* focus = this->getFocusView();
-        if (focus == NULL)
-            focus = this;
-            
-        //should this one be the same?
-        SkEvent evt(SK_EventType_KeyUp);
-        evt.setFast32(key);
-        if (focus->doEvent(evt))
-            return true;
-    }
-    return false;
-}
-
-void SkWindow::addMenu(SkOSMenu* menu)
-{
-	*fMenus.append() = menu;
-	this->onAddMenu(menu);
-}
-
-void SkWindow::setTitle(const char title[]) {
-    if (NULL == title) {
-        title = "";
-    }
-    fTitle.set(title);
-    this->onSetTitle(title);
-}
-
-bool SkWindow::handleMenu(uint32_t cmd)
-{
-	for (int i = 0; i < fMenus.count(); i++)
-	{
-		SkEvent* evt = fMenus[i]->createEvent(cmd);
-		if (evt)
-		{
-			evt->post(this->getSinkID());
-			return true;
-		}
-	}
-	return false;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-bool SkWindow::onEvent(const SkEvent& evt)
-{
-	if (evt.isType(SK_EventDelayInval))
-	{
-		SkRegion::Iterator	iter(fDirtyRgn);
-
-		for (; !iter.done(); iter.next())
-			this->onHandleInval(iter.rect());
-		fWaitingOnInval = false;
-		return true;
-	}
-	return this->INHERITED::onEvent(evt);
-}
-
-bool SkWindow::onGetFocusView(SkView** focus) const
-{
-	if (focus)
-		*focus = fFocusView;
-	return true;
-}
-
-bool SkWindow::onSetFocusView(SkView* focus)
-{
-	if (fFocusView != focus)
-	{
-		if (fFocusView)
-			fFocusView->onFocusChange(false);
-		fFocusView = focus;
-		if (focus)
-			focus->onFocusChange(true);
-	}
-	return true;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void SkWindow::onHandleInval(const SkIRect&)
-{
-}
-
-bool SkWindow::onHandleChar(SkUnichar)
-{
-	return false;
-}
-
-bool SkWindow::onHandleKey(SkKey key)
-{
-	return false;
-}
-
-bool SkWindow::onHandleKeyUp(SkKey key)
-{
-    return false;
-}
-
-bool SkWindow::handleClick(int x, int y, Click::State state)
-{
-	bool handled = false;
-
-	switch (state) {
-	case Click::kDown_State:
-		if (fClick)
-			delete fClick;
-		fClick = this->findClickHandler(SkIntToScalar(x), SkIntToScalar(y));
-		if (fClick)
-		{
-			SkView::DoClickDown(fClick, x, y);
-			handled = true;
-		}
-		break;
-	case Click::kMoved_State:
-		if (fClick)
-		{
-			SkView::DoClickMoved(fClick, x, y);
-			handled = true;
-		}
-		break;
-	case Click::kUp_State:
-		if (fClick)
-		{
-			SkView::DoClickUp(fClick, x, y);
-			delete fClick;
-			fClick = NULL;
-			handled = true;
-		}
-		break;
-	}
-	return handled;
-}
-
diff --git a/tests/Android.mk b/tests/Android.mk
index e1c03ec..a5611ee 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -3,24 +3,40 @@
 
 
 LOCAL_SRC_FILES:= \
-        BlitRowTest.cpp \
-        GeometryTest.cpp \
-        MathTest.cpp \
-        MatrixTest.cpp \
-        PackBitsTest.cpp \
-        Sk64Test.cpp \
-        StringTest.cpp \
-        Test.cpp UtilsTest.cpp \
-        PathTest.cpp \
-        SrcOverTest.cpp \
-        StreamTest.cpp \
-        SortTest.cpp \
-        PathMeasureTest.cpp
+  BitmapCopyTest.cpp \
+  BitmapGetColorTest.cpp \
+  BlitRowTest.cpp \
+  ClipCubicTest.cpp \
+  ClipStackTest.cpp \
+  ClipperTest.cpp \
+  DequeTest.cpp \
+  FillPathTest.cpp \
+  FlateTest.cpp \
+  GeometryTest.cpp \
+  InfRectTest.cpp \
+  MathTest.cpp \
+  MatrixTest.cpp \
+  PackBitsTest.cpp \
+  PaintTest.cpp \
+  ParsePathTest.cpp \
+  PathMeasureTest.cpp \
+  PathTest.cpp \
+  RefDictTest.cpp \
+  RegionTest.cpp \
+  Sk64Test.cpp \
+  SortTest.cpp \
+  SrcOverTest.cpp \
+  StreamTest.cpp \
+  StringTest.cpp \
+  Test.cpp \
+  TestSize.cpp \
+  UtilsTest.cpp \
+  XfermodeTest.cpp
 
 # The name of the file with a main function must
 # match native test's naming rule: xxx_test.cpp.
 LOCAL_SRC_FILES += \
-        skia_test.cpp
+  skia_test.cpp
 
 LOCAL_MODULE:= skia_test
 
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index be3850e..1878dfa 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -62,10 +62,14 @@
     }
 }
 
-static void init_src(const SkBitmap& bitmap) {
+static void init_src(const SkBitmap& bitmap, const SkColorTable* ct) {
     SkAutoLockPixels lock(bitmap);
     if (bitmap.getPixels()) {
-        memset(bitmap.getPixels(), 4, bitmap.getSize());
+        if (ct) {
+            sk_bzero(bitmap.getPixels(), bitmap.getSize());
+        } else {
+            bitmap.eraseColor(SK_ColorWHITE);
+        }
     }
 }
 
@@ -81,6 +85,151 @@
     const char*         fValid;
 };
 
+// Utility functions for copyPixelsTo()/copyPixelsFrom() tests.
+// getPixel()
+// setPixel()
+// getSkConfigName()
+// struct Coordinates
+// reportCopyVerification()
+// writeCoordPixels()
+
+// Utility function to read the value of a given pixel in bm. All
+// values converted to uint32_t for simplification of comparisons.
+uint32_t getPixel(int x, int y, const SkBitmap& bm) {
+    uint32_t val = 0;
+    uint16_t val16;
+    uint8_t val8, shift;
+    SkAutoLockPixels lock(bm);
+    const void* rawAddr = bm.getAddr(x,y);
+
+    switch (bm.getConfig()) {
+        case SkBitmap::kARGB_8888_Config:
+            memcpy(&val, rawAddr, sizeof(uint32_t));
+            break;
+        case SkBitmap::kARGB_4444_Config:
+        case SkBitmap::kRGB_565_Config:
+            memcpy(&val16, rawAddr, sizeof(uint16_t));
+            val = val16;
+            break;
+        case SkBitmap::kA8_Config:
+        case SkBitmap::kIndex8_Config:
+            memcpy(&val8, rawAddr, sizeof(uint8_t));
+            val = val8;
+            break;
+        case SkBitmap::kA1_Config:
+            memcpy(&val8, rawAddr, sizeof(uint8_t));
+            shift = x % 8;
+            val = (val8 >> shift) & 0x1 ;
+            break;
+        default:
+            break;
+    }
+    return val;
+}
+
+// Utility function to set value of any pixel in bm.
+// bm.getConfig() specifies what format 'val' must be
+// converted to, but at present uint32_t can handle all formats.
+void setPixel(int x, int y, uint32_t val, SkBitmap& bm) {
+    uint16_t val16;
+    uint8_t val8, shift;
+    SkAutoLockPixels lock(bm);
+    void* rawAddr = bm.getAddr(x,y);
+
+    switch (bm.getConfig()) {
+        case SkBitmap::kARGB_8888_Config:
+            memcpy(rawAddr, &val, sizeof(uint32_t));
+            break;
+        case SkBitmap::kARGB_4444_Config:
+        case SkBitmap::kRGB_565_Config:
+            val16 = val & 0xFFFF;
+            memcpy(rawAddr, &val16, sizeof(uint16_t));
+            break;
+        case SkBitmap::kA8_Config:
+        case SkBitmap::kIndex8_Config:
+            val8 = val & 0xFF;
+            memcpy(rawAddr, &val8, sizeof(uint8_t));
+            break;
+        case SkBitmap::kA1_Config:
+            shift = x % 8; // We assume we're in the right byte.
+            memcpy(&val8, rawAddr, sizeof(uint8_t));
+            if (val & 0x1) // Turn bit on.
+                val8 |= (0x1 << shift);
+            else // Turn bit off.
+                val8 &= ~(0x1 << shift);
+            memcpy(rawAddr, &val8, sizeof(uint8_t));
+            break;
+        default:
+            // Ignore.
+            break;
+    }
+}
+
+// Utility to return string containing name of each format, to
+// simplify diagnostic output.
+const char* getSkConfigName(const SkBitmap& bm) {
+    switch (bm.getConfig()) {
+        case SkBitmap::kNo_Config: return "SkBitmap::kNo_Config";
+        case SkBitmap::kA1_Config: return "SkBitmap::kA1_Config";
+        case SkBitmap::kA8_Config: return "SkBitmap::kA8_Config";
+        case SkBitmap::kIndex8_Config: return "SkBitmap::kIndex8_Config";
+        case SkBitmap::kRGB_565_Config: return "SkBitmap::kRGB_565_Config";
+        case SkBitmap::kARGB_4444_Config: return "SkBitmap::kARGB_4444_Config";
+        case SkBitmap::kARGB_8888_Config: return "SkBitmap::kARGB_8888_Config";
+        case SkBitmap::kRLE_Index8_Config:
+            return "SkBitmap::kRLE_Index8_Config,";
+        default: return "Unknown SkBitmap configuration.";
+    }
+}
+
+// Helper struct to contain pixel locations, while avoiding need for STL.
+struct Coordinates {
+
+    const int length;
+    SkIPoint* const data;
+
+    explicit Coordinates(int _length): length(_length)
+                                     , data(new SkIPoint[length]) { }
+
+    ~Coordinates(){
+        delete [] data;
+    }
+
+    SkIPoint* operator[](int i) const {
+        // Use with care, no bounds checking.
+        return data + i;
+    }
+};
+
+// A function to verify that two bitmaps contain the same pixel values
+// at all coordinates indicated by coords. Simplifies verification of
+// copied bitmaps.
+void reportCopyVerification(const SkBitmap& bm1, const SkBitmap& bm2,
+                            Coordinates& coords,
+                            const char* msg,
+                            skiatest::Reporter* reporter){
+    bool success = true;
+
+    // Confirm all pixels in the list match.
+    for (int i = 0; i < coords.length; ++i)
+        success = success &&
+                  (getPixel(coords[i]->fX, coords[i]->fY, bm1) ==
+                   getPixel(coords[i]->fX, coords[i]->fY, bm2));
+
+    if (!success) {
+        SkString str;
+        str.printf("%s [config = %s]",
+                   msg, getSkConfigName(bm1));
+        reporter->reportFailed(str);
+    }
+}
+
+// Writes unique pixel values at locations specified by coords.
+void writeCoordPixels(SkBitmap& bm, const Coordinates& coords) {
+    for (int i = 0; i < coords.length; ++i)
+        setPixel(coords[i]->fX, coords[i]->fY, i, bm);
+}
+
 static void TestBitmapCopy(skiatest::Reporter* reporter) {
     static const Pair gPairs[] = {
         { SkBitmap::kNo_Config,         "00000000"  },
@@ -94,6 +243,10 @@
  //       { SkBitmap::kRLE_Index8_Config, "00101111"  }
     };
 
+    static const bool isExtracted[] = {
+        false, true
+    };
+
     const int W = 20;
     const int H = 33;
 
@@ -110,7 +263,7 @@
             src.allocPixels(ct);
             SkSafeUnref(ct);
 
-            init_src(src);
+            init_src(src, ct);
             bool success = src.copyTo(&dst, gPairs[j].fConfig);
             bool expected = gPairs[i].fValid[j] != '0';
             if (success != expected) {
@@ -120,7 +273,7 @@
                            boolStr(success));
                 reporter->reportFailed(str);
             }
-            
+
             bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
             if (success != canSucceed) {
                 SkString str;
@@ -161,7 +314,7 @@
                         REPORTER_ASSERT(reporter, copy.width() == 1);
                         REPORTER_ASSERT(reporter, copy.height() == 1);
                         REPORTER_ASSERT(reporter, copy.rowBytes() <= 4);
-                        
+
                         SkAutoLockPixels alp0(subset);
                         SkAutoLockPixels alp1(copy);
                         // they should both have, or both not-have, a colortable
@@ -176,7 +329,257 @@
                 REPORTER_ASSERT(reporter, dst.width() == 0);
                 REPORTER_ASSERT(reporter, dst.height() == 0);
             }
-        }
+        } // for (size_t j = ...
+
+        // Tests for getSafeSize(), getSafeSize64(), copyPixelsTo(),
+        // copyPixelsFrom().
+        //
+        for (size_t copyCase = 0; copyCase < SK_ARRAY_COUNT(isExtracted);
+             ++copyCase) {
+            // Test copying to/from external buffer.
+            // Note: the tests below have hard-coded values ---
+            //       Please take care if modifying.
+            if (gPairs[i].fConfig != SkBitmap::kRLE_Index8_Config) {
+
+                // Tests for getSafeSize64().
+                // Test with a very large configuration without pixel buffer
+                // attached.
+                SkBitmap tstSafeSize;
+                tstSafeSize.setConfig(gPairs[i].fConfig, 100000000U,
+                                      100000000U);
+                Sk64 safeSize = tstSafeSize.getSafeSize64();
+                if (safeSize.isNeg()) {
+                    SkString str;
+                    str.printf("getSafeSize64() negative: %s",
+                        getSkConfigName(tstSafeSize));
+                    reporter->reportFailed(str);
+                }
+                bool sizeFail = false;
+                // Compare against hand-computed values.
+                switch (gPairs[i].fConfig) {
+                    case SkBitmap::kNo_Config:
+                        break;
+
+                    case SkBitmap::kA1_Config:
+                        if (safeSize.fHi != 0x470DE ||
+                            safeSize.fLo != 0x4DF82000)
+                            sizeFail = true;
+                        break;
+
+                    case SkBitmap::kA8_Config:
+                    case SkBitmap::kIndex8_Config:
+                        if (safeSize.fHi != 0x2386F2 ||
+                            safeSize.fLo != 0x6FC10000)
+                            sizeFail = true;
+                        break;
+
+                    case SkBitmap::kRGB_565_Config:
+                    case SkBitmap::kARGB_4444_Config:
+                        if (safeSize.fHi != 0x470DE4 ||
+                            safeSize.fLo != 0xDF820000)
+                            sizeFail = true;
+                        break;
+
+                    case SkBitmap::kARGB_8888_Config:
+                        if (safeSize.fHi != 0x8E1BC9 ||
+                            safeSize.fLo != 0xBF040000)
+                            sizeFail = true;
+                        break;
+
+                    case SkBitmap::kRLE_Index8_Config:
+                        break;
+
+                    default:
+                        break;
+                }
+                if (sizeFail) {
+                    SkString str;
+                    str.printf("getSafeSize64() wrong size: %s",
+                        getSkConfigName(tstSafeSize));
+                    reporter->reportFailed(str);
+                }
+
+                size_t subW, subH;
+                // Set sizes to be height = 2 to force the last row of the
+                // source to be used, thus verifying correct operation if
+                // the bitmap is an extracted subset.
+                if (gPairs[i].fConfig == SkBitmap::kA1_Config) {
+                    // If one-bit per pixel, use 9 pixels to force more than
+                    // one byte per row.
+                    subW = 9;
+                    subH = 2;
+                } else {
+                    // All other configurations are at least one byte per pixel,
+                    // and different configs will test copying different numbers
+                    // of bytes.
+                    subW = subH = 2;
+                }
+
+                // Create bitmap to act as source for copies and subsets.
+                SkBitmap src, subset;
+                SkColorTable* ct = NULL;
+                if (isExtracted[copyCase]) { // A larger image to extract from.
+                    src.setConfig(gPairs[i].fConfig, 2 * subW + 1, subH);
+                } else // Tests expect a 2x2 bitmap, so make smaller.
+                    src.setConfig(gPairs[i].fConfig, subW, subH);
+                if (SkBitmap::kIndex8_Config == src.config() ||
+                        SkBitmap::kRLE_Index8_Config == src.config()) {
+                    ct = init_ctable();
+                }
+
+                src.allocPixels(ct);
+                SkSafeUnref(ct);
+
+                // Either copy src or extract into 'subset', which is used
+                // for subsequent calls to copyPixelsTo/From.
+                bool srcReady = false;
+                if (isExtracted[copyCase]) {
+                    // The extractedSubset() test case allows us to test copy-
+                    // ing when src and dst mave possibly different strides.
+                    SkIRect r;
+                    if (gPairs[i].fConfig == SkBitmap::kA1_Config)
+                        // This config seems to need byte-alignment of
+                        // extracted subset bits.
+                        r.set(0, 0, subW, subH);
+                    else
+                        r.set(1, 0, 1 + subW, subH); // 2x2 extracted bitmap
+
+                    srcReady = src.extractSubset(&subset, r);
+                } else {
+                    srcReady = src.copyTo(&subset, src.getConfig());
+                }
+
+                // Not all configurations will generate a valid 'subset'.
+                if (srcReady) {
+
+                    // Allocate our target buffer 'buf' for all copies.
+                    // To simplify verifying correctness of copies attach
+                    // buf to a SkBitmap, but copies are done using the
+                    // raw buffer pointer.
+                    const uint32_t bufSize = subH *
+                        SkBitmap::ComputeRowBytes(src.getConfig(), subW) * 2;
+                    uint8_t* buf = new uint8_t[bufSize];
+
+                    SkBitmap bufBm; // Attach buf to this bitmap.
+                    bool successExpected;
+
+                    // Set up values for each pixel being copied.
+                    Coordinates coords(subW * subH);
+                    for (size_t x = 0; x < subW; ++x)
+                        for (size_t y = 0; y < subH; ++y)
+                        {
+                            int index = y * subW + x;
+                            SkASSERT(index < coords.length);
+                            coords[index]->fX = x;
+                            coords[index]->fY = y;
+                        }
+
+                    writeCoordPixels(subset, coords);
+
+                    // Test #1 ////////////////////////////////////////////
+
+                    // Before/after comparisons easier if we attach buf
+                    // to an appropriately configured SkBitmap.
+                    memset(buf, 0xFF, bufSize);
+                    // Config with stride greater than src but that fits in buf.
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+                        SkBitmap::ComputeRowBytes(subset.getConfig(), subW)
+                                                  * 2);
+                    bufBm.setPixels(buf);
+                    successExpected = false;
+                    // Then attempt to copy with a stride that is too large
+                    // to fit in the buffer.
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes() * 3)
+                        == successExpected);
+
+                    if (successExpected)
+                        reportCopyVerification(subset, bufBm, coords,
+                            "copyPixelsTo(buf, bufSize, 1.5*maxRowBytes)",
+                            reporter);
+
+                    // Test #2 ////////////////////////////////////////////
+                    // This test should always succeed, but in the case
+                    // of extracted bitmaps only because we handle the
+                    // issue of getSafeSize(). Without getSafeSize()
+                    // buffer overrun/read would occur.
+                    memset(buf, 0xFF, bufSize);
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+                                    subset.rowBytes());
+                    bufBm.setPixels(buf);
+                    successExpected = subset.getSafeSize() <= bufSize;
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsTo(buf, bufSize) ==
+                            successExpected);
+                    if (successExpected)
+                        reportCopyVerification(subset, bufBm, coords,
+                        "copyPixelsTo(buf, bufSize)", reporter);
+
+                    // Test #3 ////////////////////////////////////////////
+                    // Copy with different stride between src and dst.
+                    memset(buf, 0xFF, bufSize);
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH,
+                                    subset.rowBytes()+1);
+                    bufBm.setPixels(buf);
+                    successExpected = true; // Should always work.
+                    REPORTER_ASSERT(reporter,
+                            subset.copyPixelsTo(buf, bufSize,
+                                subset.rowBytes()+1) == successExpected);
+                    if (successExpected)
+                        reportCopyVerification(subset, bufBm, coords,
+                        "copyPixelsTo(buf, bufSize, rowBytes+1)", reporter);
+
+                    // Test #4 ////////////////////////////////////////////
+                    // Test copy with stride too small.
+                    memset(buf, 0xFF, bufSize);
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+                    bufBm.setPixels(buf);
+                    successExpected = false;
+                    // Request copy with stride too small.
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsTo(buf, bufSize, bufBm.rowBytes()-1)
+                            == successExpected);
+                    if (successExpected)
+                        reportCopyVerification(subset, bufBm, coords,
+                        "copyPixelsTo(buf, bufSize, rowBytes()-1)", reporter);
+
+                    // Test #5 ////////////////////////////////////////////
+                    // Tests the case where the source stride is too small
+                    // for the source configuration.
+                    memset(buf, 0xFF, bufSize);
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+                    bufBm.setPixels(buf);
+                    writeCoordPixels(bufBm, coords);
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsFrom(buf, bufSize, 1) == false);
+
+                    // Test #6 ////////////////////////////////////////////
+                    // Tests basic copy from an external buffer to the bitmap.
+                    // If the bitmap is "extracted", this also tests the case
+                    // where the source stride is different from the dest.
+                    // stride.
+                    // We've made the buffer large enough to always succeed.
+                    bufBm.setConfig(gPairs[i].fConfig, subW, subH);
+                    bufBm.setPixels(buf);
+                    writeCoordPixels(bufBm, coords);
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsFrom(buf, bufSize, bufBm.rowBytes()) ==
+                            true);
+                    reportCopyVerification(bufBm, subset, coords,
+                        "copyPixelsFrom(buf, bufSize)",
+                        reporter);
+
+                    // Test #7 ////////////////////////////////////////////
+                    // Tests the case where the source buffer is too small
+                    // for the transfer.
+                    REPORTER_ASSERT(reporter,
+                        subset.copyPixelsFrom(buf, 1, subset.rowBytes()) ==
+                            false);
+
+                    delete [] buf;
+                }
+            }
+        } // for (size_t copyCase ...
     }
 }
 
diff --git a/tests/BitmapGetColorTest.cpp b/tests/BitmapGetColorTest.cpp
new file mode 100644
index 0000000..81cf412
--- /dev/null
+++ b/tests/BitmapGetColorTest.cpp
@@ -0,0 +1,36 @@
+#include "Test.h"
+#include "SkBitmap.h"
+
+static void TestGetColor(skiatest::Reporter* reporter) {
+    static const struct Rec {
+        SkBitmap::Config    fConfig;
+        SkColor             fInColor;
+        SkColor             fOutColor;
+    } gRec[] = {
+        // todo: add some tests that involve alpha, so we exercise the
+        // unpremultiply aspect of getColor()
+        {   SkBitmap::kA8_Config,           0xFF000000,     0xFF000000  },
+        {   SkBitmap::kA8_Config,           0,              0           },
+        {   SkBitmap::kARGB_4444_Config,    0xFF224466,     0xFF224466  },
+        {   SkBitmap::kARGB_4444_Config,    0,              0           },
+        {   SkBitmap::kRGB_565_Config,      0xFF00FF00,     0xFF00FF00  },
+        {   SkBitmap::kRGB_565_Config,      0xFFFF00FF,     0xFFFF00FF  },
+        {   SkBitmap::kARGB_8888_Config,    0xFFFFFFFF,     0xFFFFFFFF  },
+        {   SkBitmap::kARGB_8888_Config,    0,              0           },
+        {   SkBitmap::kARGB_8888_Config,    0xFF224466,     0xFF224466  },
+    };
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
+        SkBitmap bm;
+        uint32_t storage[1];
+        bm.setConfig(gRec[i].fConfig, 1, 1);
+        bm.setPixels(storage);
+        bm.eraseColor(gRec[i].fInColor);
+
+        SkColor c = bm.getColor(0, 0);
+        REPORTER_ASSERT(reporter, c == gRec[i].fOutColor);
+    }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("GetColor", TestGetColorClass, TestGetColor)
diff --git a/tests/BlitRowTest.cpp b/tests/BlitRowTest.cpp
index 91d6b94..d18cb8a 100644
--- a/tests/BlitRowTest.cpp
+++ b/tests/BlitRowTest.cpp
@@ -207,7 +207,8 @@
     SkBitmap srcBM;
     srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, H);
     srcBM.allocPixels();
-    SkRect srcR = { 0, 0, srcBM.width(), srcBM.height() };
+    SkRect srcR = {
+        0, 0, SkIntToScalar(srcBM.width()), SkIntToScalar(srcBM.height()) };
 
     // cons up a mesh to draw the bitmap with
     Mesh mesh(srcBM, &paint);
diff --git a/tests/ClipCubicTest.cpp b/tests/ClipCubicTest.cpp
index 905b733..e38a22f 100644
--- a/tests/ClipCubicTest.cpp
+++ b/tests/ClipCubicTest.cpp
@@ -7,10 +7,10 @@
 static void PrintCurve(const char *name, const SkPoint crv[4]) {
     printf("%s: %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g\n",
             name,
-            crv[0].fX, crv[0].fY,
-            crv[1].fX, crv[1].fY,
-            crv[2].fX, crv[2].fY,
-            crv[3].fX, crv[3].fY);
+            (float)crv[0].fX, (float)crv[0].fY,
+            (float)crv[1].fX, (float)crv[1].fY,
+            (float)crv[2].fX, (float)crv[2].fY,
+            (float)crv[3].fX, (float)crv[3].fY);
 
 }
 
@@ -46,17 +46,17 @@
 
 static void TestCubicClipping(skiatest::Reporter* reporter) {
     static SkPoint crv[4] = {
-        { SkFloatToScalar(0), SkFloatToScalar(0)  },
-        { SkFloatToScalar(2), SkFloatToScalar(3)  },
-        { SkFloatToScalar(1), SkFloatToScalar(10) },
-        { SkFloatToScalar(4), SkFloatToScalar(12) }
+        { SkIntToScalar(0), SkIntToScalar(0)  },
+        { SkIntToScalar(2), SkIntToScalar(3)  },
+        { SkIntToScalar(1), SkIntToScalar(10) },
+        { SkIntToScalar(4), SkIntToScalar(12) }
     };
 
     SkCubicClipper clipper;
     SkPoint clipped[4], shouldbe[4];
     SkIRect clipRect;
     bool success;
-    const float tol = 1e-4;
+    const float tol = SkFloatToScalar(1e-4);
 
     // Test no clip, with plenty of room.
     clipRect.set(-2, -2, 6, 14);
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
new file mode 100644
index 0000000..e3c95b4
--- /dev/null
+++ b/tests/ClipStackTest.cpp
@@ -0,0 +1,49 @@
+#include "Test.h"
+#include "SkClipStack.h"
+
+static void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack,
+                         int count) {
+    REPORTER_ASSERT(reporter, count == stack.getSaveCount());
+
+    SkClipStack::B2FIter iter(stack);
+    int counter = 0;
+    while (iter.next()) {
+        counter += 1;
+    }
+    REPORTER_ASSERT(reporter, count == counter);
+}
+
+static void TestClipStack(skiatest::Reporter* reporter) {
+    SkClipStack stack;
+
+    assert_count(reporter, stack, 0);
+
+    static const SkIRect gRects[] = {
+        { 0, 0, 100, 100 },
+        { 25, 25, 125, 125 },
+        { 0, 0, 1000, 1000 },
+        { 0, 0, 75, 75 }
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) {
+        stack.clipDevRect(gRects[i]);
+    }
+
+    // all of the above rects should have been intersected, leaving only 1 rect
+    SkClipStack::B2FIter iter(stack);
+    const SkClipStack::B2FIter::Clip* clip = iter.next();
+    const SkRect answer = { 25, 25, 75, 75 };
+
+    REPORTER_ASSERT(reporter, clip);
+    REPORTER_ASSERT(reporter, clip->fRect);
+    REPORTER_ASSERT(reporter, !clip->fPath);
+    REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == clip->fOp);
+    REPORTER_ASSERT(reporter, *clip->fRect == answer);
+    // now check that we only had one in our iterator
+    REPORTER_ASSERT(reporter, !iter.next());
+
+    stack.reset();
+    assert_count(reporter, stack, 0);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack)
diff --git a/tests/DequeTest.cpp b/tests/DequeTest.cpp
new file mode 100644
index 0000000..e74fd28
--- /dev/null
+++ b/tests/DequeTest.cpp
@@ -0,0 +1,96 @@
+#include "Test.h"
+#include "SkDeque.h"
+
+static void assert_count(skiatest::Reporter* reporter, const SkDeque& deq, int count) {
+    if (0 == count) {
+        REPORTER_ASSERT(reporter, deq.empty());
+        REPORTER_ASSERT(reporter, 0 == deq.count());
+        REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize());
+        REPORTER_ASSERT(reporter, NULL == deq.front());
+        REPORTER_ASSERT(reporter, NULL == deq.back());
+    } else {
+        REPORTER_ASSERT(reporter, !deq.empty());
+        REPORTER_ASSERT(reporter, count == deq.count());
+        REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize());
+        REPORTER_ASSERT(reporter, NULL != deq.front());
+        REPORTER_ASSERT(reporter, NULL != deq.back());
+        if (1 == count) {
+            REPORTER_ASSERT(reporter, deq.back() == deq.front());
+        } else {
+            REPORTER_ASSERT(reporter, deq.back() != deq.front());
+        }
+    }
+}
+
+static void assert_f2biter(skiatest::Reporter* reporter, const SkDeque& deq,
+                           int max, int min) {
+    SkDeque::F2BIter iter(deq);
+    void* ptr;
+
+    int value = max;
+    while ((ptr = iter.next()) != NULL) {
+        REPORTER_ASSERT(reporter, value == *(int*)ptr);
+        value -= 1;
+    }
+    REPORTER_ASSERT(reporter, value+1 == min);
+}
+
+static void TestDeque(skiatest::Reporter* reporter) {
+    SkDeque deq(sizeof(int));
+    int i;
+
+    // test pushing on the front
+
+    assert_count(reporter, deq, 0);
+    for (i = 1; i <= 10; i++) {
+        *(int*)deq.push_front() = i;
+    }
+    assert_count(reporter, deq, 10);
+    assert_f2biter(reporter, deq, 10, 1);
+
+    for (i = 0; i < 5; i++) {
+        deq.pop_front();
+    }
+    assert_count(reporter, deq, 5);
+    assert_f2biter(reporter, deq, 5, 1);
+
+    for (i = 0; i < 5; i++) {
+        deq.pop_front();
+    }
+    assert_count(reporter, deq, 0);
+
+    // now test pushing on the back
+
+    for (i = 10; i >= 1; --i) {
+        *(int*)deq.push_back() = i;
+    }
+    assert_count(reporter, deq, 10);
+    assert_f2biter(reporter, deq, 10, 1);
+
+    for (i = 0; i < 5; i++) {
+        deq.pop_back();
+    }
+    assert_count(reporter, deq, 5);
+    assert_f2biter(reporter, deq, 10, 6);
+
+    for (i = 0; i < 5; i++) {
+        deq.pop_back();
+    }
+    assert_count(reporter, deq, 0);
+
+    // now tests pushing/poping on both ends
+
+    *(int*)deq.push_front() = 5;
+    *(int*)deq.push_back() = 4;
+    *(int*)deq.push_front() = 6;
+    *(int*)deq.push_back() = 3;
+    *(int*)deq.push_front() = 7;
+    *(int*)deq.push_back() = 2;
+    *(int*)deq.push_front() = 8;
+    *(int*)deq.push_back() = 1;
+    assert_count(reporter, deq, 8);
+    assert_f2biter(reporter, deq, 8, 1);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Deque", TestDequeClass, TestDeque)
diff --git a/tests/FillPathTest.cpp b/tests/FillPathTest.cpp
new file mode 100644
index 0000000..ffc9f8e
--- /dev/null
+++ b/tests/FillPathTest.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Chromium Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Test.h"
+#include "SkRegion.h"
+#include "SkPath.h"
+#include "SkScan.h"
+#include "SkBlitter.h"
+
+namespace {
+
+struct FakeBlitter : public SkBlitter {
+  FakeBlitter()
+      : m_blitCount(0)
+  {}
+
+  virtual void blitH(int x, int y, int width) {
+    m_blitCount++;
+  }
+
+  int m_blitCount;
+};
+
+}
+
+// http://code.google.com/p/skia/issues/detail?id=87
+// Lines which is not clipped by boundary based clipping, 
+// but skipped after tessellation, should be cleared by the blitter.
+static void TestFillPathInverse(skiatest::Reporter* reporter) {
+  FakeBlitter blitter;
+  SkRegion clip;
+  SkPath path;
+  int height = 100;
+  int width  = 200;
+  int expected_lines = 5;
+  clip.setRect(0, height - expected_lines, width, height);
+  path.moveTo(0.0, 0.0);
+  path.quadTo(width/2, height, width, 0.0);
+  path.close();
+  path.setFillType(SkPath::kInverseWinding_FillType);
+  SkScan::FillPath(path, clip, &blitter);
+
+  REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("FillPath", FillPathTestClass, TestFillPathInverse)
diff --git a/tests/FlateTest.cpp b/tests/FlateTest.cpp
new file mode 100644
index 0000000..f8e0921
--- /dev/null
+++ b/tests/FlateTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Test.h"
+#include "SkFlate.h"
+#include "SkStream.h"
+
+// A memory stream that reports zero size with the standard call, like
+// an unseekable file stream would.
+class SkZeroSizeMemStream : public SkMemoryStream {
+public:
+    virtual size_t read(void* buffer, size_t size) {
+        if (buffer == NULL && size == 0)
+            return 0;
+        if (buffer == NULL && size == kGetSizeKey)
+            size = 0;
+        return SkMemoryStream::read(buffer, size);
+    }
+
+    static const size_t kGetSizeKey = 0xDEADBEEF;
+};
+
+static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
+                      size_t dataSize) {
+    if (testStream == NULL)
+      return;
+
+    SkMemoryStream testData(dataSize);
+    uint8_t* data = (uint8_t*)testData.getMemoryBase();
+    srand(0);  // Make data deterministic.
+    for (size_t i = 0; i < dataSize; i++)
+        data[i] = rand() & 0xFF;
+
+    testStream->setMemory(testData.getMemoryBase(), dataSize, true);
+    SkDynamicMemoryWStream compressed;
+    bool status = SkFlate::Deflate(testStream, &compressed);
+    REPORTER_ASSERT(reporter, status);
+
+    // Check that the input data wasn't changed.
+    size_t inputSize = testStream->getLength();
+    if (inputSize == 0)
+        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
+    REPORTER_ASSERT(reporter, testData.getLength() == inputSize);
+    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
+                                     testStream->getMemoryBase(),
+                                     testData.getLength()) == 0);
+
+    // Assume there are two test sizes, big and small.
+    if (dataSize < 1024)
+      REPORTER_ASSERT(reporter, compressed.getOffset() < 1024);
+    else
+      REPORTER_ASSERT(reporter, compressed.getOffset() > 1024);
+
+    testStream->setMemory(compressed.getStream(), compressed.getOffset(), true);
+    SkDynamicMemoryWStream uncompressed;
+    status = SkFlate::Inflate(testStream, &uncompressed);
+    REPORTER_ASSERT(reporter, status);
+
+    // Check that the input data wasn't changed.
+    inputSize = testStream->getLength();
+    if (inputSize == 0)
+        inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
+    REPORTER_ASSERT(reporter, compressed.getOffset() == inputSize);
+    REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
+                                     compressed.getStream(),
+                                     compressed.getOffset()) == 0);
+
+    // Check that the uncompressed data matches the source data.
+    REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset());
+    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
+                                     uncompressed.getStream(),
+                                     testData.getLength()) == 0);
+}
+
+static void TestFlateCompression(skiatest::Reporter* reporter) {
+    TestFlate(reporter, NULL, 0);
+#ifdef SK_ZLIB_INCLUDE
+    REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
+
+    SkMemoryStream memStream;
+    TestFlate(reporter, &memStream, 512);
+    TestFlate(reporter, &memStream, 10240);
+
+    SkZeroSizeMemStream fileStream;
+    TestFlate(reporter, &fileStream, 512);
+    TestFlate(reporter, &fileStream, 10240);
+#endif
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Flate", FlateTestClass, TestFlateCompression)
diff --git a/tests/InfRectTest.cpp b/tests/InfRectTest.cpp
new file mode 100644
index 0000000..1e15023
--- /dev/null
+++ b/tests/InfRectTest.cpp
@@ -0,0 +1,44 @@
+#include "Test.h"
+#include "SkRect.h"
+
+#ifdef SK_SCALAR_IS_FLOAT
+static float make_zero() {
+    return sk_float_sin(0);
+}
+#endif
+
+static void check_invalid(skiatest::Reporter* reporter,
+                          SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
+    SkRect rect;
+    rect.set(l, t, r, b);
+    REPORTER_ASSERT(reporter, !rect.hasValidCoordinates());
+}
+
+// Tests that hasValidCoordinates() will reject any rect with +/-inf values
+// as one of its coordinates.
+static void TestInfRect(skiatest::Reporter* reporter) {
+#ifdef SK_SCALAR_IS_FLOAT
+    float invalid = 1 / make_zero();    // infinity
+#else
+    SkFixed invalid = SK_FixedNaN;
+#endif
+    SkScalar small = SkIntToScalar(10);
+    SkScalar big = SkIntToScalar(100);
+
+    SkRect rect = SkRect::MakeXYWH(small, small, big, big);
+    REPORTER_ASSERT(reporter, rect.hasValidCoordinates());
+
+    check_invalid(reporter, small, small, big, invalid);
+    check_invalid(reporter, small, small, invalid, big);
+    check_invalid(reporter, small, invalid, big, big);
+    check_invalid(reporter, invalid, small, big, big);
+    check_invalid(reporter, small, small, big, -invalid);
+    check_invalid(reporter, small, small, -invalid, big);
+    check_invalid(reporter, small, -invalid, big, big);
+    check_invalid(reporter, -invalid, small, big, big);
+}
+
+// need tests for SkStrSearch
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("InfRect", InfRectTestClass, TestInfRect)
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 4bfbd94..493691e 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -146,6 +146,38 @@
     }
 }
 
+#ifdef SK_SCALAR_IS_FLOAT
+static float make_zero() {
+    return sk_float_sin(0);
+}
+#endif
+
+static void unittest_isfinite(skiatest::Reporter* reporter) {
+#ifdef SK_SCALAR_IS_FLOAT
+    float nan = ::asin(2);
+    float inf = 1.0 / make_zero();
+    float big = 3.40282e+038;
+
+    REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
+    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
+    REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
+    REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
+#else
+    SkFixed nan = SK_FixedNaN;
+    SkFixed big = SK_FixedMax;
+#endif
+
+    REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
+    REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
+    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
+    REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
+    
+    REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
+    REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
+    REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
+    REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
+}
+
 #endif
 
 static void test_muldiv255(skiatest::Reporter* reporter) {
@@ -171,6 +203,19 @@
 #endif
 }
 
+static void test_muldiv255ceiling(skiatest::Reporter* reporter) {
+    for (int c = 0; c <= 255; c++) {
+        for (int a = 0; a <= 255; a++) {
+            int product = (c * a + 255);
+            int expected_ceiling = (product + (product >> 8)) >> 8;
+            int webkit_ceiling = (c * a + 254) / 255;
+            REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
+            int skia_ceiling = SkMulDiv255Ceiling(c, a);
+            REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
+        }
+    }
+}
+
 static void test_copysign(skiatest::Reporter* reporter) {
     static const int32_t gTriples[] = {
         // x, y, expected result
@@ -237,6 +282,7 @@
 #endif
 
     test_muldiv255(reporter);
+    test_muldiv255ceiling(reporter);
     test_copysign(reporter);
 
     {
@@ -295,6 +341,7 @@
 
 #ifdef SK_CAN_USE_FLOAT
     unittest_fastfloat(reporter);
+    unittest_isfinite(reporter);
 #endif
 
 #ifdef SkLONGLONG
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
index 052687d..49a98c2 100644
--- a/tests/MatrixTest.cpp
+++ b/tests/MatrixTest.cpp
@@ -5,7 +5,7 @@
 #ifdef SK_SCALAR_IS_FLOAT
     const float tolerance = 0.000005f;
 #else
-    const int32_t tolerance = 3;
+    const int32_t tolerance = 8;
 #endif
 
     return SkScalarAbs(a - b) <= tolerance;
@@ -14,7 +14,7 @@
 static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
     for (int i = 0; i < 9; i++) {
         if (!nearly_equal_scalar(a[i], b[i])) {
-            printf("not equal %g %g\n", a[i], b[i]);
+            printf("not equal %g %g\n", (float)a[i], (float)b[i]);
             return false;
         }
     }
diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp
new file mode 100644
index 0000000..6feab51
--- /dev/null
+++ b/tests/PDFPrimitivesTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include "Test.h"
+#include "SkPDFCatalog.h"
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkScalar.h"
+#include "SkStream.h"
+
+static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj,
+                              const std::string& representation,
+                              bool indirect) {
+    size_t directSize = obj->getOutputSize(NULL, false);
+    REPORTER_ASSERT(reporter, directSize == representation.size());
+
+    SkDynamicMemoryWStream buffer;
+    obj->emitObject(&buffer, NULL, false);
+    REPORTER_ASSERT(reporter, directSize == buffer.getOffset());
+    REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), representation.c_str(),
+                                     directSize) == 0);
+
+    if (indirect) {
+        // Indirect output.
+        static char header[] = "1 0 obj\n";
+        static size_t headerLen = strlen(header);
+        static char footer[] = "\nendobj\n";
+        static size_t footerLen = strlen(footer);
+
+        SkPDFCatalog catalog;
+        catalog.addObject(obj, false);
+
+        size_t indirectSize = obj->getOutputSize(&catalog, true);
+        REPORTER_ASSERT(reporter,
+                        indirectSize == directSize + headerLen + footerLen);
+
+        buffer.reset();
+        obj->emitObject(&buffer, &catalog, true);
+        REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset());
+        REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), header,
+                                         headerLen) == 0);
+        REPORTER_ASSERT(reporter,
+                        memcmp(buffer.getStream() + headerLen,
+                               representation.c_str(), directSize) == 0);
+        REPORTER_ASSERT(reporter,
+                        memcmp(buffer.getStream() + headerLen + directSize,
+                               footer, footerLen) == 0);
+    }
+}
+
+static void TestCatalog(skiatest::Reporter* reporter) {
+    SkPDFCatalog catalog;
+    SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+    int1->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
+    int2->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFInt> int3 = new SkPDFInt(3);
+    int3->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFInt> int1Again(int1.get());
+
+    catalog.addObject(int1.get(), false);
+    catalog.addObject(int2.get(), false);
+    catalog.addObject(int3.get(), false);
+
+    REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
+    REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
+    REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int3.get()) == 3);
+
+    SkDynamicMemoryWStream buffer;
+    catalog.emitObjectNumber(&buffer, int1.get());
+    catalog.emitObjectNumber(&buffer, int2.get());
+    catalog.emitObjectNumber(&buffer, int3.get());
+    catalog.emitObjectNumber(&buffer, int1Again.get());
+    char expectedResult[] = "1 02 03 01 0";
+    REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
+                                     strlen(expectedResult)) == 0);
+}
+
+static void TestObjectRef(skiatest::Reporter* reporter) {
+    SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+    int1->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFInt> int2 = new SkPDFInt(2);
+    int2->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFObjRef> int2ref = new SkPDFObjRef(int2.get());
+    int2ref->unref();  // SkRefPtr and new both took a reference.
+
+    SkPDFCatalog catalog;
+    catalog.addObject(int1.get(), false);
+    catalog.addObject(int2.get(), false);
+    REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int1.get()) == 3);
+    REPORTER_ASSERT(reporter, catalog.getObjectNumberSize(int2.get()) == 3);
+
+    char expectedResult[] = "2 0 R";
+    SkDynamicMemoryWStream buffer;
+    int2ref->emitObject(&buffer, &catalog, false);
+    REPORTER_ASSERT(reporter, buffer.getOffset() == strlen(expectedResult));
+    REPORTER_ASSERT(reporter, memcmp(buffer.getStream(), expectedResult,
+                                     buffer.getOffset()) == 0);
+}
+
+static void TestPDFPrimitives(skiatest::Reporter* reporter) {
+    SkRefPtr<SkPDFInt> int42 = new SkPDFInt(42);
+    int42->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, int42.get(), "42", true);
+
+    SkRefPtr<SkPDFScalar> realHalf = new SkPDFScalar(SK_ScalarHalf);
+    realHalf->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, realHalf.get(), "0.5", true);
+
+    SkRefPtr<SkPDFScalar> bigScalar = new SkPDFScalar(110999.75);
+    bigScalar->unref();  // SkRefPtr and new both took a reference.
+#if defined(SK_SCALAR_IS_FIXED) || !defined(SK_ALLOW_LARGE_PDF_SCALARS)
+    CheckObjectOutput(reporter, bigScalar.get(), "111000", true);
+#else
+    CheckObjectOutput(reporter, bigScalar.get(), "110999.75", true);
+#endif
+
+#if defined(SK_SCALAR_IS_FLOAT) && defined(SK_ALLOW_LARGE_PDF_SCALARS)
+    SkRefPtr<SkPDFScalar> biggerScalar = new SkPDFScalar(50000000.1);
+    biggerScalar->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, biggerScalar.get(), "50000000", true);
+
+    SkRefPtr<SkPDFScalar> smallestScalar = new SkPDFScalar(1.0/65536);
+    smallestScalar->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, smallestScalar.get(), "0.00001526", true);
+#endif
+
+    SkRefPtr<SkPDFString> stringSimple = new SkPDFString("test ) string ( foo");
+    stringSimple->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, stringSimple.get(), "(test \\) string \\( foo)",
+                      true);
+    SkRefPtr<SkPDFString> stringComplex =
+        new SkPDFString("\ttest ) string ( foo");
+    stringComplex->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, stringComplex.get(),
+                      "<0974657374202920737472696E67202820666F6F>", true);
+
+    SkRefPtr<SkPDFName> name = new SkPDFName("Test name\twith#tab");
+    name->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, name.get(), "/Test#20name#09with#23tab", false);
+
+    SkRefPtr<SkPDFArray> array = new SkPDFArray;
+    array->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, array.get(), "[]", true);
+    array->append(int42.get());
+    CheckObjectOutput(reporter, array.get(), "[42]", true);
+    array->append(realHalf.get());
+    CheckObjectOutput(reporter, array.get(), "[42 0.5]", true);
+    SkRefPtr<SkPDFInt> int0 = new SkPDFInt(0);
+    int0->unref();  // SkRefPtr and new both took a reference.
+    array->append(int0.get());
+    CheckObjectOutput(reporter, array.get(), "[42 0.5 0]", true);
+    SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
+    int1->unref();  // SkRefPtr and new both took a reference.
+    array->setAt(0, int1.get());
+    CheckObjectOutput(reporter, array.get(), "[1 0.5 0]", true);
+
+    SkRefPtr<SkPDFDict> dict = new SkPDFDict;
+    dict->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, dict.get(), "<<>>", true);
+    SkRefPtr<SkPDFName> n1 = new SkPDFName("n1");
+    n1->unref();  // SkRefPtr and new both took a reference.
+    dict->insert(n1.get(), int42.get());
+    CheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>", true);
+    SkRefPtr<SkPDFName> n2 = new SkPDFName("n2");
+    n2->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFName> n3 = new SkPDFName("n3");
+    n3->unref();  // SkRefPtr and new both took a reference.
+    dict->insert(n2.get(), realHalf.get());
+    dict->insert(n3.get(), array.get());
+    CheckObjectOutput(reporter, dict.get(),
+                      "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>", true);
+
+    char streamBytes[] = "Test\nFoo\tBar";
+    SkRefPtr<SkMemoryStream> streamData = new SkMemoryStream(
+        streamBytes, strlen(streamBytes), true);
+    streamData->unref();  // SkRefPtr and new both took a reference.
+    SkRefPtr<SkPDFStream> stream = new SkPDFStream(streamData.get());
+    stream->unref();  // SkRefPtr and new both took a reference.
+    CheckObjectOutput(reporter, stream.get(),
+                      "<</Length 12\n>> stream\nTest\nFoo\tBar\nendstream",
+                      true);
+    stream->insert(n1.get(), int42.get());
+    CheckObjectOutput(reporter, stream.get(),
+                      "<</Length 12\n/n1 42\n>> stream\nTest\nFoo\tBar"
+                      "\nendstream",
+                      true);
+
+    TestCatalog(reporter);
+
+    TestObjectRef(reporter);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PDFPrimitives", PDFPrimitivesTestClass, TestPDFPrimitives)
diff --git a/tests/PaintTest.cpp b/tests/PaintTest.cpp
index 4e6c8b9..5b19090 100644
--- a/tests/PaintTest.cpp
+++ b/tests/PaintTest.cpp
@@ -8,10 +8,14 @@
     SkPath path, stroke;
     SkPaint paint;
 
-    path.moveTo(460.2881309415525, 303.250847066498);
-    path.cubicTo(463.36378422175284, 302.1169735073363,
-                 456.32239330810046, 304.720354932878,
-                 453.15255460013304, 305.788586869862);
+    path.moveTo(SkFloatToFixed(460.2881309415525f),
+                SkFloatToFixed(303.250847066498));
+    path.cubicTo(SkFloatToFixed(463.36378422175284),
+                 SkFloatToFixed(302.1169735073363),
+                 SkFloatToFixed(456.32239330810046),
+                 SkFloatToFixed(304.720354932878),
+                 SkFloatToFixed(453.15255460013304),
+                 SkFloatToFixed(305.788586869862));
     
     SkRect fillR, strokeR;
     fillR = path.getBounds();
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 9f26d01..b4b6317 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -6,7 +6,7 @@
                                 const SkRect& bounds) {
     REPORTER_ASSERT(reporter, p.isConvex());
     REPORTER_ASSERT(reporter, p.getBounds() == bounds);
-    
+
     SkPath p2(p);
     REPORTER_ASSERT(reporter, p2.isConvex());
     REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
@@ -45,12 +45,12 @@
     p.setIsConvex(false);
     p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
     check_convex_bounds(reporter, p, bounds);
-    
+
     p.reset();
     p.setIsConvex(false);
     p.addOval(bounds);
     check_convex_bounds(reporter, p, bounds);
-    
+
     p.reset();
     p.setIsConvex(false);
     p.addRect(bounds);
@@ -88,6 +88,18 @@
     p.moveTo(SK_Scalar1, 0);
     p.getLastPt(&pt);
     REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1);
+
+    // check that reset and rewind clear the convex hint back to false
+    p.setIsConvex(false);
+    REPORTER_ASSERT(reporter, !p.isConvex());
+    p.setIsConvex(true);
+    REPORTER_ASSERT(reporter, p.isConvex());
+    p.reset();
+    REPORTER_ASSERT(reporter, !p.isConvex());
+    p.setIsConvex(true);
+    REPORTER_ASSERT(reporter, p.isConvex());
+    p.rewind();
+    REPORTER_ASSERT(reporter, !p.isConvex());
 }
 
 #include "TestClassDef.h"
diff --git a/tests/RefDictTest.cpp b/tests/RefDictTest.cpp
new file mode 100644
index 0000000..f52541b
--- /dev/null
+++ b/tests/RefDictTest.cpp
@@ -0,0 +1,66 @@
+#include "Test.h"
+#include "SkRefDict.h"
+
+class TestRC : public SkRefCnt {
+};
+
+static void TestRefDict(skiatest::Reporter* reporter) {
+    TestRC    data0, data1;
+    SkRefDict dict;
+
+    REPORTER_ASSERT(reporter, NULL == dict.find(NULL));
+    REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+    REPORTER_ASSERT(reporter, NULL == dict.find("bar"));
+
+    dict.set("foo", &data0);
+    REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+    REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+
+    dict.set("foo", &data0);
+    REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+    REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+
+    dict.set("foo", &data1);
+    REPORTER_ASSERT(reporter, &data1 == dict.find("foo"));
+    REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+    REPORTER_ASSERT(reporter, 2 == data1.getRefCnt());
+
+    dict.set("foo", NULL);
+    REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+    REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+    REPORTER_ASSERT(reporter, 1 == data1.getRefCnt());
+
+    dict.set("foo", &data0);
+    dict.set("bar", &data1);
+    REPORTER_ASSERT(reporter, &data0 == dict.find("foo"));
+    REPORTER_ASSERT(reporter, &data1 == dict.find("bar"));
+    REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+    REPORTER_ASSERT(reporter, 2 == data1.getRefCnt());
+
+    dict.set("foo", &data1);
+    REPORTER_ASSERT(reporter, &data1 == dict.find("foo"));
+    REPORTER_ASSERT(reporter, &data1 == dict.find("bar"));
+    REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+    REPORTER_ASSERT(reporter, 3 == data1.getRefCnt());
+
+    dict.removeAll();
+    REPORTER_ASSERT(reporter, NULL == dict.find("foo"));
+    REPORTER_ASSERT(reporter, NULL == dict.find("bar"));
+    REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+    REPORTER_ASSERT(reporter, 1 == data1.getRefCnt());
+
+    {
+        SkRefDict d;
+        REPORTER_ASSERT(reporter, NULL == d.find("foo"));
+        REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+        d.set("foo", &data0);
+        REPORTER_ASSERT(reporter, &data0 == d.find("foo"));
+        REPORTER_ASSERT(reporter, 2 == data0.getRefCnt());
+        // let d go out of scope still with a ref on data0
+    }
+    // be sure d's destructor lowered data0's owner count back to 1
+    REPORTER_ASSERT(reporter, 1 == data0.getRefCnt());
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("RefDict", RefDictTestClass, TestRefDict)
diff --git a/tests/RegionTest.cpp b/tests/RegionTest.cpp
new file mode 100644
index 0000000..ee34d8b
--- /dev/null
+++ b/tests/RegionTest.cpp
@@ -0,0 +1,63 @@
+#include "Test.h"
+#include "SkRegion.h"
+#include "SkRandom.h"
+
+static void rand_rect(SkIRect* rect, SkRandom& rand) {
+    int bits = 6;
+    int shift = 32 - bits;
+    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
+              rand.nextU() >> shift, rand.nextU() >> shift);
+    rect->sort();
+}
+
+static bool test_rects(const SkIRect rect[], int count) {
+    SkRegion rgn0, rgn1;
+
+    for (int i = 0; i < count; i++) {
+        rgn0.op(rect[i], SkRegion::kUnion_Op);
+    }
+    rgn1.setRects(rect, count);
+
+    if (rgn0 != rgn1) {
+        SkDebugf("\n");
+        for (int i = 0; i < count; i++) {
+            SkDebugf(" { %d, %d, %d, %d },\n",
+                     rect[i].fLeft, rect[i].fTop,
+                     rect[i].fRight, rect[i].fBottom);
+        }
+        SkDebugf("\n");
+        return false;
+    }
+    return true;
+}
+
+static void TestRegion(skiatest::Reporter* reporter) {
+    const SkIRect r2[] = {
+        { 0, 0, 1, 1 },
+        { 2, 2, 3, 3 },
+    };
+    REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
+    
+    const SkIRect rects[] = {
+        { 0, 0, 1, 2 },
+        { 2, 1, 3, 3 },
+        { 4, 0, 5, 1 },
+        { 6, 0, 7, 4 },
+    };
+    REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
+
+    SkRandom rand;
+    for (int i = 0; i < 1000; i++) {
+        SkRegion rgn0, rgn1;
+
+        const int N = 8;
+        SkIRect rect[N];
+        for (int j = 0; j < N; j++) {
+            rand_rect(&rect[j], rand);
+        }
+        REPORTER_ASSERT(reporter, test_rects(rect, N));
+    }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Region", RegionTestClass, TestRegion)
diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp
index 344c752..270ccfd 100644
--- a/tests/StringTest.cpp
+++ b/tests/StringTest.cpp
@@ -48,6 +48,43 @@
     a.set("ab");
     a.set("abc");
     a.set("abcd");
+
+    a.set("");
+    a.appendS64(72036854775808LL, 0);
+    REPORTER_ASSERT(reporter, a.equals("72036854775808"));
+
+    a.set("");
+    a.appendS64(-1844674407370LL, 0);
+    REPORTER_ASSERT(reporter, a.equals("-1844674407370"));
+
+    a.set("");
+    a.appendS64(73709551616LL, 15);
+    REPORTER_ASSERT(reporter, a.equals("000073709551616"));
+
+    a.set("");
+    a.appendS64(-429496729612LL, 15);
+    REPORTER_ASSERT(reporter, a.equals("-000429496729612"));
+
+    static const struct {
+        SkScalar    fValue;
+        const char* fString;
+    } gRec[] = {
+        { 0,            "0" },
+        { SK_Scalar1,   "1" },
+        { -SK_Scalar1,  "-1" },
+        { SK_Scalar1/2, "0.5" },
+#ifdef SK_SCALAR_IS_FLOAT
+        { 3.4028234e38f,   "3.4028235e+38" },
+        { -3.4028234e38f, "-3.4028235e+38" },
+#endif
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
+        a.reset();
+        a.appendScalar(gRec[i].fValue);
+        REPORTER_ASSERT(reporter, a.size() <= SkStrAppendScalar_MaxSize);
+//        SkDebugf(" received <%s> expected <%s>\n", a.c_str(), gRec[i].fString);
+        REPORTER_ASSERT(reporter, a.equals(gRec[i].fString));
+    }
 }
 
 #include "TestClassDef.h"
diff --git a/tests/TestSize.cpp b/tests/TestSize.cpp
index 6551509..9e0aaaa 100644
--- a/tests/TestSize.cpp
+++ b/tests/TestSize.cpp
@@ -53,7 +53,7 @@
     SkISize ia;
     ia.set(ix, iy);
     a.set(x, y);
-    REPORTER_ASSERT(reporter, a.round() == ia);
+    REPORTER_ASSERT(reporter, a.toRound() == ia);
 };
 
 #include "TestClassDef.h"
diff --git a/tests/UtilsTest.cpp b/tests/UtilsTest.cpp
index 8a8319c..2019a77 100644
--- a/tests/UtilsTest.cpp
+++ b/tests/UtilsTest.cpp
@@ -1,9 +1,71 @@
 #include "Test.h"
 #include "SkRandom.h"
+#include "SkRefCnt.h"
 #include "SkTSearch.h"
 #include "SkTSort.h"
 #include "SkUtils.h"
 
+class RefClass : public SkRefCnt {
+public:
+    RefClass(int n) : fN(n) {}
+    int get() const { return fN; }
+
+private:
+    int fN;
+};
+
+static void test_refptr(skiatest::Reporter* reporter) {
+    RefClass* r0 = new RefClass(0);
+
+    SkRefPtr<RefClass> rc0;
+    REPORTER_ASSERT(reporter, rc0.get() == NULL);
+    REPORTER_ASSERT(reporter, !rc0);
+
+    SkRefPtr<RefClass> rc1;
+    REPORTER_ASSERT(reporter, rc0 == rc1);
+    REPORTER_ASSERT(reporter, rc0.get() != r0);
+
+    rc0 = r0;
+    REPORTER_ASSERT(reporter, rc0);
+    REPORTER_ASSERT(reporter, rc0 != rc1);
+    REPORTER_ASSERT(reporter, rc0.get() == r0);
+
+    rc1 = rc0;
+    REPORTER_ASSERT(reporter, rc1);
+    REPORTER_ASSERT(reporter, rc0 == rc1);
+    REPORTER_ASSERT(reporter, rc0.get() == r0);
+
+    rc0 = NULL;
+    REPORTER_ASSERT(reporter, rc0.get() == NULL);
+    REPORTER_ASSERT(reporter, !rc0);
+    REPORTER_ASSERT(reporter, rc0 != rc1);
+
+    r0->unref();
+}
+
+static void test_autounref(skiatest::Reporter* reporter) {
+    RefClass obj(0);
+    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+
+    SkAutoTUnref<RefClass> tmp(&obj);
+    REPORTER_ASSERT(reporter, &obj == tmp.get());
+    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+
+    REPORTER_ASSERT(reporter, &obj == tmp.detach());
+    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+    REPORTER_ASSERT(reporter, NULL == tmp.detach());
+    REPORTER_ASSERT(reporter, NULL == tmp.get());
+
+    obj.ref();
+    REPORTER_ASSERT(reporter, 2 == obj.getRefCnt());
+    {
+        SkAutoTUnref<RefClass> tmp2(&obj);
+    }
+    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 #define kSEARCH_COUNT   91
 
 static void test_search(skiatest::Reporter* reporter) {
@@ -103,7 +165,9 @@
 
     test_utf16(reporter);
     test_search(reporter);
+    test_refptr(reporter);
+    test_autounref(reporter);
 }
 
 #include "TestClassDef.h"
-DEFINE_TESTCLASS("UTF", UtfTestClass, TestUTF)
+DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF)
diff --git a/tests/XfermodeTest.cpp b/tests/XfermodeTest.cpp
new file mode 100644
index 0000000..6ab6cd7
--- /dev/null
+++ b/tests/XfermodeTest.cpp
@@ -0,0 +1,30 @@
+#include "Test.h"
+#include "SkColor.h"
+#include "SkXfermode.h"
+
+SkPMColor bogusXfermodeProc(SkPMColor src, SkPMColor dst) {
+    return 42;
+}
+
+static void test_asMode(skiatest::Reporter* reporter) {
+    for (int mode = 0; mode <= SkXfermode::kLastMode; mode++) {
+        SkXfermode* xfer = SkXfermode::Create((SkXfermode::Mode) mode);
+        SkXfermode::Mode reportedMode = (SkXfermode::Mode) -1;
+        REPORTER_ASSERT(reporter,
+                        xfer != NULL || mode == SkXfermode::kSrcOver_Mode);
+        if (xfer) {
+          REPORTER_ASSERT(reporter, xfer->asMode(&reportedMode));
+          REPORTER_ASSERT(reporter, reportedMode == mode);
+          xfer->unref();
+        }
+    }
+
+    SkXfermode* bogusXfer = new SkProcXfermode(bogusXfermodeProc);
+    SkXfermode::Mode reportedMode = (SkXfermode::Mode) -1;
+    REPORTER_ASSERT(reporter, !bogusXfer->asMode(&reportedMode));
+    REPORTER_ASSERT(reporter, reportedMode == -1);
+    bogusXfer->unref();
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("Xfermode", XfermodeTestClass, test_asMode)
diff --git a/tests/tests_files.mk b/tests/tests_files.mk
new file mode 100644
index 0000000..5280502
--- /dev/null
+++ b/tests/tests_files.mk
@@ -0,0 +1,31 @@
+SOURCE := \
+    BitmapCopyTest.cpp \
+    BitmapGetColorTest.cpp \
+    BlitRowTest.cpp \
+    ClipCubicTest.cpp \
+    ClipStackTest.cpp \
+    ClipperTest.cpp \
+    DequeTest.cpp \
+    FillPathTest.cpp \
+    FlateTest.cpp \
+    GeometryTest.cpp \
+    InfRectTest.cpp \
+    MathTest.cpp \
+    MatrixTest.cpp \
+    PackBitsTest.cpp \
+    PaintTest.cpp \
+    ParsePathTest.cpp \
+    PathMeasureTest.cpp \
+    PathTest.cpp \
+    RefDictTest.cpp \
+    RegionTest.cpp \
+    Sk64Test.cpp \
+    skia_test.cpp \
+    SortTest.cpp \
+    SrcOverTest.cpp \
+    StreamTest.cpp \
+    StringTest.cpp \
+    Test.cpp \
+    TestSize.cpp \
+    UtilsTest.cpp \
+    XfermodeTest.cpp
diff --git a/xcode/GL.xcodeproj/project.pbxproj b/xcode/GL.xcodeproj/project.pbxproj
deleted file mode 100644
index 2d60cf8..0000000
--- a/xcode/GL.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,267 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 44;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DCF60EDCA0BD00F77EA2 /* SkGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCE90EDCA0BD00F77EA2 /* SkGL.cpp */; };
-		00B7DCF70EDCA0BD00F77EA2 /* SkGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCEA0EDCA0BD00F77EA2 /* SkGL.h */; };
-		00B7DCF80EDCA0BD00F77EA2 /* SkGLCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCEB0EDCA0BD00F77EA2 /* SkGLCanvas.cpp */; };
-		00B7DCF90EDCA0BD00F77EA2 /* SkGLDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCEC0EDCA0BD00F77EA2 /* SkGLDevice.cpp */; };
-		00B7DCFA0EDCA0BD00F77EA2 /* SkGLDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCED0EDCA0BD00F77EA2 /* SkGLDevice.h */; };
-		00B7DCFB0EDCA0BD00F77EA2 /* SkGLDevice_FBO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCEE0EDCA0BD00F77EA2 /* SkGLDevice_FBO.cpp */; };
-		00B7DCFC0EDCA0BD00F77EA2 /* SkGLDevice_FBO.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCEF0EDCA0BD00F77EA2 /* SkGLDevice_FBO.h */; };
-		00B7DCFD0EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCF00EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.cpp */; };
-		00B7DCFE0EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCF10EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.h */; };
-		00B7DCFF0EDCA0BD00F77EA2 /* SkGLTextCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCF20EDCA0BD00F77EA2 /* SkGLTextCache.cpp */; };
-		00B7DD000EDCA0BD00F77EA2 /* SkGLTextCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCF30EDCA0BD00F77EA2 /* SkGLTextCache.h */; };
-		00B7DD010EDCA0BD00F77EA2 /* SkTextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCF40EDCA0BD00F77EA2 /* SkTextureCache.cpp */; };
-		00B7DD020EDCA0BD00F77EA2 /* SkTextureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DCF50EDCA0BD00F77EA2 /* SkTextureCache.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DCE90EDCA0BD00F77EA2 /* SkGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGL.cpp; path = ../libsgl/gl/SkGL.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCEA0EDCA0BD00F77EA2 /* SkGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGL.h; path = ../libsgl/gl/SkGL.h; sourceTree = SOURCE_ROOT; };
-		00B7DCEB0EDCA0BD00F77EA2 /* SkGLCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLCanvas.cpp; path = ../libsgl/gl/SkGLCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCEC0EDCA0BD00F77EA2 /* SkGLDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice.cpp; path = ../libsgl/gl/SkGLDevice.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCED0EDCA0BD00F77EA2 /* SkGLDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice.h; path = ../libsgl/gl/SkGLDevice.h; sourceTree = SOURCE_ROOT; };
-		00B7DCEE0EDCA0BD00F77EA2 /* SkGLDevice_FBO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice_FBO.cpp; path = ../libsgl/gl/SkGLDevice_FBO.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCEF0EDCA0BD00F77EA2 /* SkGLDevice_FBO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice_FBO.h; path = ../libsgl/gl/SkGLDevice_FBO.h; sourceTree = SOURCE_ROOT; };
-		00B7DCF00EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice_SWLayer.cpp; path = ../libsgl/gl/SkGLDevice_SWLayer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCF10EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice_SWLayer.h; path = ../libsgl/gl/SkGLDevice_SWLayer.h; sourceTree = SOURCE_ROOT; };
-		00B7DCF20EDCA0BD00F77EA2 /* SkGLTextCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLTextCache.cpp; path = ../libsgl/gl/SkGLTextCache.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCF30EDCA0BD00F77EA2 /* SkGLTextCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLTextCache.h; path = ../libsgl/gl/SkGLTextCache.h; sourceTree = SOURCE_ROOT; };
-		00B7DCF40EDCA0BD00F77EA2 /* SkTextureCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextureCache.cpp; path = ../libsgl/gl/SkTextureCache.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCF50EDCA0BD00F77EA2 /* SkTextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTextureCache.h; path = ../libsgl/gl/SkTextureCache.h; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libGL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libGL.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* GL */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = GL;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DCE90EDCA0BD00F77EA2 /* SkGL.cpp */,
-				00B7DCEA0EDCA0BD00F77EA2 /* SkGL.h */,
-				00B7DCEB0EDCA0BD00F77EA2 /* SkGLCanvas.cpp */,
-				00B7DCEC0EDCA0BD00F77EA2 /* SkGLDevice.cpp */,
-				00B7DCED0EDCA0BD00F77EA2 /* SkGLDevice.h */,
-				00B7DCEE0EDCA0BD00F77EA2 /* SkGLDevice_FBO.cpp */,
-				00B7DCEF0EDCA0BD00F77EA2 /* SkGLDevice_FBO.h */,
-				00B7DCF00EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.cpp */,
-				00B7DCF10EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.h */,
-				00B7DCF20EDCA0BD00F77EA2 /* SkGLTextCache.cpp */,
-				00B7DCF30EDCA0BD00F77EA2 /* SkGLTextCache.h */,
-				00B7DCF40EDCA0BD00F77EA2 /* SkTextureCache.cpp */,
-				00B7DCF50EDCA0BD00F77EA2 /* SkTextureCache.h */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libGL.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DCF70EDCA0BD00F77EA2 /* SkGL.h in Headers */,
-				00B7DCFA0EDCA0BD00F77EA2 /* SkGLDevice.h in Headers */,
-				00B7DCFC0EDCA0BD00F77EA2 /* SkGLDevice_FBO.h in Headers */,
-				00B7DCFE0EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.h in Headers */,
-				00B7DD000EDCA0BD00F77EA2 /* SkGLTextCache.h in Headers */,
-				00B7DD020EDCA0BD00F77EA2 /* SkTextureCache.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* GL */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "GL" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = GL;
-			productName = GL;
-			productReference = D2AAC046055464E500DB518D /* libGL.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "GL" */;
-			compatibilityVersion = "Xcode 3.0";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* GL */;
-			projectDirPath = "";
-			projectRoot = "";
-			targets = (
-				D2AAC045055464E500DB518D /* GL */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DCF60EDCA0BD00F77EA2 /* SkGL.cpp in Sources */,
-				00B7DCF80EDCA0BD00F77EA2 /* SkGLCanvas.cpp in Sources */,
-				00B7DCF90EDCA0BD00F77EA2 /* SkGLDevice.cpp in Sources */,
-				00B7DCFB0EDCA0BD00F77EA2 /* SkGLDevice_FBO.cpp in Sources */,
-				00B7DCFD0EDCA0BD00F77EA2 /* SkGLDevice_SWLayer.cpp in Sources */,
-				00B7DCFF0EDCA0BD00F77EA2 /* SkGLTextCache.cpp in Sources */,
-				00B7DD010EDCA0BD00F77EA2 /* SkTextureCache.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = GL;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = GL;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_DEBUG,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
-				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_SIGN_COMPARE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../libsgl/sgl ../include/corecg ../include/graphics";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = (
-					ppc,
-					i386,
-				);
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
-				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_SIGN_COMPARE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../libsgl/sgl ../include/corecg ../include/graphics";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "GL" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "GL" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/SampleCode/English.lproj/InfoPlist.strings b/xcode/SampleCode/English.lproj/InfoPlist.strings
deleted file mode 100644
index e842e19..0000000
--- a/xcode/SampleCode/English.lproj/InfoPlist.strings
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Localized versions of Info.plist keys */
-
-NSHumanReadableCopyright = "© __MyCompanyName__, 2008";
diff --git a/xcode/SampleCode/English.lproj/main.nib/classes.nib b/xcode/SampleCode/English.lproj/main.nib/classes.nib
deleted file mode 100644
index c4b887e..0000000
--- a/xcode/SampleCode/English.lproj/main.nib/classes.nib
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>IBVersion</key>
-	<string>1</string>
-</dict>
-</plist>
diff --git a/xcode/SampleCode/English.lproj/main.nib/info.nib b/xcode/SampleCode/English.lproj/main.nib/info.nib
deleted file mode 100644
index 2af896b..0000000
--- a/xcode/SampleCode/English.lproj/main.nib/info.nib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>IBFramework Version</key>
-	<string>629</string>
-	<key>IBLastKnownRelativeProjectPath</key>
-	<string>../../SampleCode.xcodeproj</string>
-	<key>IBOldestOS</key>
-	<integer>5</integer>
-	<key>IBOpenObjects</key>
-	<array/>
-	<key>IBSystem Version</key>
-	<string>9B18</string>
-	<key>targetFramework</key>
-	<string>IBCarbonFramework</string>
-</dict>
-</plist>
diff --git a/xcode/SampleCode/English.lproj/main.nib/objects.xib b/xcode/SampleCode/English.lproj/main.nib/objects.xib
deleted file mode 100644
index a9e438e..0000000
--- a/xcode/SampleCode/English.lproj/main.nib/objects.xib
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<object class="NSIBObjectData">
-  <object name="rootObject" class="NSCustomObject" id="1">
-  </object>
-  <array count="38" name="allObjects">
-    <object class="IBCarbonMenuItem" id="193">
-      <string name="title">Arrange in Front</string>
-      <boolean name="dynamic">TRUE</boolean>
-      <int name="keyEquivalentModifier">1572864</int>
-      <ostype name="command">frnt</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="148">
-      <string name="title">Select All</string>
-      <string name="keyEquivalent">a</string>
-      <ostype name="command">sall</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="152">
-      <string name="title">Edit</string>
-      <object name="submenu" class="IBCarbonMenu" id="147">
-        <string name="title">Edit</string>
-        <array count="10" name="items">
-          <object class="IBCarbonMenuItem" id="141">
-            <string name="title">Undo</string>
-            <string name="keyEquivalent">z</string>
-            <ostype name="command">undo</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="146">
-            <string name="title">Redo</string>
-            <string name="keyEquivalent">Z</string>
-            <ostype name="command">redo</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="142">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="143">
-            <string name="title">Cut</string>
-            <string name="keyEquivalent">x</string>
-            <ostype name="command">cut </ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="149">
-            <string name="title">Copy</string>
-            <string name="keyEquivalent">c</string>
-            <ostype name="command">copy</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="144">
-            <string name="title">Paste</string>
-            <string name="keyEquivalent">v</string>
-            <ostype name="command">past</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="151">
-            <string name="title">Delete</string>
-            <ostype name="command">clea</ostype>
-          </object>
-          <reference idRef="148"/>
-          <object class="IBCarbonMenuItem" id="199">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="198">
-            <string name="title">Special Characters…</string>
-            <ostype name="command">chrp</ostype>
-          </object>
-        </array>
-      </object>
-    </object>
-    <object class="IBCarbonRootControl" id="167">
-      <string name="bounds">0 0 360 480 </string>
-    </object>
-    <object class="IBCarbonMenuItem" id="139">
-      <string name="title">New</string>
-      <string name="keyEquivalent">n</string>
-      <ostype name="command">new </ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="192">
-      <string name="title">Window</string>
-      <object name="submenu" class="IBCarbonMenu" id="195">
-        <string name="title">Window</string>
-        <string name="name">_NSWindowsMenu</string>
-        <array count="6" name="items">
-          <object class="IBCarbonMenuItem" id="190">
-            <string name="title">Minimize</string>
-            <string name="keyEquivalent">m</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <ostype name="command">mini</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="191">
-            <string name="title">Minimize All</string>
-            <string name="keyEquivalent">m</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <int name="keyEquivalentModifier">1572864</int>
-            <ostype name="command">mina</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="197">
-            <string name="title">Zoom</string>
-            <ostype name="command">zoom</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="194">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="196">
-            <string name="title">Bring All to Front</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <ostype name="command">bfrt</ostype>
-          </object>
-          <reference idRef="193"/>
-        </array>
-      </object>
-    </object>
-    <object class="IBCarbonMenuItem" id="132">
-      <string name="title">Revert</string>
-      <string name="keyEquivalent">r</string>
-      <ostype name="command">rvrt</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="187">
-      <string name="title">About Foo</string>
-      <int name="keyEquivalentModifier">0</int>
-      <ostype name="command">abou</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="138">
-      <string name="title">Save</string>
-      <string name="keyEquivalent">s</string>
-      <ostype name="command">save</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="137">
-      <string name="title">Save As…</string>
-      <string name="keyEquivalent">S</string>
-      <ostype name="command">svas</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="136">
-      <string name="title">Print…</string>
-      <string name="keyEquivalent">p</string>
-      <ostype name="command">prnt</ostype>
-    </object>
-    <reference idRef="146"/>
-    <reference idRef="142"/>
-    <reference idRef="143"/>
-    <object class="IBCarbonWindow" id="166">
-      <boolean name="liveResize">TRUE</boolean>
-      <int name="scalingMode">1048576</int>
-      <string name="title">Window</string>
-      <reference name="rootControl" idRef="167"/>
-      <string name="windowRect">1001 727 1361 1207 </string>
-      <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
-    </object>
-    <reference idRef="199"/>
-    <object class="IBCarbonMenuItem" id="135">
-      <string name="title">Page Setup…</string>
-      <string name="keyEquivalent">P</string>
-      <ostype name="command">page</ostype>
-    </object>
-    <reference idRef="144"/>
-    <object class="IBCarbonMenuItem" id="134">
-      <string name="title">Open…</string>
-      <string name="keyEquivalent">o</string>
-      <ostype name="command">open</ostype>
-    </object>
-    <object class="IBCarbonMenu" id="131">
-      <string name="title">File</string>
-      <array count="10" name="items">
-        <reference idRef="139"/>
-        <reference idRef="134"/>
-        <object class="IBCarbonMenuItem" id="133">
-          <boolean name="separator">TRUE</boolean>
-        </object>
-        <object class="IBCarbonMenuItem" id="130">
-          <string name="title">Close</string>
-          <string name="keyEquivalent">w</string>
-          <ostype name="command">clos</ostype>
-        </object>
-        <reference idRef="138"/>
-        <reference idRef="137"/>
-        <reference idRef="132"/>
-        <object class="IBCarbonMenuItem" id="128">
-          <boolean name="separator">TRUE</boolean>
-        </object>
-        <reference idRef="135"/>
-        <reference idRef="136"/>
-      </array>
-    </object>
-    <reference idRef="128"/>
-    <reference idRef="141"/>
-    <reference idRef="198"/>
-    <object class="IBCarbonMenu" id="29">
-      <string name="title">main</string>
-      <string name="name">_NSMainMenu</string>
-      <array count="4" name="items">
-        <object class="IBCarbonMenuItem" id="185">
-          <string name="title">Foo</string>
-          <object name="submenu" class="IBCarbonMenu" id="184">
-            <string name="title">Foo</string>
-            <string name="name">_NSAppleMenu</string>
-            <array count="1" name="items">
-              <reference idRef="187"/>
-            </array>
-          </object>
-        </object>
-        <object class="IBCarbonMenuItem" id="127">
-          <string name="title">File</string>
-          <reference name="submenu" idRef="131"/>
-        </object>
-        <reference idRef="152"/>
-        <reference idRef="192"/>
-      </array>
-    </object>
-    <reference idRef="184"/>
-    <reference idRef="194"/>
-    <reference idRef="195"/>
-    <reference idRef="127"/>
-    <reference idRef="147"/>
-    <reference idRef="133"/>
-    <reference idRef="149"/>
-    <reference idRef="151"/>
-    <reference idRef="190"/>
-    <reference idRef="185"/>
-    <reference idRef="197"/>
-    <reference idRef="130"/>
-    <reference idRef="191"/>
-    <reference idRef="196"/>
-  </array>
-  <array count="38" name="allParents">
-    <reference idRef="195"/>
-    <reference idRef="147"/>
-    <reference idRef="29"/>
-    <reference idRef="166"/>
-    <reference idRef="131"/>
-    <reference idRef="29"/>
-    <reference idRef="131"/>
-    <reference idRef="184"/>
-    <reference idRef="131"/>
-    <reference idRef="131"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="1"/>
-    <reference idRef="147"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="131"/>
-    <reference idRef="127"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="1"/>
-    <reference idRef="185"/>
-    <reference idRef="195"/>
-    <reference idRef="192"/>
-    <reference idRef="29"/>
-    <reference idRef="152"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="195"/>
-    <reference idRef="29"/>
-    <reference idRef="195"/>
-    <reference idRef="131"/>
-    <reference idRef="195"/>
-    <reference idRef="195"/>
-  </array>
-  <dictionary count="3" name="nameTable">
-    <string>File&apos;s Owner</string>
-    <reference idRef="1"/>
-    <string>MainWindow</string>
-    <reference idRef="166"/>
-    <string>MenuBar</string>
-    <reference idRef="29"/>
-  </dictionary>
-  <string name="targetFramework">IBCarbonFramework</string>
-  <unsigned_int name="nextObjectID">200</unsigned_int>
-</object>
diff --git a/xcode/SampleCode/Info.plist b/xcode/SampleCode/Info.plist
deleted file mode 100644
index e12ff9b..0000000
--- a/xcode/SampleCode/Info.plist
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>${EXECUTABLE_NAME}</string>
-	<key>CFBundleIconFile</key>
-	<string></string>
-	<key>CFBundleIdentifier</key>
-	<string>com.yourcompany.SampleCode</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>${PRODUCT_NAME}</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1.0</string>
-	<key>CSResourcesFileMapped</key>
-	<true/>
-</dict>
-</plist>
diff --git a/xcode/SampleCode/SampleCode.xcodeproj/project.pbxproj b/xcode/SampleCode/SampleCode.xcodeproj/project.pbxproj
deleted file mode 100644
index 685aea4..0000000
--- a/xcode/SampleCode/SampleCode.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1067 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		0008AEE10DABF08F00477EFB /* libgiflib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0008AEDE0DABF01400477EFB /* libgiflib.a */; };
-		00152A800EE71EB60068F9B2 /* SkDumpCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00152A7F0EE71EB60068F9B2 /* SkDumpCanvas.cpp */; };
-		0017F2CF0D6F3933008D9B31 /* libgraphics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C440D3E999300651393 /* libgraphics.a */; };
-		0017F2D00D6F393F008D9B31 /* libcorecg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C2C0D3E999300651393 /* libcorecg.a */; };
-		0017F2D60D6F3949008D9B31 /* libviews.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C5E0D3E999300651393 /* libviews.a */; };
-		006860100D8A1C8B00CD71AA /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0068600F0D8A1C8A00CD71AA /* OpenGL.framework */; };
-		006860290D8A1DFB00CD71AA /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 006860280D8A1DFB00CD71AA /* AGL.framework */; };
-		0081D7800EE45EF100AB0A0A /* SampleRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F60EDCAF2000F77EA2 /* SampleRegion.cpp */; };
-		0082BE7C0EE414DE00DEE451 /* SkSetPoly3To3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0082BE790EE414DE00DEE451 /* SkSetPoly3To3.cpp */; };
-		009A74250DA11C5D00876C03 /* libGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 009A740E0DA11B1F00876C03 /* libGL.a */; };
-		00B7E3030EDCAF2000F77EA2 /* SampleAll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2D70EDCAF2000F77EA2 /* SampleAll.cpp */; };
-		00B7E3040EDCAF2000F77EA2 /* SampleApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2D80EDCAF2000F77EA2 /* SampleApp.cpp */; };
-		00B7E3050EDCAF2000F77EA2 /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2D90EDCAF2000F77EA2 /* SampleArc.cpp */; };
-		00B7E3060EDCAF2000F77EA2 /* SampleBitmapRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2DA0EDCAF2000F77EA2 /* SampleBitmapRect.cpp */; };
-		00B7E3070EDCAF2000F77EA2 /* SampleCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2DB0EDCAF2000F77EA2 /* SampleCamera.cpp */; };
-		00B7E3080EDCAF2000F77EA2 /* SampleCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2DC0EDCAF2000F77EA2 /* SampleCircle.cpp */; };
-		00B7E3090EDCAF2000F77EA2 /* SampleCull.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2DE0EDCAF2000F77EA2 /* SampleCull.cpp */; };
-		00B7E30A0EDCAF2000F77EA2 /* SampleDither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2DF0EDCAF2000F77EA2 /* SampleDither.cpp */; };
-		00B7E30B0EDCAF2000F77EA2 /* SampleDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E00EDCAF2000F77EA2 /* SampleDrawLooper.cpp */; };
-		00B7E30C0EDCAF2000F77EA2 /* SampleEmboss.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E10EDCAF2000F77EA2 /* SampleEmboss.cpp */; };
-		00B7E30D0EDCAF2000F77EA2 /* SampleEncode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E20EDCAF2000F77EA2 /* SampleEncode.cpp */; };
-		00B7E30F0EDCAF2000F77EA2 /* SampleFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E40EDCAF2000F77EA2 /* SampleFilter.cpp */; };
-		00B7E3100EDCAF2000F77EA2 /* SampleFilter2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E50EDCAF2000F77EA2 /* SampleFilter2.cpp */; };
-		00B7E3110EDCAF2000F77EA2 /* SampleFontCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E60EDCAF2000F77EA2 /* SampleFontCache.cpp */; };
-		00B7E3130EDCAF2000F77EA2 /* SampleImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E80EDCAF2000F77EA2 /* SampleImage.cpp */; };
-		00B7E3140EDCAF2000F77EA2 /* SampleImageDir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2E90EDCAF2000F77EA2 /* SampleImageDir.cpp */; };
-		00B7E3150EDCAF2000F77EA2 /* SampleLayers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2EA0EDCAF2000F77EA2 /* SampleLayers.cpp */; };
-		00B7E3160EDCAF2000F77EA2 /* SampleLines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2EB0EDCAF2000F77EA2 /* SampleLines.cpp */; };
-		00B7E3170EDCAF2000F77EA2 /* SampleMeasure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2EC0EDCAF2000F77EA2 /* SampleMeasure.cpp */; };
-		00B7E3180EDCAF2000F77EA2 /* SampleNinePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2ED0EDCAF2000F77EA2 /* SampleNinePatch.cpp */; };
-		00B7E3190EDCAF2000F77EA2 /* SampleOverflow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2EE0EDCAF2000F77EA2 /* SampleOverflow.cpp */; };
-		00B7E31A0EDCAF2000F77EA2 /* SamplePageFlip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2EF0EDCAF2000F77EA2 /* SamplePageFlip.cpp */; };
-		00B7E31B0EDCAF2000F77EA2 /* SamplePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F00EDCAF2000F77EA2 /* SamplePatch.cpp */; };
-		00B7E31C0EDCAF2000F77EA2 /* SamplePath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F10EDCAF2000F77EA2 /* SamplePath.cpp */; };
-		00B7E31D0EDCAF2000F77EA2 /* SamplePathEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F20EDCAF2000F77EA2 /* SamplePathEffects.cpp */; };
-		00B7E31E0EDCAF2000F77EA2 /* SamplePicture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F30EDCAF2000F77EA2 /* SamplePicture.cpp */; };
-		00B7E31F0EDCAF2000F77EA2 /* SamplePoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F40EDCAF2000F77EA2 /* SamplePoints.cpp */; };
-		00B7E3200EDCAF2000F77EA2 /* SamplePolyToPoly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F50EDCAF2000F77EA2 /* SamplePolyToPoly.cpp */; };
-		00B7E3220EDCAF2000F77EA2 /* SampleShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F70EDCAF2000F77EA2 /* SampleShaders.cpp */; };
-		00B7E3230EDCAF2000F77EA2 /* SampleStrokeText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F80EDCAF2000F77EA2 /* SampleStrokeText.cpp */; };
-		00B7E3240EDCAF2000F77EA2 /* SampleTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2F90EDCAF2000F77EA2 /* SampleTests.cpp */; };
-		00B7E3250EDCAF2000F77EA2 /* SampleText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FA0EDCAF2000F77EA2 /* SampleText.cpp */; };
-		00B7E3260EDCAF2000F77EA2 /* SampleTextAlpha.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FB0EDCAF2000F77EA2 /* SampleTextAlpha.cpp */; };
-		00B7E3270EDCAF2000F77EA2 /* SampleTextEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FC0EDCAF2000F77EA2 /* SampleTextEffects.cpp */; };
-		00B7E3280EDCAF2000F77EA2 /* SampleTextOnPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FD0EDCAF2000F77EA2 /* SampleTextOnPath.cpp */; };
-		00B7E3290EDCAF2000F77EA2 /* SampleTiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FE0EDCAF2000F77EA2 /* SampleTiling.cpp */; };
-		00B7E32A0EDCAF2000F77EA2 /* SampleTypeface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2FF0EDCAF2000F77EA2 /* SampleTypeface.cpp */; };
-		00B7E32B0EDCAF2000F77EA2 /* SampleVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3000EDCAF2000F77EA2 /* SampleVertices.cpp */; };
-		00B7E32C0EDCAF2000F77EA2 /* SampleXfermodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3010EDCAF2000F77EA2 /* SampleXfermodes.cpp */; };
-		00B7E32D0EDCAF2000F77EA2 /* vertexdump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3020EDCAF2000F77EA2 /* vertexdump.cpp */; };
-		00B7E3560EDCB03600F77EA2 /* test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3520EDCB03600F77EA2 /* test.cpp */; };
-		00B7E3570EDCB03600F77EA2 /* test_drawcolor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3540EDCB03600F77EA2 /* test_drawcolor.cpp */; };
-		00B7E3580EDCB03600F77EA2 /* test_drawrect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3550EDCB03600F77EA2 /* test_drawrect.cpp */; };
-		00D12E4D0DAD3D0A003918C5 /* libanimator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0013C7920D94043200B41703 /* libanimator.a */; };
-		00ED8CD70D3E9FD900651393 /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C320D3E999300651393 /* libexpat.a */; };
-		00ED8CD80D3E9FDB00651393 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C380D3E999300651393 /* libfreetype.a */; };
-		00ED8CDB0D3E9FE300651393 /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C480D3E999300651393 /* libjpeg.a */; };
-		00ED8CDC0D3E9FE500651393 /* liblibpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C4C0D3E999300651393 /* liblibpng.a */; };
-		00ED8CDD0D3E9FE700651393 /* libports-mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C520D3E999300651393 /* libports-mac.a */; };
-		00ED8CDE0D3E9FEA00651393 /* libports.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C580D3E999300651393 /* libports.a */; };
-		00ED8CE00D3E9FEF00651393 /* libzlib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00ED8C620D3E999300651393 /* libzlib.a */; };
-		8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
-		8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; };
-		8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		0008AEDD0DABF01400477EFB /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 0008AED90DABF01300477EFB /* giflib.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = giflib;
-		};
-		0008AF0F0DABF9BD00477EFB /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 0008AED90DABF01300477EFB /* giflib.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = giflib;
-		};
-		0013C7910D94043200B41703 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 0013C78A0D94043200B41703 /* animator.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = animator;
-		};
-		0013C7940D94044800B41703 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 0013C78A0D94043200B41703 /* animator.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = animator;
-		};
-		009A740D0DA11B1F00876C03 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 009A74060DA11B1F00876C03 /* GL.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = GL;
-		};
-		009A741C0DA11BAE00876C03 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 009A74060DA11B1F00876C03 /* GL.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = GL;
-		};
-		00ED8C2B0D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C060D3E999300651393 /* corecg.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = corecg;
-		};
-		00ED8C310D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C090D3E999300651393 /* expat.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = expat;
-		};
-		00ED8C370D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C0C0D3E999300651393 /* freetype2.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = freetype;
-		};
-		00ED8C430D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C120D3E999300651393 /* graphics.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC06F0554671400DB518D;
-			remoteInfo = graphics;
-		};
-		00ED8C470D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C150D3E999300651393 /* jpeg.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = jpeg;
-		};
-		00ED8C4B0D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C180D3E999300651393 /* libpng.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = libpng;
-		};
-		00ED8C510D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C1B0D3E999300651393 /* ports-mac.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = "ports-mac";
-		};
-		00ED8C570D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C1E0D3E999300651393 /* ports.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = ports;
-		};
-		00ED8C5D0D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C210D3E999300651393 /* views.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = views;
-		};
-		00ED8C610D3E999300651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C240D3E999300651393 /* zlib.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = zlib;
-		};
-		00ED8C9D0D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C1B0D3E999300651393 /* ports-mac.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = "ports-mac";
-		};
-		00ED8C9F0D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C1E0D3E999300651393 /* ports.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = ports;
-		};
-		00ED8CA10D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C150D3E999300651393 /* jpeg.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = jpeg;
-		};
-		00ED8CA30D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C120D3E999300651393 /* graphics.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC06E0554671400DB518D;
-			remoteInfo = graphics;
-		};
-		00ED8CA70D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C090D3E999300651393 /* expat.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = expat;
-		};
-		00ED8CA90D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C210D3E999300651393 /* views.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = views;
-		};
-		00ED8CAB0D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C060D3E999300651393 /* corecg.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = corecg;
-		};
-		00ED8CAD0D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C240D3E999300651393 /* zlib.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = zlib;
-		};
-		00ED8CAF0D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C0C0D3E999300651393 /* freetype2.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = freetype;
-		};
-		00ED8CB10D3E9AFA00651393 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00ED8C180D3E999300651393 /* libpng.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = libpng;
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
-		0008AED90DABF01300477EFB /* giflib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = giflib.xcodeproj; path = ../giflib.xcodeproj; sourceTree = SOURCE_ROOT; };
-		0013C78A0D94043200B41703 /* animator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = animator.xcodeproj; path = ../animator.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00152A7F0EE71EB60068F9B2 /* SkDumpCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDumpCanvas.cpp; path = ../../libsgl/effects/SkDumpCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00152A810EE71EEC0068F9B2 /* SkDumpCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDumpCanvas.h; path = ../../include/graphics/SkDumpCanvas.h; sourceTree = SOURCE_ROOT; };
-		0068600F0D8A1C8A00CD71AA /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = SDKs/MacOSX10.5.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = SYSTEM_DEVELOPER_DIR; };
-		006860280D8A1DFB00CD71AA /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = SDKs/MacOSX10.5.sdk/System/Library/Frameworks/AGL.framework; sourceTree = SYSTEM_DEVELOPER_DIR; };
-		0082BE790EE414DE00DEE451 /* SkSetPoly3To3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSetPoly3To3.cpp; path = ../../test/SkSetPoly3To3.cpp; sourceTree = SOURCE_ROOT; };
-		0082BE7A0EE414DE00DEE451 /* SkSetPoly3To3_A.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSetPoly3To3_A.cpp; path = ../../test/SkSetPoly3To3_A.cpp; sourceTree = SOURCE_ROOT; };
-		0082BE7B0EE414DE00DEE451 /* SkSetPoly3To3_D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSetPoly3To3_D.cpp; path = ../../test/SkSetPoly3To3_D.cpp; sourceTree = SOURCE_ROOT; };
-		009A74060DA11B1F00876C03 /* GL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GL.xcodeproj; path = ../GL.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00B7E2D70EDCAF2000F77EA2 /* SampleAll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleAll.cpp; path = ../../Samples/SampleAll.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2D80EDCAF2000F77EA2 /* SampleApp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleApp.cpp; path = ../../Samples/SampleApp.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2D90EDCAF2000F77EA2 /* SampleArc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleArc.cpp; path = ../../Samples/SampleArc.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2DA0EDCAF2000F77EA2 /* SampleBitmapRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleBitmapRect.cpp; path = ../../Samples/SampleBitmapRect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2DB0EDCAF2000F77EA2 /* SampleCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleCamera.cpp; path = ../../Samples/SampleCamera.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2DC0EDCAF2000F77EA2 /* SampleCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleCircle.cpp; path = ../../Samples/SampleCircle.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2DD0EDCAF2000F77EA2 /* SampleCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SampleCode.h; path = ../../Samples/SampleCode.h; sourceTree = SOURCE_ROOT; };
-		00B7E2DE0EDCAF2000F77EA2 /* SampleCull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleCull.cpp; path = ../../Samples/SampleCull.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2DF0EDCAF2000F77EA2 /* SampleDither.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleDither.cpp; path = ../../Samples/SampleDither.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E00EDCAF2000F77EA2 /* SampleDrawLooper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleDrawLooper.cpp; path = ../../Samples/SampleDrawLooper.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E10EDCAF2000F77EA2 /* SampleEmboss.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleEmboss.cpp; path = ../../Samples/SampleEmboss.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E20EDCAF2000F77EA2 /* SampleEncode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleEncode.cpp; path = ../../Samples/SampleEncode.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E30EDCAF2000F77EA2 /* SampleFillType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFillType.cpp; path = ../../Samples/SampleFillType.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E40EDCAF2000F77EA2 /* SampleFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFilter.cpp; path = ../../Samples/SampleFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E50EDCAF2000F77EA2 /* SampleFilter2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFilter2.cpp; path = ../../Samples/SampleFilter2.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E60EDCAF2000F77EA2 /* SampleFontCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFontCache.cpp; path = ../../Samples/SampleFontCache.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E70EDCAF2000F77EA2 /* SampleGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleGL.cpp; path = ../../Samples/SampleGL.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E80EDCAF2000F77EA2 /* SampleImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleImage.cpp; path = ../../Samples/SampleImage.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2E90EDCAF2000F77EA2 /* SampleImageDir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleImageDir.cpp; path = ../../Samples/SampleImageDir.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2EA0EDCAF2000F77EA2 /* SampleLayers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleLayers.cpp; path = ../../Samples/SampleLayers.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2EB0EDCAF2000F77EA2 /* SampleLines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleLines.cpp; path = ../../Samples/SampleLines.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2EC0EDCAF2000F77EA2 /* SampleMeasure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleMeasure.cpp; path = ../../Samples/SampleMeasure.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2ED0EDCAF2000F77EA2 /* SampleNinePatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleNinePatch.cpp; path = ../../Samples/SampleNinePatch.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2EE0EDCAF2000F77EA2 /* SampleOverflow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleOverflow.cpp; path = ../../Samples/SampleOverflow.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2EF0EDCAF2000F77EA2 /* SamplePageFlip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePageFlip.cpp; path = ../../Samples/SamplePageFlip.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F00EDCAF2000F77EA2 /* SamplePatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePatch.cpp; path = ../../Samples/SamplePatch.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F10EDCAF2000F77EA2 /* SamplePath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePath.cpp; path = ../../Samples/SamplePath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F20EDCAF2000F77EA2 /* SamplePathEffects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePathEffects.cpp; path = ../../Samples/SamplePathEffects.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F30EDCAF2000F77EA2 /* SamplePicture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePicture.cpp; path = ../../Samples/SamplePicture.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F40EDCAF2000F77EA2 /* SamplePoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePoints.cpp; path = ../../Samples/SamplePoints.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F50EDCAF2000F77EA2 /* SamplePolyToPoly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplePolyToPoly.cpp; path = ../../Samples/SamplePolyToPoly.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F60EDCAF2000F77EA2 /* SampleRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleRegion.cpp; path = ../../Samples/SampleRegion.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F70EDCAF2000F77EA2 /* SampleShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleShaders.cpp; path = ../../Samples/SampleShaders.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F80EDCAF2000F77EA2 /* SampleStrokeText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleStrokeText.cpp; path = ../../Samples/SampleStrokeText.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2F90EDCAF2000F77EA2 /* SampleTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTests.cpp; path = ../../Samples/SampleTests.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FA0EDCAF2000F77EA2 /* SampleText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleText.cpp; path = ../../Samples/SampleText.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FB0EDCAF2000F77EA2 /* SampleTextAlpha.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTextAlpha.cpp; path = ../../Samples/SampleTextAlpha.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FC0EDCAF2000F77EA2 /* SampleTextEffects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTextEffects.cpp; path = ../../Samples/SampleTextEffects.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FD0EDCAF2000F77EA2 /* SampleTextOnPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTextOnPath.cpp; path = ../../Samples/SampleTextOnPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FE0EDCAF2000F77EA2 /* SampleTiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTiling.cpp; path = ../../Samples/SampleTiling.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E2FF0EDCAF2000F77EA2 /* SampleTypeface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTypeface.cpp; path = ../../Samples/SampleTypeface.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3000EDCAF2000F77EA2 /* SampleVertices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleVertices.cpp; path = ../../Samples/SampleVertices.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3010EDCAF2000F77EA2 /* SampleXfermodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleXfermodes.cpp; path = ../../Samples/SampleXfermodes.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3020EDCAF2000F77EA2 /* vertexdump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vertexdump.cpp; path = ../../Samples/vertexdump.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3430EDCAFA600F77EA2 /* SkGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGeometry.h; path = ../../libsgl/sgl/SkGeometry.h; sourceTree = SOURCE_ROOT; };
-		00B7E3520EDCB03600F77EA2 /* test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test.cpp; path = ../../test/test.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3530EDCB03600F77EA2 /* test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = test.h; path = ../../test/test.h; sourceTree = SOURCE_ROOT; };
-		00B7E3540EDCB03600F77EA2 /* test_drawcolor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_drawcolor.cpp; path = ../../test/test_drawcolor.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3550EDCB03600F77EA2 /* test_drawrect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_drawrect.cpp; path = ../../test/test_drawrect.cpp; sourceTree = SOURCE_ROOT; };
-		00ED8C060D3E999300651393 /* corecg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = corecg.xcodeproj; path = ../corecg.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C090D3E999300651393 /* expat.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = expat.xcodeproj; path = ../expat.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C0C0D3E999300651393 /* freetype2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = freetype2.xcodeproj; path = ../freetype2.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C120D3E999300651393 /* graphics.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = graphics.xcodeproj; path = ../graphics.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C150D3E999300651393 /* jpeg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jpeg.xcodeproj; path = ../jpeg.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C180D3E999300651393 /* libpng.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libpng.xcodeproj; path = ../libpng.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C1B0D3E999300651393 /* ports-mac.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "ports-mac.xcodeproj"; path = "../ports-mac.xcodeproj"; sourceTree = SOURCE_ROOT; };
-		00ED8C1E0D3E999300651393 /* ports.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ports.xcodeproj; path = ../ports.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C210D3E999300651393 /* views.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = views.xcodeproj; path = ../views.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00ED8C240D3E999300651393 /* zlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = zlib.xcodeproj; path = ../zlib.xcodeproj; sourceTree = SOURCE_ROOT; };
-		0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
-		1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = "<group>"; };
-		20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
-		8D0C4E960486CD37000505A6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		8D0C4E970486CD37000505A6 /* SampleCode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleCode.app; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		8D0C4E910486CD37000505A6 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00ED8CD70D3E9FD900651393 /* libexpat.a in Frameworks */,
-				00ED8CD80D3E9FDB00651393 /* libfreetype.a in Frameworks */,
-				00ED8CDB0D3E9FE300651393 /* libjpeg.a in Frameworks */,
-				00ED8CDC0D3E9FE500651393 /* liblibpng.a in Frameworks */,
-				00ED8CDD0D3E9FE700651393 /* libports-mac.a in Frameworks */,
-				00ED8CDE0D3E9FEA00651393 /* libports.a in Frameworks */,
-				00ED8CE00D3E9FEF00651393 /* libzlib.a in Frameworks */,
-				8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
-				0017F2CF0D6F3933008D9B31 /* libgraphics.a in Frameworks */,
-				0017F2D00D6F393F008D9B31 /* libcorecg.a in Frameworks */,
-				0017F2D60D6F3949008D9B31 /* libviews.a in Frameworks */,
-				006860100D8A1C8B00CD71AA /* OpenGL.framework in Frameworks */,
-				006860290D8A1DFB00CD71AA /* AGL.framework in Frameworks */,
-				009A74250DA11C5D00876C03 /* libGL.a in Frameworks */,
-				0008AEE10DABF08F00477EFB /* libgiflib.a in Frameworks */,
-				00D12E4D0DAD3D0A003918C5 /* libanimator.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		0008AEDA0DABF01300477EFB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				0008AEDE0DABF01400477EFB /* libgiflib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		0013C78B0D94043200B41703 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				0013C7920D94043200B41703 /* libanimator.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		009A74070DA11B1F00876C03 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				009A740E0DA11B1F00876C03 /* libGL.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00B7E2D60EDCAF0E00F77EA2 /* Samples */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E3430EDCAFA600F77EA2 /* SkGeometry.h */,
-				00B7E2D70EDCAF2000F77EA2 /* SampleAll.cpp */,
-				00B7E2D80EDCAF2000F77EA2 /* SampleApp.cpp */,
-				00B7E2D90EDCAF2000F77EA2 /* SampleArc.cpp */,
-				00B7E2DA0EDCAF2000F77EA2 /* SampleBitmapRect.cpp */,
-				00B7E2DB0EDCAF2000F77EA2 /* SampleCamera.cpp */,
-				00B7E2DC0EDCAF2000F77EA2 /* SampleCircle.cpp */,
-				00B7E2DD0EDCAF2000F77EA2 /* SampleCode.h */,
-				00B7E2DE0EDCAF2000F77EA2 /* SampleCull.cpp */,
-				00B7E2DF0EDCAF2000F77EA2 /* SampleDither.cpp */,
-				00B7E2E00EDCAF2000F77EA2 /* SampleDrawLooper.cpp */,
-				00B7E2E10EDCAF2000F77EA2 /* SampleEmboss.cpp */,
-				00B7E2E20EDCAF2000F77EA2 /* SampleEncode.cpp */,
-				00B7E2E30EDCAF2000F77EA2 /* SampleFillType.cpp */,
-				00B7E2E40EDCAF2000F77EA2 /* SampleFilter.cpp */,
-				00B7E2E50EDCAF2000F77EA2 /* SampleFilter2.cpp */,
-				00B7E2E60EDCAF2000F77EA2 /* SampleFontCache.cpp */,
-				00B7E2E70EDCAF2000F77EA2 /* SampleGL.cpp */,
-				00B7E2E80EDCAF2000F77EA2 /* SampleImage.cpp */,
-				00B7E2E90EDCAF2000F77EA2 /* SampleImageDir.cpp */,
-				00B7E2EA0EDCAF2000F77EA2 /* SampleLayers.cpp */,
-				00B7E2EB0EDCAF2000F77EA2 /* SampleLines.cpp */,
-				00B7E2EC0EDCAF2000F77EA2 /* SampleMeasure.cpp */,
-				00B7E2ED0EDCAF2000F77EA2 /* SampleNinePatch.cpp */,
-				00B7E2EE0EDCAF2000F77EA2 /* SampleOverflow.cpp */,
-				00B7E2EF0EDCAF2000F77EA2 /* SamplePageFlip.cpp */,
-				00B7E2F00EDCAF2000F77EA2 /* SamplePatch.cpp */,
-				00B7E2F10EDCAF2000F77EA2 /* SamplePath.cpp */,
-				00B7E2F20EDCAF2000F77EA2 /* SamplePathEffects.cpp */,
-				00B7E2F30EDCAF2000F77EA2 /* SamplePicture.cpp */,
-				00B7E2F40EDCAF2000F77EA2 /* SamplePoints.cpp */,
-				00B7E2F50EDCAF2000F77EA2 /* SamplePolyToPoly.cpp */,
-				00B7E2F60EDCAF2000F77EA2 /* SampleRegion.cpp */,
-				00B7E2F70EDCAF2000F77EA2 /* SampleShaders.cpp */,
-				00B7E2F80EDCAF2000F77EA2 /* SampleStrokeText.cpp */,
-				00B7E2F90EDCAF2000F77EA2 /* SampleTests.cpp */,
-				00B7E2FA0EDCAF2000F77EA2 /* SampleText.cpp */,
-				00B7E2FB0EDCAF2000F77EA2 /* SampleTextAlpha.cpp */,
-				00B7E2FC0EDCAF2000F77EA2 /* SampleTextEffects.cpp */,
-				00B7E2FD0EDCAF2000F77EA2 /* SampleTextOnPath.cpp */,
-				00B7E2FE0EDCAF2000F77EA2 /* SampleTiling.cpp */,
-				00B7E2FF0EDCAF2000F77EA2 /* SampleTypeface.cpp */,
-				00B7E3000EDCAF2000F77EA2 /* SampleVertices.cpp */,
-				00B7E3010EDCAF2000F77EA2 /* SampleXfermodes.cpp */,
-				00B7E3020EDCAF2000F77EA2 /* vertexdump.cpp */,
-			);
-			name = Samples;
-			sourceTree = "<group>";
-		};
-		00B7E3510EDCB02800F77EA2 /* tests */ = {
-			isa = PBXGroup;
-			children = (
-				00152A810EE71EEC0068F9B2 /* SkDumpCanvas.h */,
-				00152A7F0EE71EB60068F9B2 /* SkDumpCanvas.cpp */,
-				0082BE790EE414DE00DEE451 /* SkSetPoly3To3.cpp */,
-				0082BE7A0EE414DE00DEE451 /* SkSetPoly3To3_A.cpp */,
-				0082BE7B0EE414DE00DEE451 /* SkSetPoly3To3_D.cpp */,
-				00B7E3520EDCB03600F77EA2 /* test.cpp */,
-				00B7E3530EDCB03600F77EA2 /* test.h */,
-				00B7E3540EDCB03600F77EA2 /* test_drawcolor.cpp */,
-				00B7E3550EDCB03600F77EA2 /* test_drawrect.cpp */,
-			);
-			name = tests;
-			sourceTree = "<group>";
-		};
-		00ED8C070D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C2C0D3E999300651393 /* libcorecg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C0A0D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C320D3E999300651393 /* libexpat.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C0D0D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C380D3E999300651393 /* libfreetype.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C130D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C440D3E999300651393 /* libgraphics.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C160D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C480D3E999300651393 /* libjpeg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C190D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C4C0D3E999300651393 /* liblibpng.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C1C0D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C520D3E999300651393 /* libports-mac.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C1F0D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C580D3E999300651393 /* libports.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C220D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C5E0D3E999300651393 /* libviews.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00ED8C250D3E999300651393 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00ED8C620D3E999300651393 /* libzlib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		195DF8CFFE9D517E11CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				8D0C4E970486CD37000505A6 /* SampleCode.app */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		20286C29FDCF999611CA2CEA /* SampleCode */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E3510EDCB02800F77EA2 /* tests */,
-				00B7E2D60EDCAF0E00F77EA2 /* Samples */,
-				0008AED90DABF01300477EFB /* giflib.xcodeproj */,
-				009A74060DA11B1F00876C03 /* GL.xcodeproj */,
-				0013C78A0D94043200B41703 /* animator.xcodeproj */,
-				00ED8C060D3E999300651393 /* corecg.xcodeproj */,
-				00ED8C090D3E999300651393 /* expat.xcodeproj */,
-				00ED8C0C0D3E999300651393 /* freetype2.xcodeproj */,
-				00ED8C120D3E999300651393 /* graphics.xcodeproj */,
-				00ED8C150D3E999300651393 /* jpeg.xcodeproj */,
-				00ED8C180D3E999300651393 /* libpng.xcodeproj */,
-				00ED8C1B0D3E999300651393 /* ports-mac.xcodeproj */,
-				00ED8C1E0D3E999300651393 /* ports.xcodeproj */,
-				00ED8C210D3E999300651393 /* views.xcodeproj */,
-				00ED8C240D3E999300651393 /* zlib.xcodeproj */,
-				20286C2CFDCF999611CA2CEA /* Resources */,
-				20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */,
-				195DF8CFFE9D517E11CA2CBB /* Products */,
-			);
-			name = SampleCode;
-			sourceTree = "<group>";
-		};
-		20286C2CFDCF999611CA2CEA /* Resources */ = {
-			isa = PBXGroup;
-			children = (
-				8D0C4E960486CD37000505A6 /* Info.plist */,
-				0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */,
-				02345980000FD03B11CA0E72 /* main.nib */,
-			);
-			name = Resources;
-			sourceTree = "<group>";
-		};
-		20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = {
-			isa = PBXGroup;
-			children = (
-				006860280D8A1DFB00CD71AA /* AGL.framework */,
-				0068600F0D8A1C8A00CD71AA /* OpenGL.framework */,
-				20286C33FDCF999611CA2CEA /* Carbon.framework */,
-			);
-			name = "External Frameworks and Libraries";
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		8D0C4E890486CD37000505A6 /* SampleCode */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "SampleCode" */;
-			buildPhases = (
-				8D0C4E8C0486CD37000505A6 /* Resources */,
-				8D0C4E8F0486CD37000505A6 /* Sources */,
-				8D0C4E910486CD37000505A6 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				00ED8C9E0D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CA00D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CA20D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CA40D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CA80D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CAA0D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CAC0D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CAE0D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CB00D3E9AFA00651393 /* PBXTargetDependency */,
-				00ED8CB20D3E9AFA00651393 /* PBXTargetDependency */,
-				0013C7950D94044800B41703 /* PBXTargetDependency */,
-				009A741D0DA11BAE00876C03 /* PBXTargetDependency */,
-				0008AF100DABF9BD00477EFB /* PBXTargetDependency */,
-			);
-			name = SampleCode;
-			productInstallPath = "$(HOME)/Applications";
-			productName = SampleCode;
-			productReference = 8D0C4E970486CD37000505A6 /* SampleCode.app */;
-			productType = "com.apple.product-type.application";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		20286C28FDCF999611CA2CEA /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "SampleCode" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 20286C29FDCF999611CA2CEA /* SampleCode */;
-			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 0013C78B0D94043200B41703 /* Products */;
-					ProjectRef = 0013C78A0D94043200B41703 /* animator.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C070D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C060D3E999300651393 /* corecg.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C0A0D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C090D3E999300651393 /* expat.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C0D0D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C0C0D3E999300651393 /* freetype2.xcodeproj */;
-				},
-				{
-					ProductGroup = 0008AEDA0DABF01300477EFB /* Products */;
-					ProjectRef = 0008AED90DABF01300477EFB /* giflib.xcodeproj */;
-				},
-				{
-					ProductGroup = 009A74070DA11B1F00876C03 /* Products */;
-					ProjectRef = 009A74060DA11B1F00876C03 /* GL.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C130D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C120D3E999300651393 /* graphics.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C160D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C150D3E999300651393 /* jpeg.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C190D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C180D3E999300651393 /* libpng.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C1C0D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C1B0D3E999300651393 /* ports-mac.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C1F0D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C1E0D3E999300651393 /* ports.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C220D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C210D3E999300651393 /* views.xcodeproj */;
-				},
-				{
-					ProductGroup = 00ED8C250D3E999300651393 /* Products */;
-					ProjectRef = 00ED8C240D3E999300651393 /* zlib.xcodeproj */;
-				},
-			);
-			projectRoot = "";
-			targets = (
-				8D0C4E890486CD37000505A6 /* SampleCode */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXReferenceProxy section */
-		0008AEDE0DABF01400477EFB /* libgiflib.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libgiflib.a;
-			remoteRef = 0008AEDD0DABF01400477EFB /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		0013C7920D94043200B41703 /* libanimator.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libanimator.a;
-			remoteRef = 0013C7910D94043200B41703 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		009A740E0DA11B1F00876C03 /* libGL.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libGL.a;
-			remoteRef = 009A740D0DA11B1F00876C03 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C2C0D3E999300651393 /* libcorecg.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libcorecg.a;
-			remoteRef = 00ED8C2B0D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C320D3E999300651393 /* libexpat.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libexpat.a;
-			remoteRef = 00ED8C310D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C380D3E999300651393 /* libfreetype.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libfreetype.a;
-			remoteRef = 00ED8C370D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C440D3E999300651393 /* libgraphics.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libgraphics.a;
-			remoteRef = 00ED8C430D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C480D3E999300651393 /* libjpeg.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libjpeg.a;
-			remoteRef = 00ED8C470D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C4C0D3E999300651393 /* liblibpng.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = liblibpng.a;
-			remoteRef = 00ED8C4B0D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C520D3E999300651393 /* libports-mac.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = "libports-mac.a";
-			remoteRef = 00ED8C510D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C580D3E999300651393 /* libports.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libports.a;
-			remoteRef = 00ED8C570D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C5E0D3E999300651393 /* libviews.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libviews.a;
-			remoteRef = 00ED8C5D0D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00ED8C620D3E999300651393 /* libzlib.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libzlib.a;
-			remoteRef = 00ED8C610D3E999300651393 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
-/* Begin PBXResourcesBuildPhase section */
-		8D0C4E8C0486CD37000505A6 /* Resources */ = {
-			isa = PBXResourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */,
-				8D0C4E8E0486CD37000505A6 /* main.nib in Resources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
-		8D0C4E8F0486CD37000505A6 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E3030EDCAF2000F77EA2 /* SampleAll.cpp in Sources */,
-				00B7E3040EDCAF2000F77EA2 /* SampleApp.cpp in Sources */,
-				00B7E3060EDCAF2000F77EA2 /* SampleBitmapRect.cpp in Sources */,
-				00B7E3070EDCAF2000F77EA2 /* SampleCamera.cpp in Sources */,
-				00B7E3090EDCAF2000F77EA2 /* SampleCull.cpp in Sources */,
-				00B7E30B0EDCAF2000F77EA2 /* SampleDrawLooper.cpp in Sources */,
-				00B7E30C0EDCAF2000F77EA2 /* SampleEmboss.cpp in Sources */,
-				00B7E30D0EDCAF2000F77EA2 /* SampleEncode.cpp in Sources */,
-				00B7E30F0EDCAF2000F77EA2 /* SampleFilter.cpp in Sources */,
-				00B7E3100EDCAF2000F77EA2 /* SampleFilter2.cpp in Sources */,
-				00B7E3110EDCAF2000F77EA2 /* SampleFontCache.cpp in Sources */,
-				00B7E3130EDCAF2000F77EA2 /* SampleImage.cpp in Sources */,
-				00B7E3140EDCAF2000F77EA2 /* SampleImageDir.cpp in Sources */,
-				00B7E3150EDCAF2000F77EA2 /* SampleLayers.cpp in Sources */,
-				00B7E3160EDCAF2000F77EA2 /* SampleLines.cpp in Sources */,
-				00B7E3170EDCAF2000F77EA2 /* SampleMeasure.cpp in Sources */,
-				00B7E3180EDCAF2000F77EA2 /* SampleNinePatch.cpp in Sources */,
-				00B7E3190EDCAF2000F77EA2 /* SampleOverflow.cpp in Sources */,
-				00B7E31A0EDCAF2000F77EA2 /* SamplePageFlip.cpp in Sources */,
-				00B7E31B0EDCAF2000F77EA2 /* SamplePatch.cpp in Sources */,
-				00B7E31C0EDCAF2000F77EA2 /* SamplePath.cpp in Sources */,
-				00B7E31D0EDCAF2000F77EA2 /* SamplePathEffects.cpp in Sources */,
-				00B7E31E0EDCAF2000F77EA2 /* SamplePicture.cpp in Sources */,
-				00B7E31F0EDCAF2000F77EA2 /* SamplePoints.cpp in Sources */,
-				00B7E3200EDCAF2000F77EA2 /* SamplePolyToPoly.cpp in Sources */,
-				00B7E3220EDCAF2000F77EA2 /* SampleShaders.cpp in Sources */,
-				00B7E3230EDCAF2000F77EA2 /* SampleStrokeText.cpp in Sources */,
-				00B7E3240EDCAF2000F77EA2 /* SampleTests.cpp in Sources */,
-				00B7E3250EDCAF2000F77EA2 /* SampleText.cpp in Sources */,
-				00B7E3260EDCAF2000F77EA2 /* SampleTextAlpha.cpp in Sources */,
-				00B7E3270EDCAF2000F77EA2 /* SampleTextEffects.cpp in Sources */,
-				00B7E3280EDCAF2000F77EA2 /* SampleTextOnPath.cpp in Sources */,
-				00B7E3290EDCAF2000F77EA2 /* SampleTiling.cpp in Sources */,
-				00B7E32A0EDCAF2000F77EA2 /* SampleTypeface.cpp in Sources */,
-				00B7E32B0EDCAF2000F77EA2 /* SampleVertices.cpp in Sources */,
-				00B7E32C0EDCAF2000F77EA2 /* SampleXfermodes.cpp in Sources */,
-				00B7E32D0EDCAF2000F77EA2 /* vertexdump.cpp in Sources */,
-				00B7E3560EDCB03600F77EA2 /* test.cpp in Sources */,
-				00B7E3570EDCB03600F77EA2 /* test_drawcolor.cpp in Sources */,
-				00B7E3580EDCB03600F77EA2 /* test_drawrect.cpp in Sources */,
-				0082BE7C0EE414DE00DEE451 /* SkSetPoly3To3.cpp in Sources */,
-				0081D7800EE45EF100AB0A0A /* SampleRegion.cpp in Sources */,
-				00152A800EE71EB60068F9B2 /* SkDumpCanvas.cpp in Sources */,
-				00B7E3080EDCAF2000F77EA2 /* SampleCircle.cpp in Sources */,
-				00B7E3050EDCAF2000F77EA2 /* SampleArc.cpp in Sources */,
-				00B7E30A0EDCAF2000F77EA2 /* SampleDither.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		0008AF100DABF9BD00477EFB /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = giflib;
-			targetProxy = 0008AF0F0DABF9BD00477EFB /* PBXContainerItemProxy */;
-		};
-		0013C7950D94044800B41703 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = animator;
-			targetProxy = 0013C7940D94044800B41703 /* PBXContainerItemProxy */;
-		};
-		009A741D0DA11BAE00876C03 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = GL;
-			targetProxy = 009A741C0DA11BAE00876C03 /* PBXContainerItemProxy */;
-		};
-		00ED8C9E0D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = "ports-mac";
-			targetProxy = 00ED8C9D0D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CA00D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = ports;
-			targetProxy = 00ED8C9F0D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CA20D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = jpeg;
-			targetProxy = 00ED8CA10D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CA40D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = graphics;
-			targetProxy = 00ED8CA30D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CA80D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = expat;
-			targetProxy = 00ED8CA70D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CAA0D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = views;
-			targetProxy = 00ED8CA90D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CAC0D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = corecg;
-			targetProxy = 00ED8CAB0D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CAE0D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = zlib;
-			targetProxy = 00ED8CAD0D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CB00D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = freetype;
-			targetProxy = 00ED8CAF0D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-		00ED8CB20D3E9AFA00651393 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = libpng;
-			targetProxy = 00ED8CB10D3E9AFA00651393 /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin PBXVariantGroup section */
-		02345980000FD03B11CA0E72 /* main.nib */ = {
-			isa = PBXVariantGroup;
-			children = (
-				1870340FFE93FCAF11CA0CD7 /* English */,
-			);
-			name = main.nib;
-			sourceTree = "<group>";
-		};
-		0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */ = {
-			isa = PBXVariantGroup;
-			children = (
-				0867D6ABFE840B52C02AAC07 /* English */,
-			);
-			name = InfoPlist.strings;
-			sourceTree = "<group>";
-		};
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
-		006B85250EED8C4400938119 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_DEBUGGING_SYMBOLS = full;
-				GCC_ENABLE_ASM_KEYWORD = NO;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_OPTIMIZATION_LEVEL = 2;
-				GCC_PREFIX_HEADER = " ";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_RELEASE,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				USER_HEADER_SEARCH_PATHS = "../../include/**";
-			};
-			name = Release;
-		};
-		006B85260EED8C4400938119 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				FRAMEWORK_SEARCH_PATHS = (
-					"$(inherited)",
-					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
-				);
-				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(DEVELOPER_DIR)/SDKs/MacOSX10.5.sdk/System/Library/Frameworks\"";
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PRECOMPILE_PREFIX_HEADER = NO;
-				GCC_PREFIX_HEADER = SampleCode_Prefix.pch;
-				INFOPLIST_FILE = Info.plist;
-				INSTALL_PATH = "$(HOME)/Applications";
-				PRODUCT_NAME = SampleCode;
-				WRAPPER_EXTENSION = app;
-				ZERO_LINK = YES;
-			};
-			name = Release;
-		};
-		C0E91AC608A95435008D54AB /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				FRAMEWORK_SEARCH_PATHS = (
-					"$(inherited)",
-					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
-				);
-				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(DEVELOPER_DIR)/SDKs/MacOSX10.5.sdk/System/Library/Frameworks\"";
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PRECOMPILE_PREFIX_HEADER = NO;
-				GCC_PREFIX_HEADER = SampleCode_Prefix.pch;
-				INFOPLIST_FILE = Info.plist;
-				INSTALL_PATH = "$(HOME)/Applications";
-				PRODUCT_NAME = SampleCode;
-				WRAPPER_EXTENSION = app;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		C0E91ACA08A95435008D54AB /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_DEBUGGING_SYMBOLS = full;
-				GCC_ENABLE_ASM_KEYWORD = NO;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREFIX_HEADER = " ";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_DEBUG,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				USER_HEADER_SEARCH_PATHS = "../../include/**";
-			};
-			name = Debug;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "SampleCode" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				C0E91AC608A95435008D54AB /* Debug */,
-				006B85260EED8C4400938119 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-		C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "SampleCode" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				C0E91ACA08A95435008D54AB /* Debug */,
-				006B85250EED8C4400938119 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 20286C28FDCF999611CA2CEA /* Project object */;
-}
diff --git a/xcode/SampleCode/SampleCode_Prefix.pch b/xcode/SampleCode/SampleCode_Prefix.pch
deleted file mode 100644
index e69de29..0000000
--- a/xcode/SampleCode/SampleCode_Prefix.pch
+++ /dev/null
diff --git a/xcode/Simple/English.lproj/InfoPlist.strings b/xcode/Simple/English.lproj/InfoPlist.strings
deleted file mode 100644
index 26bf880..0000000
--- a/xcode/Simple/English.lproj/InfoPlist.strings
+++ /dev/null
Binary files differ
diff --git a/xcode/Simple/English.lproj/main.nib/classes.nib b/xcode/Simple/English.lproj/main.nib/classes.nib
deleted file mode 100644
index c4b887e..0000000
--- a/xcode/Simple/English.lproj/main.nib/classes.nib
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>IBVersion</key>
-	<string>1</string>
-</dict>
-</plist>
diff --git a/xcode/Simple/English.lproj/main.nib/info.nib b/xcode/Simple/English.lproj/main.nib/info.nib
deleted file mode 100644
index 2af896b..0000000
--- a/xcode/Simple/English.lproj/main.nib/info.nib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>IBFramework Version</key>
-	<string>629</string>
-	<key>IBLastKnownRelativeProjectPath</key>
-	<string>../../SampleCode.xcodeproj</string>
-	<key>IBOldestOS</key>
-	<integer>5</integer>
-	<key>IBOpenObjects</key>
-	<array/>
-	<key>IBSystem Version</key>
-	<string>9B18</string>
-	<key>targetFramework</key>
-	<string>IBCarbonFramework</string>
-</dict>
-</plist>
diff --git a/xcode/Simple/English.lproj/main.nib/objects.xib b/xcode/Simple/English.lproj/main.nib/objects.xib
deleted file mode 100644
index a9e438e..0000000
--- a/xcode/Simple/English.lproj/main.nib/objects.xib
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<object class="NSIBObjectData">
-  <object name="rootObject" class="NSCustomObject" id="1">
-  </object>
-  <array count="38" name="allObjects">
-    <object class="IBCarbonMenuItem" id="193">
-      <string name="title">Arrange in Front</string>
-      <boolean name="dynamic">TRUE</boolean>
-      <int name="keyEquivalentModifier">1572864</int>
-      <ostype name="command">frnt</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="148">
-      <string name="title">Select All</string>
-      <string name="keyEquivalent">a</string>
-      <ostype name="command">sall</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="152">
-      <string name="title">Edit</string>
-      <object name="submenu" class="IBCarbonMenu" id="147">
-        <string name="title">Edit</string>
-        <array count="10" name="items">
-          <object class="IBCarbonMenuItem" id="141">
-            <string name="title">Undo</string>
-            <string name="keyEquivalent">z</string>
-            <ostype name="command">undo</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="146">
-            <string name="title">Redo</string>
-            <string name="keyEquivalent">Z</string>
-            <ostype name="command">redo</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="142">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="143">
-            <string name="title">Cut</string>
-            <string name="keyEquivalent">x</string>
-            <ostype name="command">cut </ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="149">
-            <string name="title">Copy</string>
-            <string name="keyEquivalent">c</string>
-            <ostype name="command">copy</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="144">
-            <string name="title">Paste</string>
-            <string name="keyEquivalent">v</string>
-            <ostype name="command">past</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="151">
-            <string name="title">Delete</string>
-            <ostype name="command">clea</ostype>
-          </object>
-          <reference idRef="148"/>
-          <object class="IBCarbonMenuItem" id="199">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="198">
-            <string name="title">Special Characters…</string>
-            <ostype name="command">chrp</ostype>
-          </object>
-        </array>
-      </object>
-    </object>
-    <object class="IBCarbonRootControl" id="167">
-      <string name="bounds">0 0 360 480 </string>
-    </object>
-    <object class="IBCarbonMenuItem" id="139">
-      <string name="title">New</string>
-      <string name="keyEquivalent">n</string>
-      <ostype name="command">new </ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="192">
-      <string name="title">Window</string>
-      <object name="submenu" class="IBCarbonMenu" id="195">
-        <string name="title">Window</string>
-        <string name="name">_NSWindowsMenu</string>
-        <array count="6" name="items">
-          <object class="IBCarbonMenuItem" id="190">
-            <string name="title">Minimize</string>
-            <string name="keyEquivalent">m</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <ostype name="command">mini</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="191">
-            <string name="title">Minimize All</string>
-            <string name="keyEquivalent">m</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <int name="keyEquivalentModifier">1572864</int>
-            <ostype name="command">mina</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="197">
-            <string name="title">Zoom</string>
-            <ostype name="command">zoom</ostype>
-          </object>
-          <object class="IBCarbonMenuItem" id="194">
-            <boolean name="separator">TRUE</boolean>
-          </object>
-          <object class="IBCarbonMenuItem" id="196">
-            <string name="title">Bring All to Front</string>
-            <boolean name="dynamic">TRUE</boolean>
-            <ostype name="command">bfrt</ostype>
-          </object>
-          <reference idRef="193"/>
-        </array>
-      </object>
-    </object>
-    <object class="IBCarbonMenuItem" id="132">
-      <string name="title">Revert</string>
-      <string name="keyEquivalent">r</string>
-      <ostype name="command">rvrt</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="187">
-      <string name="title">About Foo</string>
-      <int name="keyEquivalentModifier">0</int>
-      <ostype name="command">abou</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="138">
-      <string name="title">Save</string>
-      <string name="keyEquivalent">s</string>
-      <ostype name="command">save</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="137">
-      <string name="title">Save As…</string>
-      <string name="keyEquivalent">S</string>
-      <ostype name="command">svas</ostype>
-    </object>
-    <object class="IBCarbonMenuItem" id="136">
-      <string name="title">Print…</string>
-      <string name="keyEquivalent">p</string>
-      <ostype name="command">prnt</ostype>
-    </object>
-    <reference idRef="146"/>
-    <reference idRef="142"/>
-    <reference idRef="143"/>
-    <object class="IBCarbonWindow" id="166">
-      <boolean name="liveResize">TRUE</boolean>
-      <int name="scalingMode">1048576</int>
-      <string name="title">Window</string>
-      <reference name="rootControl" idRef="167"/>
-      <string name="windowRect">1001 727 1361 1207 </string>
-      <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
-    </object>
-    <reference idRef="199"/>
-    <object class="IBCarbonMenuItem" id="135">
-      <string name="title">Page Setup…</string>
-      <string name="keyEquivalent">P</string>
-      <ostype name="command">page</ostype>
-    </object>
-    <reference idRef="144"/>
-    <object class="IBCarbonMenuItem" id="134">
-      <string name="title">Open…</string>
-      <string name="keyEquivalent">o</string>
-      <ostype name="command">open</ostype>
-    </object>
-    <object class="IBCarbonMenu" id="131">
-      <string name="title">File</string>
-      <array count="10" name="items">
-        <reference idRef="139"/>
-        <reference idRef="134"/>
-        <object class="IBCarbonMenuItem" id="133">
-          <boolean name="separator">TRUE</boolean>
-        </object>
-        <object class="IBCarbonMenuItem" id="130">
-          <string name="title">Close</string>
-          <string name="keyEquivalent">w</string>
-          <ostype name="command">clos</ostype>
-        </object>
-        <reference idRef="138"/>
-        <reference idRef="137"/>
-        <reference idRef="132"/>
-        <object class="IBCarbonMenuItem" id="128">
-          <boolean name="separator">TRUE</boolean>
-        </object>
-        <reference idRef="135"/>
-        <reference idRef="136"/>
-      </array>
-    </object>
-    <reference idRef="128"/>
-    <reference idRef="141"/>
-    <reference idRef="198"/>
-    <object class="IBCarbonMenu" id="29">
-      <string name="title">main</string>
-      <string name="name">_NSMainMenu</string>
-      <array count="4" name="items">
-        <object class="IBCarbonMenuItem" id="185">
-          <string name="title">Foo</string>
-          <object name="submenu" class="IBCarbonMenu" id="184">
-            <string name="title">Foo</string>
-            <string name="name">_NSAppleMenu</string>
-            <array count="1" name="items">
-              <reference idRef="187"/>
-            </array>
-          </object>
-        </object>
-        <object class="IBCarbonMenuItem" id="127">
-          <string name="title">File</string>
-          <reference name="submenu" idRef="131"/>
-        </object>
-        <reference idRef="152"/>
-        <reference idRef="192"/>
-      </array>
-    </object>
-    <reference idRef="184"/>
-    <reference idRef="194"/>
-    <reference idRef="195"/>
-    <reference idRef="127"/>
-    <reference idRef="147"/>
-    <reference idRef="133"/>
-    <reference idRef="149"/>
-    <reference idRef="151"/>
-    <reference idRef="190"/>
-    <reference idRef="185"/>
-    <reference idRef="197"/>
-    <reference idRef="130"/>
-    <reference idRef="191"/>
-    <reference idRef="196"/>
-  </array>
-  <array count="38" name="allParents">
-    <reference idRef="195"/>
-    <reference idRef="147"/>
-    <reference idRef="29"/>
-    <reference idRef="166"/>
-    <reference idRef="131"/>
-    <reference idRef="29"/>
-    <reference idRef="131"/>
-    <reference idRef="184"/>
-    <reference idRef="131"/>
-    <reference idRef="131"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="1"/>
-    <reference idRef="147"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="131"/>
-    <reference idRef="127"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="1"/>
-    <reference idRef="185"/>
-    <reference idRef="195"/>
-    <reference idRef="192"/>
-    <reference idRef="29"/>
-    <reference idRef="152"/>
-    <reference idRef="131"/>
-    <reference idRef="147"/>
-    <reference idRef="147"/>
-    <reference idRef="195"/>
-    <reference idRef="29"/>
-    <reference idRef="195"/>
-    <reference idRef="131"/>
-    <reference idRef="195"/>
-    <reference idRef="195"/>
-  </array>
-  <dictionary count="3" name="nameTable">
-    <string>File&apos;s Owner</string>
-    <reference idRef="1"/>
-    <string>MainWindow</string>
-    <reference idRef="166"/>
-    <string>MenuBar</string>
-    <reference idRef="29"/>
-  </dictionary>
-  <string name="targetFramework">IBCarbonFramework</string>
-  <unsigned_int name="nextObjectID">200</unsigned_int>
-</object>
diff --git a/xcode/Simple/Info.plist b/xcode/Simple/Info.plist
deleted file mode 100644
index d70d738..0000000
--- a/xcode/Simple/Info.plist
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>$(EXECUTABLE_NAME)</string>
-	<key>CFBundleIconFile</key>
-	<string></string>
-	<key>CFBundleIdentifier</key>
-	<string>com.yourcompany.Simple</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>$(PRODUCT_NAME)</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1.0</string>
-	<key>CSResourcesFileMapped</key>
-	<true/>
-</dict>
-</plist>
diff --git a/xcode/Simple/Simple.xcodeproj/project.pbxproj b/xcode/Simple/Simple.xcodeproj/project.pbxproj
deleted file mode 100644
index d24c9e9..0000000
--- a/xcode/Simple/Simple.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,335 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		0099A4CA0EF176A5004F1DA4 /* SimpleApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0099A4C90EF176A5004F1DA4 /* SimpleApp.cpp */; };
-		00AFCD5B0EF1667600BD2FF1 /* libskia2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00AFCD4D0EF165CE00BD2FF1 /* libskia2.a */; };
-		00AFCD750EF1679700BD2FF1 /* skia_mac.cp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD730EF1679700BD2FF1 /* skia_mac.cp */; };
-		8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
-		8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; };
-		8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		00AFCD4C0EF165CE00BD2FF1 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00AFCD300EF165CE00BD2FF1 /* skia2.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = skia2;
-		};
-		00AFCD510EF165E500BD2FF1 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00AFCD300EF165CE00BD2FF1 /* skia2.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = skia2;
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
-		0099A4C90EF176A5004F1DA4 /* SimpleApp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleApp.cpp; sourceTree = "<group>"; };
-		00AFCD300EF165CE00BD2FF1 /* skia2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = skia2.xcodeproj; path = ../skia2.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00AFCD730EF1679700BD2FF1 /* skia_mac.cp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = skia_mac.cp; path = ../ports/skia_mac.cp; sourceTree = SOURCE_ROOT; };
-		0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
-		1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = "<group>"; };
-		20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
-		5048396D09E3307300765E4B /* SimpleProj.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; path = SimpleProj.xcconfig; sourceTree = "<group>"; };
-		5048396E09E3307300765E4B /* SimpleTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; path = SimpleTarget.xcconfig; sourceTree = "<group>"; };
-		508344B209E5C41E0093A071 /* Simple.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Simple.app; sourceTree = BUILT_PRODUCTS_DIR; };
-		8D0C4E960486CD37000505A6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		8D0C4E910486CD37000505A6 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
-				00AFCD5B0EF1667600BD2FF1 /* libskia2.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		00AFCD310EF165CE00BD2FF1 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00AFCD4D0EF165CE00BD2FF1 /* libskia2.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		195DF8CFFE9D517E11CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				508344B209E5C41E0093A071 /* Simple.app */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		20286C29FDCF999611CA2CEA /* Simple */ = {
-			isa = PBXGroup;
-			children = (
-				5048396909E3304600765E4B /* Configuration Files */,
-				20286C2AFDCF999611CA2CEA /* Sources */,
-				20286C2CFDCF999611CA2CEA /* Resources */,
-				20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */,
-				195DF8CFFE9D517E11CA2CBB /* Products */,
-				00AFCD300EF165CE00BD2FF1 /* skia2.xcodeproj */,
-			);
-			name = Simple;
-			sourceTree = "<group>";
-		};
-		20286C2AFDCF999611CA2CEA /* Sources */ = {
-			isa = PBXGroup;
-			children = (
-				0099A4C90EF176A5004F1DA4 /* SimpleApp.cpp */,
-				00AFCD730EF1679700BD2FF1 /* skia_mac.cp */,
-			);
-			name = Sources;
-			sourceTree = "<group>";
-		};
-		20286C2CFDCF999611CA2CEA /* Resources */ = {
-			isa = PBXGroup;
-			children = (
-				8D0C4E960486CD37000505A6 /* Info.plist */,
-				0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */,
-				02345980000FD03B11CA0E72 /* main.nib */,
-			);
-			name = Resources;
-			sourceTree = "<group>";
-		};
-		20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = {
-			isa = PBXGroup;
-			children = (
-				20286C33FDCF999611CA2CEA /* Carbon.framework */,
-			);
-			name = "External Frameworks and Libraries";
-			sourceTree = "<group>";
-		};
-		5048396909E3304600765E4B /* Configuration Files */ = {
-			isa = PBXGroup;
-			children = (
-				5048396D09E3307300765E4B /* SimpleProj.xcconfig */,
-				5048396E09E3307300765E4B /* SimpleTarget.xcconfig */,
-			);
-			name = "Configuration Files";
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		8D0C4E890486CD37000505A6 /* Simple */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "Simple" */;
-			buildPhases = (
-				8D0C4E8C0486CD37000505A6 /* Resources */,
-				8D0C4E8F0486CD37000505A6 /* Sources */,
-				8D0C4E910486CD37000505A6 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				00AFCD520EF165E500BD2FF1 /* PBXTargetDependency */,
-			);
-			name = Simple;
-			productInstallPath = "$(HOME)/Applications";
-			productName = Simple;
-			productReference = 508344B209E5C41E0093A071 /* Simple.app */;
-			productType = "com.apple.product-type.application";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		20286C28FDCF999611CA2CEA /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "Simple" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 20286C29FDCF999611CA2CEA /* Simple */;
-			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 00AFCD310EF165CE00BD2FF1 /* Products */;
-					ProjectRef = 00AFCD300EF165CE00BD2FF1 /* skia2.xcodeproj */;
-				},
-			);
-			projectRoot = "";
-			targets = (
-				8D0C4E890486CD37000505A6 /* Simple */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXReferenceProxy section */
-		00AFCD4D0EF165CE00BD2FF1 /* libskia2.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libskia2.a;
-			remoteRef = 00AFCD4C0EF165CE00BD2FF1 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
-/* Begin PBXResourcesBuildPhase section */
-		8D0C4E8C0486CD37000505A6 /* Resources */ = {
-			isa = PBXResourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */,
-				8D0C4E8E0486CD37000505A6 /* main.nib in Resources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
-		8D0C4E8F0486CD37000505A6 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00AFCD750EF1679700BD2FF1 /* skia_mac.cp in Sources */,
-				0099A4CA0EF176A5004F1DA4 /* SimpleApp.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		00AFCD520EF165E500BD2FF1 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = skia2;
-			targetProxy = 00AFCD510EF165E500BD2FF1 /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin PBXVariantGroup section */
-		02345980000FD03B11CA0E72 /* main.nib */ = {
-			isa = PBXVariantGroup;
-			children = (
-				1870340FFE93FCAF11CA0CD7 /* English */,
-			);
-			name = main.nib;
-			sourceTree = "<group>";
-		};
-		0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */ = {
-			isa = PBXVariantGroup;
-			children = (
-				0867D6ABFE840B52C02AAC07 /* English */,
-			);
-			name = InfoPlist.strings;
-			sourceTree = "<group>";
-		};
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
-		C0E91AC608A95435008D54AB /* Debug */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5048396E09E3307300765E4B /* SimpleTarget.xcconfig */;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_PREFIX_HEADER = Simple_Prefix.pch;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"_GLIBCXX_DEBUG=1",
-					"_GLIBCXX_DEBUG_PEDANTIC=1",
-				);
-			};
-			name = Debug;
-		};
-		C0E91AC708A95435008D54AB /* Release */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5048396E09E3307300765E4B /* SimpleTarget.xcconfig */;
-			buildSettings = {
-				DEAD_CODE_STRIPPING = YES;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_PREFIX_HEADER = Simple_Prefix.pch;
-				INSTALL_PATH = "$(HOME)/Applications";
-				PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
-			};
-			name = Release;
-		};
-		C0E91ACA08A95435008D54AB /* Debug */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5048396D09E3307300765E4B /* SimpleProj.xcconfig */;
-			buildSettings = {
-				ARCHS = (
-					i386,
-					ppc,
-				);
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_INCREASE_PRECOMPILED_HEADER_SHARING = NO;
-				GCC_MODEL_TUNING = "";
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_DEBUG,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				USER_HEADER_SEARCH_PATHS = "../../include/**";
-				VALID_ARCHS = "i386 x86_64";
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		C0E91ACB08A95435008D54AB /* Release */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5048396D09E3307300765E4B /* SimpleProj.xcconfig */;
-			buildSettings = {
-				ARCHS = (
-					i386,
-					ppc,
-				);
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_INCREASE_PRECOMPILED_HEADER_SHARING = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_RELEASE,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				SEPARATE_STRIP = YES;
-				USER_HEADER_SEARCH_PATHS = "../../include/**";
-				VALID_ARCHS = "i386 x86_64";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		C0E91AC508A95435008D54AB /* Build configuration list for PBXNativeTarget "Simple" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				C0E91AC608A95435008D54AB /* Debug */,
-				C0E91AC708A95435008D54AB /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		C0E91AC908A95435008D54AB /* Build configuration list for PBXProject "Simple" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				C0E91ACA08A95435008D54AB /* Debug */,
-				C0E91ACB08A95435008D54AB /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 20286C28FDCF999611CA2CEA /* Project object */;
-}
diff --git a/xcode/Simple/SimpleApp.cpp b/xcode/Simple/SimpleApp.cpp
deleted file mode 100644
index 7e7e282..0000000
--- a/xcode/Simple/SimpleApp.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "SkCanvas.h"
-#include "SkDevice.h"
-#include "SkGraphics.h"
-#include "SkPaint.h"
-#include "SkPicture.h"
-#include "SkStream.h"
-#include "SkWindow.h"
-
-//////////////////////////////////////////////////////////////////////////////
-
-class SimpleWindow : public SkOSWindow {
-public:
-	SimpleWindow(void* hwnd);
-
-protected:
-    virtual void onDraw(SkCanvas* canvas);
-	virtual bool onHandleKey(SkKey key);
-    virtual bool onHandleChar(SkUnichar);
-    virtual void onSizeChange();
-    
-    virtual SkCanvas* beforeChildren(SkCanvas*);
-    virtual void afterChildren(SkCanvas*);
-
-	virtual bool onEvent(const SkEvent& evt);
-
-private:
-    typedef SkOSWindow INHERITED;
-};
-
-SimpleWindow::SimpleWindow(void* hwnd) : INHERITED(hwnd) {
-//	this->setConfig(SkBitmap::kRGB_565_Config);
-	this->setConfig(SkBitmap::kARGB_8888_Config);
-	this->setVisibleP(true);
-    this->setTitle("Simple");
-}
-
-void SimpleWindow::onDraw(SkCanvas* canvas) {
-    canvas->drawColor(SK_ColorWHITE);
-    
-    const SkScalar w = this->width();
-    const SkScalar h = this->height();
-
-    SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setTextSize(SkIntToScalar(40));
-    paint.setTextAlign(SkPaint::kCenter_Align);
-
-    canvas->drawText("Hello world", 11, w/2, h/2, paint);
-}
-
-SkCanvas* SimpleWindow::beforeChildren(SkCanvas* canvas) {
-    // can wack the canvas here, which will affect child views
-    // and can be "undone" in afterChildren()
-    //
-    // e.g. return a picture-canvas, or wack the clip or matrix, etc.
-
-    return canvas;
-}
-
-void SimpleWindow::afterChildren(SkCanvas* orig) {
-}
-
-bool SimpleWindow::onEvent(const SkEvent& evt) {
-    return this->INHERITED::onEvent(evt);
-}
-
-bool SimpleWindow::onHandleChar(SkUnichar uni) {
-    return this->INHERITED::onHandleChar(uni);
-}
-
-bool SimpleWindow::onHandleKey(SkKey key) {
-    return this->INHERITED::onHandleKey(key);
-}
-
-void SimpleWindow::onSizeChange() {
-    this->INHERITED::onSizeChange();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkOSWindow* create_sk_window(void* hwnd) {
-	return new SimpleWindow(hwnd);
-}
-
-void get_preferred_size(int* x, int* y, int* width, int* height) {
-    *x = 10;
-    *y = 50;
-    *width = 640;
-    *height = 480;
-}
-
-void application_init() {
-//    setenv("ANDROID_ROOT", "../../../data", 0);
-    setenv("ANDROID_ROOT", "/android/device/data", 0);
-	SkGraphics::Init(true);
-	SkEvent::Init();
-}
-
-void application_term() {
-	SkEvent::Term();
-	SkGraphics::Term();
-}
diff --git a/xcode/Simple/SimpleProj.xcconfig b/xcode/Simple/SimpleProj.xcconfig
deleted file mode 100644
index 73543b8..0000000
--- a/xcode/Simple/SimpleProj.xcconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-	GCC_ENABLE_CPP_EXCEPTIONS = YES;
-	GCC_ENABLE_CPP_RTTI = YES;
-	GCC_WARN_ABOUT_RETURN_TYPE = YES;
-	GCC_WARN_UNUSED_VARIABLE = YES;
-	GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
-	GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-	PREBINDING = NO;
-	INFOPLIST_EXPAND_BUILD_SETTINGS = YES;
\ No newline at end of file
diff --git a/xcode/Simple/SimpleTarget.xcconfig b/xcode/Simple/SimpleTarget.xcconfig
deleted file mode 100644
index 1d47d33..0000000
--- a/xcode/Simple/SimpleTarget.xcconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-	GCC_PRECOMPILE_PREFIX_HEADER = YES;
-	GCC_PREFIX_HEADER = Simple_Prefix.pch;
-	INFOPLIST_FILE = Info.plist;
-	INSTALL_PATH = $(HOME)/Applications;
-	PRODUCT_NAME = 	Simple;
-	STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = Dynamic;
-	GCC_SYMBOLS_PRIVATE_EXTERN = YES;
diff --git a/xcode/Simple/Simple_Prefix.pch b/xcode/Simple/Simple_Prefix.pch
deleted file mode 100644
index ffcb61e..0000000
--- a/xcode/Simple/Simple_Prefix.pch
+++ /dev/null
@@ -1,4 +0,0 @@
-//
-// Prefix header for all source files of the 'Simple' target in the 'Simple' project.
-//
-
diff --git a/xcode/animator.xcodeproj/project.pbxproj b/xcode/animator.xcodeproj/project.pbxproj
deleted file mode 100644
index ea401fd..0000000
--- a/xcode/animator.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,833 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DDB80EDCA15800F77EA2 /* SkAnimate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD170EDCA15800F77EA2 /* SkAnimate.h */; };
-		00B7DDB90EDCA15800F77EA2 /* SkAnimateActive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD1A0EDCA15800F77EA2 /* SkAnimateActive.cpp */; };
-		00B7DDBA0EDCA15800F77EA2 /* SkAnimateActive.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD1B0EDCA15800F77EA2 /* SkAnimateActive.h */; };
-		00B7DDBB0EDCA15800F77EA2 /* SkAnimateBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD1C0EDCA15800F77EA2 /* SkAnimateBase.cpp */; };
-		00B7DDBC0EDCA15800F77EA2 /* SkAnimateBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD1D0EDCA15800F77EA2 /* SkAnimateBase.h */; };
-		00B7DDBD0EDCA15800F77EA2 /* SkAnimateField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD1E0EDCA15800F77EA2 /* SkAnimateField.cpp */; };
-		00B7DDBE0EDCA15800F77EA2 /* SkAnimateMaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD1F0EDCA15800F77EA2 /* SkAnimateMaker.cpp */; };
-		00B7DDBF0EDCA15800F77EA2 /* SkAnimateMaker.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD200EDCA15800F77EA2 /* SkAnimateMaker.h */; };
-		00B7DDC00EDCA15800F77EA2 /* SkAnimateProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD210EDCA15800F77EA2 /* SkAnimateProperties.h */; };
-		00B7DDC10EDCA15800F77EA2 /* SkAnimateSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD240EDCA15800F77EA2 /* SkAnimateSet.cpp */; };
-		00B7DDC20EDCA15800F77EA2 /* SkAnimateSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD250EDCA15800F77EA2 /* SkAnimateSet.h */; };
-		00B7DDC30EDCA15800F77EA2 /* SkAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD260EDCA15800F77EA2 /* SkAnimator.cpp */; };
-		00B7DDC40EDCA15800F77EA2 /* SkAnimatorScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD270EDCA15800F77EA2 /* SkAnimatorScript.cpp */; };
-		00B7DDC50EDCA15800F77EA2 /* SkAnimatorScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD280EDCA15800F77EA2 /* SkAnimatorScript.h */; };
-		00B7DDC60EDCA15800F77EA2 /* SkAnimatorScript2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD290EDCA15800F77EA2 /* SkAnimatorScript2.cpp */; };
-		00B7DDC70EDCA15800F77EA2 /* SkAnimatorScript2.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD2A0EDCA15800F77EA2 /* SkAnimatorScript2.h */; };
-		00B7DDC80EDCA15800F77EA2 /* SkBase64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD2B0EDCA15800F77EA2 /* SkBase64.cpp */; };
-		00B7DDC90EDCA15800F77EA2 /* SkBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD2C0EDCA15800F77EA2 /* SkBase64.h */; };
-		00B7DDCA0EDCA15800F77EA2 /* SkBoundable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD2D0EDCA15800F77EA2 /* SkBoundable.cpp */; };
-		00B7DDCB0EDCA15800F77EA2 /* SkBoundable.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD2E0EDCA15800F77EA2 /* SkBoundable.h */; };
-		00B7DDCF0EDCA15800F77EA2 /* SkDisplayable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD320EDCA15800F77EA2 /* SkDisplayable.cpp */; };
-		00B7DDD00EDCA15800F77EA2 /* SkDisplayable.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD330EDCA15800F77EA2 /* SkDisplayable.h */; };
-		00B7DDD10EDCA15800F77EA2 /* SkDisplayAdd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD340EDCA15800F77EA2 /* SkDisplayAdd.cpp */; };
-		00B7DDD20EDCA15800F77EA2 /* SkDisplayAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD350EDCA15800F77EA2 /* SkDisplayAdd.h */; };
-		00B7DDD30EDCA15800F77EA2 /* SkDisplayApply.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD360EDCA15800F77EA2 /* SkDisplayApply.cpp */; };
-		00B7DDD40EDCA15800F77EA2 /* SkDisplayApply.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD370EDCA15800F77EA2 /* SkDisplayApply.h */; };
-		00B7DDD50EDCA15800F77EA2 /* SkDisplayBounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD380EDCA15800F77EA2 /* SkDisplayBounds.cpp */; };
-		00B7DDD60EDCA15800F77EA2 /* SkDisplayBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD390EDCA15800F77EA2 /* SkDisplayBounds.h */; };
-		00B7DDD70EDCA15800F77EA2 /* SkDisplayEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD3A0EDCA15800F77EA2 /* SkDisplayEvent.cpp */; };
-		00B7DDD80EDCA15800F77EA2 /* SkDisplayEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD3B0EDCA15800F77EA2 /* SkDisplayEvent.h */; };
-		00B7DDD90EDCA15800F77EA2 /* SkDisplayEvents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD3C0EDCA15800F77EA2 /* SkDisplayEvents.cpp */; };
-		00B7DDDA0EDCA15800F77EA2 /* SkDisplayEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD3D0EDCA15800F77EA2 /* SkDisplayEvents.h */; };
-		00B7DDDB0EDCA15800F77EA2 /* SkDisplayInclude.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD3E0EDCA15800F77EA2 /* SkDisplayInclude.cpp */; };
-		00B7DDDC0EDCA15800F77EA2 /* SkDisplayInclude.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD3F0EDCA15800F77EA2 /* SkDisplayInclude.h */; };
-		00B7DDDD0EDCA15800F77EA2 /* SkDisplayInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD400EDCA15800F77EA2 /* SkDisplayInput.cpp */; };
-		00B7DDDE0EDCA15800F77EA2 /* SkDisplayInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD410EDCA15800F77EA2 /* SkDisplayInput.h */; };
-		00B7DDDF0EDCA15800F77EA2 /* SkDisplayList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD420EDCA15800F77EA2 /* SkDisplayList.cpp */; };
-		00B7DDE00EDCA15800F77EA2 /* SkDisplayList.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD430EDCA15800F77EA2 /* SkDisplayList.h */; };
-		00B7DDE10EDCA15800F77EA2 /* SkDisplayMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD440EDCA15800F77EA2 /* SkDisplayMath.cpp */; };
-		00B7DDE20EDCA15800F77EA2 /* SkDisplayMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD450EDCA15800F77EA2 /* SkDisplayMath.h */; };
-		00B7DDE30EDCA15800F77EA2 /* SkDisplayMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD460EDCA15800F77EA2 /* SkDisplayMovie.cpp */; };
-		00B7DDE40EDCA15800F77EA2 /* SkDisplayMovie.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD470EDCA15800F77EA2 /* SkDisplayMovie.h */; };
-		00B7DDE50EDCA15800F77EA2 /* SkDisplayNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD480EDCA15800F77EA2 /* SkDisplayNumber.cpp */; };
-		00B7DDE60EDCA15800F77EA2 /* SkDisplayNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD490EDCA15800F77EA2 /* SkDisplayNumber.h */; };
-		00B7DDE70EDCA15800F77EA2 /* SkDisplayPost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD4A0EDCA15800F77EA2 /* SkDisplayPost.cpp */; };
-		00B7DDE80EDCA15800F77EA2 /* SkDisplayPost.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD4B0EDCA15800F77EA2 /* SkDisplayPost.h */; };
-		00B7DDE90EDCA15800F77EA2 /* SkDisplayRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD4C0EDCA15800F77EA2 /* SkDisplayRandom.cpp */; };
-		00B7DDEA0EDCA15800F77EA2 /* SkDisplayRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD4D0EDCA15800F77EA2 /* SkDisplayRandom.h */; };
-		00B7DDEB0EDCA15800F77EA2 /* SkDisplayScreenplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD4E0EDCA15800F77EA2 /* SkDisplayScreenplay.cpp */; };
-		00B7DDEC0EDCA15800F77EA2 /* SkDisplayScreenplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD4F0EDCA15800F77EA2 /* SkDisplayScreenplay.h */; };
-		00B7DDED0EDCA15800F77EA2 /* SkDisplayType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD500EDCA15800F77EA2 /* SkDisplayType.cpp */; };
-		00B7DDEE0EDCA15800F77EA2 /* SkDisplayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD510EDCA15800F77EA2 /* SkDisplayType.h */; };
-		00B7DDEF0EDCA15800F77EA2 /* SkDisplayTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD520EDCA15800F77EA2 /* SkDisplayTypes.cpp */; };
-		00B7DDF00EDCA15800F77EA2 /* SkDisplayTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD530EDCA15800F77EA2 /* SkDisplayTypes.h */; };
-		00B7DDF10EDCA15800F77EA2 /* SkDisplayXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD540EDCA15800F77EA2 /* SkDisplayXMLParser.cpp */; };
-		00B7DDF20EDCA15800F77EA2 /* SkDisplayXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD550EDCA15800F77EA2 /* SkDisplayXMLParser.h */; };
-		00B7DDF30EDCA15800F77EA2 /* SkDraw3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD560EDCA15800F77EA2 /* SkDraw3D.cpp */; };
-		00B7DDF40EDCA15800F77EA2 /* SkDraw3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD570EDCA15800F77EA2 /* SkDraw3D.h */; };
-		00B7DDF50EDCA15800F77EA2 /* SkDrawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD580EDCA15800F77EA2 /* SkDrawable.cpp */; };
-		00B7DDF60EDCA15800F77EA2 /* SkDrawable.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD590EDCA15800F77EA2 /* SkDrawable.h */; };
-		00B7DDF70EDCA15800F77EA2 /* SkDrawBitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD5A0EDCA15800F77EA2 /* SkDrawBitmap.cpp */; };
-		00B7DDF80EDCA15800F77EA2 /* SkDrawBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD5B0EDCA15800F77EA2 /* SkDrawBitmap.h */; };
-		00B7DDF90EDCA15800F77EA2 /* SkDrawBlur.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD5C0EDCA15800F77EA2 /* SkDrawBlur.cpp */; };
-		00B7DDFA0EDCA15800F77EA2 /* SkDrawBlur.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD5D0EDCA15800F77EA2 /* SkDrawBlur.h */; };
-		00B7DDFB0EDCA15800F77EA2 /* SkDrawClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD5E0EDCA15800F77EA2 /* SkDrawClip.cpp */; };
-		00B7DDFC0EDCA15800F77EA2 /* SkDrawClip.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD5F0EDCA15800F77EA2 /* SkDrawClip.h */; };
-		00B7DDFD0EDCA15800F77EA2 /* SkDrawColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD600EDCA15800F77EA2 /* SkDrawColor.cpp */; };
-		00B7DDFE0EDCA15800F77EA2 /* SkDrawColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD610EDCA15800F77EA2 /* SkDrawColor.h */; };
-		00B7DDFF0EDCA15800F77EA2 /* SkDrawDash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD620EDCA15800F77EA2 /* SkDrawDash.cpp */; };
-		00B7DE000EDCA15800F77EA2 /* SkDrawDash.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD630EDCA15800F77EA2 /* SkDrawDash.h */; };
-		00B7DE010EDCA15800F77EA2 /* SkDrawDiscrete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD640EDCA15800F77EA2 /* SkDrawDiscrete.cpp */; };
-		00B7DE020EDCA15800F77EA2 /* SkDrawDiscrete.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD650EDCA15800F77EA2 /* SkDrawDiscrete.h */; };
-		00B7DE030EDCA15800F77EA2 /* SkDrawEmboss.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD660EDCA15800F77EA2 /* SkDrawEmboss.cpp */; };
-		00B7DE040EDCA15800F77EA2 /* SkDrawEmboss.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD670EDCA15800F77EA2 /* SkDrawEmboss.h */; };
-		00B7DE050EDCA15800F77EA2 /* SkDrawExtraPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD680EDCA15800F77EA2 /* SkDrawExtraPathEffect.cpp */; };
-		00B7DE060EDCA15800F77EA2 /* SkDrawFull.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD690EDCA15800F77EA2 /* SkDrawFull.cpp */; };
-		00B7DE070EDCA15800F77EA2 /* SkDrawFull.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD6A0EDCA15800F77EA2 /* SkDrawFull.h */; };
-		00B7DE080EDCA15800F77EA2 /* SkDrawGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD6B0EDCA15800F77EA2 /* SkDrawGradient.cpp */; };
-		00B7DE090EDCA15800F77EA2 /* SkDrawGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD6C0EDCA15800F77EA2 /* SkDrawGradient.h */; };
-		00B7DE0A0EDCA15800F77EA2 /* SkDrawGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD6D0EDCA15800F77EA2 /* SkDrawGroup.cpp */; };
-		00B7DE0B0EDCA15800F77EA2 /* SkDrawGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD6E0EDCA15800F77EA2 /* SkDrawGroup.h */; };
-		00B7DE0C0EDCA15800F77EA2 /* SkDrawLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD6F0EDCA15800F77EA2 /* SkDrawLine.cpp */; };
-		00B7DE0D0EDCA15800F77EA2 /* SkDrawLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD700EDCA15800F77EA2 /* SkDrawLine.h */; };
-		00B7DE0E0EDCA15800F77EA2 /* SkDrawMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD710EDCA15800F77EA2 /* SkDrawMatrix.cpp */; };
-		00B7DE0F0EDCA15800F77EA2 /* SkDrawMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD720EDCA15800F77EA2 /* SkDrawMatrix.h */; };
-		00B7DE100EDCA15800F77EA2 /* SkDrawOval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD730EDCA15800F77EA2 /* SkDrawOval.cpp */; };
-		00B7DE110EDCA15800F77EA2 /* SkDrawOval.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD740EDCA15800F77EA2 /* SkDrawOval.h */; };
-		00B7DE120EDCA15800F77EA2 /* SkDrawPaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD750EDCA15800F77EA2 /* SkDrawPaint.cpp */; };
-		00B7DE130EDCA15800F77EA2 /* SkDrawPaint.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD760EDCA15800F77EA2 /* SkDrawPaint.h */; };
-		00B7DE140EDCA15800F77EA2 /* SkDrawPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD770EDCA15800F77EA2 /* SkDrawPath.cpp */; };
-		00B7DE150EDCA15800F77EA2 /* SkDrawPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD780EDCA15800F77EA2 /* SkDrawPath.h */; };
-		00B7DE160EDCA15800F77EA2 /* SkDrawPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD790EDCA15800F77EA2 /* SkDrawPoint.cpp */; };
-		00B7DE170EDCA15800F77EA2 /* SkDrawPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD7A0EDCA15800F77EA2 /* SkDrawPoint.h */; };
-		00B7DE180EDCA15800F77EA2 /* SkDrawRectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD7B0EDCA15800F77EA2 /* SkDrawRectangle.cpp */; };
-		00B7DE190EDCA15800F77EA2 /* SkDrawRectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD7C0EDCA15800F77EA2 /* SkDrawRectangle.h */; };
-		00B7DE1A0EDCA15800F77EA2 /* SkDrawSaveLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD7D0EDCA15800F77EA2 /* SkDrawSaveLayer.cpp */; };
-		00B7DE1B0EDCA15800F77EA2 /* SkDrawSaveLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD7E0EDCA15800F77EA2 /* SkDrawSaveLayer.h */; };
-		00B7DE1C0EDCA15800F77EA2 /* SkDrawShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD7F0EDCA15800F77EA2 /* SkDrawShader.cpp */; };
-		00B7DE1D0EDCA15800F77EA2 /* SkDrawShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD800EDCA15800F77EA2 /* SkDrawShader.h */; };
-		00B7DE1E0EDCA15800F77EA2 /* SkDrawText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD810EDCA15800F77EA2 /* SkDrawText.cpp */; };
-		00B7DE1F0EDCA15800F77EA2 /* SkDrawText.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD820EDCA15800F77EA2 /* SkDrawText.h */; };
-		00B7DE200EDCA15800F77EA2 /* SkDrawTextBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD830EDCA15800F77EA2 /* SkDrawTextBox.cpp */; };
-		00B7DE210EDCA15800F77EA2 /* SkDrawTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD840EDCA15800F77EA2 /* SkDrawTextBox.h */; };
-		00B7DE220EDCA15800F77EA2 /* SkDrawTo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD850EDCA15800F77EA2 /* SkDrawTo.cpp */; };
-		00B7DE230EDCA15800F77EA2 /* SkDrawTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD860EDCA15800F77EA2 /* SkDrawTo.h */; };
-		00B7DE240EDCA15800F77EA2 /* SkDrawTransparentShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD870EDCA15800F77EA2 /* SkDrawTransparentShader.cpp */; };
-		00B7DE250EDCA15800F77EA2 /* SkDrawTransparentShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD880EDCA15800F77EA2 /* SkDrawTransparentShader.h */; };
-		00B7DE260EDCA15800F77EA2 /* SkDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD890EDCA15800F77EA2 /* SkDump.cpp */; };
-		00B7DE270EDCA15800F77EA2 /* SkDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD8A0EDCA15800F77EA2 /* SkDump.h */; };
-		00B7DE280EDCA15800F77EA2 /* SkExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD8C0EDCA15800F77EA2 /* SkExtras.h */; };
-		00B7DE290EDCA15800F77EA2 /* SkGetCondensedInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD8D0EDCA15800F77EA2 /* SkGetCondensedInfo.cpp */; };
-		00B7DE2A0EDCA15800F77EA2 /* SkHitClear.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD8E0EDCA15800F77EA2 /* SkHitClear.cpp */; };
-		00B7DE2B0EDCA15800F77EA2 /* SkHitClear.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD8F0EDCA15800F77EA2 /* SkHitClear.h */; };
-		00B7DE2C0EDCA15800F77EA2 /* SkHitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD900EDCA15800F77EA2 /* SkHitTest.cpp */; };
-		00B7DE2D0EDCA15800F77EA2 /* SkHitTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD910EDCA15800F77EA2 /* SkHitTest.h */; };
-		00B7DE2E0EDCA15800F77EA2 /* SkIntArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD920EDCA15800F77EA2 /* SkIntArray.h */; };
-		00B7DE2F0EDCA15800F77EA2 /* SkMatrixParts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD930EDCA15800F77EA2 /* SkMatrixParts.cpp */; };
-		00B7DE300EDCA15800F77EA2 /* SkMatrixParts.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD940EDCA15800F77EA2 /* SkMatrixParts.h */; };
-		00B7DE310EDCA15800F77EA2 /* SkMemberInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD950EDCA15800F77EA2 /* SkMemberInfo.cpp */; };
-		00B7DE320EDCA15800F77EA2 /* SkMemberInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD960EDCA15800F77EA2 /* SkMemberInfo.h */; };
-		00B7DE330EDCA15800F77EA2 /* SkOpArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD970EDCA15800F77EA2 /* SkOpArray.cpp */; };
-		00B7DE340EDCA15800F77EA2 /* SkOpArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD980EDCA15800F77EA2 /* SkOpArray.h */; };
-		00B7DE350EDCA15800F77EA2 /* SkOperand.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD990EDCA15800F77EA2 /* SkOperand.h */; };
-		00B7DE360EDCA15800F77EA2 /* SkOperand2.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD9A0EDCA15800F77EA2 /* SkOperand2.h */; };
-		00B7DE370EDCA15800F77EA2 /* SkOperandInterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD9B0EDCA15800F77EA2 /* SkOperandInterpolator.h */; };
-		00B7DE380EDCA15800F77EA2 /* SkOperandIterpolator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD9C0EDCA15800F77EA2 /* SkOperandIterpolator.cpp */; };
-		00B7DE390EDCA15800F77EA2 /* SkPaintParts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD9D0EDCA15800F77EA2 /* SkPaintParts.cpp */; };
-		00B7DE3A0EDCA15800F77EA2 /* SkPaintParts.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DD9E0EDCA15800F77EA2 /* SkPaintParts.h */; };
-		00B7DE3B0EDCA15800F77EA2 /* SkPathParts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DD9F0EDCA15800F77EA2 /* SkPathParts.cpp */; };
-		00B7DE3C0EDCA15800F77EA2 /* SkPathParts.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA00EDCA15800F77EA2 /* SkPathParts.h */; };
-		00B7DE3D0EDCA15800F77EA2 /* SkPostParts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDA10EDCA15800F77EA2 /* SkPostParts.cpp */; };
-		00B7DE3E0EDCA15800F77EA2 /* SkPostParts.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA20EDCA15800F77EA2 /* SkPostParts.h */; };
-		00B7DE3F0EDCA15800F77EA2 /* SkScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDA30EDCA15800F77EA2 /* SkScript.cpp */; };
-		00B7DE400EDCA15800F77EA2 /* SkScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA40EDCA15800F77EA2 /* SkScript.h */; };
-		00B7DE410EDCA15800F77EA2 /* SkScript2.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA50EDCA15800F77EA2 /* SkScript2.h */; };
-		00B7DE420EDCA15800F77EA2 /* SkScriptCallBack.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA60EDCA15800F77EA2 /* SkScriptCallBack.h */; };
-		00B7DE430EDCA15800F77EA2 /* SkScriptDecompile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDA70EDCA15800F77EA2 /* SkScriptDecompile.cpp */; };
-		00B7DE440EDCA15800F77EA2 /* SkScriptRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDA80EDCA15800F77EA2 /* SkScriptRuntime.cpp */; };
-		00B7DE450EDCA15800F77EA2 /* SkScriptRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDA90EDCA15800F77EA2 /* SkScriptRuntime.h */; };
-		00B7DE460EDCA15800F77EA2 /* SkScriptTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDAA0EDCA15800F77EA2 /* SkScriptTokenizer.cpp */; };
-		00B7DE470EDCA15800F77EA2 /* SkSnapshot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDAB0EDCA15800F77EA2 /* SkSnapshot.cpp */; };
-		00B7DE480EDCA15800F77EA2 /* SkSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDAC0EDCA15800F77EA2 /* SkSnapshot.h */; };
-		00B7DE490EDCA15800F77EA2 /* SkSVGPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDAD0EDCA15800F77EA2 /* SkSVGPath.cpp */; };
-		00B7DE4A0EDCA15800F77EA2 /* SkTDArray_Experimental.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDAE0EDCA15800F77EA2 /* SkTDArray_Experimental.h */; };
-		00B7DE4B0EDCA15800F77EA2 /* SkTextOnPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDAF0EDCA15800F77EA2 /* SkTextOnPath.cpp */; };
-		00B7DE4C0EDCA15800F77EA2 /* SkTextOnPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDB00EDCA15800F77EA2 /* SkTextOnPath.h */; };
-		00B7DE4D0EDCA15800F77EA2 /* SkTextToPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDB10EDCA15800F77EA2 /* SkTextToPath.cpp */; };
-		00B7DE4E0EDCA15800F77EA2 /* SkTextToPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDB20EDCA15800F77EA2 /* SkTextToPath.h */; };
-		00B7DE4F0EDCA15800F77EA2 /* SkTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDB30EDCA15800F77EA2 /* SkTime.cpp */; };
-		00B7DE500EDCA15800F77EA2 /* SkTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDB40EDCA15800F77EA2 /* SkTypedArray.cpp */; };
-		00B7DE510EDCA15800F77EA2 /* SkTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDB50EDCA15800F77EA2 /* SkTypedArray.h */; };
-		00B7DE520EDCA15800F77EA2 /* SkXMLAnimatorWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DDB60EDCA15800F77EA2 /* SkXMLAnimatorWriter.cpp */; };
-		00B7DE530EDCA15800F77EA2 /* SkXMLAnimatorWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DDB70EDCA15800F77EA2 /* SkXMLAnimatorWriter.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DD170EDCA15800F77EA2 /* SkAnimate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimate.h; path = ../libsgl/animator/SkAnimate.h; sourceTree = SOURCE_ROOT; };
-		00B7DD1A0EDCA15800F77EA2 /* SkAnimateActive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimateActive.cpp; path = ../libsgl/animator/SkAnimateActive.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD1B0EDCA15800F77EA2 /* SkAnimateActive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimateActive.h; path = ../libsgl/animator/SkAnimateActive.h; sourceTree = SOURCE_ROOT; };
-		00B7DD1C0EDCA15800F77EA2 /* SkAnimateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimateBase.cpp; path = ../libsgl/animator/SkAnimateBase.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD1D0EDCA15800F77EA2 /* SkAnimateBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimateBase.h; path = ../libsgl/animator/SkAnimateBase.h; sourceTree = SOURCE_ROOT; };
-		00B7DD1E0EDCA15800F77EA2 /* SkAnimateField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimateField.cpp; path = ../libsgl/animator/SkAnimateField.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD1F0EDCA15800F77EA2 /* SkAnimateMaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimateMaker.cpp; path = ../libsgl/animator/SkAnimateMaker.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD200EDCA15800F77EA2 /* SkAnimateMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimateMaker.h; path = ../libsgl/animator/SkAnimateMaker.h; sourceTree = SOURCE_ROOT; };
-		00B7DD210EDCA15800F77EA2 /* SkAnimateProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimateProperties.h; path = ../libsgl/animator/SkAnimateProperties.h; sourceTree = SOURCE_ROOT; };
-		00B7DD240EDCA15800F77EA2 /* SkAnimateSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimateSet.cpp; path = ../libsgl/animator/SkAnimateSet.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD250EDCA15800F77EA2 /* SkAnimateSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimateSet.h; path = ../libsgl/animator/SkAnimateSet.h; sourceTree = SOURCE_ROOT; };
-		00B7DD260EDCA15800F77EA2 /* SkAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimator.cpp; path = ../libsgl/animator/SkAnimator.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD270EDCA15800F77EA2 /* SkAnimatorScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimatorScript.cpp; path = ../libsgl/animator/SkAnimatorScript.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD280EDCA15800F77EA2 /* SkAnimatorScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimatorScript.h; path = ../libsgl/animator/SkAnimatorScript.h; sourceTree = SOURCE_ROOT; };
-		00B7DD290EDCA15800F77EA2 /* SkAnimatorScript2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAnimatorScript2.cpp; path = ../libsgl/animator/SkAnimatorScript2.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD2A0EDCA15800F77EA2 /* SkAnimatorScript2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAnimatorScript2.h; path = ../libsgl/animator/SkAnimatorScript2.h; sourceTree = SOURCE_ROOT; };
-		00B7DD2B0EDCA15800F77EA2 /* SkBase64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBase64.cpp; path = ../libsgl/animator/SkBase64.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD2C0EDCA15800F77EA2 /* SkBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBase64.h; path = ../libsgl/animator/SkBase64.h; sourceTree = SOURCE_ROOT; };
-		00B7DD2D0EDCA15800F77EA2 /* SkBoundable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBoundable.cpp; path = ../libsgl/animator/SkBoundable.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD2E0EDCA15800F77EA2 /* SkBoundable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBoundable.h; path = ../libsgl/animator/SkBoundable.h; sourceTree = SOURCE_ROOT; };
-		00B7DD320EDCA15800F77EA2 /* SkDisplayable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayable.cpp; path = ../libsgl/animator/SkDisplayable.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD330EDCA15800F77EA2 /* SkDisplayable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayable.h; path = ../libsgl/animator/SkDisplayable.h; sourceTree = SOURCE_ROOT; };
-		00B7DD340EDCA15800F77EA2 /* SkDisplayAdd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayAdd.cpp; path = ../libsgl/animator/SkDisplayAdd.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD350EDCA15800F77EA2 /* SkDisplayAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayAdd.h; path = ../libsgl/animator/SkDisplayAdd.h; sourceTree = SOURCE_ROOT; };
-		00B7DD360EDCA15800F77EA2 /* SkDisplayApply.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayApply.cpp; path = ../libsgl/animator/SkDisplayApply.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD370EDCA15800F77EA2 /* SkDisplayApply.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayApply.h; path = ../libsgl/animator/SkDisplayApply.h; sourceTree = SOURCE_ROOT; };
-		00B7DD380EDCA15800F77EA2 /* SkDisplayBounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayBounds.cpp; path = ../libsgl/animator/SkDisplayBounds.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD390EDCA15800F77EA2 /* SkDisplayBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayBounds.h; path = ../libsgl/animator/SkDisplayBounds.h; sourceTree = SOURCE_ROOT; };
-		00B7DD3A0EDCA15800F77EA2 /* SkDisplayEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayEvent.cpp; path = ../libsgl/animator/SkDisplayEvent.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD3B0EDCA15800F77EA2 /* SkDisplayEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayEvent.h; path = ../libsgl/animator/SkDisplayEvent.h; sourceTree = SOURCE_ROOT; };
-		00B7DD3C0EDCA15800F77EA2 /* SkDisplayEvents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayEvents.cpp; path = ../libsgl/animator/SkDisplayEvents.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD3D0EDCA15800F77EA2 /* SkDisplayEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayEvents.h; path = ../libsgl/animator/SkDisplayEvents.h; sourceTree = SOURCE_ROOT; };
-		00B7DD3E0EDCA15800F77EA2 /* SkDisplayInclude.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayInclude.cpp; path = ../libsgl/animator/SkDisplayInclude.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD3F0EDCA15800F77EA2 /* SkDisplayInclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayInclude.h; path = ../libsgl/animator/SkDisplayInclude.h; sourceTree = SOURCE_ROOT; };
-		00B7DD400EDCA15800F77EA2 /* SkDisplayInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayInput.cpp; path = ../libsgl/animator/SkDisplayInput.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD410EDCA15800F77EA2 /* SkDisplayInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayInput.h; path = ../libsgl/animator/SkDisplayInput.h; sourceTree = SOURCE_ROOT; };
-		00B7DD420EDCA15800F77EA2 /* SkDisplayList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayList.cpp; path = ../libsgl/animator/SkDisplayList.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD430EDCA15800F77EA2 /* SkDisplayList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayList.h; path = ../libsgl/animator/SkDisplayList.h; sourceTree = SOURCE_ROOT; };
-		00B7DD440EDCA15800F77EA2 /* SkDisplayMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayMath.cpp; path = ../libsgl/animator/SkDisplayMath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD450EDCA15800F77EA2 /* SkDisplayMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayMath.h; path = ../libsgl/animator/SkDisplayMath.h; sourceTree = SOURCE_ROOT; };
-		00B7DD460EDCA15800F77EA2 /* SkDisplayMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayMovie.cpp; path = ../libsgl/animator/SkDisplayMovie.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD470EDCA15800F77EA2 /* SkDisplayMovie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayMovie.h; path = ../libsgl/animator/SkDisplayMovie.h; sourceTree = SOURCE_ROOT; };
-		00B7DD480EDCA15800F77EA2 /* SkDisplayNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayNumber.cpp; path = ../libsgl/animator/SkDisplayNumber.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD490EDCA15800F77EA2 /* SkDisplayNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayNumber.h; path = ../libsgl/animator/SkDisplayNumber.h; sourceTree = SOURCE_ROOT; };
-		00B7DD4A0EDCA15800F77EA2 /* SkDisplayPost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayPost.cpp; path = ../libsgl/animator/SkDisplayPost.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD4B0EDCA15800F77EA2 /* SkDisplayPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayPost.h; path = ../libsgl/animator/SkDisplayPost.h; sourceTree = SOURCE_ROOT; };
-		00B7DD4C0EDCA15800F77EA2 /* SkDisplayRandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayRandom.cpp; path = ../libsgl/animator/SkDisplayRandom.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD4D0EDCA15800F77EA2 /* SkDisplayRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayRandom.h; path = ../libsgl/animator/SkDisplayRandom.h; sourceTree = SOURCE_ROOT; };
-		00B7DD4E0EDCA15800F77EA2 /* SkDisplayScreenplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayScreenplay.cpp; path = ../libsgl/animator/SkDisplayScreenplay.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD4F0EDCA15800F77EA2 /* SkDisplayScreenplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayScreenplay.h; path = ../libsgl/animator/SkDisplayScreenplay.h; sourceTree = SOURCE_ROOT; };
-		00B7DD500EDCA15800F77EA2 /* SkDisplayType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayType.cpp; path = ../libsgl/animator/SkDisplayType.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD510EDCA15800F77EA2 /* SkDisplayType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayType.h; path = ../libsgl/animator/SkDisplayType.h; sourceTree = SOURCE_ROOT; };
-		00B7DD520EDCA15800F77EA2 /* SkDisplayTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayTypes.cpp; path = ../libsgl/animator/SkDisplayTypes.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD530EDCA15800F77EA2 /* SkDisplayTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayTypes.h; path = ../libsgl/animator/SkDisplayTypes.h; sourceTree = SOURCE_ROOT; };
-		00B7DD540EDCA15800F77EA2 /* SkDisplayXMLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDisplayXMLParser.cpp; path = ../libsgl/animator/SkDisplayXMLParser.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD550EDCA15800F77EA2 /* SkDisplayXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDisplayXMLParser.h; path = ../libsgl/animator/SkDisplayXMLParser.h; sourceTree = SOURCE_ROOT; };
-		00B7DD560EDCA15800F77EA2 /* SkDraw3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDraw3D.cpp; path = ../libsgl/animator/SkDraw3D.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD570EDCA15800F77EA2 /* SkDraw3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDraw3D.h; path = ../libsgl/animator/SkDraw3D.h; sourceTree = SOURCE_ROOT; };
-		00B7DD580EDCA15800F77EA2 /* SkDrawable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawable.cpp; path = ../libsgl/animator/SkDrawable.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD590EDCA15800F77EA2 /* SkDrawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawable.h; path = ../libsgl/animator/SkDrawable.h; sourceTree = SOURCE_ROOT; };
-		00B7DD5A0EDCA15800F77EA2 /* SkDrawBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawBitmap.cpp; path = ../libsgl/animator/SkDrawBitmap.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD5B0EDCA15800F77EA2 /* SkDrawBitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawBitmap.h; path = ../libsgl/animator/SkDrawBitmap.h; sourceTree = SOURCE_ROOT; };
-		00B7DD5C0EDCA15800F77EA2 /* SkDrawBlur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawBlur.cpp; path = ../libsgl/animator/SkDrawBlur.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD5D0EDCA15800F77EA2 /* SkDrawBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawBlur.h; path = ../libsgl/animator/SkDrawBlur.h; sourceTree = SOURCE_ROOT; };
-		00B7DD5E0EDCA15800F77EA2 /* SkDrawClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawClip.cpp; path = ../libsgl/animator/SkDrawClip.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD5F0EDCA15800F77EA2 /* SkDrawClip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawClip.h; path = ../libsgl/animator/SkDrawClip.h; sourceTree = SOURCE_ROOT; };
-		00B7DD600EDCA15800F77EA2 /* SkDrawColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawColor.cpp; path = ../libsgl/animator/SkDrawColor.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD610EDCA15800F77EA2 /* SkDrawColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawColor.h; path = ../libsgl/animator/SkDrawColor.h; sourceTree = SOURCE_ROOT; };
-		00B7DD620EDCA15800F77EA2 /* SkDrawDash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawDash.cpp; path = ../libsgl/animator/SkDrawDash.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD630EDCA15800F77EA2 /* SkDrawDash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawDash.h; path = ../libsgl/animator/SkDrawDash.h; sourceTree = SOURCE_ROOT; };
-		00B7DD640EDCA15800F77EA2 /* SkDrawDiscrete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawDiscrete.cpp; path = ../libsgl/animator/SkDrawDiscrete.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD650EDCA15800F77EA2 /* SkDrawDiscrete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawDiscrete.h; path = ../libsgl/animator/SkDrawDiscrete.h; sourceTree = SOURCE_ROOT; };
-		00B7DD660EDCA15800F77EA2 /* SkDrawEmboss.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawEmboss.cpp; path = ../libsgl/animator/SkDrawEmboss.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD670EDCA15800F77EA2 /* SkDrawEmboss.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawEmboss.h; path = ../libsgl/animator/SkDrawEmboss.h; sourceTree = SOURCE_ROOT; };
-		00B7DD680EDCA15800F77EA2 /* SkDrawExtraPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawExtraPathEffect.cpp; path = ../libsgl/animator/SkDrawExtraPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD690EDCA15800F77EA2 /* SkDrawFull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawFull.cpp; path = ../libsgl/animator/SkDrawFull.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD6A0EDCA15800F77EA2 /* SkDrawFull.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawFull.h; path = ../libsgl/animator/SkDrawFull.h; sourceTree = SOURCE_ROOT; };
-		00B7DD6B0EDCA15800F77EA2 /* SkDrawGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawGradient.cpp; path = ../libsgl/animator/SkDrawGradient.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD6C0EDCA15800F77EA2 /* SkDrawGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawGradient.h; path = ../libsgl/animator/SkDrawGradient.h; sourceTree = SOURCE_ROOT; };
-		00B7DD6D0EDCA15800F77EA2 /* SkDrawGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawGroup.cpp; path = ../libsgl/animator/SkDrawGroup.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD6E0EDCA15800F77EA2 /* SkDrawGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawGroup.h; path = ../libsgl/animator/SkDrawGroup.h; sourceTree = SOURCE_ROOT; };
-		00B7DD6F0EDCA15800F77EA2 /* SkDrawLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawLine.cpp; path = ../libsgl/animator/SkDrawLine.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD700EDCA15800F77EA2 /* SkDrawLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawLine.h; path = ../libsgl/animator/SkDrawLine.h; sourceTree = SOURCE_ROOT; };
-		00B7DD710EDCA15800F77EA2 /* SkDrawMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawMatrix.cpp; path = ../libsgl/animator/SkDrawMatrix.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD720EDCA15800F77EA2 /* SkDrawMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawMatrix.h; path = ../libsgl/animator/SkDrawMatrix.h; sourceTree = SOURCE_ROOT; };
-		00B7DD730EDCA15800F77EA2 /* SkDrawOval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawOval.cpp; path = ../libsgl/animator/SkDrawOval.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD740EDCA15800F77EA2 /* SkDrawOval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawOval.h; path = ../libsgl/animator/SkDrawOval.h; sourceTree = SOURCE_ROOT; };
-		00B7DD750EDCA15800F77EA2 /* SkDrawPaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawPaint.cpp; path = ../libsgl/animator/SkDrawPaint.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD760EDCA15800F77EA2 /* SkDrawPaint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawPaint.h; path = ../libsgl/animator/SkDrawPaint.h; sourceTree = SOURCE_ROOT; };
-		00B7DD770EDCA15800F77EA2 /* SkDrawPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawPath.cpp; path = ../libsgl/animator/SkDrawPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD780EDCA15800F77EA2 /* SkDrawPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawPath.h; path = ../libsgl/animator/SkDrawPath.h; sourceTree = SOURCE_ROOT; };
-		00B7DD790EDCA15800F77EA2 /* SkDrawPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawPoint.cpp; path = ../libsgl/animator/SkDrawPoint.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD7A0EDCA15800F77EA2 /* SkDrawPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawPoint.h; path = ../libsgl/animator/SkDrawPoint.h; sourceTree = SOURCE_ROOT; };
-		00B7DD7B0EDCA15800F77EA2 /* SkDrawRectangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawRectangle.cpp; path = ../libsgl/animator/SkDrawRectangle.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD7C0EDCA15800F77EA2 /* SkDrawRectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawRectangle.h; path = ../libsgl/animator/SkDrawRectangle.h; sourceTree = SOURCE_ROOT; };
-		00B7DD7D0EDCA15800F77EA2 /* SkDrawSaveLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawSaveLayer.cpp; path = ../libsgl/animator/SkDrawSaveLayer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD7E0EDCA15800F77EA2 /* SkDrawSaveLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawSaveLayer.h; path = ../libsgl/animator/SkDrawSaveLayer.h; sourceTree = SOURCE_ROOT; };
-		00B7DD7F0EDCA15800F77EA2 /* SkDrawShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawShader.cpp; path = ../libsgl/animator/SkDrawShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD800EDCA15800F77EA2 /* SkDrawShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawShader.h; path = ../libsgl/animator/SkDrawShader.h; sourceTree = SOURCE_ROOT; };
-		00B7DD810EDCA15800F77EA2 /* SkDrawText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawText.cpp; path = ../libsgl/animator/SkDrawText.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD820EDCA15800F77EA2 /* SkDrawText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawText.h; path = ../libsgl/animator/SkDrawText.h; sourceTree = SOURCE_ROOT; };
-		00B7DD830EDCA15800F77EA2 /* SkDrawTextBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawTextBox.cpp; path = ../libsgl/animator/SkDrawTextBox.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD840EDCA15800F77EA2 /* SkDrawTextBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawTextBox.h; path = ../libsgl/animator/SkDrawTextBox.h; sourceTree = SOURCE_ROOT; };
-		00B7DD850EDCA15800F77EA2 /* SkDrawTo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawTo.cpp; path = ../libsgl/animator/SkDrawTo.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD860EDCA15800F77EA2 /* SkDrawTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawTo.h; path = ../libsgl/animator/SkDrawTo.h; sourceTree = SOURCE_ROOT; };
-		00B7DD870EDCA15800F77EA2 /* SkDrawTransparentShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawTransparentShader.cpp; path = ../libsgl/animator/SkDrawTransparentShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD880EDCA15800F77EA2 /* SkDrawTransparentShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawTransparentShader.h; path = ../libsgl/animator/SkDrawTransparentShader.h; sourceTree = SOURCE_ROOT; };
-		00B7DD890EDCA15800F77EA2 /* SkDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDump.cpp; path = ../libsgl/animator/SkDump.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD8A0EDCA15800F77EA2 /* SkDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDump.h; path = ../libsgl/animator/SkDump.h; sourceTree = SOURCE_ROOT; };
-		00B7DD8C0EDCA15800F77EA2 /* SkExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkExtras.h; path = ../libsgl/animator/SkExtras.h; sourceTree = SOURCE_ROOT; };
-		00B7DD8D0EDCA15800F77EA2 /* SkGetCondensedInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGetCondensedInfo.cpp; path = ../libsgl/animator/SkGetCondensedInfo.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD8E0EDCA15800F77EA2 /* SkHitClear.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkHitClear.cpp; path = ../libsgl/animator/SkHitClear.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD8F0EDCA15800F77EA2 /* SkHitClear.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkHitClear.h; path = ../libsgl/animator/SkHitClear.h; sourceTree = SOURCE_ROOT; };
-		00B7DD900EDCA15800F77EA2 /* SkHitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkHitTest.cpp; path = ../libsgl/animator/SkHitTest.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD910EDCA15800F77EA2 /* SkHitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkHitTest.h; path = ../libsgl/animator/SkHitTest.h; sourceTree = SOURCE_ROOT; };
-		00B7DD920EDCA15800F77EA2 /* SkIntArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkIntArray.h; path = ../libsgl/animator/SkIntArray.h; sourceTree = SOURCE_ROOT; };
-		00B7DD930EDCA15800F77EA2 /* SkMatrixParts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMatrixParts.cpp; path = ../libsgl/animator/SkMatrixParts.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD940EDCA15800F77EA2 /* SkMatrixParts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkMatrixParts.h; path = ../libsgl/animator/SkMatrixParts.h; sourceTree = SOURCE_ROOT; };
-		00B7DD950EDCA15800F77EA2 /* SkMemberInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMemberInfo.cpp; path = ../libsgl/animator/SkMemberInfo.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD960EDCA15800F77EA2 /* SkMemberInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkMemberInfo.h; path = ../libsgl/animator/SkMemberInfo.h; sourceTree = SOURCE_ROOT; };
-		00B7DD970EDCA15800F77EA2 /* SkOpArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOpArray.cpp; path = ../libsgl/animator/SkOpArray.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD980EDCA15800F77EA2 /* SkOpArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkOpArray.h; path = ../libsgl/animator/SkOpArray.h; sourceTree = SOURCE_ROOT; };
-		00B7DD990EDCA15800F77EA2 /* SkOperand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkOperand.h; path = ../libsgl/animator/SkOperand.h; sourceTree = SOURCE_ROOT; };
-		00B7DD9A0EDCA15800F77EA2 /* SkOperand2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkOperand2.h; path = ../libsgl/animator/SkOperand2.h; sourceTree = SOURCE_ROOT; };
-		00B7DD9B0EDCA15800F77EA2 /* SkOperandInterpolator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkOperandInterpolator.h; path = ../libsgl/animator/SkOperandInterpolator.h; sourceTree = SOURCE_ROOT; };
-		00B7DD9C0EDCA15800F77EA2 /* SkOperandIterpolator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOperandIterpolator.cpp; path = ../libsgl/animator/SkOperandIterpolator.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD9D0EDCA15800F77EA2 /* SkPaintParts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPaintParts.cpp; path = ../libsgl/animator/SkPaintParts.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DD9E0EDCA15800F77EA2 /* SkPaintParts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPaintParts.h; path = ../libsgl/animator/SkPaintParts.h; sourceTree = SOURCE_ROOT; };
-		00B7DD9F0EDCA15800F77EA2 /* SkPathParts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathParts.cpp; path = ../libsgl/animator/SkPathParts.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDA00EDCA15800F77EA2 /* SkPathParts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPathParts.h; path = ../libsgl/animator/SkPathParts.h; sourceTree = SOURCE_ROOT; };
-		00B7DDA10EDCA15800F77EA2 /* SkPostParts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPostParts.cpp; path = ../libsgl/animator/SkPostParts.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDA20EDCA15800F77EA2 /* SkPostParts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPostParts.h; path = ../libsgl/animator/SkPostParts.h; sourceTree = SOURCE_ROOT; };
-		00B7DDA30EDCA15800F77EA2 /* SkScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScript.cpp; path = ../libsgl/animator/SkScript.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDA40EDCA15800F77EA2 /* SkScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScript.h; path = ../libsgl/animator/SkScript.h; sourceTree = SOURCE_ROOT; };
-		00B7DDA50EDCA15800F77EA2 /* SkScript2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScript2.h; path = ../libsgl/animator/SkScript2.h; sourceTree = SOURCE_ROOT; };
-		00B7DDA60EDCA15800F77EA2 /* SkScriptCallBack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScriptCallBack.h; path = ../libsgl/animator/SkScriptCallBack.h; sourceTree = SOURCE_ROOT; };
-		00B7DDA70EDCA15800F77EA2 /* SkScriptDecompile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScriptDecompile.cpp; path = ../libsgl/animator/SkScriptDecompile.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDA80EDCA15800F77EA2 /* SkScriptRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScriptRuntime.cpp; path = ../libsgl/animator/SkScriptRuntime.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDA90EDCA15800F77EA2 /* SkScriptRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScriptRuntime.h; path = ../libsgl/animator/SkScriptRuntime.h; sourceTree = SOURCE_ROOT; };
-		00B7DDAA0EDCA15800F77EA2 /* SkScriptTokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScriptTokenizer.cpp; path = ../libsgl/animator/SkScriptTokenizer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDAB0EDCA15800F77EA2 /* SkSnapshot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSnapshot.cpp; path = ../libsgl/animator/SkSnapshot.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDAC0EDCA15800F77EA2 /* SkSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSnapshot.h; path = ../libsgl/animator/SkSnapshot.h; sourceTree = SOURCE_ROOT; };
-		00B7DDAD0EDCA15800F77EA2 /* SkSVGPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSVGPath.cpp; path = ../libsgl/animator/SkSVGPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDAE0EDCA15800F77EA2 /* SkTDArray_Experimental.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTDArray_Experimental.h; path = ../libsgl/animator/SkTDArray_Experimental.h; sourceTree = SOURCE_ROOT; };
-		00B7DDAF0EDCA15800F77EA2 /* SkTextOnPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextOnPath.cpp; path = ../libsgl/animator/SkTextOnPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDB00EDCA15800F77EA2 /* SkTextOnPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTextOnPath.h; path = ../libsgl/animator/SkTextOnPath.h; sourceTree = SOURCE_ROOT; };
-		00B7DDB10EDCA15800F77EA2 /* SkTextToPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextToPath.cpp; path = ../libsgl/animator/SkTextToPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDB20EDCA15800F77EA2 /* SkTextToPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTextToPath.h; path = ../libsgl/animator/SkTextToPath.h; sourceTree = SOURCE_ROOT; };
-		00B7DDB30EDCA15800F77EA2 /* SkTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTime.cpp; path = ../libsgl/animator/SkTime.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDB40EDCA15800F77EA2 /* SkTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTypedArray.cpp; path = ../libsgl/animator/SkTypedArray.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDB50EDCA15800F77EA2 /* SkTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTypedArray.h; path = ../libsgl/animator/SkTypedArray.h; sourceTree = SOURCE_ROOT; };
-		00B7DDB60EDCA15800F77EA2 /* SkXMLAnimatorWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLAnimatorWriter.cpp; path = ../libsgl/animator/SkXMLAnimatorWriter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DDB70EDCA15800F77EA2 /* SkXMLAnimatorWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkXMLAnimatorWriter.h; path = ../libsgl/animator/SkXMLAnimatorWriter.h; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libanimator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libanimator.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* animator */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = animator;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DD170EDCA15800F77EA2 /* SkAnimate.h */,
-				00B7DD1A0EDCA15800F77EA2 /* SkAnimateActive.cpp */,
-				00B7DD1B0EDCA15800F77EA2 /* SkAnimateActive.h */,
-				00B7DD1C0EDCA15800F77EA2 /* SkAnimateBase.cpp */,
-				00B7DD1D0EDCA15800F77EA2 /* SkAnimateBase.h */,
-				00B7DD1E0EDCA15800F77EA2 /* SkAnimateField.cpp */,
-				00B7DD1F0EDCA15800F77EA2 /* SkAnimateMaker.cpp */,
-				00B7DD200EDCA15800F77EA2 /* SkAnimateMaker.h */,
-				00B7DD210EDCA15800F77EA2 /* SkAnimateProperties.h */,
-				00B7DD240EDCA15800F77EA2 /* SkAnimateSet.cpp */,
-				00B7DD250EDCA15800F77EA2 /* SkAnimateSet.h */,
-				00B7DD260EDCA15800F77EA2 /* SkAnimator.cpp */,
-				00B7DD270EDCA15800F77EA2 /* SkAnimatorScript.cpp */,
-				00B7DD280EDCA15800F77EA2 /* SkAnimatorScript.h */,
-				00B7DD290EDCA15800F77EA2 /* SkAnimatorScript2.cpp */,
-				00B7DD2A0EDCA15800F77EA2 /* SkAnimatorScript2.h */,
-				00B7DD2B0EDCA15800F77EA2 /* SkBase64.cpp */,
-				00B7DD2C0EDCA15800F77EA2 /* SkBase64.h */,
-				00B7DD2D0EDCA15800F77EA2 /* SkBoundable.cpp */,
-				00B7DD2E0EDCA15800F77EA2 /* SkBoundable.h */,
-				00B7DD320EDCA15800F77EA2 /* SkDisplayable.cpp */,
-				00B7DD330EDCA15800F77EA2 /* SkDisplayable.h */,
-				00B7DD340EDCA15800F77EA2 /* SkDisplayAdd.cpp */,
-				00B7DD350EDCA15800F77EA2 /* SkDisplayAdd.h */,
-				00B7DD360EDCA15800F77EA2 /* SkDisplayApply.cpp */,
-				00B7DD370EDCA15800F77EA2 /* SkDisplayApply.h */,
-				00B7DD380EDCA15800F77EA2 /* SkDisplayBounds.cpp */,
-				00B7DD390EDCA15800F77EA2 /* SkDisplayBounds.h */,
-				00B7DD3A0EDCA15800F77EA2 /* SkDisplayEvent.cpp */,
-				00B7DD3B0EDCA15800F77EA2 /* SkDisplayEvent.h */,
-				00B7DD3C0EDCA15800F77EA2 /* SkDisplayEvents.cpp */,
-				00B7DD3D0EDCA15800F77EA2 /* SkDisplayEvents.h */,
-				00B7DD3E0EDCA15800F77EA2 /* SkDisplayInclude.cpp */,
-				00B7DD3F0EDCA15800F77EA2 /* SkDisplayInclude.h */,
-				00B7DD400EDCA15800F77EA2 /* SkDisplayInput.cpp */,
-				00B7DD410EDCA15800F77EA2 /* SkDisplayInput.h */,
-				00B7DD420EDCA15800F77EA2 /* SkDisplayList.cpp */,
-				00B7DD430EDCA15800F77EA2 /* SkDisplayList.h */,
-				00B7DD440EDCA15800F77EA2 /* SkDisplayMath.cpp */,
-				00B7DD450EDCA15800F77EA2 /* SkDisplayMath.h */,
-				00B7DD460EDCA15800F77EA2 /* SkDisplayMovie.cpp */,
-				00B7DD470EDCA15800F77EA2 /* SkDisplayMovie.h */,
-				00B7DD480EDCA15800F77EA2 /* SkDisplayNumber.cpp */,
-				00B7DD490EDCA15800F77EA2 /* SkDisplayNumber.h */,
-				00B7DD4A0EDCA15800F77EA2 /* SkDisplayPost.cpp */,
-				00B7DD4B0EDCA15800F77EA2 /* SkDisplayPost.h */,
-				00B7DD4C0EDCA15800F77EA2 /* SkDisplayRandom.cpp */,
-				00B7DD4D0EDCA15800F77EA2 /* SkDisplayRandom.h */,
-				00B7DD4E0EDCA15800F77EA2 /* SkDisplayScreenplay.cpp */,
-				00B7DD4F0EDCA15800F77EA2 /* SkDisplayScreenplay.h */,
-				00B7DD500EDCA15800F77EA2 /* SkDisplayType.cpp */,
-				00B7DD510EDCA15800F77EA2 /* SkDisplayType.h */,
-				00B7DD520EDCA15800F77EA2 /* SkDisplayTypes.cpp */,
-				00B7DD530EDCA15800F77EA2 /* SkDisplayTypes.h */,
-				00B7DD540EDCA15800F77EA2 /* SkDisplayXMLParser.cpp */,
-				00B7DD550EDCA15800F77EA2 /* SkDisplayXMLParser.h */,
-				00B7DD560EDCA15800F77EA2 /* SkDraw3D.cpp */,
-				00B7DD570EDCA15800F77EA2 /* SkDraw3D.h */,
-				00B7DD580EDCA15800F77EA2 /* SkDrawable.cpp */,
-				00B7DD590EDCA15800F77EA2 /* SkDrawable.h */,
-				00B7DD5A0EDCA15800F77EA2 /* SkDrawBitmap.cpp */,
-				00B7DD5B0EDCA15800F77EA2 /* SkDrawBitmap.h */,
-				00B7DD5C0EDCA15800F77EA2 /* SkDrawBlur.cpp */,
-				00B7DD5D0EDCA15800F77EA2 /* SkDrawBlur.h */,
-				00B7DD5E0EDCA15800F77EA2 /* SkDrawClip.cpp */,
-				00B7DD5F0EDCA15800F77EA2 /* SkDrawClip.h */,
-				00B7DD600EDCA15800F77EA2 /* SkDrawColor.cpp */,
-				00B7DD610EDCA15800F77EA2 /* SkDrawColor.h */,
-				00B7DD620EDCA15800F77EA2 /* SkDrawDash.cpp */,
-				00B7DD630EDCA15800F77EA2 /* SkDrawDash.h */,
-				00B7DD640EDCA15800F77EA2 /* SkDrawDiscrete.cpp */,
-				00B7DD650EDCA15800F77EA2 /* SkDrawDiscrete.h */,
-				00B7DD660EDCA15800F77EA2 /* SkDrawEmboss.cpp */,
-				00B7DD670EDCA15800F77EA2 /* SkDrawEmboss.h */,
-				00B7DD680EDCA15800F77EA2 /* SkDrawExtraPathEffect.cpp */,
-				00B7DD690EDCA15800F77EA2 /* SkDrawFull.cpp */,
-				00B7DD6A0EDCA15800F77EA2 /* SkDrawFull.h */,
-				00B7DD6B0EDCA15800F77EA2 /* SkDrawGradient.cpp */,
-				00B7DD6C0EDCA15800F77EA2 /* SkDrawGradient.h */,
-				00B7DD6D0EDCA15800F77EA2 /* SkDrawGroup.cpp */,
-				00B7DD6E0EDCA15800F77EA2 /* SkDrawGroup.h */,
-				00B7DD6F0EDCA15800F77EA2 /* SkDrawLine.cpp */,
-				00B7DD700EDCA15800F77EA2 /* SkDrawLine.h */,
-				00B7DD710EDCA15800F77EA2 /* SkDrawMatrix.cpp */,
-				00B7DD720EDCA15800F77EA2 /* SkDrawMatrix.h */,
-				00B7DD730EDCA15800F77EA2 /* SkDrawOval.cpp */,
-				00B7DD740EDCA15800F77EA2 /* SkDrawOval.h */,
-				00B7DD750EDCA15800F77EA2 /* SkDrawPaint.cpp */,
-				00B7DD760EDCA15800F77EA2 /* SkDrawPaint.h */,
-				00B7DD770EDCA15800F77EA2 /* SkDrawPath.cpp */,
-				00B7DD780EDCA15800F77EA2 /* SkDrawPath.h */,
-				00B7DD790EDCA15800F77EA2 /* SkDrawPoint.cpp */,
-				00B7DD7A0EDCA15800F77EA2 /* SkDrawPoint.h */,
-				00B7DD7B0EDCA15800F77EA2 /* SkDrawRectangle.cpp */,
-				00B7DD7C0EDCA15800F77EA2 /* SkDrawRectangle.h */,
-				00B7DD7D0EDCA15800F77EA2 /* SkDrawSaveLayer.cpp */,
-				00B7DD7E0EDCA15800F77EA2 /* SkDrawSaveLayer.h */,
-				00B7DD7F0EDCA15800F77EA2 /* SkDrawShader.cpp */,
-				00B7DD800EDCA15800F77EA2 /* SkDrawShader.h */,
-				00B7DD810EDCA15800F77EA2 /* SkDrawText.cpp */,
-				00B7DD820EDCA15800F77EA2 /* SkDrawText.h */,
-				00B7DD830EDCA15800F77EA2 /* SkDrawTextBox.cpp */,
-				00B7DD840EDCA15800F77EA2 /* SkDrawTextBox.h */,
-				00B7DD850EDCA15800F77EA2 /* SkDrawTo.cpp */,
-				00B7DD860EDCA15800F77EA2 /* SkDrawTo.h */,
-				00B7DD870EDCA15800F77EA2 /* SkDrawTransparentShader.cpp */,
-				00B7DD880EDCA15800F77EA2 /* SkDrawTransparentShader.h */,
-				00B7DD890EDCA15800F77EA2 /* SkDump.cpp */,
-				00B7DD8A0EDCA15800F77EA2 /* SkDump.h */,
-				00B7DD8C0EDCA15800F77EA2 /* SkExtras.h */,
-				00B7DD8D0EDCA15800F77EA2 /* SkGetCondensedInfo.cpp */,
-				00B7DD8E0EDCA15800F77EA2 /* SkHitClear.cpp */,
-				00B7DD8F0EDCA15800F77EA2 /* SkHitClear.h */,
-				00B7DD900EDCA15800F77EA2 /* SkHitTest.cpp */,
-				00B7DD910EDCA15800F77EA2 /* SkHitTest.h */,
-				00B7DD920EDCA15800F77EA2 /* SkIntArray.h */,
-				00B7DD930EDCA15800F77EA2 /* SkMatrixParts.cpp */,
-				00B7DD940EDCA15800F77EA2 /* SkMatrixParts.h */,
-				00B7DD950EDCA15800F77EA2 /* SkMemberInfo.cpp */,
-				00B7DD960EDCA15800F77EA2 /* SkMemberInfo.h */,
-				00B7DD970EDCA15800F77EA2 /* SkOpArray.cpp */,
-				00B7DD980EDCA15800F77EA2 /* SkOpArray.h */,
-				00B7DD990EDCA15800F77EA2 /* SkOperand.h */,
-				00B7DD9A0EDCA15800F77EA2 /* SkOperand2.h */,
-				00B7DD9B0EDCA15800F77EA2 /* SkOperandInterpolator.h */,
-				00B7DD9C0EDCA15800F77EA2 /* SkOperandIterpolator.cpp */,
-				00B7DD9D0EDCA15800F77EA2 /* SkPaintParts.cpp */,
-				00B7DD9E0EDCA15800F77EA2 /* SkPaintParts.h */,
-				00B7DD9F0EDCA15800F77EA2 /* SkPathParts.cpp */,
-				00B7DDA00EDCA15800F77EA2 /* SkPathParts.h */,
-				00B7DDA10EDCA15800F77EA2 /* SkPostParts.cpp */,
-				00B7DDA20EDCA15800F77EA2 /* SkPostParts.h */,
-				00B7DDA30EDCA15800F77EA2 /* SkScript.cpp */,
-				00B7DDA40EDCA15800F77EA2 /* SkScript.h */,
-				00B7DDA50EDCA15800F77EA2 /* SkScript2.h */,
-				00B7DDA60EDCA15800F77EA2 /* SkScriptCallBack.h */,
-				00B7DDA70EDCA15800F77EA2 /* SkScriptDecompile.cpp */,
-				00B7DDA80EDCA15800F77EA2 /* SkScriptRuntime.cpp */,
-				00B7DDA90EDCA15800F77EA2 /* SkScriptRuntime.h */,
-				00B7DDAA0EDCA15800F77EA2 /* SkScriptTokenizer.cpp */,
-				00B7DDAB0EDCA15800F77EA2 /* SkSnapshot.cpp */,
-				00B7DDAC0EDCA15800F77EA2 /* SkSnapshot.h */,
-				00B7DDAD0EDCA15800F77EA2 /* SkSVGPath.cpp */,
-				00B7DDAE0EDCA15800F77EA2 /* SkTDArray_Experimental.h */,
-				00B7DDAF0EDCA15800F77EA2 /* SkTextOnPath.cpp */,
-				00B7DDB00EDCA15800F77EA2 /* SkTextOnPath.h */,
-				00B7DDB10EDCA15800F77EA2 /* SkTextToPath.cpp */,
-				00B7DDB20EDCA15800F77EA2 /* SkTextToPath.h */,
-				00B7DDB30EDCA15800F77EA2 /* SkTime.cpp */,
-				00B7DDB40EDCA15800F77EA2 /* SkTypedArray.cpp */,
-				00B7DDB50EDCA15800F77EA2 /* SkTypedArray.h */,
-				00B7DDB60EDCA15800F77EA2 /* SkXMLAnimatorWriter.cpp */,
-				00B7DDB70EDCA15800F77EA2 /* SkXMLAnimatorWriter.h */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libanimator.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DDB80EDCA15800F77EA2 /* SkAnimate.h in Headers */,
-				00B7DDBA0EDCA15800F77EA2 /* SkAnimateActive.h in Headers */,
-				00B7DDBC0EDCA15800F77EA2 /* SkAnimateBase.h in Headers */,
-				00B7DDBF0EDCA15800F77EA2 /* SkAnimateMaker.h in Headers */,
-				00B7DDC00EDCA15800F77EA2 /* SkAnimateProperties.h in Headers */,
-				00B7DDC20EDCA15800F77EA2 /* SkAnimateSet.h in Headers */,
-				00B7DDC50EDCA15800F77EA2 /* SkAnimatorScript.h in Headers */,
-				00B7DDC70EDCA15800F77EA2 /* SkAnimatorScript2.h in Headers */,
-				00B7DDC90EDCA15800F77EA2 /* SkBase64.h in Headers */,
-				00B7DDCB0EDCA15800F77EA2 /* SkBoundable.h in Headers */,
-				00B7DDD00EDCA15800F77EA2 /* SkDisplayable.h in Headers */,
-				00B7DDD20EDCA15800F77EA2 /* SkDisplayAdd.h in Headers */,
-				00B7DDD40EDCA15800F77EA2 /* SkDisplayApply.h in Headers */,
-				00B7DDD60EDCA15800F77EA2 /* SkDisplayBounds.h in Headers */,
-				00B7DDD80EDCA15800F77EA2 /* SkDisplayEvent.h in Headers */,
-				00B7DDDA0EDCA15800F77EA2 /* SkDisplayEvents.h in Headers */,
-				00B7DDDC0EDCA15800F77EA2 /* SkDisplayInclude.h in Headers */,
-				00B7DDDE0EDCA15800F77EA2 /* SkDisplayInput.h in Headers */,
-				00B7DDE00EDCA15800F77EA2 /* SkDisplayList.h in Headers */,
-				00B7DDE20EDCA15800F77EA2 /* SkDisplayMath.h in Headers */,
-				00B7DDE40EDCA15800F77EA2 /* SkDisplayMovie.h in Headers */,
-				00B7DDE60EDCA15800F77EA2 /* SkDisplayNumber.h in Headers */,
-				00B7DDE80EDCA15800F77EA2 /* SkDisplayPost.h in Headers */,
-				00B7DDEA0EDCA15800F77EA2 /* SkDisplayRandom.h in Headers */,
-				00B7DDEC0EDCA15800F77EA2 /* SkDisplayScreenplay.h in Headers */,
-				00B7DDEE0EDCA15800F77EA2 /* SkDisplayType.h in Headers */,
-				00B7DDF00EDCA15800F77EA2 /* SkDisplayTypes.h in Headers */,
-				00B7DDF20EDCA15800F77EA2 /* SkDisplayXMLParser.h in Headers */,
-				00B7DDF40EDCA15800F77EA2 /* SkDraw3D.h in Headers */,
-				00B7DDF60EDCA15800F77EA2 /* SkDrawable.h in Headers */,
-				00B7DDF80EDCA15800F77EA2 /* SkDrawBitmap.h in Headers */,
-				00B7DDFA0EDCA15800F77EA2 /* SkDrawBlur.h in Headers */,
-				00B7DDFC0EDCA15800F77EA2 /* SkDrawClip.h in Headers */,
-				00B7DDFE0EDCA15800F77EA2 /* SkDrawColor.h in Headers */,
-				00B7DE000EDCA15800F77EA2 /* SkDrawDash.h in Headers */,
-				00B7DE020EDCA15800F77EA2 /* SkDrawDiscrete.h in Headers */,
-				00B7DE040EDCA15800F77EA2 /* SkDrawEmboss.h in Headers */,
-				00B7DE070EDCA15800F77EA2 /* SkDrawFull.h in Headers */,
-				00B7DE090EDCA15800F77EA2 /* SkDrawGradient.h in Headers */,
-				00B7DE0B0EDCA15800F77EA2 /* SkDrawGroup.h in Headers */,
-				00B7DE0D0EDCA15800F77EA2 /* SkDrawLine.h in Headers */,
-				00B7DE0F0EDCA15800F77EA2 /* SkDrawMatrix.h in Headers */,
-				00B7DE110EDCA15800F77EA2 /* SkDrawOval.h in Headers */,
-				00B7DE130EDCA15800F77EA2 /* SkDrawPaint.h in Headers */,
-				00B7DE150EDCA15800F77EA2 /* SkDrawPath.h in Headers */,
-				00B7DE170EDCA15800F77EA2 /* SkDrawPoint.h in Headers */,
-				00B7DE190EDCA15800F77EA2 /* SkDrawRectangle.h in Headers */,
-				00B7DE1B0EDCA15800F77EA2 /* SkDrawSaveLayer.h in Headers */,
-				00B7DE1D0EDCA15800F77EA2 /* SkDrawShader.h in Headers */,
-				00B7DE1F0EDCA15800F77EA2 /* SkDrawText.h in Headers */,
-				00B7DE210EDCA15800F77EA2 /* SkDrawTextBox.h in Headers */,
-				00B7DE230EDCA15800F77EA2 /* SkDrawTo.h in Headers */,
-				00B7DE250EDCA15800F77EA2 /* SkDrawTransparentShader.h in Headers */,
-				00B7DE270EDCA15800F77EA2 /* SkDump.h in Headers */,
-				00B7DE280EDCA15800F77EA2 /* SkExtras.h in Headers */,
-				00B7DE2B0EDCA15800F77EA2 /* SkHitClear.h in Headers */,
-				00B7DE2D0EDCA15800F77EA2 /* SkHitTest.h in Headers */,
-				00B7DE2E0EDCA15800F77EA2 /* SkIntArray.h in Headers */,
-				00B7DE300EDCA15800F77EA2 /* SkMatrixParts.h in Headers */,
-				00B7DE320EDCA15800F77EA2 /* SkMemberInfo.h in Headers */,
-				00B7DE340EDCA15800F77EA2 /* SkOpArray.h in Headers */,
-				00B7DE350EDCA15800F77EA2 /* SkOperand.h in Headers */,
-				00B7DE360EDCA15800F77EA2 /* SkOperand2.h in Headers */,
-				00B7DE370EDCA15800F77EA2 /* SkOperandInterpolator.h in Headers */,
-				00B7DE3A0EDCA15800F77EA2 /* SkPaintParts.h in Headers */,
-				00B7DE3C0EDCA15800F77EA2 /* SkPathParts.h in Headers */,
-				00B7DE3E0EDCA15800F77EA2 /* SkPostParts.h in Headers */,
-				00B7DE400EDCA15800F77EA2 /* SkScript.h in Headers */,
-				00B7DE410EDCA15800F77EA2 /* SkScript2.h in Headers */,
-				00B7DE420EDCA15800F77EA2 /* SkScriptCallBack.h in Headers */,
-				00B7DE450EDCA15800F77EA2 /* SkScriptRuntime.h in Headers */,
-				00B7DE480EDCA15800F77EA2 /* SkSnapshot.h in Headers */,
-				00B7DE4A0EDCA15800F77EA2 /* SkTDArray_Experimental.h in Headers */,
-				00B7DE4C0EDCA15800F77EA2 /* SkTextOnPath.h in Headers */,
-				00B7DE4E0EDCA15800F77EA2 /* SkTextToPath.h in Headers */,
-				00B7DE510EDCA15800F77EA2 /* SkTypedArray.h in Headers */,
-				00B7DE530EDCA15800F77EA2 /* SkXMLAnimatorWriter.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* animator */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "animator" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = animator;
-			productName = animator;
-			productReference = D2AAC046055464E500DB518D /* libanimator.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "animator" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* animator */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				D2AAC045055464E500DB518D /* animator */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DDB90EDCA15800F77EA2 /* SkAnimateActive.cpp in Sources */,
-				00B7DDBB0EDCA15800F77EA2 /* SkAnimateBase.cpp in Sources */,
-				00B7DDBD0EDCA15800F77EA2 /* SkAnimateField.cpp in Sources */,
-				00B7DDBE0EDCA15800F77EA2 /* SkAnimateMaker.cpp in Sources */,
-				00B7DDC10EDCA15800F77EA2 /* SkAnimateSet.cpp in Sources */,
-				00B7DDC30EDCA15800F77EA2 /* SkAnimator.cpp in Sources */,
-				00B7DDC40EDCA15800F77EA2 /* SkAnimatorScript.cpp in Sources */,
-				00B7DDC60EDCA15800F77EA2 /* SkAnimatorScript2.cpp in Sources */,
-				00B7DDC80EDCA15800F77EA2 /* SkBase64.cpp in Sources */,
-				00B7DDCA0EDCA15800F77EA2 /* SkBoundable.cpp in Sources */,
-				00B7DDCF0EDCA15800F77EA2 /* SkDisplayable.cpp in Sources */,
-				00B7DDD10EDCA15800F77EA2 /* SkDisplayAdd.cpp in Sources */,
-				00B7DDD30EDCA15800F77EA2 /* SkDisplayApply.cpp in Sources */,
-				00B7DDD50EDCA15800F77EA2 /* SkDisplayBounds.cpp in Sources */,
-				00B7DDD70EDCA15800F77EA2 /* SkDisplayEvent.cpp in Sources */,
-				00B7DDD90EDCA15800F77EA2 /* SkDisplayEvents.cpp in Sources */,
-				00B7DDDB0EDCA15800F77EA2 /* SkDisplayInclude.cpp in Sources */,
-				00B7DDDD0EDCA15800F77EA2 /* SkDisplayInput.cpp in Sources */,
-				00B7DDDF0EDCA15800F77EA2 /* SkDisplayList.cpp in Sources */,
-				00B7DDE10EDCA15800F77EA2 /* SkDisplayMath.cpp in Sources */,
-				00B7DDE30EDCA15800F77EA2 /* SkDisplayMovie.cpp in Sources */,
-				00B7DDE50EDCA15800F77EA2 /* SkDisplayNumber.cpp in Sources */,
-				00B7DDE70EDCA15800F77EA2 /* SkDisplayPost.cpp in Sources */,
-				00B7DDE90EDCA15800F77EA2 /* SkDisplayRandom.cpp in Sources */,
-				00B7DDEB0EDCA15800F77EA2 /* SkDisplayScreenplay.cpp in Sources */,
-				00B7DDED0EDCA15800F77EA2 /* SkDisplayType.cpp in Sources */,
-				00B7DDEF0EDCA15800F77EA2 /* SkDisplayTypes.cpp in Sources */,
-				00B7DDF10EDCA15800F77EA2 /* SkDisplayXMLParser.cpp in Sources */,
-				00B7DDF30EDCA15800F77EA2 /* SkDraw3D.cpp in Sources */,
-				00B7DDF50EDCA15800F77EA2 /* SkDrawable.cpp in Sources */,
-				00B7DDF70EDCA15800F77EA2 /* SkDrawBitmap.cpp in Sources */,
-				00B7DDF90EDCA15800F77EA2 /* SkDrawBlur.cpp in Sources */,
-				00B7DDFB0EDCA15800F77EA2 /* SkDrawClip.cpp in Sources */,
-				00B7DDFD0EDCA15800F77EA2 /* SkDrawColor.cpp in Sources */,
-				00B7DDFF0EDCA15800F77EA2 /* SkDrawDash.cpp in Sources */,
-				00B7DE010EDCA15800F77EA2 /* SkDrawDiscrete.cpp in Sources */,
-				00B7DE030EDCA15800F77EA2 /* SkDrawEmboss.cpp in Sources */,
-				00B7DE050EDCA15800F77EA2 /* SkDrawExtraPathEffect.cpp in Sources */,
-				00B7DE060EDCA15800F77EA2 /* SkDrawFull.cpp in Sources */,
-				00B7DE080EDCA15800F77EA2 /* SkDrawGradient.cpp in Sources */,
-				00B7DE0A0EDCA15800F77EA2 /* SkDrawGroup.cpp in Sources */,
-				00B7DE0C0EDCA15800F77EA2 /* SkDrawLine.cpp in Sources */,
-				00B7DE0E0EDCA15800F77EA2 /* SkDrawMatrix.cpp in Sources */,
-				00B7DE100EDCA15800F77EA2 /* SkDrawOval.cpp in Sources */,
-				00B7DE120EDCA15800F77EA2 /* SkDrawPaint.cpp in Sources */,
-				00B7DE140EDCA15800F77EA2 /* SkDrawPath.cpp in Sources */,
-				00B7DE160EDCA15800F77EA2 /* SkDrawPoint.cpp in Sources */,
-				00B7DE180EDCA15800F77EA2 /* SkDrawRectangle.cpp in Sources */,
-				00B7DE1A0EDCA15800F77EA2 /* SkDrawSaveLayer.cpp in Sources */,
-				00B7DE1C0EDCA15800F77EA2 /* SkDrawShader.cpp in Sources */,
-				00B7DE1E0EDCA15800F77EA2 /* SkDrawText.cpp in Sources */,
-				00B7DE200EDCA15800F77EA2 /* SkDrawTextBox.cpp in Sources */,
-				00B7DE220EDCA15800F77EA2 /* SkDrawTo.cpp in Sources */,
-				00B7DE240EDCA15800F77EA2 /* SkDrawTransparentShader.cpp in Sources */,
-				00B7DE260EDCA15800F77EA2 /* SkDump.cpp in Sources */,
-				00B7DE290EDCA15800F77EA2 /* SkGetCondensedInfo.cpp in Sources */,
-				00B7DE2A0EDCA15800F77EA2 /* SkHitClear.cpp in Sources */,
-				00B7DE2C0EDCA15800F77EA2 /* SkHitTest.cpp in Sources */,
-				00B7DE2F0EDCA15800F77EA2 /* SkMatrixParts.cpp in Sources */,
-				00B7DE310EDCA15800F77EA2 /* SkMemberInfo.cpp in Sources */,
-				00B7DE330EDCA15800F77EA2 /* SkOpArray.cpp in Sources */,
-				00B7DE380EDCA15800F77EA2 /* SkOperandIterpolator.cpp in Sources */,
-				00B7DE390EDCA15800F77EA2 /* SkPaintParts.cpp in Sources */,
-				00B7DE3B0EDCA15800F77EA2 /* SkPathParts.cpp in Sources */,
-				00B7DE3D0EDCA15800F77EA2 /* SkPostParts.cpp in Sources */,
-				00B7DE3F0EDCA15800F77EA2 /* SkScript.cpp in Sources */,
-				00B7DE430EDCA15800F77EA2 /* SkScriptDecompile.cpp in Sources */,
-				00B7DE440EDCA15800F77EA2 /* SkScriptRuntime.cpp in Sources */,
-				00B7DE460EDCA15800F77EA2 /* SkScriptTokenizer.cpp in Sources */,
-				00B7DE470EDCA15800F77EA2 /* SkSnapshot.cpp in Sources */,
-				00B7DE490EDCA15800F77EA2 /* SkSVGPath.cpp in Sources */,
-				00B7DE4B0EDCA15800F77EA2 /* SkTextOnPath.cpp in Sources */,
-				00B7DE4D0EDCA15800F77EA2 /* SkTextToPath.cpp in Sources */,
-				00B7DE4F0EDCA15800F77EA2 /* SkTime.cpp in Sources */,
-				00B7DE500EDCA15800F77EA2 /* SkTypedArray.cpp in Sources */,
-				00B7DE520EDCA15800F77EA2 /* SkXMLAnimatorWriter.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = animator;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = animator;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_BUILD_FOR_MAC;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/graphics ../include/corecg";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/graphics ../include/corecg";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "animator" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "animator" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/chipmunk.xcodeproj/project.pbxproj b/xcode/chipmunk.xcodeproj/project.pbxproj
deleted file mode 100644
index d30ddcd..0000000
--- a/xcode/chipmunk.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,258 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		FE16E1510CE26D84006BB7E0 /* chipmunk.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1270CE26C3D006BB7E0 /* chipmunk.c */; };
-		FE16E1520CE26D86006BB7E0 /* cpArbiter.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E12A0CE26C3D006BB7E0 /* cpArbiter.c */; };
-		FE16E1530CE26D87006BB7E0 /* cpArray.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E12C0CE26C3D006BB7E0 /* cpArray.c */; };
-		FE16E1540CE26D88006BB7E0 /* cpBB.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E12E0CE26C3D006BB7E0 /* cpBB.c */; };
-		FE16E1550CE26D8A006BB7E0 /* cpBody.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1300CE26C3D006BB7E0 /* cpBody.c */; };
-		FE16E1560CE26D8B006BB7E0 /* cpCollision.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1320CE26C3D006BB7E0 /* cpCollision.c */; };
-		FE16E1570CE26D8C006BB7E0 /* cpHashSet.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1340CE26C3D006BB7E0 /* cpHashSet.c */; };
-		FE16E1580CE26D8F006BB7E0 /* cpJoint.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1360CE26C3D006BB7E0 /* cpJoint.c */; };
-		FE16E1590CE26D91006BB7E0 /* cpPolyShape.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1380CE26C3D006BB7E0 /* cpPolyShape.c */; };
-		FE16E15E0CE26D9E006BB7E0 /* cpShape.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E13A0CE26C3D006BB7E0 /* cpShape.c */; };
-		FE16E15F0CE26D9F006BB7E0 /* cpSpace.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E13C0CE26C3D006BB7E0 /* cpSpace.c */; };
-		FE16E1600CE26DA0006BB7E0 /* cpSpaceHash.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E13E0CE26C3D006BB7E0 /* cpSpaceHash.c */; };
-		FE16E1610CE26DA1006BB7E0 /* cpVect.c in Sources */ = {isa = PBXBuildFile; fileRef = FE16E1400CE26C3D006BB7E0 /* cpVect.c */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		FE16E1270CE26C3D006BB7E0 /* chipmunk.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = chipmunk.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/chipmunk.c"; sourceTree = "<absolute>"; };
-		FE16E1280CE26C3D006BB7E0 /* chipmunk.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = chipmunk.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/chipmunk.h"; sourceTree = "<absolute>"; };
-		FE16E1290CE26C3D006BB7E0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = CMakeLists.txt; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/CMakeLists.txt"; sourceTree = "<absolute>"; };
-		FE16E12A0CE26C3D006BB7E0 /* cpArbiter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpArbiter.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpArbiter.c"; sourceTree = "<absolute>"; };
-		FE16E12B0CE26C3D006BB7E0 /* cpArbiter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpArbiter.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpArbiter.h"; sourceTree = "<absolute>"; };
-		FE16E12C0CE26C3D006BB7E0 /* cpArray.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpArray.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpArray.c"; sourceTree = "<absolute>"; };
-		FE16E12D0CE26C3D006BB7E0 /* cpArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpArray.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpArray.h"; sourceTree = "<absolute>"; };
-		FE16E12E0CE26C3D006BB7E0 /* cpBB.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpBB.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpBB.c"; sourceTree = "<absolute>"; };
-		FE16E12F0CE26C3D006BB7E0 /* cpBB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpBB.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpBB.h"; sourceTree = "<absolute>"; };
-		FE16E1300CE26C3D006BB7E0 /* cpBody.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpBody.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpBody.c"; sourceTree = "<absolute>"; };
-		FE16E1310CE26C3D006BB7E0 /* cpBody.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpBody.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpBody.h"; sourceTree = "<absolute>"; };
-		FE16E1320CE26C3D006BB7E0 /* cpCollision.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpCollision.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpCollision.c"; sourceTree = "<absolute>"; };
-		FE16E1330CE26C3D006BB7E0 /* cpCollision.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpCollision.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpCollision.h"; sourceTree = "<absolute>"; };
-		FE16E1340CE26C3D006BB7E0 /* cpHashSet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpHashSet.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpHashSet.c"; sourceTree = "<absolute>"; };
-		FE16E1350CE26C3D006BB7E0 /* cpHashSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpHashSet.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpHashSet.h"; sourceTree = "<absolute>"; };
-		FE16E1360CE26C3D006BB7E0 /* cpJoint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpJoint.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpJoint.c"; sourceTree = "<absolute>"; };
-		FE16E1370CE26C3D006BB7E0 /* cpJoint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpJoint.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpJoint.h"; sourceTree = "<absolute>"; };
-		FE16E1380CE26C3D006BB7E0 /* cpPolyShape.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpPolyShape.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpPolyShape.c"; sourceTree = "<absolute>"; };
-		FE16E1390CE26C3D006BB7E0 /* cpPolyShape.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpPolyShape.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpPolyShape.h"; sourceTree = "<absolute>"; };
-		FE16E13A0CE26C3D006BB7E0 /* cpShape.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpShape.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpShape.c"; sourceTree = "<absolute>"; };
-		FE16E13B0CE26C3D006BB7E0 /* cpShape.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpShape.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpShape.h"; sourceTree = "<absolute>"; };
-		FE16E13C0CE26C3D006BB7E0 /* cpSpace.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpSpace.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpSpace.c"; sourceTree = "<absolute>"; };
-		FE16E13D0CE26C3D006BB7E0 /* cpSpace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpSpace.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpSpace.h"; sourceTree = "<absolute>"; };
-		FE16E13E0CE26C3D006BB7E0 /* cpSpaceHash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpSpaceHash.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpSpaceHash.c"; sourceTree = "<absolute>"; };
-		FE16E13F0CE26C3D006BB7E0 /* cpSpaceHash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpSpaceHash.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpSpaceHash.h"; sourceTree = "<absolute>"; };
-		FE16E1400CE26C3D006BB7E0 /* cpVect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpVect.c; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpVect.c"; sourceTree = "<absolute>"; };
-		FE16E1410CE26C3D006BB7E0 /* cpVect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpVect.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/cpVect.h"; sourceTree = "<absolute>"; };
-		FE16E1420CE26C3D006BB7E0 /* prime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = prime.h; path = "/Users/caryclark/Desktop/Chipmunk-4.0.2/src/prime.h"; sourceTree = "<absolute>"; };
-		FE16E14C0CE26D61006BB7E0 /* libchipmunk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libchipmunk.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		FE16E14A0CE26D61006BB7E0 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		FE16E11A0CE26B5D006BB7E0 = {
-			isa = PBXGroup;
-			children = (
-				FE16E1250CE26B6A006BB7E0 /* Sources */,
-				FE16E14D0CE26D61006BB7E0 /* Products */,
-			);
-			sourceTree = "<group>";
-		};
-		FE16E1250CE26B6A006BB7E0 /* Sources */ = {
-			isa = PBXGroup;
-			children = (
-				FE16E1270CE26C3D006BB7E0 /* chipmunk.c */,
-				FE16E1280CE26C3D006BB7E0 /* chipmunk.h */,
-				FE16E1290CE26C3D006BB7E0 /* CMakeLists.txt */,
-				FE16E12A0CE26C3D006BB7E0 /* cpArbiter.c */,
-				FE16E12B0CE26C3D006BB7E0 /* cpArbiter.h */,
-				FE16E12C0CE26C3D006BB7E0 /* cpArray.c */,
-				FE16E12D0CE26C3D006BB7E0 /* cpArray.h */,
-				FE16E12E0CE26C3D006BB7E0 /* cpBB.c */,
-				FE16E12F0CE26C3D006BB7E0 /* cpBB.h */,
-				FE16E1300CE26C3D006BB7E0 /* cpBody.c */,
-				FE16E1310CE26C3D006BB7E0 /* cpBody.h */,
-				FE16E1320CE26C3D006BB7E0 /* cpCollision.c */,
-				FE16E1330CE26C3D006BB7E0 /* cpCollision.h */,
-				FE16E1340CE26C3D006BB7E0 /* cpHashSet.c */,
-				FE16E1350CE26C3D006BB7E0 /* cpHashSet.h */,
-				FE16E1360CE26C3D006BB7E0 /* cpJoint.c */,
-				FE16E1370CE26C3D006BB7E0 /* cpJoint.h */,
-				FE16E1380CE26C3D006BB7E0 /* cpPolyShape.c */,
-				FE16E1390CE26C3D006BB7E0 /* cpPolyShape.h */,
-				FE16E13A0CE26C3D006BB7E0 /* cpShape.c */,
-				FE16E13B0CE26C3D006BB7E0 /* cpShape.h */,
-				FE16E13C0CE26C3D006BB7E0 /* cpSpace.c */,
-				FE16E13D0CE26C3D006BB7E0 /* cpSpace.h */,
-				FE16E13E0CE26C3D006BB7E0 /* cpSpaceHash.c */,
-				FE16E13F0CE26C3D006BB7E0 /* cpSpaceHash.h */,
-				FE16E1400CE26C3D006BB7E0 /* cpVect.c */,
-				FE16E1410CE26C3D006BB7E0 /* cpVect.h */,
-				FE16E1420CE26C3D006BB7E0 /* prime.h */,
-			);
-			name = Sources;
-			sourceTree = "<group>";
-		};
-		FE16E14D0CE26D61006BB7E0 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				FE16E14C0CE26D61006BB7E0 /* libchipmunk.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		FE16E1480CE26D61006BB7E0 /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		FE16E14B0CE26D61006BB7E0 /* chipmunk */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FE16E14E0CE26D61006BB7E0 /* Build configuration list for PBXNativeTarget "chipmunk" */;
-			buildPhases = (
-				FE16E1480CE26D61006BB7E0 /* Headers */,
-				FE16E1490CE26D61006BB7E0 /* Sources */,
-				FE16E14A0CE26D61006BB7E0 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = chipmunk;
-			productName = chipmunk;
-			productReference = FE16E14C0CE26D61006BB7E0 /* libchipmunk.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		FE16E11C0CE26B5D006BB7E0 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = FE16E11D0CE26B5D006BB7E0 /* Build configuration list for PBXProject "chipmunk" */;
-			hasScannedForEncodings = 0;
-			mainGroup = FE16E11A0CE26B5D006BB7E0;
-			productRefGroup = FE16E14D0CE26D61006BB7E0 /* Products */;
-			projectDirPath = "";
-			targets = (
-				FE16E14B0CE26D61006BB7E0 /* chipmunk */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		FE16E1490CE26D61006BB7E0 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FE16E1510CE26D84006BB7E0 /* chipmunk.c in Sources */,
-				FE16E1520CE26D86006BB7E0 /* cpArbiter.c in Sources */,
-				FE16E1530CE26D87006BB7E0 /* cpArray.c in Sources */,
-				FE16E1540CE26D88006BB7E0 /* cpBB.c in Sources */,
-				FE16E1550CE26D8A006BB7E0 /* cpBody.c in Sources */,
-				FE16E1560CE26D8B006BB7E0 /* cpCollision.c in Sources */,
-				FE16E1570CE26D8C006BB7E0 /* cpHashSet.c in Sources */,
-				FE16E1580CE26D8F006BB7E0 /* cpJoint.c in Sources */,
-				FE16E1590CE26D91006BB7E0 /* cpPolyShape.c in Sources */,
-				FE16E15E0CE26D9E006BB7E0 /* cpShape.c in Sources */,
-				FE16E15F0CE26D9F006BB7E0 /* cpSpace.c in Sources */,
-				FE16E1600CE26DA0006BB7E0 /* cpSpaceHash.c in Sources */,
-				FE16E1610CE26DA1006BB7E0 /* cpVect.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		FE16E11E0CE26B5D006BB7E0 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-			};
-			name = Debug;
-		};
-		FE16E11F0CE26B5D006BB7E0 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-			};
-			name = Release;
-		};
-		FE16E14F0CE26D61006BB7E0 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PREBINDING = NO;
-				PRODUCT_NAME = chipmunk;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		FE16E1500CE26D61006BB7E0 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PREBINDING = NO;
-				PRODUCT_NAME = chipmunk;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		FE16E11D0CE26B5D006BB7E0 /* Build configuration list for PBXProject "chipmunk" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE16E11E0CE26B5D006BB7E0 /* Debug */,
-				FE16E11F0CE26B5D006BB7E0 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		FE16E14E0CE26D61006BB7E0 /* Build configuration list for PBXNativeTarget "chipmunk" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE16E14F0CE26D61006BB7E0 /* Debug */,
-				FE16E1500CE26D61006BB7E0 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = FE16E11C0CE26B5D006BB7E0 /* Project object */;
-}
diff --git a/xcode/corecg.xcodeproj/project.pbxproj b/xcode/corecg.xcodeproj/project.pbxproj
deleted file mode 100644
index 1b01d4f..0000000
--- a/xcode/corecg.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,292 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DE790EDCA1CE00F77EA2 /* Sk64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE640EDCA1CE00F77EA2 /* Sk64.cpp */; };
-		00B7DE7A0EDCA1CE00F77EA2 /* SkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE650EDCA1CE00F77EA2 /* SkBuffer.cpp */; };
-		00B7DE7B0EDCA1CE00F77EA2 /* SkChunkAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE660EDCA1CE00F77EA2 /* SkChunkAlloc.cpp */; };
-		00B7DE7C0EDCA1CE00F77EA2 /* SkCordic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE670EDCA1CE00F77EA2 /* SkCordic.cpp */; };
-		00B7DE7D0EDCA1CE00F77EA2 /* SkCordic.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DE680EDCA1CE00F77EA2 /* SkCordic.h */; };
-		00B7DE7E0EDCA1CE00F77EA2 /* SkDebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE690EDCA1CE00F77EA2 /* SkDebug.cpp */; };
-		00B7DE7F0EDCA1CE00F77EA2 /* SkDebug_stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE6A0EDCA1CE00F77EA2 /* SkDebug_stdio.cpp */; };
-		00B7DE800EDCA1CE00F77EA2 /* SkFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE6B0EDCA1CE00F77EA2 /* SkFloat.cpp */; };
-		00B7DE810EDCA1CE00F77EA2 /* SkFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DE6C0EDCA1CE00F77EA2 /* SkFloat.h */; };
-		00B7DE820EDCA1CE00F77EA2 /* SkFloatBits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE6D0EDCA1CE00F77EA2 /* SkFloatBits.cpp */; };
-		00B7DE830EDCA1CE00F77EA2 /* SkInterpolator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE6E0EDCA1CE00F77EA2 /* SkInterpolator.cpp */; };
-		00B7DE840EDCA1CE00F77EA2 /* SkMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE6F0EDCA1CE00F77EA2 /* SkMath.cpp */; };
-		00B7DE850EDCA1CE00F77EA2 /* SkMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE700EDCA1CE00F77EA2 /* SkMatrix.cpp */; };
-		00B7DE860EDCA1CE00F77EA2 /* SkMemory_stdlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE710EDCA1CE00F77EA2 /* SkMemory_stdlib.cpp */; };
-		00B7DE870EDCA1CE00F77EA2 /* SkPageFlipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE720EDCA1CE00F77EA2 /* SkPageFlipper.cpp */; };
-		00B7DE880EDCA1CE00F77EA2 /* SkPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE730EDCA1CE00F77EA2 /* SkPoint.cpp */; };
-		00B7DE890EDCA1CE00F77EA2 /* SkRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE740EDCA1CE00F77EA2 /* SkRect.cpp */; };
-		00B7DE8A0EDCA1CE00F77EA2 /* SkRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE750EDCA1CE00F77EA2 /* SkRegion.cpp */; };
-		00B7DE8B0EDCA1CE00F77EA2 /* SkRegionPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DE760EDCA1CE00F77EA2 /* SkRegionPriv.h */; };
-		00B7DE8C0EDCA1CE00F77EA2 /* SkSinTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DE770EDCA1CE00F77EA2 /* SkSinTable.h */; };
-		00B7DE8D0EDCA1CE00F77EA2 /* SkTSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DE780EDCA1CE00F77EA2 /* SkTSort.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DE640EDCA1CE00F77EA2 /* Sk64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk64.cpp; path = ../libcorecg/Sk64.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE650EDCA1CE00F77EA2 /* SkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBuffer.cpp; path = ../libcorecg/SkBuffer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE660EDCA1CE00F77EA2 /* SkChunkAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkChunkAlloc.cpp; path = ../libcorecg/SkChunkAlloc.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE670EDCA1CE00F77EA2 /* SkCordic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCordic.cpp; path = ../libcorecg/SkCordic.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE680EDCA1CE00F77EA2 /* SkCordic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkCordic.h; path = ../libcorecg/SkCordic.h; sourceTree = SOURCE_ROOT; };
-		00B7DE690EDCA1CE00F77EA2 /* SkDebug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDebug.cpp; path = ../libcorecg/SkDebug.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE6A0EDCA1CE00F77EA2 /* SkDebug_stdio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDebug_stdio.cpp; path = ../libcorecg/SkDebug_stdio.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE6B0EDCA1CE00F77EA2 /* SkFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFloat.cpp; path = ../libcorecg/SkFloat.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE6C0EDCA1CE00F77EA2 /* SkFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFloat.h; path = ../libcorecg/SkFloat.h; sourceTree = SOURCE_ROOT; };
-		00B7DE6D0EDCA1CE00F77EA2 /* SkFloatBits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFloatBits.cpp; path = ../libcorecg/SkFloatBits.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE6E0EDCA1CE00F77EA2 /* SkInterpolator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkInterpolator.cpp; path = ../libcorecg/SkInterpolator.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE6F0EDCA1CE00F77EA2 /* SkMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMath.cpp; path = ../libcorecg/SkMath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE700EDCA1CE00F77EA2 /* SkMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMatrix.cpp; path = ../libcorecg/SkMatrix.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE710EDCA1CE00F77EA2 /* SkMemory_stdlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMemory_stdlib.cpp; path = ../libcorecg/SkMemory_stdlib.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE720EDCA1CE00F77EA2 /* SkPageFlipper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPageFlipper.cpp; path = ../libcorecg/SkPageFlipper.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE730EDCA1CE00F77EA2 /* SkPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPoint.cpp; path = ../libcorecg/SkPoint.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE740EDCA1CE00F77EA2 /* SkRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRect.cpp; path = ../libcorecg/SkRect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE750EDCA1CE00F77EA2 /* SkRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRegion.cpp; path = ../libcorecg/SkRegion.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DE760EDCA1CE00F77EA2 /* SkRegionPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkRegionPriv.h; path = ../libcorecg/SkRegionPriv.h; sourceTree = SOURCE_ROOT; };
-		00B7DE770EDCA1CE00F77EA2 /* SkSinTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSinTable.h; path = ../libcorecg/SkSinTable.h; sourceTree = SOURCE_ROOT; };
-		00B7DE780EDCA1CE00F77EA2 /* SkTSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTSort.h; path = ../libcorecg/SkTSort.h; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libcorecg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcorecg.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* corecg */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = corecg;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DE640EDCA1CE00F77EA2 /* Sk64.cpp */,
-				00B7DE650EDCA1CE00F77EA2 /* SkBuffer.cpp */,
-				00B7DE660EDCA1CE00F77EA2 /* SkChunkAlloc.cpp */,
-				00B7DE670EDCA1CE00F77EA2 /* SkCordic.cpp */,
-				00B7DE680EDCA1CE00F77EA2 /* SkCordic.h */,
-				00B7DE690EDCA1CE00F77EA2 /* SkDebug.cpp */,
-				00B7DE6A0EDCA1CE00F77EA2 /* SkDebug_stdio.cpp */,
-				00B7DE6B0EDCA1CE00F77EA2 /* SkFloat.cpp */,
-				00B7DE6C0EDCA1CE00F77EA2 /* SkFloat.h */,
-				00B7DE6D0EDCA1CE00F77EA2 /* SkFloatBits.cpp */,
-				00B7DE6E0EDCA1CE00F77EA2 /* SkInterpolator.cpp */,
-				00B7DE6F0EDCA1CE00F77EA2 /* SkMath.cpp */,
-				00B7DE700EDCA1CE00F77EA2 /* SkMatrix.cpp */,
-				00B7DE710EDCA1CE00F77EA2 /* SkMemory_stdlib.cpp */,
-				00B7DE720EDCA1CE00F77EA2 /* SkPageFlipper.cpp */,
-				00B7DE730EDCA1CE00F77EA2 /* SkPoint.cpp */,
-				00B7DE740EDCA1CE00F77EA2 /* SkRect.cpp */,
-				00B7DE750EDCA1CE00F77EA2 /* SkRegion.cpp */,
-				00B7DE760EDCA1CE00F77EA2 /* SkRegionPriv.h */,
-				00B7DE770EDCA1CE00F77EA2 /* SkSinTable.h */,
-				00B7DE780EDCA1CE00F77EA2 /* SkTSort.h */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libcorecg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DE7D0EDCA1CE00F77EA2 /* SkCordic.h in Headers */,
-				00B7DE810EDCA1CE00F77EA2 /* SkFloat.h in Headers */,
-				00B7DE8B0EDCA1CE00F77EA2 /* SkRegionPriv.h in Headers */,
-				00B7DE8C0EDCA1CE00F77EA2 /* SkSinTable.h in Headers */,
-				00B7DE8D0EDCA1CE00F77EA2 /* SkTSort.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* corecg */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "corecg" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = corecg;
-			productName = corecg;
-			productReference = D2AAC046055464E500DB518D /* libcorecg.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "corecg" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* corecg */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC045055464E500DB518D /* corecg */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DE790EDCA1CE00F77EA2 /* Sk64.cpp in Sources */,
-				00B7DE7A0EDCA1CE00F77EA2 /* SkBuffer.cpp in Sources */,
-				00B7DE7B0EDCA1CE00F77EA2 /* SkChunkAlloc.cpp in Sources */,
-				00B7DE7C0EDCA1CE00F77EA2 /* SkCordic.cpp in Sources */,
-				00B7DE7E0EDCA1CE00F77EA2 /* SkDebug.cpp in Sources */,
-				00B7DE7F0EDCA1CE00F77EA2 /* SkDebug_stdio.cpp in Sources */,
-				00B7DE800EDCA1CE00F77EA2 /* SkFloat.cpp in Sources */,
-				00B7DE820EDCA1CE00F77EA2 /* SkFloatBits.cpp in Sources */,
-				00B7DE830EDCA1CE00F77EA2 /* SkInterpolator.cpp in Sources */,
-				00B7DE840EDCA1CE00F77EA2 /* SkMath.cpp in Sources */,
-				00B7DE850EDCA1CE00F77EA2 /* SkMatrix.cpp in Sources */,
-				00B7DE860EDCA1CE00F77EA2 /* SkMemory_stdlib.cpp in Sources */,
-				00B7DE870EDCA1CE00F77EA2 /* SkPageFlipper.cpp in Sources */,
-				00B7DE880EDCA1CE00F77EA2 /* SkPoint.cpp in Sources */,
-				00B7DE890EDCA1CE00F77EA2 /* SkRect.cpp in Sources */,
-				00B7DE8A0EDCA1CE00F77EA2 /* SkRegion.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = corecg;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = (
-					ppc,
-					i386,
-				);
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = corecg;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = ../include/corecg;
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_RELEASE;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = ../include/corecg;
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "corecg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "corecg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/expat.xcodeproj/project.pbxproj b/xcode/expat.xcodeproj/project.pbxproj
deleted file mode 100644
index 37a9b0f..0000000
--- a/xcode/expat.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,246 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DE9E0EDCA22F00F77EA2 /* SkXMLPullParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DE9C0EDCA22F00F77EA2 /* SkXMLPullParser.cpp */; };
-		00B7DEA20EDCA25700F77EA2 /* SkXMLParser_expat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEA10EDCA25700F77EA2 /* SkXMLParser_expat.cpp */; };
-		00B7DEA60EDCA27F00F77EA2 /* xmlparse.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEA30EDCA27F00F77EA2 /* xmlparse.c */; };
-		00B7DEA70EDCA27F00F77EA2 /* xmlrole.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEA40EDCA27F00F77EA2 /* xmlrole.c */; };
-		00B7DEA80EDCA27F00F77EA2 /* xmltok.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEA50EDCA27F00F77EA2 /* xmltok.c */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DE9C0EDCA22F00F77EA2 /* SkXMLPullParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLPullParser.cpp; path = ../libsgl/xml/SkXMLPullParser.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DEA10EDCA25700F77EA2 /* SkXMLParser_expat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLParser_expat.cpp; path = ../libsgl/ports/SkXMLParser_expat.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DEA30EDCA27F00F77EA2 /* xmlparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmlparse.c; path = ../../expat/lib/xmlparse.c; sourceTree = SOURCE_ROOT; };
-		00B7DEA40EDCA27F00F77EA2 /* xmlrole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmlrole.c; path = ../../expat/lib/xmlrole.c; sourceTree = SOURCE_ROOT; };
-		00B7DEA50EDCA27F00F77EA2 /* xmltok.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmltok.c; path = ../../expat/lib/xmltok.c; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libexpat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libexpat.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* expat */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = expat;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DEA30EDCA27F00F77EA2 /* xmlparse.c */,
-				00B7DEA40EDCA27F00F77EA2 /* xmlrole.c */,
-				00B7DEA50EDCA27F00F77EA2 /* xmltok.c */,
-				00B7DEA10EDCA25700F77EA2 /* SkXMLParser_expat.cpp */,
-				00B7DE9C0EDCA22F00F77EA2 /* SkXMLPullParser.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libexpat.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* expat */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "expat" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = expat;
-			productName = expat;
-			productReference = D2AAC046055464E500DB518D /* libexpat.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "expat" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* expat */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				D2AAC045055464E500DB518D /* expat */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DE9E0EDCA22F00F77EA2 /* SkXMLPullParser.cpp in Sources */,
-				00B7DEA20EDCA25700F77EA2 /* SkXMLParser_expat.cpp in Sources */,
-				00B7DEA60EDCA27F00F77EA2 /* xmlparse.c in Sources */,
-				00B7DEA70EDCA27F00F77EA2 /* xmlrole.c in Sources */,
-				00B7DEA80EDCA27F00F77EA2 /* xmltok.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = expat;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					MACOS_CLASSIC,
-					XML_STATIC,
-					SK_RELEASE,
-				);
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = expat;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					MACOS_CLASSIC,
-					XML_STATIC,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/** ../../expat/lib";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					MACOS_CLASSIC,
-					XML_STATIC,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/** ../../expat/lib";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "expat" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "expat" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/freetype2.xcodeproj/project.pbxproj b/xcode/freetype2.xcodeproj/project.pbxproj
deleted file mode 100644
index 08c13a3..0000000
--- a/xcode/freetype2.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,456 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DEE20EDCA46500F77EA2 /* ftadvanc.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEC70EDCA46500F77EA2 /* ftadvanc.c */; };
-		00B7DEE30EDCA46500F77EA2 /* ftapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEC80EDCA46500F77EA2 /* ftapi.c */; };
-		00B7DEE40EDCA46500F77EA2 /* ftbase.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEC90EDCA46500F77EA2 /* ftbase.c */; };
-		00B7DEE50EDCA46500F77EA2 /* ftbbox.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECA0EDCA46500F77EA2 /* ftbbox.c */; };
-		00B7DEE60EDCA46500F77EA2 /* ftbitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECB0EDCA46500F77EA2 /* ftbitmap.c */; };
-		00B7DEE70EDCA46500F77EA2 /* ftcalc.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECC0EDCA46500F77EA2 /* ftcalc.c */; };
-		00B7DEE80EDCA46500F77EA2 /* ftdbgmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECD0EDCA46500F77EA2 /* ftdbgmem.c */; };
-		00B7DEE90EDCA46500F77EA2 /* ftdebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECE0EDCA46500F77EA2 /* ftdebug.c */; };
-		00B7DEEA0EDCA46500F77EA2 /* ftgasp.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DECF0EDCA46500F77EA2 /* ftgasp.c */; };
-		00B7DEEB0EDCA46500F77EA2 /* ftgloadr.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED00EDCA46500F77EA2 /* ftgloadr.c */; };
-		00B7DEEC0EDCA46500F77EA2 /* ftglyph.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED10EDCA46500F77EA2 /* ftglyph.c */; };
-		00B7DEED0EDCA46500F77EA2 /* ftinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED20EDCA46500F77EA2 /* ftinit.c */; };
-		00B7DEEE0EDCA46500F77EA2 /* ftlcdfil.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED30EDCA46500F77EA2 /* ftlcdfil.c */; };
-		00B7DEEF0EDCA46500F77EA2 /* ftmm.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED40EDCA46500F77EA2 /* ftmm.c */; };
-		00B7DEF00EDCA46500F77EA2 /* ftnames.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED50EDCA46500F77EA2 /* ftnames.c */; };
-		00B7DEF10EDCA46500F77EA2 /* ftobjs.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED60EDCA46500F77EA2 /* ftobjs.c */; };
-		00B7DEF20EDCA46500F77EA2 /* ftoutln.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED70EDCA46500F77EA2 /* ftoutln.c */; };
-		00B7DEF30EDCA46500F77EA2 /* ftpatent.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED80EDCA46500F77EA2 /* ftpatent.c */; };
-		00B7DEF40EDCA46500F77EA2 /* ftrfork.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DED90EDCA46500F77EA2 /* ftrfork.c */; };
-		00B7DEF50EDCA46500F77EA2 /* ftstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDA0EDCA46500F77EA2 /* ftstream.c */; };
-		00B7DEF60EDCA46500F77EA2 /* ftstroke.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDB0EDCA46500F77EA2 /* ftstroke.c */; };
-		00B7DEF70EDCA46500F77EA2 /* ftsynth.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDC0EDCA46500F77EA2 /* ftsynth.c */; };
-		00B7DEF80EDCA46500F77EA2 /* ftsystem.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDD0EDCA46500F77EA2 /* ftsystem.c */; };
-		00B7DEF90EDCA46500F77EA2 /* fttrigon.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDE0EDCA46500F77EA2 /* fttrigon.c */; };
-		00B7DEFA0EDCA46500F77EA2 /* ftutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEDF0EDCA46500F77EA2 /* ftutil.c */; };
-		00B7DEFB0EDCA46500F77EA2 /* ftwinfnt.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEE00EDCA46500F77EA2 /* ftwinfnt.c */; };
-		00B7DEFC0EDCA46500F77EA2 /* ftxf86.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEE10EDCA46500F77EA2 /* ftxf86.c */; };
-		00B7DEFE0EDCA47900F77EA2 /* raster.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEFD0EDCA47900F77EA2 /* raster.c */; };
-		00B7DF000EDCA48B00F77EA2 /* sfnt.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DEFF0EDCA48B00F77EA2 /* sfnt.c */; };
-		00B7DF020EDCA49C00F77EA2 /* smooth.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF010EDCA49C00F77EA2 /* smooth.c */; };
-		00B7DF040EDCA4AF00F77EA2 /* autofit.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF030EDCA4AF00F77EA2 /* autofit.c */; };
-		00B7DF060EDCA4BE00F77EA2 /* truetype.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF050EDCA4BE00F77EA2 /* truetype.c */; };
-		00B7DF080EDCA4CE00F77EA2 /* cff.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF070EDCA4CE00F77EA2 /* cff.c */; };
-		00B7DF0A0EDCA4DD00F77EA2 /* psaux.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF090EDCA4DD00F77EA2 /* psaux.c */; };
-		00B7DF0C0EDCA4ED00F77EA2 /* psnames.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF0B0EDCA4ED00F77EA2 /* psnames.c */; };
-		00B7DF100EDCA50100F77EA2 /* pshinter.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF0F0EDCA50100F77EA2 /* pshinter.c */; };
-		00B7DF120EDCA51600F77EA2 /* SkFontHost_FreeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF110EDCA51600F77EA2 /* SkFontHost_FreeType.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DEC70EDCA46500F77EA2 /* ftadvanc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftadvanc.c; path = ../../freetype/src/base/ftadvanc.c; sourceTree = SOURCE_ROOT; };
-		00B7DEC80EDCA46500F77EA2 /* ftapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftapi.c; path = ../../freetype/src/base/ftapi.c; sourceTree = SOURCE_ROOT; };
-		00B7DEC90EDCA46500F77EA2 /* ftbase.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftbase.c; path = ../../freetype/src/base/ftbase.c; sourceTree = SOURCE_ROOT; };
-		00B7DECA0EDCA46500F77EA2 /* ftbbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftbbox.c; path = ../../freetype/src/base/ftbbox.c; sourceTree = SOURCE_ROOT; };
-		00B7DECB0EDCA46500F77EA2 /* ftbitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftbitmap.c; path = ../../freetype/src/base/ftbitmap.c; sourceTree = SOURCE_ROOT; };
-		00B7DECC0EDCA46500F77EA2 /* ftcalc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftcalc.c; path = ../../freetype/src/base/ftcalc.c; sourceTree = SOURCE_ROOT; };
-		00B7DECD0EDCA46500F77EA2 /* ftdbgmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftdbgmem.c; path = ../../freetype/src/base/ftdbgmem.c; sourceTree = SOURCE_ROOT; };
-		00B7DECE0EDCA46500F77EA2 /* ftdebug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftdebug.c; path = ../../freetype/src/base/ftdebug.c; sourceTree = SOURCE_ROOT; };
-		00B7DECF0EDCA46500F77EA2 /* ftgasp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftgasp.c; path = ../../freetype/src/base/ftgasp.c; sourceTree = SOURCE_ROOT; };
-		00B7DED00EDCA46500F77EA2 /* ftgloadr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftgloadr.c; path = ../../freetype/src/base/ftgloadr.c; sourceTree = SOURCE_ROOT; };
-		00B7DED10EDCA46500F77EA2 /* ftglyph.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftglyph.c; path = ../../freetype/src/base/ftglyph.c; sourceTree = SOURCE_ROOT; };
-		00B7DED20EDCA46500F77EA2 /* ftinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftinit.c; path = ../../freetype/src/base/ftinit.c; sourceTree = SOURCE_ROOT; };
-		00B7DED30EDCA46500F77EA2 /* ftlcdfil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftlcdfil.c; path = ../../freetype/src/base/ftlcdfil.c; sourceTree = SOURCE_ROOT; };
-		00B7DED40EDCA46500F77EA2 /* ftmm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftmm.c; path = ../../freetype/src/base/ftmm.c; sourceTree = SOURCE_ROOT; };
-		00B7DED50EDCA46500F77EA2 /* ftnames.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftnames.c; path = ../../freetype/src/base/ftnames.c; sourceTree = SOURCE_ROOT; };
-		00B7DED60EDCA46500F77EA2 /* ftobjs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftobjs.c; path = ../../freetype/src/base/ftobjs.c; sourceTree = SOURCE_ROOT; };
-		00B7DED70EDCA46500F77EA2 /* ftoutln.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftoutln.c; path = ../../freetype/src/base/ftoutln.c; sourceTree = SOURCE_ROOT; };
-		00B7DED80EDCA46500F77EA2 /* ftpatent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftpatent.c; path = ../../freetype/src/base/ftpatent.c; sourceTree = SOURCE_ROOT; };
-		00B7DED90EDCA46500F77EA2 /* ftrfork.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftrfork.c; path = ../../freetype/src/base/ftrfork.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDA0EDCA46500F77EA2 /* ftstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftstream.c; path = ../../freetype/src/base/ftstream.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDB0EDCA46500F77EA2 /* ftstroke.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftstroke.c; path = ../../freetype/src/base/ftstroke.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDC0EDCA46500F77EA2 /* ftsynth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftsynth.c; path = ../../freetype/src/base/ftsynth.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDD0EDCA46500F77EA2 /* ftsystem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftsystem.c; path = ../../freetype/src/base/ftsystem.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDE0EDCA46500F77EA2 /* fttrigon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fttrigon.c; path = ../../freetype/src/base/fttrigon.c; sourceTree = SOURCE_ROOT; };
-		00B7DEDF0EDCA46500F77EA2 /* ftutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftutil.c; path = ../../freetype/src/base/ftutil.c; sourceTree = SOURCE_ROOT; };
-		00B7DEE00EDCA46500F77EA2 /* ftwinfnt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftwinfnt.c; path = ../../freetype/src/base/ftwinfnt.c; sourceTree = SOURCE_ROOT; };
-		00B7DEE10EDCA46500F77EA2 /* ftxf86.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ftxf86.c; path = ../../freetype/src/base/ftxf86.c; sourceTree = SOURCE_ROOT; };
-		00B7DEFD0EDCA47900F77EA2 /* raster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raster.c; path = ../../freetype/src/raster/raster.c; sourceTree = SOURCE_ROOT; };
-		00B7DEFF0EDCA48B00F77EA2 /* sfnt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sfnt.c; path = ../../freetype/src/sfnt/sfnt.c; sourceTree = SOURCE_ROOT; };
-		00B7DF010EDCA49C00F77EA2 /* smooth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smooth.c; path = ../../freetype/src/smooth/smooth.c; sourceTree = SOURCE_ROOT; };
-		00B7DF030EDCA4AF00F77EA2 /* autofit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = autofit.c; path = ../../freetype/src/autofit/autofit.c; sourceTree = SOURCE_ROOT; };
-		00B7DF050EDCA4BE00F77EA2 /* truetype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = truetype.c; path = ../../freetype/src/truetype/truetype.c; sourceTree = SOURCE_ROOT; };
-		00B7DF070EDCA4CE00F77EA2 /* cff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cff.c; path = ../../freetype/src/cff/cff.c; sourceTree = SOURCE_ROOT; };
-		00B7DF090EDCA4DD00F77EA2 /* psaux.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = psaux.c; path = ../../freetype/src/psaux/psaux.c; sourceTree = SOURCE_ROOT; };
-		00B7DF0B0EDCA4ED00F77EA2 /* psnames.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = psnames.c; path = ../../freetype/src/psnames/psnames.c; sourceTree = SOURCE_ROOT; };
-		00B7DF0F0EDCA50100F77EA2 /* pshinter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pshinter.c; path = ../../freetype/src/pshinter/pshinter.c; sourceTree = SOURCE_ROOT; };
-		00B7DF110EDCA51600F77EA2 /* SkFontHost_FreeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_FreeType.cpp; path = ../libsgl/ports/SkFontHost_FreeType.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libfreetype.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfreetype.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* freetype */ = {
-			isa = PBXGroup;
-			children = (
-				FE33C98F094E104700C4A640 /* base */,
-				FE33C990094E105100C4A640 /* raster */,
-				FE33C997094E109300C4A640 /* snft */,
-				FE33C998094E109D00C4A640 /* smooth */,
-				FE33C999094E10B000C4A640 /* autohint */,
-				FE33C99A094E10BD00C4A640 /* truetype */,
-				FE33C99B094E10C600C4A640 /* cff */,
-				FE33C99E094E10E100C4A640 /* psaux */,
-				FE33C99F094E10EB00C4A640 /* psnames */,
-				FE33C9A0094E10F400C4A640 /* pshinter */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = freetype;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF110EDCA51600F77EA2 /* SkFontHost_FreeType.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libfreetype.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-		FE33C98F094E104700C4A640 /* base */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DEC70EDCA46500F77EA2 /* ftadvanc.c */,
-				00B7DEC80EDCA46500F77EA2 /* ftapi.c */,
-				00B7DEC90EDCA46500F77EA2 /* ftbase.c */,
-				00B7DECA0EDCA46500F77EA2 /* ftbbox.c */,
-				00B7DECB0EDCA46500F77EA2 /* ftbitmap.c */,
-				00B7DECC0EDCA46500F77EA2 /* ftcalc.c */,
-				00B7DECD0EDCA46500F77EA2 /* ftdbgmem.c */,
-				00B7DECE0EDCA46500F77EA2 /* ftdebug.c */,
-				00B7DECF0EDCA46500F77EA2 /* ftgasp.c */,
-				00B7DED00EDCA46500F77EA2 /* ftgloadr.c */,
-				00B7DED10EDCA46500F77EA2 /* ftglyph.c */,
-				00B7DED20EDCA46500F77EA2 /* ftinit.c */,
-				00B7DED30EDCA46500F77EA2 /* ftlcdfil.c */,
-				00B7DED40EDCA46500F77EA2 /* ftmm.c */,
-				00B7DED50EDCA46500F77EA2 /* ftnames.c */,
-				00B7DED60EDCA46500F77EA2 /* ftobjs.c */,
-				00B7DED70EDCA46500F77EA2 /* ftoutln.c */,
-				00B7DED80EDCA46500F77EA2 /* ftpatent.c */,
-				00B7DED90EDCA46500F77EA2 /* ftrfork.c */,
-				00B7DEDA0EDCA46500F77EA2 /* ftstream.c */,
-				00B7DEDB0EDCA46500F77EA2 /* ftstroke.c */,
-				00B7DEDC0EDCA46500F77EA2 /* ftsynth.c */,
-				00B7DEDD0EDCA46500F77EA2 /* ftsystem.c */,
-				00B7DEDE0EDCA46500F77EA2 /* fttrigon.c */,
-				00B7DEDF0EDCA46500F77EA2 /* ftutil.c */,
-				00B7DEE00EDCA46500F77EA2 /* ftwinfnt.c */,
-				00B7DEE10EDCA46500F77EA2 /* ftxf86.c */,
-			);
-			name = base;
-			sourceTree = "<group>";
-		};
-		FE33C990094E105100C4A640 /* raster */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DEFD0EDCA47900F77EA2 /* raster.c */,
-			);
-			name = raster;
-			sourceTree = "<group>";
-		};
-		FE33C997094E109300C4A640 /* snft */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DEFF0EDCA48B00F77EA2 /* sfnt.c */,
-			);
-			name = snft;
-			sourceTree = "<group>";
-		};
-		FE33C998094E109D00C4A640 /* smooth */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF010EDCA49C00F77EA2 /* smooth.c */,
-			);
-			name = smooth;
-			sourceTree = "<group>";
-		};
-		FE33C999094E10B000C4A640 /* autohint */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF030EDCA4AF00F77EA2 /* autofit.c */,
-			);
-			name = autohint;
-			sourceTree = "<group>";
-		};
-		FE33C99A094E10BD00C4A640 /* truetype */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF050EDCA4BE00F77EA2 /* truetype.c */,
-			);
-			name = truetype;
-			sourceTree = "<group>";
-		};
-		FE33C99B094E10C600C4A640 /* cff */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF070EDCA4CE00F77EA2 /* cff.c */,
-			);
-			name = cff;
-			sourceTree = "<group>";
-		};
-		FE33C99E094E10E100C4A640 /* psaux */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF090EDCA4DD00F77EA2 /* psaux.c */,
-			);
-			name = psaux;
-			sourceTree = "<group>";
-		};
-		FE33C99F094E10EB00C4A640 /* psnames */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF0B0EDCA4ED00F77EA2 /* psnames.c */,
-			);
-			name = psnames;
-			sourceTree = "<group>";
-		};
-		FE33C9A0094E10F400C4A640 /* pshinter */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF0F0EDCA50100F77EA2 /* pshinter.c */,
-			);
-			name = pshinter;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* freetype */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "freetype" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = freetype;
-			productName = freetype;
-			productReference = D2AAC046055464E500DB518D /* libfreetype.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "freetype2" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* freetype */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC045055464E500DB518D /* freetype */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DEE20EDCA46500F77EA2 /* ftadvanc.c in Sources */,
-				00B7DEE30EDCA46500F77EA2 /* ftapi.c in Sources */,
-				00B7DEE40EDCA46500F77EA2 /* ftbase.c in Sources */,
-				00B7DEE50EDCA46500F77EA2 /* ftbbox.c in Sources */,
-				00B7DEE60EDCA46500F77EA2 /* ftbitmap.c in Sources */,
-				00B7DEE70EDCA46500F77EA2 /* ftcalc.c in Sources */,
-				00B7DEE80EDCA46500F77EA2 /* ftdbgmem.c in Sources */,
-				00B7DEE90EDCA46500F77EA2 /* ftdebug.c in Sources */,
-				00B7DEEA0EDCA46500F77EA2 /* ftgasp.c in Sources */,
-				00B7DEEB0EDCA46500F77EA2 /* ftgloadr.c in Sources */,
-				00B7DEEC0EDCA46500F77EA2 /* ftglyph.c in Sources */,
-				00B7DEED0EDCA46500F77EA2 /* ftinit.c in Sources */,
-				00B7DEEE0EDCA46500F77EA2 /* ftlcdfil.c in Sources */,
-				00B7DEEF0EDCA46500F77EA2 /* ftmm.c in Sources */,
-				00B7DEF00EDCA46500F77EA2 /* ftnames.c in Sources */,
-				00B7DEF10EDCA46500F77EA2 /* ftobjs.c in Sources */,
-				00B7DEF20EDCA46500F77EA2 /* ftoutln.c in Sources */,
-				00B7DEF30EDCA46500F77EA2 /* ftpatent.c in Sources */,
-				00B7DEF40EDCA46500F77EA2 /* ftrfork.c in Sources */,
-				00B7DEF50EDCA46500F77EA2 /* ftstream.c in Sources */,
-				00B7DEF60EDCA46500F77EA2 /* ftstroke.c in Sources */,
-				00B7DEF70EDCA46500F77EA2 /* ftsynth.c in Sources */,
-				00B7DEF80EDCA46500F77EA2 /* ftsystem.c in Sources */,
-				00B7DEF90EDCA46500F77EA2 /* fttrigon.c in Sources */,
-				00B7DEFA0EDCA46500F77EA2 /* ftutil.c in Sources */,
-				00B7DEFB0EDCA46500F77EA2 /* ftwinfnt.c in Sources */,
-				00B7DEFC0EDCA46500F77EA2 /* ftxf86.c in Sources */,
-				00B7DEFE0EDCA47900F77EA2 /* raster.c in Sources */,
-				00B7DF000EDCA48B00F77EA2 /* sfnt.c in Sources */,
-				00B7DF020EDCA49C00F77EA2 /* smooth.c in Sources */,
-				00B7DF040EDCA4AF00F77EA2 /* autofit.c in Sources */,
-				00B7DF060EDCA4BE00F77EA2 /* truetype.c in Sources */,
-				00B7DF080EDCA4CE00F77EA2 /* cff.c in Sources */,
-				00B7DF0A0EDCA4DD00F77EA2 /* psaux.c in Sources */,
-				00B7DF0C0EDCA4ED00F77EA2 /* psnames.c in Sources */,
-				00B7DF100EDCA50100F77EA2 /* pshinter.c in Sources */,
-				00B7DF120EDCA51600F77EA2 /* SkFontHost_FreeType.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = freetype;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = freetype;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = YES;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					TT_CONFIG_OPTION_BYTECODE_INTERPRETER,
-					FT2_BUILD_LIBRARY,
-					DARWIN_NO_CARBON,
-					SK_DEBUG,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../../freetype/include ../include/**";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = YES;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					TT_CONFIG_OPTION_BYTECODE_INTERPRETER,
-					FT2_BUILD_LIBRARY,
-					DARWIN_NO_CARBON,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../../freetype/include ../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "freetype" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "freetype2" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/gif.xcodeproj/project.pbxproj b/xcode/gif.xcodeproj/project.pbxproj
deleted file mode 100644
index 0645a35..0000000
--- a/xcode/gif.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,264 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		008CFC4D0C04B77E00FB4126 /* SkMovie_gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008CFC4C0C04B77E00FB4126 /* SkMovie_gif.cpp */; };
-		00B13BE30C0C6EFA0033F013 /* SkMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B13BE20C0C6EFA0033F013 /* SkMovie.cpp */; };
-		FE08AB3F0945EFBE0057213F /* gif_lib_private.h in Headers */ = {isa = PBXBuildFile; fileRef = FE08AB3D0945EFBE0057213F /* gif_lib_private.h */; };
-		FE08AB400945EFBE0057213F /* gif_lib.h in Headers */ = {isa = PBXBuildFile; fileRef = FE08AB3E0945EFBE0057213F /* gif_lib.h */; };
-		FE08AB440945EFEF0057213F /* dgif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = FE08AB410945EFEF0057213F /* dgif_lib.c */; };
-		FE08AB450945EFEF0057213F /* gif_err.c in Sources */ = {isa = PBXBuildFile; fileRef = FE08AB420945EFEF0057213F /* gif_err.c */; };
-		FE08AB460945EFEF0057213F /* gifalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = FE08AB430945EFEF0057213F /* gifalloc.c */; };
-		FE7B86240948E6A1001B952C /* SkImageDecoder_libgif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7B86230948E6A1001B952C /* SkImageDecoder_libgif.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		008CFC4C0C04B77E00FB4126 /* SkMovie_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie_gif.cpp; path = ../../libs/graphics/images/SkMovie_gif.cpp; sourceTree = SOURCE_ROOT; };
-		00B13BE20C0C6EFA0033F013 /* SkMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie.cpp; path = ../../libs/graphics/images/SkMovie.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libgif.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgif.a; sourceTree = BUILT_PRODUCTS_DIR; };
-		FE08AB3D0945EFBE0057213F /* gif_lib_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib_private.h; path = "../../extlibs/libgif-4.0/gif_lib_private.h"; sourceTree = SOURCE_ROOT; };
-		FE08AB3E0945EFBE0057213F /* gif_lib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib.h; path = "../../extlibs/libgif-4.0/gif_lib.h"; sourceTree = SOURCE_ROOT; };
-		FE08AB410945EFEF0057213F /* dgif_lib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dgif_lib.c; path = "../../extlibs/libgif-4.0/dgif_lib.c"; sourceTree = SOURCE_ROOT; };
-		FE08AB420945EFEF0057213F /* gif_err.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gif_err.c; path = "../../extlibs/libgif-4.0/gif_err.c"; sourceTree = SOURCE_ROOT; };
-		FE08AB430945EFEF0057213F /* gifalloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gifalloc.c; path = "../../extlibs/libgif-4.0/gifalloc.c"; sourceTree = SOURCE_ROOT; };
-		FE7B86230948E6A1001B952C /* SkImageDecoder_libgif.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libgif.cpp; path = ../../libs/graphics/images/SkImageDecoder_libgif.cpp; sourceTree = SOURCE_ROOT; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* gif */ = {
-			isa = PBXGroup;
-			children = (
-				00B13BE20C0C6EFA0033F013 /* SkMovie.cpp */,
-				FE08AB3C0945EF830057213F /* Include */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = gif;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				008CFC4C0C04B77E00FB4126 /* SkMovie_gif.cpp */,
-				FE7B86230948E6A1001B952C /* SkImageDecoder_libgif.cpp */,
-				FE08AB410945EFEF0057213F /* dgif_lib.c */,
-				FE08AB420945EFEF0057213F /* gif_err.c */,
-				FE08AB430945EFEF0057213F /* gifalloc.c */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libgif.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-		FE08AB3C0945EF830057213F /* Include */ = {
-			isa = PBXGroup;
-			children = (
-				FE08AB3D0945EFBE0057213F /* gif_lib_private.h */,
-				FE08AB3E0945EFBE0057213F /* gif_lib.h */,
-			);
-			name = Include;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FE08AB3F0945EFBE0057213F /* gif_lib_private.h in Headers */,
-				FE08AB400945EFBE0057213F /* gif_lib.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* gif */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FE5F47EB094782A50095980F /* Build configuration list for PBXNativeTarget "gif" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = gif;
-			productName = gif;
-			productReference = D2AAC046055464E500DB518D /* libgif.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = FE5F47EF094782A50095980F /* Build configuration list for PBXProject "gif" */;
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* gif */;
-			projectDirPath = "";
-			targets = (
-				D2AAC045055464E500DB518D /* gif */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FE08AB440945EFEF0057213F /* dgif_lib.c in Sources */,
-				FE08AB450945EFEF0057213F /* gif_err.c in Sources */,
-				FE08AB460945EFEF0057213F /* gifalloc.c in Sources */,
-				FE7B86240948E6A1001B952C /* SkImageDecoder_libgif.cpp in Sources */,
-				008CFC4D0C04B77E00FB4126 /* SkMovie_gif.cpp in Sources */,
-				00B13BE30C0C6EFA0033F013 /* SkMovie.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		FE5F47EC094782A50095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					_LIB,
-					SK_FORCE_SCALARFIXED,
-				);
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = ../../include/graphics;
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = gif;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		FE5F47ED094782A50095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = gif;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		FE5F47F0094782A50095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../../include/graphics ../../include/corecg";
-			};
-			name = Debug;
-		};
-		FE5F47F1094782A50095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_RELEASE;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../../include/graphics ../../include/corecg";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		FE5F47EB094782A50095980F /* Build configuration list for PBXNativeTarget "gif" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F47EC094782A50095980F /* Debug */,
-				FE5F47ED094782A50095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-		FE5F47EF094782A50095980F /* Build configuration list for PBXProject "gif" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F47F0094782A50095980F /* Debug */,
-				FE5F47F1094782A50095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/giflib.xcodeproj/project.pbxproj b/xcode/giflib.xcodeproj/project.pbxproj
deleted file mode 100644
index 6c289a3..0000000
--- a/xcode/giflib.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,235 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 44;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7DCD40EDCA06600F77EA2 /* SkImageDecoder_libgif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD10EDCA06600F77EA2 /* SkImageDecoder_libgif.cpp */; };
-		00B7DCD50EDCA06600F77EA2 /* SkMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD20EDCA06600F77EA2 /* SkMovie.cpp */; };
-		00B7DCD60EDCA06600F77EA2 /* SkMovie_gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD30EDCA06600F77EA2 /* SkMovie_gif.cpp */; };
-		00B7DCDA0EDCA07F00F77EA2 /* dgif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD70EDCA07F00F77EA2 /* dgif_lib.c */; };
-		00B7DCDB0EDCA07F00F77EA2 /* gif_err.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD80EDCA07F00F77EA2 /* gif_err.c */; };
-		00B7DCDC0EDCA07F00F77EA2 /* gifalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DCD90EDCA07F00F77EA2 /* gifalloc.c */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7DCD10EDCA06600F77EA2 /* SkImageDecoder_libgif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libgif.cpp; path = ../libsgl/images/SkImageDecoder_libgif.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCD20EDCA06600F77EA2 /* SkMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie.cpp; path = ../libsgl/images/SkMovie.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCD30EDCA06600F77EA2 /* SkMovie_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie_gif.cpp; path = ../libsgl/images/SkMovie_gif.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DCD70EDCA07F00F77EA2 /* dgif_lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dgif_lib.c; path = ../../giflib/dgif_lib.c; sourceTree = SOURCE_ROOT; };
-		00B7DCD80EDCA07F00F77EA2 /* gif_err.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gif_err.c; path = ../../giflib/gif_err.c; sourceTree = SOURCE_ROOT; };
-		00B7DCD90EDCA07F00F77EA2 /* gifalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gifalloc.c; path = ../../giflib/gifalloc.c; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libgiflib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgiflib.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* giflib */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DCD10EDCA06600F77EA2 /* SkImageDecoder_libgif.cpp */,
-				00B7DCD20EDCA06600F77EA2 /* SkMovie.cpp */,
-				00B7DCD30EDCA06600F77EA2 /* SkMovie_gif.cpp */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = giflib;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DCD70EDCA07F00F77EA2 /* dgif_lib.c */,
-				00B7DCD80EDCA07F00F77EA2 /* gif_err.c */,
-				00B7DCD90EDCA07F00F77EA2 /* gifalloc.c */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libgiflib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* giflib */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "giflib" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = giflib;
-			productName = giflib;
-			productReference = D2AAC046055464E500DB518D /* libgiflib.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "giflib" */;
-			compatibilityVersion = "Xcode 3.0";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* giflib */;
-			projectDirPath = "";
-			projectRoot = "";
-			targets = (
-				D2AAC045055464E500DB518D /* giflib */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DCD40EDCA06600F77EA2 /* SkImageDecoder_libgif.cpp in Sources */,
-				00B7DCD50EDCA06600F77EA2 /* SkMovie.cpp in Sources */,
-				00B7DCD60EDCA06600F77EA2 /* SkMovie_gif.cpp in Sources */,
-				00B7DCDA0EDCA07F00F77EA2 /* dgif_lib.c in Sources */,
-				00B7DCDB0EDCA07F00F77EA2 /* gif_err.c in Sources */,
-				00B7DCDC0EDCA07F00F77EA2 /* gifalloc.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = giflib;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = giflib;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					HAVE_CONFIG_H,
-					SK_DEBUG,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../include/graphics ../include/corecg";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = (
-					ppc,
-					i386,
-				);
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					HAVE_CONFIG_H,
-					SK_RELEASE,
-				);
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../include/graphics ../include/corecg";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "giflib" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "giflib" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/graphics.xcodeproj/project.pbxproj b/xcode/graphics.xcodeproj/project.pbxproj
deleted file mode 100644
index e64247c..0000000
--- a/xcode/graphics.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,843 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 44;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		006B43940EF73CFC00F15BC4 /* SkString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 006B43930EF73CFC00F15BC4 /* SkString.cpp */; };
-		006B43AE0EF7444A00F15BC4 /* SkUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 006B43AD0EF7444A00F15BC4 /* SkUtils.cpp */; };
-		00B7DF260EDCA56700F77EA2 /* SkPathHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF1D0EDCA56700F77EA2 /* SkPathHeap.cpp */; };
-		00B7DF270EDCA56700F77EA2 /* SkPathHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF1E0EDCA56700F77EA2 /* SkPathHeap.h */; };
-		00B7DF280EDCA56700F77EA2 /* SkPicture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF1F0EDCA56700F77EA2 /* SkPicture.cpp */; };
-		00B7DF290EDCA56700F77EA2 /* SkPictureFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF200EDCA56700F77EA2 /* SkPictureFlat.cpp */; };
-		00B7DF2A0EDCA56700F77EA2 /* SkPictureFlat.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF210EDCA56700F77EA2 /* SkPictureFlat.h */; };
-		00B7DF2B0EDCA56700F77EA2 /* SkPicturePlayback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF220EDCA56700F77EA2 /* SkPicturePlayback.cpp */; };
-		00B7DF2C0EDCA56700F77EA2 /* SkPicturePlayback.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF230EDCA56700F77EA2 /* SkPicturePlayback.h */; };
-		00B7DF2D0EDCA56700F77EA2 /* SkPictureRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF240EDCA56700F77EA2 /* SkPictureRecord.cpp */; };
-		00B7DF2E0EDCA56700F77EA2 /* SkPictureRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF250EDCA56700F77EA2 /* SkPictureRecord.h */; };
-		00B7DF4E0EDCA57800F77EA2 /* Sk1DPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF2F0EDCA57800F77EA2 /* Sk1DPathEffect.cpp */; };
-		00B7DF4F0EDCA57800F77EA2 /* Sk2DPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF300EDCA57800F77EA2 /* Sk2DPathEffect.cpp */; };
-		00B7DF500EDCA57800F77EA2 /* SkAvoidXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF310EDCA57800F77EA2 /* SkAvoidXfermode.cpp */; };
-		00B7DF510EDCA57800F77EA2 /* SkBlurDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF320EDCA57800F77EA2 /* SkBlurDrawLooper.cpp */; };
-		00B7DF520EDCA57800F77EA2 /* SkBlurMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF330EDCA57800F77EA2 /* SkBlurMask.cpp */; };
-		00B7DF530EDCA57800F77EA2 /* SkBlurMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF340EDCA57800F77EA2 /* SkBlurMask.h */; };
-		00B7DF540EDCA57800F77EA2 /* SkBlurMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF350EDCA57800F77EA2 /* SkBlurMaskFilter.cpp */; };
-		00B7DF550EDCA57800F77EA2 /* SkCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF360EDCA57800F77EA2 /* SkCamera.cpp */; };
-		00B7DF560EDCA57800F77EA2 /* SkColorFilters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF370EDCA57800F77EA2 /* SkColorFilters.cpp */; };
-		00B7DF570EDCA57800F77EA2 /* SkColorMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF380EDCA57800F77EA2 /* SkColorMatrix.cpp */; };
-		00B7DF580EDCA57800F77EA2 /* SkColorMatrixFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF390EDCA57800F77EA2 /* SkColorMatrixFilter.cpp */; };
-		00B7DF590EDCA57800F77EA2 /* SkCornerPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF3A0EDCA57800F77EA2 /* SkCornerPathEffect.cpp */; };
-		00B7DF5A0EDCA57800F77EA2 /* SkCullPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF3B0EDCA57800F77EA2 /* SkCullPoints.cpp */; };
-		00B7DF5B0EDCA57800F77EA2 /* SkDashPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF3C0EDCA57800F77EA2 /* SkDashPathEffect.cpp */; };
-		00B7DF5C0EDCA57800F77EA2 /* SkDiscretePathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF3D0EDCA57800F77EA2 /* SkDiscretePathEffect.cpp */; };
-		00B7DF5D0EDCA57800F77EA2 /* SkEmbossMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF3E0EDCA57800F77EA2 /* SkEmbossMask.cpp */; };
-		00B7DF5E0EDCA57800F77EA2 /* SkEmbossMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF3F0EDCA57800F77EA2 /* SkEmbossMask.h */; };
-		00B7DF5F0EDCA57800F77EA2 /* SkEmbossMask_Table.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF400EDCA57800F77EA2 /* SkEmbossMask_Table.h */; };
-		00B7DF600EDCA57800F77EA2 /* SkEmbossMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF410EDCA57800F77EA2 /* SkEmbossMaskFilter.cpp */; };
-		00B7DF610EDCA57800F77EA2 /* SkGradientShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF420EDCA57800F77EA2 /* SkGradientShader.cpp */; };
-		00B7DF620EDCA57800F77EA2 /* SkKernel33MaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF430EDCA57800F77EA2 /* SkKernel33MaskFilter.cpp */; };
-		00B7DF630EDCA57800F77EA2 /* SkLayerDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF440EDCA57800F77EA2 /* SkLayerDrawLooper.cpp */; };
-		00B7DF640EDCA57800F77EA2 /* SkLayerRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF450EDCA57800F77EA2 /* SkLayerRasterizer.cpp */; };
-		00B7DF650EDCA57800F77EA2 /* SkNinePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF460EDCA57800F77EA2 /* SkNinePatch.cpp */; };
-		00B7DF660EDCA57800F77EA2 /* SkPaintFlagsDrawFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF470EDCA57800F77EA2 /* SkPaintFlagsDrawFilter.cpp */; };
-		00B7DF670EDCA57800F77EA2 /* SkPixelXorXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF480EDCA57800F77EA2 /* SkPixelXorXfermode.cpp */; };
-		00B7DF680EDCA57800F77EA2 /* SkProxyCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF490EDCA57800F77EA2 /* SkProxyCanvas.cpp */; };
-		00B7DF690EDCA57800F77EA2 /* SkRadialGradient_Table.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF4A0EDCA57800F77EA2 /* SkRadialGradient_Table.h */; };
-		00B7DF6A0EDCA57800F77EA2 /* SkShaderExtras.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF4B0EDCA57800F77EA2 /* SkShaderExtras.cpp */; };
-		00B7DF6B0EDCA57800F77EA2 /* SkTransparentShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF4C0EDCA57800F77EA2 /* SkTransparentShader.cpp */; };
-		00B7DF6C0EDCA57800F77EA2 /* SkUnitMappers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF4D0EDCA57800F77EA2 /* SkUnitMappers.cpp */; };
-		00B7DF8E0EDCA59200F77EA2 /* SkFDStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF730EDCA59200F77EA2 /* SkFDStream.cpp */; };
-		00B7DF8F0EDCA59200F77EA2 /* SkFlipPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF740EDCA59200F77EA2 /* SkFlipPixelRef.cpp */; };
-		00B7DF900EDCA59200F77EA2 /* SkImageDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF750EDCA59200F77EA2 /* SkImageDecoder.cpp */; };
-		00B7DF990EDCA59200F77EA2 /* SkImageRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF7E0EDCA59200F77EA2 /* SkImageRef.cpp */; };
-		00B7DF9A0EDCA59200F77EA2 /* SkImageRef_GlobalPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF7F0EDCA59200F77EA2 /* SkImageRef_GlobalPool.cpp */; };
-		00B7DF9B0EDCA59200F77EA2 /* SkImageRefPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF800EDCA59200F77EA2 /* SkImageRefPool.cpp */; };
-		00B7DF9D0EDCA59200F77EA2 /* SkMMapStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF820EDCA59200F77EA2 /* SkMMapStream.cpp */; };
-		00B7DFA00EDCA59200F77EA2 /* SkScaledBitmapSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF850EDCA59200F77EA2 /* SkScaledBitmapSampler.cpp */; };
-		00B7DFA10EDCA59200F77EA2 /* SkScaledBitmapSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DF860EDCA59200F77EA2 /* SkScaledBitmapSampler.h */; };
-		00B7DFA20EDCA59200F77EA2 /* SkStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DF870EDCA59200F77EA2 /* SkStream.cpp */; };
-		00B7DFAD0EDCA60D00F77EA2 /* SkBML_Verbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFA30EDCA60D00F77EA2 /* SkBML_Verbs.h */; };
-		00B7DFAE0EDCA60D00F77EA2 /* SkBML_XMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFA40EDCA60D00F77EA2 /* SkBML_XMLParser.cpp */; };
-		00B7DFAF0EDCA60D00F77EA2 /* SkDOM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFA50EDCA60D00F77EA2 /* SkDOM.cpp */; };
-		00B7DFB20EDCA60D00F77EA2 /* SkParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFA80EDCA60D00F77EA2 /* SkParse.cpp */; };
-		00B7DFB30EDCA60D00F77EA2 /* SkParseColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFA90EDCA60D00F77EA2 /* SkParseColor.cpp */; };
-		00B7DFB40EDCA60D00F77EA2 /* SkXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFAA0EDCA60D00F77EA2 /* SkXMLParser.cpp */; };
-		00B7DFB60EDCA60D00F77EA2 /* SkXMLWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFAC0EDCA60D00F77EA2 /* SkXMLWriter.cpp */; };
-		00B7E0120EDCA64500F77EA2 /* SkAlphaRuns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFB70EDCA64500F77EA2 /* SkAlphaRuns.cpp */; };
-		00B7E0130EDCA64500F77EA2 /* SkAntiRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFB80EDCA64500F77EA2 /* SkAntiRun.h */; };
-		00B7E0140EDCA64500F77EA2 /* SkAutoKern.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFB90EDCA64500F77EA2 /* SkAutoKern.h */; };
-		00B7E0150EDCA64500F77EA2 /* SkBitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFBA0EDCA64500F77EA2 /* SkBitmap.cpp */; };
-		00B7E0160EDCA64500F77EA2 /* SkBitmap_scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFBB0EDCA64500F77EA2 /* SkBitmap_scroll.cpp */; };
-		00B7E0170EDCA64500F77EA2 /* SkBitmapProcShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFBC0EDCA64500F77EA2 /* SkBitmapProcShader.cpp */; };
-		00B7E0180EDCA64500F77EA2 /* SkBitmapProcShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFBD0EDCA64500F77EA2 /* SkBitmapProcShader.h */; };
-		00B7E0190EDCA64500F77EA2 /* SkBitmapProcState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFBE0EDCA64500F77EA2 /* SkBitmapProcState.cpp */; };
-		00B7E01A0EDCA64500F77EA2 /* SkBitmapProcState.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFBF0EDCA64500F77EA2 /* SkBitmapProcState.h */; };
-		00B7E01B0EDCA64500F77EA2 /* SkBitmapProcState_matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC00EDCA64500F77EA2 /* SkBitmapProcState_matrix.h */; };
-		00B7E01C0EDCA64500F77EA2 /* SkBitmapProcState_matrixProcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFC10EDCA64500F77EA2 /* SkBitmapProcState_matrixProcs.cpp */; };
-		00B7E01D0EDCA64500F77EA2 /* SkBitmapProcState_sample.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC20EDCA64500F77EA2 /* SkBitmapProcState_sample.h */; };
-		00B7E01E0EDCA64500F77EA2 /* SkBitmapSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFC30EDCA64500F77EA2 /* SkBitmapSampler.cpp */; };
-		00B7E01F0EDCA64500F77EA2 /* SkBitmapSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC40EDCA64500F77EA2 /* SkBitmapSampler.h */; };
-		00B7E0200EDCA64500F77EA2 /* SkBitmapSamplerTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC50EDCA64500F77EA2 /* SkBitmapSamplerTemplate.h */; };
-		00B7E0210EDCA64500F77EA2 /* SkBitmapShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFC60EDCA64500F77EA2 /* SkBitmapShader.cpp */; };
-		00B7E0220EDCA64500F77EA2 /* SkBitmapShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC70EDCA64500F77EA2 /* SkBitmapShader.h */; };
-		00B7E0230EDCA64500F77EA2 /* SkBitmapShader16BilerpTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC80EDCA64500F77EA2 /* SkBitmapShader16BilerpTemplate.h */; };
-		00B7E0240EDCA64500F77EA2 /* SkBitmapShaderTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFC90EDCA64500F77EA2 /* SkBitmapShaderTemplate.h */; };
-		00B7E0250EDCA64500F77EA2 /* SkBlitBWMaskTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFCA0EDCA64500F77EA2 /* SkBlitBWMaskTemplate.h */; };
-		00B7E0260EDCA64500F77EA2 /* SkBlitRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFCB0EDCA64500F77EA2 /* SkBlitRow.h */; };
-		00B7E0270EDCA64500F77EA2 /* SkBlitRow_D16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFCC0EDCA64500F77EA2 /* SkBlitRow_D16.cpp */; };
-		00B7E0280EDCA64500F77EA2 /* SkBlitRow_D4444.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFCD0EDCA64500F77EA2 /* SkBlitRow_D4444.cpp */; };
-		00B7E0290EDCA64500F77EA2 /* SkBlitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFCE0EDCA64500F77EA2 /* SkBlitter.cpp */; };
-		00B7E02A0EDCA64500F77EA2 /* SkBlitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFCF0EDCA64500F77EA2 /* SkBlitter.h */; };
-		00B7E02B0EDCA64500F77EA2 /* SkBlitter_4444.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD00EDCA64500F77EA2 /* SkBlitter_4444.cpp */; };
-		00B7E02C0EDCA64500F77EA2 /* SkBlitter_A1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD10EDCA64500F77EA2 /* SkBlitter_A1.cpp */; };
-		00B7E02D0EDCA64500F77EA2 /* SkBlitter_A8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD20EDCA64500F77EA2 /* SkBlitter_A8.cpp */; };
-		00B7E02E0EDCA64500F77EA2 /* SkBlitter_ARGB32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD30EDCA64500F77EA2 /* SkBlitter_ARGB32.cpp */; };
-		00B7E02F0EDCA64500F77EA2 /* SkBlitter_RGB16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD40EDCA64500F77EA2 /* SkBlitter_RGB16.cpp */; };
-		00B7E0300EDCA64500F77EA2 /* SkBlitter_Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD50EDCA64500F77EA2 /* SkBlitter_Sprite.cpp */; };
-		00B7E0310EDCA64500F77EA2 /* SkCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD60EDCA64500F77EA2 /* SkCanvas.cpp */; };
-		00B7E0320EDCA64500F77EA2 /* SkColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD70EDCA64500F77EA2 /* SkColor.cpp */; };
-		00B7E0330EDCA64500F77EA2 /* SkColorFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD80EDCA64500F77EA2 /* SkColorFilter.cpp */; };
-		00B7E0340EDCA64500F77EA2 /* SkColorTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFD90EDCA64500F77EA2 /* SkColorTable.cpp */; };
-		00B7E0350EDCA64500F77EA2 /* SkCoreBlitters.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFDA0EDCA64500F77EA2 /* SkCoreBlitters.h */; };
-		00B7E0360EDCA64500F77EA2 /* SkDeque.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFDB0EDCA64500F77EA2 /* SkDeque.cpp */; };
-		00B7E0370EDCA64500F77EA2 /* SkDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFDC0EDCA64500F77EA2 /* SkDevice.cpp */; };
-		00B7E0380EDCA64500F77EA2 /* SkDither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFDD0EDCA64500F77EA2 /* SkDither.cpp */; };
-		00B7E0390EDCA64500F77EA2 /* SkDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFDE0EDCA64500F77EA2 /* SkDraw.cpp */; };
-		00B7E03A0EDCA64500F77EA2 /* SkDrawProcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFDF0EDCA64500F77EA2 /* SkDrawProcs.h */; };
-		00B7E03B0EDCA64500F77EA2 /* SkEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE00EDCA64500F77EA2 /* SkEdge.cpp */; };
-		00B7E03C0EDCA64500F77EA2 /* SkEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFE10EDCA64500F77EA2 /* SkEdge.h */; };
-		00B7E03D0EDCA64500F77EA2 /* SkFilterProc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE20EDCA64500F77EA2 /* SkFilterProc.cpp */; };
-		00B7E03E0EDCA64500F77EA2 /* SkFilterProc.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFE30EDCA64500F77EA2 /* SkFilterProc.h */; };
-		00B7E03F0EDCA64500F77EA2 /* SkFlattenable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE40EDCA64500F77EA2 /* SkFlattenable.cpp */; };
-		00B7E0400EDCA64500F77EA2 /* SkFP.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFE50EDCA64500F77EA2 /* SkFP.h */; };
-		00B7E0410EDCA64500F77EA2 /* SkGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE60EDCA64500F77EA2 /* SkGeometry.cpp */; };
-		00B7E0420EDCA64500F77EA2 /* SkGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFE70EDCA64500F77EA2 /* SkGeometry.h */; };
-		00B7E0430EDCA64500F77EA2 /* SkGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE80EDCA64500F77EA2 /* SkGlobals.cpp */; };
-		00B7E0440EDCA64500F77EA2 /* SkGlyphCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFE90EDCA64500F77EA2 /* SkGlyphCache.cpp */; };
-		00B7E0450EDCA64500F77EA2 /* SkGlyphCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFEA0EDCA64500F77EA2 /* SkGlyphCache.h */; };
-		00B7E0460EDCA64500F77EA2 /* SkGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFEB0EDCA64500F77EA2 /* SkGraphics.cpp */; };
-		00B7E0470EDCA64500F77EA2 /* SkMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFEC0EDCA64500F77EA2 /* SkMask.cpp */; };
-		00B7E0480EDCA64500F77EA2 /* SkMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFED0EDCA64500F77EA2 /* SkMaskFilter.cpp */; };
-		00B7E0490EDCA64500F77EA2 /* SkPackBits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFEE0EDCA64500F77EA2 /* SkPackBits.cpp */; };
-		00B7E04A0EDCA64500F77EA2 /* SkPaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFEF0EDCA64500F77EA2 /* SkPaint.cpp */; };
-		00B7E04B0EDCA64500F77EA2 /* SkPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF00EDCA64500F77EA2 /* SkPath.cpp */; };
-		00B7E04C0EDCA64500F77EA2 /* SkPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF10EDCA64500F77EA2 /* SkPathEffect.cpp */; };
-		00B7E04D0EDCA64500F77EA2 /* SkPathMeasure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF20EDCA64500F77EA2 /* SkPathMeasure.cpp */; };
-		00B7E04E0EDCA64500F77EA2 /* SkPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF30EDCA64500F77EA2 /* SkPixelRef.cpp */; };
-		00B7E04F0EDCA64500F77EA2 /* SkProcSpriteBlitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF40EDCA64500F77EA2 /* SkProcSpriteBlitter.cpp */; };
-		00B7E0500EDCA64500F77EA2 /* SkPtrRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF50EDCA64500F77EA2 /* SkPtrRecorder.cpp */; };
-		00B7E0510EDCA64500F77EA2 /* SkRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF60EDCA64500F77EA2 /* SkRasterizer.cpp */; };
-		00B7E0520EDCA64500F77EA2 /* SkRefCnt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF70EDCA64500F77EA2 /* SkRefCnt.cpp */; };
-		00B7E0530EDCA64500F77EA2 /* SkRegion_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF80EDCA64500F77EA2 /* SkRegion_path.cpp */; };
-		00B7E0540EDCA64500F77EA2 /* SkScalerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFF90EDCA64500F77EA2 /* SkScalerContext.cpp */; };
-		00B7E0550EDCA64500F77EA2 /* SkScan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFFA0EDCA64500F77EA2 /* SkScan.cpp */; };
-		00B7E0560EDCA64500F77EA2 /* SkScan.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7DFFB0EDCA64500F77EA2 /* SkScan.h */; };
-		00B7E0570EDCA64500F77EA2 /* SkScan_Antihair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFFC0EDCA64500F77EA2 /* SkScan_Antihair.cpp */; };
-		00B7E0580EDCA64500F77EA2 /* SkScan_AntiPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFFD0EDCA64500F77EA2 /* SkScan_AntiPath.cpp */; };
-		00B7E0590EDCA64500F77EA2 /* SkScan_Hairline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFFE0EDCA64500F77EA2 /* SkScan_Hairline.cpp */; };
-		00B7E05A0EDCA64500F77EA2 /* SkScan_Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7DFFF0EDCA64500F77EA2 /* SkScan_Path.cpp */; };
-		00B7E05B0EDCA64500F77EA2 /* SkScanPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E0000EDCA64500F77EA2 /* SkScanPriv.h */; };
-		00B7E05C0EDCA64500F77EA2 /* SkShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0010EDCA64500F77EA2 /* SkShader.cpp */; };
-		00B7E05D0EDCA64500F77EA2 /* SkSpriteBlitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E0020EDCA64500F77EA2 /* SkSpriteBlitter.h */; };
-		00B7E05E0EDCA64500F77EA2 /* SkSpriteBlitter_ARGB32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0030EDCA64500F77EA2 /* SkSpriteBlitter_ARGB32.cpp */; };
-		00B7E05F0EDCA64500F77EA2 /* SkSpriteBlitter_RGB16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0040EDCA64500F77EA2 /* SkSpriteBlitter_RGB16.cpp */; };
-		00B7E0600EDCA64500F77EA2 /* SkSpriteBlitterTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E0050EDCA64500F77EA2 /* SkSpriteBlitterTemplate.h */; };
-		00B7E0620EDCA64500F77EA2 /* SkStroke.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0070EDCA64500F77EA2 /* SkStroke.cpp */; };
-		00B7E0630EDCA64500F77EA2 /* SkStrokerPriv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0080EDCA64500F77EA2 /* SkStrokerPriv.cpp */; };
-		00B7E0640EDCA64500F77EA2 /* SkStrokerPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E0090EDCA64500F77EA2 /* SkStrokerPriv.h */; };
-		00B7E0650EDCA64500F77EA2 /* SkTemplatesPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E00A0EDCA64500F77EA2 /* SkTemplatesPriv.h */; };
-		00B7E0660EDCA64500F77EA2 /* SkTSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E00B0EDCA64500F77EA2 /* SkTSearch.cpp */; };
-		00B7E0670EDCA64500F77EA2 /* SkTSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E00C0EDCA64500F77EA2 /* SkTSort.h */; };
-		00B7E0680EDCA64500F77EA2 /* SkTypeface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E00D0EDCA64500F77EA2 /* SkTypeface.cpp */; };
-		00B7E0690EDCA64500F77EA2 /* SkUnPreMultiply.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E00E0EDCA64500F77EA2 /* SkUnPreMultiply.cpp */; };
-		00B7E06B0EDCA64500F77EA2 /* SkWriter32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0100EDCA64500F77EA2 /* SkWriter32.cpp */; };
-		00B7E06C0EDCA64500F77EA2 /* SkXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0110EDCA64500F77EA2 /* SkXfermode.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		006B43930EF73CFC00F15BC4 /* SkString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkString.cpp; path = ../libcorecg/SkString.cpp; sourceTree = SOURCE_ROOT; };
-		006B43AD0EF7444A00F15BC4 /* SkUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUtils.cpp; path = ../libcorecg/SkUtils.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF1D0EDCA56700F77EA2 /* SkPathHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathHeap.cpp; path = ../libsgl/picture/SkPathHeap.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF1E0EDCA56700F77EA2 /* SkPathHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPathHeap.h; path = ../libsgl/picture/SkPathHeap.h; sourceTree = SOURCE_ROOT; };
-		00B7DF1F0EDCA56700F77EA2 /* SkPicture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPicture.cpp; path = ../libsgl/picture/SkPicture.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF200EDCA56700F77EA2 /* SkPictureFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPictureFlat.cpp; path = ../libsgl/picture/SkPictureFlat.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF210EDCA56700F77EA2 /* SkPictureFlat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPictureFlat.h; path = ../libsgl/picture/SkPictureFlat.h; sourceTree = SOURCE_ROOT; };
-		00B7DF220EDCA56700F77EA2 /* SkPicturePlayback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPicturePlayback.cpp; path = ../libsgl/picture/SkPicturePlayback.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF230EDCA56700F77EA2 /* SkPicturePlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPicturePlayback.h; path = ../libsgl/picture/SkPicturePlayback.h; sourceTree = SOURCE_ROOT; };
-		00B7DF240EDCA56700F77EA2 /* SkPictureRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPictureRecord.cpp; path = ../libsgl/picture/SkPictureRecord.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF250EDCA56700F77EA2 /* SkPictureRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPictureRecord.h; path = ../libsgl/picture/SkPictureRecord.h; sourceTree = SOURCE_ROOT; };
-		00B7DF2F0EDCA57800F77EA2 /* Sk1DPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk1DPathEffect.cpp; path = ../libsgl/effects/Sk1DPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF300EDCA57800F77EA2 /* Sk2DPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk2DPathEffect.cpp; path = ../libsgl/effects/Sk2DPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF310EDCA57800F77EA2 /* SkAvoidXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAvoidXfermode.cpp; path = ../libsgl/effects/SkAvoidXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF320EDCA57800F77EA2 /* SkBlurDrawLooper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurDrawLooper.cpp; path = ../libsgl/effects/SkBlurDrawLooper.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF330EDCA57800F77EA2 /* SkBlurMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurMask.cpp; path = ../libsgl/effects/SkBlurMask.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF340EDCA57800F77EA2 /* SkBlurMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlurMask.h; path = ../libsgl/effects/SkBlurMask.h; sourceTree = SOURCE_ROOT; };
-		00B7DF350EDCA57800F77EA2 /* SkBlurMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurMaskFilter.cpp; path = ../libsgl/effects/SkBlurMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF360EDCA57800F77EA2 /* SkCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCamera.cpp; path = ../libsgl/effects/SkCamera.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF370EDCA57800F77EA2 /* SkColorFilters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorFilters.cpp; path = ../libsgl/effects/SkColorFilters.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF380EDCA57800F77EA2 /* SkColorMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorMatrix.cpp; path = ../libsgl/effects/SkColorMatrix.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF390EDCA57800F77EA2 /* SkColorMatrixFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorMatrixFilter.cpp; path = ../libsgl/effects/SkColorMatrixFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3A0EDCA57800F77EA2 /* SkCornerPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCornerPathEffect.cpp; path = ../libsgl/effects/SkCornerPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3B0EDCA57800F77EA2 /* SkCullPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCullPoints.cpp; path = ../libsgl/effects/SkCullPoints.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3C0EDCA57800F77EA2 /* SkDashPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDashPathEffect.cpp; path = ../libsgl/effects/SkDashPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3D0EDCA57800F77EA2 /* SkDiscretePathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDiscretePathEffect.cpp; path = ../libsgl/effects/SkDiscretePathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3E0EDCA57800F77EA2 /* SkEmbossMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEmbossMask.cpp; path = ../libsgl/effects/SkEmbossMask.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF3F0EDCA57800F77EA2 /* SkEmbossMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEmbossMask.h; path = ../libsgl/effects/SkEmbossMask.h; sourceTree = SOURCE_ROOT; };
-		00B7DF400EDCA57800F77EA2 /* SkEmbossMask_Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEmbossMask_Table.h; path = ../libsgl/effects/SkEmbossMask_Table.h; sourceTree = SOURCE_ROOT; };
-		00B7DF410EDCA57800F77EA2 /* SkEmbossMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEmbossMaskFilter.cpp; path = ../libsgl/effects/SkEmbossMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF420EDCA57800F77EA2 /* SkGradientShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGradientShader.cpp; path = ../libsgl/effects/SkGradientShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF430EDCA57800F77EA2 /* SkKernel33MaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkKernel33MaskFilter.cpp; path = ../libsgl/effects/SkKernel33MaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF440EDCA57800F77EA2 /* SkLayerDrawLooper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLayerDrawLooper.cpp; path = ../libsgl/effects/SkLayerDrawLooper.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF450EDCA57800F77EA2 /* SkLayerRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLayerRasterizer.cpp; path = ../libsgl/effects/SkLayerRasterizer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF460EDCA57800F77EA2 /* SkNinePatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkNinePatch.cpp; path = ../libsgl/effects/SkNinePatch.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF470EDCA57800F77EA2 /* SkPaintFlagsDrawFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPaintFlagsDrawFilter.cpp; path = ../libsgl/effects/SkPaintFlagsDrawFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF480EDCA57800F77EA2 /* SkPixelXorXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPixelXorXfermode.cpp; path = ../libsgl/effects/SkPixelXorXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF490EDCA57800F77EA2 /* SkProxyCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProxyCanvas.cpp; path = ../libsgl/effects/SkProxyCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF4A0EDCA57800F77EA2 /* SkRadialGradient_Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkRadialGradient_Table.h; path = ../libsgl/effects/SkRadialGradient_Table.h; sourceTree = SOURCE_ROOT; };
-		00B7DF4B0EDCA57800F77EA2 /* SkShaderExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkShaderExtras.cpp; path = ../libsgl/effects/SkShaderExtras.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF4C0EDCA57800F77EA2 /* SkTransparentShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTransparentShader.cpp; path = ../libsgl/effects/SkTransparentShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF4D0EDCA57800F77EA2 /* SkUnitMappers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUnitMappers.cpp; path = ../libsgl/effects/SkUnitMappers.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF730EDCA59200F77EA2 /* SkFDStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFDStream.cpp; path = ../libsgl/images/SkFDStream.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF740EDCA59200F77EA2 /* SkFlipPixelRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFlipPixelRef.cpp; path = ../libsgl/images/SkFlipPixelRef.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF750EDCA59200F77EA2 /* SkImageDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder.cpp; path = ../libsgl/images/SkImageDecoder.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF7E0EDCA59200F77EA2 /* SkImageRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRef.cpp; path = ../libsgl/images/SkImageRef.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF7F0EDCA59200F77EA2 /* SkImageRef_GlobalPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRef_GlobalPool.cpp; path = ../libsgl/images/SkImageRef_GlobalPool.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF800EDCA59200F77EA2 /* SkImageRefPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRefPool.cpp; path = ../libsgl/images/SkImageRefPool.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF820EDCA59200F77EA2 /* SkMMapStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMMapStream.cpp; path = ../libsgl/images/SkMMapStream.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF850EDCA59200F77EA2 /* SkScaledBitmapSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScaledBitmapSampler.cpp; path = ../libsgl/images/SkScaledBitmapSampler.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DF860EDCA59200F77EA2 /* SkScaledBitmapSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScaledBitmapSampler.h; path = ../libsgl/images/SkScaledBitmapSampler.h; sourceTree = SOURCE_ROOT; };
-		00B7DF870EDCA59200F77EA2 /* SkStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStream.cpp; path = ../libsgl/images/SkStream.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFA30EDCA60D00F77EA2 /* SkBML_Verbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBML_Verbs.h; path = ../libsgl/xml/SkBML_Verbs.h; sourceTree = SOURCE_ROOT; };
-		00B7DFA40EDCA60D00F77EA2 /* SkBML_XMLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBML_XMLParser.cpp; path = ../libsgl/xml/SkBML_XMLParser.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFA50EDCA60D00F77EA2 /* SkDOM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDOM.cpp; path = ../libsgl/xml/SkDOM.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFA80EDCA60D00F77EA2 /* SkParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParse.cpp; path = ../libsgl/xml/SkParse.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFA90EDCA60D00F77EA2 /* SkParseColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParseColor.cpp; path = ../libsgl/xml/SkParseColor.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFAA0EDCA60D00F77EA2 /* SkXMLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLParser.cpp; path = ../libsgl/xml/SkXMLParser.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFAC0EDCA60D00F77EA2 /* SkXMLWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLWriter.cpp; path = ../libsgl/xml/SkXMLWriter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFB70EDCA64500F77EA2 /* SkAlphaRuns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAlphaRuns.cpp; path = ../libsgl/sgl/SkAlphaRuns.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFB80EDCA64500F77EA2 /* SkAntiRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAntiRun.h; path = ../libsgl/sgl/SkAntiRun.h; sourceTree = SOURCE_ROOT; };
-		00B7DFB90EDCA64500F77EA2 /* SkAutoKern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAutoKern.h; path = ../libsgl/sgl/SkAutoKern.h; sourceTree = SOURCE_ROOT; };
-		00B7DFBA0EDCA64500F77EA2 /* SkBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap.cpp; path = ../libsgl/sgl/SkBitmap.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFBB0EDCA64500F77EA2 /* SkBitmap_scroll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap_scroll.cpp; path = ../libsgl/sgl/SkBitmap_scroll.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFBC0EDCA64500F77EA2 /* SkBitmapProcShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcShader.cpp; path = ../libsgl/sgl/SkBitmapProcShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFBD0EDCA64500F77EA2 /* SkBitmapProcShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcShader.h; path = ../libsgl/sgl/SkBitmapProcShader.h; sourceTree = SOURCE_ROOT; };
-		00B7DFBE0EDCA64500F77EA2 /* SkBitmapProcState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcState.cpp; path = ../libsgl/sgl/SkBitmapProcState.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFBF0EDCA64500F77EA2 /* SkBitmapProcState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState.h; path = ../libsgl/sgl/SkBitmapProcState.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC00EDCA64500F77EA2 /* SkBitmapProcState_matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState_matrix.h; path = ../libsgl/sgl/SkBitmapProcState_matrix.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC10EDCA64500F77EA2 /* SkBitmapProcState_matrixProcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcState_matrixProcs.cpp; path = ../libsgl/sgl/SkBitmapProcState_matrixProcs.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFC20EDCA64500F77EA2 /* SkBitmapProcState_sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState_sample.h; path = ../libsgl/sgl/SkBitmapProcState_sample.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC30EDCA64500F77EA2 /* SkBitmapSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapSampler.cpp; path = ../libsgl/sgl/SkBitmapSampler.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFC40EDCA64500F77EA2 /* SkBitmapSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapSampler.h; path = ../libsgl/sgl/SkBitmapSampler.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC50EDCA64500F77EA2 /* SkBitmapSamplerTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapSamplerTemplate.h; path = ../libsgl/sgl/SkBitmapSamplerTemplate.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC60EDCA64500F77EA2 /* SkBitmapShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapShader.cpp; path = ../libsgl/sgl/SkBitmapShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFC70EDCA64500F77EA2 /* SkBitmapShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShader.h; path = ../libsgl/sgl/SkBitmapShader.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC80EDCA64500F77EA2 /* SkBitmapShader16BilerpTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShader16BilerpTemplate.h; path = ../libsgl/sgl/SkBitmapShader16BilerpTemplate.h; sourceTree = SOURCE_ROOT; };
-		00B7DFC90EDCA64500F77EA2 /* SkBitmapShaderTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShaderTemplate.h; path = ../libsgl/sgl/SkBitmapShaderTemplate.h; sourceTree = SOURCE_ROOT; };
-		00B7DFCA0EDCA64500F77EA2 /* SkBlitBWMaskTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitBWMaskTemplate.h; path = ../libsgl/sgl/SkBlitBWMaskTemplate.h; sourceTree = SOURCE_ROOT; };
-		00B7DFCB0EDCA64500F77EA2 /* SkBlitRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitRow.h; path = ../libsgl/sgl/SkBlitRow.h; sourceTree = SOURCE_ROOT; };
-		00B7DFCC0EDCA64500F77EA2 /* SkBlitRow_D16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitRow_D16.cpp; path = ../libsgl/sgl/SkBlitRow_D16.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFCD0EDCA64500F77EA2 /* SkBlitRow_D4444.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitRow_D4444.cpp; path = ../libsgl/sgl/SkBlitRow_D4444.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFCE0EDCA64500F77EA2 /* SkBlitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter.cpp; path = ../libsgl/sgl/SkBlitter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFCF0EDCA64500F77EA2 /* SkBlitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitter.h; path = ../libsgl/sgl/SkBlitter.h; sourceTree = SOURCE_ROOT; };
-		00B7DFD00EDCA64500F77EA2 /* SkBlitter_4444.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_4444.cpp; path = ../libsgl/sgl/SkBlitter_4444.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD10EDCA64500F77EA2 /* SkBlitter_A1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_A1.cpp; path = ../libsgl/sgl/SkBlitter_A1.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD20EDCA64500F77EA2 /* SkBlitter_A8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_A8.cpp; path = ../libsgl/sgl/SkBlitter_A8.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD30EDCA64500F77EA2 /* SkBlitter_ARGB32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_ARGB32.cpp; path = ../libsgl/sgl/SkBlitter_ARGB32.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD40EDCA64500F77EA2 /* SkBlitter_RGB16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_RGB16.cpp; path = ../libsgl/sgl/SkBlitter_RGB16.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD50EDCA64500F77EA2 /* SkBlitter_Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_Sprite.cpp; path = ../libsgl/sgl/SkBlitter_Sprite.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD60EDCA64500F77EA2 /* SkCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCanvas.cpp; path = ../libsgl/sgl/SkCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD70EDCA64500F77EA2 /* SkColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColor.cpp; path = ../libsgl/sgl/SkColor.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD80EDCA64500F77EA2 /* SkColorFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorFilter.cpp; path = ../libsgl/sgl/SkColorFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFD90EDCA64500F77EA2 /* SkColorTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorTable.cpp; path = ../libsgl/sgl/SkColorTable.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFDA0EDCA64500F77EA2 /* SkCoreBlitters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkCoreBlitters.h; path = ../libsgl/sgl/SkCoreBlitters.h; sourceTree = SOURCE_ROOT; };
-		00B7DFDB0EDCA64500F77EA2 /* SkDeque.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDeque.cpp; path = ../libsgl/sgl/SkDeque.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFDC0EDCA64500F77EA2 /* SkDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDevice.cpp; path = ../libsgl/sgl/SkDevice.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFDD0EDCA64500F77EA2 /* SkDither.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDither.cpp; path = ../libsgl/sgl/SkDither.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFDE0EDCA64500F77EA2 /* SkDraw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDraw.cpp; path = ../libsgl/sgl/SkDraw.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFDF0EDCA64500F77EA2 /* SkDrawProcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawProcs.h; path = ../libsgl/sgl/SkDrawProcs.h; sourceTree = SOURCE_ROOT; };
-		00B7DFE00EDCA64500F77EA2 /* SkEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEdge.cpp; path = ../libsgl/sgl/SkEdge.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFE10EDCA64500F77EA2 /* SkEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEdge.h; path = ../libsgl/sgl/SkEdge.h; sourceTree = SOURCE_ROOT; };
-		00B7DFE20EDCA64500F77EA2 /* SkFilterProc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFilterProc.cpp; path = ../libsgl/sgl/SkFilterProc.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFE30EDCA64500F77EA2 /* SkFilterProc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFilterProc.h; path = ../libsgl/sgl/SkFilterProc.h; sourceTree = SOURCE_ROOT; };
-		00B7DFE40EDCA64500F77EA2 /* SkFlattenable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFlattenable.cpp; path = ../libsgl/sgl/SkFlattenable.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFE50EDCA64500F77EA2 /* SkFP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFP.h; path = ../libsgl/sgl/SkFP.h; sourceTree = SOURCE_ROOT; };
-		00B7DFE60EDCA64500F77EA2 /* SkGeometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGeometry.cpp; path = ../libsgl/sgl/SkGeometry.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFE70EDCA64500F77EA2 /* SkGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGeometry.h; path = ../libsgl/sgl/SkGeometry.h; sourceTree = SOURCE_ROOT; };
-		00B7DFE80EDCA64500F77EA2 /* SkGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlobals.cpp; path = ../libsgl/sgl/SkGlobals.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFE90EDCA64500F77EA2 /* SkGlyphCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlyphCache.cpp; path = ../libsgl/sgl/SkGlyphCache.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFEA0EDCA64500F77EA2 /* SkGlyphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGlyphCache.h; path = ../libsgl/sgl/SkGlyphCache.h; sourceTree = SOURCE_ROOT; };
-		00B7DFEB0EDCA64500F77EA2 /* SkGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGraphics.cpp; path = ../libsgl/sgl/SkGraphics.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFEC0EDCA64500F77EA2 /* SkMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMask.cpp; path = ../libsgl/sgl/SkMask.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFED0EDCA64500F77EA2 /* SkMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMaskFilter.cpp; path = ../libsgl/sgl/SkMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFEE0EDCA64500F77EA2 /* SkPackBits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPackBits.cpp; path = ../libsgl/sgl/SkPackBits.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFEF0EDCA64500F77EA2 /* SkPaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPaint.cpp; path = ../libsgl/sgl/SkPaint.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF00EDCA64500F77EA2 /* SkPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPath.cpp; path = ../libsgl/sgl/SkPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF10EDCA64500F77EA2 /* SkPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathEffect.cpp; path = ../libsgl/sgl/SkPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF20EDCA64500F77EA2 /* SkPathMeasure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathMeasure.cpp; path = ../libsgl/sgl/SkPathMeasure.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF30EDCA64500F77EA2 /* SkPixelRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPixelRef.cpp; path = ../libsgl/sgl/SkPixelRef.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF40EDCA64500F77EA2 /* SkProcSpriteBlitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProcSpriteBlitter.cpp; path = ../libsgl/sgl/SkProcSpriteBlitter.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF50EDCA64500F77EA2 /* SkPtrRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPtrRecorder.cpp; path = ../libsgl/sgl/SkPtrRecorder.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF60EDCA64500F77EA2 /* SkRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRasterizer.cpp; path = ../libsgl/sgl/SkRasterizer.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF70EDCA64500F77EA2 /* SkRefCnt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRefCnt.cpp; path = ../libsgl/sgl/SkRefCnt.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF80EDCA64500F77EA2 /* SkRegion_path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRegion_path.cpp; path = ../libsgl/sgl/SkRegion_path.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFF90EDCA64500F77EA2 /* SkScalerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScalerContext.cpp; path = ../libsgl/sgl/SkScalerContext.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFFA0EDCA64500F77EA2 /* SkScan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan.cpp; path = ../libsgl/sgl/SkScan.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFFB0EDCA64500F77EA2 /* SkScan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScan.h; path = ../libsgl/sgl/SkScan.h; sourceTree = SOURCE_ROOT; };
-		00B7DFFC0EDCA64500F77EA2 /* SkScan_Antihair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Antihair.cpp; path = ../libsgl/sgl/SkScan_Antihair.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFFD0EDCA64500F77EA2 /* SkScan_AntiPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_AntiPath.cpp; path = ../libsgl/sgl/SkScan_AntiPath.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFFE0EDCA64500F77EA2 /* SkScan_Hairline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Hairline.cpp; path = ../libsgl/sgl/SkScan_Hairline.cpp; sourceTree = SOURCE_ROOT; };
-		00B7DFFF0EDCA64500F77EA2 /* SkScan_Path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Path.cpp; path = ../libsgl/sgl/SkScan_Path.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0000EDCA64500F77EA2 /* SkScanPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScanPriv.h; path = ../libsgl/sgl/SkScanPriv.h; sourceTree = SOURCE_ROOT; };
-		00B7E0010EDCA64500F77EA2 /* SkShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkShader.cpp; path = ../libsgl/sgl/SkShader.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0020EDCA64500F77EA2 /* SkSpriteBlitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSpriteBlitter.h; path = ../libsgl/sgl/SkSpriteBlitter.h; sourceTree = SOURCE_ROOT; };
-		00B7E0030EDCA64500F77EA2 /* SkSpriteBlitter_ARGB32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSpriteBlitter_ARGB32.cpp; path = ../libsgl/sgl/SkSpriteBlitter_ARGB32.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0040EDCA64500F77EA2 /* SkSpriteBlitter_RGB16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSpriteBlitter_RGB16.cpp; path = ../libsgl/sgl/SkSpriteBlitter_RGB16.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0050EDCA64500F77EA2 /* SkSpriteBlitterTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSpriteBlitterTemplate.h; path = ../libsgl/sgl/SkSpriteBlitterTemplate.h; sourceTree = SOURCE_ROOT; };
-		00B7E0070EDCA64500F77EA2 /* SkStroke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStroke.cpp; path = ../libsgl/sgl/SkStroke.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0080EDCA64500F77EA2 /* SkStrokerPriv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStrokerPriv.cpp; path = ../libsgl/sgl/SkStrokerPriv.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0090EDCA64500F77EA2 /* SkStrokerPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkStrokerPriv.h; path = ../libsgl/sgl/SkStrokerPriv.h; sourceTree = SOURCE_ROOT; };
-		00B7E00A0EDCA64500F77EA2 /* SkTemplatesPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTemplatesPriv.h; path = ../libsgl/sgl/SkTemplatesPriv.h; sourceTree = SOURCE_ROOT; };
-		00B7E00B0EDCA64500F77EA2 /* SkTSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTSearch.cpp; path = ../libsgl/sgl/SkTSearch.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E00C0EDCA64500F77EA2 /* SkTSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTSort.h; path = ../libsgl/sgl/SkTSort.h; sourceTree = SOURCE_ROOT; };
-		00B7E00D0EDCA64500F77EA2 /* SkTypeface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTypeface.cpp; path = ../libsgl/sgl/SkTypeface.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E00E0EDCA64500F77EA2 /* SkUnPreMultiply.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUnPreMultiply.cpp; path = ../libsgl/sgl/SkUnPreMultiply.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0100EDCA64500F77EA2 /* SkWriter32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWriter32.cpp; path = ../libsgl/sgl/SkWriter32.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0110EDCA64500F77EA2 /* SkXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXfermode.cpp; path = ../libsgl/sgl/SkXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC06F0554671400DB518D /* libgraphics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgraphics.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D2AAC06D0554671400DB518D /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		001142D10DCA3ED10070D0A3 /* picture */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF1D0EDCA56700F77EA2 /* SkPathHeap.cpp */,
-				00B7DF1E0EDCA56700F77EA2 /* SkPathHeap.h */,
-				00B7DF1F0EDCA56700F77EA2 /* SkPicture.cpp */,
-				00B7DF200EDCA56700F77EA2 /* SkPictureFlat.cpp */,
-				00B7DF210EDCA56700F77EA2 /* SkPictureFlat.h */,
-				00B7DF220EDCA56700F77EA2 /* SkPicturePlayback.cpp */,
-				00B7DF230EDCA56700F77EA2 /* SkPicturePlayback.h */,
-				00B7DF240EDCA56700F77EA2 /* SkPictureRecord.cpp */,
-				00B7DF250EDCA56700F77EA2 /* SkPictureRecord.h */,
-			);
-			name = picture;
-			sourceTree = "<group>";
-		};
-		034768DDFF38A45A11DB9C8B /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC06F0554671400DB518D /* libgraphics.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		0867D691FE84028FC02AAC07 /* graphics */ = {
-			isa = PBXGroup;
-			children = (
-				001142D10DCA3ED10070D0A3 /* picture */,
-				FE5F48C8094798660095980F /* effects */,
-				FE5F48C5094797E90095980F /* images */,
-				FE5F48B2094797A80095980F /* xml */,
-				08FB77ACFE841707C02AAC07 /* sgl */,
-				034768DDFF38A45A11DB9C8B /* Products */,
-			);
-			name = graphics;
-			sourceTree = "<group>";
-		};
-		08FB77ACFE841707C02AAC07 /* sgl */ = {
-			isa = PBXGroup;
-			children = (
-				006B43AD0EF7444A00F15BC4 /* SkUtils.cpp */,
-				006B43930EF73CFC00F15BC4 /* SkString.cpp */,
-				00B7DFB70EDCA64500F77EA2 /* SkAlphaRuns.cpp */,
-				00B7DFB80EDCA64500F77EA2 /* SkAntiRun.h */,
-				00B7DFB90EDCA64500F77EA2 /* SkAutoKern.h */,
-				00B7DFBA0EDCA64500F77EA2 /* SkBitmap.cpp */,
-				00B7DFBB0EDCA64500F77EA2 /* SkBitmap_scroll.cpp */,
-				00B7DFBC0EDCA64500F77EA2 /* SkBitmapProcShader.cpp */,
-				00B7DFBD0EDCA64500F77EA2 /* SkBitmapProcShader.h */,
-				00B7DFBE0EDCA64500F77EA2 /* SkBitmapProcState.cpp */,
-				00B7DFBF0EDCA64500F77EA2 /* SkBitmapProcState.h */,
-				00B7DFC00EDCA64500F77EA2 /* SkBitmapProcState_matrix.h */,
-				00B7DFC10EDCA64500F77EA2 /* SkBitmapProcState_matrixProcs.cpp */,
-				00B7DFC20EDCA64500F77EA2 /* SkBitmapProcState_sample.h */,
-				00B7DFC30EDCA64500F77EA2 /* SkBitmapSampler.cpp */,
-				00B7DFC40EDCA64500F77EA2 /* SkBitmapSampler.h */,
-				00B7DFC50EDCA64500F77EA2 /* SkBitmapSamplerTemplate.h */,
-				00B7DFC60EDCA64500F77EA2 /* SkBitmapShader.cpp */,
-				00B7DFC70EDCA64500F77EA2 /* SkBitmapShader.h */,
-				00B7DFC80EDCA64500F77EA2 /* SkBitmapShader16BilerpTemplate.h */,
-				00B7DFC90EDCA64500F77EA2 /* SkBitmapShaderTemplate.h */,
-				00B7DFCA0EDCA64500F77EA2 /* SkBlitBWMaskTemplate.h */,
-				00B7DFCB0EDCA64500F77EA2 /* SkBlitRow.h */,
-				00B7DFCC0EDCA64500F77EA2 /* SkBlitRow_D16.cpp */,
-				00B7DFCD0EDCA64500F77EA2 /* SkBlitRow_D4444.cpp */,
-				00B7DFCE0EDCA64500F77EA2 /* SkBlitter.cpp */,
-				00B7DFCF0EDCA64500F77EA2 /* SkBlitter.h */,
-				00B7DFD00EDCA64500F77EA2 /* SkBlitter_4444.cpp */,
-				00B7DFD10EDCA64500F77EA2 /* SkBlitter_A1.cpp */,
-				00B7DFD20EDCA64500F77EA2 /* SkBlitter_A8.cpp */,
-				00B7DFD30EDCA64500F77EA2 /* SkBlitter_ARGB32.cpp */,
-				00B7DFD40EDCA64500F77EA2 /* SkBlitter_RGB16.cpp */,
-				00B7DFD50EDCA64500F77EA2 /* SkBlitter_Sprite.cpp */,
-				00B7DFD60EDCA64500F77EA2 /* SkCanvas.cpp */,
-				00B7DFD70EDCA64500F77EA2 /* SkColor.cpp */,
-				00B7DFD80EDCA64500F77EA2 /* SkColorFilter.cpp */,
-				00B7DFD90EDCA64500F77EA2 /* SkColorTable.cpp */,
-				00B7DFDA0EDCA64500F77EA2 /* SkCoreBlitters.h */,
-				00B7DFDB0EDCA64500F77EA2 /* SkDeque.cpp */,
-				00B7DFDC0EDCA64500F77EA2 /* SkDevice.cpp */,
-				00B7DFDD0EDCA64500F77EA2 /* SkDither.cpp */,
-				00B7DFDE0EDCA64500F77EA2 /* SkDraw.cpp */,
-				00B7DFDF0EDCA64500F77EA2 /* SkDrawProcs.h */,
-				00B7DFE00EDCA64500F77EA2 /* SkEdge.cpp */,
-				00B7DFE10EDCA64500F77EA2 /* SkEdge.h */,
-				00B7DFE20EDCA64500F77EA2 /* SkFilterProc.cpp */,
-				00B7DFE30EDCA64500F77EA2 /* SkFilterProc.h */,
-				00B7DFE40EDCA64500F77EA2 /* SkFlattenable.cpp */,
-				00B7DFE50EDCA64500F77EA2 /* SkFP.h */,
-				00B7DFE60EDCA64500F77EA2 /* SkGeometry.cpp */,
-				00B7DFE70EDCA64500F77EA2 /* SkGeometry.h */,
-				00B7DFE80EDCA64500F77EA2 /* SkGlobals.cpp */,
-				00B7DFE90EDCA64500F77EA2 /* SkGlyphCache.cpp */,
-				00B7DFEA0EDCA64500F77EA2 /* SkGlyphCache.h */,
-				00B7DFEB0EDCA64500F77EA2 /* SkGraphics.cpp */,
-				00B7DFEC0EDCA64500F77EA2 /* SkMask.cpp */,
-				00B7DFED0EDCA64500F77EA2 /* SkMaskFilter.cpp */,
-				00B7DFEE0EDCA64500F77EA2 /* SkPackBits.cpp */,
-				00B7DFEF0EDCA64500F77EA2 /* SkPaint.cpp */,
-				00B7DFF00EDCA64500F77EA2 /* SkPath.cpp */,
-				00B7DFF10EDCA64500F77EA2 /* SkPathEffect.cpp */,
-				00B7DFF20EDCA64500F77EA2 /* SkPathMeasure.cpp */,
-				00B7DFF30EDCA64500F77EA2 /* SkPixelRef.cpp */,
-				00B7DFF40EDCA64500F77EA2 /* SkProcSpriteBlitter.cpp */,
-				00B7DFF50EDCA64500F77EA2 /* SkPtrRecorder.cpp */,
-				00B7DFF60EDCA64500F77EA2 /* SkRasterizer.cpp */,
-				00B7DFF70EDCA64500F77EA2 /* SkRefCnt.cpp */,
-				00B7DFF80EDCA64500F77EA2 /* SkRegion_path.cpp */,
-				00B7DFF90EDCA64500F77EA2 /* SkScalerContext.cpp */,
-				00B7DFFA0EDCA64500F77EA2 /* SkScan.cpp */,
-				00B7DFFB0EDCA64500F77EA2 /* SkScan.h */,
-				00B7DFFC0EDCA64500F77EA2 /* SkScan_Antihair.cpp */,
-				00B7DFFD0EDCA64500F77EA2 /* SkScan_AntiPath.cpp */,
-				00B7DFFE0EDCA64500F77EA2 /* SkScan_Hairline.cpp */,
-				00B7DFFF0EDCA64500F77EA2 /* SkScan_Path.cpp */,
-				00B7E0000EDCA64500F77EA2 /* SkScanPriv.h */,
-				00B7E0010EDCA64500F77EA2 /* SkShader.cpp */,
-				00B7E0020EDCA64500F77EA2 /* SkSpriteBlitter.h */,
-				00B7E0030EDCA64500F77EA2 /* SkSpriteBlitter_ARGB32.cpp */,
-				00B7E0040EDCA64500F77EA2 /* SkSpriteBlitter_RGB16.cpp */,
-				00B7E0050EDCA64500F77EA2 /* SkSpriteBlitterTemplate.h */,
-				00B7E0070EDCA64500F77EA2 /* SkStroke.cpp */,
-				00B7E0080EDCA64500F77EA2 /* SkStrokerPriv.cpp */,
-				00B7E0090EDCA64500F77EA2 /* SkStrokerPriv.h */,
-				00B7E00A0EDCA64500F77EA2 /* SkTemplatesPriv.h */,
-				00B7E00B0EDCA64500F77EA2 /* SkTSearch.cpp */,
-				00B7E00C0EDCA64500F77EA2 /* SkTSort.h */,
-				00B7E00D0EDCA64500F77EA2 /* SkTypeface.cpp */,
-				00B7E00E0EDCA64500F77EA2 /* SkUnPreMultiply.cpp */,
-				00B7E0100EDCA64500F77EA2 /* SkWriter32.cpp */,
-				00B7E0110EDCA64500F77EA2 /* SkXfermode.cpp */,
-			);
-			name = sgl;
-			sourceTree = "<group>";
-		};
-		FE5F48B2094797A80095980F /* xml */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DFA30EDCA60D00F77EA2 /* SkBML_Verbs.h */,
-				00B7DFA40EDCA60D00F77EA2 /* SkBML_XMLParser.cpp */,
-				00B7DFA50EDCA60D00F77EA2 /* SkDOM.cpp */,
-				00B7DFA80EDCA60D00F77EA2 /* SkParse.cpp */,
-				00B7DFA90EDCA60D00F77EA2 /* SkParseColor.cpp */,
-				00B7DFAA0EDCA60D00F77EA2 /* SkXMLParser.cpp */,
-				00B7DFAC0EDCA60D00F77EA2 /* SkXMLWriter.cpp */,
-			);
-			name = xml;
-			sourceTree = "<group>";
-		};
-		FE5F48C5094797E90095980F /* images */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF730EDCA59200F77EA2 /* SkFDStream.cpp */,
-				00B7DF740EDCA59200F77EA2 /* SkFlipPixelRef.cpp */,
-				00B7DF750EDCA59200F77EA2 /* SkImageDecoder.cpp */,
-				00B7DF7E0EDCA59200F77EA2 /* SkImageRef.cpp */,
-				00B7DF7F0EDCA59200F77EA2 /* SkImageRef_GlobalPool.cpp */,
-				00B7DF800EDCA59200F77EA2 /* SkImageRefPool.cpp */,
-				00B7DF820EDCA59200F77EA2 /* SkMMapStream.cpp */,
-				00B7DF850EDCA59200F77EA2 /* SkScaledBitmapSampler.cpp */,
-				00B7DF860EDCA59200F77EA2 /* SkScaledBitmapSampler.h */,
-				00B7DF870EDCA59200F77EA2 /* SkStream.cpp */,
-			);
-			name = images;
-			sourceTree = "<group>";
-		};
-		FE5F48C8094798660095980F /* effects */ = {
-			isa = PBXGroup;
-			children = (
-				00B7DF2F0EDCA57800F77EA2 /* Sk1DPathEffect.cpp */,
-				00B7DF300EDCA57800F77EA2 /* Sk2DPathEffect.cpp */,
-				00B7DF310EDCA57800F77EA2 /* SkAvoidXfermode.cpp */,
-				00B7DF320EDCA57800F77EA2 /* SkBlurDrawLooper.cpp */,
-				00B7DF330EDCA57800F77EA2 /* SkBlurMask.cpp */,
-				00B7DF340EDCA57800F77EA2 /* SkBlurMask.h */,
-				00B7DF350EDCA57800F77EA2 /* SkBlurMaskFilter.cpp */,
-				00B7DF360EDCA57800F77EA2 /* SkCamera.cpp */,
-				00B7DF370EDCA57800F77EA2 /* SkColorFilters.cpp */,
-				00B7DF380EDCA57800F77EA2 /* SkColorMatrix.cpp */,
-				00B7DF390EDCA57800F77EA2 /* SkColorMatrixFilter.cpp */,
-				00B7DF3A0EDCA57800F77EA2 /* SkCornerPathEffect.cpp */,
-				00B7DF3B0EDCA57800F77EA2 /* SkCullPoints.cpp */,
-				00B7DF3C0EDCA57800F77EA2 /* SkDashPathEffect.cpp */,
-				00B7DF3D0EDCA57800F77EA2 /* SkDiscretePathEffect.cpp */,
-				00B7DF3E0EDCA57800F77EA2 /* SkEmbossMask.cpp */,
-				00B7DF3F0EDCA57800F77EA2 /* SkEmbossMask.h */,
-				00B7DF400EDCA57800F77EA2 /* SkEmbossMask_Table.h */,
-				00B7DF410EDCA57800F77EA2 /* SkEmbossMaskFilter.cpp */,
-				00B7DF420EDCA57800F77EA2 /* SkGradientShader.cpp */,
-				00B7DF430EDCA57800F77EA2 /* SkKernel33MaskFilter.cpp */,
-				00B7DF440EDCA57800F77EA2 /* SkLayerDrawLooper.cpp */,
-				00B7DF450EDCA57800F77EA2 /* SkLayerRasterizer.cpp */,
-				00B7DF460EDCA57800F77EA2 /* SkNinePatch.cpp */,
-				00B7DF470EDCA57800F77EA2 /* SkPaintFlagsDrawFilter.cpp */,
-				00B7DF480EDCA57800F77EA2 /* SkPixelXorXfermode.cpp */,
-				00B7DF490EDCA57800F77EA2 /* SkProxyCanvas.cpp */,
-				00B7DF4A0EDCA57800F77EA2 /* SkRadialGradient_Table.h */,
-				00B7DF4B0EDCA57800F77EA2 /* SkShaderExtras.cpp */,
-				00B7DF4C0EDCA57800F77EA2 /* SkTransparentShader.cpp */,
-				00B7DF4D0EDCA57800F77EA2 /* SkUnitMappers.cpp */,
-			);
-			name = effects;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC06B0554671400DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DF270EDCA56700F77EA2 /* SkPathHeap.h in Headers */,
-				00B7DF2A0EDCA56700F77EA2 /* SkPictureFlat.h in Headers */,
-				00B7DF2C0EDCA56700F77EA2 /* SkPicturePlayback.h in Headers */,
-				00B7DF2E0EDCA56700F77EA2 /* SkPictureRecord.h in Headers */,
-				00B7DF530EDCA57800F77EA2 /* SkBlurMask.h in Headers */,
-				00B7DF5E0EDCA57800F77EA2 /* SkEmbossMask.h in Headers */,
-				00B7DF5F0EDCA57800F77EA2 /* SkEmbossMask_Table.h in Headers */,
-				00B7DF690EDCA57800F77EA2 /* SkRadialGradient_Table.h in Headers */,
-				00B7DFA10EDCA59200F77EA2 /* SkScaledBitmapSampler.h in Headers */,
-				00B7DFAD0EDCA60D00F77EA2 /* SkBML_Verbs.h in Headers */,
-				00B7E0130EDCA64500F77EA2 /* SkAntiRun.h in Headers */,
-				00B7E0140EDCA64500F77EA2 /* SkAutoKern.h in Headers */,
-				00B7E0180EDCA64500F77EA2 /* SkBitmapProcShader.h in Headers */,
-				00B7E01A0EDCA64500F77EA2 /* SkBitmapProcState.h in Headers */,
-				00B7E01B0EDCA64500F77EA2 /* SkBitmapProcState_matrix.h in Headers */,
-				00B7E01D0EDCA64500F77EA2 /* SkBitmapProcState_sample.h in Headers */,
-				00B7E01F0EDCA64500F77EA2 /* SkBitmapSampler.h in Headers */,
-				00B7E0200EDCA64500F77EA2 /* SkBitmapSamplerTemplate.h in Headers */,
-				00B7E0220EDCA64500F77EA2 /* SkBitmapShader.h in Headers */,
-				00B7E0230EDCA64500F77EA2 /* SkBitmapShader16BilerpTemplate.h in Headers */,
-				00B7E0240EDCA64500F77EA2 /* SkBitmapShaderTemplate.h in Headers */,
-				00B7E0250EDCA64500F77EA2 /* SkBlitBWMaskTemplate.h in Headers */,
-				00B7E0260EDCA64500F77EA2 /* SkBlitRow.h in Headers */,
-				00B7E02A0EDCA64500F77EA2 /* SkBlitter.h in Headers */,
-				00B7E0350EDCA64500F77EA2 /* SkCoreBlitters.h in Headers */,
-				00B7E03A0EDCA64500F77EA2 /* SkDrawProcs.h in Headers */,
-				00B7E03C0EDCA64500F77EA2 /* SkEdge.h in Headers */,
-				00B7E03E0EDCA64500F77EA2 /* SkFilterProc.h in Headers */,
-				00B7E0400EDCA64500F77EA2 /* SkFP.h in Headers */,
-				00B7E0420EDCA64500F77EA2 /* SkGeometry.h in Headers */,
-				00B7E0450EDCA64500F77EA2 /* SkGlyphCache.h in Headers */,
-				00B7E0560EDCA64500F77EA2 /* SkScan.h in Headers */,
-				00B7E05B0EDCA64500F77EA2 /* SkScanPriv.h in Headers */,
-				00B7E05D0EDCA64500F77EA2 /* SkSpriteBlitter.h in Headers */,
-				00B7E0600EDCA64500F77EA2 /* SkSpriteBlitterTemplate.h in Headers */,
-				00B7E0640EDCA64500F77EA2 /* SkStrokerPriv.h in Headers */,
-				00B7E0650EDCA64500F77EA2 /* SkTemplatesPriv.h in Headers */,
-				00B7E0670EDCA64500F77EA2 /* SkTSort.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC06E0554671400DB518D /* graphics */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB920108733DBB0010E9CD /* Build configuration list for PBXNativeTarget "graphics" */;
-			buildPhases = (
-				D2AAC06B0554671400DB518D /* Headers */,
-				D2AAC06C0554671400DB518D /* Sources */,
-				D2AAC06D0554671400DB518D /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = graphics;
-			productName = graphics;
-			productReference = D2AAC06F0554671400DB518D /* libgraphics.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		0867D690FE84028FC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB920508733DBB0010E9CD /* Build configuration list for PBXProject "graphics" */;
-			compatibilityVersion = "Xcode 3.0";
-			hasScannedForEncodings = 1;
-			mainGroup = 0867D691FE84028FC02AAC07 /* graphics */;
-			productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC06E0554671400DB518D /* graphics */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC06C0554671400DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7DF260EDCA56700F77EA2 /* SkPathHeap.cpp in Sources */,
-				00B7DF280EDCA56700F77EA2 /* SkPicture.cpp in Sources */,
-				00B7DF290EDCA56700F77EA2 /* SkPictureFlat.cpp in Sources */,
-				00B7DF2B0EDCA56700F77EA2 /* SkPicturePlayback.cpp in Sources */,
-				00B7DF2D0EDCA56700F77EA2 /* SkPictureRecord.cpp in Sources */,
-				00B7DF4E0EDCA57800F77EA2 /* Sk1DPathEffect.cpp in Sources */,
-				00B7DF4F0EDCA57800F77EA2 /* Sk2DPathEffect.cpp in Sources */,
-				00B7DF500EDCA57800F77EA2 /* SkAvoidXfermode.cpp in Sources */,
-				00B7DF510EDCA57800F77EA2 /* SkBlurDrawLooper.cpp in Sources */,
-				00B7DF520EDCA57800F77EA2 /* SkBlurMask.cpp in Sources */,
-				00B7DF540EDCA57800F77EA2 /* SkBlurMaskFilter.cpp in Sources */,
-				00B7DF550EDCA57800F77EA2 /* SkCamera.cpp in Sources */,
-				00B7DF560EDCA57800F77EA2 /* SkColorFilters.cpp in Sources */,
-				00B7DF570EDCA57800F77EA2 /* SkColorMatrix.cpp in Sources */,
-				00B7DF580EDCA57800F77EA2 /* SkColorMatrixFilter.cpp in Sources */,
-				00B7DF590EDCA57800F77EA2 /* SkCornerPathEffect.cpp in Sources */,
-				00B7DF5A0EDCA57800F77EA2 /* SkCullPoints.cpp in Sources */,
-				00B7DF5B0EDCA57800F77EA2 /* SkDashPathEffect.cpp in Sources */,
-				00B7DF5C0EDCA57800F77EA2 /* SkDiscretePathEffect.cpp in Sources */,
-				00B7DF5D0EDCA57800F77EA2 /* SkEmbossMask.cpp in Sources */,
-				00B7DF600EDCA57800F77EA2 /* SkEmbossMaskFilter.cpp in Sources */,
-				00B7DF610EDCA57800F77EA2 /* SkGradientShader.cpp in Sources */,
-				00B7DF620EDCA57800F77EA2 /* SkKernel33MaskFilter.cpp in Sources */,
-				00B7DF630EDCA57800F77EA2 /* SkLayerDrawLooper.cpp in Sources */,
-				00B7DF640EDCA57800F77EA2 /* SkLayerRasterizer.cpp in Sources */,
-				00B7DF650EDCA57800F77EA2 /* SkNinePatch.cpp in Sources */,
-				00B7DF660EDCA57800F77EA2 /* SkPaintFlagsDrawFilter.cpp in Sources */,
-				00B7DF670EDCA57800F77EA2 /* SkPixelXorXfermode.cpp in Sources */,
-				00B7DF680EDCA57800F77EA2 /* SkProxyCanvas.cpp in Sources */,
-				00B7DF6A0EDCA57800F77EA2 /* SkShaderExtras.cpp in Sources */,
-				00B7DF6B0EDCA57800F77EA2 /* SkTransparentShader.cpp in Sources */,
-				00B7DF6C0EDCA57800F77EA2 /* SkUnitMappers.cpp in Sources */,
-				00B7DF8E0EDCA59200F77EA2 /* SkFDStream.cpp in Sources */,
-				00B7DF8F0EDCA59200F77EA2 /* SkFlipPixelRef.cpp in Sources */,
-				00B7DF900EDCA59200F77EA2 /* SkImageDecoder.cpp in Sources */,
-				00B7DF990EDCA59200F77EA2 /* SkImageRef.cpp in Sources */,
-				00B7DF9A0EDCA59200F77EA2 /* SkImageRef_GlobalPool.cpp in Sources */,
-				00B7DF9B0EDCA59200F77EA2 /* SkImageRefPool.cpp in Sources */,
-				00B7DF9D0EDCA59200F77EA2 /* SkMMapStream.cpp in Sources */,
-				00B7DFA00EDCA59200F77EA2 /* SkScaledBitmapSampler.cpp in Sources */,
-				00B7DFA20EDCA59200F77EA2 /* SkStream.cpp in Sources */,
-				00B7DFAE0EDCA60D00F77EA2 /* SkBML_XMLParser.cpp in Sources */,
-				00B7DFAF0EDCA60D00F77EA2 /* SkDOM.cpp in Sources */,
-				00B7DFB20EDCA60D00F77EA2 /* SkParse.cpp in Sources */,
-				00B7DFB30EDCA60D00F77EA2 /* SkParseColor.cpp in Sources */,
-				00B7DFB40EDCA60D00F77EA2 /* SkXMLParser.cpp in Sources */,
-				00B7DFB60EDCA60D00F77EA2 /* SkXMLWriter.cpp in Sources */,
-				00B7E0120EDCA64500F77EA2 /* SkAlphaRuns.cpp in Sources */,
-				00B7E0150EDCA64500F77EA2 /* SkBitmap.cpp in Sources */,
-				00B7E0160EDCA64500F77EA2 /* SkBitmap_scroll.cpp in Sources */,
-				00B7E0170EDCA64500F77EA2 /* SkBitmapProcShader.cpp in Sources */,
-				00B7E0190EDCA64500F77EA2 /* SkBitmapProcState.cpp in Sources */,
-				00B7E01C0EDCA64500F77EA2 /* SkBitmapProcState_matrixProcs.cpp in Sources */,
-				00B7E01E0EDCA64500F77EA2 /* SkBitmapSampler.cpp in Sources */,
-				00B7E0210EDCA64500F77EA2 /* SkBitmapShader.cpp in Sources */,
-				00B7E0270EDCA64500F77EA2 /* SkBlitRow_D16.cpp in Sources */,
-				00B7E0280EDCA64500F77EA2 /* SkBlitRow_D4444.cpp in Sources */,
-				00B7E0290EDCA64500F77EA2 /* SkBlitter.cpp in Sources */,
-				00B7E02B0EDCA64500F77EA2 /* SkBlitter_4444.cpp in Sources */,
-				00B7E02C0EDCA64500F77EA2 /* SkBlitter_A1.cpp in Sources */,
-				00B7E02D0EDCA64500F77EA2 /* SkBlitter_A8.cpp in Sources */,
-				00B7E02E0EDCA64500F77EA2 /* SkBlitter_ARGB32.cpp in Sources */,
-				00B7E02F0EDCA64500F77EA2 /* SkBlitter_RGB16.cpp in Sources */,
-				00B7E0300EDCA64500F77EA2 /* SkBlitter_Sprite.cpp in Sources */,
-				00B7E0310EDCA64500F77EA2 /* SkCanvas.cpp in Sources */,
-				00B7E0320EDCA64500F77EA2 /* SkColor.cpp in Sources */,
-				00B7E0330EDCA64500F77EA2 /* SkColorFilter.cpp in Sources */,
-				00B7E0340EDCA64500F77EA2 /* SkColorTable.cpp in Sources */,
-				00B7E0360EDCA64500F77EA2 /* SkDeque.cpp in Sources */,
-				00B7E0370EDCA64500F77EA2 /* SkDevice.cpp in Sources */,
-				00B7E0380EDCA64500F77EA2 /* SkDither.cpp in Sources */,
-				00B7E0390EDCA64500F77EA2 /* SkDraw.cpp in Sources */,
-				00B7E03B0EDCA64500F77EA2 /* SkEdge.cpp in Sources */,
-				00B7E03D0EDCA64500F77EA2 /* SkFilterProc.cpp in Sources */,
-				00B7E03F0EDCA64500F77EA2 /* SkFlattenable.cpp in Sources */,
-				00B7E0410EDCA64500F77EA2 /* SkGeometry.cpp in Sources */,
-				00B7E0430EDCA64500F77EA2 /* SkGlobals.cpp in Sources */,
-				00B7E0440EDCA64500F77EA2 /* SkGlyphCache.cpp in Sources */,
-				00B7E0460EDCA64500F77EA2 /* SkGraphics.cpp in Sources */,
-				00B7E0470EDCA64500F77EA2 /* SkMask.cpp in Sources */,
-				00B7E0480EDCA64500F77EA2 /* SkMaskFilter.cpp in Sources */,
-				00B7E0490EDCA64500F77EA2 /* SkPackBits.cpp in Sources */,
-				00B7E04A0EDCA64500F77EA2 /* SkPaint.cpp in Sources */,
-				00B7E04B0EDCA64500F77EA2 /* SkPath.cpp in Sources */,
-				00B7E04C0EDCA64500F77EA2 /* SkPathEffect.cpp in Sources */,
-				00B7E04D0EDCA64500F77EA2 /* SkPathMeasure.cpp in Sources */,
-				00B7E04E0EDCA64500F77EA2 /* SkPixelRef.cpp in Sources */,
-				00B7E04F0EDCA64500F77EA2 /* SkProcSpriteBlitter.cpp in Sources */,
-				00B7E0500EDCA64500F77EA2 /* SkPtrRecorder.cpp in Sources */,
-				00B7E0510EDCA64500F77EA2 /* SkRasterizer.cpp in Sources */,
-				00B7E0520EDCA64500F77EA2 /* SkRefCnt.cpp in Sources */,
-				00B7E0530EDCA64500F77EA2 /* SkRegion_path.cpp in Sources */,
-				00B7E0540EDCA64500F77EA2 /* SkScalerContext.cpp in Sources */,
-				00B7E0550EDCA64500F77EA2 /* SkScan.cpp in Sources */,
-				00B7E0570EDCA64500F77EA2 /* SkScan_Antihair.cpp in Sources */,
-				00B7E0580EDCA64500F77EA2 /* SkScan_AntiPath.cpp in Sources */,
-				00B7E0590EDCA64500F77EA2 /* SkScan_Hairline.cpp in Sources */,
-				00B7E05A0EDCA64500F77EA2 /* SkScan_Path.cpp in Sources */,
-				00B7E05C0EDCA64500F77EA2 /* SkShader.cpp in Sources */,
-				00B7E05E0EDCA64500F77EA2 /* SkSpriteBlitter_ARGB32.cpp in Sources */,
-				00B7E05F0EDCA64500F77EA2 /* SkSpriteBlitter_RGB16.cpp in Sources */,
-				00B7E0620EDCA64500F77EA2 /* SkStroke.cpp in Sources */,
-				00B7E0630EDCA64500F77EA2 /* SkStrokerPriv.cpp in Sources */,
-				00B7E0660EDCA64500F77EA2 /* SkTSearch.cpp in Sources */,
-				00B7E0680EDCA64500F77EA2 /* SkTypeface.cpp in Sources */,
-				00B7E0690EDCA64500F77EA2 /* SkUnPreMultiply.cpp in Sources */,
-				00B7E06B0EDCA64500F77EA2 /* SkWriter32.cpp in Sources */,
-				00B7E06C0EDCA64500F77EA2 /* SkXfermode.cpp in Sources */,
-				006B43940EF73CFC00F15BC4 /* SkString.cpp in Sources */,
-				006B43AE0EF7444A00F15BC4 /* SkUtils.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB920208733DBB0010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREFIX_HEADER = graphics_Prefix.pch;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = graphics;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB920308733DBB0010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREFIX_HEADER = graphics_Prefix.pch;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = graphics;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB920608733DBB0010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_DEBUGGING_SYMBOLS = full;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PFE_FILE_C_DIALECTS = "";
-				GCC_PREPROCESSOR_DEFINITIONS = SK_DEBUG;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/** ../libcorecg";
-			};
-			name = Debug;
-		};
-		1DEB920708733DBB0010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_DEBUGGING_SYMBOLS = full;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PFE_FILE_C_DIALECTS = "";
-				GCC_PREPROCESSOR_DEFINITIONS = SK_RELEASE;
-				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/** ../libcorecg";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB920108733DBB0010E9CD /* Build configuration list for PBXNativeTarget "graphics" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB920208733DBB0010E9CD /* Debug */,
-				1DEB920308733DBB0010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB920508733DBB0010E9CD /* Build configuration list for PBXProject "graphics" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB920608733DBB0010E9CD /* Debug */,
-				1DEB920708733DBB0010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
-}
diff --git a/xcode/hostapp/test.cpp b/xcode/hostapp/test.cpp
deleted file mode 100644
index 4f66a82..0000000
--- a/xcode/hostapp/test.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <Carbon/Carbon.h>
-#include "SkCGUtils.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-
-extern "C" void SkiaDraw(CGContextRef cg, CGRect bounds);
-
-static void sampleDraw(SkCanvas* canvas) {
-    canvas->drawColor(0xFF0000FF);
-    
-    SkPaint paint;
-    paint.setAntiAlias(true);
-
-    canvas->drawCircle(SkIntToScalar(100), SkIntToScalar(100),
-                       SkIntToScalar(90), paint);
-    
-    const char text[] = "fry42";
-    const size_t len = strlen(text);
-
-    paint.setColor(SK_ColorWHITE);
-    paint.setTextSize(SkIntToScalar(50));
-    canvas->drawText(text, len, SkIntToScalar(100), SkIntToScalar(50), paint);
-    paint.setTextAlign(SkPaint::kCenter_Align);
-    canvas->drawText(text, len, SkIntToScalar(100), SkIntToScalar(100), paint);
-    paint.setTextAlign(SkPaint::kRight_Align);
-    canvas->drawText(text, len, SkIntToScalar(100), SkIntToScalar(150), paint);
-}
-
-static CGImageRef gImage;
-
-void SkiaDraw(CGContextRef cg, CGRect bounds) {
-    if (NULL == gImage) {
-        SkBitmap bitmap;
-        bitmap.setConfig(SkBitmap::kARGB_8888_Config, 640, 480);
-        bitmap.allocPixels();
-        
-        SkCanvas canvas(bitmap);
-        sampleDraw(&canvas);
-        
-        gImage = SkCreateCGImageRef(bitmap);
-    }
-
-	float components[] = { 1, 1, 1, 1 };
-
-	CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
-	CGColorRef color = CGColorCreate(colorspace, components);
-
-    CGContextSetFillColorWithColor(cg, color);
-    CGColorRelease(color);
-	CGColorSpaceRelease(colorspace);
-
-    CGContextFillRect(cg, bounds);
-
-    CGRect r = CGRectMake(0, 0, 640, 480);
-    
-    CGContextSaveGState(cg);
-    CGContextTranslateCTM(cg, 0, r.size.height);
-    CGContextScaleCTM(cg, 1, -1);
-    
-    CGContextDrawImage(cg, r, gImage);
-    
-    CGContextRestoreGState(cg);
-}
-
-
diff --git a/xcode/jpeg.xcodeproj/project.pbxproj b/xcode/jpeg.xcodeproj/project.pbxproj
deleted file mode 100644
index ee1c4b3..0000000
--- a/xcode/jpeg.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,451 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E07F0EDCA73700F77EA2 /* SkImageDecoder_libjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E07E0EDCA73700F77EA2 /* SkImageDecoder_libjpeg.cpp */; };
-		00B7E0D60EDCA78B00F77EA2 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0890EDCA78B00F77EA2 /* jcapimin.c */; };
-		00B7E0D70EDCA78B00F77EA2 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E08A0EDCA78B00F77EA2 /* jcapistd.c */; };
-		00B7E0D80EDCA78B00F77EA2 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E08B0EDCA78B00F77EA2 /* jccoefct.c */; };
-		00B7E0D90EDCA78B00F77EA2 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E08C0EDCA78B00F77EA2 /* jccolor.c */; };
-		00B7E0DA0EDCA78B00F77EA2 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E08D0EDCA78B00F77EA2 /* jcdctmgr.c */; };
-		00B7E0DB0EDCA78B00F77EA2 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E08E0EDCA78B00F77EA2 /* jchuff.c */; };
-		00B7E0DD0EDCA78B00F77EA2 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0900EDCA78B00F77EA2 /* jcinit.c */; };
-		00B7E0DE0EDCA78B00F77EA2 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0910EDCA78B00F77EA2 /* jcmainct.c */; };
-		00B7E0DF0EDCA78B00F77EA2 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0920EDCA78B00F77EA2 /* jcmarker.c */; };
-		00B7E0E00EDCA78B00F77EA2 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0930EDCA78B00F77EA2 /* jcmaster.c */; };
-		00B7E0E10EDCA78B00F77EA2 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0940EDCA78B00F77EA2 /* jcomapi.c */; };
-		00B7E0E30EDCA78B00F77EA2 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A20EDCA78B00F77EA2 /* jcparam.c */; };
-		00B7E0E40EDCA78B00F77EA2 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A30EDCA78B00F77EA2 /* jcphuff.c */; };
-		00B7E0E50EDCA78B00F77EA2 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A40EDCA78B00F77EA2 /* jcprepct.c */; };
-		00B7E0E60EDCA78B00F77EA2 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A50EDCA78B00F77EA2 /* jcsample.c */; };
-		00B7E0E70EDCA78B00F77EA2 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A60EDCA78B00F77EA2 /* jctrans.c */; };
-		00B7E0E80EDCA78B00F77EA2 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A70EDCA78B00F77EA2 /* jdapimin.c */; };
-		00B7E0E90EDCA78B00F77EA2 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A80EDCA78B00F77EA2 /* jdapistd.c */; };
-		00B7E0EA0EDCA78B00F77EA2 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0A90EDCA78B00F77EA2 /* jdatadst.c */; };
-		00B7E0EB0EDCA78B00F77EA2 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0AA0EDCA78B00F77EA2 /* jdatasrc.c */; };
-		00B7E0EC0EDCA78B00F77EA2 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0AB0EDCA78B00F77EA2 /* jdcoefct.c */; };
-		00B7E0ED0EDCA78B00F77EA2 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0AC0EDCA78B00F77EA2 /* jdcolor.c */; };
-		00B7E0EF0EDCA78B00F77EA2 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0AE0EDCA78B00F77EA2 /* jddctmgr.c */; };
-		00B7E0F00EDCA78B00F77EA2 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0AF0EDCA78B00F77EA2 /* jdhuff.c */; };
-		00B7E0F20EDCA78B00F77EA2 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B10EDCA78B00F77EA2 /* jdinput.c */; };
-		00B7E0F30EDCA78B00F77EA2 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B20EDCA78B00F77EA2 /* jdmainct.c */; };
-		00B7E0F40EDCA78B00F77EA2 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B30EDCA78B00F77EA2 /* jdmarker.c */; };
-		00B7E0F50EDCA78B00F77EA2 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B40EDCA78B00F77EA2 /* jdmaster.c */; };
-		00B7E0F60EDCA78B00F77EA2 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B50EDCA78B00F77EA2 /* jdmerge.c */; };
-		00B7E0F70EDCA78B00F77EA2 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B60EDCA78B00F77EA2 /* jdphuff.c */; };
-		00B7E0F80EDCA78B00F77EA2 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B70EDCA78B00F77EA2 /* jdpostct.c */; };
-		00B7E0F90EDCA78B00F77EA2 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B80EDCA78B00F77EA2 /* jdsample.c */; };
-		00B7E0FA0EDCA78B00F77EA2 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0B90EDCA78B00F77EA2 /* jdtrans.c */; };
-		00B7E0FB0EDCA78B00F77EA2 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0BA0EDCA78B00F77EA2 /* jerror.c */; };
-		00B7E0FD0EDCA78B00F77EA2 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0BC0EDCA78B00F77EA2 /* jfdctflt.c */; };
-		00B7E0FE0EDCA78B00F77EA2 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0BD0EDCA78B00F77EA2 /* jfdctfst.c */; };
-		00B7E0FF0EDCA78B00F77EA2 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0BE0EDCA78B00F77EA2 /* jfdctint.c */; };
-		00B7E1000EDCA78B00F77EA2 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0BF0EDCA78B00F77EA2 /* jidctflt.c */; };
-		00B7E1010EDCA78B00F77EA2 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0C00EDCA78B00F77EA2 /* jidctfst.c */; };
-		00B7E1030EDCA78B00F77EA2 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0C20EDCA78B00F77EA2 /* jidctint.c */; };
-		00B7E1040EDCA78B00F77EA2 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0C30EDCA78B00F77EA2 /* jidctred.c */; };
-		00B7E1070EDCA78B00F77EA2 /* jmemansi.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0C60EDCA78B00F77EA2 /* jmemansi.c */; };
-		00B7E10B0EDCA78B00F77EA2 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0CA0EDCA78B00F77EA2 /* jmemmgr.c */; };
-		00B7E1130EDCA78B00F77EA2 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0D30EDCA78B00F77EA2 /* jquant1.c */; };
-		00B7E1140EDCA78B00F77EA2 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0D40EDCA78B00F77EA2 /* jquant2.c */; };
-		00B7E1150EDCA78B00F77EA2 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E0D50EDCA78B00F77EA2 /* jutils.c */; };
-		00B7E11C0EDCA84F00F77EA2 /* jchuff.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E1180EDCA84F00F77EA2 /* jchuff.h */; };
-		00B7E11D0EDCA84F00F77EA2 /* jconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E1190EDCA84F00F77EA2 /* jconfig.h */; };
-		00B7E11E0EDCA84F00F77EA2 /* jerror.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E11A0EDCA84F00F77EA2 /* jerror.h */; };
-		00B7E11F0EDCA84F00F77EA2 /* jpeglib.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E11B0EDCA84F00F77EA2 /* jpeglib.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E07E0EDCA73700F77EA2 /* SkImageDecoder_libjpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libjpeg.cpp; path = ../libsgl/images/SkImageDecoder_libjpeg.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E0890EDCA78B00F77EA2 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../../jpeg/jcapimin.c; sourceTree = SOURCE_ROOT; };
-		00B7E08A0EDCA78B00F77EA2 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../../jpeg/jcapistd.c; sourceTree = SOURCE_ROOT; };
-		00B7E08B0EDCA78B00F77EA2 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../../jpeg/jccoefct.c; sourceTree = SOURCE_ROOT; };
-		00B7E08C0EDCA78B00F77EA2 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../../jpeg/jccolor.c; sourceTree = SOURCE_ROOT; };
-		00B7E08D0EDCA78B00F77EA2 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../../jpeg/jcdctmgr.c; sourceTree = SOURCE_ROOT; };
-		00B7E08E0EDCA78B00F77EA2 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../../jpeg/jchuff.c; sourceTree = SOURCE_ROOT; };
-		00B7E0900EDCA78B00F77EA2 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../../jpeg/jcinit.c; sourceTree = SOURCE_ROOT; };
-		00B7E0910EDCA78B00F77EA2 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../../jpeg/jcmainct.c; sourceTree = SOURCE_ROOT; };
-		00B7E0920EDCA78B00F77EA2 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../../jpeg/jcmarker.c; sourceTree = SOURCE_ROOT; };
-		00B7E0930EDCA78B00F77EA2 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../../jpeg/jcmaster.c; sourceTree = SOURCE_ROOT; };
-		00B7E0940EDCA78B00F77EA2 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../../jpeg/jcomapi.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A20EDCA78B00F77EA2 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../../jpeg/jcparam.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A30EDCA78B00F77EA2 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../../jpeg/jcphuff.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A40EDCA78B00F77EA2 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../../jpeg/jcprepct.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A50EDCA78B00F77EA2 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../../jpeg/jcsample.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A60EDCA78B00F77EA2 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../../jpeg/jctrans.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A70EDCA78B00F77EA2 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../../jpeg/jdapimin.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A80EDCA78B00F77EA2 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../../jpeg/jdapistd.c; sourceTree = SOURCE_ROOT; };
-		00B7E0A90EDCA78B00F77EA2 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../../jpeg/jdatadst.c; sourceTree = SOURCE_ROOT; };
-		00B7E0AA0EDCA78B00F77EA2 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../../jpeg/jdatasrc.c; sourceTree = SOURCE_ROOT; };
-		00B7E0AB0EDCA78B00F77EA2 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../../jpeg/jdcoefct.c; sourceTree = SOURCE_ROOT; };
-		00B7E0AC0EDCA78B00F77EA2 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../../jpeg/jdcolor.c; sourceTree = SOURCE_ROOT; };
-		00B7E0AE0EDCA78B00F77EA2 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../../jpeg/jddctmgr.c; sourceTree = SOURCE_ROOT; };
-		00B7E0AF0EDCA78B00F77EA2 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../../jpeg/jdhuff.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B10EDCA78B00F77EA2 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../../jpeg/jdinput.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B20EDCA78B00F77EA2 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../../jpeg/jdmainct.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B30EDCA78B00F77EA2 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../../jpeg/jdmarker.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B40EDCA78B00F77EA2 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../../jpeg/jdmaster.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B50EDCA78B00F77EA2 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../../jpeg/jdmerge.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B60EDCA78B00F77EA2 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../../jpeg/jdphuff.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B70EDCA78B00F77EA2 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../../jpeg/jdpostct.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B80EDCA78B00F77EA2 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../../jpeg/jdsample.c; sourceTree = SOURCE_ROOT; };
-		00B7E0B90EDCA78B00F77EA2 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../../jpeg/jdtrans.c; sourceTree = SOURCE_ROOT; };
-		00B7E0BA0EDCA78B00F77EA2 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../../jpeg/jerror.c; sourceTree = SOURCE_ROOT; };
-		00B7E0BC0EDCA78B00F77EA2 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../../jpeg/jfdctflt.c; sourceTree = SOURCE_ROOT; };
-		00B7E0BD0EDCA78B00F77EA2 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../../jpeg/jfdctfst.c; sourceTree = SOURCE_ROOT; };
-		00B7E0BE0EDCA78B00F77EA2 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../../jpeg/jfdctint.c; sourceTree = SOURCE_ROOT; };
-		00B7E0BF0EDCA78B00F77EA2 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../../jpeg/jidctflt.c; sourceTree = SOURCE_ROOT; };
-		00B7E0C00EDCA78B00F77EA2 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../../jpeg/jidctfst.c; sourceTree = SOURCE_ROOT; };
-		00B7E0C20EDCA78B00F77EA2 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../../jpeg/jidctint.c; sourceTree = SOURCE_ROOT; };
-		00B7E0C30EDCA78B00F77EA2 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../../jpeg/jidctred.c; sourceTree = SOURCE_ROOT; };
-		00B7E0C60EDCA78B00F77EA2 /* jmemansi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemansi.c; path = ../../jpeg/jmemansi.c; sourceTree = SOURCE_ROOT; };
-		00B7E0CA0EDCA78B00F77EA2 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../../jpeg/jmemmgr.c; sourceTree = SOURCE_ROOT; };
-		00B7E0D30EDCA78B00F77EA2 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../../jpeg/jquant1.c; sourceTree = SOURCE_ROOT; };
-		00B7E0D40EDCA78B00F77EA2 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../../jpeg/jquant2.c; sourceTree = SOURCE_ROOT; };
-		00B7E0D50EDCA78B00F77EA2 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../jpeg/jutils.c; sourceTree = SOURCE_ROOT; };
-		00B7E1180EDCA84F00F77EA2 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../../jpeg/jchuff.h; sourceTree = SOURCE_ROOT; };
-		00B7E1190EDCA84F00F77EA2 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../../jpeg/jconfig.h; sourceTree = SOURCE_ROOT; };
-		00B7E11A0EDCA84F00F77EA2 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../../jpeg/jerror.h; sourceTree = SOURCE_ROOT; };
-		00B7E11B0EDCA84F00F77EA2 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../../jpeg/jpeglib.h; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libjpeg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjpeg.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* jpeg */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E07E0EDCA73700F77EA2 /* SkImageDecoder_libjpeg.cpp */,
-				FE08AA3E0945D5620057213F /* Include */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = jpeg;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E0890EDCA78B00F77EA2 /* jcapimin.c */,
-				00B7E08A0EDCA78B00F77EA2 /* jcapistd.c */,
-				00B7E08B0EDCA78B00F77EA2 /* jccoefct.c */,
-				00B7E08C0EDCA78B00F77EA2 /* jccolor.c */,
-				00B7E08D0EDCA78B00F77EA2 /* jcdctmgr.c */,
-				00B7E08E0EDCA78B00F77EA2 /* jchuff.c */,
-				00B7E0900EDCA78B00F77EA2 /* jcinit.c */,
-				00B7E0910EDCA78B00F77EA2 /* jcmainct.c */,
-				00B7E0920EDCA78B00F77EA2 /* jcmarker.c */,
-				00B7E0930EDCA78B00F77EA2 /* jcmaster.c */,
-				00B7E0940EDCA78B00F77EA2 /* jcomapi.c */,
-				00B7E0A20EDCA78B00F77EA2 /* jcparam.c */,
-				00B7E0A30EDCA78B00F77EA2 /* jcphuff.c */,
-				00B7E0A40EDCA78B00F77EA2 /* jcprepct.c */,
-				00B7E0A50EDCA78B00F77EA2 /* jcsample.c */,
-				00B7E0A60EDCA78B00F77EA2 /* jctrans.c */,
-				00B7E0A70EDCA78B00F77EA2 /* jdapimin.c */,
-				00B7E0A80EDCA78B00F77EA2 /* jdapistd.c */,
-				00B7E0A90EDCA78B00F77EA2 /* jdatadst.c */,
-				00B7E0AA0EDCA78B00F77EA2 /* jdatasrc.c */,
-				00B7E0AB0EDCA78B00F77EA2 /* jdcoefct.c */,
-				00B7E0AC0EDCA78B00F77EA2 /* jdcolor.c */,
-				00B7E0AE0EDCA78B00F77EA2 /* jddctmgr.c */,
-				00B7E0AF0EDCA78B00F77EA2 /* jdhuff.c */,
-				00B7E0B10EDCA78B00F77EA2 /* jdinput.c */,
-				00B7E0B20EDCA78B00F77EA2 /* jdmainct.c */,
-				00B7E0B30EDCA78B00F77EA2 /* jdmarker.c */,
-				00B7E0B40EDCA78B00F77EA2 /* jdmaster.c */,
-				00B7E0B50EDCA78B00F77EA2 /* jdmerge.c */,
-				00B7E0B60EDCA78B00F77EA2 /* jdphuff.c */,
-				00B7E0B70EDCA78B00F77EA2 /* jdpostct.c */,
-				00B7E0B80EDCA78B00F77EA2 /* jdsample.c */,
-				00B7E0B90EDCA78B00F77EA2 /* jdtrans.c */,
-				00B7E0BA0EDCA78B00F77EA2 /* jerror.c */,
-				00B7E0BC0EDCA78B00F77EA2 /* jfdctflt.c */,
-				00B7E0BD0EDCA78B00F77EA2 /* jfdctfst.c */,
-				00B7E0BE0EDCA78B00F77EA2 /* jfdctint.c */,
-				00B7E0BF0EDCA78B00F77EA2 /* jidctflt.c */,
-				00B7E0C00EDCA78B00F77EA2 /* jidctfst.c */,
-				00B7E0C20EDCA78B00F77EA2 /* jidctint.c */,
-				00B7E0C30EDCA78B00F77EA2 /* jidctred.c */,
-				00B7E0C60EDCA78B00F77EA2 /* jmemansi.c */,
-				00B7E0CA0EDCA78B00F77EA2 /* jmemmgr.c */,
-				00B7E0D30EDCA78B00F77EA2 /* jquant1.c */,
-				00B7E0D40EDCA78B00F77EA2 /* jquant2.c */,
-				00B7E0D50EDCA78B00F77EA2 /* jutils.c */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libjpeg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-		FE08AA3E0945D5620057213F /* Include */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E1180EDCA84F00F77EA2 /* jchuff.h */,
-				00B7E1190EDCA84F00F77EA2 /* jconfig.h */,
-				00B7E11A0EDCA84F00F77EA2 /* jerror.h */,
-				00B7E11B0EDCA84F00F77EA2 /* jpeglib.h */,
-			);
-			name = Include;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E11C0EDCA84F00F77EA2 /* jchuff.h in Headers */,
-				00B7E11D0EDCA84F00F77EA2 /* jconfig.h in Headers */,
-				00B7E11E0EDCA84F00F77EA2 /* jerror.h in Headers */,
-				00B7E11F0EDCA84F00F77EA2 /* jpeglib.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* jpeg */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FE5F48080947840B0095980F /* Build configuration list for PBXNativeTarget "jpeg" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = jpeg;
-			productName = jpeg;
-			productReference = D2AAC046055464E500DB518D /* libjpeg.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = FE5F480C0947840B0095980F /* Build configuration list for PBXProject "jpeg" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* jpeg */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC045055464E500DB518D /* jpeg */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E07F0EDCA73700F77EA2 /* SkImageDecoder_libjpeg.cpp in Sources */,
-				00B7E0D60EDCA78B00F77EA2 /* jcapimin.c in Sources */,
-				00B7E0D70EDCA78B00F77EA2 /* jcapistd.c in Sources */,
-				00B7E0D80EDCA78B00F77EA2 /* jccoefct.c in Sources */,
-				00B7E0D90EDCA78B00F77EA2 /* jccolor.c in Sources */,
-				00B7E0DA0EDCA78B00F77EA2 /* jcdctmgr.c in Sources */,
-				00B7E0DB0EDCA78B00F77EA2 /* jchuff.c in Sources */,
-				00B7E0DD0EDCA78B00F77EA2 /* jcinit.c in Sources */,
-				00B7E0DE0EDCA78B00F77EA2 /* jcmainct.c in Sources */,
-				00B7E0DF0EDCA78B00F77EA2 /* jcmarker.c in Sources */,
-				00B7E0E00EDCA78B00F77EA2 /* jcmaster.c in Sources */,
-				00B7E0E10EDCA78B00F77EA2 /* jcomapi.c in Sources */,
-				00B7E0E30EDCA78B00F77EA2 /* jcparam.c in Sources */,
-				00B7E0E40EDCA78B00F77EA2 /* jcphuff.c in Sources */,
-				00B7E0E50EDCA78B00F77EA2 /* jcprepct.c in Sources */,
-				00B7E0E60EDCA78B00F77EA2 /* jcsample.c in Sources */,
-				00B7E0E70EDCA78B00F77EA2 /* jctrans.c in Sources */,
-				00B7E0E80EDCA78B00F77EA2 /* jdapimin.c in Sources */,
-				00B7E0E90EDCA78B00F77EA2 /* jdapistd.c in Sources */,
-				00B7E0EA0EDCA78B00F77EA2 /* jdatadst.c in Sources */,
-				00B7E0EB0EDCA78B00F77EA2 /* jdatasrc.c in Sources */,
-				00B7E0EC0EDCA78B00F77EA2 /* jdcoefct.c in Sources */,
-				00B7E0ED0EDCA78B00F77EA2 /* jdcolor.c in Sources */,
-				00B7E0EF0EDCA78B00F77EA2 /* jddctmgr.c in Sources */,
-				00B7E0F00EDCA78B00F77EA2 /* jdhuff.c in Sources */,
-				00B7E0F20EDCA78B00F77EA2 /* jdinput.c in Sources */,
-				00B7E0F30EDCA78B00F77EA2 /* jdmainct.c in Sources */,
-				00B7E0F40EDCA78B00F77EA2 /* jdmarker.c in Sources */,
-				00B7E0F50EDCA78B00F77EA2 /* jdmaster.c in Sources */,
-				00B7E0F60EDCA78B00F77EA2 /* jdmerge.c in Sources */,
-				00B7E0F70EDCA78B00F77EA2 /* jdphuff.c in Sources */,
-				00B7E0F80EDCA78B00F77EA2 /* jdpostct.c in Sources */,
-				00B7E0F90EDCA78B00F77EA2 /* jdsample.c in Sources */,
-				00B7E0FA0EDCA78B00F77EA2 /* jdtrans.c in Sources */,
-				00B7E0FB0EDCA78B00F77EA2 /* jerror.c in Sources */,
-				00B7E0FD0EDCA78B00F77EA2 /* jfdctflt.c in Sources */,
-				00B7E0FE0EDCA78B00F77EA2 /* jfdctfst.c in Sources */,
-				00B7E0FF0EDCA78B00F77EA2 /* jfdctint.c in Sources */,
-				00B7E1000EDCA78B00F77EA2 /* jidctflt.c in Sources */,
-				00B7E1010EDCA78B00F77EA2 /* jidctfst.c in Sources */,
-				00B7E1030EDCA78B00F77EA2 /* jidctint.c in Sources */,
-				00B7E1040EDCA78B00F77EA2 /* jidctred.c in Sources */,
-				00B7E1070EDCA78B00F77EA2 /* jmemansi.c in Sources */,
-				00B7E10B0EDCA78B00F77EA2 /* jmemmgr.c in Sources */,
-				00B7E1130EDCA78B00F77EA2 /* jquant1.c in Sources */,
-				00B7E1140EDCA78B00F77EA2 /* jquant2.c in Sources */,
-				00B7E1150EDCA78B00F77EA2 /* jutils.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		FE5F48090947840B0095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = jpeg;
-				PUBLIC_HEADERS_FOLDER_PATH = "";
-				REZ_PREPROCESSOR_DEFINITIONS = "_LIB SK_FORCE_SCALARFIXED";
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		FE5F480A0947840B0095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = jpeg;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		FE5F480D0947840B0095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_DEBUG,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Debug;
-		};
-		FE5F480E0947840B0095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_RELEASE,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		FE5F48080947840B0095980F /* Build configuration list for PBXNativeTarget "jpeg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F48090947840B0095980F /* Debug */,
-				FE5F480A0947840B0095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		FE5F480C0947840B0095980F /* Build configuration list for PBXProject "jpeg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F480D0947840B0095980F /* Debug */,
-				FE5F480E0947840B0095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/libpng.xcodeproj/project.pbxproj b/xcode/libpng.xcodeproj/project.pbxproj
deleted file mode 100644
index 7e12316..0000000
--- a/xcode/libpng.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,306 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E1390EDCA95200F77EA2 /* SkImageDecoder_libpng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1380EDCA95200F77EA2 /* SkImageDecoder_libpng.cpp */; };
-		00B7E14B0EDCA98D00F77EA2 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13A0EDCA98D00F77EA2 /* png.c */; };
-		00B7E14C0EDCA98D00F77EA2 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13B0EDCA98D00F77EA2 /* pngerror.c */; };
-		00B7E14D0EDCA98D00F77EA2 /* pnggccrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13C0EDCA98D00F77EA2 /* pnggccrd.c */; };
-		00B7E14E0EDCA98D00F77EA2 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13D0EDCA98D00F77EA2 /* pngget.c */; };
-		00B7E14F0EDCA98D00F77EA2 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13E0EDCA98D00F77EA2 /* pngmem.c */; };
-		00B7E1500EDCA98D00F77EA2 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E13F0EDCA98D00F77EA2 /* pngpread.c */; };
-		00B7E1510EDCA98D00F77EA2 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1400EDCA98D00F77EA2 /* pngread.c */; };
-		00B7E1520EDCA98D00F77EA2 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1410EDCA98D00F77EA2 /* pngrio.c */; };
-		00B7E1530EDCA98D00F77EA2 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1420EDCA98D00F77EA2 /* pngrtran.c */; };
-		00B7E1540EDCA98D00F77EA2 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1430EDCA98D00F77EA2 /* pngrutil.c */; };
-		00B7E1550EDCA98D00F77EA2 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1440EDCA98D00F77EA2 /* pngset.c */; };
-		00B7E1560EDCA98D00F77EA2 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1450EDCA98D00F77EA2 /* pngtrans.c */; };
-		00B7E1570EDCA98D00F77EA2 /* pngvcrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1460EDCA98D00F77EA2 /* pngvcrd.c */; };
-		00B7E1580EDCA98D00F77EA2 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1470EDCA98D00F77EA2 /* pngwio.c */; };
-		00B7E1590EDCA98D00F77EA2 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1480EDCA98D00F77EA2 /* pngwrite.c */; };
-		00B7E15A0EDCA98D00F77EA2 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1490EDCA98D00F77EA2 /* pngwtran.c */; };
-		00B7E15B0EDCA98D00F77EA2 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E14A0EDCA98D00F77EA2 /* pngwutil.c */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E1380EDCA95200F77EA2 /* SkImageDecoder_libpng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libpng.cpp; path = ../libsgl/images/SkImageDecoder_libpng.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E13A0EDCA98D00F77EA2 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../../libpng/png.c; sourceTree = SOURCE_ROOT; };
-		00B7E13B0EDCA98D00F77EA2 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../../libpng/pngerror.c; sourceTree = SOURCE_ROOT; };
-		00B7E13C0EDCA98D00F77EA2 /* pnggccrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pnggccrd.c; path = ../../libpng/pnggccrd.c; sourceTree = SOURCE_ROOT; };
-		00B7E13D0EDCA98D00F77EA2 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../../libpng/pngget.c; sourceTree = SOURCE_ROOT; };
-		00B7E13E0EDCA98D00F77EA2 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../../libpng/pngmem.c; sourceTree = SOURCE_ROOT; };
-		00B7E13F0EDCA98D00F77EA2 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../../libpng/pngpread.c; sourceTree = SOURCE_ROOT; };
-		00B7E1400EDCA98D00F77EA2 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../../libpng/pngread.c; sourceTree = SOURCE_ROOT; };
-		00B7E1410EDCA98D00F77EA2 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../../libpng/pngrio.c; sourceTree = SOURCE_ROOT; };
-		00B7E1420EDCA98D00F77EA2 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; };
-		00B7E1430EDCA98D00F77EA2 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; };
-		00B7E1440EDCA98D00F77EA2 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../../libpng/pngset.c; sourceTree = SOURCE_ROOT; };
-		00B7E1450EDCA98D00F77EA2 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; };
-		00B7E1460EDCA98D00F77EA2 /* pngvcrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngvcrd.c; path = ../../libpng/pngvcrd.c; sourceTree = SOURCE_ROOT; };
-		00B7E1470EDCA98D00F77EA2 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../../libpng/pngwio.c; sourceTree = SOURCE_ROOT; };
-		00B7E1480EDCA98D00F77EA2 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = ../../libpng/pngwrite.c; sourceTree = SOURCE_ROOT; };
-		00B7E1490EDCA98D00F77EA2 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; };
-		00B7E14A0EDCA98D00F77EA2 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* liblibpng.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblibpng.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* libpng */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E1380EDCA95200F77EA2 /* SkImageDecoder_libpng.cpp */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = libpng;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E13A0EDCA98D00F77EA2 /* png.c */,
-				00B7E13B0EDCA98D00F77EA2 /* pngerror.c */,
-				00B7E13C0EDCA98D00F77EA2 /* pnggccrd.c */,
-				00B7E13D0EDCA98D00F77EA2 /* pngget.c */,
-				00B7E13E0EDCA98D00F77EA2 /* pngmem.c */,
-				00B7E13F0EDCA98D00F77EA2 /* pngpread.c */,
-				00B7E1400EDCA98D00F77EA2 /* pngread.c */,
-				00B7E1410EDCA98D00F77EA2 /* pngrio.c */,
-				00B7E1420EDCA98D00F77EA2 /* pngrtran.c */,
-				00B7E1430EDCA98D00F77EA2 /* pngrutil.c */,
-				00B7E1440EDCA98D00F77EA2 /* pngset.c */,
-				00B7E1450EDCA98D00F77EA2 /* pngtrans.c */,
-				00B7E1460EDCA98D00F77EA2 /* pngvcrd.c */,
-				00B7E1470EDCA98D00F77EA2 /* pngwio.c */,
-				00B7E1480EDCA98D00F77EA2 /* pngwrite.c */,
-				00B7E1490EDCA98D00F77EA2 /* pngwtran.c */,
-				00B7E14A0EDCA98D00F77EA2 /* pngwutil.c */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* liblibpng.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* libpng */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FE5F4815094784400095980F /* Build configuration list for PBXNativeTarget "libpng" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = libpng;
-			productName = libpng;
-			productReference = D2AAC046055464E500DB518D /* liblibpng.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = FE5F4819094784400095980F /* Build configuration list for PBXProject "libpng" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* libpng */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC045055464E500DB518D /* libpng */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E1390EDCA95200F77EA2 /* SkImageDecoder_libpng.cpp in Sources */,
-				00B7E14B0EDCA98D00F77EA2 /* png.c in Sources */,
-				00B7E14C0EDCA98D00F77EA2 /* pngerror.c in Sources */,
-				00B7E14D0EDCA98D00F77EA2 /* pnggccrd.c in Sources */,
-				00B7E14E0EDCA98D00F77EA2 /* pngget.c in Sources */,
-				00B7E14F0EDCA98D00F77EA2 /* pngmem.c in Sources */,
-				00B7E1500EDCA98D00F77EA2 /* pngpread.c in Sources */,
-				00B7E1510EDCA98D00F77EA2 /* pngread.c in Sources */,
-				00B7E1520EDCA98D00F77EA2 /* pngrio.c in Sources */,
-				00B7E1530EDCA98D00F77EA2 /* pngrtran.c in Sources */,
-				00B7E1540EDCA98D00F77EA2 /* pngrutil.c in Sources */,
-				00B7E1550EDCA98D00F77EA2 /* pngset.c in Sources */,
-				00B7E1560EDCA98D00F77EA2 /* pngtrans.c in Sources */,
-				00B7E1570EDCA98D00F77EA2 /* pngvcrd.c in Sources */,
-				00B7E1580EDCA98D00F77EA2 /* pngwio.c in Sources */,
-				00B7E1590EDCA98D00F77EA2 /* pngwrite.c in Sources */,
-				00B7E15A0EDCA98D00F77EA2 /* pngwtran.c in Sources */,
-				00B7E15B0EDCA98D00F77EA2 /* pngwutil.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		FE5F4816094784400095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = (
-					../../include/graphics,
-					../../extlibs/png,
-					../../extlibs/zlib,
-				);
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = libpng;
-				REZ_PREPROCESSOR_DEFINITIONS = "_LIB PNG_USER_CONFIG SK_FORCE_SCALARFIXED";
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		FE5F4817094784400095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = libpng;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		FE5F481A094784400095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_DEBUG,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Debug;
-		};
-		FE5F481B094784400095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		FE5F4815094784400095980F /* Build configuration list for PBXNativeTarget "libpng" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F4816094784400095980F /* Debug */,
-				FE5F4817094784400095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		FE5F4819094784400095980F /* Build configuration list for PBXProject "libpng" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F481A094784400095980F /* Debug */,
-				FE5F481B094784400095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/ports-mac.xcodeproj/project.pbxproj b/xcode/ports-mac.xcodeproj/project.pbxproj
deleted file mode 100644
index e4aba44..0000000
--- a/xcode/ports-mac.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,248 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E16C0EDCA9EA00F77EA2 /* SkThread_pthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E16A0EDCA9EA00F77EA2 /* SkThread_pthread.cpp */; };
-		00B7E16D0EDCA9EA00F77EA2 /* SkTime_Unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E16B0EDCA9EA00F77EA2 /* SkTime_Unix.cpp */; };
-		00B7E16F0EDCA9FA00F77EA2 /* SkImageDecoder_wbmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E16E0EDCA9FA00F77EA2 /* SkImageDecoder_wbmp.cpp */; };
-		FE33C956094E031400C4A640 /* SkBitmap_Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE33C954094E031400C4A640 /* SkBitmap_Mac.cpp */; };
-		FE33C957094E031400C4A640 /* SkOSWindow_Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE33C955094E031400C4A640 /* SkOSWindow_Mac.cpp */; };
-		FE33C959094E041D00C4A640 /* skia_mac.cp in Sources */ = {isa = PBXBuildFile; fileRef = FE33C958094E041D00C4A640 /* skia_mac.cp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E16A0EDCA9EA00F77EA2 /* SkThread_pthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkThread_pthread.cpp; path = ../libsgl/ports/SkThread_pthread.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E16B0EDCA9EA00F77EA2 /* SkTime_Unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTime_Unix.cpp; path = ../libsgl/ports/SkTime_Unix.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E16E0EDCA9FA00F77EA2 /* SkImageDecoder_wbmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_wbmp.cpp; path = ../libsgl/images/SkImageDecoder_wbmp.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libports-mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libports-mac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
-		FE33C954094E031400C4A640 /* SkBitmap_Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap_Mac.cpp; path = ports/SkBitmap_Mac.cpp; sourceTree = "<group>"; };
-		FE33C955094E031400C4A640 /* SkOSWindow_Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSWindow_Mac.cpp; path = ports/SkOSWindow_Mac.cpp; sourceTree = "<group>"; };
-		FE33C958094E041D00C4A640 /* skia_mac.cp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = skia_mac.cp; path = ports/skia_mac.cp; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* ports-mac */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = "ports-mac";
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E16E0EDCA9FA00F77EA2 /* SkImageDecoder_wbmp.cpp */,
-				00B7E16A0EDCA9EA00F77EA2 /* SkThread_pthread.cpp */,
-				00B7E16B0EDCA9EA00F77EA2 /* SkTime_Unix.cpp */,
-				FE33C958094E041D00C4A640 /* skia_mac.cp */,
-				FE33C954094E031400C4A640 /* SkBitmap_Mac.cpp */,
-				FE33C955094E031400C4A640 /* SkOSWindow_Mac.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libports-mac.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* ports-mac */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "ports-mac" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "ports-mac";
-			productName = "ports-mac";
-			productReference = D2AAC046055464E500DB518D /* libports-mac.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "ports-mac" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* ports-mac */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				D2AAC045055464E500DB518D /* ports-mac */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				FE33C956094E031400C4A640 /* SkBitmap_Mac.cpp in Sources */,
-				FE33C957094E031400C4A640 /* SkOSWindow_Mac.cpp in Sources */,
-				FE33C959094E041D00C4A640 /* skia_mac.cp in Sources */,
-				00B7E16C0EDCA9EA00F77EA2 /* SkThread_pthread.cpp in Sources */,
-				00B7E16D0EDCA9EA00F77EA2 /* SkTime_Unix.cpp in Sources */,
-				00B7E16F0EDCA9FA00F77EA2 /* SkImageDecoder_wbmp.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_BUILD_FOR_MAC;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = "ports-mac";
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = "ports-mac";
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_BUILD_FOR_MAC;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "ports-mac" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "ports-mac" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/ports.xcodeproj/project.pbxproj b/xcode/ports.xcodeproj/project.pbxproj
deleted file mode 100644
index 7d22634..0000000
--- a/xcode/ports.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,251 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E18F0EDCAA5900F77EA2 /* bmpdecoderhelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E18D0EDCAA5900F77EA2 /* bmpdecoderhelper.cpp */; };
-		00B7E1900EDCAA5900F77EA2 /* SkImageDecoder_libbmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E18E0EDCAA5900F77EA2 /* SkImageDecoder_libbmp.cpp */; };
-		00B7E1950EDCAA9300F77EA2 /* SkFontHost_android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1910EDCAA9300F77EA2 /* SkFontHost_android.cpp */; };
-		00B7E1960EDCAA9300F77EA2 /* SkGlobals_global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1920EDCAA9300F77EA2 /* SkGlobals_global.cpp */; };
-		00B7E1970EDCAA9300F77EA2 /* SkImageDecoder_Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1930EDCAA9300F77EA2 /* SkImageDecoder_Factory.cpp */; };
-		00B7E1980EDCAA9300F77EA2 /* SkOSFile_stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1940EDCAA9300F77EA2 /* SkOSFile_stdio.cpp */; };
-		00B7E19A0EDCAAA100F77EA2 /* SkImageDecoder_libico.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1990EDCAAA100F77EA2 /* SkImageDecoder_libico.cpp */; };
-		00B7E3610EDCB05400F77EA2 /* SkFontHost_gamma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E3600EDCB05400F77EA2 /* SkFontHost_gamma.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E18D0EDCAA5900F77EA2 /* bmpdecoderhelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bmpdecoderhelper.cpp; path = ../libsgl/images/bmpdecoderhelper.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E18E0EDCAA5900F77EA2 /* SkImageDecoder_libbmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libbmp.cpp; path = ../libsgl/images/SkImageDecoder_libbmp.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1910EDCAA9300F77EA2 /* SkFontHost_android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_android.cpp; path = ../libsgl/ports/SkFontHost_android.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1920EDCAA9300F77EA2 /* SkGlobals_global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlobals_global.cpp; path = ../libsgl/ports/SkGlobals_global.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1930EDCAA9300F77EA2 /* SkImageDecoder_Factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_Factory.cpp; path = ../libsgl/ports/SkImageDecoder_Factory.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1940EDCAA9300F77EA2 /* SkOSFile_stdio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSFile_stdio.cpp; path = ../libsgl/ports/SkOSFile_stdio.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1990EDCAAA100F77EA2 /* SkImageDecoder_libico.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libico.cpp; path = ../libsgl/images/SkImageDecoder_libico.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E3600EDCB05400F77EA2 /* SkFontHost_gamma.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_gamma.cpp; path = ../libsgl/ports/SkFontHost_gamma.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libports.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libports.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* ports */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = ports;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E3600EDCB05400F77EA2 /* SkFontHost_gamma.cpp */,
-				00B7E1990EDCAAA100F77EA2 /* SkImageDecoder_libico.cpp */,
-				00B7E1910EDCAA9300F77EA2 /* SkFontHost_android.cpp */,
-				00B7E1920EDCAA9300F77EA2 /* SkGlobals_global.cpp */,
-				00B7E1930EDCAA9300F77EA2 /* SkImageDecoder_Factory.cpp */,
-				00B7E1940EDCAA9300F77EA2 /* SkOSFile_stdio.cpp */,
-				00B7E18D0EDCAA5900F77EA2 /* bmpdecoderhelper.cpp */,
-				00B7E18E0EDCAA5900F77EA2 /* SkImageDecoder_libbmp.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libports.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* ports */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "ports" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = ports;
-			productName = ports;
-			productReference = D2AAC046055464E500DB518D /* libports.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "ports" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* ports */;
-			projectDirPath = "";
-			projectRoot = ../..;
-			targets = (
-				D2AAC045055464E500DB518D /* ports */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E18F0EDCAA5900F77EA2 /* bmpdecoderhelper.cpp in Sources */,
-				00B7E1900EDCAA5900F77EA2 /* SkImageDecoder_libbmp.cpp in Sources */,
-				00B7E1950EDCAA9300F77EA2 /* SkFontHost_android.cpp in Sources */,
-				00B7E1960EDCAA9300F77EA2 /* SkGlobals_global.cpp in Sources */,
-				00B7E1970EDCAA9300F77EA2 /* SkImageDecoder_Factory.cpp in Sources */,
-				00B7E1980EDCAA9300F77EA2 /* SkOSFile_stdio.cpp in Sources */,
-				00B7E19A0EDCAAA100F77EA2 /* SkImageDecoder_libico.cpp in Sources */,
-				00B7E3610EDCB05400F77EA2 /* SkFontHost_gamma.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = ports;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = ports;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_BUILD_FOR_MAC;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_RELEASE,
-				);
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "ports" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "ports" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/ports/skia_mac.cp b/xcode/ports/skia_mac.cp
deleted file mode 100644
index 81b26e1..0000000
--- a/xcode/ports/skia_mac.cp
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "SkTypes.h"
-
-#if defined(SK_BUILD_FOR_MAC) && !defined(SK_USE_WXWIDGETS)
-#include <Carbon/Carbon.h>
-#include <unistd.h>
-#include <cerrno>
-#include "SkApplication.h"
-
-extern void get_preferred_size(int*, int*, int*, int* );
-
-int main(int argc, char* argv[])
-{
-    
-#if 0
-{
-	FILE* f = ::fopen("/whereami.txt", "w");
-	for (int i = 0; i < argc; i++)
-		fprintf(f, "[%d] %s\n", i, argv[i]);
-	::fclose(f);
-}
-#else
-// argv[0] is set to the execution path of the application, e.g. 
-// /Users/caryclark/android/device/build/ide/xcode/animatorTest/build/Debug/animatorTest.app/Contents/MacOS/animatorTest
-// the desired directory path is :
-// /Users/caryclark/android/device/jsapps
-// the variable (client-specific) part is :
-// /Users/caryclark/android/
-// since different applications share this library, they only have in common:
-// {client}/device/build/ide/xcode/{application}
-{
-	const char* applicationPath = argv[0];
-	const char* common = strstr(applicationPath, "build/ide/xcode/");
-	const char systemParent[] = "apps/"; 
-	if (common != 0) {
-		size_t prefixLength = common - applicationPath;
-		char* workingDirectory = new char[prefixLength + sizeof(systemParent)];
-		strncpy(workingDirectory, applicationPath, prefixLength);
-		strcpy(&workingDirectory[prefixLength], systemParent);
-		int error = chdir(workingDirectory);
-		if (error != 0) {
-			error = errno;
-			SkASSERT(error != ENOENT);
-			SkASSERT(error != ENOTDIR);
-			SkASSERT(error != EACCES);
-			SkASSERT(error != EIO);
-			SkASSERT(0);
-		}
-		delete workingDirectory;
-	}
-}
-#endif
-	IBNibRef 		nibRef;
-    WindowRef 		window;
-    
-    OSStatus		err;
-
-    // Create a Nib reference passing the name of the nib file (without the .nib extension)
-    // CreateNibReference only searches into the application bundle.
-    err = CreateNibReference(CFSTR("main"), &nibRef);
-    require_noerr( err, CantGetNibRef );
-    
-    // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
-    // object. This name is set in InterfaceBuilder when the nib is created.
-    err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
-    require_noerr( err, CantSetMenuBar );
-    
-    // Then create a window. "MainWindow" is the name of the window object. This name is set in 
-    // InterfaceBuilder when the nib is created.
-    err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
-    require_noerr( err, CantCreateWindow );
-
-    // We don't need the nib reference anymore.
-    DisposeNibReference(nibRef);
-    {
-	// if we get here, we can start our normal Skia sequence
-	application_init();
-	(void)create_sk_window(window);
-        int x =0, y =0, width =640, height=480;
-        get_preferred_size(&x, &y, &width, &height);
-        MoveWindow(window, x, y, false);
-        SizeWindow(window, width, height, false);
-    }
-    // The window was created hidden so show it.
-    ShowWindow( window );
-
-    // Call the event loop
-    RunApplicationEventLoop();
-	
-	application_term();
-
-CantCreateWindow:
-CantSetMenuBar:
-CantGetNibRef:
-	return err;
-}
-
-#endif
\ No newline at end of file
diff --git a/xcode/pvjpeg.xcodeproj/project.pbxproj b/xcode/pvjpeg.xcodeproj/project.pbxproj
deleted file mode 100644
index 5d09e2d..0000000
--- a/xcode/pvjpeg.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,261 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 44;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		007ECA0E0DA67F7B0086775A /* jpgdec_bitstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA010DA67F7B0086775A /* jpgdec_bitstream.cpp */; };
-		007ECA0F0DA67F7B0086775A /* jpgdec_cint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA020DA67F7B0086775A /* jpgdec_cint.cpp */; };
-		007ECA100DA67F7B0086775A /* jpgdec_colorconv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA030DA67F7B0086775A /* jpgdec_colorconv.cpp */; };
-		007ECA110DA67F7B0086775A /* jpgdec_ct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA040DA67F7B0086775A /* jpgdec_ct.cpp */; };
-		007ECA120DA67F7B0086775A /* jpgdec_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA050DA67F7B0086775A /* jpgdec_decoder.cpp */; };
-		007ECA130DA67F7B0086775A /* jpgdec_header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA060DA67F7B0086775A /* jpgdec_header.cpp */; };
-		007ECA140DA67F7B0086775A /* jpgdec_huffman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA070DA67F7B0086775A /* jpgdec_huffman.cpp */; };
-		007ECA150DA67F7B0086775A /* jpgdec_idctp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA080DA67F7B0086775A /* jpgdec_idctp.cpp */; };
-		007ECA160DA67F7B0086775A /* jpgdec_idcts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA090DA67F7B0086775A /* jpgdec_idcts.cpp */; };
-		007ECA170DA67F7B0086775A /* jpgdec_scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA0A0DA67F7B0086775A /* jpgdec_scan.cpp */; };
-		007ECA180DA67F7B0086775A /* jpgdec_table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA0B0DA67F7B0086775A /* jpgdec_table.cpp */; };
-		007ECA190DA67F7B0086775A /* jpgdec_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA0C0DA67F7B0086775A /* jpgdec_utils.cpp */; };
-		007ECA1A0DA67F7B0086775A /* pvjpgdecoder_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA0D0DA67F7B0086775A /* pvjpgdecoder_factory.cpp */; };
-		007ECA500DA683160086775A /* SkImageDecoder_libpvjpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007ECA4F0DA683160086775A /* SkImageDecoder_libpvjpeg.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		007ECA010DA67F7B0086775A /* jpgdec_bitstream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_bitstream.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_bitstream.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA020DA67F7B0086775A /* jpgdec_cint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_cint.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_cint.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA030DA67F7B0086775A /* jpgdec_colorconv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_colorconv.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_colorconv.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA040DA67F7B0086775A /* jpgdec_ct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_ct.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_ct.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA050DA67F7B0086775A /* jpgdec_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_decoder.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_decoder.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA060DA67F7B0086775A /* jpgdec_header.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_header.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_header.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA070DA67F7B0086775A /* jpgdec_huffman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_huffman.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_huffman.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA080DA67F7B0086775A /* jpgdec_idctp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_idctp.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_idctp.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA090DA67F7B0086775A /* jpgdec_idcts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_idcts.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_idcts.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA0A0DA67F7B0086775A /* jpgdec_scan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_scan.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_scan.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA0B0DA67F7B0086775A /* jpgdec_table.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_table.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_table.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA0C0DA67F7B0086775A /* jpgdec_utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jpgdec_utils.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/jpgdec_utils.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA0D0DA67F7B0086775A /* pvjpgdecoder_factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pvjpgdecoder_factory.cpp; path = ../../extlibs/pv/codecs_v2/image/jpeg/dec/src/pvjpgdecoder_factory.cpp; sourceTree = SOURCE_ROOT; };
-		007ECA4F0DA683160086775A /* SkImageDecoder_libpvjpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libpvjpeg.cpp; path = ../../libs/graphics/images/SkImageDecoder_libpvjpeg.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libpvjpeg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpvjpeg.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* pvjpeg */ = {
-			isa = PBXGroup;
-			children = (
-				007ECA4F0DA683160086775A /* SkImageDecoder_libpvjpeg.cpp */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = pvjpeg;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				007ECA010DA67F7B0086775A /* jpgdec_bitstream.cpp */,
-				007ECA020DA67F7B0086775A /* jpgdec_cint.cpp */,
-				007ECA030DA67F7B0086775A /* jpgdec_colorconv.cpp */,
-				007ECA040DA67F7B0086775A /* jpgdec_ct.cpp */,
-				007ECA050DA67F7B0086775A /* jpgdec_decoder.cpp */,
-				007ECA060DA67F7B0086775A /* jpgdec_header.cpp */,
-				007ECA070DA67F7B0086775A /* jpgdec_huffman.cpp */,
-				007ECA080DA67F7B0086775A /* jpgdec_idctp.cpp */,
-				007ECA090DA67F7B0086775A /* jpgdec_idcts.cpp */,
-				007ECA0A0DA67F7B0086775A /* jpgdec_scan.cpp */,
-				007ECA0B0DA67F7B0086775A /* jpgdec_table.cpp */,
-				007ECA0C0DA67F7B0086775A /* jpgdec_utils.cpp */,
-				007ECA0D0DA67F7B0086775A /* pvjpgdecoder_factory.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libpvjpeg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* pvjpeg */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "pvjpeg" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = pvjpeg;
-			productName = pvjpeg;
-			productReference = D2AAC046055464E500DB518D /* libpvjpeg.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "pvjpeg" */;
-			compatibilityVersion = "Xcode 3.0";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* pvjpeg */;
-			projectDirPath = "";
-			projectRoot = "";
-			targets = (
-				D2AAC045055464E500DB518D /* pvjpeg */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				007ECA0E0DA67F7B0086775A /* jpgdec_bitstream.cpp in Sources */,
-				007ECA0F0DA67F7B0086775A /* jpgdec_cint.cpp in Sources */,
-				007ECA100DA67F7B0086775A /* jpgdec_colorconv.cpp in Sources */,
-				007ECA110DA67F7B0086775A /* jpgdec_ct.cpp in Sources */,
-				007ECA120DA67F7B0086775A /* jpgdec_decoder.cpp in Sources */,
-				007ECA130DA67F7B0086775A /* jpgdec_header.cpp in Sources */,
-				007ECA140DA67F7B0086775A /* jpgdec_huffman.cpp in Sources */,
-				007ECA150DA67F7B0086775A /* jpgdec_idctp.cpp in Sources */,
-				007ECA160DA67F7B0086775A /* jpgdec_idcts.cpp in Sources */,
-				007ECA170DA67F7B0086775A /* jpgdec_scan.cpp in Sources */,
-				007ECA180DA67F7B0086775A /* jpgdec_table.cpp in Sources */,
-				007ECA190DA67F7B0086775A /* jpgdec_utils.cpp in Sources */,
-				007ECA1A0DA67F7B0086775A /* pvjpgdecoder_factory.cpp in Sources */,
-				007ECA500DA683160086775A /* SkImageDecoder_libpvjpeg.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = pvjpeg;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = pvjpeg;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = "USE_PV_OSCL_LIB=0";
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../../extlibs/pv/** ../../include/corecg ../../include/graphics";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = (
-					ppc,
-					i386,
-				);
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = "USE_PV_OSCL_LIB=0";
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
-				USER_HEADER_SEARCH_PATHS = "../../extlibs/pv/** ../../include/corecg ../../include/graphics";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "pvjpeg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "pvjpeg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/skia2.xcodeproj/project.pbxproj b/xcode/skia2.xcodeproj/project.pbxproj
deleted file mode 100644
index 1a27e69..0000000
--- a/xcode/skia2.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1389 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		003E926F0EED78220091D85B /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00A5676D0EED77850096A2A1 /* libfreetype.a */; };
-		006B43FE0EF7526E00F15BC4 /* SkString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 006B43FC0EF7526E00F15BC4 /* SkString.cpp */; };
-		006B43FF0EF7526E00F15BC4 /* SkUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 006B43FD0EF7526E00F15BC4 /* SkUtils.cpp */; };
-		00A567300EED6F6E0096A2A1 /* libgiflib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00BE44670EE9D1780008420F /* libgiflib.a */; };
-		00AFCD710EF1672C00BD2FF1 /* SkDOM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD700EF1672C00BD2FF1 /* SkDOM.cpp */; };
-		00AFCD7C0EF167BC00BD2FF1 /* SkParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD790EF167BC00BD2FF1 /* SkParse.cpp */; };
-		00AFCD7D0EF167BC00BD2FF1 /* SkParseColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD7A0EF167BC00BD2FF1 /* SkParseColor.cpp */; };
-		00AFCD7E0EF167BC00BD2FF1 /* SkXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD7B0EF167BC00BD2FF1 /* SkXMLParser.cpp */; };
-		00AFCD890EF1684200BD2FF1 /* SkBitmap_Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD880EF1684200BD2FF1 /* SkBitmap_Mac.cpp */; };
-		00AFCD8B0EF1685100BD2FF1 /* SkOSWindow_Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AFCD8A0EF1685100BD2FF1 /* SkOSWindow_Mac.cpp */; };
-		00AFCE240EF16C0500BD2FF1 /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00AFCE150EF16BA400BD2FF1 /* libexpat.a */; };
-		00BE435D0EE9CDFA0008420F /* Sk1DPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42800EE9CDFA0008420F /* Sk1DPathEffect.cpp */; };
-		00BE435E0EE9CDFA0008420F /* Sk2DPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42810EE9CDFA0008420F /* Sk2DPathEffect.cpp */; };
-		00BE435F0EE9CDFA0008420F /* SkAvoidXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42820EE9CDFA0008420F /* SkAvoidXfermode.cpp */; };
-		00BE43600EE9CDFA0008420F /* SkBlurDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42830EE9CDFA0008420F /* SkBlurDrawLooper.cpp */; };
-		00BE43610EE9CDFA0008420F /* SkBlurMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42840EE9CDFA0008420F /* SkBlurMask.cpp */; };
-		00BE43620EE9CDFA0008420F /* SkBlurMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42850EE9CDFA0008420F /* SkBlurMask.h */; };
-		00BE43630EE9CDFA0008420F /* SkBlurMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42860EE9CDFA0008420F /* SkBlurMaskFilter.cpp */; };
-		00BE43640EE9CDFA0008420F /* SkCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42870EE9CDFA0008420F /* SkCamera.cpp */; };
-		00BE43650EE9CDFA0008420F /* SkColorFilters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42880EE9CDFA0008420F /* SkColorFilters.cpp */; };
-		00BE43660EE9CDFA0008420F /* SkColorMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42890EE9CDFA0008420F /* SkColorMatrix.cpp */; };
-		00BE43670EE9CDFA0008420F /* SkColorMatrixFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428A0EE9CDFA0008420F /* SkColorMatrixFilter.cpp */; };
-		00BE43680EE9CDFA0008420F /* SkCornerPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428B0EE9CDFA0008420F /* SkCornerPathEffect.cpp */; };
-		00BE43690EE9CDFA0008420F /* SkCullPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428C0EE9CDFA0008420F /* SkCullPoints.cpp */; };
-		00BE436A0EE9CDFA0008420F /* SkDashPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428D0EE9CDFA0008420F /* SkDashPathEffect.cpp */; };
-		00BE436B0EE9CDFA0008420F /* SkDiscretePathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428E0EE9CDFA0008420F /* SkDiscretePathEffect.cpp */; };
-		00BE436C0EE9CDFA0008420F /* SkDumpCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE428F0EE9CDFA0008420F /* SkDumpCanvas.cpp */; };
-		00BE436D0EE9CDFA0008420F /* SkEmbossMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42900EE9CDFA0008420F /* SkEmbossMask.cpp */; };
-		00BE436E0EE9CDFA0008420F /* SkEmbossMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42910EE9CDFA0008420F /* SkEmbossMask.h */; };
-		00BE436F0EE9CDFA0008420F /* SkEmbossMask_Table.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42920EE9CDFA0008420F /* SkEmbossMask_Table.h */; };
-		00BE43700EE9CDFA0008420F /* SkEmbossMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42930EE9CDFA0008420F /* SkEmbossMaskFilter.cpp */; };
-		00BE43710EE9CDFA0008420F /* SkGradientShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42940EE9CDFA0008420F /* SkGradientShader.cpp */; };
-		00BE43720EE9CDFA0008420F /* SkKernel33MaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42950EE9CDFA0008420F /* SkKernel33MaskFilter.cpp */; };
-		00BE43730EE9CDFA0008420F /* SkLayerDrawLooper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42960EE9CDFA0008420F /* SkLayerDrawLooper.cpp */; };
-		00BE43740EE9CDFA0008420F /* SkLayerRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42970EE9CDFA0008420F /* SkLayerRasterizer.cpp */; };
-		00BE43750EE9CDFA0008420F /* SkNinePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42980EE9CDFA0008420F /* SkNinePatch.cpp */; };
-		00BE43760EE9CDFA0008420F /* SkPaintFlagsDrawFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42990EE9CDFA0008420F /* SkPaintFlagsDrawFilter.cpp */; };
-		00BE43770EE9CDFA0008420F /* SkPixelXorXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE429A0EE9CDFA0008420F /* SkPixelXorXfermode.cpp */; };
-		00BE43780EE9CDFA0008420F /* SkProxyCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE429B0EE9CDFA0008420F /* SkProxyCanvas.cpp */; };
-		00BE43790EE9CDFA0008420F /* SkRadialGradient_Table.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE429C0EE9CDFA0008420F /* SkRadialGradient_Table.h */; };
-		00BE437A0EE9CDFA0008420F /* SkShaderExtras.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE429D0EE9CDFA0008420F /* SkShaderExtras.cpp */; };
-		00BE437B0EE9CDFA0008420F /* SkTransparentShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE429E0EE9CDFA0008420F /* SkTransparentShader.cpp */; };
-		00BE437C0EE9CDFA0008420F /* SkUnitMappers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE429F0EE9CDFA0008420F /* SkUnitMappers.cpp */; };
-		00BE437D0EE9CDFA0008420F /* SkBGViewArtist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A10EE9CDFA0008420F /* SkBGViewArtist.cpp */; };
-		00BE437E0EE9CDFA0008420F /* SkBorderView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A20EE9CDFA0008420F /* SkBorderView.cpp */; };
-		00BE437F0EE9CDFA0008420F /* SkEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A30EE9CDFA0008420F /* SkEvent.cpp */; };
-		00BE43800EE9CDFA0008420F /* SkEventSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A40EE9CDFA0008420F /* SkEventSink.cpp */; };
-		00BE43810EE9CDFA0008420F /* SkImageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A50EE9CDFA0008420F /* SkImageView.cpp */; };
-		00BE43820EE9CDFA0008420F /* SkListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A60EE9CDFA0008420F /* SkListView.cpp */; };
-		00BE43830EE9CDFA0008420F /* SkListWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A70EE9CDFA0008420F /* SkListWidget.cpp */; };
-		00BE43840EE9CDFA0008420F /* SkMetaData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A80EE9CDFA0008420F /* SkMetaData.cpp */; };
-		00BE43850EE9CDFA0008420F /* SkOSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42A90EE9CDFA0008420F /* SkOSFile.cpp */; };
-		00BE43860EE9CDFA0008420F /* SkOSMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AA0EE9CDFA0008420F /* SkOSMenu.cpp */; };
-		00BE43870EE9CDFA0008420F /* SkOSSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AB0EE9CDFA0008420F /* SkOSSound.cpp */; };
-		00BE43880EE9CDFA0008420F /* SkParsePaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AC0EE9CDFA0008420F /* SkParsePaint.cpp */; };
-		00BE43890EE9CDFA0008420F /* SkProgressBarView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AD0EE9CDFA0008420F /* SkProgressBarView.cpp */; };
-		00BE438A0EE9CDFA0008420F /* SkProgressView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AE0EE9CDFA0008420F /* SkProgressView.cpp */; };
-		00BE438B0EE9CDFA0008420F /* SkScrollBarView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42AF0EE9CDFA0008420F /* SkScrollBarView.cpp */; };
-		00BE438C0EE9CDFA0008420F /* SkStackViewLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B00EE9CDFA0008420F /* SkStackViewLayout.cpp */; };
-		00BE438D0EE9CDFA0008420F /* SkTagList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B10EE9CDFA0008420F /* SkTagList.cpp */; };
-		00BE438E0EE9CDFA0008420F /* SkTagList.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42B20EE9CDFA0008420F /* SkTagList.h */; };
-		00BE438F0EE9CDFA0008420F /* SkTextBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B30EE9CDFA0008420F /* SkTextBox.cpp */; };
-		00BE43900EE9CDFA0008420F /* SkView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B40EE9CDFA0008420F /* SkView.cpp */; };
-		00BE43910EE9CDFA0008420F /* SkViewInflate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B50EE9CDFA0008420F /* SkViewInflate.cpp */; };
-		00BE43920EE9CDFA0008420F /* SkViewPriv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B60EE9CDFA0008420F /* SkViewPriv.cpp */; };
-		00BE43930EE9CDFA0008420F /* SkViewPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42B70EE9CDFA0008420F /* SkViewPriv.h */; };
-		00BE43940EE9CDFA0008420F /* SkWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B80EE9CDFA0008420F /* SkWidget.cpp */; };
-		00BE43950EE9CDFA0008420F /* SkWidgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42B90EE9CDFA0008420F /* SkWidgets.cpp */; };
-		00BE43960EE9CDFA0008420F /* SkWidgetViews.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42BA0EE9CDFA0008420F /* SkWidgetViews.cpp */; };
-		00BE43970EE9CDFA0008420F /* SkWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42BB0EE9CDFA0008420F /* SkWindow.cpp */; };
-		00BE43980EE9CDFA0008420F /* SkFDStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42BD0EE9CDFA0008420F /* SkFDStream.cpp */; };
-		00BE43990EE9CDFA0008420F /* SkFlipPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42BE0EE9CDFA0008420F /* SkFlipPixelRef.cpp */; };
-		00BE439A0EE9CDFA0008420F /* SkImageDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42BF0EE9CDFA0008420F /* SkImageDecoder.cpp */; };
-		00BE439C0EE9CDFA0008420F /* SkImageDecoder_libbmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42C10EE9CDFA0008420F /* SkImageDecoder_libbmp.cpp */; };
-		00BE439E0EE9CDFA0008420F /* SkImageDecoder_libico.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42C30EE9CDFA0008420F /* SkImageDecoder_libico.cpp */; };
-		00BE43A20EE9CDFA0008420F /* SkImageDecoder_wbmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42C70EE9CDFA0008420F /* SkImageDecoder_wbmp.cpp */; };
-		00BE43A30EE9CDFA0008420F /* SkImageRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42C80EE9CDFA0008420F /* SkImageRef.cpp */; };
-		00BE43A40EE9CDFA0008420F /* SkImageRef_GlobalPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42C90EE9CDFA0008420F /* SkImageRef_GlobalPool.cpp */; };
-		00BE43A50EE9CDFA0008420F /* SkImageRefPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42CA0EE9CDFA0008420F /* SkImageRefPool.cpp */; };
-		00BE43A60EE9CDFA0008420F /* SkImageRefPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42CB0EE9CDFA0008420F /* SkImageRefPool.h */; };
-		00BE43A70EE9CDFA0008420F /* SkMMapStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42CC0EE9CDFA0008420F /* SkMMapStream.cpp */; };
-		00BE43A80EE9CDFA0008420F /* SkMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42CD0EE9CDFA0008420F /* SkMovie.cpp */; };
-		00BE43AA0EE9CDFA0008420F /* SkScaledBitmapSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42CF0EE9CDFA0008420F /* SkScaledBitmapSampler.cpp */; };
-		00BE43AB0EE9CDFA0008420F /* SkScaledBitmapSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42D00EE9CDFA0008420F /* SkScaledBitmapSampler.h */; };
-		00BE43AC0EE9CDFA0008420F /* SkStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D10EE9CDFA0008420F /* SkStream.cpp */; };
-		00BE43AD0EE9CDFA0008420F /* SkFontHost_android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D30EE9CDFA0008420F /* SkFontHost_android.cpp */; };
-		00BE43AE0EE9CDFA0008420F /* SkFontHost_gamma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D40EE9CDFA0008420F /* SkFontHost_gamma.cpp */; };
-		00BE43AF0EE9CDFA0008420F /* SkGlobals_global.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D50EE9CDFA0008420F /* SkGlobals_global.cpp */; };
-		00BE43B00EE9CDFA0008420F /* SkImageDecoder_Factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D60EE9CDFA0008420F /* SkImageDecoder_Factory.cpp */; };
-		00BE43B10EE9CDFA0008420F /* SkThread_pthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D70EE9CDFA0008420F /* SkThread_pthread.cpp */; };
-		00BE43B20EE9CDFA0008420F /* SkTime_Unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42D80EE9CDFA0008420F /* SkTime_Unix.cpp */; };
-		00BE43B30EE9CDFA0008420F /* SkPathHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42DA0EE9CDFA0008420F /* SkPathHeap.cpp */; };
-		00BE43B40EE9CDFA0008420F /* SkPathHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42DB0EE9CDFA0008420F /* SkPathHeap.h */; };
-		00BE43B50EE9CDFA0008420F /* SkPicture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42DC0EE9CDFA0008420F /* SkPicture.cpp */; };
-		00BE43B60EE9CDFA0008420F /* SkPictureFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42DD0EE9CDFA0008420F /* SkPictureFlat.cpp */; };
-		00BE43B70EE9CDFA0008420F /* SkPictureFlat.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42DE0EE9CDFA0008420F /* SkPictureFlat.h */; };
-		00BE43B80EE9CDFA0008420F /* SkPicturePlayback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42DF0EE9CDFA0008420F /* SkPicturePlayback.cpp */; };
-		00BE43B90EE9CDFA0008420F /* SkPicturePlayback.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42E00EE9CDFA0008420F /* SkPicturePlayback.h */; };
-		00BE43BA0EE9CDFA0008420F /* SkPictureRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42E10EE9CDFA0008420F /* SkPictureRecord.cpp */; };
-		00BE43BB0EE9CDFA0008420F /* SkPictureRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42E20EE9CDFA0008420F /* SkPictureRecord.h */; };
-		00BE43BC0EE9CDFA0008420F /* SkGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42E30EE9CDFA0008420F /* SkGL.cpp */; };
-		00BE43BD0EE9CDFA0008420F /* SkGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42E40EE9CDFA0008420F /* SkGL.h */; };
-		00BE43BE0EE9CDFA0008420F /* SkGLCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42E50EE9CDFA0008420F /* SkGLCanvas.cpp */; };
-		00BE43BF0EE9CDFA0008420F /* SkGLDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42E60EE9CDFA0008420F /* SkGLDevice.cpp */; };
-		00BE43C00EE9CDFA0008420F /* SkGLDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42E70EE9CDFA0008420F /* SkGLDevice.h */; };
-		00BE43C10EE9CDFA0008420F /* SkGLDevice_FBO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42E80EE9CDFA0008420F /* SkGLDevice_FBO.cpp */; };
-		00BE43C20EE9CDFA0008420F /* SkGLDevice_FBO.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42E90EE9CDFA0008420F /* SkGLDevice_FBO.h */; };
-		00BE43C30EE9CDFA0008420F /* SkGLDevice_SWLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42EA0EE9CDFA0008420F /* SkGLDevice_SWLayer.cpp */; };
-		00BE43C40EE9CDFA0008420F /* SkGLDevice_SWLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42EB0EE9CDFA0008420F /* SkGLDevice_SWLayer.h */; };
-		00BE43C50EE9CDFA0008420F /* SkGLTextCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42EC0EE9CDFA0008420F /* SkGLTextCache.cpp */; };
-		00BE43C60EE9CDFA0008420F /* SkGLTextCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42ED0EE9CDFA0008420F /* SkGLTextCache.h */; };
-		00BE43C70EE9CDFA0008420F /* SkTextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42EE0EE9CDFA0008420F /* SkTextureCache.cpp */; };
-		00BE43C80EE9CDFA0008420F /* SkTextureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42EF0EE9CDFA0008420F /* SkTextureCache.h */; };
-		00BE43C90EE9CDFA0008420F /* SkAlphaRuns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42F00EE9CDFA0008420F /* SkAlphaRuns.cpp */; };
-		00BE43CA0EE9CDFA0008420F /* SkAntiRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42F10EE9CDFA0008420F /* SkAntiRun.h */; };
-		00BE43CB0EE9CDFA0008420F /* SkAutoKern.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42F20EE9CDFA0008420F /* SkAutoKern.h */; };
-		00BE43CC0EE9CDFA0008420F /* SkBitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42F30EE9CDFA0008420F /* SkBitmap.cpp */; };
-		00BE43CD0EE9CDFA0008420F /* SkBitmap_scroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42F40EE9CDFA0008420F /* SkBitmap_scroll.cpp */; };
-		00BE43CE0EE9CDFA0008420F /* SkBitmapProcShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42F50EE9CDFA0008420F /* SkBitmapProcShader.cpp */; };
-		00BE43CF0EE9CDFA0008420F /* SkBitmapProcShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42F60EE9CDFA0008420F /* SkBitmapProcShader.h */; };
-		00BE43D00EE9CDFA0008420F /* SkBitmapProcState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42F70EE9CDFA0008420F /* SkBitmapProcState.cpp */; };
-		00BE43D10EE9CDFA0008420F /* SkBitmapProcState.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42F80EE9CDFA0008420F /* SkBitmapProcState.h */; };
-		00BE43D20EE9CDFA0008420F /* SkBitmapProcState_matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42F90EE9CDFA0008420F /* SkBitmapProcState_matrix.h */; };
-		00BE43D30EE9CDFA0008420F /* SkBitmapProcState_matrixProcs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42FA0EE9CDFA0008420F /* SkBitmapProcState_matrixProcs.cpp */; };
-		00BE43D40EE9CDFA0008420F /* SkBitmapProcState_sample.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42FB0EE9CDFA0008420F /* SkBitmapProcState_sample.h */; };
-		00BE43D50EE9CDFA0008420F /* SkBitmapSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42FC0EE9CDFA0008420F /* SkBitmapSampler.cpp */; };
-		00BE43D60EE9CDFA0008420F /* SkBitmapSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42FD0EE9CDFA0008420F /* SkBitmapSampler.h */; };
-		00BE43D70EE9CDFA0008420F /* SkBitmapSamplerTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE42FE0EE9CDFA0008420F /* SkBitmapSamplerTemplate.h */; };
-		00BE43D80EE9CDFA0008420F /* SkBitmapShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE42FF0EE9CDFA0008420F /* SkBitmapShader.cpp */; };
-		00BE43D90EE9CDFA0008420F /* SkBitmapShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43000EE9CDFA0008420F /* SkBitmapShader.h */; };
-		00BE43DA0EE9CDFA0008420F /* SkBitmapShader16BilerpTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43010EE9CDFA0008420F /* SkBitmapShader16BilerpTemplate.h */; };
-		00BE43DB0EE9CDFA0008420F /* SkBitmapShaderTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43020EE9CDFA0008420F /* SkBitmapShaderTemplate.h */; };
-		00BE43DC0EE9CDFA0008420F /* SkBlitBWMaskTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43030EE9CDFA0008420F /* SkBlitBWMaskTemplate.h */; };
-		00BE43DD0EE9CDFA0008420F /* SkBlitRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43040EE9CDFA0008420F /* SkBlitRow.h */; };
-		00BE43DE0EE9CDFA0008420F /* SkBlitRow_D16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43050EE9CDFA0008420F /* SkBlitRow_D16.cpp */; };
-		00BE43DF0EE9CDFA0008420F /* SkBlitRow_D4444.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43060EE9CDFA0008420F /* SkBlitRow_D4444.cpp */; };
-		00BE43E00EE9CDFA0008420F /* SkBlitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43070EE9CDFA0008420F /* SkBlitter.cpp */; };
-		00BE43E10EE9CDFA0008420F /* SkBlitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43080EE9CDFA0008420F /* SkBlitter.h */; };
-		00BE43E20EE9CDFA0008420F /* SkBlitter_4444.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43090EE9CDFA0008420F /* SkBlitter_4444.cpp */; };
-		00BE43E30EE9CDFA0008420F /* SkBlitter_A1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430A0EE9CDFA0008420F /* SkBlitter_A1.cpp */; };
-		00BE43E40EE9CDFA0008420F /* SkBlitter_A8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430B0EE9CDFA0008420F /* SkBlitter_A8.cpp */; };
-		00BE43E50EE9CDFA0008420F /* SkBlitter_ARGB32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430C0EE9CDFA0008420F /* SkBlitter_ARGB32.cpp */; };
-		00BE43E60EE9CDFA0008420F /* SkBlitter_RGB16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430D0EE9CDFA0008420F /* SkBlitter_RGB16.cpp */; };
-		00BE43E70EE9CDFA0008420F /* SkBlitter_Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430E0EE9CDFA0008420F /* SkBlitter_Sprite.cpp */; };
-		00BE43E80EE9CDFA0008420F /* SkCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE430F0EE9CDFA0008420F /* SkCanvas.cpp */; };
-		00BE43E90EE9CDFA0008420F /* SkColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43100EE9CDFA0008420F /* SkColor.cpp */; };
-		00BE43EA0EE9CDFA0008420F /* SkColorFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43110EE9CDFA0008420F /* SkColorFilter.cpp */; };
-		00BE43EB0EE9CDFA0008420F /* SkColorTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43120EE9CDFA0008420F /* SkColorTable.cpp */; };
-		00BE43EC0EE9CDFA0008420F /* SkCoreBlitters.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43130EE9CDFA0008420F /* SkCoreBlitters.h */; };
-		00BE43ED0EE9CDFA0008420F /* SkDeque.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43140EE9CDFA0008420F /* SkDeque.cpp */; };
-		00BE43EE0EE9CDFA0008420F /* SkDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43150EE9CDFA0008420F /* SkDevice.cpp */; };
-		00BE43EF0EE9CDFA0008420F /* SkDither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43160EE9CDFA0008420F /* SkDither.cpp */; };
-		00BE43F00EE9CDFA0008420F /* SkDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43170EE9CDFA0008420F /* SkDraw.cpp */; };
-		00BE43F10EE9CDFA0008420F /* SkDrawProcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43180EE9CDFA0008420F /* SkDrawProcs.h */; };
-		00BE43F20EE9CDFA0008420F /* SkEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43190EE9CDFA0008420F /* SkEdge.cpp */; };
-		00BE43F30EE9CDFA0008420F /* SkEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE431A0EE9CDFA0008420F /* SkEdge.h */; };
-		00BE43F40EE9CDFA0008420F /* SkFilterProc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE431B0EE9CDFA0008420F /* SkFilterProc.cpp */; };
-		00BE43F50EE9CDFA0008420F /* SkFilterProc.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE431C0EE9CDFA0008420F /* SkFilterProc.h */; };
-		00BE43F60EE9CDFA0008420F /* SkFlattenable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE431D0EE9CDFA0008420F /* SkFlattenable.cpp */; };
-		00BE43F70EE9CDFA0008420F /* SkFP.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE431E0EE9CDFA0008420F /* SkFP.h */; };
-		00BE43F80EE9CDFA0008420F /* SkGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE431F0EE9CDFA0008420F /* SkGeometry.cpp */; };
-		00BE43F90EE9CDFA0008420F /* SkGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43200EE9CDFA0008420F /* SkGeometry.h */; };
-		00BE43FA0EE9CDFA0008420F /* SkGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43210EE9CDFA0008420F /* SkGlobals.cpp */; };
-		00BE43FB0EE9CDFA0008420F /* SkGlyphCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43220EE9CDFA0008420F /* SkGlyphCache.cpp */; };
-		00BE43FC0EE9CDFA0008420F /* SkGlyphCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43230EE9CDFA0008420F /* SkGlyphCache.h */; };
-		00BE43FD0EE9CDFA0008420F /* SkGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43240EE9CDFA0008420F /* SkGraphics.cpp */; };
-		00BE43FE0EE9CDFA0008420F /* SkMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43250EE9CDFA0008420F /* SkMask.cpp */; };
-		00BE43FF0EE9CDFA0008420F /* SkMaskFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43260EE9CDFA0008420F /* SkMaskFilter.cpp */; };
-		00BE44000EE9CDFA0008420F /* SkPackBits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43270EE9CDFA0008420F /* SkPackBits.cpp */; };
-		00BE44010EE9CDFA0008420F /* SkPaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43280EE9CDFA0008420F /* SkPaint.cpp */; };
-		00BE44020EE9CDFA0008420F /* SkPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43290EE9CDFA0008420F /* SkPath.cpp */; };
-		00BE44030EE9CDFA0008420F /* SkPathEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432A0EE9CDFA0008420F /* SkPathEffect.cpp */; };
-		00BE44040EE9CDFA0008420F /* SkPathMeasure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432B0EE9CDFA0008420F /* SkPathMeasure.cpp */; };
-		00BE44050EE9CDFA0008420F /* SkPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432C0EE9CDFA0008420F /* SkPixelRef.cpp */; };
-		00BE44060EE9CDFA0008420F /* SkProcSpriteBlitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432D0EE9CDFA0008420F /* SkProcSpriteBlitter.cpp */; };
-		00BE44070EE9CDFA0008420F /* SkPtrRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432E0EE9CDFA0008420F /* SkPtrRecorder.cpp */; };
-		00BE44080EE9CDFA0008420F /* SkRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE432F0EE9CDFA0008420F /* SkRasterizer.cpp */; };
-		00BE44090EE9CDFA0008420F /* SkRefCnt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43300EE9CDFA0008420F /* SkRefCnt.cpp */; };
-		00BE440A0EE9CDFA0008420F /* SkRegion_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43310EE9CDFA0008420F /* SkRegion_path.cpp */; };
-		00BE440B0EE9CDFA0008420F /* SkScalerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43320EE9CDFA0008420F /* SkScalerContext.cpp */; };
-		00BE440C0EE9CDFA0008420F /* SkScan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43330EE9CDFA0008420F /* SkScan.cpp */; };
-		00BE440D0EE9CDFA0008420F /* SkScan.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43340EE9CDFA0008420F /* SkScan.h */; };
-		00BE440E0EE9CDFA0008420F /* SkScan_Antihair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43350EE9CDFA0008420F /* SkScan_Antihair.cpp */; };
-		00BE440F0EE9CDFA0008420F /* SkScan_AntiPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43360EE9CDFA0008420F /* SkScan_AntiPath.cpp */; };
-		00BE44100EE9CDFA0008420F /* SkScan_Hairline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43370EE9CDFA0008420F /* SkScan_Hairline.cpp */; };
-		00BE44110EE9CDFA0008420F /* SkScan_Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43380EE9CDFA0008420F /* SkScan_Path.cpp */; };
-		00BE44120EE9CDFA0008420F /* SkScanPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43390EE9CDFA0008420F /* SkScanPriv.h */; };
-		00BE44130EE9CDFA0008420F /* SkShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE433A0EE9CDFA0008420F /* SkShader.cpp */; };
-		00BE44140EE9CDFA0008420F /* SkSpriteBlitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE433B0EE9CDFA0008420F /* SkSpriteBlitter.h */; };
-		00BE44150EE9CDFA0008420F /* SkSpriteBlitter_ARGB32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE433C0EE9CDFA0008420F /* SkSpriteBlitter_ARGB32.cpp */; };
-		00BE44160EE9CDFA0008420F /* SkSpriteBlitter_RGB16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE433D0EE9CDFA0008420F /* SkSpriteBlitter_RGB16.cpp */; };
-		00BE44170EE9CDFA0008420F /* SkSpriteBlitterTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE433E0EE9CDFA0008420F /* SkSpriteBlitterTemplate.h */; };
-		00BE44190EE9CDFA0008420F /* SkStroke.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43400EE9CDFA0008420F /* SkStroke.cpp */; };
-		00BE441A0EE9CDFA0008420F /* SkStrokerPriv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43410EE9CDFA0008420F /* SkStrokerPriv.cpp */; };
-		00BE441B0EE9CDFA0008420F /* SkStrokerPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43420EE9CDFA0008420F /* SkStrokerPriv.h */; };
-		00BE441C0EE9CDFA0008420F /* SkTemplatesPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43430EE9CDFA0008420F /* SkTemplatesPriv.h */; };
-		00BE441D0EE9CDFA0008420F /* SkTSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43440EE9CDFA0008420F /* SkTSearch.cpp */; };
-		00BE441E0EE9CDFA0008420F /* SkTSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43450EE9CDFA0008420F /* SkTSort.h */; };
-		00BE441F0EE9CDFA0008420F /* SkTypeface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43460EE9CDFA0008420F /* SkTypeface.cpp */; };
-		00BE44200EE9CDFA0008420F /* SkUnPreMultiply.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43470EE9CDFA0008420F /* SkUnPreMultiply.cpp */; };
-		00BE44220EE9CDFA0008420F /* SkWriter32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43490EE9CDFA0008420F /* SkWriter32.cpp */; };
-		00BE44230EE9CDFA0008420F /* SkXfermode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE434A0EE9CDFA0008420F /* SkXfermode.cpp */; };
-		00BE44240EE9CDFA0008420F /* Sk64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE434B0EE9CDFA0008420F /* Sk64.cpp */; };
-		00BE44250EE9CDFA0008420F /* SkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE434C0EE9CDFA0008420F /* SkBuffer.cpp */; };
-		00BE44260EE9CDFA0008420F /* SkChunkAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE434D0EE9CDFA0008420F /* SkChunkAlloc.cpp */; };
-		00BE44270EE9CDFA0008420F /* SkCordic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE434E0EE9CDFA0008420F /* SkCordic.cpp */; };
-		00BE44280EE9CDFA0008420F /* SkCordic.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE434F0EE9CDFA0008420F /* SkCordic.h */; };
-		00BE44290EE9CDFA0008420F /* SkDebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43500EE9CDFA0008420F /* SkDebug.cpp */; };
-		00BE442A0EE9CDFA0008420F /* SkDebug_stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43510EE9CDFA0008420F /* SkDebug_stdio.cpp */; };
-		00BE442B0EE9CDFA0008420F /* SkFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43520EE9CDFA0008420F /* SkFloat.cpp */; };
-		00BE442C0EE9CDFA0008420F /* SkFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 00BE43530EE9CDFA0008420F /* SkFloat.h */; };
-		00BE442D0EE9CDFA0008420F /* SkFloatBits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43540EE9CDFA0008420F /* SkFloatBits.cpp */; };
-		00BE442E0EE9CDFA0008420F /* SkInterpolator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43550EE9CDFA0008420F /* SkInterpolator.cpp */; };
-		00BE442F0EE9CDFA0008420F /* SkMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43560EE9CDFA0008420F /* SkMath.cpp */; };
-		00BE44300EE9CDFA0008420F /* SkMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43570EE9CDFA0008420F /* SkMatrix.cpp */; };
-		00BE44310EE9CDFA0008420F /* SkMemory_stdlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43580EE9CDFA0008420F /* SkMemory_stdlib.cpp */; };
-		00BE44320EE9CDFA0008420F /* SkPageFlipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE43590EE9CDFA0008420F /* SkPageFlipper.cpp */; };
-		00BE44330EE9CDFA0008420F /* SkPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE435A0EE9CDFA0008420F /* SkPoint.cpp */; };
-		00BE44340EE9CDFA0008420F /* SkRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE435B0EE9CDFA0008420F /* SkRect.cpp */; };
-		00BE44350EE9CDFA0008420F /* SkRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE435C0EE9CDFA0008420F /* SkRegion.cpp */; };
-		00BE44C90EE9D4FC0008420F /* SkOSFile_stdio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE44C80EE9D4FC0008420F /* SkOSFile_stdio.cpp */; };
-		00BE44D40EE9D5660008420F /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00BE446A0EE9D1780008420F /* libjpeg.a */; };
-		00BE44D50EE9D5670008420F /* liblibpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00BE446D0EE9D1780008420F /* liblibpng.a */; };
-		00BE44D60EE9D5690008420F /* libzlib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00BE44700EE9D1780008420F /* libzlib.a */; };
-		00BE45070EE9D8120008420F /* bmpdecoderhelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BE45060EE9D8120008420F /* bmpdecoderhelper.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		003E929A0EED79240091D85B /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00A567680EED77850096A2A1 /* freetype2.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = freetype;
-		};
-		003E92D90EED7C3B0091D85B /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE445C0EE9D1780008420F /* zlib.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = zlib;
-		};
-		00A5676C0EED77850096A2A1 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00A567680EED77850096A2A1 /* freetype2.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = freetype;
-		};
-		00AFCE140EF16BA400BD2FF1 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00AFCE0D0EF16BA400BD2FF1 /* expat.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = expat;
-		};
-		00AFCE170EF16BBB00BD2FF1 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00AFCE0D0EF16BA400BD2FF1 /* expat.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = expat;
-		};
-		00BE44660EE9D1780008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE444D0EE9D1780008420F /* giflib.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = giflib;
-		};
-		00BE44690EE9D1780008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE44560EE9D1780008420F /* jpeg.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = jpeg;
-		};
-		00BE446C0EE9D1780008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE44590EE9D1780008420F /* libpng.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = libpng;
-		};
-		00BE446F0EE9D1780008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE445C0EE9D1780008420F /* zlib.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = zlib;
-		};
-		00BE44F00EE9D70D0008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE44560EE9D1780008420F /* jpeg.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = jpeg;
-		};
-		00BE44F40EE9D70D0008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE444D0EE9D1780008420F /* giflib.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = giflib;
-		};
-		00BE44F60EE9D70D0008420F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00BE44590EE9D1780008420F /* libpng.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = libpng;
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
-		006B43FC0EF7526E00F15BC4 /* SkString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkString.cpp; path = ../libcorecg/SkString.cpp; sourceTree = SOURCE_ROOT; };
-		006B43FD0EF7526E00F15BC4 /* SkUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUtils.cpp; path = ../libcorecg/SkUtils.cpp; sourceTree = SOURCE_ROOT; };
-		00A567680EED77850096A2A1 /* freetype2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = freetype2.xcodeproj; sourceTree = "<group>"; };
-		00AFCD700EF1672C00BD2FF1 /* SkDOM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDOM.cpp; path = ../libsgl/xml/SkDOM.cpp; sourceTree = SOURCE_ROOT; };
-		00AFCD790EF167BC00BD2FF1 /* SkParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParse.cpp; path = ../libsgl/xml/SkParse.cpp; sourceTree = SOURCE_ROOT; };
-		00AFCD7A0EF167BC00BD2FF1 /* SkParseColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParseColor.cpp; path = ../libsgl/xml/SkParseColor.cpp; sourceTree = SOURCE_ROOT; };
-		00AFCD7B0EF167BC00BD2FF1 /* SkXMLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLParser.cpp; path = ../libsgl/xml/SkXMLParser.cpp; sourceTree = SOURCE_ROOT; };
-		00AFCD880EF1684200BD2FF1 /* SkBitmap_Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap_Mac.cpp; path = ports/SkBitmap_Mac.cpp; sourceTree = "<group>"; };
-		00AFCD8A0EF1685100BD2FF1 /* SkOSWindow_Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSWindow_Mac.cpp; path = ports/SkOSWindow_Mac.cpp; sourceTree = "<group>"; };
-		00AFCE0D0EF16BA400BD2FF1 /* expat.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = expat.xcodeproj; sourceTree = "<group>"; };
-		00BE42800EE9CDFA0008420F /* Sk1DPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk1DPathEffect.cpp; path = ../libsgl/effects/Sk1DPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42810EE9CDFA0008420F /* Sk2DPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk2DPathEffect.cpp; path = ../libsgl/effects/Sk2DPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42820EE9CDFA0008420F /* SkAvoidXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAvoidXfermode.cpp; path = ../libsgl/effects/SkAvoidXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42830EE9CDFA0008420F /* SkBlurDrawLooper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurDrawLooper.cpp; path = ../libsgl/effects/SkBlurDrawLooper.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42840EE9CDFA0008420F /* SkBlurMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurMask.cpp; path = ../libsgl/effects/SkBlurMask.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42850EE9CDFA0008420F /* SkBlurMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlurMask.h; path = ../libsgl/effects/SkBlurMask.h; sourceTree = SOURCE_ROOT; };
-		00BE42860EE9CDFA0008420F /* SkBlurMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlurMaskFilter.cpp; path = ../libsgl/effects/SkBlurMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42870EE9CDFA0008420F /* SkCamera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCamera.cpp; path = ../libsgl/effects/SkCamera.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42880EE9CDFA0008420F /* SkColorFilters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorFilters.cpp; path = ../libsgl/effects/SkColorFilters.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42890EE9CDFA0008420F /* SkColorMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorMatrix.cpp; path = ../libsgl/effects/SkColorMatrix.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428A0EE9CDFA0008420F /* SkColorMatrixFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorMatrixFilter.cpp; path = ../libsgl/effects/SkColorMatrixFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428B0EE9CDFA0008420F /* SkCornerPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCornerPathEffect.cpp; path = ../libsgl/effects/SkCornerPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428C0EE9CDFA0008420F /* SkCullPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCullPoints.cpp; path = ../libsgl/effects/SkCullPoints.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428D0EE9CDFA0008420F /* SkDashPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDashPathEffect.cpp; path = ../libsgl/effects/SkDashPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428E0EE9CDFA0008420F /* SkDiscretePathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDiscretePathEffect.cpp; path = ../libsgl/effects/SkDiscretePathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE428F0EE9CDFA0008420F /* SkDumpCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDumpCanvas.cpp; path = ../libsgl/effects/SkDumpCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42900EE9CDFA0008420F /* SkEmbossMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEmbossMask.cpp; path = ../libsgl/effects/SkEmbossMask.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42910EE9CDFA0008420F /* SkEmbossMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEmbossMask.h; path = ../libsgl/effects/SkEmbossMask.h; sourceTree = SOURCE_ROOT; };
-		00BE42920EE9CDFA0008420F /* SkEmbossMask_Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEmbossMask_Table.h; path = ../libsgl/effects/SkEmbossMask_Table.h; sourceTree = SOURCE_ROOT; };
-		00BE42930EE9CDFA0008420F /* SkEmbossMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEmbossMaskFilter.cpp; path = ../libsgl/effects/SkEmbossMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42940EE9CDFA0008420F /* SkGradientShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGradientShader.cpp; path = ../libsgl/effects/SkGradientShader.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42950EE9CDFA0008420F /* SkKernel33MaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkKernel33MaskFilter.cpp; path = ../libsgl/effects/SkKernel33MaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42960EE9CDFA0008420F /* SkLayerDrawLooper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLayerDrawLooper.cpp; path = ../libsgl/effects/SkLayerDrawLooper.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42970EE9CDFA0008420F /* SkLayerRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLayerRasterizer.cpp; path = ../libsgl/effects/SkLayerRasterizer.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42980EE9CDFA0008420F /* SkNinePatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkNinePatch.cpp; path = ../libsgl/effects/SkNinePatch.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42990EE9CDFA0008420F /* SkPaintFlagsDrawFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPaintFlagsDrawFilter.cpp; path = ../libsgl/effects/SkPaintFlagsDrawFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE429A0EE9CDFA0008420F /* SkPixelXorXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPixelXorXfermode.cpp; path = ../libsgl/effects/SkPixelXorXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		00BE429B0EE9CDFA0008420F /* SkProxyCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProxyCanvas.cpp; path = ../libsgl/effects/SkProxyCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00BE429C0EE9CDFA0008420F /* SkRadialGradient_Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkRadialGradient_Table.h; path = ../libsgl/effects/SkRadialGradient_Table.h; sourceTree = SOURCE_ROOT; };
-		00BE429D0EE9CDFA0008420F /* SkShaderExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkShaderExtras.cpp; path = ../libsgl/effects/SkShaderExtras.cpp; sourceTree = SOURCE_ROOT; };
-		00BE429E0EE9CDFA0008420F /* SkTransparentShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTransparentShader.cpp; path = ../libsgl/effects/SkTransparentShader.cpp; sourceTree = SOURCE_ROOT; };
-		00BE429F0EE9CDFA0008420F /* SkUnitMappers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUnitMappers.cpp; path = ../libsgl/effects/SkUnitMappers.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A10EE9CDFA0008420F /* SkBGViewArtist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBGViewArtist.cpp; path = ../libsgl/views/SkBGViewArtist.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A20EE9CDFA0008420F /* SkBorderView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBorderView.cpp; path = ../libsgl/views/SkBorderView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A30EE9CDFA0008420F /* SkEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEvent.cpp; path = ../libsgl/views/SkEvent.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A40EE9CDFA0008420F /* SkEventSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEventSink.cpp; path = ../libsgl/views/SkEventSink.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A50EE9CDFA0008420F /* SkImageView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageView.cpp; path = ../libsgl/views/SkImageView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A60EE9CDFA0008420F /* SkListView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkListView.cpp; path = ../libsgl/views/SkListView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A70EE9CDFA0008420F /* SkListWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkListWidget.cpp; path = ../libsgl/views/SkListWidget.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A80EE9CDFA0008420F /* SkMetaData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMetaData.cpp; path = ../libsgl/views/SkMetaData.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42A90EE9CDFA0008420F /* SkOSFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSFile.cpp; path = ../libsgl/views/SkOSFile.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AA0EE9CDFA0008420F /* SkOSMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSMenu.cpp; path = ../libsgl/views/SkOSMenu.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AB0EE9CDFA0008420F /* SkOSSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSSound.cpp; path = ../libsgl/views/SkOSSound.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AC0EE9CDFA0008420F /* SkParsePaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParsePaint.cpp; path = ../libsgl/views/SkParsePaint.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AD0EE9CDFA0008420F /* SkProgressBarView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProgressBarView.cpp; path = ../libsgl/views/SkProgressBarView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AE0EE9CDFA0008420F /* SkProgressView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProgressView.cpp; path = ../libsgl/views/SkProgressView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42AF0EE9CDFA0008420F /* SkScrollBarView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScrollBarView.cpp; path = ../libsgl/views/SkScrollBarView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B00EE9CDFA0008420F /* SkStackViewLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStackViewLayout.cpp; path = ../libsgl/views/SkStackViewLayout.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B10EE9CDFA0008420F /* SkTagList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTagList.cpp; path = ../libsgl/views/SkTagList.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B20EE9CDFA0008420F /* SkTagList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTagList.h; path = ../libsgl/views/SkTagList.h; sourceTree = SOURCE_ROOT; };
-		00BE42B30EE9CDFA0008420F /* SkTextBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextBox.cpp; path = ../libsgl/views/SkTextBox.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B40EE9CDFA0008420F /* SkView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkView.cpp; path = ../libsgl/views/SkView.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B50EE9CDFA0008420F /* SkViewInflate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkViewInflate.cpp; path = ../libsgl/views/SkViewInflate.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B60EE9CDFA0008420F /* SkViewPriv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkViewPriv.cpp; path = ../libsgl/views/SkViewPriv.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B70EE9CDFA0008420F /* SkViewPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkViewPriv.h; path = ../libsgl/views/SkViewPriv.h; sourceTree = SOURCE_ROOT; };
-		00BE42B80EE9CDFA0008420F /* SkWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidget.cpp; path = ../libsgl/views/SkWidget.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42B90EE9CDFA0008420F /* SkWidgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidgets.cpp; path = ../libsgl/views/SkWidgets.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42BA0EE9CDFA0008420F /* SkWidgetViews.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidgetViews.cpp; path = ../libsgl/views/SkWidgetViews.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42BB0EE9CDFA0008420F /* SkWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWindow.cpp; path = ../libsgl/views/SkWindow.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42BD0EE9CDFA0008420F /* SkFDStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFDStream.cpp; path = ../libsgl/images/SkFDStream.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42BE0EE9CDFA0008420F /* SkFlipPixelRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFlipPixelRef.cpp; path = ../libsgl/images/SkFlipPixelRef.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42BF0EE9CDFA0008420F /* SkImageDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder.cpp; path = ../libsgl/images/SkImageDecoder.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42C10EE9CDFA0008420F /* SkImageDecoder_libbmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libbmp.cpp; path = ../libsgl/images/SkImageDecoder_libbmp.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42C30EE9CDFA0008420F /* SkImageDecoder_libico.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_libico.cpp; path = ../libsgl/images/SkImageDecoder_libico.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42C70EE9CDFA0008420F /* SkImageDecoder_wbmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_wbmp.cpp; path = ../libsgl/images/SkImageDecoder_wbmp.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42C80EE9CDFA0008420F /* SkImageRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRef.cpp; path = ../libsgl/images/SkImageRef.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42C90EE9CDFA0008420F /* SkImageRef_GlobalPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRef_GlobalPool.cpp; path = ../libsgl/images/SkImageRef_GlobalPool.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42CA0EE9CDFA0008420F /* SkImageRefPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageRefPool.cpp; path = ../libsgl/images/SkImageRefPool.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42CB0EE9CDFA0008420F /* SkImageRefPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkImageRefPool.h; path = ../libsgl/images/SkImageRefPool.h; sourceTree = SOURCE_ROOT; };
-		00BE42CC0EE9CDFA0008420F /* SkMMapStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMMapStream.cpp; path = ../libsgl/images/SkMMapStream.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42CD0EE9CDFA0008420F /* SkMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie.cpp; path = ../libsgl/images/SkMovie.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42CF0EE9CDFA0008420F /* SkScaledBitmapSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScaledBitmapSampler.cpp; path = ../libsgl/images/SkScaledBitmapSampler.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D00EE9CDFA0008420F /* SkScaledBitmapSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScaledBitmapSampler.h; path = ../libsgl/images/SkScaledBitmapSampler.h; sourceTree = SOURCE_ROOT; };
-		00BE42D10EE9CDFA0008420F /* SkStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStream.cpp; path = ../libsgl/images/SkStream.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D30EE9CDFA0008420F /* SkFontHost_android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_android.cpp; path = ../libsgl/ports/SkFontHost_android.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D40EE9CDFA0008420F /* SkFontHost_gamma.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_gamma.cpp; path = ../libsgl/ports/SkFontHost_gamma.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D50EE9CDFA0008420F /* SkGlobals_global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlobals_global.cpp; path = ../libsgl/ports/SkGlobals_global.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D60EE9CDFA0008420F /* SkImageDecoder_Factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageDecoder_Factory.cpp; path = ../libsgl/ports/SkImageDecoder_Factory.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D70EE9CDFA0008420F /* SkThread_pthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkThread_pthread.cpp; path = ../libsgl/ports/SkThread_pthread.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42D80EE9CDFA0008420F /* SkTime_Unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTime_Unix.cpp; path = ../libsgl/ports/SkTime_Unix.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42DA0EE9CDFA0008420F /* SkPathHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathHeap.cpp; path = ../libsgl/picture/SkPathHeap.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42DB0EE9CDFA0008420F /* SkPathHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPathHeap.h; path = ../libsgl/picture/SkPathHeap.h; sourceTree = SOURCE_ROOT; };
-		00BE42DC0EE9CDFA0008420F /* SkPicture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPicture.cpp; path = ../libsgl/picture/SkPicture.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42DD0EE9CDFA0008420F /* SkPictureFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPictureFlat.cpp; path = ../libsgl/picture/SkPictureFlat.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42DE0EE9CDFA0008420F /* SkPictureFlat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPictureFlat.h; path = ../libsgl/picture/SkPictureFlat.h; sourceTree = SOURCE_ROOT; };
-		00BE42DF0EE9CDFA0008420F /* SkPicturePlayback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPicturePlayback.cpp; path = ../libsgl/picture/SkPicturePlayback.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E00EE9CDFA0008420F /* SkPicturePlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPicturePlayback.h; path = ../libsgl/picture/SkPicturePlayback.h; sourceTree = SOURCE_ROOT; };
-		00BE42E10EE9CDFA0008420F /* SkPictureRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPictureRecord.cpp; path = ../libsgl/picture/SkPictureRecord.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E20EE9CDFA0008420F /* SkPictureRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkPictureRecord.h; path = ../libsgl/picture/SkPictureRecord.h; sourceTree = SOURCE_ROOT; };
-		00BE42E30EE9CDFA0008420F /* SkGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGL.cpp; path = ../libsgl/gl/SkGL.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E40EE9CDFA0008420F /* SkGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGL.h; path = ../libsgl/gl/SkGL.h; sourceTree = SOURCE_ROOT; };
-		00BE42E50EE9CDFA0008420F /* SkGLCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLCanvas.cpp; path = ../libsgl/gl/SkGLCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E60EE9CDFA0008420F /* SkGLDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice.cpp; path = ../libsgl/gl/SkGLDevice.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E70EE9CDFA0008420F /* SkGLDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice.h; path = ../libsgl/gl/SkGLDevice.h; sourceTree = SOURCE_ROOT; };
-		00BE42E80EE9CDFA0008420F /* SkGLDevice_FBO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice_FBO.cpp; path = ../libsgl/gl/SkGLDevice_FBO.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42E90EE9CDFA0008420F /* SkGLDevice_FBO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice_FBO.h; path = ../libsgl/gl/SkGLDevice_FBO.h; sourceTree = SOURCE_ROOT; };
-		00BE42EA0EE9CDFA0008420F /* SkGLDevice_SWLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLDevice_SWLayer.cpp; path = ../libsgl/gl/SkGLDevice_SWLayer.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42EB0EE9CDFA0008420F /* SkGLDevice_SWLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLDevice_SWLayer.h; path = ../libsgl/gl/SkGLDevice_SWLayer.h; sourceTree = SOURCE_ROOT; };
-		00BE42EC0EE9CDFA0008420F /* SkGLTextCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGLTextCache.cpp; path = ../libsgl/gl/SkGLTextCache.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42ED0EE9CDFA0008420F /* SkGLTextCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGLTextCache.h; path = ../libsgl/gl/SkGLTextCache.h; sourceTree = SOURCE_ROOT; };
-		00BE42EE0EE9CDFA0008420F /* SkTextureCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextureCache.cpp; path = ../libsgl/gl/SkTextureCache.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42EF0EE9CDFA0008420F /* SkTextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTextureCache.h; path = ../libsgl/gl/SkTextureCache.h; sourceTree = SOURCE_ROOT; };
-		00BE42F00EE9CDFA0008420F /* SkAlphaRuns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkAlphaRuns.cpp; path = ../libsgl/sgl/SkAlphaRuns.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42F10EE9CDFA0008420F /* SkAntiRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAntiRun.h; path = ../libsgl/sgl/SkAntiRun.h; sourceTree = SOURCE_ROOT; };
-		00BE42F20EE9CDFA0008420F /* SkAutoKern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkAutoKern.h; path = ../libsgl/sgl/SkAutoKern.h; sourceTree = SOURCE_ROOT; };
-		00BE42F30EE9CDFA0008420F /* SkBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap.cpp; path = ../libsgl/sgl/SkBitmap.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42F40EE9CDFA0008420F /* SkBitmap_scroll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmap_scroll.cpp; path = ../libsgl/sgl/SkBitmap_scroll.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42F50EE9CDFA0008420F /* SkBitmapProcShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcShader.cpp; path = ../libsgl/sgl/SkBitmapProcShader.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42F60EE9CDFA0008420F /* SkBitmapProcShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcShader.h; path = ../libsgl/sgl/SkBitmapProcShader.h; sourceTree = SOURCE_ROOT; };
-		00BE42F70EE9CDFA0008420F /* SkBitmapProcState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcState.cpp; path = ../libsgl/sgl/SkBitmapProcState.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42F80EE9CDFA0008420F /* SkBitmapProcState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState.h; path = ../libsgl/sgl/SkBitmapProcState.h; sourceTree = SOURCE_ROOT; };
-		00BE42F90EE9CDFA0008420F /* SkBitmapProcState_matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState_matrix.h; path = ../libsgl/sgl/SkBitmapProcState_matrix.h; sourceTree = SOURCE_ROOT; };
-		00BE42FA0EE9CDFA0008420F /* SkBitmapProcState_matrixProcs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapProcState_matrixProcs.cpp; path = ../libsgl/sgl/SkBitmapProcState_matrixProcs.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42FB0EE9CDFA0008420F /* SkBitmapProcState_sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapProcState_sample.h; path = ../libsgl/sgl/SkBitmapProcState_sample.h; sourceTree = SOURCE_ROOT; };
-		00BE42FC0EE9CDFA0008420F /* SkBitmapSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapSampler.cpp; path = ../libsgl/sgl/SkBitmapSampler.cpp; sourceTree = SOURCE_ROOT; };
-		00BE42FD0EE9CDFA0008420F /* SkBitmapSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapSampler.h; path = ../libsgl/sgl/SkBitmapSampler.h; sourceTree = SOURCE_ROOT; };
-		00BE42FE0EE9CDFA0008420F /* SkBitmapSamplerTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapSamplerTemplate.h; path = ../libsgl/sgl/SkBitmapSamplerTemplate.h; sourceTree = SOURCE_ROOT; };
-		00BE42FF0EE9CDFA0008420F /* SkBitmapShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapShader.cpp; path = ../libsgl/sgl/SkBitmapShader.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43000EE9CDFA0008420F /* SkBitmapShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShader.h; path = ../libsgl/sgl/SkBitmapShader.h; sourceTree = SOURCE_ROOT; };
-		00BE43010EE9CDFA0008420F /* SkBitmapShader16BilerpTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShader16BilerpTemplate.h; path = ../libsgl/sgl/SkBitmapShader16BilerpTemplate.h; sourceTree = SOURCE_ROOT; };
-		00BE43020EE9CDFA0008420F /* SkBitmapShaderTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapShaderTemplate.h; path = ../libsgl/sgl/SkBitmapShaderTemplate.h; sourceTree = SOURCE_ROOT; };
-		00BE43030EE9CDFA0008420F /* SkBlitBWMaskTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitBWMaskTemplate.h; path = ../libsgl/sgl/SkBlitBWMaskTemplate.h; sourceTree = SOURCE_ROOT; };
-		00BE43040EE9CDFA0008420F /* SkBlitRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitRow.h; path = ../libsgl/sgl/SkBlitRow.h; sourceTree = SOURCE_ROOT; };
-		00BE43050EE9CDFA0008420F /* SkBlitRow_D16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitRow_D16.cpp; path = ../libsgl/sgl/SkBlitRow_D16.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43060EE9CDFA0008420F /* SkBlitRow_D4444.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitRow_D4444.cpp; path = ../libsgl/sgl/SkBlitRow_D4444.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43070EE9CDFA0008420F /* SkBlitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter.cpp; path = ../libsgl/sgl/SkBlitter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43080EE9CDFA0008420F /* SkBlitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBlitter.h; path = ../libsgl/sgl/SkBlitter.h; sourceTree = SOURCE_ROOT; };
-		00BE43090EE9CDFA0008420F /* SkBlitter_4444.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_4444.cpp; path = ../libsgl/sgl/SkBlitter_4444.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430A0EE9CDFA0008420F /* SkBlitter_A1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_A1.cpp; path = ../libsgl/sgl/SkBlitter_A1.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430B0EE9CDFA0008420F /* SkBlitter_A8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_A8.cpp; path = ../libsgl/sgl/SkBlitter_A8.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430C0EE9CDFA0008420F /* SkBlitter_ARGB32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_ARGB32.cpp; path = ../libsgl/sgl/SkBlitter_ARGB32.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430D0EE9CDFA0008420F /* SkBlitter_RGB16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_RGB16.cpp; path = ../libsgl/sgl/SkBlitter_RGB16.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430E0EE9CDFA0008420F /* SkBlitter_Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBlitter_Sprite.cpp; path = ../libsgl/sgl/SkBlitter_Sprite.cpp; sourceTree = SOURCE_ROOT; };
-		00BE430F0EE9CDFA0008420F /* SkCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCanvas.cpp; path = ../libsgl/sgl/SkCanvas.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43100EE9CDFA0008420F /* SkColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColor.cpp; path = ../libsgl/sgl/SkColor.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43110EE9CDFA0008420F /* SkColorFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorFilter.cpp; path = ../libsgl/sgl/SkColorFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43120EE9CDFA0008420F /* SkColorTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkColorTable.cpp; path = ../libsgl/sgl/SkColorTable.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43130EE9CDFA0008420F /* SkCoreBlitters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkCoreBlitters.h; path = ../libsgl/sgl/SkCoreBlitters.h; sourceTree = SOURCE_ROOT; };
-		00BE43140EE9CDFA0008420F /* SkDeque.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDeque.cpp; path = ../libsgl/sgl/SkDeque.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43150EE9CDFA0008420F /* SkDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDevice.cpp; path = ../libsgl/sgl/SkDevice.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43160EE9CDFA0008420F /* SkDither.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDither.cpp; path = ../libsgl/sgl/SkDither.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43170EE9CDFA0008420F /* SkDraw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDraw.cpp; path = ../libsgl/sgl/SkDraw.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43180EE9CDFA0008420F /* SkDrawProcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkDrawProcs.h; path = ../libsgl/sgl/SkDrawProcs.h; sourceTree = SOURCE_ROOT; };
-		00BE43190EE9CDFA0008420F /* SkEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEdge.cpp; path = ../libsgl/sgl/SkEdge.cpp; sourceTree = SOURCE_ROOT; };
-		00BE431A0EE9CDFA0008420F /* SkEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkEdge.h; path = ../libsgl/sgl/SkEdge.h; sourceTree = SOURCE_ROOT; };
-		00BE431B0EE9CDFA0008420F /* SkFilterProc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFilterProc.cpp; path = ../libsgl/sgl/SkFilterProc.cpp; sourceTree = SOURCE_ROOT; };
-		00BE431C0EE9CDFA0008420F /* SkFilterProc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFilterProc.h; path = ../libsgl/sgl/SkFilterProc.h; sourceTree = SOURCE_ROOT; };
-		00BE431D0EE9CDFA0008420F /* SkFlattenable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFlattenable.cpp; path = ../libsgl/sgl/SkFlattenable.cpp; sourceTree = SOURCE_ROOT; };
-		00BE431E0EE9CDFA0008420F /* SkFP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFP.h; path = ../libsgl/sgl/SkFP.h; sourceTree = SOURCE_ROOT; };
-		00BE431F0EE9CDFA0008420F /* SkGeometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGeometry.cpp; path = ../libsgl/sgl/SkGeometry.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43200EE9CDFA0008420F /* SkGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGeometry.h; path = ../libsgl/sgl/SkGeometry.h; sourceTree = SOURCE_ROOT; };
-		00BE43210EE9CDFA0008420F /* SkGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlobals.cpp; path = ../libsgl/sgl/SkGlobals.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43220EE9CDFA0008420F /* SkGlyphCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGlyphCache.cpp; path = ../libsgl/sgl/SkGlyphCache.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43230EE9CDFA0008420F /* SkGlyphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkGlyphCache.h; path = ../libsgl/sgl/SkGlyphCache.h; sourceTree = SOURCE_ROOT; };
-		00BE43240EE9CDFA0008420F /* SkGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGraphics.cpp; path = ../libsgl/sgl/SkGraphics.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43250EE9CDFA0008420F /* SkMask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMask.cpp; path = ../libsgl/sgl/SkMask.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43260EE9CDFA0008420F /* SkMaskFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMaskFilter.cpp; path = ../libsgl/sgl/SkMaskFilter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43270EE9CDFA0008420F /* SkPackBits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPackBits.cpp; path = ../libsgl/sgl/SkPackBits.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43280EE9CDFA0008420F /* SkPaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPaint.cpp; path = ../libsgl/sgl/SkPaint.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43290EE9CDFA0008420F /* SkPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPath.cpp; path = ../libsgl/sgl/SkPath.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432A0EE9CDFA0008420F /* SkPathEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathEffect.cpp; path = ../libsgl/sgl/SkPathEffect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432B0EE9CDFA0008420F /* SkPathMeasure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPathMeasure.cpp; path = ../libsgl/sgl/SkPathMeasure.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432C0EE9CDFA0008420F /* SkPixelRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPixelRef.cpp; path = ../libsgl/sgl/SkPixelRef.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432D0EE9CDFA0008420F /* SkProcSpriteBlitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProcSpriteBlitter.cpp; path = ../libsgl/sgl/SkProcSpriteBlitter.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432E0EE9CDFA0008420F /* SkPtrRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPtrRecorder.cpp; path = ../libsgl/sgl/SkPtrRecorder.cpp; sourceTree = SOURCE_ROOT; };
-		00BE432F0EE9CDFA0008420F /* SkRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRasterizer.cpp; path = ../libsgl/sgl/SkRasterizer.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43300EE9CDFA0008420F /* SkRefCnt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRefCnt.cpp; path = ../libsgl/sgl/SkRefCnt.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43310EE9CDFA0008420F /* SkRegion_path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRegion_path.cpp; path = ../libsgl/sgl/SkRegion_path.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43320EE9CDFA0008420F /* SkScalerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScalerContext.cpp; path = ../libsgl/sgl/SkScalerContext.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43330EE9CDFA0008420F /* SkScan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan.cpp; path = ../libsgl/sgl/SkScan.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43340EE9CDFA0008420F /* SkScan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScan.h; path = ../libsgl/sgl/SkScan.h; sourceTree = SOURCE_ROOT; };
-		00BE43350EE9CDFA0008420F /* SkScan_Antihair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Antihair.cpp; path = ../libsgl/sgl/SkScan_Antihair.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43360EE9CDFA0008420F /* SkScan_AntiPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_AntiPath.cpp; path = ../libsgl/sgl/SkScan_AntiPath.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43370EE9CDFA0008420F /* SkScan_Hairline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Hairline.cpp; path = ../libsgl/sgl/SkScan_Hairline.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43380EE9CDFA0008420F /* SkScan_Path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScan_Path.cpp; path = ../libsgl/sgl/SkScan_Path.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43390EE9CDFA0008420F /* SkScanPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkScanPriv.h; path = ../libsgl/sgl/SkScanPriv.h; sourceTree = SOURCE_ROOT; };
-		00BE433A0EE9CDFA0008420F /* SkShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkShader.cpp; path = ../libsgl/sgl/SkShader.cpp; sourceTree = SOURCE_ROOT; };
-		00BE433B0EE9CDFA0008420F /* SkSpriteBlitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSpriteBlitter.h; path = ../libsgl/sgl/SkSpriteBlitter.h; sourceTree = SOURCE_ROOT; };
-		00BE433C0EE9CDFA0008420F /* SkSpriteBlitter_ARGB32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSpriteBlitter_ARGB32.cpp; path = ../libsgl/sgl/SkSpriteBlitter_ARGB32.cpp; sourceTree = SOURCE_ROOT; };
-		00BE433D0EE9CDFA0008420F /* SkSpriteBlitter_RGB16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkSpriteBlitter_RGB16.cpp; path = ../libsgl/sgl/SkSpriteBlitter_RGB16.cpp; sourceTree = SOURCE_ROOT; };
-		00BE433E0EE9CDFA0008420F /* SkSpriteBlitterTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkSpriteBlitterTemplate.h; path = ../libsgl/sgl/SkSpriteBlitterTemplate.h; sourceTree = SOURCE_ROOT; };
-		00BE43400EE9CDFA0008420F /* SkStroke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStroke.cpp; path = ../libsgl/sgl/SkStroke.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43410EE9CDFA0008420F /* SkStrokerPriv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStrokerPriv.cpp; path = ../libsgl/sgl/SkStrokerPriv.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43420EE9CDFA0008420F /* SkStrokerPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkStrokerPriv.h; path = ../libsgl/sgl/SkStrokerPriv.h; sourceTree = SOURCE_ROOT; };
-		00BE43430EE9CDFA0008420F /* SkTemplatesPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTemplatesPriv.h; path = ../libsgl/sgl/SkTemplatesPriv.h; sourceTree = SOURCE_ROOT; };
-		00BE43440EE9CDFA0008420F /* SkTSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTSearch.cpp; path = ../libsgl/sgl/SkTSearch.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43450EE9CDFA0008420F /* SkTSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTSort.h; path = ../libsgl/sgl/SkTSort.h; sourceTree = SOURCE_ROOT; };
-		00BE43460EE9CDFA0008420F /* SkTypeface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTypeface.cpp; path = ../libsgl/sgl/SkTypeface.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43470EE9CDFA0008420F /* SkUnPreMultiply.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUnPreMultiply.cpp; path = ../libsgl/sgl/SkUnPreMultiply.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43490EE9CDFA0008420F /* SkWriter32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWriter32.cpp; path = ../libsgl/sgl/SkWriter32.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434A0EE9CDFA0008420F /* SkXfermode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXfermode.cpp; path = ../libsgl/sgl/SkXfermode.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434B0EE9CDFA0008420F /* Sk64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk64.cpp; path = ../libcorecg/Sk64.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434C0EE9CDFA0008420F /* SkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBuffer.cpp; path = ../libcorecg/SkBuffer.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434D0EE9CDFA0008420F /* SkChunkAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkChunkAlloc.cpp; path = ../libcorecg/SkChunkAlloc.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434E0EE9CDFA0008420F /* SkCordic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkCordic.cpp; path = ../libcorecg/SkCordic.cpp; sourceTree = SOURCE_ROOT; };
-		00BE434F0EE9CDFA0008420F /* SkCordic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkCordic.h; path = ../libcorecg/SkCordic.h; sourceTree = SOURCE_ROOT; };
-		00BE43500EE9CDFA0008420F /* SkDebug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDebug.cpp; path = ../libcorecg/SkDebug.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43510EE9CDFA0008420F /* SkDebug_stdio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDebug_stdio.cpp; path = ../libcorecg/SkDebug_stdio.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43520EE9CDFA0008420F /* SkFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFloat.cpp; path = ../libcorecg/SkFloat.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43530EE9CDFA0008420F /* SkFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkFloat.h; path = ../libcorecg/SkFloat.h; sourceTree = SOURCE_ROOT; };
-		00BE43540EE9CDFA0008420F /* SkFloatBits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFloatBits.cpp; path = ../libcorecg/SkFloatBits.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43550EE9CDFA0008420F /* SkInterpolator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkInterpolator.cpp; path = ../libcorecg/SkInterpolator.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43560EE9CDFA0008420F /* SkMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMath.cpp; path = ../libcorecg/SkMath.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43570EE9CDFA0008420F /* SkMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMatrix.cpp; path = ../libcorecg/SkMatrix.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43580EE9CDFA0008420F /* SkMemory_stdlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMemory_stdlib.cpp; path = ../libcorecg/SkMemory_stdlib.cpp; sourceTree = SOURCE_ROOT; };
-		00BE43590EE9CDFA0008420F /* SkPageFlipper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPageFlipper.cpp; path = ../libcorecg/SkPageFlipper.cpp; sourceTree = SOURCE_ROOT; };
-		00BE435A0EE9CDFA0008420F /* SkPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPoint.cpp; path = ../libcorecg/SkPoint.cpp; sourceTree = SOURCE_ROOT; };
-		00BE435B0EE9CDFA0008420F /* SkRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRect.cpp; path = ../libcorecg/SkRect.cpp; sourceTree = SOURCE_ROOT; };
-		00BE435C0EE9CDFA0008420F /* SkRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRegion.cpp; path = ../libcorecg/SkRegion.cpp; sourceTree = SOURCE_ROOT; };
-		00BE444D0EE9D1780008420F /* giflib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = giflib.xcodeproj; sourceTree = "<group>"; };
-		00BE44560EE9D1780008420F /* jpeg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = jpeg.xcodeproj; sourceTree = "<group>"; };
-		00BE44590EE9D1780008420F /* libpng.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = libpng.xcodeproj; sourceTree = "<group>"; };
-		00BE445C0EE9D1780008420F /* zlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = zlib.xcodeproj; sourceTree = "<group>"; };
-		00BE44C80EE9D4FC0008420F /* SkOSFile_stdio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSFile_stdio.cpp; path = ../libsgl/ports/SkOSFile_stdio.cpp; sourceTree = SOURCE_ROOT; };
-		00BE45060EE9D8120008420F /* bmpdecoderhelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bmpdecoderhelper.cpp; path = ../libsgl/images/bmpdecoderhelper.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libskia2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libskia2.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00BE44D40EE9D5660008420F /* libjpeg.a in Frameworks */,
-				00BE44D50EE9D5670008420F /* liblibpng.a in Frameworks */,
-				00BE44D60EE9D5690008420F /* libzlib.a in Frameworks */,
-				00A567300EED6F6E0096A2A1 /* libgiflib.a in Frameworks */,
-				003E926F0EED78220091D85B /* libfreetype.a in Frameworks */,
-				00AFCE240EF16C0500BD2FF1 /* libexpat.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		00A567690EED77850096A2A1 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00A5676D0EED77850096A2A1 /* libfreetype.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00AFCD780EF167A300BD2FF1 /* xml */ = {
-			isa = PBXGroup;
-			children = (
-				00AFCD790EF167BC00BD2FF1 /* SkParse.cpp */,
-				00AFCD7A0EF167BC00BD2FF1 /* SkParseColor.cpp */,
-				00AFCD7B0EF167BC00BD2FF1 /* SkXMLParser.cpp */,
-				00AFCD700EF1672C00BD2FF1 /* SkDOM.cpp */,
-			);
-			name = xml;
-			sourceTree = "<group>";
-		};
-		00AFCE0E0EF16BA400BD2FF1 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00AFCE150EF16BA400BD2FF1 /* libexpat.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00BE427F0EE9CDFA0008420F /* effects */ = {
-			isa = PBXGroup;
-			children = (
-				00BE42800EE9CDFA0008420F /* Sk1DPathEffect.cpp */,
-				00BE42810EE9CDFA0008420F /* Sk2DPathEffect.cpp */,
-				00BE42820EE9CDFA0008420F /* SkAvoidXfermode.cpp */,
-				00BE42830EE9CDFA0008420F /* SkBlurDrawLooper.cpp */,
-				00BE42840EE9CDFA0008420F /* SkBlurMask.cpp */,
-				00BE42850EE9CDFA0008420F /* SkBlurMask.h */,
-				00BE42860EE9CDFA0008420F /* SkBlurMaskFilter.cpp */,
-				00BE42870EE9CDFA0008420F /* SkCamera.cpp */,
-				00BE42880EE9CDFA0008420F /* SkColorFilters.cpp */,
-				00BE42890EE9CDFA0008420F /* SkColorMatrix.cpp */,
-				00BE428A0EE9CDFA0008420F /* SkColorMatrixFilter.cpp */,
-				00BE428B0EE9CDFA0008420F /* SkCornerPathEffect.cpp */,
-				00BE428C0EE9CDFA0008420F /* SkCullPoints.cpp */,
-				00BE428D0EE9CDFA0008420F /* SkDashPathEffect.cpp */,
-				00BE428E0EE9CDFA0008420F /* SkDiscretePathEffect.cpp */,
-				00BE428F0EE9CDFA0008420F /* SkDumpCanvas.cpp */,
-				00BE42900EE9CDFA0008420F /* SkEmbossMask.cpp */,
-				00BE42910EE9CDFA0008420F /* SkEmbossMask.h */,
-				00BE42920EE9CDFA0008420F /* SkEmbossMask_Table.h */,
-				00BE42930EE9CDFA0008420F /* SkEmbossMaskFilter.cpp */,
-				00BE42940EE9CDFA0008420F /* SkGradientShader.cpp */,
-				00BE42950EE9CDFA0008420F /* SkKernel33MaskFilter.cpp */,
-				00BE42960EE9CDFA0008420F /* SkLayerDrawLooper.cpp */,
-				00BE42970EE9CDFA0008420F /* SkLayerRasterizer.cpp */,
-				00BE42980EE9CDFA0008420F /* SkNinePatch.cpp */,
-				00BE42990EE9CDFA0008420F /* SkPaintFlagsDrawFilter.cpp */,
-				00BE429A0EE9CDFA0008420F /* SkPixelXorXfermode.cpp */,
-				00BE429B0EE9CDFA0008420F /* SkProxyCanvas.cpp */,
-				00BE429C0EE9CDFA0008420F /* SkRadialGradient_Table.h */,
-				00BE429D0EE9CDFA0008420F /* SkShaderExtras.cpp */,
-				00BE429E0EE9CDFA0008420F /* SkTransparentShader.cpp */,
-				00BE429F0EE9CDFA0008420F /* SkUnitMappers.cpp */,
-			);
-			name = effects;
-			sourceTree = "<group>";
-		};
-		00BE42A00EE9CDFA0008420F /* view */ = {
-			isa = PBXGroup;
-			children = (
-				00BE42A10EE9CDFA0008420F /* SkBGViewArtist.cpp */,
-				00BE42A20EE9CDFA0008420F /* SkBorderView.cpp */,
-				00BE42A30EE9CDFA0008420F /* SkEvent.cpp */,
-				00BE42A40EE9CDFA0008420F /* SkEventSink.cpp */,
-				00BE42A50EE9CDFA0008420F /* SkImageView.cpp */,
-				00BE42A60EE9CDFA0008420F /* SkListView.cpp */,
-				00BE42A70EE9CDFA0008420F /* SkListWidget.cpp */,
-				00BE42A80EE9CDFA0008420F /* SkMetaData.cpp */,
-				00BE42A90EE9CDFA0008420F /* SkOSFile.cpp */,
-				00BE42AA0EE9CDFA0008420F /* SkOSMenu.cpp */,
-				00BE42AB0EE9CDFA0008420F /* SkOSSound.cpp */,
-				00BE42AC0EE9CDFA0008420F /* SkParsePaint.cpp */,
-				00BE42AD0EE9CDFA0008420F /* SkProgressBarView.cpp */,
-				00BE42AE0EE9CDFA0008420F /* SkProgressView.cpp */,
-				00BE42AF0EE9CDFA0008420F /* SkScrollBarView.cpp */,
-				00BE42B00EE9CDFA0008420F /* SkStackViewLayout.cpp */,
-				00BE42B10EE9CDFA0008420F /* SkTagList.cpp */,
-				00BE42B20EE9CDFA0008420F /* SkTagList.h */,
-				00BE42B30EE9CDFA0008420F /* SkTextBox.cpp */,
-				00BE42B40EE9CDFA0008420F /* SkView.cpp */,
-				00BE42B50EE9CDFA0008420F /* SkViewInflate.cpp */,
-				00BE42B60EE9CDFA0008420F /* SkViewPriv.cpp */,
-				00BE42B70EE9CDFA0008420F /* SkViewPriv.h */,
-				00BE42B80EE9CDFA0008420F /* SkWidget.cpp */,
-				00BE42B90EE9CDFA0008420F /* SkWidgets.cpp */,
-				00BE42BA0EE9CDFA0008420F /* SkWidgetViews.cpp */,
-				00BE42BB0EE9CDFA0008420F /* SkWindow.cpp */,
-			);
-			name = view;
-			sourceTree = "<group>";
-		};
-		00BE42BC0EE9CDFA0008420F /* image */ = {
-			isa = PBXGroup;
-			children = (
-				00BE45060EE9D8120008420F /* bmpdecoderhelper.cpp */,
-				00BE42BD0EE9CDFA0008420F /* SkFDStream.cpp */,
-				00BE42BE0EE9CDFA0008420F /* SkFlipPixelRef.cpp */,
-				00BE42BF0EE9CDFA0008420F /* SkImageDecoder.cpp */,
-				00BE42C10EE9CDFA0008420F /* SkImageDecoder_libbmp.cpp */,
-				00BE42C30EE9CDFA0008420F /* SkImageDecoder_libico.cpp */,
-				00BE42C70EE9CDFA0008420F /* SkImageDecoder_wbmp.cpp */,
-				00BE42C80EE9CDFA0008420F /* SkImageRef.cpp */,
-				00BE42C90EE9CDFA0008420F /* SkImageRef_GlobalPool.cpp */,
-				00BE42CA0EE9CDFA0008420F /* SkImageRefPool.cpp */,
-				00BE42CB0EE9CDFA0008420F /* SkImageRefPool.h */,
-				00BE42CC0EE9CDFA0008420F /* SkMMapStream.cpp */,
-				00BE42CD0EE9CDFA0008420F /* SkMovie.cpp */,
-				00BE42CF0EE9CDFA0008420F /* SkScaledBitmapSampler.cpp */,
-				00BE42D00EE9CDFA0008420F /* SkScaledBitmapSampler.h */,
-				00BE42D10EE9CDFA0008420F /* SkStream.cpp */,
-			);
-			name = image;
-			sourceTree = "<group>";
-		};
-		00BE42D20EE9CDFA0008420F /* port */ = {
-			isa = PBXGroup;
-			children = (
-				00AFCD8A0EF1685100BD2FF1 /* SkOSWindow_Mac.cpp */,
-				00AFCD880EF1684200BD2FF1 /* SkBitmap_Mac.cpp */,
-				00BE44C80EE9D4FC0008420F /* SkOSFile_stdio.cpp */,
-				00BE42D30EE9CDFA0008420F /* SkFontHost_android.cpp */,
-				00BE42D40EE9CDFA0008420F /* SkFontHost_gamma.cpp */,
-				00BE42D50EE9CDFA0008420F /* SkGlobals_global.cpp */,
-				00BE42D60EE9CDFA0008420F /* SkImageDecoder_Factory.cpp */,
-				00BE42D70EE9CDFA0008420F /* SkThread_pthread.cpp */,
-				00BE42D80EE9CDFA0008420F /* SkTime_Unix.cpp */,
-			);
-			name = port;
-			sourceTree = "<group>";
-		};
-		00BE42D90EE9CDFA0008420F /* core */ = {
-			isa = PBXGroup;
-			children = (
-				006B43FC0EF7526E00F15BC4 /* SkString.cpp */,
-				006B43FD0EF7526E00F15BC4 /* SkUtils.cpp */,
-				00BE42DA0EE9CDFA0008420F /* SkPathHeap.cpp */,
-				00BE42DB0EE9CDFA0008420F /* SkPathHeap.h */,
-				00BE42DC0EE9CDFA0008420F /* SkPicture.cpp */,
-				00BE42DD0EE9CDFA0008420F /* SkPictureFlat.cpp */,
-				00BE42DE0EE9CDFA0008420F /* SkPictureFlat.h */,
-				00BE42DF0EE9CDFA0008420F /* SkPicturePlayback.cpp */,
-				00BE42E00EE9CDFA0008420F /* SkPicturePlayback.h */,
-				00BE42E10EE9CDFA0008420F /* SkPictureRecord.cpp */,
-				00BE42E20EE9CDFA0008420F /* SkPictureRecord.h */,
-				00BE42E30EE9CDFA0008420F /* SkGL.cpp */,
-				00BE42E40EE9CDFA0008420F /* SkGL.h */,
-				00BE42E50EE9CDFA0008420F /* SkGLCanvas.cpp */,
-				00BE42E60EE9CDFA0008420F /* SkGLDevice.cpp */,
-				00BE42E70EE9CDFA0008420F /* SkGLDevice.h */,
-				00BE42E80EE9CDFA0008420F /* SkGLDevice_FBO.cpp */,
-				00BE42E90EE9CDFA0008420F /* SkGLDevice_FBO.h */,
-				00BE42EA0EE9CDFA0008420F /* SkGLDevice_SWLayer.cpp */,
-				00BE42EB0EE9CDFA0008420F /* SkGLDevice_SWLayer.h */,
-				00BE42EC0EE9CDFA0008420F /* SkGLTextCache.cpp */,
-				00BE42ED0EE9CDFA0008420F /* SkGLTextCache.h */,
-				00BE42EE0EE9CDFA0008420F /* SkTextureCache.cpp */,
-				00BE42EF0EE9CDFA0008420F /* SkTextureCache.h */,
-				00BE42F00EE9CDFA0008420F /* SkAlphaRuns.cpp */,
-				00BE42F10EE9CDFA0008420F /* SkAntiRun.h */,
-				00BE42F20EE9CDFA0008420F /* SkAutoKern.h */,
-				00BE42F30EE9CDFA0008420F /* SkBitmap.cpp */,
-				00BE42F40EE9CDFA0008420F /* SkBitmap_scroll.cpp */,
-				00BE42F50EE9CDFA0008420F /* SkBitmapProcShader.cpp */,
-				00BE42F60EE9CDFA0008420F /* SkBitmapProcShader.h */,
-				00BE42F70EE9CDFA0008420F /* SkBitmapProcState.cpp */,
-				00BE42F80EE9CDFA0008420F /* SkBitmapProcState.h */,
-				00BE42F90EE9CDFA0008420F /* SkBitmapProcState_matrix.h */,
-				00BE42FA0EE9CDFA0008420F /* SkBitmapProcState_matrixProcs.cpp */,
-				00BE42FB0EE9CDFA0008420F /* SkBitmapProcState_sample.h */,
-				00BE42FC0EE9CDFA0008420F /* SkBitmapSampler.cpp */,
-				00BE42FD0EE9CDFA0008420F /* SkBitmapSampler.h */,
-				00BE42FE0EE9CDFA0008420F /* SkBitmapSamplerTemplate.h */,
-				00BE42FF0EE9CDFA0008420F /* SkBitmapShader.cpp */,
-				00BE43000EE9CDFA0008420F /* SkBitmapShader.h */,
-				00BE43010EE9CDFA0008420F /* SkBitmapShader16BilerpTemplate.h */,
-				00BE43020EE9CDFA0008420F /* SkBitmapShaderTemplate.h */,
-				00BE43030EE9CDFA0008420F /* SkBlitBWMaskTemplate.h */,
-				00BE43040EE9CDFA0008420F /* SkBlitRow.h */,
-				00BE43050EE9CDFA0008420F /* SkBlitRow_D16.cpp */,
-				00BE43060EE9CDFA0008420F /* SkBlitRow_D4444.cpp */,
-				00BE43070EE9CDFA0008420F /* SkBlitter.cpp */,
-				00BE43080EE9CDFA0008420F /* SkBlitter.h */,
-				00BE43090EE9CDFA0008420F /* SkBlitter_4444.cpp */,
-				00BE430A0EE9CDFA0008420F /* SkBlitter_A1.cpp */,
-				00BE430B0EE9CDFA0008420F /* SkBlitter_A8.cpp */,
-				00BE430C0EE9CDFA0008420F /* SkBlitter_ARGB32.cpp */,
-				00BE430D0EE9CDFA0008420F /* SkBlitter_RGB16.cpp */,
-				00BE430E0EE9CDFA0008420F /* SkBlitter_Sprite.cpp */,
-				00BE430F0EE9CDFA0008420F /* SkCanvas.cpp */,
-				00BE43100EE9CDFA0008420F /* SkColor.cpp */,
-				00BE43110EE9CDFA0008420F /* SkColorFilter.cpp */,
-				00BE43120EE9CDFA0008420F /* SkColorTable.cpp */,
-				00BE43130EE9CDFA0008420F /* SkCoreBlitters.h */,
-				00BE43140EE9CDFA0008420F /* SkDeque.cpp */,
-				00BE43150EE9CDFA0008420F /* SkDevice.cpp */,
-				00BE43160EE9CDFA0008420F /* SkDither.cpp */,
-				00BE43170EE9CDFA0008420F /* SkDraw.cpp */,
-				00BE43180EE9CDFA0008420F /* SkDrawProcs.h */,
-				00BE43190EE9CDFA0008420F /* SkEdge.cpp */,
-				00BE431A0EE9CDFA0008420F /* SkEdge.h */,
-				00BE431B0EE9CDFA0008420F /* SkFilterProc.cpp */,
-				00BE431C0EE9CDFA0008420F /* SkFilterProc.h */,
-				00BE431D0EE9CDFA0008420F /* SkFlattenable.cpp */,
-				00BE431E0EE9CDFA0008420F /* SkFP.h */,
-				00BE431F0EE9CDFA0008420F /* SkGeometry.cpp */,
-				00BE43200EE9CDFA0008420F /* SkGeometry.h */,
-				00BE43210EE9CDFA0008420F /* SkGlobals.cpp */,
-				00BE43220EE9CDFA0008420F /* SkGlyphCache.cpp */,
-				00BE43230EE9CDFA0008420F /* SkGlyphCache.h */,
-				00BE43240EE9CDFA0008420F /* SkGraphics.cpp */,
-				00BE43250EE9CDFA0008420F /* SkMask.cpp */,
-				00BE43260EE9CDFA0008420F /* SkMaskFilter.cpp */,
-				00BE43270EE9CDFA0008420F /* SkPackBits.cpp */,
-				00BE43280EE9CDFA0008420F /* SkPaint.cpp */,
-				00BE43290EE9CDFA0008420F /* SkPath.cpp */,
-				00BE432A0EE9CDFA0008420F /* SkPathEffect.cpp */,
-				00BE432B0EE9CDFA0008420F /* SkPathMeasure.cpp */,
-				00BE432C0EE9CDFA0008420F /* SkPixelRef.cpp */,
-				00BE432D0EE9CDFA0008420F /* SkProcSpriteBlitter.cpp */,
-				00BE432E0EE9CDFA0008420F /* SkPtrRecorder.cpp */,
-				00BE432F0EE9CDFA0008420F /* SkRasterizer.cpp */,
-				00BE43300EE9CDFA0008420F /* SkRefCnt.cpp */,
-				00BE43310EE9CDFA0008420F /* SkRegion_path.cpp */,
-				00BE43320EE9CDFA0008420F /* SkScalerContext.cpp */,
-				00BE43330EE9CDFA0008420F /* SkScan.cpp */,
-				00BE43340EE9CDFA0008420F /* SkScan.h */,
-				00BE43350EE9CDFA0008420F /* SkScan_Antihair.cpp */,
-				00BE43360EE9CDFA0008420F /* SkScan_AntiPath.cpp */,
-				00BE43370EE9CDFA0008420F /* SkScan_Hairline.cpp */,
-				00BE43380EE9CDFA0008420F /* SkScan_Path.cpp */,
-				00BE43390EE9CDFA0008420F /* SkScanPriv.h */,
-				00BE433A0EE9CDFA0008420F /* SkShader.cpp */,
-				00BE433B0EE9CDFA0008420F /* SkSpriteBlitter.h */,
-				00BE433C0EE9CDFA0008420F /* SkSpriteBlitter_ARGB32.cpp */,
-				00BE433D0EE9CDFA0008420F /* SkSpriteBlitter_RGB16.cpp */,
-				00BE433E0EE9CDFA0008420F /* SkSpriteBlitterTemplate.h */,
-				00BE43400EE9CDFA0008420F /* SkStroke.cpp */,
-				00BE43410EE9CDFA0008420F /* SkStrokerPriv.cpp */,
-				00BE43420EE9CDFA0008420F /* SkStrokerPriv.h */,
-				00BE43430EE9CDFA0008420F /* SkTemplatesPriv.h */,
-				00BE43440EE9CDFA0008420F /* SkTSearch.cpp */,
-				00BE43450EE9CDFA0008420F /* SkTSort.h */,
-				00BE43460EE9CDFA0008420F /* SkTypeface.cpp */,
-				00BE43470EE9CDFA0008420F /* SkUnPreMultiply.cpp */,
-				00BE43490EE9CDFA0008420F /* SkWriter32.cpp */,
-				00BE434A0EE9CDFA0008420F /* SkXfermode.cpp */,
-				00BE434B0EE9CDFA0008420F /* Sk64.cpp */,
-				00BE434C0EE9CDFA0008420F /* SkBuffer.cpp */,
-				00BE434D0EE9CDFA0008420F /* SkChunkAlloc.cpp */,
-				00BE434E0EE9CDFA0008420F /* SkCordic.cpp */,
-				00BE434F0EE9CDFA0008420F /* SkCordic.h */,
-				00BE43500EE9CDFA0008420F /* SkDebug.cpp */,
-				00BE43510EE9CDFA0008420F /* SkDebug_stdio.cpp */,
-				00BE43520EE9CDFA0008420F /* SkFloat.cpp */,
-				00BE43530EE9CDFA0008420F /* SkFloat.h */,
-				00BE43540EE9CDFA0008420F /* SkFloatBits.cpp */,
-				00BE43550EE9CDFA0008420F /* SkInterpolator.cpp */,
-				00BE43560EE9CDFA0008420F /* SkMath.cpp */,
-				00BE43570EE9CDFA0008420F /* SkMatrix.cpp */,
-				00BE43580EE9CDFA0008420F /* SkMemory_stdlib.cpp */,
-				00BE43590EE9CDFA0008420F /* SkPageFlipper.cpp */,
-				00BE435A0EE9CDFA0008420F /* SkPoint.cpp */,
-				00BE435B0EE9CDFA0008420F /* SkRect.cpp */,
-				00BE435C0EE9CDFA0008420F /* SkRegion.cpp */,
-			);
-			name = core;
-			sourceTree = "<group>";
-		};
-		00BE444E0EE9D1780008420F /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00BE44670EE9D1780008420F /* libgiflib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00BE44570EE9D1780008420F /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00BE446A0EE9D1780008420F /* libjpeg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00BE445A0EE9D1780008420F /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00BE446D0EE9D1780008420F /* liblibpng.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00BE445D0EE9D1780008420F /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00BE44700EE9D1780008420F /* libzlib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		08FB7794FE84155DC02AAC07 /* skia2 */ = {
-			isa = PBXGroup;
-			children = (
-				00AFCD780EF167A300BD2FF1 /* xml */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-				00BE42D90EE9CDFA0008420F /* core */,
-				00BE42D20EE9CDFA0008420F /* port */,
-				00BE42BC0EE9CDFA0008420F /* image */,
-				00BE42A00EE9CDFA0008420F /* view */,
-				00BE427F0EE9CDFA0008420F /* effects */,
-				00BE444D0EE9D1780008420F /* giflib.xcodeproj */,
-				00BE44560EE9D1780008420F /* jpeg.xcodeproj */,
-				00BE44590EE9D1780008420F /* libpng.xcodeproj */,
-				00BE445C0EE9D1780008420F /* zlib.xcodeproj */,
-				00A567680EED77850096A2A1 /* freetype2.xcodeproj */,
-				00AFCE0D0EF16BA400BD2FF1 /* expat.xcodeproj */,
-			);
-			name = skia2;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libskia2.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00BE43620EE9CDFA0008420F /* SkBlurMask.h in Headers */,
-				00BE436E0EE9CDFA0008420F /* SkEmbossMask.h in Headers */,
-				00BE436F0EE9CDFA0008420F /* SkEmbossMask_Table.h in Headers */,
-				00BE43790EE9CDFA0008420F /* SkRadialGradient_Table.h in Headers */,
-				00BE438E0EE9CDFA0008420F /* SkTagList.h in Headers */,
-				00BE43930EE9CDFA0008420F /* SkViewPriv.h in Headers */,
-				00BE43A60EE9CDFA0008420F /* SkImageRefPool.h in Headers */,
-				00BE43AB0EE9CDFA0008420F /* SkScaledBitmapSampler.h in Headers */,
-				00BE43B40EE9CDFA0008420F /* SkPathHeap.h in Headers */,
-				00BE43B70EE9CDFA0008420F /* SkPictureFlat.h in Headers */,
-				00BE43B90EE9CDFA0008420F /* SkPicturePlayback.h in Headers */,
-				00BE43BB0EE9CDFA0008420F /* SkPictureRecord.h in Headers */,
-				00BE43BD0EE9CDFA0008420F /* SkGL.h in Headers */,
-				00BE43C00EE9CDFA0008420F /* SkGLDevice.h in Headers */,
-				00BE43C20EE9CDFA0008420F /* SkGLDevice_FBO.h in Headers */,
-				00BE43C40EE9CDFA0008420F /* SkGLDevice_SWLayer.h in Headers */,
-				00BE43C60EE9CDFA0008420F /* SkGLTextCache.h in Headers */,
-				00BE43C80EE9CDFA0008420F /* SkTextureCache.h in Headers */,
-				00BE43CA0EE9CDFA0008420F /* SkAntiRun.h in Headers */,
-				00BE43CB0EE9CDFA0008420F /* SkAutoKern.h in Headers */,
-				00BE43CF0EE9CDFA0008420F /* SkBitmapProcShader.h in Headers */,
-				00BE43D10EE9CDFA0008420F /* SkBitmapProcState.h in Headers */,
-				00BE43D20EE9CDFA0008420F /* SkBitmapProcState_matrix.h in Headers */,
-				00BE43D40EE9CDFA0008420F /* SkBitmapProcState_sample.h in Headers */,
-				00BE43D60EE9CDFA0008420F /* SkBitmapSampler.h in Headers */,
-				00BE43D70EE9CDFA0008420F /* SkBitmapSamplerTemplate.h in Headers */,
-				00BE43D90EE9CDFA0008420F /* SkBitmapShader.h in Headers */,
-				00BE43DA0EE9CDFA0008420F /* SkBitmapShader16BilerpTemplate.h in Headers */,
-				00BE43DB0EE9CDFA0008420F /* SkBitmapShaderTemplate.h in Headers */,
-				00BE43DC0EE9CDFA0008420F /* SkBlitBWMaskTemplate.h in Headers */,
-				00BE43DD0EE9CDFA0008420F /* SkBlitRow.h in Headers */,
-				00BE43E10EE9CDFA0008420F /* SkBlitter.h in Headers */,
-				00BE43EC0EE9CDFA0008420F /* SkCoreBlitters.h in Headers */,
-				00BE43F10EE9CDFA0008420F /* SkDrawProcs.h in Headers */,
-				00BE43F30EE9CDFA0008420F /* SkEdge.h in Headers */,
-				00BE43F50EE9CDFA0008420F /* SkFilterProc.h in Headers */,
-				00BE43F70EE9CDFA0008420F /* SkFP.h in Headers */,
-				00BE43F90EE9CDFA0008420F /* SkGeometry.h in Headers */,
-				00BE43FC0EE9CDFA0008420F /* SkGlyphCache.h in Headers */,
-				00BE440D0EE9CDFA0008420F /* SkScan.h in Headers */,
-				00BE44120EE9CDFA0008420F /* SkScanPriv.h in Headers */,
-				00BE44140EE9CDFA0008420F /* SkSpriteBlitter.h in Headers */,
-				00BE44170EE9CDFA0008420F /* SkSpriteBlitterTemplate.h in Headers */,
-				00BE441B0EE9CDFA0008420F /* SkStrokerPriv.h in Headers */,
-				00BE441C0EE9CDFA0008420F /* SkTemplatesPriv.h in Headers */,
-				00BE441E0EE9CDFA0008420F /* SkTSort.h in Headers */,
-				00BE44280EE9CDFA0008420F /* SkCordic.h in Headers */,
-				00BE442C0EE9CDFA0008420F /* SkFloat.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* skia2 */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "skia2" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				00BE44F10EE9D70D0008420F /* PBXTargetDependency */,
-				00BE44F50EE9D70D0008420F /* PBXTargetDependency */,
-				00BE44F70EE9D70D0008420F /* PBXTargetDependency */,
-				003E929B0EED79240091D85B /* PBXTargetDependency */,
-				003E92DA0EED7C3B0091D85B /* PBXTargetDependency */,
-				00AFCE180EF16BBB00BD2FF1 /* PBXTargetDependency */,
-			);
-			name = skia2;
-			productName = skia2;
-			productReference = D2AAC046055464E500DB518D /* libskia2.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "skia2" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* skia2 */;
-			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 00AFCE0E0EF16BA400BD2FF1 /* Products */;
-					ProjectRef = 00AFCE0D0EF16BA400BD2FF1 /* expat.xcodeproj */;
-				},
-				{
-					ProductGroup = 00A567690EED77850096A2A1 /* Products */;
-					ProjectRef = 00A567680EED77850096A2A1 /* freetype2.xcodeproj */;
-				},
-				{
-					ProductGroup = 00BE444E0EE9D1780008420F /* Products */;
-					ProjectRef = 00BE444D0EE9D1780008420F /* giflib.xcodeproj */;
-				},
-				{
-					ProductGroup = 00BE44570EE9D1780008420F /* Products */;
-					ProjectRef = 00BE44560EE9D1780008420F /* jpeg.xcodeproj */;
-				},
-				{
-					ProductGroup = 00BE445A0EE9D1780008420F /* Products */;
-					ProjectRef = 00BE44590EE9D1780008420F /* libpng.xcodeproj */;
-				},
-				{
-					ProductGroup = 00BE445D0EE9D1780008420F /* Products */;
-					ProjectRef = 00BE445C0EE9D1780008420F /* zlib.xcodeproj */;
-				},
-			);
-			projectRoot = "";
-			targets = (
-				D2AAC045055464E500DB518D /* skia2 */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXReferenceProxy section */
-		00A5676D0EED77850096A2A1 /* libfreetype.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libfreetype.a;
-			remoteRef = 00A5676C0EED77850096A2A1 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00AFCE150EF16BA400BD2FF1 /* libexpat.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libexpat.a;
-			remoteRef = 00AFCE140EF16BA400BD2FF1 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00BE44670EE9D1780008420F /* libgiflib.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libgiflib.a;
-			remoteRef = 00BE44660EE9D1780008420F /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00BE446A0EE9D1780008420F /* libjpeg.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libjpeg.a;
-			remoteRef = 00BE44690EE9D1780008420F /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00BE446D0EE9D1780008420F /* liblibpng.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = liblibpng.a;
-			remoteRef = 00BE446C0EE9D1780008420F /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00BE44700EE9D1780008420F /* libzlib.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libzlib.a;
-			remoteRef = 00BE446F0EE9D1780008420F /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00BE435D0EE9CDFA0008420F /* Sk1DPathEffect.cpp in Sources */,
-				00BE435E0EE9CDFA0008420F /* Sk2DPathEffect.cpp in Sources */,
-				00BE435F0EE9CDFA0008420F /* SkAvoidXfermode.cpp in Sources */,
-				00BE43600EE9CDFA0008420F /* SkBlurDrawLooper.cpp in Sources */,
-				00BE43610EE9CDFA0008420F /* SkBlurMask.cpp in Sources */,
-				00BE43630EE9CDFA0008420F /* SkBlurMaskFilter.cpp in Sources */,
-				00BE43640EE9CDFA0008420F /* SkCamera.cpp in Sources */,
-				00BE43650EE9CDFA0008420F /* SkColorFilters.cpp in Sources */,
-				00BE43660EE9CDFA0008420F /* SkColorMatrix.cpp in Sources */,
-				00BE43670EE9CDFA0008420F /* SkColorMatrixFilter.cpp in Sources */,
-				00BE43680EE9CDFA0008420F /* SkCornerPathEffect.cpp in Sources */,
-				00BE43690EE9CDFA0008420F /* SkCullPoints.cpp in Sources */,
-				00BE436A0EE9CDFA0008420F /* SkDashPathEffect.cpp in Sources */,
-				00BE436B0EE9CDFA0008420F /* SkDiscretePathEffect.cpp in Sources */,
-				00BE436C0EE9CDFA0008420F /* SkDumpCanvas.cpp in Sources */,
-				00BE436D0EE9CDFA0008420F /* SkEmbossMask.cpp in Sources */,
-				00BE43700EE9CDFA0008420F /* SkEmbossMaskFilter.cpp in Sources */,
-				00BE43710EE9CDFA0008420F /* SkGradientShader.cpp in Sources */,
-				00BE43720EE9CDFA0008420F /* SkKernel33MaskFilter.cpp in Sources */,
-				00BE43730EE9CDFA0008420F /* SkLayerDrawLooper.cpp in Sources */,
-				00BE43740EE9CDFA0008420F /* SkLayerRasterizer.cpp in Sources */,
-				00BE43750EE9CDFA0008420F /* SkNinePatch.cpp in Sources */,
-				00BE43760EE9CDFA0008420F /* SkPaintFlagsDrawFilter.cpp in Sources */,
-				00BE43770EE9CDFA0008420F /* SkPixelXorXfermode.cpp in Sources */,
-				00BE43780EE9CDFA0008420F /* SkProxyCanvas.cpp in Sources */,
-				00BE437A0EE9CDFA0008420F /* SkShaderExtras.cpp in Sources */,
-				00BE437B0EE9CDFA0008420F /* SkTransparentShader.cpp in Sources */,
-				00BE437C0EE9CDFA0008420F /* SkUnitMappers.cpp in Sources */,
-				00BE437D0EE9CDFA0008420F /* SkBGViewArtist.cpp in Sources */,
-				00BE437E0EE9CDFA0008420F /* SkBorderView.cpp in Sources */,
-				00BE437F0EE9CDFA0008420F /* SkEvent.cpp in Sources */,
-				00BE43800EE9CDFA0008420F /* SkEventSink.cpp in Sources */,
-				00BE43810EE9CDFA0008420F /* SkImageView.cpp in Sources */,
-				00BE43820EE9CDFA0008420F /* SkListView.cpp in Sources */,
-				00BE43830EE9CDFA0008420F /* SkListWidget.cpp in Sources */,
-				00BE43840EE9CDFA0008420F /* SkMetaData.cpp in Sources */,
-				00BE43850EE9CDFA0008420F /* SkOSFile.cpp in Sources */,
-				00BE43860EE9CDFA0008420F /* SkOSMenu.cpp in Sources */,
-				00BE43870EE9CDFA0008420F /* SkOSSound.cpp in Sources */,
-				00BE43880EE9CDFA0008420F /* SkParsePaint.cpp in Sources */,
-				00BE43890EE9CDFA0008420F /* SkProgressBarView.cpp in Sources */,
-				00BE438A0EE9CDFA0008420F /* SkProgressView.cpp in Sources */,
-				00BE438B0EE9CDFA0008420F /* SkScrollBarView.cpp in Sources */,
-				00BE438C0EE9CDFA0008420F /* SkStackViewLayout.cpp in Sources */,
-				00BE438D0EE9CDFA0008420F /* SkTagList.cpp in Sources */,
-				00BE438F0EE9CDFA0008420F /* SkTextBox.cpp in Sources */,
-				00BE43900EE9CDFA0008420F /* SkView.cpp in Sources */,
-				00BE43910EE9CDFA0008420F /* SkViewInflate.cpp in Sources */,
-				00BE43920EE9CDFA0008420F /* SkViewPriv.cpp in Sources */,
-				00BE43940EE9CDFA0008420F /* SkWidget.cpp in Sources */,
-				00BE43950EE9CDFA0008420F /* SkWidgets.cpp in Sources */,
-				00BE43960EE9CDFA0008420F /* SkWidgetViews.cpp in Sources */,
-				00BE43970EE9CDFA0008420F /* SkWindow.cpp in Sources */,
-				00BE43980EE9CDFA0008420F /* SkFDStream.cpp in Sources */,
-				00BE43990EE9CDFA0008420F /* SkFlipPixelRef.cpp in Sources */,
-				00BE439A0EE9CDFA0008420F /* SkImageDecoder.cpp in Sources */,
-				00BE439C0EE9CDFA0008420F /* SkImageDecoder_libbmp.cpp in Sources */,
-				00BE439E0EE9CDFA0008420F /* SkImageDecoder_libico.cpp in Sources */,
-				00BE43A20EE9CDFA0008420F /* SkImageDecoder_wbmp.cpp in Sources */,
-				00BE43A30EE9CDFA0008420F /* SkImageRef.cpp in Sources */,
-				00BE43A40EE9CDFA0008420F /* SkImageRef_GlobalPool.cpp in Sources */,
-				00BE43A50EE9CDFA0008420F /* SkImageRefPool.cpp in Sources */,
-				00BE43A70EE9CDFA0008420F /* SkMMapStream.cpp in Sources */,
-				00BE43A80EE9CDFA0008420F /* SkMovie.cpp in Sources */,
-				00BE43AA0EE9CDFA0008420F /* SkScaledBitmapSampler.cpp in Sources */,
-				00BE43AC0EE9CDFA0008420F /* SkStream.cpp in Sources */,
-				00BE43AD0EE9CDFA0008420F /* SkFontHost_android.cpp in Sources */,
-				00BE43AE0EE9CDFA0008420F /* SkFontHost_gamma.cpp in Sources */,
-				00BE43AF0EE9CDFA0008420F /* SkGlobals_global.cpp in Sources */,
-				00BE43B00EE9CDFA0008420F /* SkImageDecoder_Factory.cpp in Sources */,
-				00BE43B10EE9CDFA0008420F /* SkThread_pthread.cpp in Sources */,
-				00BE43B20EE9CDFA0008420F /* SkTime_Unix.cpp in Sources */,
-				00BE43B30EE9CDFA0008420F /* SkPathHeap.cpp in Sources */,
-				00BE43B50EE9CDFA0008420F /* SkPicture.cpp in Sources */,
-				00BE43B60EE9CDFA0008420F /* SkPictureFlat.cpp in Sources */,
-				00BE43B80EE9CDFA0008420F /* SkPicturePlayback.cpp in Sources */,
-				00BE43BA0EE9CDFA0008420F /* SkPictureRecord.cpp in Sources */,
-				00BE43BC0EE9CDFA0008420F /* SkGL.cpp in Sources */,
-				00BE43BE0EE9CDFA0008420F /* SkGLCanvas.cpp in Sources */,
-				00BE43BF0EE9CDFA0008420F /* SkGLDevice.cpp in Sources */,
-				00BE43C10EE9CDFA0008420F /* SkGLDevice_FBO.cpp in Sources */,
-				00BE43C30EE9CDFA0008420F /* SkGLDevice_SWLayer.cpp in Sources */,
-				00BE43C50EE9CDFA0008420F /* SkGLTextCache.cpp in Sources */,
-				00BE43C70EE9CDFA0008420F /* SkTextureCache.cpp in Sources */,
-				00BE43C90EE9CDFA0008420F /* SkAlphaRuns.cpp in Sources */,
-				00BE43CC0EE9CDFA0008420F /* SkBitmap.cpp in Sources */,
-				00BE43CD0EE9CDFA0008420F /* SkBitmap_scroll.cpp in Sources */,
-				00BE43CE0EE9CDFA0008420F /* SkBitmapProcShader.cpp in Sources */,
-				00BE43D00EE9CDFA0008420F /* SkBitmapProcState.cpp in Sources */,
-				00BE43D30EE9CDFA0008420F /* SkBitmapProcState_matrixProcs.cpp in Sources */,
-				00BE43D50EE9CDFA0008420F /* SkBitmapSampler.cpp in Sources */,
-				00BE43D80EE9CDFA0008420F /* SkBitmapShader.cpp in Sources */,
-				00BE43DE0EE9CDFA0008420F /* SkBlitRow_D16.cpp in Sources */,
-				00BE43DF0EE9CDFA0008420F /* SkBlitRow_D4444.cpp in Sources */,
-				00BE43E00EE9CDFA0008420F /* SkBlitter.cpp in Sources */,
-				00BE43E20EE9CDFA0008420F /* SkBlitter_4444.cpp in Sources */,
-				00BE43E30EE9CDFA0008420F /* SkBlitter_A1.cpp in Sources */,
-				00BE43E40EE9CDFA0008420F /* SkBlitter_A8.cpp in Sources */,
-				00BE43E50EE9CDFA0008420F /* SkBlitter_ARGB32.cpp in Sources */,
-				00BE43E60EE9CDFA0008420F /* SkBlitter_RGB16.cpp in Sources */,
-				00BE43E70EE9CDFA0008420F /* SkBlitter_Sprite.cpp in Sources */,
-				00BE43E80EE9CDFA0008420F /* SkCanvas.cpp in Sources */,
-				00BE43E90EE9CDFA0008420F /* SkColor.cpp in Sources */,
-				00BE43EA0EE9CDFA0008420F /* SkColorFilter.cpp in Sources */,
-				00BE43EB0EE9CDFA0008420F /* SkColorTable.cpp in Sources */,
-				00BE43ED0EE9CDFA0008420F /* SkDeque.cpp in Sources */,
-				00BE43EE0EE9CDFA0008420F /* SkDevice.cpp in Sources */,
-				00BE43EF0EE9CDFA0008420F /* SkDither.cpp in Sources */,
-				00BE43F00EE9CDFA0008420F /* SkDraw.cpp in Sources */,
-				00BE43F20EE9CDFA0008420F /* SkEdge.cpp in Sources */,
-				00BE43F40EE9CDFA0008420F /* SkFilterProc.cpp in Sources */,
-				00BE43F60EE9CDFA0008420F /* SkFlattenable.cpp in Sources */,
-				00BE43F80EE9CDFA0008420F /* SkGeometry.cpp in Sources */,
-				00BE43FA0EE9CDFA0008420F /* SkGlobals.cpp in Sources */,
-				00BE43FB0EE9CDFA0008420F /* SkGlyphCache.cpp in Sources */,
-				00BE43FD0EE9CDFA0008420F /* SkGraphics.cpp in Sources */,
-				00BE43FE0EE9CDFA0008420F /* SkMask.cpp in Sources */,
-				00BE43FF0EE9CDFA0008420F /* SkMaskFilter.cpp in Sources */,
-				00BE44000EE9CDFA0008420F /* SkPackBits.cpp in Sources */,
-				00BE44010EE9CDFA0008420F /* SkPaint.cpp in Sources */,
-				00BE44020EE9CDFA0008420F /* SkPath.cpp in Sources */,
-				00BE44030EE9CDFA0008420F /* SkPathEffect.cpp in Sources */,
-				00BE44040EE9CDFA0008420F /* SkPathMeasure.cpp in Sources */,
-				00BE44050EE9CDFA0008420F /* SkPixelRef.cpp in Sources */,
-				00BE44060EE9CDFA0008420F /* SkProcSpriteBlitter.cpp in Sources */,
-				00BE44070EE9CDFA0008420F /* SkPtrRecorder.cpp in Sources */,
-				00BE44080EE9CDFA0008420F /* SkRasterizer.cpp in Sources */,
-				00BE44090EE9CDFA0008420F /* SkRefCnt.cpp in Sources */,
-				00BE440A0EE9CDFA0008420F /* SkRegion_path.cpp in Sources */,
-				00BE440B0EE9CDFA0008420F /* SkScalerContext.cpp in Sources */,
-				00BE440C0EE9CDFA0008420F /* SkScan.cpp in Sources */,
-				00BE440E0EE9CDFA0008420F /* SkScan_Antihair.cpp in Sources */,
-				00BE440F0EE9CDFA0008420F /* SkScan_AntiPath.cpp in Sources */,
-				00BE44100EE9CDFA0008420F /* SkScan_Hairline.cpp in Sources */,
-				00BE44110EE9CDFA0008420F /* SkScan_Path.cpp in Sources */,
-				00BE44130EE9CDFA0008420F /* SkShader.cpp in Sources */,
-				00BE44150EE9CDFA0008420F /* SkSpriteBlitter_ARGB32.cpp in Sources */,
-				00BE44160EE9CDFA0008420F /* SkSpriteBlitter_RGB16.cpp in Sources */,
-				00BE44190EE9CDFA0008420F /* SkStroke.cpp in Sources */,
-				00BE441A0EE9CDFA0008420F /* SkStrokerPriv.cpp in Sources */,
-				00BE441D0EE9CDFA0008420F /* SkTSearch.cpp in Sources */,
-				00BE441F0EE9CDFA0008420F /* SkTypeface.cpp in Sources */,
-				00BE44200EE9CDFA0008420F /* SkUnPreMultiply.cpp in Sources */,
-				00BE44220EE9CDFA0008420F /* SkWriter32.cpp in Sources */,
-				00BE44230EE9CDFA0008420F /* SkXfermode.cpp in Sources */,
-				00BE44240EE9CDFA0008420F /* Sk64.cpp in Sources */,
-				00BE44250EE9CDFA0008420F /* SkBuffer.cpp in Sources */,
-				00BE44260EE9CDFA0008420F /* SkChunkAlloc.cpp in Sources */,
-				00BE44270EE9CDFA0008420F /* SkCordic.cpp in Sources */,
-				00BE44290EE9CDFA0008420F /* SkDebug.cpp in Sources */,
-				00BE442A0EE9CDFA0008420F /* SkDebug_stdio.cpp in Sources */,
-				00BE442B0EE9CDFA0008420F /* SkFloat.cpp in Sources */,
-				00BE442D0EE9CDFA0008420F /* SkFloatBits.cpp in Sources */,
-				00BE442E0EE9CDFA0008420F /* SkInterpolator.cpp in Sources */,
-				00BE442F0EE9CDFA0008420F /* SkMath.cpp in Sources */,
-				00BE44300EE9CDFA0008420F /* SkMatrix.cpp in Sources */,
-				00BE44310EE9CDFA0008420F /* SkMemory_stdlib.cpp in Sources */,
-				00BE44320EE9CDFA0008420F /* SkPageFlipper.cpp in Sources */,
-				00BE44330EE9CDFA0008420F /* SkPoint.cpp in Sources */,
-				00BE44340EE9CDFA0008420F /* SkRect.cpp in Sources */,
-				00BE44350EE9CDFA0008420F /* SkRegion.cpp in Sources */,
-				00BE44C90EE9D4FC0008420F /* SkOSFile_stdio.cpp in Sources */,
-				00BE45070EE9D8120008420F /* bmpdecoderhelper.cpp in Sources */,
-				00AFCD710EF1672C00BD2FF1 /* SkDOM.cpp in Sources */,
-				00AFCD7C0EF167BC00BD2FF1 /* SkParse.cpp in Sources */,
-				00AFCD7D0EF167BC00BD2FF1 /* SkParseColor.cpp in Sources */,
-				00AFCD7E0EF167BC00BD2FF1 /* SkXMLParser.cpp in Sources */,
-				00AFCD890EF1684200BD2FF1 /* SkBitmap_Mac.cpp in Sources */,
-				00AFCD8B0EF1685100BD2FF1 /* SkOSWindow_Mac.cpp in Sources */,
-				006B43FE0EF7526E00F15BC4 /* SkString.cpp in Sources */,
-				006B43FF0EF7526E00F15BC4 /* SkUtils.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		003E929B0EED79240091D85B /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = freetype;
-			targetProxy = 003E929A0EED79240091D85B /* PBXContainerItemProxy */;
-		};
-		003E92DA0EED7C3B0091D85B /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = zlib;
-			targetProxy = 003E92D90EED7C3B0091D85B /* PBXContainerItemProxy */;
-		};
-		00AFCE180EF16BBB00BD2FF1 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = expat;
-			targetProxy = 00AFCE170EF16BBB00BD2FF1 /* PBXContainerItemProxy */;
-		};
-		00BE44F10EE9D70D0008420F /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = jpeg;
-			targetProxy = 00BE44F00EE9D70D0008420F /* PBXContainerItemProxy */;
-		};
-		00BE44F50EE9D70D0008420F /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = giflib;
-			targetProxy = 00BE44F40EE9D70D0008420F /* PBXContainerItemProxy */;
-		};
-		00BE44F70EE9D70D0008420F /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = libpng;
-			targetProxy = 00BE44F60EE9D70D0008420F /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
-		00A9BB930EF6BFC400D8DC2B /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_MODEL_TUNING = "";
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_RELEASE,
-					SK_BUILD_FOR_MAC,
-				);
-				GCC_STRICT_ALIASING = YES;
-				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_SIGN_COMPARE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-				VALID_ARCHS = "i386 x86_64";
-			};
-			name = Release;
-		};
-		00A9BB940EF6BFC400D8DC2B /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = skia2;
-				ZERO_LINK = YES;
-			};
-			name = Release;
-		};
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = skia2;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_OBJC_EXCEPTIONS = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					SK_BUILD_FOR_MAC,
-					SK_DEBUG,
-				);
-				GCC_STRICT_ALIASING = YES;
-				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_SIGN_COMPARE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				USER_HEADER_SEARCH_PATHS = "../include/**";
-				VALID_ARCHS = "i386 x86_64";
-			};
-			name = Debug;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "skia2" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				00A9BB940EF6BFC400D8DC2B /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "skia2" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				00A9BB930EF6BFC400D8DC2B /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/svg.xcodeproj/project.pbxproj b/xcode/svg.xcodeproj/project.pbxproj
deleted file mode 100644
index c4374eb..0000000
--- a/xcode/svg.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,435 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		002843AB09DDC030002E9CB0 /* SkSVGCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028437609DDC02F002E9CB0 /* SkSVGCircle.cpp */; };
-		002843AC09DDC030002E9CB0 /* SkSVGCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028437709DDC02F002E9CB0 /* SkSVGCircle.h */; };
-		002843AD09DDC030002E9CB0 /* SkSVGClipPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028437809DDC02F002E9CB0 /* SkSVGClipPath.cpp */; };
-		002843AE09DDC030002E9CB0 /* SkSVGClipPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028437909DDC02F002E9CB0 /* SkSVGClipPath.h */; };
-		002843AF09DDC030002E9CB0 /* SkSVGDefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028437A09DDC02F002E9CB0 /* SkSVGDefs.cpp */; };
-		002843B009DDC030002E9CB0 /* SkSVGDefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028437B09DDC02F002E9CB0 /* SkSVGDefs.h */; };
-		002843B109DDC030002E9CB0 /* SkSVGElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028437C09DDC02F002E9CB0 /* SkSVGElements.cpp */; };
-		002843B209DDC030002E9CB0 /* SkSVGElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028437D09DDC02F002E9CB0 /* SkSVGElements.h */; };
-		002843B309DDC030002E9CB0 /* SkSVGEllipse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028437E09DDC02F002E9CB0 /* SkSVGEllipse.cpp */; };
-		002843B409DDC030002E9CB0 /* SkSVGEllipse.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028437F09DDC02F002E9CB0 /* SkSVGEllipse.h */; };
-		002843B509DDC030002E9CB0 /* SkSVGFeColorMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438009DDC02F002E9CB0 /* SkSVGFeColorMatrix.cpp */; };
-		002843B609DDC030002E9CB0 /* SkSVGFeColorMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438109DDC02F002E9CB0 /* SkSVGFeColorMatrix.h */; };
-		002843B709DDC030002E9CB0 /* SkSVGFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438209DDC02F002E9CB0 /* SkSVGFilter.cpp */; };
-		002843B809DDC030002E9CB0 /* SkSVGFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438309DDC02F002E9CB0 /* SkSVGFilter.h */; };
-		002843B909DDC030002E9CB0 /* SkSVGG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438409DDC02F002E9CB0 /* SkSVGG.cpp */; };
-		002843BA09DDC030002E9CB0 /* SkSVGG.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438509DDC02F002E9CB0 /* SkSVGG.h */; };
-		002843BB09DDC030002E9CB0 /* SkSVGGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438609DDC02F002E9CB0 /* SkSVGGradient.cpp */; };
-		002843BC09DDC030002E9CB0 /* SkSVGGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438709DDC02F002E9CB0 /* SkSVGGradient.h */; };
-		002843BD09DDC030002E9CB0 /* SkSVGGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438809DDC02F002E9CB0 /* SkSVGGroup.cpp */; };
-		002843BE09DDC030002E9CB0 /* SkSVGGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438909DDC02F002E9CB0 /* SkSVGGroup.h */; };
-		002843BF09DDC030002E9CB0 /* SkSVGImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438A09DDC02F002E9CB0 /* SkSVGImage.cpp */; };
-		002843C009DDC030002E9CB0 /* SkSVGImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438B09DDC02F002E9CB0 /* SkSVGImage.h */; };
-		002843C109DDC030002E9CB0 /* SkSVGLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438C09DDC02F002E9CB0 /* SkSVGLine.cpp */; };
-		002843C209DDC030002E9CB0 /* SkSVGLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438D09DDC02F002E9CB0 /* SkSVGLine.h */; };
-		002843C309DDC030002E9CB0 /* SkSVGLinearGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028438E09DDC02F002E9CB0 /* SkSVGLinearGradient.cpp */; };
-		002843C409DDC030002E9CB0 /* SkSVGLinearGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028438F09DDC02F002E9CB0 /* SkSVGLinearGradient.h */; };
-		002843C509DDC030002E9CB0 /* SkSVGMask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439009DDC02F002E9CB0 /* SkSVGMask.cpp */; };
-		002843C609DDC030002E9CB0 /* SkSVGMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439109DDC02F002E9CB0 /* SkSVGMask.h */; };
-		002843C709DDC030002E9CB0 /* SkSVGMetadata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439209DDC02F002E9CB0 /* SkSVGMetadata.cpp */; };
-		002843C809DDC030002E9CB0 /* SkSVGMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439309DDC02F002E9CB0 /* SkSVGMetadata.h */; };
-		002843C909DDC030002E9CB0 /* SkSVGPaintState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439409DDC02F002E9CB0 /* SkSVGPaintState.cpp */; };
-		002843CA09DDC030002E9CB0 /* SkSVGParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439509DDC02F002E9CB0 /* SkSVGParser.cpp */; };
-		002843CB09DDC030002E9CB0 /* SkSVGPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439609DDC02F002E9CB0 /* SkSVGPath.cpp */; };
-		002843CC09DDC030002E9CB0 /* SkSVGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439709DDC02F002E9CB0 /* SkSVGPath.h */; };
-		002843CD09DDC030002E9CB0 /* SkSVGPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439809DDC02F002E9CB0 /* SkSVGPolygon.cpp */; };
-		002843CE09DDC030002E9CB0 /* SkSVGPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439909DDC02F002E9CB0 /* SkSVGPolygon.h */; };
-		002843CF09DDC030002E9CB0 /* SkSVGPolyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439A09DDC02F002E9CB0 /* SkSVGPolyline.cpp */; };
-		002843D009DDC030002E9CB0 /* SkSVGPolyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439B09DDC02F002E9CB0 /* SkSVGPolyline.h */; };
-		002843D109DDC030002E9CB0 /* SkSVGRadialGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439C09DDC02F002E9CB0 /* SkSVGRadialGradient.cpp */; };
-		002843D209DDC030002E9CB0 /* SkSVGRadialGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439D09DDC02F002E9CB0 /* SkSVGRadialGradient.h */; };
-		002843D309DDC030002E9CB0 /* SkSVGRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0028439E09DDC02F002E9CB0 /* SkSVGRect.cpp */; };
-		002843D409DDC030002E9CB0 /* SkSVGRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 0028439F09DDC02F002E9CB0 /* SkSVGRect.h */; };
-		002843D509DDC030002E9CB0 /* SkSVGStop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002843A009DDC02F002E9CB0 /* SkSVGStop.cpp */; };
-		002843D609DDC030002E9CB0 /* SkSVGStop.h in Headers */ = {isa = PBXBuildFile; fileRef = 002843A109DDC02F002E9CB0 /* SkSVGStop.h */; };
-		002843D709DDC030002E9CB0 /* SkSVGSVG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002843A209DDC02F002E9CB0 /* SkSVGSVG.cpp */; };
-		002843D809DDC030002E9CB0 /* SkSVGSVG.h in Headers */ = {isa = PBXBuildFile; fileRef = 002843A309DDC02F002E9CB0 /* SkSVGSVG.h */; };
-		002843D909DDC030002E9CB0 /* SkSVGSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002843A409DDC02F002E9CB0 /* SkSVGSymbol.cpp */; };
-		002843DA09DDC030002E9CB0 /* SkSVGSymbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 002843A509DDC02F002E9CB0 /* SkSVGSymbol.h */; };
-		002843DB09DDC030002E9CB0 /* SkSVGText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002843A609DDC02F002E9CB0 /* SkSVGText.cpp */; };
-		002843DC09DDC030002E9CB0 /* SkSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 002843A709DDC02F002E9CB0 /* SkSVGText.h */; };
-		002843DD09DDC030002E9CB0 /* SkSVGUse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002843A809DDC02F002E9CB0 /* SkSVGUse.cpp */; };
-		002843DE09DDC030002E9CB0 /* SkSVGUse.h in Headers */ = {isa = PBXBuildFile; fileRef = 002843A909DDC02F002E9CB0 /* SkSVGUse.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXBuildStyle section */
-		014CEA520018CE5811CA2923 /* Debug */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-			};
-			name = Debug;
-		};
-		014CEA530018CE5811CA2923 /* Release */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-			};
-			name = Release;
-		};
-/* End PBXBuildStyle section */
-
-/* Begin PBXFileReference section */
-		0028437609DDC02F002E9CB0 /* SkSVGCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGCircle.cpp; sourceTree = "<group>"; };
-		0028437709DDC02F002E9CB0 /* SkSVGCircle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGCircle.h; sourceTree = "<group>"; };
-		0028437809DDC02F002E9CB0 /* SkSVGClipPath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGClipPath.cpp; sourceTree = "<group>"; };
-		0028437909DDC02F002E9CB0 /* SkSVGClipPath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGClipPath.h; sourceTree = "<group>"; };
-		0028437A09DDC02F002E9CB0 /* SkSVGDefs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGDefs.cpp; sourceTree = "<group>"; };
-		0028437B09DDC02F002E9CB0 /* SkSVGDefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGDefs.h; sourceTree = "<group>"; };
-		0028437C09DDC02F002E9CB0 /* SkSVGElements.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGElements.cpp; sourceTree = "<group>"; };
-		0028437D09DDC02F002E9CB0 /* SkSVGElements.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGElements.h; sourceTree = "<group>"; };
-		0028437E09DDC02F002E9CB0 /* SkSVGEllipse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGEllipse.cpp; sourceTree = "<group>"; };
-		0028437F09DDC02F002E9CB0 /* SkSVGEllipse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGEllipse.h; sourceTree = "<group>"; };
-		0028438009DDC02F002E9CB0 /* SkSVGFeColorMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGFeColorMatrix.cpp; sourceTree = "<group>"; };
-		0028438109DDC02F002E9CB0 /* SkSVGFeColorMatrix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGFeColorMatrix.h; sourceTree = "<group>"; };
-		0028438209DDC02F002E9CB0 /* SkSVGFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGFilter.cpp; sourceTree = "<group>"; };
-		0028438309DDC02F002E9CB0 /* SkSVGFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGFilter.h; sourceTree = "<group>"; };
-		0028438409DDC02F002E9CB0 /* SkSVGG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGG.cpp; sourceTree = "<group>"; };
-		0028438509DDC02F002E9CB0 /* SkSVGG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGG.h; sourceTree = "<group>"; };
-		0028438609DDC02F002E9CB0 /* SkSVGGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGGradient.cpp; sourceTree = "<group>"; };
-		0028438709DDC02F002E9CB0 /* SkSVGGradient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGGradient.h; sourceTree = "<group>"; };
-		0028438809DDC02F002E9CB0 /* SkSVGGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGGroup.cpp; sourceTree = "<group>"; };
-		0028438909DDC02F002E9CB0 /* SkSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGGroup.h; sourceTree = "<group>"; };
-		0028438A09DDC02F002E9CB0 /* SkSVGImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGImage.cpp; sourceTree = "<group>"; };
-		0028438B09DDC02F002E9CB0 /* SkSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGImage.h; sourceTree = "<group>"; };
-		0028438C09DDC02F002E9CB0 /* SkSVGLine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGLine.cpp; sourceTree = "<group>"; };
-		0028438D09DDC02F002E9CB0 /* SkSVGLine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGLine.h; sourceTree = "<group>"; };
-		0028438E09DDC02F002E9CB0 /* SkSVGLinearGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGLinearGradient.cpp; sourceTree = "<group>"; };
-		0028438F09DDC02F002E9CB0 /* SkSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGLinearGradient.h; sourceTree = "<group>"; };
-		0028439009DDC02F002E9CB0 /* SkSVGMask.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGMask.cpp; sourceTree = "<group>"; };
-		0028439109DDC02F002E9CB0 /* SkSVGMask.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGMask.h; sourceTree = "<group>"; };
-		0028439209DDC02F002E9CB0 /* SkSVGMetadata.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGMetadata.cpp; sourceTree = "<group>"; };
-		0028439309DDC02F002E9CB0 /* SkSVGMetadata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGMetadata.h; sourceTree = "<group>"; };
-		0028439409DDC02F002E9CB0 /* SkSVGPaintState.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGPaintState.cpp; sourceTree = "<group>"; };
-		0028439509DDC02F002E9CB0 /* SkSVGParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGParser.cpp; sourceTree = "<group>"; };
-		0028439609DDC02F002E9CB0 /* SkSVGPath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGPath.cpp; sourceTree = "<group>"; };
-		0028439709DDC02F002E9CB0 /* SkSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGPath.h; sourceTree = "<group>"; };
-		0028439809DDC02F002E9CB0 /* SkSVGPolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGPolygon.cpp; sourceTree = "<group>"; };
-		0028439909DDC02F002E9CB0 /* SkSVGPolygon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGPolygon.h; sourceTree = "<group>"; };
-		0028439A09DDC02F002E9CB0 /* SkSVGPolyline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGPolyline.cpp; sourceTree = "<group>"; };
-		0028439B09DDC02F002E9CB0 /* SkSVGPolyline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGPolyline.h; sourceTree = "<group>"; };
-		0028439C09DDC02F002E9CB0 /* SkSVGRadialGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGRadialGradient.cpp; sourceTree = "<group>"; };
-		0028439D09DDC02F002E9CB0 /* SkSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGRadialGradient.h; sourceTree = "<group>"; };
-		0028439E09DDC02F002E9CB0 /* SkSVGRect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGRect.cpp; sourceTree = "<group>"; };
-		0028439F09DDC02F002E9CB0 /* SkSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGRect.h; sourceTree = "<group>"; };
-		002843A009DDC02F002E9CB0 /* SkSVGStop.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGStop.cpp; sourceTree = "<group>"; };
-		002843A109DDC02F002E9CB0 /* SkSVGStop.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGStop.h; sourceTree = "<group>"; };
-		002843A209DDC02F002E9CB0 /* SkSVGSVG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGSVG.cpp; sourceTree = "<group>"; };
-		002843A309DDC02F002E9CB0 /* SkSVGSVG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGSVG.h; sourceTree = "<group>"; };
-		002843A409DDC02F002E9CB0 /* SkSVGSymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGSymbol.cpp; sourceTree = "<group>"; };
-		002843A509DDC02F002E9CB0 /* SkSVGSymbol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGSymbol.h; sourceTree = "<group>"; };
-		002843A609DDC02F002E9CB0 /* SkSVGText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGText.cpp; sourceTree = "<group>"; };
-		002843A709DDC02F002E9CB0 /* SkSVGText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGText.h; sourceTree = "<group>"; };
-		002843A809DDC02F002E9CB0 /* SkSVGUse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SkSVGUse.cpp; sourceTree = "<group>"; };
-		002843A909DDC02F002E9CB0 /* SkSVGUse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SkSVGUse.h; sourceTree = "<group>"; };
-		D2AAC046055464E500DB518D /* libsvg.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsvg.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		0028437409DDC02F002E9CB0 /* svg */ = {
-			isa = PBXGroup;
-			children = (
-				0028437609DDC02F002E9CB0 /* SkSVGCircle.cpp */,
-				0028437709DDC02F002E9CB0 /* SkSVGCircle.h */,
-				0028437809DDC02F002E9CB0 /* SkSVGClipPath.cpp */,
-				0028437909DDC02F002E9CB0 /* SkSVGClipPath.h */,
-				0028437A09DDC02F002E9CB0 /* SkSVGDefs.cpp */,
-				0028437B09DDC02F002E9CB0 /* SkSVGDefs.h */,
-				0028437C09DDC02F002E9CB0 /* SkSVGElements.cpp */,
-				0028437D09DDC02F002E9CB0 /* SkSVGElements.h */,
-				0028437E09DDC02F002E9CB0 /* SkSVGEllipse.cpp */,
-				0028437F09DDC02F002E9CB0 /* SkSVGEllipse.h */,
-				0028438009DDC02F002E9CB0 /* SkSVGFeColorMatrix.cpp */,
-				0028438109DDC02F002E9CB0 /* SkSVGFeColorMatrix.h */,
-				0028438209DDC02F002E9CB0 /* SkSVGFilter.cpp */,
-				0028438309DDC02F002E9CB0 /* SkSVGFilter.h */,
-				0028438409DDC02F002E9CB0 /* SkSVGG.cpp */,
-				0028438509DDC02F002E9CB0 /* SkSVGG.h */,
-				0028438609DDC02F002E9CB0 /* SkSVGGradient.cpp */,
-				0028438709DDC02F002E9CB0 /* SkSVGGradient.h */,
-				0028438809DDC02F002E9CB0 /* SkSVGGroup.cpp */,
-				0028438909DDC02F002E9CB0 /* SkSVGGroup.h */,
-				0028438A09DDC02F002E9CB0 /* SkSVGImage.cpp */,
-				0028438B09DDC02F002E9CB0 /* SkSVGImage.h */,
-				0028438C09DDC02F002E9CB0 /* SkSVGLine.cpp */,
-				0028438D09DDC02F002E9CB0 /* SkSVGLine.h */,
-				0028438E09DDC02F002E9CB0 /* SkSVGLinearGradient.cpp */,
-				0028438F09DDC02F002E9CB0 /* SkSVGLinearGradient.h */,
-				0028439009DDC02F002E9CB0 /* SkSVGMask.cpp */,
-				0028439109DDC02F002E9CB0 /* SkSVGMask.h */,
-				0028439209DDC02F002E9CB0 /* SkSVGMetadata.cpp */,
-				0028439309DDC02F002E9CB0 /* SkSVGMetadata.h */,
-				0028439409DDC02F002E9CB0 /* SkSVGPaintState.cpp */,
-				0028439509DDC02F002E9CB0 /* SkSVGParser.cpp */,
-				0028439609DDC02F002E9CB0 /* SkSVGPath.cpp */,
-				0028439709DDC02F002E9CB0 /* SkSVGPath.h */,
-				0028439809DDC02F002E9CB0 /* SkSVGPolygon.cpp */,
-				0028439909DDC02F002E9CB0 /* SkSVGPolygon.h */,
-				0028439A09DDC02F002E9CB0 /* SkSVGPolyline.cpp */,
-				0028439B09DDC02F002E9CB0 /* SkSVGPolyline.h */,
-				0028439C09DDC02F002E9CB0 /* SkSVGRadialGradient.cpp */,
-				0028439D09DDC02F002E9CB0 /* SkSVGRadialGradient.h */,
-				0028439E09DDC02F002E9CB0 /* SkSVGRect.cpp */,
-				0028439F09DDC02F002E9CB0 /* SkSVGRect.h */,
-				002843A009DDC02F002E9CB0 /* SkSVGStop.cpp */,
-				002843A109DDC02F002E9CB0 /* SkSVGStop.h */,
-				002843A209DDC02F002E9CB0 /* SkSVGSVG.cpp */,
-				002843A309DDC02F002E9CB0 /* SkSVGSVG.h */,
-				002843A409DDC02F002E9CB0 /* SkSVGSymbol.cpp */,
-				002843A509DDC02F002E9CB0 /* SkSVGSymbol.h */,
-				002843A609DDC02F002E9CB0 /* SkSVGText.cpp */,
-				002843A709DDC02F002E9CB0 /* SkSVGText.h */,
-				002843A809DDC02F002E9CB0 /* SkSVGUse.cpp */,
-				002843A909DDC02F002E9CB0 /* SkSVGUse.h */,
-			);
-			name = svg;
-			path = ../../libs/graphics/svg;
-			sourceTree = SOURCE_ROOT;
-		};
-		08FB7794FE84155DC02AAC07 /* svg */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = svg;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				0028437409DDC02F002E9CB0 /* svg */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libsvg.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				002843AC09DDC030002E9CB0 /* SkSVGCircle.h in Headers */,
-				002843AE09DDC030002E9CB0 /* SkSVGClipPath.h in Headers */,
-				002843B009DDC030002E9CB0 /* SkSVGDefs.h in Headers */,
-				002843B209DDC030002E9CB0 /* SkSVGElements.h in Headers */,
-				002843B409DDC030002E9CB0 /* SkSVGEllipse.h in Headers */,
-				002843B609DDC030002E9CB0 /* SkSVGFeColorMatrix.h in Headers */,
-				002843B809DDC030002E9CB0 /* SkSVGFilter.h in Headers */,
-				002843BA09DDC030002E9CB0 /* SkSVGG.h in Headers */,
-				002843BC09DDC030002E9CB0 /* SkSVGGradient.h in Headers */,
-				002843BE09DDC030002E9CB0 /* SkSVGGroup.h in Headers */,
-				002843C009DDC030002E9CB0 /* SkSVGImage.h in Headers */,
-				002843C209DDC030002E9CB0 /* SkSVGLine.h in Headers */,
-				002843C409DDC030002E9CB0 /* SkSVGLinearGradient.h in Headers */,
-				002843C609DDC030002E9CB0 /* SkSVGMask.h in Headers */,
-				002843C809DDC030002E9CB0 /* SkSVGMetadata.h in Headers */,
-				002843CC09DDC030002E9CB0 /* SkSVGPath.h in Headers */,
-				002843CE09DDC030002E9CB0 /* SkSVGPolygon.h in Headers */,
-				002843D009DDC030002E9CB0 /* SkSVGPolyline.h in Headers */,
-				002843D209DDC030002E9CB0 /* SkSVGRadialGradient.h in Headers */,
-				002843D409DDC030002E9CB0 /* SkSVGRect.h in Headers */,
-				002843D609DDC030002E9CB0 /* SkSVGStop.h in Headers */,
-				002843D809DDC030002E9CB0 /* SkSVGSVG.h in Headers */,
-				002843DA09DDC030002E9CB0 /* SkSVGSymbol.h in Headers */,
-				002843DC09DDC030002E9CB0 /* SkSVGText.h in Headers */,
-				002843DE09DDC030002E9CB0 /* SkSVGUse.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* svg */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "svg" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			buildSettings = {
-			};
-			dependencies = (
-			);
-			name = svg;
-			productName = svg;
-			productReference = D2AAC046055464E500DB518D /* libsvg.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "svg" */;
-			buildSettings = {
-			};
-			buildStyles = (
-				014CEA520018CE5811CA2923 /* Debug */,
-				014CEA530018CE5811CA2923 /* Release */,
-			);
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* svg */;
-			projectDirPath = "";
-			targets = (
-				D2AAC045055464E500DB518D /* svg */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				002843AB09DDC030002E9CB0 /* SkSVGCircle.cpp in Sources */,
-				002843AD09DDC030002E9CB0 /* SkSVGClipPath.cpp in Sources */,
-				002843AF09DDC030002E9CB0 /* SkSVGDefs.cpp in Sources */,
-				002843B109DDC030002E9CB0 /* SkSVGElements.cpp in Sources */,
-				002843B309DDC030002E9CB0 /* SkSVGEllipse.cpp in Sources */,
-				002843B509DDC030002E9CB0 /* SkSVGFeColorMatrix.cpp in Sources */,
-				002843B709DDC030002E9CB0 /* SkSVGFilter.cpp in Sources */,
-				002843B909DDC030002E9CB0 /* SkSVGG.cpp in Sources */,
-				002843BB09DDC030002E9CB0 /* SkSVGGradient.cpp in Sources */,
-				002843BD09DDC030002E9CB0 /* SkSVGGroup.cpp in Sources */,
-				002843BF09DDC030002E9CB0 /* SkSVGImage.cpp in Sources */,
-				002843C109DDC030002E9CB0 /* SkSVGLine.cpp in Sources */,
-				002843C309DDC030002E9CB0 /* SkSVGLinearGradient.cpp in Sources */,
-				002843C509DDC030002E9CB0 /* SkSVGMask.cpp in Sources */,
-				002843C709DDC030002E9CB0 /* SkSVGMetadata.cpp in Sources */,
-				002843C909DDC030002E9CB0 /* SkSVGPaintState.cpp in Sources */,
-				002843CA09DDC030002E9CB0 /* SkSVGParser.cpp in Sources */,
-				002843CB09DDC030002E9CB0 /* SkSVGPath.cpp in Sources */,
-				002843CD09DDC030002E9CB0 /* SkSVGPolygon.cpp in Sources */,
-				002843CF09DDC030002E9CB0 /* SkSVGPolyline.cpp in Sources */,
-				002843D109DDC030002E9CB0 /* SkSVGRadialGradient.cpp in Sources */,
-				002843D309DDC030002E9CB0 /* SkSVGRect.cpp in Sources */,
-				002843D509DDC030002E9CB0 /* SkSVGStop.cpp in Sources */,
-				002843D709DDC030002E9CB0 /* SkSVGSVG.cpp in Sources */,
-				002843D909DDC030002E9CB0 /* SkSVGSymbol.cpp in Sources */,
-				002843DB09DDC030002E9CB0 /* SkSVGText.cpp in Sources */,
-				002843DD09DDC030002E9CB0 /* SkSVGUse.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = svg;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = (
-					ppc,
-					i386,
-				);
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = svg;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				USER_HEADER_SEARCH_PATHS = "../../include/graphics ../../include/corecg";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				USER_HEADER_SEARCH_PATHS = "../../include/graphics ../../include/corecg";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "svg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "svg" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/views.xcodeproj/project.pbxproj b/xcode/views.xcodeproj/project.pbxproj
deleted file mode 100644
index 05d65d3..0000000
--- a/xcode/views.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,324 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E1C20EDCAB1500F77EA2 /* SkEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1BC0EDCAB1500F77EA2 /* SkEvent.cpp */; };
-		00B7E1C30EDCAB1500F77EA2 /* SkEventSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1BD0EDCAB1500F77EA2 /* SkEventSink.cpp */; };
-		00B7E1C40EDCAB1500F77EA2 /* SkMetaData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1BE0EDCAB1500F77EA2 /* SkMetaData.cpp */; };
-		00B7E1C50EDCAB1500F77EA2 /* SkTagList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1BF0EDCAB1500F77EA2 /* SkTagList.cpp */; };
-		00B7E1C60EDCAB1500F77EA2 /* SkTagList.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E1C00EDCAB1500F77EA2 /* SkTagList.h */; };
-		00B7E1C70EDCAB1500F77EA2 /* SkTextBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1C10EDCAB1500F77EA2 /* SkTextBox.cpp */; };
-		00B7E1DF0EDCABAC00F77EA2 /* SkBGViewArtist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CA0EDCABAC00F77EA2 /* SkBGViewArtist.cpp */; };
-		00B7E1E00EDCABAC00F77EA2 /* SkBorderView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CB0EDCABAC00F77EA2 /* SkBorderView.cpp */; };
-		00B7E1E10EDCABAC00F77EA2 /* SkImageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CC0EDCABAC00F77EA2 /* SkImageView.cpp */; };
-		00B7E1E20EDCABAC00F77EA2 /* SkListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CD0EDCABAC00F77EA2 /* SkListView.cpp */; };
-		00B7E1E30EDCABAC00F77EA2 /* SkListWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CE0EDCABAC00F77EA2 /* SkListWidget.cpp */; };
-		00B7E1E40EDCABAC00F77EA2 /* SkOSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1CF0EDCABAC00F77EA2 /* SkOSFile.cpp */; };
-		00B7E1E50EDCABAC00F77EA2 /* SkOSMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D00EDCABAC00F77EA2 /* SkOSMenu.cpp */; };
-		00B7E1E60EDCABAC00F77EA2 /* SkOSSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D10EDCABAC00F77EA2 /* SkOSSound.cpp */; };
-		00B7E1E70EDCABAC00F77EA2 /* SkParsePaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D20EDCABAC00F77EA2 /* SkParsePaint.cpp */; };
-		00B7E1E80EDCABAC00F77EA2 /* SkProgressBarView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D30EDCABAC00F77EA2 /* SkProgressBarView.cpp */; };
-		00B7E1E90EDCABAC00F77EA2 /* SkProgressView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D40EDCABAC00F77EA2 /* SkProgressView.cpp */; };
-		00B7E1EA0EDCABAC00F77EA2 /* SkScrollBarView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D50EDCABAC00F77EA2 /* SkScrollBarView.cpp */; };
-		00B7E1EB0EDCABAC00F77EA2 /* SkStackViewLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D60EDCABAC00F77EA2 /* SkStackViewLayout.cpp */; };
-		00B7E1EC0EDCABAC00F77EA2 /* SkView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D70EDCABAC00F77EA2 /* SkView.cpp */; };
-		00B7E1ED0EDCABAC00F77EA2 /* SkViewInflate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D80EDCABAC00F77EA2 /* SkViewInflate.cpp */; };
-		00B7E1EE0EDCABAC00F77EA2 /* SkViewPriv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1D90EDCABAC00F77EA2 /* SkViewPriv.cpp */; };
-		00B7E1EF0EDCABAC00F77EA2 /* SkViewPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B7E1DA0EDCABAC00F77EA2 /* SkViewPriv.h */; };
-		00B7E1F00EDCABAC00F77EA2 /* SkWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1DB0EDCABAC00F77EA2 /* SkWidget.cpp */; };
-		00B7E1F10EDCABAC00F77EA2 /* SkWidgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1DC0EDCABAC00F77EA2 /* SkWidgets.cpp */; };
-		00B7E1F20EDCABAC00F77EA2 /* SkWidgetViews.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1DD0EDCABAC00F77EA2 /* SkWidgetViews.cpp */; };
-		00B7E1F30EDCABAC00F77EA2 /* SkWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E1DE0EDCABAC00F77EA2 /* SkWindow.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E1BC0EDCAB1500F77EA2 /* SkEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEvent.cpp; path = ../libsgl/views/SkEvent.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1BD0EDCAB1500F77EA2 /* SkEventSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkEventSink.cpp; path = ../libsgl/views/SkEventSink.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1BE0EDCAB1500F77EA2 /* SkMetaData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMetaData.cpp; path = ../libsgl/views/SkMetaData.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1BF0EDCAB1500F77EA2 /* SkTagList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTagList.cpp; path = ../libsgl/views/SkTagList.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1C00EDCAB1500F77EA2 /* SkTagList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkTagList.h; path = ../libsgl/views/SkTagList.h; sourceTree = SOURCE_ROOT; };
-		00B7E1C10EDCAB1500F77EA2 /* SkTextBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkTextBox.cpp; path = ../libsgl/views/SkTextBox.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CA0EDCABAC00F77EA2 /* SkBGViewArtist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBGViewArtist.cpp; path = ../libsgl/views/SkBGViewArtist.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CB0EDCABAC00F77EA2 /* SkBorderView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBorderView.cpp; path = ../libsgl/views/SkBorderView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CC0EDCABAC00F77EA2 /* SkImageView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkImageView.cpp; path = ../libsgl/views/SkImageView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CD0EDCABAC00F77EA2 /* SkListView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkListView.cpp; path = ../libsgl/views/SkListView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CE0EDCABAC00F77EA2 /* SkListWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkListWidget.cpp; path = ../libsgl/views/SkListWidget.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1CF0EDCABAC00F77EA2 /* SkOSFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSFile.cpp; path = ../libsgl/views/SkOSFile.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D00EDCABAC00F77EA2 /* SkOSMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSMenu.cpp; path = ../libsgl/views/SkOSMenu.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D10EDCABAC00F77EA2 /* SkOSSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkOSSound.cpp; path = ../libsgl/views/SkOSSound.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D20EDCABAC00F77EA2 /* SkParsePaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkParsePaint.cpp; path = ../libsgl/views/SkParsePaint.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D30EDCABAC00F77EA2 /* SkProgressBarView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProgressBarView.cpp; path = ../libsgl/views/SkProgressBarView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D40EDCABAC00F77EA2 /* SkProgressView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkProgressView.cpp; path = ../libsgl/views/SkProgressView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D50EDCABAC00F77EA2 /* SkScrollBarView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkScrollBarView.cpp; path = ../libsgl/views/SkScrollBarView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D60EDCABAC00F77EA2 /* SkStackViewLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkStackViewLayout.cpp; path = ../libsgl/views/SkStackViewLayout.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D70EDCABAC00F77EA2 /* SkView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkView.cpp; path = ../libsgl/views/SkView.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D80EDCABAC00F77EA2 /* SkViewInflate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkViewInflate.cpp; path = ../libsgl/views/SkViewInflate.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1D90EDCABAC00F77EA2 /* SkViewPriv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkViewPriv.cpp; path = ../libsgl/views/SkViewPriv.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1DA0EDCABAC00F77EA2 /* SkViewPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkViewPriv.h; path = ../libsgl/views/SkViewPriv.h; sourceTree = SOURCE_ROOT; };
-		00B7E1DB0EDCABAC00F77EA2 /* SkWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidget.cpp; path = ../libsgl/views/SkWidget.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1DC0EDCABAC00F77EA2 /* SkWidgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidgets.cpp; path = ../libsgl/views/SkWidgets.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1DD0EDCABAC00F77EA2 /* SkWidgetViews.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWidgetViews.cpp; path = ../libsgl/views/SkWidgetViews.cpp; sourceTree = SOURCE_ROOT; };
-		00B7E1DE0EDCABAC00F77EA2 /* SkWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWindow.cpp; path = ../libsgl/views/SkWindow.cpp; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libviews.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libviews.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* views */ = {
-			isa = PBXGroup;
-			children = (
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = views;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E1CA0EDCABAC00F77EA2 /* SkBGViewArtist.cpp */,
-				00B7E1CB0EDCABAC00F77EA2 /* SkBorderView.cpp */,
-				00B7E1CC0EDCABAC00F77EA2 /* SkImageView.cpp */,
-				00B7E1CD0EDCABAC00F77EA2 /* SkListView.cpp */,
-				00B7E1CE0EDCABAC00F77EA2 /* SkListWidget.cpp */,
-				00B7E1CF0EDCABAC00F77EA2 /* SkOSFile.cpp */,
-				00B7E1D00EDCABAC00F77EA2 /* SkOSMenu.cpp */,
-				00B7E1D10EDCABAC00F77EA2 /* SkOSSound.cpp */,
-				00B7E1D20EDCABAC00F77EA2 /* SkParsePaint.cpp */,
-				00B7E1D30EDCABAC00F77EA2 /* SkProgressBarView.cpp */,
-				00B7E1D40EDCABAC00F77EA2 /* SkProgressView.cpp */,
-				00B7E1D50EDCABAC00F77EA2 /* SkScrollBarView.cpp */,
-				00B7E1D60EDCABAC00F77EA2 /* SkStackViewLayout.cpp */,
-				00B7E1D70EDCABAC00F77EA2 /* SkView.cpp */,
-				00B7E1D80EDCABAC00F77EA2 /* SkViewInflate.cpp */,
-				00B7E1D90EDCABAC00F77EA2 /* SkViewPriv.cpp */,
-				00B7E1DA0EDCABAC00F77EA2 /* SkViewPriv.h */,
-				00B7E1DB0EDCABAC00F77EA2 /* SkWidget.cpp */,
-				00B7E1DC0EDCABAC00F77EA2 /* SkWidgets.cpp */,
-				00B7E1DD0EDCABAC00F77EA2 /* SkWidgetViews.cpp */,
-				00B7E1DE0EDCABAC00F77EA2 /* SkWindow.cpp */,
-				00B7E1BC0EDCAB1500F77EA2 /* SkEvent.cpp */,
-				00B7E1BD0EDCAB1500F77EA2 /* SkEventSink.cpp */,
-				00B7E1BE0EDCAB1500F77EA2 /* SkMetaData.cpp */,
-				00B7E1BF0EDCAB1500F77EA2 /* SkTagList.cpp */,
-				00B7E1C00EDCAB1500F77EA2 /* SkTagList.h */,
-				00B7E1C10EDCAB1500F77EA2 /* SkTextBox.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libviews.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E1C60EDCAB1500F77EA2 /* SkTagList.h in Headers */,
-				00B7E1EF0EDCABAC00F77EA2 /* SkViewPriv.h in Headers */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* views */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "views" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = views;
-			productName = views;
-			productReference = D2AAC046055464E500DB518D /* libviews.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "views" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* views */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				D2AAC045055464E500DB518D /* views */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E1C20EDCAB1500F77EA2 /* SkEvent.cpp in Sources */,
-				00B7E1C30EDCAB1500F77EA2 /* SkEventSink.cpp in Sources */,
-				00B7E1C40EDCAB1500F77EA2 /* SkMetaData.cpp in Sources */,
-				00B7E1C50EDCAB1500F77EA2 /* SkTagList.cpp in Sources */,
-				00B7E1C70EDCAB1500F77EA2 /* SkTextBox.cpp in Sources */,
-				00B7E1DF0EDCABAC00F77EA2 /* SkBGViewArtist.cpp in Sources */,
-				00B7E1E00EDCABAC00F77EA2 /* SkBorderView.cpp in Sources */,
-				00B7E1E10EDCABAC00F77EA2 /* SkImageView.cpp in Sources */,
-				00B7E1E20EDCABAC00F77EA2 /* SkListView.cpp in Sources */,
-				00B7E1E30EDCABAC00F77EA2 /* SkListWidget.cpp in Sources */,
-				00B7E1E40EDCABAC00F77EA2 /* SkOSFile.cpp in Sources */,
-				00B7E1E50EDCABAC00F77EA2 /* SkOSMenu.cpp in Sources */,
-				00B7E1E60EDCABAC00F77EA2 /* SkOSSound.cpp in Sources */,
-				00B7E1E70EDCABAC00F77EA2 /* SkParsePaint.cpp in Sources */,
-				00B7E1E80EDCABAC00F77EA2 /* SkProgressBarView.cpp in Sources */,
-				00B7E1E90EDCABAC00F77EA2 /* SkProgressView.cpp in Sources */,
-				00B7E1EA0EDCABAC00F77EA2 /* SkScrollBarView.cpp in Sources */,
-				00B7E1EB0EDCABAC00F77EA2 /* SkStackViewLayout.cpp in Sources */,
-				00B7E1EC0EDCABAC00F77EA2 /* SkView.cpp in Sources */,
-				00B7E1ED0EDCABAC00F77EA2 /* SkViewInflate.cpp in Sources */,
-				00B7E1EE0EDCABAC00F77EA2 /* SkViewPriv.cpp in Sources */,
-				00B7E1F00EDCABAC00F77EA2 /* SkWidget.cpp in Sources */,
-				00B7E1F10EDCABAC00F77EA2 /* SkWidgets.cpp in Sources */,
-				00B7E1F20EDCABAC00F77EA2 /* SkWidgetViews.cpp in Sources */,
-				00B7E1F30EDCABAC00F77EA2 /* SkWindow.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB91EC08733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = views;
-				ZERO_LINK = NO;
-			};
-			name = Debug;
-		};
-		1DEB91ED08733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/lib;
-				PRODUCT_NAME = views;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		1DEB91F008733DB70010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = YES;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = "";
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../libsgl/sgl ../include/**";
-			};
-			name = Debug;
-		};
-		1DEB91F108733DB70010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = YES;
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_RELEASE;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "$(HEADER_SEARCH_PATHS)";
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "";
-				SHARED_PRECOMPS_DIR = "";
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = "../libsgl/sgl ../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "views" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91EC08733DB70010E9CD /* Debug */,
-				1DEB91ED08733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "views" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB91F008733DB70010E9CD /* Debug */,
-				1DEB91F108733DB70010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/xcode/zlib.xcodeproj/project.pbxproj b/xcode/zlib.xcodeproj/project.pbxproj
deleted file mode 100644
index b7f96b2..0000000
--- a/xcode/zlib.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,269 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 42;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00B7E21D0EDCAC9E00F77EA2 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2120EDCAC9E00F77EA2 /* adler32.c */; };
-		00B7E21E0EDCAC9E00F77EA2 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2130EDCAC9E00F77EA2 /* compress.c */; };
-		00B7E21F0EDCAC9E00F77EA2 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2140EDCAC9E00F77EA2 /* crc32.c */; };
-		00B7E2200EDCAC9E00F77EA2 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2150EDCAC9E00F77EA2 /* deflate.c */; };
-		00B7E2210EDCAC9E00F77EA2 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2160EDCAC9E00F77EA2 /* infback.c */; };
-		00B7E2220EDCAC9E00F77EA2 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2170EDCAC9E00F77EA2 /* inffast.c */; };
-		00B7E2230EDCAC9E00F77EA2 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2180EDCAC9E00F77EA2 /* inflate.c */; };
-		00B7E2240EDCAC9E00F77EA2 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E2190EDCAC9E00F77EA2 /* inftrees.c */; };
-		00B7E2250EDCAC9E00F77EA2 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E21A0EDCAC9E00F77EA2 /* trees.c */; };
-		00B7E2260EDCAC9E00F77EA2 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E21B0EDCAC9E00F77EA2 /* uncompr.c */; };
-		00B7E2270EDCAC9E00F77EA2 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 00B7E21C0EDCAC9E00F77EA2 /* zutil.c */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		00B7E2120EDCAC9E00F77EA2 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ../../zlib/adler32.c; sourceTree = SOURCE_ROOT; };
-		00B7E2130EDCAC9E00F77EA2 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ../../zlib/compress.c; sourceTree = SOURCE_ROOT; };
-		00B7E2140EDCAC9E00F77EA2 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ../../zlib/crc32.c; sourceTree = SOURCE_ROOT; };
-		00B7E2150EDCAC9E00F77EA2 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ../../zlib/deflate.c; sourceTree = SOURCE_ROOT; };
-		00B7E2160EDCAC9E00F77EA2 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ../../zlib/infback.c; sourceTree = SOURCE_ROOT; };
-		00B7E2170EDCAC9E00F77EA2 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../../zlib/inffast.c; sourceTree = SOURCE_ROOT; };
-		00B7E2180EDCAC9E00F77EA2 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ../../zlib/inflate.c; sourceTree = SOURCE_ROOT; };
-		00B7E2190EDCAC9E00F77EA2 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ../../zlib/inftrees.c; sourceTree = SOURCE_ROOT; };
-		00B7E21A0EDCAC9E00F77EA2 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ../../zlib/trees.c; sourceTree = SOURCE_ROOT; };
-		00B7E21B0EDCAC9E00F77EA2 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ../../zlib/uncompr.c; sourceTree = SOURCE_ROOT; };
-		00B7E21C0EDCAC9E00F77EA2 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ../../zlib/zutil.c; sourceTree = SOURCE_ROOT; };
-		D2AAC046055464E500DB518D /* libzlib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libzlib.a; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		D289987405E68DCB004EDB86 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* zlib */ = {
-			isa = PBXGroup;
-			children = (
-				FE08AA1A0944F1FE0057213F /* Include */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6A0FF2B0290797F04C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = zlib;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				00B7E2120EDCAC9E00F77EA2 /* adler32.c */,
-				00B7E2130EDCAC9E00F77EA2 /* compress.c */,
-				00B7E2140EDCAC9E00F77EA2 /* crc32.c */,
-				00B7E2150EDCAC9E00F77EA2 /* deflate.c */,
-				00B7E2160EDCAC9E00F77EA2 /* infback.c */,
-				00B7E2170EDCAC9E00F77EA2 /* inffast.c */,
-				00B7E2180EDCAC9E00F77EA2 /* inflate.c */,
-				00B7E2190EDCAC9E00F77EA2 /* inftrees.c */,
-				00B7E21A0EDCAC9E00F77EA2 /* trees.c */,
-				00B7E21B0EDCAC9E00F77EA2 /* uncompr.c */,
-				00B7E21C0EDCAC9E00F77EA2 /* zutil.c */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				D2AAC046055464E500DB518D /* libzlib.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6A0FF2B0290797F04C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-		FE08AA1A0944F1FE0057213F /* Include */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			name = Include;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
-		D2AAC043055464E500DB518D /* Headers */ = {
-			isa = PBXHeadersBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
-		D2AAC045055464E500DB518D /* zlib */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = FE5F4830094784880095980F /* Build configuration list for PBXNativeTarget "zlib" */;
-			buildPhases = (
-				D2AAC043055464E500DB518D /* Headers */,
-				D2AAC044055464E500DB518D /* Sources */,
-				D289987405E68DCB004EDB86 /* Frameworks */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = zlib;
-			productName = zlib;
-			productReference = D2AAC046055464E500DB518D /* libzlib.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = FE5F4834094784880095980F /* Build configuration list for PBXProject "zlib" */;
-			compatibilityVersion = "Xcode 2.4";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* zlib */;
-			projectDirPath = "";
-			projectRoot = ..;
-			targets = (
-				D2AAC045055464E500DB518D /* zlib */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
-		D2AAC044055464E500DB518D /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00B7E21D0EDCAC9E00F77EA2 /* adler32.c in Sources */,
-				00B7E21E0EDCAC9E00F77EA2 /* compress.c in Sources */,
-				00B7E21F0EDCAC9E00F77EA2 /* crc32.c in Sources */,
-				00B7E2200EDCAC9E00F77EA2 /* deflate.c in Sources */,
-				00B7E2210EDCAC9E00F77EA2 /* infback.c in Sources */,
-				00B7E2220EDCAC9E00F77EA2 /* inffast.c in Sources */,
-				00B7E2230EDCAC9E00F77EA2 /* inflate.c in Sources */,
-				00B7E2240EDCAC9E00F77EA2 /* inftrees.c in Sources */,
-				00B7E2250EDCAC9E00F77EA2 /* trees.c in Sources */,
-				00B7E2260EDCAC9E00F77EA2 /* uncompr.c in Sources */,
-				00B7E2270EDCAC9E00F77EA2 /* zutil.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
-		FE5F4831094784880095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = zlib;
-				ZERO_LINK = YES;
-			};
-			name = Debug;
-		};
-		FE5F4832094784880095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-				GCC_ENABLE_FIX_AND_CONTINUE = NO;
-				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-				GCC_MODEL_TUNING = G5;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				INSTALL_PATH = /usr/local/lib;
-				LIBRARY_STYLE = STATIC;
-				PREBINDING = NO;
-				PRODUCT_NAME = zlib;
-				ZERO_LINK = NO;
-			};
-			name = Release;
-		};
-		FE5F4835094784880095980F /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = ../../zlib;
-			};
-			name = Debug;
-		};
-		FE5F4836094784880095980F /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-				GCC_CW_ASM_SYNTAX = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_ENABLE_PASCAL_STRINGS = NO;
-				GCC_ENABLE_SYMBOL_SEPARATION = NO;
-				GCC_PREPROCESSOR_DEFINITIONS = SK_RELEASE;
-				GCC_USE_GCC3_PFE_SUPPORT = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				LINK_WITH_STANDARD_LIBRARIES = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				STRIP_INSTALLED_PRODUCT = NO;
-				USER_HEADER_SEARCH_PATHS = ../../zlib;
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		FE5F4830094784880095980F /* Build configuration list for PBXNativeTarget "zlib" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F4831094784880095980F /* Debug */,
-				FE5F4832094784880095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-		FE5F4834094784880095980F /* Build configuration list for PBXProject "zlib" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				FE5F4835094784880095980F /* Debug */,
-				FE5F4836094784880095980F /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Debug;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}