1 #include "SampleCode.h" 2 #include "SkView.h" 3 #include "SkCanvas.h" 4 #include "SkGradientShader.h" 5 #include "SkPath.h" 6 #include "SkRegion.h" 7 #include "SkShader.h" 8 #include "SkUtils.h" 9 #include "SkColorPriv.h" 10 #include "SkColorFilter.h" 11 #include "SkTypeface.h" 12 #include "SkAvoidXfermode.h" 13 14 static inline SkPMColor rgb2gray(SkPMColor c) { 15 unsigned r = SkGetPackedR32(c); 16 unsigned g = SkGetPackedG32(c); 17 unsigned b = SkGetPackedB32(c); 18 19 unsigned x = (r * 5 + g * 7 + b * 4) >> 4; 20 21 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT)); 22 } 23 24 class SkGrayScaleColorFilter : public SkColorFilter { 25 public: 26 virtual void filterSpan(const SkPMColor src[], int count, 27 SkPMColor result[]) { 28 for (int i = 0; i < count; i++) { 29 result[i] = rgb2gray(src[i]); 30 } 31 } 32 }; 33 34 class SkChannelMaskColorFilter : public SkColorFilter { 35 public: 36 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) { 37 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask); 38 } 39 40 virtual void filterSpan(const SkPMColor src[], int count, 41 SkPMColor result[]) { 42 SkPMColor mask = fMask; 43 for (int i = 0; i < count; i++) { 44 result[i] = src[i] & mask; 45 } 46 } 47 48 private: 49 SkPMColor fMask; 50 }; 51 52 /////////////////////////////////////////////////////////// 53 54 #include "SkGradientShader.h" 55 #include "SkLayerRasterizer.h" 56 #include "SkBlurMaskFilter.h" 57 58 static void r0(SkLayerRasterizer* rast, SkPaint& p) { 59 p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3), 60 SkBlurMaskFilter::kNormal_BlurStyle))->unref(); 61 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3)); 62 63 p.setMaskFilter(NULL); 64 p.setStyle(SkPaint::kStroke_Style); 65 p.setStrokeWidth(SK_Scalar1); 66 rast->addLayer(p); 67 68 p.setAlpha(0x11); 69 p.setStyle(SkPaint::kFill_Style); 70 p.setXfermodeMode(SkXfermode::kSrc_Mode); 71 rast->addLayer(p); 72 } 73 74 static void r1(SkLayerRasterizer* rast, SkPaint& p) { 75 rast->addLayer(p); 76 77 p.setAlpha(0x40); 78 p.setXfermodeMode(SkXfermode::kSrc_Mode); 79 p.setStyle(SkPaint::kStroke_Style); 80 p.setStrokeWidth(SK_Scalar1*2); 81 rast->addLayer(p); 82 } 83 84 static void r2(SkLayerRasterizer* rast, SkPaint& p) { 85 p.setStyle(SkPaint::kStrokeAndFill_Style); 86 p.setStrokeWidth(SK_Scalar1*4); 87 rast->addLayer(p); 88 89 p.setStyle(SkPaint::kStroke_Style); 90 p.setStrokeWidth(SK_Scalar1*3/2); 91 p.setXfermodeMode(SkXfermode::kClear_Mode); 92 rast->addLayer(p); 93 } 94 95 static void r3(SkLayerRasterizer* rast, SkPaint& p) { 96 p.setStyle(SkPaint::kStroke_Style); 97 p.setStrokeWidth(SK_Scalar1*3); 98 rast->addLayer(p); 99 100 p.setAlpha(0x20); 101 p.setStyle(SkPaint::kFill_Style); 102 p.setXfermodeMode(SkXfermode::kSrc_Mode); 103 rast->addLayer(p); 104 } 105 106 static void r4(SkLayerRasterizer* rast, SkPaint& p) { 107 p.setAlpha(0x60); 108 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3)); 109 110 p.setAlpha(0xFF); 111 p.setXfermodeMode(SkXfermode::kClear_Mode); 112 rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2); 113 114 p.setXfermode(NULL); 115 rast->addLayer(p); 116 } 117 118 #include "SkDiscretePathEffect.h" 119 120 static void r5(SkLayerRasterizer* rast, SkPaint& p) { 121 rast->addLayer(p); 122 123 p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref(); 124 p.setXfermodeMode(SkXfermode::kSrcOut_Mode); 125 rast->addLayer(p); 126 } 127 128 static void r6(SkLayerRasterizer* rast, SkPaint& p) { 129 rast->addLayer(p); 130 131 p.setAntiAlias(false); 132 SkLayerRasterizer* rast2 = new SkLayerRasterizer; 133 r5(rast2, p); 134 p.setRasterizer(rast2)->unref(); 135 p.setXfermodeMode(SkXfermode::kClear_Mode); 136 rast->addLayer(p); 137 } 138 139 #include "Sk2DPathEffect.h" 140 141 class Dot2DPathEffect : public Sk2DPathEffect { 142 public: 143 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix) 144 : Sk2DPathEffect(matrix), fRadius(radius) {} 145 146 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 147 this->INHERITED::flatten(buffer); 148 149 buffer.writeScalar(fRadius); 150 } 151 virtual Factory getFactory() { return CreateProc; } 152 153 protected: 154 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) { 155 dst->addCircle(loc.fX, loc.fY, fRadius); 156 } 157 158 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) { 159 fRadius = buffer.readScalar(); 160 } 161 private: 162 SkScalar fRadius; 163 164 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 165 return new Dot2DPathEffect(buffer); 166 } 167 168 typedef Sk2DPathEffect INHERITED; 169 }; 170 171 static void r7(SkLayerRasterizer* rast, SkPaint& p) { 172 SkMatrix lattice; 173 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); 174 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 175 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref(); 176 rast->addLayer(p); 177 } 178 179 static void r8(SkLayerRasterizer* rast, SkPaint& p) { 180 rast->addLayer(p); 181 182 SkMatrix lattice; 183 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); 184 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 185 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref(); 186 p.setXfermodeMode(SkXfermode::kClear_Mode); 187 rast->addLayer(p); 188 189 p.setPathEffect(NULL); 190 p.setXfermode(NULL); 191 p.setStyle(SkPaint::kStroke_Style); 192 p.setStrokeWidth(SK_Scalar1); 193 rast->addLayer(p); 194 } 195 196 class Line2DPathEffect : public Sk2DPathEffect { 197 public: 198 Line2DPathEffect(SkScalar width, const SkMatrix& matrix) 199 : Sk2DPathEffect(matrix), fWidth(width) {} 200 201 virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { 202 if (this->INHERITED::filterPath(dst, src, width)) { 203 *width = fWidth; 204 return true; 205 } 206 return false; 207 } 208 209 virtual Factory getFactory() { return CreateProc; } 210 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 211 this->INHERITED::flatten(buffer); 212 buffer.writeScalar(fWidth); 213 } 214 215 protected: 216 virtual void nextSpan(int u, int v, int ucount, SkPath* dst) { 217 if (ucount > 1) { 218 SkPoint src[2], dstP[2]; 219 220 src[0].set(SkIntToScalar(u) + SK_ScalarHalf, 221 SkIntToScalar(v) + SK_ScalarHalf); 222 src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, 223 SkIntToScalar(v) + SK_ScalarHalf); 224 this->getMatrix().mapPoints(dstP, src, 2); 225 226 dst->moveTo(dstP[0]); 227 dst->lineTo(dstP[1]); 228 } 229 } 230 231 Line2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) { 232 fWidth = buffer.readScalar(); 233 } 234 235 private: 236 SkScalar fWidth; 237 238 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 239 return new Line2DPathEffect(buffer); 240 } 241 242 typedef Sk2DPathEffect INHERITED; 243 }; 244 245 static void r9(SkLayerRasterizer* rast, SkPaint& p) { 246 rast->addLayer(p); 247 248 SkMatrix lattice; 249 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0); 250 lattice.postRotate(SkIntToScalar(30), 0, 0); 251 p.setPathEffect(new Line2DPathEffect(SK_Scalar1*2, lattice))->unref(); 252 p.setXfermodeMode(SkXfermode::kClear_Mode); 253 rast->addLayer(p); 254 255 p.setPathEffect(NULL); 256 p.setXfermode(NULL); 257 p.setStyle(SkPaint::kStroke_Style); 258 p.setStrokeWidth(SK_Scalar1); 259 rast->addLayer(p); 260 } 261 262 typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&); 263 264 static const raster_proc gRastProcs[] = { 265 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 266 }; 267 268 static const struct { 269 SkColor fMul, fAdd; 270 } gLightingColors[] = { 271 { 0x808080, 0x800000 }, // general case 272 { 0x707070, 0x707070 }, // no-pin case 273 { 0xFFFFFF, 0x800000 }, // just-add case 274 { 0x808080, 0x000000 }, // just-mul case 275 { 0xFFFFFF, 0x000000 } // identity case 276 }; 277 278 #include "SkXfermode.h" 279 280 static unsigned color_dist16(uint16_t a, uint16_t b) { 281 unsigned dr = SkAbs32(SkPacked16ToR32(a) - SkPacked16ToR32(b)); 282 unsigned dg = SkAbs32(SkPacked16ToG32(a) - SkPacked16ToG32(b)); 283 unsigned db = SkAbs32(SkPacked16ToB32(a) - SkPacked16ToB32(b)); 284 285 return SkMax32(dr, SkMax32(dg, db)); 286 } 287 288 static unsigned scale_dist(unsigned dist, unsigned scale) { 289 dist >>= 6; 290 dist = (dist << 2) | dist; 291 dist = (dist << 4) | dist; 292 return dist; 293 294 // return SkAlphaMul(dist, scale); 295 } 296 297 static void apply_shader(SkPaint* paint, int index) { 298 raster_proc proc = gRastProcs[index]; 299 if (proc) 300 { 301 SkPaint p; 302 SkLayerRasterizer* rast = new SkLayerRasterizer; 303 304 p.setAntiAlias(true); 305 proc(rast, p); 306 paint->setRasterizer(rast)->unref(); 307 } 308 309 #if 0 310 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 }; 311 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref(); 312 #endif 313 paint->setColor(SK_ColorBLUE); 314 } 315 316 static int gRastIndex; 317 318 class TextEffectView : public SampleView { 319 SkTypeface* fFace; 320 public: 321 TextEffectView() { 322 fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb"); 323 } 324 325 virtual ~TextEffectView() { 326 SkSafeUnref(fFace); 327 } 328 329 protected: 330 // overrides from SkEventSink 331 virtual bool onQuery(SkEvent* evt) { 332 if (SampleCode::TitleQ(*evt)) { 333 SampleCode::TitleR(evt, "Text Effects"); 334 return true; 335 } 336 return this->INHERITED::onQuery(evt); 337 } 338 339 virtual void onDrawContent(SkCanvas* canvas) { 340 canvas->save(); 341 // canvas->scale(SK_Scalar1*2, SK_Scalar1*2, 0, 0); 342 343 SkPaint paint; 344 345 paint.setAntiAlias(true); 346 paint.setTextSize(SkIntToScalar(56)); 347 paint.setTypeface(SkTypeface::CreateFromName("sans-serif", 348 SkTypeface::kBold)); 349 350 SkScalar x = SkIntToScalar(20); 351 SkScalar y = paint.getTextSize(); 352 353 SkString str("TextEffects"); 354 355 paint.setTypeface(fFace); 356 357 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) { 358 apply_shader(&paint, i); 359 360 // paint.setMaskFilter(NULL); 361 // paint.setColor(SK_ColorBLACK); 362 363 #if 1 364 int index = i % SK_ARRAY_COUNT(gLightingColors); 365 paint.setColorFilter(SkColorFilter::CreateLightingFilter( 366 gLightingColors[index].fMul, 367 gLightingColors[index].fAdd))->unref(); 368 #endif 369 370 canvas->drawText(str.c_str(), str.size(), x, y, paint); 371 372 y += paint.getFontSpacing(); 373 } 374 375 canvas->restore(); 376 } 377 378 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 379 gRastIndex = (gRastIndex + 1) % SK_ARRAY_COUNT(gRastProcs); 380 this->inval(NULL); 381 382 return this->INHERITED::onFindClickHandler(x, y); 383 } 384 385 virtual bool onClick(Click* click) { 386 return this->INHERITED::onClick(click); 387 } 388 389 private: 390 typedef SampleView INHERITED; 391 }; 392 393 ////////////////////////////////////////////////////////////////////////////// 394 395 static SkView* MyFactory() { return new TextEffectView; } 396 static SkViewRegister reg(MyFactory); 397 398