| Index: gm/bitmapalphathreshold.cpp
|
| diff --git a/gm/bitmapalphathreshold.cpp b/gm/bitmapalphathreshold.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2c8123a8069a3ab586572708db8b3bd40dd38cd1
|
| --- /dev/null
|
| +++ b/gm/bitmapalphathreshold.cpp
|
| @@ -0,0 +1,144 @@
|
| +/*
|
| + * Copyright 2013 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 "SkGradientShader.h"
|
| +#include "SkBitmapAlphaThresholdShader.h"
|
| +#include "SkTArray.h"
|
| +#include "SkParsePath.h"
|
| +
|
| +class BitmapAlphaThresholdGM : public skiagm::GM {
|
| +public:
|
| + BitmapAlphaThresholdGM() {
|
| + this->setBGColor(0xFF000000);
|
| + }
|
| +
|
| +protected:
|
| + virtual uint32_t onGetFlags() const {
|
| + // narrow this flags when the shader has a CPU implementation and
|
| + // when it serializes.
|
| + return
|
| + kSkipPDF_Flag |
|
| + kSkipPicture_Flag |
|
| + kSkipPipe_Flag |
|
| + kSkipPipeCrossProcess_Flag |
|
| + kSkipTiled_Flag |
|
| + kSkip565_Flag |
|
| + kSkipScaledReplay_Flag |
|
| + kSkipPDFRasterization_Flag |
|
| +
|
| + kGPUOnly_Flag;
|
| + }
|
| +
|
| +private:
|
| + virtual void onOnceBeforeDraw() SK_OVERRIDE {
|
| + fBM.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
|
| + if (!fBM.allocPixels()) {
|
| + return;
|
| + }
|
| + SkCanvas canvas(fBM);
|
| + SkPoint pts[] = { {0, 0}, {SkIntToScalar(fBM.width()), SkIntToScalar(fBM.height())} };
|
| + SkColor colors[] = {0x00000000, 0xffffffff};
|
| + SkShader* grad = SkGradientShader::CreateLinear(pts, colors, NULL, 2,
|
| + SkShader::kClamp_TileMode);
|
| + SkPaint gradPaint;
|
| + gradPaint.setShader(grad)->unref();
|
| + gradPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
| + canvas.drawPaint(gradPaint);
|
| +
|
| + // Construct the region used as a mask.
|
| + SkRegion bmpBoundsClip;
|
| + bmpBoundsClip.setRect(0, 0, fBM.width(), fBM.height());
|
| + SkPath circlePath;
|
| + SkScalar radius = SkScalarSqrt(SkIntToScalar(fBM.width() * fBM.height())) / 2;
|
| + circlePath.addCircle(SkIntToScalar(fBM.width() / 2),
|
| + SkIntToScalar(fBM.height() / 2),
|
| + radius);
|
| + fMask.setPath(circlePath, bmpBoundsClip);
|
| +
|
| + SkPath batPath;
|
| + SkParsePath::FromSVGString(
|
| + "M305.214,374.779c2.463,0,3.45,0.493,3.45,0.493l1.478-6.241c0,0,1.15,4.763,1.643,9.034"
|
| + "c0.493,4.271,8.048,1.479,14.454,0.164c6.405-1.314,7.72-11.662,7.72-11.662h59.294c0,0-35.807,10.841-26.772,34.656"
|
| + "c0,0-52.889-8.048-61.101,24.967h-0.001c-8.212-33.015-61.101-24.967-61.101-24.967c9.034-23.815-26.772-34.656-26.772-34.656"
|
| + "h59.294c0,0,1.314,10.348,7.719,11.662c6.406,1.314,13.962,4.106,14.454-0.164c0.493-4.271,1.643-9.034,1.643-9.034l1.479,6.241"
|
| + "c0,0,0.985-0.493,3.449-0.493H305.214L305.214,374.779z",
|
| + &batPath);
|
| +
|
| + SkMatrix matrix;
|
| + matrix.setTranslate(-208, -280);
|
| + matrix.postScale(radius / 100, radius / 100);
|
| + batPath.transform(matrix, &batPath);
|
| + SkRegion batRegion;
|
| + batRegion.setPath(batPath, bmpBoundsClip);
|
| +
|
| + fMask.op(batRegion, SkRegion::kDifference_Op);
|
| + }
|
| +
|
| + virtual SkString onShortName() SK_OVERRIDE {
|
| + return SkString("bat");
|
| + }
|
| +
|
| + virtual SkISize onISize() SK_OVERRIDE {
|
| + return SkISize::Make(920, 480);
|
| + }
|
| +
|
| + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
| +
|
| + SkTArray<SkMatrix> lms;
|
| + lms.push_back().reset();
|
| + lms.push_back().setScale(SK_Scalar1 / 2, SK_Scalar1);
|
| + lms.push_back().setScale(SK_Scalar1, 2 * SK_Scalar1);
|
| + lms.push_back().setSkew(0, SK_Scalar1 / 200);
|
| + lms.push_back().setRotate(SK_Scalar1 * 10);
|
| +
|
| + static const SkScalar kMargin = 5 * SK_Scalar1;
|
| + canvas->translate(kMargin, kMargin);
|
| + canvas->save();
|
| +
|
| + static const U8CPU kThresholds[] = { 0x0, 0x08, 0x40, 0x80, 0xC0, 0xF0, 0xFF };
|
| +
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(kThresholds); ++i) {
|
| + for (int j = 0; j < lms.count(); ++j) {
|
| + SkRect rect;
|
| + rect.fLeft = 0;
|
| + rect.fTop = 0;
|
| + rect.fRight = SkIntToScalar(fBM.width());
|
| + rect.fBottom = SkIntToScalar(fBM.height());
|
| +
|
| + SkShader* thresh;
|
| + // This SkShader currently only has a GPU implementation.
|
| + if (canvas->getDevice()->accessRenderTarget()) {
|
| + thresh = SkBitmapAlphaThresholdShader::Create(fBM, fMask, kThresholds[i]);
|
| + } else {
|
| + thresh = SkShader::CreateBitmapShader(fBM, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
|
| + }
|
| +
|
| + thresh->setLocalMatrix(lms[j]);
|
| +
|
| + SkPaint paint;
|
| + paint.setShader(thresh)->unref();
|
| +
|
| + canvas->drawRect(rect, paint);
|
| + canvas->translate(SkIntToScalar(fBM.width() + kMargin), 0);
|
| + }
|
| + canvas->restore();
|
| + canvas->translate(0, SkIntToScalar(fBM.height() + kMargin));
|
| + canvas->save();
|
| + }
|
| +
|
| + }
|
| +
|
| + SkBitmap fBM;
|
| + SkRegion fMask;
|
| +
|
| + typedef skiagm::GM INHERITED;
|
| +};
|
| +
|
| +//////////////////////////////////////////////////////////////////////////////
|
| +
|
| +DEF_GM( return new BitmapAlphaThresholdGM(); )
|
|
|