• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 "include/core/SkOverdrawCanvas.h"
9 
10 #include "include/core/SkColorFilter.h"
11 #include "include/core/SkDrawable.h"
12 #include "include/core/SkPath.h"
13 #include "include/core/SkRRect.h"
14 #include "include/core/SkRSXform.h"
15 #include "include/core/SkTextBlob.h"
16 #include "include/private/SkTo.h"
17 #include "src/core/SkDevice.h"
18 #include "src/core/SkDrawShadowInfo.h"
19 #include "src/core/SkGlyphRunPainter.h"
20 #include "src/core/SkImagePriv.h"
21 #include "src/core/SkLatticeIter.h"
22 #include "src/core/SkStrikeCache.h"
23 #include "src/core/SkTextBlobPriv.h"
24 #include "src/utils/SkPatchUtils.h"
25 
SkOverdrawCanvas(SkCanvas * canvas)26 SkOverdrawCanvas::SkOverdrawCanvas(SkCanvas* canvas)
27     : INHERITED(canvas->onImageInfo().width(), canvas->onImageInfo().height())
28 {
29     // Non-drawing calls that SkOverdrawCanvas does not override (translate, save, etc.)
30     // will pass through to the input canvas.
31     this->addCanvas(canvas);
32 
33     static constexpr float kIncrementAlpha[] = {
34             0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
35             0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
36             0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
37             0.0f, 0.0f, 0.0f, 0.0f, 1.0f/255,
38     };
39 
40     fPaint.setAntiAlias(false);
41     fPaint.setBlendMode(SkBlendMode::kPlus);
42     fPaint.setColorFilter(SkColorFilters::Matrix(kIncrementAlpha));
43 }
44 
45 namespace {
46 class TextDevice : public SkNoPixelsDevice, public SkGlyphRunListPainter::BitmapDevicePainter {
47 public:
TextDevice(SkCanvas * overdrawCanvas,const SkSurfaceProps & props)48     TextDevice(SkCanvas* overdrawCanvas, const SkSurfaceProps& props)
49             : SkNoPixelsDevice{SkIRect::MakeWH(32767, 32767), props},
50               fOverdrawCanvas{overdrawCanvas},
51               fPainter{props, kN32_SkColorType, nullptr, SkStrikeCache::GlobalStrikeCache()} {}
52 
paintPaths(SkSpan<const SkPathPos> pathsAndPositions,SkScalar scale,const SkPaint & paint) const53     void paintPaths(SkSpan<const SkPathPos> pathsAndPositions, SkScalar scale,
54                     const SkPaint& paint) const override {}
55 
paintMasks(SkSpan<const SkMask> masks,const SkPaint & paint) const56     void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const override {
57         for (auto& mask : masks) {
58             fOverdrawCanvas->drawRect(SkRect::Make(mask.fBounds), SkPaint());
59         }
60     }
61 
62 protected:
drawGlyphRunList(const SkGlyphRunList & glyphRunList)63     void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override {
64         fPainter.drawForBitmapDevice(glyphRunList, fOverdrawCanvas->getTotalMatrix(), this);
65     }
66 
67 private:
68     SkCanvas* const fOverdrawCanvas;
69     SkGlyphRunListPainter fPainter;
70 };
71 }  // namespace
72 
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)73 void SkOverdrawCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
74                                       const SkPaint& paint) {
75     SkGlyphRunBuilder b;
76     SkSurfaceProps props{0, kUnknown_SkPixelGeometry};
77     this->getProps(&props);
78     TextDevice device{this, props};
79 
80     b.drawTextBlob(paint, *blob, {x, y}, &device);
81 }
82 
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode blendMode,const SkPaint &)83 void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
84                                    const SkPoint texCoords[4], SkBlendMode blendMode,
85                                    const SkPaint&) {
86     fList[0]->onDrawPatch(cubics, colors, texCoords, blendMode, fPaint);
87 }
88 
onDrawPaint(const SkPaint & paint)89 void SkOverdrawCanvas::onDrawPaint(const SkPaint& paint) {
90     if (0 == paint.getColor() && !paint.getColorFilter() && !paint.getShader()) {
91         // This is a clear, ignore it.
92     } else {
93         fList[0]->onDrawPaint(this->overdrawPaint(paint));
94     }
95 }
96 
onDrawBehind(const SkPaint & paint)97 void SkOverdrawCanvas::onDrawBehind(const SkPaint& paint) {
98     fList[0]->onDrawBehind(this->overdrawPaint(paint));
99 }
100 
onDrawRect(const SkRect & rect,const SkPaint & paint)101 void SkOverdrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
102     fList[0]->onDrawRect(rect, this->overdrawPaint(paint));
103 }
104 
onDrawRegion(const SkRegion & region,const SkPaint & paint)105 void SkOverdrawCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
106     fList[0]->onDrawRegion(region, this->overdrawPaint(paint));
107 }
108 
onDrawOval(const SkRect & oval,const SkPaint & paint)109 void SkOverdrawCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
110     fList[0]->onDrawOval(oval, this->overdrawPaint(paint));
111 }
112 
onDrawArc(const SkRect & arc,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)113 void SkOverdrawCanvas::onDrawArc(const SkRect& arc, SkScalar startAngle, SkScalar sweepAngle,
114                                  bool useCenter, const SkPaint& paint) {
115     fList[0]->onDrawArc(arc, startAngle, sweepAngle, useCenter, this->overdrawPaint(paint));
116 }
117 
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)118 void SkOverdrawCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
119                                     const SkPaint& paint) {
120     fList[0]->onDrawDRRect(outer, inner, this->overdrawPaint(paint));
121 }
122 
onDrawRRect(const SkRRect & rect,const SkPaint & paint)123 void SkOverdrawCanvas::onDrawRRect(const SkRRect& rect, const SkPaint& paint) {
124     fList[0]->onDrawRRect(rect, this->overdrawPaint(paint));
125 }
126 
onDrawPoints(PointMode mode,size_t count,const SkPoint points[],const SkPaint & paint)127 void SkOverdrawCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint points[],
128                                     const SkPaint& paint) {
129     fList[0]->onDrawPoints(mode, count, points, this->overdrawPaint(paint));
130 }
131 
onDrawVerticesObject(const SkVertices * vertices,const SkVertices::Bone bones[],int boneCount,SkBlendMode blendMode,const SkPaint & paint)132 void SkOverdrawCanvas::onDrawVerticesObject(const SkVertices* vertices,
133                                             const SkVertices::Bone bones[], int boneCount,
134                                             SkBlendMode blendMode, const SkPaint& paint) {
135     fList[0]->onDrawVerticesObject(vertices,
136                                    bones,
137                                    boneCount,
138                                    blendMode,
139                                    this->overdrawPaint(paint));
140 }
141 
onDrawAtlas(const SkImage * image,const SkRSXform xform[],const SkRect texs[],const SkColor colors[],int count,SkBlendMode mode,const SkRect * cull,const SkPaint * paint)142 void SkOverdrawCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[],
143                                    const SkRect texs[], const SkColor colors[], int count,
144                                    SkBlendMode mode, const SkRect* cull, const SkPaint* paint) {
145     SkPaint* paintPtr = &fPaint;
146     SkPaint storage;
147     if (paint) {
148         storage = this->overdrawPaint(*paint);
149         paintPtr = &storage;
150     }
151 
152     fList[0]->onDrawAtlas(image, xform, texs, colors, count, mode, cull, paintPtr);
153 }
154 
onDrawPath(const SkPath & path,const SkPaint & paint)155 void SkOverdrawCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
156     fList[0]->onDrawPath(path, fPaint);
157 }
158 
onDrawImage(const SkImage * image,SkScalar x,SkScalar y,const SkPaint *)159 void SkOverdrawCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint*) {
160     fList[0]->onDrawRect(SkRect::MakeXYWH(x, y, image->width(), image->height()), fPaint);
161 }
162 
onDrawImageRect(const SkImage * image,const SkRect * src,const SkRect & dst,const SkPaint *,SrcRectConstraint)163 void SkOverdrawCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
164                                        const SkPaint*, SrcRectConstraint) {
165     fList[0]->onDrawRect(dst, fPaint);
166 }
167 
onDrawImageNine(const SkImage *,const SkIRect &,const SkRect & dst,const SkPaint *)168 void SkOverdrawCanvas::onDrawImageNine(const SkImage*, const SkIRect&, const SkRect& dst,
169                                        const SkPaint*) {
170     fList[0]->onDrawRect(dst, fPaint);
171 }
172 
onDrawImageLattice(const SkImage * image,const Lattice & lattice,const SkRect & dst,const SkPaint *)173 void SkOverdrawCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
174                                           const SkRect& dst, const SkPaint*) {
175     SkIRect bounds;
176     Lattice latticePlusBounds = lattice;
177     if (!latticePlusBounds.fBounds) {
178         bounds = SkIRect::MakeWH(image->width(), image->height());
179         latticePlusBounds.fBounds = &bounds;
180     }
181 
182     if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
183         SkLatticeIter iter(latticePlusBounds, dst);
184 
185         SkRect dummy, iterDst;
186         while (iter.next(&dummy, &iterDst)) {
187             fList[0]->onDrawRect(iterDst, fPaint);
188         }
189     } else {
190         fList[0]->onDrawRect(dst, fPaint);
191     }
192 }
193 
onDrawBitmap(const SkBitmap & bitmap,SkScalar x,SkScalar y,const SkPaint *)194 void SkOverdrawCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
195                                     const SkPaint*) {
196     fList[0]->onDrawRect(SkRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()), fPaint);
197 }
198 
onDrawBitmapRect(const SkBitmap &,const SkRect *,const SkRect & dst,const SkPaint *,SrcRectConstraint)199 void SkOverdrawCanvas::onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect& dst,
200                                         const SkPaint*, SrcRectConstraint) {
201     fList[0]->onDrawRect(dst, fPaint);
202 }
203 
onDrawBitmapNine(const SkBitmap &,const SkIRect &,const SkRect & dst,const SkPaint *)204 void SkOverdrawCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect& dst,
205                                         const SkPaint*) {
206     fList[0]->onDrawRect(dst, fPaint);
207 }
208 
onDrawBitmapLattice(const SkBitmap & bitmap,const Lattice & lattice,const SkRect & dst,const SkPaint * paint)209 void SkOverdrawCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
210                                            const SkRect& dst, const SkPaint* paint) {
211     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
212     this->onDrawImageLattice(image.get(), lattice, dst, paint);
213 }
214 
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)215 void SkOverdrawCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
216     drawable->draw(this, matrix);
217 }
218 
onDrawPicture(const SkPicture *,const SkMatrix *,const SkPaint *)219 void SkOverdrawCanvas::onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) {
220     SkASSERT(false);
221     return;
222 }
223 
onDrawAnnotation(const SkRect &,const char[],SkData *)224 void SkOverdrawCanvas::onDrawAnnotation(const SkRect&, const char[], SkData*) {}
225 
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rec)226 void SkOverdrawCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
227     SkRect bounds;
228     SkDrawShadowMetrics::GetLocalBounds(path, rec, this->getTotalMatrix(), &bounds);
229     fList[0]->onDrawRect(bounds, fPaint);
230 }
231 
onDrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aa,SkColor color,SkBlendMode mode)232 void SkOverdrawCanvas::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
233                                         QuadAAFlags aa, SkColor color, SkBlendMode mode) {
234     if (clip) {
235         SkPath path;
236         path.addPoly(clip, 4, true);
237         fList[0]->onDrawPath(path, fPaint);
238     } else {
239         fList[0]->onDrawRect(rect, fPaint);
240     }
241 }
242 
onDrawEdgeAAImageSet(const ImageSetEntry set[],int count,const SkPoint dstClips[],const SkMatrix preViewMatrices[],const SkPaint * paint,SrcRectConstraint constraint)243 void SkOverdrawCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[], int count,
244                                             const SkPoint dstClips[],
245                                             const SkMatrix preViewMatrices[], const SkPaint* paint,
246                                             SrcRectConstraint constraint) {
247     int clipIndex = 0;
248     for (int i = 0; i < count; ++i) {
249         if (set[i].fMatrixIndex >= 0) {
250             fList[0]->save();
251             fList[0]->concat(preViewMatrices[set[i].fMatrixIndex]);
252         }
253         if (set[i].fHasClip) {
254             SkPath path;
255             path.addPoly(dstClips + clipIndex, 4, true);
256             clipIndex += 4;
257             fList[0]->onDrawPath(path, fPaint);
258         } else {
259             fList[0]->onDrawRect(set[i].fDstRect, fPaint);
260         }
261         if (set[i].fMatrixIndex >= 0) {
262             fList[0]->restore();
263         }
264     }
265 }
266 
overdrawPaint(const SkPaint & paint)267 inline SkPaint SkOverdrawCanvas::overdrawPaint(const SkPaint& paint) {
268     SkPaint newPaint = fPaint;
269     newPaint.setStyle(paint.getStyle());
270     newPaint.setStrokeWidth(paint.getStrokeWidth());
271     return newPaint;
272 }
273