Home | History | Annotate | Download | only in utils
      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