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