1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #include "Sample.h" 8 #include "SkCanvas.h" 9 #include "SkReadBuffer.h" 10 #include "SkWriteBuffer.h" 11 #include "SkGradientShader.h" 12 #include "SkPath.h" 13 #include "SkRegion.h" 14 #include "SkShader.h" 15 #include "SkUTF.h" 16 #include "SkColorPriv.h" 17 #include "SkColorFilter.h" 18 #include "SkStrokeRec.h" 19 #include "SkTextUtils.h" 20 #include "SkTypeface.h" 21 22 #include "SkGradientShader.h" 23 #include "SkBlurMaskFilter.h" 24 25 #include "Sk2DPathEffect.h" 26 27 class Dot2DPathEffect : public Sk2DPathEffect { 28 public: 29 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix, 30 SkTDArray<SkPoint>* pts) 31 : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {} 32 33 SK_FLATTENABLE_HOOKS(Dot2DPathEffect) 34 protected: 35 void begin(const SkIRect& uvBounds, SkPath* dst) const override { 36 if (fPts) { 37 fPts->reset(); 38 } 39 this->INHERITED::begin(uvBounds, dst); 40 } 41 42 virtual void next(const SkPoint& loc, int u, int v, 43 SkPath* dst) const override { 44 if (fPts) { 45 *fPts->append() = loc; 46 } 47 dst->addCircle(loc.fX, loc.fY, fRadius); 48 } 49 50 void flatten(SkWriteBuffer& buffer) const override { 51 buffer.writeMatrix(this->getMatrix()); 52 buffer.writeScalar(fRadius); 53 } 54 55 private: 56 57 SkScalar fRadius; 58 SkTDArray<SkPoint>* fPts; 59 60 typedef Sk2DPathEffect INHERITED; 61 }; 62 63 // Register this path effect as deserializable before main(). 64 namespace { 65 static struct Initializer { 66 Initializer() { 67 SK_REGISTER_FLATTENABLE(Dot2DPathEffect); 68 } 69 } initializer; 70 } 71 72 73 sk_sp<SkFlattenable> Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) { 74 SkMatrix matrix; 75 buffer.readMatrix(&matrix); 76 return sk_make_sp<Dot2DPathEffect>(buffer.readScalar(), matrix, nullptr); 77 } 78 79 class InverseFillPE : public SkPathEffect { 80 public: 81 InverseFillPE() {} 82 virtual bool onFilterPath(SkPath* dst, const SkPath& src, 83 SkStrokeRec*, const SkRect*) const override { 84 *dst = src; 85 dst->setFillType(SkPath::kInverseWinding_FillType); 86 return true; 87 } 88 89 private: 90 SK_FLATTENABLE_HOOKS(InverseFillPE) 91 92 typedef SkPathEffect INHERITED; 93 }; 94 95 sk_sp<SkFlattenable> InverseFillPE::CreateProc(SkReadBuffer& buffer) { 96 return sk_make_sp<InverseFillPE>(); 97 } 98 99 static sk_sp<SkPathEffect> makepe(float interp, SkTDArray<SkPoint>* pts) { 100 SkMatrix lattice; 101 SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); 102 lattice.setScale(rad*2, rad*2, 0, 0); 103 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 104 return sk_make_sp<Dot2DPathEffect>(rad, lattice, pts); 105 } 106 107 class TextEffectsView : public Sample { 108 sk_sp<SkTypeface> fFace; 109 SkScalar fInterp; 110 SkScalar fDx; 111 112 public: 113 TextEffectsView() { 114 fFace = SkTypeface::MakeFromFile("/Users/reed/Downloads/p052024l.pfb"); 115 fInterp = 0; 116 fDx = SK_Scalar1/64; 117 } 118 119 protected: 120 bool onQuery(Sample::Event* evt) override { 121 if (Sample::TitleQ(*evt)) { 122 Sample::TitleR(evt, "Text Effects"); 123 return true; 124 } 125 return this->INHERITED::onQuery(evt); 126 } 127 128 void drawBG(SkCanvas* canvas) { 129 canvas->drawColor(SK_ColorWHITE); 130 } 131 132 void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkFont& font) { 133 SkTDArray<SkPoint> pts; 134 auto pe = makepe(fInterp, &pts); 135 136 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); 137 SkPath path, dstPath; 138 SkTextUtils::GetPath(s.c_str(), s.size(), kUTF8_SkTextEncoding, x, y, font, &path); 139 pe->filterPath(&dstPath, path, &rec, nullptr); 140 141 SkPaint paint; 142 paint.setAntiAlias(true); 143 paint.setStrokeWidth(10); 144 paint.setColor(SK_ColorRED); 145 canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), paint); 146 } 147 148 void onDrawContent(SkCanvas* canvas) override { 149 this->drawBG(canvas); 150 151 SkScalar x = SkIntToScalar(20); 152 SkScalar y = SkIntToScalar(300); 153 154 SkFont font(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()), 240); 155 156 SkString str("9"); 157 158 canvas->drawString(str, x, y, font, SkPaint()); 159 drawdots(canvas, str, x, y, font); 160 161 if (false) { 162 fInterp += fDx; 163 if (fInterp > 1) { 164 fInterp = 1; 165 fDx = -fDx; 166 } else if (fInterp < 0) { 167 fInterp = 0; 168 fDx = -fDx; 169 } 170 } 171 } 172 173 private: 174 typedef Sample INHERITED; 175 }; 176 177 ////////////////////////////////////////////////////////////////////////////// 178 179 DEF_SAMPLE( return new TextEffectsView(); ) 180