Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "gm.h"
      9 #include "SkGradientShader.h"
     10 #include "SkBitmapAlphaThresholdShader.h"
     11 #include "SkTArray.h"
     12 #include "SkParsePath.h"
     13 
     14 class BitmapAlphaThresholdGM : public skiagm::GM {
     15 public:
     16     BitmapAlphaThresholdGM() {
     17         this->setBGColor(0xFF000000);
     18     }
     19 
     20 private:
     21     virtual uint32_t onGetFlags() const SK_OVERRIDE {
     22         // narrow this flags when the shader has a CPU implementation and
     23         // when it serializes.
     24         return
     25             kSkipPDF_Flag               |
     26             kSkipPicture_Flag           |
     27             kSkipPipe_Flag              |
     28             kSkipPipeCrossProcess_Flag  |
     29             kSkipTiled_Flag             |
     30             kSkip565_Flag               |
     31             kSkipScaledReplay_Flag      |
     32             kSkipPDFRasterization_Flag  |
     33 
     34             kGPUOnly_Flag;
     35     }
     36 
     37     virtual void onOnceBeforeDraw() SK_OVERRIDE {
     38         fBM.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
     39         if (!fBM.allocPixels()) {
     40             return;
     41         }
     42         SkCanvas canvas(fBM);
     43         SkPoint pts[] = { {0, 0}, {SkIntToScalar(fBM.width()), SkIntToScalar(fBM.height())} };
     44         SkColor colors[] = {0x00000000, 0xffffffff};
     45         SkShader* grad = SkGradientShader::CreateLinear(pts, colors, NULL, 2,
     46                                                         SkShader::kClamp_TileMode);
     47         SkPaint gradPaint;
     48         gradPaint.setShader(grad)->unref();
     49         gradPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
     50         canvas.drawPaint(gradPaint);
     51 
     52         // Construct the region used as a mask.
     53         SkRegion bmpBoundsClip;
     54         bmpBoundsClip.setRect(0, 0, fBM.width(), fBM.height());
     55         SkPath circlePath;
     56         SkScalar radius = SkScalarSqrt(SkIntToScalar(fBM.width() * fBM.height())) / 2;
     57         circlePath.addCircle(SkIntToScalar(fBM.width() / 2),
     58                              SkIntToScalar(fBM.height() / 2),
     59                              radius);
     60         fMask.setPath(circlePath, bmpBoundsClip);
     61 
     62         SkPath batPath;
     63         SkParsePath::FromSVGString(
     64         "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"
     65         "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"
     66         "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"
     67         "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"
     68         "c0,0,0.985-0.493,3.449-0.493H305.214L305.214,374.779z",
     69         &batPath);
     70 
     71         SkMatrix matrix;
     72         matrix.setTranslate(-208, -280);
     73         matrix.postScale(radius / 100, radius / 100);
     74         batPath.transform(matrix, &batPath);
     75         SkRegion batRegion;
     76         batRegion.setPath(batPath, bmpBoundsClip);
     77 
     78         fMask.op(batRegion, SkRegion::kDifference_Op);
     79     }
     80 
     81     virtual SkString onShortName() SK_OVERRIDE {
     82         return SkString("bat");
     83     }
     84 
     85     virtual SkISize onISize() SK_OVERRIDE {
     86         return SkISize::Make(518, 735);
     87     }
     88 
     89     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
     90 
     91         SkTArray<SkMatrix> lms;
     92         lms.push_back().reset();
     93         lms.push_back().setScale(SK_Scalar1 / 2, SK_Scalar1);
     94         lms.push_back().setScale(SK_Scalar1, 2 * SK_Scalar1);
     95         lms.push_back().setRotate(-SK_Scalar1 * 30);
     96         lms.push_back().setSkew(0, SK_Scalar1 / 5);
     97 
     98         static const SkScalar kMargin = 5 * SK_Scalar1;
     99         canvas->translate(kMargin, kMargin);
    100         canvas->save();
    101 
    102         static const U8CPU kThresholds[] = { 0x0, 0x08, 0x40, 0x80, 0xC0, 0xF0, 0xFF };
    103 
    104         for (size_t i = 0; i < SK_ARRAY_COUNT(kThresholds); ++i) {
    105             for (int j = 0; j < lms.count(); ++j) {
    106                 SkRect rect;
    107                 rect.fLeft = 0;
    108                 rect.fTop = 0;
    109                 rect.fRight = SkIntToScalar(fBM.width());
    110                 rect.fBottom = SkIntToScalar(fBM.height());
    111 
    112                 SkShader* thresh;
    113                 // This SkShader currently only has a GPU implementation.
    114                 if (canvas->getDevice()->accessRenderTarget()) {
    115                     thresh = SkBitmapAlphaThresholdShader::Create(fBM, fMask, kThresholds[i]);
    116                 } else {
    117                     thresh = SkShader::CreateBitmapShader(fBM, SkShader::kClamp_TileMode,
    118                                                                SkShader::kClamp_TileMode);
    119                 }
    120 
    121                 thresh->setLocalMatrix(lms[j]);
    122 
    123                 SkPaint paint;
    124                 paint.setShader(thresh)->unref();
    125 
    126                 canvas->drawRect(rect, paint);
    127                 canvas->translate(SkIntToScalar(fBM.width() + kMargin), 0);
    128             }
    129             canvas->restore();
    130             canvas->translate(0, SkIntToScalar(fBM.height() + kMargin));
    131             canvas->save();
    132         }
    133 
    134     }
    135 
    136     SkBitmap    fBM;
    137     SkRegion    fMask;
    138 
    139     typedef skiagm::GM INHERITED;
    140 };
    141 
    142 //////////////////////////////////////////////////////////////////////////////
    143 
    144 DEF_GM( return new BitmapAlphaThresholdGM(); )
    145