1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/* 2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2012 Google Inc. 3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file. 6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "gm.h" 9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkRRect.h" 10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergernamespace skiagm { 12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass RRectGM : public GM { 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerpublic: 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger RRectGM(bool doAA, bool doClip) : fDoAA(doAA), fDoClip(doClip) { 18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setBGColor(0xFFDDDDDD); 19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->setUpRRects(); 20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerprotected: 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkString onShortName() { 24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkString name("rrect"); 25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fDoClip) { 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger name.append("_clip"); 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fDoAA) { 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger name.append("_aa"); 30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger name.append("_bw"); 32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return name; 35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual SkISize onISize() { return make_isize(kImageWidth, kImageHeight); } 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void onDraw(SkCanvas* canvas) { 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPaint paint; 42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // when clipping the AA is pushed into the clip operation 43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paint.setAntiAlias(fDoClip ? false : fDoAA); 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const SkRect kMaxTileBound = SkRect::MakeWH(SkIntToScalar(kTileX), SkIntToScalar(kTileY)); 46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int curRRect = 0; 48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int y = 1; y < kImageHeight; y += kTileY) { 49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (int x = 1; x < kImageWidth; x += kTileX) { 50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (curRRect >= kNumRRects) { 51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kMaxTileBound.contains(fRRects[curRRect].getBounds())); 54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->save(); 56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fDoClip) { 58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->clipRRect(fRRects[curRRect], SkRegion::kReplace_Op, fDoAA); 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->drawRect(kMaxTileBound, paint); 60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->drawRRect(fRRects[curRRect], paint); 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ++curRRect; 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger canvas->restore(); 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger void setUpRRects() { 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // each RRect must fit in a 0x0 -> (kTileX-2)x(kTileY-2) block. These will be tiled across 71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the screen in kTileX x kTileY tiles. The extra empty pixels on each side are for AA. 72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // simple cases 74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRRects[0].setRect(SkRect::MakeWH(kTileX-2, kTileY-2)); 75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRRects[1].setOval(SkRect::MakeWH(kTileX-2, kTileY-2)); 76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRRects[2].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 10, 10); 77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The first complex case needs special handling since it is a square 79363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRRects[kNumSimpleCases].setRectRadii(SkRect::MakeWH(kTileY-2, kTileY-2), gRadii[0]); 80d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger for (size_t i = 1; i < SK_ARRAY_COUNT(gRadii); ++i) { 81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRRects[kNumSimpleCases+i].setRectRadii(SkRect::MakeWH(kTileX-2, kTileY-2), gRadii[i]); 82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 85363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerprivate: 86363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool fDoAA; 87363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool fDoClip; // use clipRRect & drawRect instead of drawRRect 88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 89363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kImageWidth = 640; 90363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kImageHeight = 480; 91363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kTileX = 80; 93363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kTileY = 40; 94363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 95363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kNumSimpleCases = 3; 96363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kNumComplexCases = 19; 97363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const SkVector gRadii[kNumComplexCases][4]; 98363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 99363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int kNumRRects = kNumSimpleCases + kNumComplexCases; 100363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRRect fRRects[kNumRRects]; 101363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 102363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger typedef GM INHERITED; 103363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}; 104363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 105363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// Radii for the various test cases. Order is UL, UR, LR, LL 106363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkVector RRectGM::gRadii[kNumComplexCases][4] = { 107363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // a circle 108363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY } }, 109363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 110363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // odd ball cases 111363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 8, 8 }, { 32, 32 }, { 8, 8 }, { 32, 32 } }, 112363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 16, 8 }, { 8, 16 }, { 16, 8 }, { 8, 16 } }, 113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 32, 32 } }, 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // UL 116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 30, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, 117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 30, 15 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, 118363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 15, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, 119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 120363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // UR 121363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 30, 30 }, { 0, 0 }, { 0, 0 } }, 122363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 30, 15 }, { 0, 0 }, { 0, 0 } }, 123363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 15, 30 }, { 0, 0 }, { 0, 0 } }, 124363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 125363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // LR 126363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 30, 30 }, { 0, 0 } }, 127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 30, 15 }, { 0, 0 } }, 128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 15, 30 }, { 0, 0 } }, 129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // LL 131363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 30 } }, 132363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 15 } }, 133363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 15, 30 } }, 134363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // over-sized radii 136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 100, 400 }, { 0, 0 }, { 0, 0 } }, 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 0, 0 }, { 400, 400 }, { 0, 0 }, { 0, 0 } }, 138363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger { { 400, 400 }, { 400, 400 }, { 400, 400 }, { 400, 400 } }, 139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}; 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerDEF_GM( return new RRectGM(false, false); ) 144363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerDEF_GM( return new RRectGM(true, false); ) 145363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerDEF_GM( return new RRectGM(false, true); ) 146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerDEF_GM( return new RRectGM(true, true); ) 147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 149