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