updates



git-svn-id: http://skia.googlecode.com/svn/trunk@558 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleArc.cpp b/samplecode/SampleArc.cpp
index ed62537..bba5f6f 100644
--- a/samplecode/SampleArc.cpp
+++ b/samplecode/SampleArc.cpp
@@ -130,6 +130,7 @@
         
         fSweep = SampleCode::GetAnimScalar(SkIntToScalar(360)/24,
                                            SkIntToScalar(360));
+//        fSweep = SkFloatToScalar(359.99f);
 
         SkRect  r;
         SkPaint paint;
diff --git a/samplecode/SampleEffects.cpp b/samplecode/SampleEffects.cpp
index 94f0413..7b61911 100644
--- a/samplecode/SampleEffects.cpp
+++ b/samplecode/SampleEffects.cpp
@@ -8,6 +8,23 @@
 #include "SkDiscretePathEffect.h"
 #include "SkGradientShader.h"
 
+#include "SkEdgeClipper.h"
+
+static void test_edgeclipper() {
+    SkPoint pts[] = {
+        { -8.38822452e+21, -7.69721471e+19 },
+        { 1.57645875e+23, 1.44634003e+21 },
+        { 1.61519691e+23, 1.48208059e+21 },
+        { 3.13963584e+23, 2.88057438e+21 }
+    };
+    SkRect clip = { 0, 0, 300, 200 };
+    
+    SkEdgeClipper clipper;
+    clipper.clipCubic(pts, clip);
+}
+
+///////////
+
 //#define COLOR 0xFFFF8844
 #define COLOR 0xFF888888
 
@@ -74,6 +91,11 @@
             fPaint[i].setColor(COLOR);
             gPaintProcs[i](&fPaint[i]);
         }
+
+        test_edgeclipper();
+        SkColorMatrix cm;
+        cm.setRotate(SkColorMatrix::kG_Axis, 180);
+        cm.setIdentity();
     }
     
 protected:
diff --git a/samplecode/SampleFontCache.cpp b/samplecode/SampleFontCache.cpp
index fb63f71..75645bd 100644
--- a/samplecode/SampleFontCache.cpp
+++ b/samplecode/SampleFontCache.cpp
@@ -89,17 +89,14 @@
         gDone = false;
         for (int i = 0; i < N; i++)
         {
-            int             status;
-            pthread_attr_t  attr;
+            int status;
             
-            status = pthread_attr_init(&attr);
-            SkASSERT(0 == status);
-            status = pthread_create(&fMThreads[i], &attr,  measure_proc, NULL);
+            status = pthread_create(&fMThreads[i], NULL,  measure_proc, NULL);
             SkASSERT(0 == status);
 
             fBitmaps[i].setConfig(SkBitmap::kRGB_565_Config, 320, 240);
             fBitmaps[i].allocPixels();
-            status = pthread_create(&fDThreads[i], &attr,  draw_proc, &fBitmaps[i]);
+            status = pthread_create(&fDThreads[i], NULL,  draw_proc, &fBitmaps[i]);
             SkASSERT(0 == status);
         }
     }
diff --git a/samplecode/SampleNinePatch.cpp b/samplecode/SampleNinePatch.cpp
index 941b3ff..99c337b 100644
--- a/samplecode/SampleNinePatch.cpp
+++ b/samplecode/SampleNinePatch.cpp
@@ -11,7 +11,7 @@
     SkBitmap fBM;
 
 	NinePatchView() {
-        SkImageDecoder::DecodeFile("/skimages/folder_background.9.png", &fBM);
+        SkImageDecoder::DecodeFile("/skimages/btn_default_normal_disable.9.png", &fBM);
         
         // trim off the edge guide-lines
         SkBitmap tmp;
@@ -35,13 +35,44 @@
     }
     
     void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
+        SkPaint p;
+        p.setDither(true);
+        p.setColor(0xFF909090);
+        canvas->drawPaint(p);
     }
-    
+
+    static void test_rects(SkCanvas* canvas, const SkBitmap& bm, const SkPaint* paint) {
+        static const SkIRect src[] = {
+            { 0, 0, 18, 34 },
+            { 18, 0, 19, 34 },
+            { 19, 0, 36, 34 },
+            { 0, 34, 18, 35 },
+            { 18, 34, 19, 35 },
+            { 19, 34, 36, 35 },
+            { 0, 35, 18, 72 },
+            { 18, 35, 19, 72 },
+            { 19, 35, 36, 72 },
+        };
+        static const SkRect dst[] = {
+            { 0, 0, 18, 34 },
+            { 18, 0, 283, 34 },
+            { 283, 0, 300, 34 },
+            { 0, 34, 18, 163 },
+            { 18, 34, 283, 163 },
+            { 283, 34, 300, 163 },
+            { 0, 163, 18, 200 },
+            { 18, 163, 283, 200 },
+            { 283, 163, 300, 200 },
+        };
+        for (size_t i = 0; i < SK_ARRAY_COUNT(src); i++) {
+            canvas->drawBitmapRect(bm, &src[i], dst[i], paint);
+        }
+    }
+
     virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
 
-        canvas->scale(1.5f, 1.5f);
+      //  canvas->scale(1.5f, 1.5f);
         
         canvas->drawBitmap(fBM, 0, 0);
         
@@ -50,15 +81,28 @@
         int d = 25;
         
         margins.set(d, d, d, d);
+        margins.fLeft   = fBM.width()/2 - 1;
+        margins.fTop    = fBM.height()/2 - 1;
+        margins.fRight  = fBM.width() - margins.fLeft - 1;
+        margins.fBottom = fBM.height() - margins.fTop - 1;
+
+   //     canvas->translate(fX/5, fY/5);
+        canvas->translate(0, 76);
+
         dst.set(0, 0, SkIntToScalar(200), SkIntToScalar(200));
-        dst.offset(fX, fY);
         
-        SkNinePatch::DrawNine(canvas, dst, fBM, margins);
+        SkPaint paint;
+        paint.setAntiAlias(false);
+        paint.setDither(true);
+        paint.setFilterBitmap(false);
+    //    SkNinePatch::DrawNine(canvas, dst, fBM, margins, &paint);
+        test_rects(canvas, fBM, &paint);
     }
     
     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
         fX = x / 1.5f;
         fY = y / 1.5f;
+        fX = x; fY = y;
         this->inval(NULL);
         return this->INHERITED::onFindClickHandler(x, y);
     }
diff --git a/samplecode/SamplePicture.cpp b/samplecode/SamplePicture.cpp
index e232a50..6c018b7 100644
--- a/samplecode/SamplePicture.cpp
+++ b/samplecode/SamplePicture.cpp
@@ -14,6 +14,7 @@
 #include "SkUtils.h"
 #include "SkColorPriv.h"
 #include "SkColorFilter.h"
+#include "SkShape.h"
 #include "SkTime.h"
 #include "SkTypeface.h"
 #include "SkXfermode.h"
@@ -21,6 +22,69 @@
 #include "SkStream.h"
 #include "SkXMLParser.h"
 
+class SignalShape : public SkShape {
+public:
+    SignalShape() : fSignal(0) {}
+
+    SkShape* setSignal(int n) {
+        fSignal = n;
+        return this;
+    }
+
+protected:
+    virtual void onDraw(SkCanvas* canvas) {
+        SkDebugf("---- sc %d\n", canvas->getSaveCount() - 1);
+    }
+
+private:
+    int fSignal;
+};
+
+static SkPMColor SignalProc(SkPMColor src, SkPMColor dst) {
+    return dst;
+}
+
+/*  Picture playback will skip blocks of draw calls that follow a clip() call
+    that returns empty, and jump down to the corresponding restore() call.
+
+    This is a great preformance win for drawing very large/tall pictures with
+    a small visible window (think scrolling a long document). These tests make
+    sure that (a) we are performing the culling, and (b) we don't get confused
+    by nested save() calls, nor by calls to restoreToCount().
+ */
+static void test_saveRestoreCulling() {
+    SkPaint signalPaint;
+    SignalShape signalShape;
+
+    SkPicture pic;
+    SkRect r = SkRect::MakeWH(0, 0);
+    int n;
+    SkCanvas* canvas = pic.beginRecording(100, 100);
+    int startN = canvas->getSaveCount();
+    SkDebugf("---- start sc %d\n", startN);
+    canvas->drawShape(signalShape.setSignal(1));
+    canvas->save();
+    canvas->drawShape(signalShape.setSignal(2));
+    n = canvas->save();
+    canvas->drawShape(signalShape.setSignal(3));
+    canvas->save();
+    canvas->clipRect(r);
+    canvas->drawShape(signalShape.setSignal(4));
+    canvas->restoreToCount(n);
+    canvas->drawShape(signalShape.setSignal(5));
+    canvas->restore();
+    canvas->drawShape(signalShape.setSignal(6));
+    SkASSERT(canvas->getSaveCount() == startN);
+
+    SkBitmap bm;
+    bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
+    bm.allocPixels();
+    SkCanvas c(bm);
+    c.drawPicture(pic);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 #include "SkImageRef_GlobalPool.h"
 
 static SkBitmap load_bitmap() {
@@ -73,6 +137,8 @@
         // unref fPicture in our destructor, and it will in turn take care of
         // the other references to fSubPicture
         fSubPicture->unref();
+
+        test_saveRestoreCulling();
     }
     
     virtual ~PictureView() {
diff --git a/samplecode/SampleSkLayer.cpp b/samplecode/SampleSkLayer.cpp
index 54efddf..11976e9 100644
--- a/samplecode/SampleSkLayer.cpp
+++ b/samplecode/SampleSkLayer.cpp
@@ -41,7 +41,20 @@
              x1, y1, z1,
              dst.fData[0] == x1 && dst.fData[1] == y1 && dst.fData[2] == z1);
 }
-                     
+
+static void test_33(const SkMatrix44& mat,
+                    SkScalar x0, SkScalar x1, SkScalar x2,
+                    SkScalar y0, SkScalar y1, SkScalar y2) {
+    SkMatrix dst = mat;
+    if (dst[0] != x0 || dst[1] != x1 || dst[2] != x2 ||
+        dst[3] != y0 || dst[4] != y1 || dst[5] != y2) {
+        SkString str;
+        dst.toDumpString(&str);
+        SkDebugf("3x3: expected 3x3 [%g %g %g] [%g %g %g] bug got %s\n",
+                 x0, x1, x2, y0, y1, y2, str.c_str());
+    }
+}
+
 static void test44() {
     SkMatrix44 m0, m1, m2;
 
@@ -78,6 +91,15 @@
     test_map(1, 0, 0, m0, 7, 3, 4);
     test_map(0, 1, 0, m0, 2, 9, 4);
     test_map(0, 0, 1, m0, 2, 3, 11);
+
+    SkMScalar deg = 45;
+    m0.setRotateDegreesAbout(0, 0, 1, deg);
+    test_map(1, 0, 0, m0, 0.707106769, -0.707106769, 0);
+
+    m0.reset();
+    test_33(m0, 1, 0, 0, 0, 1, 0);
+    m0.setTranslate(3, 4, 5);
+    test_33(m0, 1, 0, 3, 0, 1, 4);
 }
     
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleTypeface.cpp b/samplecode/SampleTypeface.cpp
index 2fadb41..fa2f546 100644
--- a/samplecode/SampleTypeface.cpp
+++ b/samplecode/SampleTypeface.cpp
@@ -14,6 +14,36 @@
 #include "SkColorFilter.h"
 #include "SkDither.h"
 
+static int dither_4444(int x) {
+    return ((x << 1) - ((x >> 4 << 4) | (x >> 4))) >> 4;
+}
+
+/** Ensure that the max of the original and dithered value (for alpha) is always
+    >= any other dithered value. We apply this "max" in colorpriv.h when we
+    predither down to 4444, to be sure that we stay in legal premultiplied form
+ */
+static void test_4444_dither() {
+    int buckets[16];
+    sk_bzero(buckets, sizeof(buckets));
+
+    for (int a = 0; a <= 0xFF; a++) {
+        int da = dither_4444(a);
+        int maxa = SkMax32(a >> 4, da);
+    //    SkDebugf("--- %02X %X\n", a, da);
+        buckets[da] += 1;
+        for (int c = 0; c <= a; c++) {
+            int dc = dither_4444(c);
+            if (maxa < dc) {
+                SkDebugf("------------ error a=%d da=%d c=%d dc=%d\n", a, da,
+                         c, dc);
+            }
+        }
+    }
+    for (int i = 0; i < 16; i++) {
+    //    SkDebugf("[%d] = %d\n", i, buckets[i]);
+    }
+}
+
 static const struct {
     const char* fName;
     SkTypeface::Style   fStyle;
@@ -34,6 +64,7 @@
 
 public:
 	TypefaceView() {
+        test_4444_dither();
         for (int i = 0; i < gFaceCount; i++) {
             fFaces[i] = SkTypeface::CreateFromName(gFaces[i].fName,
                                                    gFaces[i].fStyle);
@@ -84,6 +115,45 @@
             canvas->drawText(text, textLen, x, y, paint);
             y += dy;
         }
+        
+        SkRect r;
+        if (false) {
+        r.set(10, 10, 100, 100);
+        paint.setStyle(SkPaint::kStrokeAndFill_Style);
+        paint.setColor(SK_ColorBLUE);
+        paint.setStrokeWidth(1);
+        canvas->drawRect(r, paint);
+        paint.setStrokeWidth(0);
+        }
+
+        if (false) {
+        r.set(294912.75f, 294912.75f, 884738.25f, 884738.25f);
+        canvas->scale(2.4414E-4f, 2.4414E-4f);
+        paint.setStyle(SkPaint::kFill_Style);
+        canvas->drawRect(r, paint);
+        }
+        
+        if (false) {
+            SkScalar rad = 90;
+            SkScalar angle = 210;
+            SkScalar cx = 150;
+            SkScalar cy = 105;
+            r.set(cx - rad, cy - rad, cx + rad, cy + rad);
+            SkPath path;
+            path.arcTo(r, angle, -(angle + 90), true);
+            path.close();
+            
+            paint.setColor(SK_ColorRED);
+            canvas->drawRect(path.getBounds(), paint);
+            paint.setColor(SK_ColorBLUE);
+            canvas->drawPath(path, paint);
+            
+            paint.setColor(SK_ColorGREEN);
+            SkPoint pts[100];
+            int count = path.getPoints(pts, 100);
+            paint.setStrokeWidth(5);
+            canvas->drawPoints(SkCanvas::kPoints_PointMode, count, pts, paint);
+        }
     }
     
 private:
diff --git a/samplecode/SampleWarp.cpp b/samplecode/SampleWarp.cpp
index 606144c..bf4ef0d 100644
--- a/samplecode/SampleWarp.cpp
+++ b/samplecode/SampleWarp.cpp
@@ -327,6 +327,7 @@
 public:
 	WarpView() {
         SkBitmap bm;
+//        SkImageDecoder::DecodeFile("/skimages/marker.png", &bm);
         SkImageDecoder::DecodeFile("/skimages/logo.gif", &bm);
    //     SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
         fBitmap = bm;
@@ -387,7 +388,7 @@
             return orig;
         }
         
-        const SkScalar period = 20;
+        const SkScalar period = 10 + dragLength/4;
         const SkScalar mag = dragLength / 3;
         
         SkScalar d = length / (period);