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 "SkGradientShader.h" 12#include "SkPath.h" 13#include "SkRegion.h" 14#include "SkShader.h" 15#include "SkUtils.h" 16#include "SkColorPriv.h" 17#include "SkColorFilter.h" 18#include "SkTypeface.h" 19#include "SkAvoidXfermode.h" 20 21static inline SkPMColor rgb2gray(SkPMColor c) 22{ 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, SkPMColor result[]) 35 { 36 for (int i = 0; i < count; i++) 37 result[i] = rgb2gray(src[i]); 38 } 39}; 40 41class SkChannelMaskColorFilter : public SkColorFilter { 42public: 43 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) 44 { 45 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask); 46 } 47 48 virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) 49 { 50 SkPMColor mask = fMask; 51 for (int i = 0; i < count; i++) 52 result[i] = src[i] & mask; 53 } 54 55private: 56 SkPMColor fMask; 57}; 58 59/////////////////////////////////////////////////////////// 60 61#include "SkGradientShader.h" 62#include "SkLayerRasterizer.h" 63#include "SkBlurMaskFilter.h" 64 65#include "Sk2DPathEffect.h" 66 67class Dot2DPathEffect : public Sk2DPathEffect { 68public: 69 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix, 70 SkTDArray<SkPoint>* pts) 71 : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {} 72 73 virtual void flatten(SkFlattenableWriteBuffer& buffer) 74 { 75 this->INHERITED::flatten(buffer); 76 77 buffer.writeScalar(fRadius); 78 } 79 virtual Factory getFactory() { return CreateProc; } 80 81protected: 82 virtual void begin(const SkIRect& uvBounds, SkPath* dst) { 83 if (fPts) { 84 fPts->reset(); 85 } 86 this->INHERITED::begin(uvBounds, dst); 87 } 88// virtual void end(SkPath* dst) {} 89 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) 90 { 91 if (fPts) { 92 *fPts->append() = loc; 93 } 94 dst->addCircle(loc.fX, loc.fY, fRadius); 95 } 96 97 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) 98 { 99 fRadius = buffer.readScalar(); 100 fPts = NULL; 101 } 102private: 103 SkScalar fRadius; 104 SkTDArray<SkPoint>* fPts; 105 106 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) 107 { 108 return new Dot2DPathEffect(buffer); 109 } 110 111 typedef Sk2DPathEffect INHERITED; 112}; 113 114class InverseFillPE : public SkPathEffect { 115public: 116 InverseFillPE() {} 117 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { 118 *dst = src; 119 dst->setFillType(SkPath::kInverseWinding_FillType); 120 return true; 121 } 122 virtual Factory getFactory() { return Factory; } 123protected: 124// InverseFillPE(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 125private: 126 static SkFlattenable* Factory(SkFlattenableReadBuffer& buffer) { 127 return new InverseFillPE; 128 } 129 typedef SkPathEffect INHERITED; 130}; 131 132static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) { 133 SkMatrix lattice; 134 SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); 135 lattice.setScale(rad*2, rad*2, 0, 0); 136 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 137 return new Dot2DPathEffect(rad, lattice, pts); 138} 139 140static void r7(SkLayerRasterizer* rast, SkPaint& p, SkScalar interp) { 141 p.setPathEffect(makepe(interp, NULL))->unref(); 142 rast->addLayer(p); 143#if 0 144 p.setPathEffect(new InverseFillPE())->unref(); 145 p.setXfermodeMode(SkXfermode::kSrcIn_Mode); 146 p.setXfermodeMode(SkXfermode::kClear_Mode); 147 p.setAlpha((1 - interp) * 255); 148 rast->addLayer(p); 149#endif 150} 151 152typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&); 153 154#include "SkXfermode.h" 155 156static void apply_shader(SkPaint* paint, float scale) 157{ 158 SkPaint p; 159 SkLayerRasterizer* rast = new SkLayerRasterizer; 160 161 p.setAntiAlias(true); 162 r7(rast, p, scale); 163 paint->setRasterizer(rast)->unref(); 164 165 paint->setColor(SK_ColorBLUE); 166} 167 168class ClockFaceView : public SkView { 169 SkTypeface* fFace; 170 SkScalar fInterp; 171 SkScalar fDx; 172public: 173 ClockFaceView() 174 { 175 fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb"); 176 fInterp = 0; 177 fDx = SK_Scalar1/64; 178 } 179 180 virtual ~ClockFaceView() 181 { 182 SkSafeUnref(fFace); 183 } 184 185protected: 186 // overrides from SkEventSink 187 virtual bool onQuery(SkEvent* evt) 188 { 189 if (SampleCode::TitleQ(*evt)) 190 { 191 SampleCode::TitleR(evt, "Text Effects"); 192 return true; 193 } 194 return this->INHERITED::onQuery(evt); 195 } 196 197 void drawBG(SkCanvas* canvas) 198 { 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 SkScalar width = -1; 208 SkPath path, dstPath; 209 orig.getTextPath("9", 1, 0, 0, &path); 210 pe->filterPath(&dstPath, path, &width); 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, 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 263