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