11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SampleCode.h" 90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkView.h" 100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h" 110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkGradientShader.h" 120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPath.h" 130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRegion.h" 140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkShader.h" 150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkUtils.h" 160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "Sk1DPathEffect.h" 170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCornerPathEffect.h" 180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPathMeasure.h" 190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRandom.h" 200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkColorPriv.h" 210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPixelXorXfermode.h" 220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define CORNER_RADIUS 12 240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkScalar gPhase; 250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic const int gXY[] = { 270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkPathEffect* make_pe(int flags) { 310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (flags == 1) 320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS)); 330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPath path; 350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.close(); 390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.offset(SkIntToScalar(-6), 0); 400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kRotate_Style); 420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (flags == 2) 440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return outer; 450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* inner = new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS)); 470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* pe = new SkComposePathEffect(outer, inner); 490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger outer->unref(); 500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger inner->unref(); 510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return pe; 520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkPathEffect* make_warp_pe() { 550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPath path; 560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.close(); 600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger path.offset(SkIntToScalar(-6), 0); 610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kMorph_Style); 630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* inner = new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS)); 640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPathEffect* pe = new SkComposePathEffect(outer, inner); 660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger outer->unref(); 670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger inner->unref(); 680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return pe; 690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/////////////////////////////////////////////////////////// 720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkColorFilter.h" 740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkLayerRasterizer.h" 750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass testrast : public SkLayerRasterizer { 770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic: 780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger testrast() { 790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPaint paint; 800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAntiAlias(true); 810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#if 0 830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStyle(SkPaint::kStroke_Style); 840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStrokeWidth(SK_Scalar1*4); 850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->addLayer(paint); 860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStrokeWidth(SK_Scalar1*1); 880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setXfermode(SkXfermode::kClear_Mode); 890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->addLayer(paint); 900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#else 910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAlpha(0x66); 920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4)); 930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAlpha(0xFF); 950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->addLayer(paint); 960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#endif 970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass PathEffectView : public SampleView { 1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPath fPath; 1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPoint fClickPt; 1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic: 1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger PathEffectView() { 1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRandom rand; 1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int steps = 20; 1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar dist = SkIntToScalar(400); 1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar x = SkIntToScalar(20); 1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar y = SkIntToScalar(50); 1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fPath.moveTo(x, y); 1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < steps; i++) { 1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger x += dist/steps; 1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25); 1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (i == steps/2) { 1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fPath.moveTo(x, tmpY); 1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } else { 1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fPath.lineTo(x, tmpY); 1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRect oval; 1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger oval.set(SkIntToScalar(20), SkIntToScalar(30), 1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkIntToScalar(100), SkIntToScalar(60)); 1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger oval.offset(x, 0); 1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8)); 1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fClickPt.set(SkIntToScalar(200), SkIntToScalar(200)); 1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setBGColor(0xFFDDDDDD); 1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected: 1360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // overrides from SkEventSink 1370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual bool onQuery(SkEvent* evt) { 1380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SampleCode::TitleQ(*evt)) { 1390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SampleCode::TitleR(evt, "PathEffects"); 1400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onQuery(evt); 1430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual void onDrawContent(SkCanvas* canvas) { 1460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger gPhase -= SampleCode::GetAnimSecondsDelta() * 40; 1470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPaint paint; 1500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#if 0 1520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setAntiAlias(true); 1530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStyle(SkPaint::kStroke_Style); 1540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStrokeWidth(SkIntToScalar(5)); 1550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawPath(fPath, paint); 1560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setStrokeWidth(0); 1570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setColor(SK_ColorWHITE); 1590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setPathEffect(make_pe(1))->unref(); 1600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawPath(fPath, paint); 1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#endif 1620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->translate(0, SkIntToScalar(50)); 1640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setColor(SK_ColorBLUE); 1660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setPathEffect(make_pe(2))->unref(); 1670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawPath(fPath, paint); 1680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->translate(0, SkIntToScalar(50)); 1700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setARGB(0xFF, 0, 0xBB, 0); 1720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setPathEffect(make_pe(3))->unref(); 1730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawPath(fPath, paint); 1740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->translate(0, SkIntToScalar(50)); 1760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setARGB(0xFF, 0, 0, 0); 1780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setPathEffect(make_warp_pe())->unref(); 1790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger paint.setRasterizer(new testrast)->unref(); 1800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawPath(fPath, paint); 1810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate: 1840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger typedef SampleView INHERITED; 1850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 1860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger////////////////////////////////////////////////////////////////////////////// 1880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkView* MyFactory() { return new PathEffectView; } 1900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkViewRegister reg(MyFactory); 1910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 192