Revert of remove unused (by clients) SkUnitMapper (https://codereview.chromium.org/283273002/)

Reason for revert:
does not address all legacy callsites in chrome.

e.g.

[13:45:32.091872] ../../ui/native_theme/native_theme_base.cc:608:76: error: no matching function for call to ‘SkGradientShader::CreateLinear(SkPoint [3], SkColor [3], NULL, int, SkShader::TileMode, NULL)’
[13:45:32.091919]            gradient_bounds, colors, NULL, 3, SkShader::kClamp_TileMode, NULL));


Original issue's description:
> remove unused (by clients) SkUnitMapper
>
> BUG=skia:
>
> Committed: http://code.google.com/p/skia/source/detail?r=14761

R=robertphillips@google.com, scroggo@google.com, george@mozilla.com
TBR=george@mozilla.com, robertphillips@google.com, scroggo@google.com
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Author: reed@google.com

Review URL: https://codereview.chromium.org/287063009

git-svn-id: http://skia.googlecode.com/svn/trunk@14763 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index 92fe258..ea1f143 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -36,6 +36,7 @@
 #include "SkRandom.h"
 #include "SkTransparentShader.h"
 #include "SkTypeface.h"
+#include "SkUnitMappers.h"
 #include "SkUtils.h"
 #include "SkXfermode.h"
 
@@ -367,8 +368,10 @@
         SkScalar* linearPos = NULL;
         int linearCount = 2;
         SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
+        SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
+        SkAutoUnref unmapLinearMapper(linearMapper);
         SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
-            linearColors, linearPos, linearCount, linearMode);
+            linearColors, linearPos, linearCount, linearMode, linearMapper);
 
         SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
         SkScalar radialRadius = SkIntToScalar(25);
@@ -376,9 +379,11 @@
         SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
         int radialCount = 3;
         SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
+        SkUnitMapper* radialMapper = new SkCosineMapper();
+        SkAutoUnref unmapRadialMapper(radialMapper);
         SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
             radialRadius, radialColors, radialPos, radialCount,
-            radialMode);
+            radialMode, radialMapper);
 
         SkTransparentShader* transparentShader = new SkTransparentShader();
         SkEmbossMaskFilter::Light light;
diff --git a/samplecode/SampleGradients.cpp b/samplecode/SampleGradients.cpp
index f328d76..fead714 100644
--- a/samplecode/SampleGradients.cpp
+++ b/samplecode/SampleGradients.cpp
@@ -13,7 +13,8 @@
 static SkShader* setgrad(const SkRect& r, SkColor c0, SkColor c1) {
     SkColor colors[] = { c0, c1 };
     SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
-    return SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
+    return SkGradientShader::CreateLinear(pts, colors, NULL, 2,
+                                          SkShader::kClamp_TileMode, NULL);
 }
 
 static void test_alphagradients(SkCanvas* canvas) {
@@ -63,26 +64,32 @@
     { 5, gColors, gPos2 }
 };
 
-static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
-    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
+static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
+    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
+                                          data.fCount, tm, mapper);
 }
 
-static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
     return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
-                                          data.fPos, data.fCount, tm);
+                                          data.fPos, data.fCount, tm, mapper);
 }
 
-static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
-    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
+    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
+                                         data.fPos, data.fCount, mapper);
 }
 
-static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
@@ -91,22 +98,22 @@
     return SkGradientShader::CreateTwoPointRadial(
                             center1, (pts[1].fX - pts[0].fX) / 7,
                             center0, (pts[1].fX - pts[0].fX) / 2,
-                            data.fColors, data.fPos, data.fCount, tm);
+                            data.fColors, data.fPos, data.fCount, tm, mapper);
 }
 
 static SkShader* Make2RadialConcentric(const SkPoint pts[2], const GradData& data,
-                                       SkShader::TileMode tm) {
+                                       SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
     return SkGradientShader::CreateTwoPointRadial(
                             center, (pts[1].fX - pts[0].fX) / 7,
                             center, (pts[1].fX - pts[0].fX) / 2,
-                            data.fColors, data.fPos, data.fCount, tm);
+                            data.fColors, data.fPos, data.fCount, tm, mapper);
 }
 
-typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
-
+typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
+                     SkShader::TileMode tm, SkUnitMapper* mapper);
 static const GradMaker gGradMakers[] = {
     MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2RadialConcentric
 };
@@ -147,7 +154,7 @@
                 canvas->save();
                 for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
                     SkShader* shader;
-                    shader = gGradMakers[j](pts, gGradData[i], (SkShader::TileMode)tm);
+                    shader = gGradMakers[j](pts, gGradData[i], (SkShader::TileMode)tm, NULL);
                     paint.setShader(shader)->unref();
                     canvas->drawRect(r, paint);
                     canvas->translate(0, SkIntToScalar(120));
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index 43f5d42..51f02a1 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -31,7 +31,7 @@
     SkColor colors[] = { 0, SK_ColorWHITE };
     SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
     SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode,
-                                                 0, &localMatrix);
+                                                 NULL, 0, &localMatrix);
 
     paint->setShader(s)->unref();
     paint->setXfermodeMode(SkXfermode::kDstIn_Mode);
diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp
index fe94bbf..09eb42f 100644
--- a/samplecode/SamplePatch.cpp
+++ b/samplecode/SamplePatch.cpp
@@ -42,7 +42,7 @@
                       { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
     SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
     return SkGradientShader::CreateLinear(pts, colors, NULL,
-                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
+                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode, NULL);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleShaderText.cpp b/samplecode/SampleShaderText.cpp
index 6f23a0b..c7048ab 100644
--- a/samplecode/SampleShaderText.cpp
+++ b/samplecode/SampleShaderText.cpp
@@ -1,14 +1,15 @@
+
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-
 #include "SampleCode.h"
 #include "SkView.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
+#include "SkUnitMappers.h"
 
 static void makebm(SkBitmap* bm, int w, int h) {
     bm->allocN32Pixels(w, h);
@@ -21,9 +22,15 @@
     SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
     SkPaint     paint;
 
+    SkUnitMapper*   um = NULL;
+
+    um = new SkCosineMapper;
+
+    SkAutoUnref au(um);
+
     paint.setDither(true);
     paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
-                                    SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
+                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
     canvas.drawPaint(paint);
 }
 
@@ -53,26 +60,32 @@
     { 5, gColors, NULL },
 };
 
-static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
-    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
+static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
+    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
+                                          data.fCount, tm, mapper);
 }
 
-static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
     return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
-                                          data.fPos, data.fCount, tm);
+                                          data.fPos, data.fCount, tm, mapper);
 }
 
-static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
-    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
+    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
+                                         data.fPos, data.fCount, mapper);
 }
 
-static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
@@ -81,11 +94,11 @@
     return SkGradientShader::CreateTwoPointRadial(
                             center1, (pts[1].fX - pts[0].fX) / 7,
                             center0, (pts[1].fX - pts[0].fX) / 2,
-                            data.fColors, data.fPos, data.fCount, tm);
+                            data.fColors, data.fPos, data.fCount, tm, mapper);
 }
 
-typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
-
+typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
+                     SkShader::TileMode tm, SkUnitMapper* mapper);
 static const GradMaker gGradMakers[] = {
     MakeLinear, MakeRadial, MakeSweep, Make2Radial
 };
@@ -139,7 +152,8 @@
             for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
                 shaders[shdIdx++] = gGradMakers[m](pts,
                                                    gGradData[d],
-                                                   SkShader::kClamp_TileMode);
+                                                   SkShader::kClamp_TileMode,
+                                                   NULL);
             }
         }
         for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp
index 6bc9a28..d828ae6 100644
--- a/samplecode/SampleSlides.cpp
+++ b/samplecode/SampleSlides.cpp
@@ -178,26 +178,32 @@
 { 5, gColors, gPos2 }
 };
 
-static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
-    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
+static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
+    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
+                                          data.fCount, tm, mapper);
 }
 
-static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
     return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
-                                          data.fPos, data.fCount, tm);
+                                          data.fPos, data.fCount, tm, mapper);
 }
 
-static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center;
     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(pts[0].fY, pts[1].fY));
-    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
+    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
+                                         data.fPos, data.fCount, mapper);
 }
 
-static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
+static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
+                             SkShader::TileMode tm, SkUnitMapper* mapper) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
@@ -206,10 +212,11 @@
     return SkGradientShader::CreateTwoPointRadial(
                                                   center1, (pts[1].fX - pts[0].fX) / 7,
                                                   center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm);
+                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
 }
 
-typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
+typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
+                               SkShader::TileMode tm, SkUnitMapper* mapper);
 static const GradMaker gGradMakers[] = {
     MakeLinear, MakeRadial, MakeSweep, Make2Radial
 };
@@ -229,7 +236,7 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
         canvas->save();
         for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
-            SkShader* shader = gGradMakers[j](pts, gGradData[i], tm);
+            SkShader* shader = gGradMakers[j](pts, gGradData[i], tm, NULL);
             paint.setShader(shader);
             canvas->drawRect(r, paint);
             shader->unref();
@@ -328,7 +335,7 @@
                       { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
     SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
     return SkGradientShader::CreateLinear(pts, colors, NULL,
-                                          SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
+                                          SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode, NULL);
 }
 
 class Rec {
diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp
index a59a802..cc3b529 100644
--- a/samplecode/SampleTiling.cpp
+++ b/samplecode/SampleTiling.cpp
@@ -21,6 +21,7 @@
 
 // effects
 #include "SkGradientShader.h"
+#include "SkUnitMappers.h"
 #include "SkBlurMask.h"
 #include "SkBlurDrawLooper.h"
 
@@ -34,9 +35,16 @@
     SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
     SkPaint     paint;
 
+    SkUnitMapper*   um = NULL;
+
+    um = new SkCosineMapper;
+//    um = new SkDiscreteMapper(12);
+
+    SkAutoUnref au(um);
+
     paint.setDither(true);
     paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
-                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref();
+                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
     canvas.drawPaint(paint);
 }
 
diff --git a/samplecode/SampleUnitMapper.cpp b/samplecode/SampleUnitMapper.cpp
new file mode 100644
index 0000000..db9af09
--- /dev/null
+++ b/samplecode/SampleUnitMapper.cpp
@@ -0,0 +1,172 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkPaint.h"
+#include "SkUnitMappers.h"
+#include "SkCubicInterval.h"
+
+#include "SkWidgetViews.h"
+
+static SkStaticTextView* make_textview(SkView* parent,
+                                       const SkRect& bounds,
+                                       const SkPaint& paint) {
+    SkStaticTextView* view = new SkStaticTextView;
+    view->setMode(SkStaticTextView::kFixedSize_Mode);
+    view->setPaint(paint);
+    view->setVisibleP(true);
+    view->setSize(bounds.width(), bounds.height());
+    view->setLoc(bounds.fLeft, bounds.fTop);
+    parent->attachChildToFront(view)->unref();
+    return view;
+}
+
+static void set_scalar(SkStaticTextView* view, SkScalar value) {
+    SkString str;
+    str.appendScalar(value);
+    view->setText(str);
+}
+
+class UnitMapperView : public SampleView {
+    SkPoint fPts[4];
+    SkMatrix fMatrix;
+    SkStaticTextView* fViews[4];
+
+    void setViews() {
+        set_scalar(fViews[0], fPts[1].fX);
+        set_scalar(fViews[1], fPts[1].fY);
+        set_scalar(fViews[2], fPts[2].fX);
+        set_scalar(fViews[3], fPts[2].fY);
+    }
+
+public:
+    UnitMapperView() {
+        fPts[0].set(0, 0);
+        fPts[1].set(SK_Scalar1 / 3, SK_Scalar1 / 3);
+        fPts[2].set(SK_Scalar1 * 2 / 3, SK_Scalar1 * 2 / 3);
+        fPts[3].set(SK_Scalar1, SK_Scalar1);
+
+        fMatrix.setScale(SK_Scalar1 * 200, -SK_Scalar1 * 200);
+        fMatrix.postTranslate(SkIntToScalar(100), SkIntToScalar(300));
+
+        SkRect r = {
+            SkIntToScalar(350), SkIntToScalar(100),
+            SkIntToScalar(500), SkIntToScalar(130)
+        };
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setTextSize(SkIntToScalar(25));
+        for (int i = 0; i < 4; i++) {
+            fViews[i] = make_textview(this, r, paint);
+            r.offset(0, r.height());
+        }
+        this->setViews();
+    }
+
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "UnitMapper");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual void onDrawContent(SkCanvas* canvas) {
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(0xFF8888FF);
+
+        SkRect r = { 0, 0, SK_Scalar1, SK_Scalar1 };
+
+        canvas->concat(fMatrix);
+        canvas->drawRect(r, paint);
+
+        paint.setColor(SK_ColorBLACK);
+        paint.setStyle(SkPaint::kStroke_Style);
+        paint.setStrokeWidth(0);
+        paint.setStrokeCap(SkPaint::kRound_Cap);
+
+        SkPath path;
+        path.moveTo(fPts[0]);
+        path.cubicTo(fPts[1], fPts[2], fPts[3]);
+        canvas->drawPath(path, paint);
+
+        paint.setColor(SK_ColorRED);
+        paint.setStrokeWidth(0);
+        canvas->drawLine(0, 0, SK_Scalar1, SK_Scalar1, paint);
+
+        paint.setColor(SK_ColorBLUE);
+        paint.setStrokeWidth(SK_Scalar1 / 60);
+        for (int i = 0; i < 50; i++) {
+            SkScalar x = i * SK_Scalar1 / 49;
+            canvas->drawPoint(x, SkEvalCubicInterval(&fPts[1], x), paint);
+        }
+
+        paint.setStrokeWidth(SK_Scalar1 / 20);
+        paint.setColor(SK_ColorGREEN);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, &fPts[1], paint);
+    }
+
+    bool invertPt(SkScalar x, SkScalar y, SkPoint* result) {
+        if (NULL == result)
+            return true;
+
+        SkMatrix m;
+        if (!fMatrix.invert(&m)) {
+            return false;
+        }
+
+        m.mapXY(x, y, result);
+        return true;
+    }
+
+    int hittest(SkScalar x, SkScalar y) {
+        SkPoint target = { x, y };
+        SkPoint pts[2] = { fPts[1], fPts[2] };
+        fMatrix.mapPoints(pts, 2);
+        for (int i = 0; i < 2; i++) {
+            if (SkPoint::Distance(pts[i], target) < SkIntToScalar(4)) {
+                return i + 1;
+            }
+        }
+        return -1;
+    }
+
+    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) SK_OVERRIDE {
+        fDragIndex = hittest(x, y);
+        return fDragIndex >= 0 ? new Click(this) : NULL;
+    }
+
+    virtual bool onClick(Click* click) {
+        if (fDragIndex >= 0) {
+            if (!invertPt(click->fCurr.fX, click->fCurr.fY,
+                          &fPts[fDragIndex])) {
+                return false;
+            }
+
+            this->setViews();
+            this->inval(NULL);
+            return true;
+        }
+        return false;
+    }
+
+private:
+    int fDragIndex;
+
+    typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new UnitMapperView; }
+static SkViewRegister reg(MyFactory);
diff --git a/samplecode/SampleVertices.cpp b/samplecode/SampleVertices.cpp
index 1e568f5..4c3a17e 100644
--- a/samplecode/SampleVertices.cpp
+++ b/samplecode/SampleVertices.cpp
@@ -47,7 +47,7 @@
                       { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
     SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
     return SkGradientShader::CreateLinear(pts, colors, NULL,
-                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
+                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode, NULL);
 }
 
 class VerticesView : public SampleView {