skia2/samplecode/SampleFilterQuality.cpp
2015-01-14 13:16:26 -08:00

185 lines
5.1 KiB
C++

/*
* 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);