1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkPaintFilterCanvas.h" 9 10 #include "SkPaint.h" 11 #include "SkPixmap.h" 12 #include "SkSurface.h" 13 #include "SkTLazy.h" 14 15 class SkPaintFilterCanvas::AutoPaintFilter { 16 public: 17 AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint* paint) 18 : fPaint(paint) { 19 fShouldDraw = canvas->onFilter(&fPaint, type); 20 } 21 22 AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint& paint) 23 : AutoPaintFilter(canvas, type, &paint) { } 24 25 const SkPaint* paint() const { return fPaint; } 26 27 bool shouldDraw() const { return fShouldDraw; } 28 29 private: 30 SkTCopyOnFirstWrite<SkPaint> fPaint; 31 bool fShouldDraw; 32 }; 33 34 SkPaintFilterCanvas::SkPaintFilterCanvas(SkCanvas *canvas) 35 : INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height()) { 36 37 // Transfer matrix & clip state before adding the target canvas. 38 this->clipRect(SkRect::Make(canvas->getDeviceClipBounds())); 39 this->setMatrix(canvas->getTotalMatrix()); 40 41 this->addCanvas(canvas); 42 } 43 44 void SkPaintFilterCanvas::onDrawPaint(const SkPaint& paint) { 45 AutoPaintFilter apf(this, kPaint_Type, paint); 46 if (apf.shouldDraw()) { 47 this->INHERITED::onDrawPaint(*apf.paint()); 48 } 49 } 50 51 void SkPaintFilterCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 52 const SkPaint& paint) { 53 AutoPaintFilter apf(this, kPoint_Type, paint); 54 if (apf.shouldDraw()) { 55 this->INHERITED::onDrawPoints(mode, count, pts, *apf.paint()); 56 } 57 } 58 59 void SkPaintFilterCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { 60 AutoPaintFilter apf(this, kRect_Type, paint); 61 if (apf.shouldDraw()) { 62 this->INHERITED::onDrawRect(rect, *apf.paint()); 63 } 64 } 65 66 void SkPaintFilterCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 67 AutoPaintFilter apf(this, kRRect_Type, paint); 68 if (apf.shouldDraw()) { 69 this->INHERITED::onDrawRRect(rrect, *apf.paint()); 70 } 71 } 72 73 void SkPaintFilterCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 74 const SkPaint& paint) { 75 AutoPaintFilter apf(this, kDRRect_Type, paint); 76 if (apf.shouldDraw()) { 77 this->INHERITED::onDrawDRRect(outer, inner, *apf.paint()); 78 } 79 } 80 81 void SkPaintFilterCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { 82 AutoPaintFilter apf(this, kOval_Type, paint); 83 if (apf.shouldDraw()) { 84 this->INHERITED::onDrawOval(rect, *apf.paint()); 85 } 86 } 87 88 void SkPaintFilterCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, 89 bool useCenter, const SkPaint& paint) { 90 AutoPaintFilter apf(this, kArc_Type, paint); 91 if (apf.shouldDraw()) { 92 this->INHERITED::onDrawArc(rect, startAngle, sweepAngle, useCenter, *apf.paint()); 93 } 94 } 95 96 void SkPaintFilterCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 97 AutoPaintFilter apf(this, kPath_Type, paint); 98 if (apf.shouldDraw()) { 99 this->INHERITED::onDrawPath(path, *apf.paint()); 100 } 101 } 102 103 void SkPaintFilterCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, 104 const SkPaint* paint) { 105 AutoPaintFilter apf(this, kBitmap_Type, paint); 106 if (apf.shouldDraw()) { 107 this->INHERITED::onDrawBitmap(bm, left, top, apf.paint()); 108 } 109 } 110 111 void SkPaintFilterCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, 112 const SkPaint* paint, SrcRectConstraint constraint) { 113 AutoPaintFilter apf(this, kBitmap_Type, paint); 114 if (apf.shouldDraw()) { 115 this->INHERITED::onDrawBitmapRect(bm, src, dst, apf.paint(), constraint); 116 } 117 } 118 119 void SkPaintFilterCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, 120 const SkRect& dst, const SkPaint* paint) { 121 AutoPaintFilter apf(this, kBitmap_Type, paint); 122 if (apf.shouldDraw()) { 123 this->INHERITED::onDrawBitmapNine(bm, center, dst, apf.paint()); 124 } 125 } 126 127 void SkPaintFilterCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, 128 const SkPaint* paint) { 129 AutoPaintFilter apf(this, kBitmap_Type, paint); 130 if (apf.shouldDraw()) { 131 this->INHERITED::onDrawImage(image, left, top, apf.paint()); 132 } 133 } 134 135 void SkPaintFilterCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, 136 const SkRect& dst, const SkPaint* paint, 137 SrcRectConstraint constraint) { 138 AutoPaintFilter apf(this, kBitmap_Type, paint); 139 if (apf.shouldDraw()) { 140 this->INHERITED::onDrawImageRect(image, src, dst, apf.paint(), constraint); 141 } 142 } 143 144 void SkPaintFilterCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, 145 const SkRect& dst, const SkPaint* paint) { 146 AutoPaintFilter apf(this, kBitmap_Type, paint); 147 if (apf.shouldDraw()) { 148 this->INHERITED::onDrawImageNine(image, center, dst, apf.paint()); 149 } 150 } 151 152 void SkPaintFilterCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 153 const SkPaint& paint) { 154 AutoPaintFilter apf(this, kVertices_Type, paint); 155 if (apf.shouldDraw()) { 156 this->INHERITED::onDrawVerticesObject(vertices, bmode, *apf.paint()); 157 } 158 } 159 160 void SkPaintFilterCanvas::onDrawPatch(const SkPoint cubics[], const SkColor colors[], 161 const SkPoint texCoords[], SkBlendMode bmode, 162 const SkPaint& paint) { 163 AutoPaintFilter apf(this, kPatch_Type, paint); 164 if (apf.shouldDraw()) { 165 this->INHERITED::onDrawPatch(cubics, colors, texCoords, bmode, *apf.paint()); 166 } 167 } 168 169 void SkPaintFilterCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* m, 170 const SkPaint* paint) { 171 AutoPaintFilter apf(this, kPicture_Type, paint); 172 if (apf.shouldDraw()) { 173 this->INHERITED::onDrawPicture(picture, m, apf.paint()); 174 } 175 } 176 177 void SkPaintFilterCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { 178 // There is no paint to filter in this case, but we can still filter on type. 179 // Subclasses need to unroll the drawable explicity (by overriding this method) in 180 // order to actually filter nested content. 181 AutoPaintFilter apf(this, kDrawable_Type, nullptr); 182 if (apf.shouldDraw()) { 183 this->INHERITED::onDrawDrawable(drawable, matrix); 184 } 185 } 186 187 void SkPaintFilterCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 188 const SkPaint& paint) { 189 AutoPaintFilter apf(this, kText_Type, paint); 190 if (apf.shouldDraw()) { 191 this->INHERITED::onDrawText(text, byteLength, x, y, *apf.paint()); 192 } 193 } 194 195 void SkPaintFilterCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 196 const SkPaint& paint) { 197 AutoPaintFilter apf(this, kText_Type, paint); 198 if (apf.shouldDraw()) { 199 this->INHERITED::onDrawPosText(text, byteLength, pos, *apf.paint()); 200 } 201 } 202 203 void SkPaintFilterCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 204 SkScalar constY, const SkPaint& paint) { 205 AutoPaintFilter apf(this, kText_Type, paint); 206 if (apf.shouldDraw()) { 207 this->INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, *apf.paint()); 208 } 209 } 210 211 void SkPaintFilterCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 212 const SkMatrix* matrix, const SkPaint& paint) { 213 AutoPaintFilter apf(this, kText_Type, paint); 214 if (apf.shouldDraw()) { 215 this->INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, *apf.paint()); 216 } 217 } 218 219 void SkPaintFilterCanvas::onDrawTextRSXform(const void* text, size_t byteLength, 220 const SkRSXform xform[], const SkRect* cull, 221 const SkPaint& paint) { 222 AutoPaintFilter apf(this, kText_Type, paint); 223 if (apf.shouldDraw()) { 224 this->INHERITED::onDrawTextRSXform(text, byteLength, xform, cull, *apf.paint()); 225 } 226 } 227 228 void SkPaintFilterCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 229 const SkPaint& paint) { 230 AutoPaintFilter apf(this, kTextBlob_Type, paint); 231 if (apf.shouldDraw()) { 232 this->INHERITED::onDrawTextBlob(blob, x, y, *apf.paint()); 233 } 234 } 235 236 sk_sp<SkSurface> SkPaintFilterCanvas::onNewSurface(const SkImageInfo& info, 237 const SkSurfaceProps& props) { 238 return proxy()->makeSurface(info, &props); 239 } 240 241 bool SkPaintFilterCanvas::onPeekPixels(SkPixmap* pixmap) { 242 return proxy()->peekPixels(pixmap); 243 } 244 245 bool SkPaintFilterCanvas::onAccessTopLayerPixels(SkPixmap* pixmap) { 246 SkImageInfo info; 247 size_t rowBytes; 248 249 void* addr = proxy()->accessTopLayerPixels(&info, &rowBytes); 250 if (!addr) { 251 return false; 252 } 253 254 pixmap->reset(info, addr, rowBytes); 255 return true; 256 } 257 258 SkImageInfo SkPaintFilterCanvas::onImageInfo() const { 259 return proxy()->imageInfo(); 260 } 261 262 bool SkPaintFilterCanvas::onGetProps(SkSurfaceProps* props) const { 263 return proxy()->getProps(props); 264 } 265