add sample for filter quality
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/788163007
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index 96d4acc..7767835 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -64,6 +64,7 @@
'../samplecode/SampleFillType.cpp',
'../samplecode/SampleFilter.cpp',
'../samplecode/SampleFilter2.cpp',
+ '../samplecode/SampleFilterQuality.cpp',
'../samplecode/SampleFilterFuzz.cpp',
'../samplecode/SampleFontCache.cpp',
'../samplecode/SampleFontScalerTest.cpp',
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
new file mode 100644
index 0000000..4c778e3
--- /dev/null
+++ b/samplecode/SampleFilterQuality.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#include "Resources.h"
+#include "SampleCode.h"
+#include "SkCanvas.h"
+#include "SkInterpolator.h"
+#include "SkSurface.h"
+#include "SkRandom.h"
+#include "SkTime.h"
+
+#define N 128
+
+static SkImage* make_image() {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ SkCanvas* canvas = surface->getCanvas();
+
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+
+ path.addRect(SkRect::MakeWH(N/2, N));
+ path.addRect(SkRect::MakeWH(N, N/2));
+ path.moveTo(0, 0); path.lineTo(N, 0); path.lineTo(0, N); path.close();
+
+ canvas->drawPath(path, SkPaint());
+ return surface->newImageSnapshot();
+}
+
+struct AnimValue {
+ SkScalar fValue;
+ SkScalar fMin;
+ SkScalar fMax;
+ SkScalar fMod;
+
+ operator SkScalar() const { return fValue; }
+
+ void set(SkScalar value, SkScalar min, SkScalar max) {
+ fValue = value;
+ fMin = min;
+ fMax = max;
+ fMod = 0;
+ }
+
+ void setMod(SkScalar value, SkScalar mod) {
+ fValue = value;
+ fMin = 0;
+ fMax = 0;
+ fMod = mod;
+ }
+
+ SkScalar inc(SkScalar delta) {
+ fValue += delta;
+ return this->fixUp();
+ }
+
+ SkScalar fixUp() {
+ if (fMod) {
+ fValue = SkScalarMod(fValue, fMod);
+ } else {
+ if (fValue > fMax) {
+ fValue = fMax;
+ } else if (fValue < fMin) {
+ fValue = fMin;
+ }
+ }
+ return fValue;
+ }
+};
+
+#define ANGLE_DELTA 3
+#define SCALE_DELTA (SK_Scalar1 / 32)
+
+class FilterQualityView : public SampleView {
+ SkAutoTUnref<SkImage> fImage;
+ AnimValue fScale, fAngle;
+
+ SkInterpolator fTrans;
+
+public:
+ FilterQualityView() : fImage(make_image()), fTrans(2, 2) {
+ fScale.set(1, SK_Scalar1 / 8, 1);
+ fAngle.setMod(0, 360);
+
+ SkScalar values[2];
+ fTrans.setMirror(true);
+ fTrans.setReset(true);
+
+ fTrans.setRepeatCount(999);
+ values[0] = values[1] = 0;
+ fTrans.setKeyFrame(0, SkTime::GetMSecs(), values);
+ values[0] = values[1] = 1;
+ fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values);
+ }
+
+protected:
+
+ // overrides from SkEventSink
+ bool onQuery(SkEvent* evt) SK_OVERRIDE {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "FilterQuality");
+ return true;
+ }
+ SkUnichar uni;
+ if (SampleCode::CharQ(*evt, &uni)) {
+ switch (uni) {
+ case '1': fAngle.inc(-ANGLE_DELTA); this->inval(NULL); return true;
+ case '2': fAngle.inc( ANGLE_DELTA); this->inval(NULL); return true;
+ case '3': fScale.inc(-SCALE_DELTA); this->inval(NULL); return true;
+ case '4': fScale.inc( SCALE_DELTA); this->inval(NULL); return true;
+ default: break;
+ }
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ void drawHere(SkCanvas* canvas, SkScalar x, SkScalar y, SkPaint::FilterLevel filter) {
+ SkAutoCanvasRestore acr(canvas, true);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setFilterLevel(filter);
+
+ canvas->translate(x, y);
+ canvas->scale(fScale, fScale);
+ canvas->rotate(fAngle);
+ canvas->drawImage(fImage, -SkScalarHalf(fImage->width()), -SkScalarHalf(fImage->height()),
+ &paint);
+ }
+
+ void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
+ SkScalar trans[2];
+ fTrans.timeToValues(SkTime::GetMSecs(), trans);
+ canvas->translate(trans[0], trans[1]);
+ this->inval(NULL);
+
+ const struct {
+ SkScalar fX;
+ SkScalar fY;
+ SkPaint::FilterLevel fFilter;
+ } rec[] = {
+ { 100, 100, SkPaint::kNone_FilterLevel },
+ { 300, 100, SkPaint::kLow_FilterLevel },
+ { 100, 300, SkPaint::kMedium_FilterLevel },
+ { 300, 300, SkPaint::kHigh_FilterLevel },
+ };
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
+ this->drawHere(canvas, rec[i].fX, rec[i].fY, rec[i].fFilter);
+ }
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(40);
+ SkString str;
+ str.appendScalar(fScale);
+ canvas->drawText(str.c_str(), str.size(), 450, 100, paint);
+ str.reset(); str.appendScalar(fAngle);
+ canvas->drawText(str.c_str(), str.size(), 450, 150, paint);
+
+ str.reset(); str.appendScalar(trans[0]);
+ canvas->drawText(str.c_str(), str.size(), 450, 200, paint);
+ str.reset(); str.appendScalar(trans[1]);
+ canvas->drawText(str.c_str(), str.size(), 450, 250, paint);
+}
+
+ virtual bool handleKey(SkKey key) {
+ this->inval(NULL);
+ return true;
+ }
+
+private:
+ typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new FilterQualityView; }
+static SkViewRegister reg(MyFactory);