1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SampleCode.h" 8837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkView.h" 9837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkCanvas.h" 108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 12837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkGradientShader.h" 13837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkPath.h" 14837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkRegion.h" 15837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkShader.h" 16837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkUtils.h" 17837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkColorPriv.h" 18837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkColorFilter.h" 19435657fd62960ceffb1c3c63f63e836373560bc5halcanary#include "SkStrokeRec.h" 20837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkTypeface.h" 21837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 22837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkGradientShader.h" 23837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkLayerRasterizer.h" 24837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "SkBlurMaskFilter.h" 25837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 26837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#include "Sk2DPathEffect.h" 27837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 28837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comclass Dot2DPathEffect : public Sk2DPathEffect { 29837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.compublic: 30837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix, 31837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkTDArray<SkPoint>* pts) 32837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {} 33837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 34ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect) 35c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth class Registrar { 36c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth public: 37c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth Registrar() { 38c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth SkFlattenable::Register("Dot2DPathEffect", 39c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth Dot2DPathEffect::CreateProc, 40c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth Dot2DPathEffect::GetFlattenableType()); 41c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth } 42c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth }; 43837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comprotected: 4436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void begin(const SkIRect& uvBounds, SkPath* dst) const override { 45837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com if (fPts) { 46837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fPts->reset(); 47837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 48837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com this->INHERITED::begin(uvBounds, dst); 49837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 50548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com 51548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual void next(const SkPoint& loc, int u, int v, 5236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkPath* dst) const override { 53837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com if (fPts) { 54837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com *fPts->append() = loc; 55837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 56837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com dst->addCircle(loc.fX, loc.fY, fRadius); 57837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 58dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 5936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override { 609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.writeMatrix(this->getMatrix()); 6154924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com buffer.writeScalar(fRadius); 6254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com } 6354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com 64837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comprivate: 65837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar fRadius; 66837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkTDArray<SkPoint>* fPts; 67837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 68837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com typedef Sk2DPathEffect INHERITED; 69837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com}; 70837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 71c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverthstatic Dot2DPathEffect::Registrar gReg0; 72c7027ab03f2e8bab4c74bc1b047642622d3d682bjvanverth 7360c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) { 749fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkMatrix matrix; 759fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.readMatrix(&matrix); 7660c9b58b3214b0154c931656e91e39b230e987d8reed return sk_make_sp<Dot2DPathEffect>(buffer.readScalar(), matrix, nullptr); 779fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 789fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 79837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comclass InverseFillPE : public SkPathEffect { 80837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.compublic: 81837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com InverseFillPE() {} 82548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual bool filterPath(SkPath* dst, const SkPath& src, 8336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkStrokeRec*, const SkRect*) const override { 84837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com *dst = src; 85837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com dst->setFillType(SkPath::kInverseWinding_FillType); 86837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com return true; 87837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 8842dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips 8942dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips#ifndef SK_IGNORE_TO_STRING 9036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void toString(SkString* str) const override { 9142dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips str->appendf("InverseFillPE: ()"); 9242dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips } 9342dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips#endif 9442dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips 95ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE) 96ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 97837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comprivate: 98837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com typedef SkPathEffect INHERITED; 99837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com}; 100837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 10160c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> InverseFillPE::CreateProc(SkReadBuffer& buffer) { 10260c9b58b3214b0154c931656e91e39b230e987d8reed return sk_make_sp<InverseFillPE>(); 10360c9b58b3214b0154c931656e91e39b230e987d8reed} 1049fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 105a439334b6e758d38501e225e2e5d0ab73e2fb6ebreedstatic sk_sp<SkPathEffect> makepe(float interp, SkTDArray<SkPoint>* pts) { 106837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkMatrix lattice; 107837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); 108837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com lattice.setScale(rad*2, rad*2, 0, 0); 109837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 110a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed return sk_make_sp<Dot2DPathEffect>(rad, lattice, pts); 111837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com} 112837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 113f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.orgstatic void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p, SkScalar interp) { 114a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed p.setPathEffect(makepe(SkScalarToFloat(interp), nullptr)); 115f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org rastBuilder->addLayer(p); 116837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#if 0 117837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setPathEffect(new InverseFillPE())->unref(); 118837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setXfermodeMode(SkXfermode::kSrcIn_Mode); 119837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setXfermodeMode(SkXfermode::kClear_Mode); 120837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setAlpha((1 - interp) * 255); 121f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org rastBuilder->addLayer(p); 122837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com#endif 123837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com} 124837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 125837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comtypedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&); 126837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 1270e39f97cd7af16e57c7257770af8340750c9b3b0Mike Reedstatic void apply_shader(SkPaint* paint, float scale) { 128837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkPaint p; 129f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org SkLayerRasterizer::Builder rastBuilder; 130837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 131837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setAntiAlias(true); 132f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org r7(&rastBuilder, p, scale); 1337b380d0d0e91ae6967c52bfa14853a77b9551de4reed paint->setRasterizer(rastBuilder.detach()); 134837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 135837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com paint->setColor(SK_ColorBLUE); 136837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com} 137837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 138837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comclass ClockFaceView : public SkView { 13913b9c95295f4c5732e34574789e721a6bc08f7b4bungeman sk_sp<SkTypeface> fFace; 140837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar fInterp; 141837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar fDx; 142102b4d57afa42587d0bc9bcbb0bff6fae791af85mike@reedtribe.org 143837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.compublic: 144102b4d57afa42587d0bc9bcbb0bff6fae791af85mike@reedtribe.org ClockFaceView() { 14513b9c95295f4c5732e34574789e721a6bc08f7b4bungeman fFace = SkTypeface::MakeFromFile("/Users/reed/Downloads/p052024l.pfb"); 146837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fInterp = 0; 147837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fDx = SK_Scalar1/64; 148837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 149dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 150837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comprotected: 151837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com // overrides from SkEventSink 152102b4d57afa42587d0bc9bcbb0bff6fae791af85mike@reedtribe.org virtual bool onQuery(SkEvent* evt) { 153102b4d57afa42587d0bc9bcbb0bff6fae791af85mike@reedtribe.org if (SampleCode::TitleQ(*evt)) { 154837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SampleCode::TitleR(evt, "Text Effects"); 155837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com return true; 156837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 157837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com return this->INHERITED::onQuery(evt); 158837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 159dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 160102b4d57afa42587d0bc9bcbb0bff6fae791af85mike@reedtribe.org void drawBG(SkCanvas* canvas) { 161837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com// canvas->drawColor(0xFFDDDDDD); 162837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com canvas->drawColor(SK_ColorWHITE); 163837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 164dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 165837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com static void drawdots(SkCanvas* canvas, const SkPaint& orig) { 166837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkTDArray<SkPoint> pts; 167a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed auto pe = makepe(0, &pts); 168dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 169fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); 170837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkPath path, dstPath; 171837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com orig.getTextPath("9", 1, 0, 0, &path); 17296fcdcc219d2a0d3579719b84b28bede76efba64halcanary pe->filterPath(&dstPath, path, &rec, nullptr); 173dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 174837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkPaint p; 175837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setAntiAlias(true); 176837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setStrokeWidth(10); 177837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com p.setColor(SK_ColorRED); 178a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), p); 179837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 180dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 181837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com virtual void onDraw(SkCanvas* canvas) { 182837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com this->drawBG(canvas); 183dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 184837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar x = SkIntToScalar(20); 185837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkScalar y = SkIntToScalar(300); 186837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkPaint paint; 187dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 188837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com paint.setAntiAlias(true); 189837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com paint.setTextSize(SkIntToScalar(240)); 190ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc paint.setTypeface(SkTypeface::MakeFromName("sans-serif", 191ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc SkFontStyle::FromOldStyle(SkTypeface::kBold))); 192837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 193837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com SkString str("9"); 194837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 195837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com paint.setTypeface(fFace); 196dd53d91b60e368f1bbff6fb22d796765205ae25dbsalomon@google.com 197c6ce750c73c6586a5c2e88a0620b04e9569af401robertphillips@google.com apply_shader(&paint, SkScalarToFloat(fInterp)); 1982a475eae622adc1e8fa29206be1eaf862c23548eCary Clark canvas->drawString(str, x, y, paint); 199837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 200837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com // drawdots(canvas, paint); 201837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 202837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com if (false) { 203837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fInterp += fDx; 204837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com if (fInterp > 1) { 205837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fInterp = 1; 206837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fDx = -fDx; 207837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } else if (fInterp < 0) { 208837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fInterp = 0; 209837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com fDx = -fDx; 210837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 21196fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->inval(nullptr); 212837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 213837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com } 214837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 215837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comprivate: 216837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com typedef SkView INHERITED; 217837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com}; 218837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 219837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com////////////////////////////////////////////////////////////////////////////// 220837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.com 221837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comstatic SkView* MyFactory() { return new ClockFaceView; } 222837cf7866e62e6a9f831e4e6de414c172a9d711areed@android.comstatic SkViewRegister reg(MyFactory); 223