1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SampleCode.h" 9#include "SkView.h" 10#include "SkCanvas.h" 11#include "SkReadBuffer.h" 12#include "SkWriteBuffer.h" 13#include "SkGradientShader.h" 14#include "SkPath.h" 15#include "SkRegion.h" 16#include "SkShader.h" 17#include "SkUtils.h" 18#include "SkColorPriv.h" 19#include "SkColorFilter.h" 20#include "SkTypeface.h" 21 22static inline SkPMColor rgb2gray(SkPMColor c) { 23 unsigned r = SkGetPackedR32(c); 24 unsigned g = SkGetPackedG32(c); 25 unsigned b = SkGetPackedB32(c); 26 27 unsigned x = (r * 5 + g * 7 + b * 4) >> 4; 28 29 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT)); 30} 31 32class SkGrayScaleColorFilter : public SkColorFilter { 33public: 34 virtual void filterSpan(const SkPMColor src[], int count, 35 SkPMColor result[]) const override { 36 for (int i = 0; i < count; i++) { 37 result[i] = rgb2gray(src[i]); 38 } 39 } 40}; 41 42class SkChannelMaskColorFilter : public SkColorFilter { 43public: 44 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) { 45 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask); 46 } 47 48 virtual void filterSpan(const SkPMColor src[], int count, 49 SkPMColor result[]) const override { 50 SkPMColor mask = fMask; 51 for (int i = 0; i < count; i++) { 52 result[i] = src[i] & mask; 53 } 54 } 55 56private: 57 SkPMColor fMask; 58}; 59 60/////////////////////////////////////////////////////////////////////////////// 61 62#include "SkGradientShader.h" 63#include "SkLayerRasterizer.h" 64#include "SkBlurMaskFilter.h" 65 66#include "Sk2DPathEffect.h" 67 68class Dot2DPathEffect : public Sk2DPathEffect { 69public: 70 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix, 71 SkTDArray<SkPoint>* pts) 72 : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {} 73 74 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect) 75 76protected: 77 void begin(const SkIRect& uvBounds, SkPath* dst) const override { 78 if (fPts) { 79 fPts->reset(); 80 } 81 this->INHERITED::begin(uvBounds, dst); 82 } 83 84 virtual void next(const SkPoint& loc, int u, int v, 85 SkPath* dst) const override { 86 if (fPts) { 87 *fPts->append() = loc; 88 } 89 dst->addCircle(loc.fX, loc.fY, fRadius); 90 } 91 92 void flatten(SkWriteBuffer& buffer) const override { 93 buffer.writeMatrix(this->getMatrix()); 94 buffer.writeScalar(fRadius); 95 } 96 97private: 98 SkScalar fRadius; 99 SkTDArray<SkPoint>* fPts; 100 101 typedef Sk2DPathEffect INHERITED; 102}; 103 104SkFlattenable* Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) { 105 SkMatrix matrix; 106 buffer.readMatrix(&matrix); 107 return SkNEW_ARGS(Dot2DPathEffect, (buffer.readScalar(), matrix, NULL)); 108} 109 110class InverseFillPE : public SkPathEffect { 111public: 112 InverseFillPE() {} 113 virtual bool filterPath(SkPath* dst, const SkPath& src, 114 SkStrokeRec*, const SkRect*) const override { 115 *dst = src; 116 dst->setFillType(SkPath::kInverseWinding_FillType); 117 return true; 118 } 119 120#ifndef SK_IGNORE_TO_STRING 121 void toString(SkString* str) const override { 122 str->appendf("InverseFillPE: ()"); 123 } 124#endif 125 126 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE) 127 128private: 129 typedef SkPathEffect INHERITED; 130}; 131 132SkFlattenable* InverseFillPE::CreateProc(SkReadBuffer& buffer) { 133 return SkNEW(InverseFillPE); 134} 135 136static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) { 137 SkMatrix lattice; 138 SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); 139 lattice.setScale(rad*2, rad*2, 0, 0); 140 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 141 return new Dot2DPathEffect(rad, lattice, pts); 142} 143 144static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p, SkScalar interp) { 145 p.setPathEffect(makepe(SkScalarToFloat(interp), NULL))->unref(); 146 rastBuilder->addLayer(p); 147#if 0 148 p.setPathEffect(new InverseFillPE())->unref(); 149 p.setXfermodeMode(SkXfermode::kSrcIn_Mode); 150 p.setXfermodeMode(SkXfermode::kClear_Mode); 151 p.setAlpha((1 - interp) * 255); 152 rastBuilder->addLayer(p); 153#endif 154} 155 156typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&); 157 158#include "SkXfermode.h" 159 160static void apply_shader(SkPaint* paint, float scale) 161{ 162 SkPaint p; 163 SkLayerRasterizer::Builder rastBuilder; 164 165 p.setAntiAlias(true); 166 r7(&rastBuilder, p, scale); 167 paint->setRasterizer(rastBuilder.detachRasterizer())->unref(); 168 169 paint->setColor(SK_ColorBLUE); 170} 171 172class ClockFaceView : public SkView { 173 SkTypeface* fFace; 174 SkScalar fInterp; 175 SkScalar fDx; 176 177public: 178 ClockFaceView() { 179 fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb"); 180 fInterp = 0; 181 fDx = SK_Scalar1/64; 182 } 183 184 virtual ~ClockFaceView() { 185 SkSafeUnref(fFace); 186 } 187 188protected: 189 // overrides from SkEventSink 190 virtual bool onQuery(SkEvent* evt) { 191 if (SampleCode::TitleQ(*evt)) { 192 SampleCode::TitleR(evt, "Text Effects"); 193 return true; 194 } 195 return this->INHERITED::onQuery(evt); 196 } 197 198 void drawBG(SkCanvas* canvas) { 199// canvas->drawColor(0xFFDDDDDD); 200 canvas->drawColor(SK_ColorWHITE); 201 } 202 203 static void drawdots(SkCanvas* canvas, const SkPaint& orig) { 204 SkTDArray<SkPoint> pts; 205 SkPathEffect* pe = makepe(0, &pts); 206 207 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); 208 SkPath path, dstPath; 209 orig.getTextPath("9", 1, 0, 0, &path); 210 pe->filterPath(&dstPath, path, &rec, NULL); 211 212 SkPaint p; 213 p.setAntiAlias(true); 214 p.setStrokeWidth(10); 215 p.setColor(SK_ColorRED); 216 canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), 217 p); 218 } 219 220 virtual void onDraw(SkCanvas* canvas) { 221 this->drawBG(canvas); 222 223 SkScalar x = SkIntToScalar(20); 224 SkScalar y = SkIntToScalar(300); 225 SkPaint paint; 226 227 paint.setAntiAlias(true); 228 paint.setTextSize(SkIntToScalar(240)); 229 paint.setTypeface(SkTypeface::CreateFromName("sans-serif", 230 SkTypeface::kBold)); 231 232 SkString str("9"); 233 234 paint.setTypeface(fFace); 235 236 apply_shader(&paint, SkScalarToFloat(fInterp)); 237 canvas->drawText(str.c_str(), str.size(), x, y, paint); 238 239 // drawdots(canvas, paint); 240 241 if (false) { 242 fInterp += fDx; 243 if (fInterp > 1) { 244 fInterp = 1; 245 fDx = -fDx; 246 } else if (fInterp < 0) { 247 fInterp = 0; 248 fDx = -fDx; 249 } 250 this->inval(NULL); 251 } 252 } 253 254private: 255 typedef SkView INHERITED; 256}; 257 258////////////////////////////////////////////////////////////////////////////// 259 260static SkView* MyFactory() { return new ClockFaceView; } 261static SkViewRegister reg(MyFactory); 262