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