ClockFaceView.cpp revision 9797272edfc73f18b4807751377518317991b880
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 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect) 74 75protected: 76 virtual void begin(const SkIRect& uvBounds, SkPath* dst) { 77 if (fPts) { 78 fPts->reset(); 79 } 80 this->INHERITED::begin(uvBounds, dst); 81 } 82// virtual void end(SkPath* dst) {} 83 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) 84 { 85 if (fPts) { 86 *fPts->append() = loc; 87 } 88 dst->addCircle(loc.fX, loc.fY, fRadius); 89 } 90 91 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) 92 { 93 fRadius = buffer.readScalar(); 94 fPts = NULL; 95 } 96 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 97 this->INHERITED::flatten(buffer); 98 buffer.writeScalar(fRadius); 99 } 100 101private: 102 SkScalar fRadius; 103 SkTDArray<SkPoint>* fPts; 104 105 typedef Sk2DPathEffect INHERITED; 106}; 107 108class InverseFillPE : public SkPathEffect { 109public: 110 InverseFillPE() {} 111 virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) SK_OVERRIDE { 112 *dst = src; 113 dst->setFillType(SkPath::kInverseWinding_FillType); 114 return true; 115 } 116 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE) 117 118protected: 119 InverseFillPE(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 120private: 121 122 typedef SkPathEffect INHERITED; 123}; 124 125static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) { 126 SkMatrix lattice; 127 SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp); 128 lattice.setScale(rad*2, rad*2, 0, 0); 129 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 130 return new Dot2DPathEffect(rad, lattice, pts); 131} 132 133static void r7(SkLayerRasterizer* rast, SkPaint& p, SkScalar interp) { 134 p.setPathEffect(makepe(SkScalarToFloat(interp), NULL))->unref(); 135 rast->addLayer(p); 136#if 0 137 p.setPathEffect(new InverseFillPE())->unref(); 138 p.setXfermodeMode(SkXfermode::kSrcIn_Mode); 139 p.setXfermodeMode(SkXfermode::kClear_Mode); 140 p.setAlpha((1 - interp) * 255); 141 rast->addLayer(p); 142#endif 143} 144 145typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&); 146 147#include "SkXfermode.h" 148 149static void apply_shader(SkPaint* paint, float scale) 150{ 151 SkPaint p; 152 SkLayerRasterizer* rast = new SkLayerRasterizer; 153 154 p.setAntiAlias(true); 155 r7(rast, p, SkFloatToScalar(scale)); 156 paint->setRasterizer(rast)->unref(); 157 158 paint->setColor(SK_ColorBLUE); 159} 160 161class ClockFaceView : public SkView { 162 SkTypeface* fFace; 163 SkScalar fInterp; 164 SkScalar fDx; 165public: 166 ClockFaceView() 167 { 168 fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb"); 169 fInterp = 0; 170 fDx = SK_Scalar1/64; 171 } 172 173 virtual ~ClockFaceView() 174 { 175 SkSafeUnref(fFace); 176 } 177 178protected: 179 // overrides from SkEventSink 180 virtual bool onQuery(SkEvent* evt) 181 { 182 if (SampleCode::TitleQ(*evt)) 183 { 184 SampleCode::TitleR(evt, "Text Effects"); 185 return true; 186 } 187 return this->INHERITED::onQuery(evt); 188 } 189 190 void drawBG(SkCanvas* canvas) 191 { 192// canvas->drawColor(0xFFDDDDDD); 193 canvas->drawColor(SK_ColorWHITE); 194 } 195 196 static void drawdots(SkCanvas* canvas, const SkPaint& orig) { 197 SkTDArray<SkPoint> pts; 198 SkPathEffect* pe = makepe(0, &pts); 199 200 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); 201 SkPath path, dstPath; 202 orig.getTextPath("9", 1, 0, 0, &path); 203 pe->filterPath(&dstPath, path, &rec); 204 205 SkPaint p; 206 p.setAntiAlias(true); 207 p.setStrokeWidth(10); 208 p.setColor(SK_ColorRED); 209 canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), 210 p); 211 } 212 213 virtual void onDraw(SkCanvas* canvas) { 214 this->drawBG(canvas); 215 216 SkScalar x = SkIntToScalar(20); 217 SkScalar y = SkIntToScalar(300); 218 SkPaint paint; 219 220 paint.setAntiAlias(true); 221 paint.setTextSize(SkIntToScalar(240)); 222 paint.setTypeface(SkTypeface::CreateFromName("sans-serif", 223 SkTypeface::kBold)); 224 225 SkString str("9"); 226 227 paint.setTypeface(fFace); 228 229 apply_shader(&paint, SkScalarToFloat(fInterp)); 230 canvas->drawText(str.c_str(), str.size(), x, y, paint); 231 232 // drawdots(canvas, paint); 233 234 if (false) { 235 fInterp += fDx; 236 if (fInterp > 1) { 237 fInterp = 1; 238 fDx = -fDx; 239 } else if (fInterp < 0) { 240 fInterp = 0; 241 fDx = -fDx; 242 } 243 this->inval(NULL); 244 } 245 } 246 247private: 248 typedef SkView INHERITED; 249}; 250 251////////////////////////////////////////////////////////////////////////////// 252 253static SkView* MyFactory() { return new ClockFaceView; } 254static SkViewRegister reg(MyFactory); 255 256