1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAnimTimer.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurMaskFilter.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRRectsGaussianEdgeMaskFilter.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOps.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRRect.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStroke.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kNumCols = 2; 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kNumRows = 5; 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kCellSize = 128; 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkScalar kPad = 8.0f; 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkScalar kInitialBlurRadius = 8.0f; 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr SkScalar kPeriod = 8.0f; 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconstexpr int kClipOffset = 32; 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////////////// 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Object { 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual ~Object() {} 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When it returns true, this call will have placed a device-space _circle, rect or 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // simple circular_ RRect in "rr" 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const = 0; 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual SkPath asPath(SkScalar inset) const = 0; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0; 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void clip(SkCanvas* canvas) const = 0; 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual bool contains(const SkRect& r) const = 0; 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual const SkRect& bounds() const = 0; 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef Object* (*PFMakeMthd)(const SkRect& r); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass RRect : public Object { 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RRect(const SkRect& r) { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad); 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override { 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ctm.isSimilarity()) { // the corners have to remain circular 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scales[2]; 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ctm.getMinMaxScales(scales)) { 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(SkScalarNearlyEqual(scales[0], scales[1])); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect devRect; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctm.mapRect(&devRect, fRRect.rect()); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar scaledRad = scales[0] * fRRect.getSimpleRadii().fX; 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *rr = SkRRect::MakeRectXY(devRect, scaledRad, scaledRad); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath asPath(SkScalar inset) const override { 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect tmp = fRRect; 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.inset(inset, inset); 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath p; 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.addRRect(tmp); 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return p; 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void draw(SkCanvas* canvas, const SkPaint& paint) const override { 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(fRRect, paint); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clip(SkCanvas* canvas) const override { 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRRect(fRRect); 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool contains(const SkRect& r) const override { 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRRect.contains(r); 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& bounds() const override { 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRRect.getBounds(); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static Object* Make(const SkRect& r) { 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new RRect(r); 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect fRRect; 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass StrokedRRect : public Object { 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot StrokedRRect(const SkRect& r) { 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRRect = SkRRect::MakeRectXY(r, 2*kPad, 2*kPad); 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStrokedBounds = r.makeOutset(kPad, kPad); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override { 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath asPath(SkScalar inset) const override { 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect tmp = fRRect; 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.inset(inset, inset); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // In this case we want the outline of the stroked rrect 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setAntiAlias(true); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setStyle(SkPaint::kStroke_Style); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setStrokeWidth(kPad); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath p, stroked; 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.addRRect(tmp); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkStroke stroke(paint); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke.strokePath(p, &stroked); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return stroked; 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void draw(SkCanvas* canvas, const SkPaint& paint) const override { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint stroke(paint); 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke.setStyle(SkPaint::kStroke_Style); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke.setStrokeWidth(kPad); 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(fRRect, stroke); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clip(SkCanvas* canvas) const override { 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(this->asPath(0.0f)); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool contains(const SkRect& r) const override { 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& bounds() const override { 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fStrokedBounds; 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static Object* Make(const SkRect& r) { 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new StrokedRRect(r); 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect fRRect; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect fStrokedBounds; 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Oval : public Object { 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Oval(const SkRect& r) { 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRRect = SkRRect::MakeOval(r); 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override { 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ctm.isSimilarity()) { // circles have to remain circles 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect devRect; 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctm.mapRect(&devRect, fRRect.rect()); 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *rr = SkRRect::MakeOval(devRect); 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath asPath(SkScalar inset) const override { 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect tmp = fRRect; 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.inset(inset, inset); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath p; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.addRRect(tmp); 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return p; 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void draw(SkCanvas* canvas, const SkPaint& paint) const override { 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(fRRect, paint); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clip(SkCanvas* canvas) const override { 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRRect(fRRect); 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool contains(const SkRect& r) const override { 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRRect.contains(r); 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& bounds() const override { 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRRect.getBounds(); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static Object* Make(const SkRect& r) { 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new Oval(r); 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect fRRect; 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Rect : public Object { 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Rect(const SkRect& r) : fRect(r) { } 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override { 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ctm.rectStaysRect()) { 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect devRect; 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctm.mapRect(&devRect, fRect); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *rr = SkRRect::MakeRect(devRect); 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath asPath(SkScalar inset) const override { 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect tmp = fRect; 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.inset(inset, inset); 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath p; 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot p.addRect(tmp); 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return p; 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void draw(SkCanvas* canvas, const SkPaint& paint) const override { 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(fRect, paint); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clip(SkCanvas* canvas) const override { 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(fRect); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool contains(const SkRect& r) const override { 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRect.contains(r); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& bounds() const override { 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fRect; 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static Object* Make(const SkRect& r) { 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new Rect(r); 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect fRect; 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Pentagon : public Object { 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Pentagon(const SkRect& r) { 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint points[5] = { 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0.000000f, -1.000000f }, 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { -0.951056f, -0.309017f }, 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { -0.587785f, 0.809017f }, 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0.587785f, 0.809017f }, 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 0.951057f, -0.309017f }, 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar height = r.height()/2.0f; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar width = r.width()/2.0f; 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.moveTo(r.centerX() + points[0].fX * width, r.centerY() + points[0].fY * height); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.lineTo(r.centerX() + points[1].fX * width, r.centerY() + points[1].fY * height); 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.lineTo(r.centerX() + points[2].fX * width, r.centerY() + points[2].fY * height); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.lineTo(r.centerX() + points[3].fX * width, r.centerY() + points[3].fY * height); 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.lineTo(r.centerX() + points[4].fX * width, r.centerY() + points[4].fY * height); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.close(); 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override { 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath asPath(SkScalar inset) const override { return fPath; } 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void draw(SkCanvas* canvas, const SkPaint& paint) const override { 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(fPath, paint); 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clip(SkCanvas* canvas) const override { 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipPath(this->asPath(0.0f)); 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool contains(const SkRect& r) const override { 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& bounds() const override { 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fPath.getBounds(); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static Object* Make(const SkRect& r) { 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new Pentagon(r); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath fPath; 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////////////// 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm { 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This GM attempts to mimic Android's reveal animation 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass RevealGM : public GM { 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum Mode { 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kBlurMask_Mode, 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kRRectsGaussianEdge_Mode, 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kLast_Mode = kRRectsGaussianEdge_Mode 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kModeCount = kLast_Mode + 1; 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum CoverageGeom { 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kRect_CoverageGeom, 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kRRect_CoverageGeom, 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kDRRect_CoverageGeom, 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kPath_CoverageGeom, 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kLast_CoverageGeom = kPath_CoverageGeom 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const int kCoverageGeomCount = kLast_CoverageGeom + 1; 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RevealGM() 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fFraction(0.5f) 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fMode(kRRectsGaussianEdge_Mode) 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fPause(false) 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBlurRadius(kInitialBlurRadius) 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fCoverageGeom(kRect_CoverageGeom) { 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool runAsBench() const override { return true; } 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString onShortName() override { 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkString("reveal"); 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkISize onISize() override { 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkISize::Make(kNumCols * kCellSize, kNumRows * kCellSize); 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onDraw(SkCanvas* canvas) override { 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot PFMakeMthd clipMakes[kNumCols] = { Oval::Make, Rect::Make }; 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot PFMakeMthd drawMakes[kNumRows] = { 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RRect::Make, StrokedRRect::Make, Oval::Make, Rect::Make, Pentagon::Make 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint strokePaint; 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot strokePaint.setStyle(SkPaint::kStroke_Style); 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot strokePaint.setStrokeWidth(0.0f); 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int y = 0; y < kNumRows; ++y) { 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int x = 0; x < kNumCols; ++x) { 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect cell = SkRect::MakeXYWH(SkIntToScalar(x*kCellSize), 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(y*kCellSize), 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(kCellSize), 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(kCellSize)); 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->save(); 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->clipRect(cell); 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cell.inset(kPad, kPad); 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint clipCenter = SkPoint::Make(cell.centerX() - kClipOffset, 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cell.centerY() + kClipOffset); 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar curSize = kCellSize * fFraction; 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect clipRect = SkRect::MakeLTRB(clipCenter.fX - curSize, 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipCenter.fY - curSize, 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipCenter.fX + curSize, 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipCenter.fY + curSize); 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<Object> clipObj((*clipMakes[x])(clipRect)); 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<Object> drawObj((*drawMakes[y])(cell)); 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The goal is to replace this clipped draw (which clips the 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // shadow) with a draw using the geometric clip 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (kBlurMask_Mode == fMode) { 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath clippedPath; 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar sigma = fBlurRadius / 4.0f; 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (clipObj->contains(drawObj->bounds())) { 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clippedPath = drawObj->asPath(2.0f*sigma); 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath drawnPath = drawObj->asPath(2.0f*sigma); 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath clipPath = clipObj->asPath(2.0f*sigma); 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAssertResult(Op(clipPath, drawnPath, kIntersect_SkPathOp, &clippedPath)); 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint blurPaint; 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blurPaint.setAntiAlias(true); 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, sigma)); 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(clippedPath, blurPaint); 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(kRRectsGaussianEdge_Mode == fMode); 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect cover = drawObj->bounds(); 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAssertResult(cover.intersect(clipObj->bounds())); 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paint; 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRRect devSpaceClipRR, devSpaceDrawnRR; 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (clipObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceClipRR) && 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot drawObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceDrawnRR)) { 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceClipRR, 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot devSpaceDrawnRR, 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBlurRadius)); 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot strokePaint.setColor(SK_ColorBLUE); 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (fCoverageGeom) { 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRect_CoverageGeom: 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(cover, paint); 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRect(cover, strokePaint); 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kRRect_CoverageGeom: { 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRRect rrect = SkRRect::MakeRectXY( 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cover.makeOutset(10.0f, 10.0f), 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10.0f, 10.0f); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(rrect, paint); 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawRRect(rrect, strokePaint); 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kDRRect_CoverageGeom: { 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRRect inner = SkRRect::MakeRectXY(cover.makeInset(10.0f, 10.0f), 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10.0f, 10.0f); 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRRect outer = SkRRect::MakeRectXY( 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cover.makeOutset(10.0f, 10.0f), 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10.0f, 10.0f); 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawDRRect(outer, inner, paint); 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawDRRect(outer, inner, strokePaint); 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case kPath_CoverageGeom: { 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.moveTo(cover.fLeft, cover.fTop); 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.lineTo(cover.centerX(), cover.centerY()); 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.lineTo(cover.fRight, cover.fTop); 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.lineTo(cover.fRight, cover.fBottom); 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.lineTo(cover.centerX(), cover.centerY()); 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.lineTo(cover.fLeft, cover.fBottom); 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.close(); 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(path, paint); 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(path, strokePaint); 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Draw the clip and draw objects for reference 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot strokePaint.setColor(SK_ColorRED); 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(drawObj->asPath(0.0f), strokePaint); 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot strokePaint.setColor(SK_ColorGREEN); 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->drawPath(clipObj->asPath(0.0f), strokePaint); 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot canvas->restore(); 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool onHandleKey(SkUnichar uni) override { 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (uni) { 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case 'C': 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMode = (Mode)((fMode + 1) % kModeCount); 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case '+': 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBlurRadius += 1.0f; 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case '-': 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBlurRadius = SkTMax(1.0f, fBlurRadius - 1.0f); 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case 'p': 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPause = !fPause; 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case 'G': 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCoverageGeom = (CoverageGeom) ((fCoverageGeom+1) % kCoverageGeomCount); 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool onAnimate(const SkAnimTimer& timer) override { 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fPause) { 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFraction = timer.pingPong(kPeriod, 0.0f, 0.0f, 1.0f); 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar fFraction; 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Mode fMode; 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fPause; 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float fBlurRadius; 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CoverageGeom fCoverageGeom; 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typedef GM INHERITED; 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////// 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM(return new RevealGM;) 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 517