Index: samplecode/SampleFilterQuality.cpp |
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4c778e35e4881b29faaafe87b1c748adafdc534d |
--- /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); |