120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com/* 320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com * Copyright 2013 Google Inc. 420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com * 520edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 620edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com * found in the LICENSE file. 720edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com */ 820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com#include "gm.h" 920edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com#include "SkBitmap.h" 1020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com#include "SkRandom.h" 1120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com#include "SkShader.h" 1220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com#include "SkXfermode.h" 1320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 1420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comnamespace skiagm { 1520edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 1620edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com/** 176db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com * Renders overlapping shapes with random SkXfermode::Modes against a checkerboard. 1820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com */ 1920edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comclass MixedXfermodesGM : public GM { 2020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.compublic: 2120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com MixedXfermodesGM() { 2220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com } 2320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 2420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comprotected: 256db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com virtual SkString onShortName() SK_OVERRIDE { 2620edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com return SkString("mixed_xfermodes"); 2720edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com } 2820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 296db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com virtual SkISize onISize() SK_OVERRIDE { 30f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina return SkISize::Make(790, 640); 3120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com } 3220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 336db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com void drawShape(SkCanvas* canvas, 346db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com const SkPaint& paint, 35e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom* random) { 366db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com static const SkRect kRect = SkRect::MakeXYWH(SkIntToScalar(-50), SkIntToScalar(-50), 376db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkIntToScalar(75), SkIntToScalar(105)); 386db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com int shape = random->nextULessThan(5); 396db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com switch (shape) { 406db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com case 0: 416db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->drawCircle(0, 0, 50, paint); 426db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com break; 436db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com case 1: 446db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), paint); 456db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com break; 466db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com case 2: 476db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->drawRect(kRect, paint); 486db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com break; 496db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com case 3: 506db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com if (fConvexPath.isEmpty()) { 516db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkPoint points[4]; 526db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com kRect.toQuad(points); 536db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConvexPath.moveTo(points[0]); 546db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConvexPath.quadTo(points[1], points[2]); 556db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConvexPath.quadTo(points[3], points[0]); 566db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkASSERT(fConvexPath.isConvex()); 576db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 586db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->drawPath(fConvexPath, paint); 596db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com break; 606db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com case 4: 616db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com if (fConcavePath.isEmpty()) { 626db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkPoint points[5] = {{0, SkIntToScalar(-50)} }; 636db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkMatrix rot; 646db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com rot.setRotate(SkIntToScalar(360) / 5); 656db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com for (int i = 1; i < 5; ++i) { 666db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com rot.mapPoints(points + i, points + i - 1, 1); 676db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 686db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConcavePath.moveTo(points[0]); 696db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com for (int i = 0; i < 5; ++i) { 706db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConcavePath.lineTo(points[(2 * i) % 5]); 716db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 726db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fConcavePath.setFillType(SkPath::kEvenOdd_FillType); 736db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkASSERT(!fConcavePath.isConvex()); 746db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 756db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->drawPath(fConcavePath, paint); 766db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com break; 776db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 786db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 796db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com 806db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 816db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com if (NULL == fBG.get()) { 826db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 836db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com 0xFFCCCCCC, 846db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com 0xFFCCCCCC, 856db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com 0xFFFFFFFF }; 866db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkBitmap bitmap; 87eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com bitmap.allocN32Pixels(2, 2); 886db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData)); 899c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org SkMatrix lm; 909c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org lm.setScale(SkIntToScalar(20), SkIntToScalar(20)); 916db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com fBG.reset(SkShader::CreateBitmapShader(bitmap, 926db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkShader::kRepeat_TileMode, 939c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org SkShader::kRepeat_TileMode, 949c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org &lm)); 956db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com } 966db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com 9720edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkPaint bgPaint; 9820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com bgPaint.setShader(fBG.get()); 9920edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com canvas->drawPaint(bgPaint); 10020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkISize size = canvas->getDeviceSize(); 1016db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkScalar maxScale = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeight))) / 300; 102e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom random; 1036db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com for (int i = 0; i < kNumShapes; ++i) { 1046db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkScalar s = random.nextRangeScalar(SK_Scalar1 / 8, SK_Scalar1) * maxScale; 1056db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkScalar r = random.nextRangeScalar(0, SkIntToScalar(360)); 1066db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkScalar dx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth)); 1076db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkScalar dy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight)); 10820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkColor color = random.nextU(); 10920edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkXfermode::Mode mode = 11020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::kLastMode + 1)); 11105a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com 11220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkPaint p; 11320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com p.setAntiAlias(true); 11420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com p.setColor(color); 11520edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com p.setXfermodeMode(mode); 1166db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->save(); 1176db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->translate(dx, dy); 1186db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->scale(s, s); 1196db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->rotate(r); 1206db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com this->drawShape(canvas, p, &random); 1216db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com canvas->restore(); 12220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com } 12320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com } 12420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 1250dcbece326ce2fa1f9046aa69a21bb99de08714avandebo@chromium.org virtual uint32_t onGetFlags() const { 1260dcbece326ce2fa1f9046aa69a21bb99de08714avandebo@chromium.org // Skip PDF rasterization since rendering this PDF takes forever. 127a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org return kSkipPDFRasterization_Flag | kSkipTiled_Flag; 1280dcbece326ce2fa1f9046aa69a21bb99de08714avandebo@chromium.org } 1290dcbece326ce2fa1f9046aa69a21bb99de08714avandebo@chromium.org 13020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comprivate: 13120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com enum { 1326db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com kNumShapes = 100, 13320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com }; 13420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com SkAutoTUnref<SkShader> fBG; 1356db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkPath fConcavePath; 1366db962617ff75cadaa6574d85620f7fe0161e23ebsalomon@google.com SkPath fConvexPath; 13720edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com typedef GM INHERITED; 13820edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com}; 13920edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 14020edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com////////////////////////////////////////////////////////////////////////////// 14120edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 14220edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comstatic GM* MyFactory(void*) { return new MixedXfermodesGM; } 14320edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.comstatic GMRegistry reg(MyFactory); 14420edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com 14520edf38a9ea04b990e0412654e342ced45d3ef15bsalomon@google.com} 146