Flutter Engine
The Flutter Engine
SkRecordDraw.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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
9
15#include "include/core/SkMesh.h"
18#include "include/core/SkRect.h"
34#include "src/core/SkRecord.h"
35#include "src/core/SkRecords.h"
38
39#include <algorithm>
40#include <optional>
41#include <vector>
42
43class SkImageFilter;
44
45void SkRecordDraw(const SkRecord& record,
46 SkCanvas* canvas,
47 SkPicture const* const drawablePicts[],
48 SkDrawable* const drawables[],
49 int drawableCount,
50 const SkBBoxHierarchy* bbh,
52 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
53
54 if (bbh) {
55 // Draw only ops that affect pixels in the canvas's current clip.
56 // The SkRecord and BBH were recorded in identity space. This canvas
57 // is not necessarily in that same space. getLocalClipBounds() returns us
58 // this canvas' clip bounds transformed back into identity space, which
59 // lets us query the BBH.
60 SkRect query = canvas->getLocalClipBounds();
61
62 std::vector<int> ops;
63 bbh->search(query, &ops);
64
65 SkRecords::Draw draw(canvas, drawablePicts, drawables, drawableCount);
66 for (int i = 0; i < (int)ops.size(); i++) {
67 if (callback && callback->abort()) {
68 return;
69 }
70 // This visit call uses the SkRecords::Draw::operator() to call
71 // methods on the |canvas|, wrapped by methods defined with the
72 // DRAW() macro.
73 record.visit(ops[i], draw);
74 }
75 } else {
76 // Draw all ops.
77 SkRecords::Draw draw(canvas, drawablePicts, drawables, drawableCount);
78 for (int i = 0; i < record.count(); i++) {
79 if (callback && callback->abort()) {
80 return;
81 }
82 // This visit call uses the SkRecords::Draw::operator() to call
83 // methods on the |canvas|, wrapped by methods defined with the
84 // DRAW() macro.
85 record.visit(i, draw);
86 }
87 }
88}
89
90namespace SkRecords {
91
92// NoOps draw nothing.
93template <> void Draw::draw(const NoOp&) {}
94
95#define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; }
96DRAW(Restore, restore())
97DRAW(Save, save())
98DRAW(SaveLayer,
99 saveLayer(SkCanvasPriv::ScaledBackdropLayer(
100 r.bounds,
101 r.paint,
102 r.backdrop.get(),
105 SkCanvas::FilterSpan{const_cast<sk_sp<SkImageFilter>*>(r.filters.data()),
106 r.filters.size()})))
107
108template <> void Draw::draw(const SaveBehind& r) {
109 SkCanvasPriv::SaveBehind(fCanvas, r.subset);
110}
111
112template <> void Draw::draw(const DrawBehind& r) {
113 SkCanvasPriv::DrawBehind(fCanvas, r.paint);
114}
115
116DRAW(SetMatrix, setMatrix(fInitialCTM.asM33() * r.matrix))
117DRAW(SetM44, setMatrix(fInitialCTM * r.matrix))
118DRAW(Concat44, concat(r.matrix))
119DRAW(Concat, concat(r.matrix))
120DRAW(Translate, translate(r.dx, r.dy))
121DRAW(Scale, scale(r.sx, r.sy))
122
123DRAW(ClipPath, clipPath(r.path, r.opAA.op(), r.opAA.aa()))
124DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op(), r.opAA.aa()))
125DRAW(ClipRect, clipRect(r.rect, r.opAA.op(), r.opAA.aa()))
126DRAW(ClipRegion, clipRegion(r.region, r.op))
127DRAW(ClipShader, clipShader(r.shader, r.op))
128
129template <> void Draw::draw(const ResetClip& r) {
131}
132
133DRAW(DrawArc, drawArc(r.oval, r.startAngle, r.sweepAngle, r.useCenter, r.paint))
134DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint))
135DRAW(DrawImage, drawImage(r.image.get(), r.left, r.top, r.sampling, r.paint))
136
137template <> void Draw::draw(const DrawImageLattice& r) {
138 SkCanvas::Lattice lattice;
139 lattice.fXCount = r.xCount;
140 lattice.fXDivs = r.xDivs;
141 lattice.fYCount = r.yCount;
142 lattice.fYDivs = r.yDivs;
143 lattice.fRectTypes = (0 == r.flagCount) ? nullptr : r.flags;
144 lattice.fColors = (0 == r.flagCount) ? nullptr : r.colors;
145 lattice.fBounds = &r.src;
146 fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.filter, r.paint);
147}
148
149DRAW(DrawImageRect, drawImageRect(r.image.get(), r.src, r.dst, r.sampling, r.paint, r.constraint))
150DRAW(DrawOval, drawOval(r.oval, r.paint))
151DRAW(DrawPaint, drawPaint(r.paint))
152DRAW(DrawPath, drawPath(r.path, r.paint))
153DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.bmode, r.paint))
154DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint))
155DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint))
156DRAW(DrawRRect, drawRRect(r.rrect, r.paint))
157DRAW(DrawRect, drawRect(r.rect, r.paint))
158DRAW(DrawRegion, drawRegion(r.region, r.paint))
159DRAW(DrawTextBlob, drawTextBlob(r.blob.get(), r.x, r.y, r.paint))
160DRAW(DrawSlug, drawSlug(r.slug.get(), r.paint))
162 r.cull, r.paint))
163DRAW(DrawVertices, drawVertices(r.vertices, r.bmode, r.paint))
164DRAW(DrawMesh, drawMesh(r.mesh, r.blender, r.paint))
165DRAW(DrawShadowRec, private_draw_shadow_rec(r.path, r.rec))
166DRAW(DrawAnnotation, drawAnnotation(r.rect, r.key.c_str(), r.value.get()))
167
169 r.rect, r.clip, r.aa, r.color, r.mode))
171 r.set.get(), r.count, r.dstClips, r.preViewMatrices, r.sampling, r.paint, r.constraint))
172
173#undef DRAW
174
175template <> void Draw::draw(const DrawDrawable& r) {
176 SkASSERT(r.index >= 0);
177 SkASSERT(r.index < fDrawableCount);
178 if (fDrawables) {
179 SkASSERT(nullptr == fDrawablePicts);
180 fCanvas->drawDrawable(fDrawables[r.index], r.matrix);
181 } else {
182 fCanvas->drawPicture(fDrawablePicts[r.index], r.matrix, nullptr);
183 }
184}
185
186// This is an SkRecord visitor that fills an SkBBoxHierarchy.
187//
188// The interesting part here is how to calculate bounds for ops which don't
189// have intrinsic bounds. What is the bounds of a Save or a Translate?
190//
191// We answer this by thinking about a particular definition of bounds: if I
192// don't execute this op, pixels in this rectangle might draw incorrectly. So
193// the bounds of a Save, a Translate, a Restore, etc. are the union of the
194// bounds of Draw* ops that they might have an effect on. For any given
195// Save/Restore block, the bounds of the Save, the Restore, and any other
196// non-drawing ("control") ops inside are exactly the union of the bounds of
197// the drawing ops inside that block.
198//
199// To implement this, we keep a stack of active Save blocks. As we consume ops
200// inside the Save/Restore block, drawing ops are unioned with the bounds of
201// the block, and control ops are stashed away for later. When we finish the
202// block with a Restore, our bounds are complete, and we go back and fill them
203// in for all the control ops we stashed away.
205public:
206 FillBounds(const SkRect& cullRect, const SkRecord& record,
207 SkRect bounds[], SkBBoxHierarchy::Metadata meta[])
208 : fCullRect(cullRect)
209 , fBounds(bounds)
210 , fMeta(meta) {
211 fCTM = SkMatrix::I();
212
213 // We push an extra save block to track the bounds of any top-level control operations.
214 fSaveStack.push_back({ 0, Bounds::MakeEmpty(), nullptr, fCTM });
215 }
216
218 // If we have any lingering unpaired Saves, simulate restores to make
219 // sure all ops in those Save blocks have their bounds calculated.
220 while (!fSaveStack.empty()) {
221 this->popSaveBlock();
222 }
223
224 // Any control ops not part of any Save/Restore block draw everywhere.
225 while (!fControlIndices.empty()) {
226 this->popControl(fCullRect);
227 }
228 }
229
230 void setCurrentOp(int currentOp) { fCurrentOp = currentOp; }
231
232
233 template <typename T> void operator()(const T& op) {
234 this->updateCTM(op);
235 this->trackBounds(op);
236 }
237
238 // In this file, SkRect are in local coordinates, Bounds are translated back to identity space.
239 typedef SkRect Bounds;
240
241 // Adjust rect for all paints that may affect its geometry, then map it to identity space.
243 // Inverted rectangles really confuse our BBHs.
244 rect.sort();
245
246 // Adjust the rect for its own paint.
247 if (!AdjustForPaint(paint, &rect)) {
248 // The paint could do anything to our bounds. The only safe answer is the cull.
249 return fCullRect;
250 }
251
252 // Adjust rect for all the paints from the SaveLayers we're inside.
253 if (!this->adjustForSaveLayerPaints(&rect)) {
254 // Same deal as above.
255 return fCullRect;
256 }
257
258 // Map the rect back to identity space.
259 fCTM.mapRect(&rect);
260
261 // Nothing can draw outside the cull rect.
262 if (!rect.intersect(fCullRect)) {
263 return Bounds::MakeEmpty();
264 }
265
266 return rect;
267 }
268
269private:
270 struct SaveBounds {
271 int controlOps; // Number of control ops in this Save block, including the Save.
272 Bounds bounds; // Bounds of everything in the block.
273 const SkPaint* paint; // Unowned. If set, adjusts the bounds of all ops in this block.
274 SkMatrix ctm;
275 };
276
277 // Only Restore, SetMatrix, Concat, and Translate change the CTM.
278 template <typename T> void updateCTM(const T&) {}
279 void updateCTM(const Restore& op) { fCTM = op.matrix; }
280 void updateCTM(const SetMatrix& op) { fCTM = op.matrix; }
281 void updateCTM(const SetM44& op) { fCTM = op.matrix.asM33(); }
282 void updateCTM(const Concat44& op) { fCTM.preConcat(op.matrix.asM33()); }
283 void updateCTM(const Concat& op) { fCTM.preConcat(op.matrix); }
284 void updateCTM(const Scale& op) { fCTM.preScale(op.sx, op.sy); }
285 void updateCTM(const Translate& op) { fCTM.preTranslate(op.dx, op.dy); }
286
287 // The bounds of these ops must be calculated when we hit the Restore
288 // from the bounds of the ops in the same Save block.
289 void trackBounds(const Save&) { this->pushSaveBlock(nullptr); }
290 void trackBounds(const SaveLayer& op) { this->pushSaveBlock(op.paint); }
291 void trackBounds(const SaveBehind&) { this->pushSaveBlock(nullptr); }
292 void trackBounds(const Restore&) {
293 const bool isSaveLayer = fSaveStack.back().paint != nullptr;
294 fBounds[fCurrentOp] = this->popSaveBlock();
295 fMeta [fCurrentOp].isDraw = isSaveLayer;
296 }
297
298 void trackBounds(const SetMatrix&) { this->pushControl(); }
299 void trackBounds(const SetM44&) { this->pushControl(); }
300 void trackBounds(const Concat&) { this->pushControl(); }
301 void trackBounds(const Concat44&) { this->pushControl(); }
302 void trackBounds(const Scale&) { this->pushControl(); }
303 void trackBounds(const Translate&) { this->pushControl(); }
304 void trackBounds(const ClipRect&) { this->pushControl(); }
305 void trackBounds(const ClipRRect&) { this->pushControl(); }
306 void trackBounds(const ClipPath&) { this->pushControl(); }
307 void trackBounds(const ClipRegion&) { this->pushControl(); }
308 void trackBounds(const ClipShader&) { this->pushControl(); }
309 void trackBounds(const ResetClip&) { this->pushControl(); }
310
311
312 // For all other ops, we can calculate and store the bounds directly now.
313 template <typename T> void trackBounds(const T& op) {
314 fBounds[fCurrentOp] = this->bounds(op);
315 fMeta [fCurrentOp].isDraw = true;
316 this->updateSaveBounds(fBounds[fCurrentOp]);
317 }
318
319 void pushSaveBlock(const SkPaint* paint) {
320 // Starting a new Save block. Push a new entry to represent that.
321 SaveBounds sb;
322 sb.controlOps = 0;
323 // If the paint affects transparent black,
324 // the bound shouldn't be smaller than the cull.
325 sb.bounds =
326 PaintMayAffectTransparentBlack(paint) ? fCullRect : Bounds::MakeEmpty();
327 sb.paint = paint;
328 sb.ctm = this->fCTM;
329
330 fSaveStack.push_back(sb);
331 this->pushControl();
332 }
333
334 static bool PaintMayAffectTransparentBlack(const SkPaint* paint) {
335 if (paint) {
336 // FIXME: this is very conservative
337 if ((paint->getImageFilter() &&
338 as_IFB(paint->getImageFilter())->affectsTransparentBlack()) ||
339 (paint->getColorFilter() &&
340 as_CFB(paint->getColorFilter())->affectsTransparentBlack())) {
341 return true;
342 }
343 const auto bm = paint->asBlendMode();
344 if (!bm) {
345 return true; // can we query other blenders for this?
346 }
347
348 // Unusual blendmodes require us to process a saved layer
349 // even with operations outisde the clip.
350 // For example, DstIn is used by masking layers.
351 // https://code.google.com/p/skia/issues/detail?id=1291
352 // https://crbug.com/401593
353 switch (bm.value()) {
354 // For each of the following transfer modes, if the source
355 // alpha is zero (our transparent black), the resulting
356 // blended alpha is not necessarily equal to the original
357 // destination alpha.
365 return true;
366 default:
367 break;
368 }
369 }
370 return false;
371 }
372
373 Bounds popSaveBlock() {
374 // We're done the Save block. Apply the block's bounds to all control ops inside it.
375 SaveBounds sb = fSaveStack.back();
376 fSaveStack.pop_back();
377
378 while (sb.controlOps --> 0) {
379 this->popControl(sb.bounds);
380 }
381
382 // This whole Save block may be part another Save block.
383 this->updateSaveBounds(sb.bounds);
384
385 // If called from a real Restore (not a phony one for balance), it'll need the bounds.
386 return sb.bounds;
387 }
388
389 void pushControl() {
390 fControlIndices.push_back(fCurrentOp);
391 if (!fSaveStack.empty()) {
392 fSaveStack.back().controlOps++;
393 }
394 }
395
396 void popControl(const Bounds& bounds) {
397 fBounds[fControlIndices.back()] = bounds;
398 fMeta [fControlIndices.back()].isDraw = false;
399 fControlIndices.pop_back();
400 }
401
402 void updateSaveBounds(const Bounds& bounds) {
403 // If we're in a Save block, expand its bounds to cover these bounds too.
404 if (!fSaveStack.empty()) {
405 fSaveStack.back().bounds.join(bounds);
406 }
407 }
408
409 Bounds bounds(const DrawPaint&) const { return fCullRect; }
410 Bounds bounds(const DrawBehind&) const { return fCullRect; }
411 Bounds bounds(const NoOp&) const { return Bounds::MakeEmpty(); } // NoOps don't draw.
412
413 Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
414 Bounds bounds(const DrawRegion& op) const {
415 SkRect rect = SkRect::Make(op.region.getBounds());
416 return this->adjustAndMap(rect, &op.paint);
417 }
418 Bounds bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); }
419 // Tighter arc bounds?
420 Bounds bounds(const DrawArc& op) const { return this->adjustAndMap(op.oval, &op.paint); }
421 Bounds bounds(const DrawRRect& op) const {
422 return this->adjustAndMap(op.rrect.rect(), &op.paint);
423 }
424 Bounds bounds(const DrawDRRect& op) const {
425 return this->adjustAndMap(op.outer.rect(), &op.paint);
426 }
427 Bounds bounds(const DrawImage& op) const {
428 const SkImage* image = op.image.get();
429 SkRect rect = SkRect::MakeXYWH(op.left, op.top, image->width(), image->height());
430
431 return this->adjustAndMap(rect, op.paint);
432 }
433 Bounds bounds(const DrawImageLattice& op) const {
434 return this->adjustAndMap(op.dst, op.paint);
435 }
436 Bounds bounds(const DrawImageRect& op) const {
437 return this->adjustAndMap(op.dst, op.paint);
438 }
439 Bounds bounds(const DrawPath& op) const {
440 return op.path.isInverseFillType() ? fCullRect
441 : this->adjustAndMap(op.path.getBounds(), &op.paint);
442 }
443 Bounds bounds(const DrawPoints& op) const {
444 SkRect dst;
445 dst.setBounds(op.pts, op.count);
446
447 // Pad the bounding box a little to make sure hairline points' bounds aren't empty.
448 SkScalar stroke = std::max(op.paint.getStrokeWidth(), 0.01f);
449 dst.outset(stroke/2, stroke/2);
450
451 return this->adjustAndMap(dst, &op.paint);
452 }
453 Bounds bounds(const DrawPatch& op) const {
454 SkRect dst;
456 return this->adjustAndMap(dst, &op.paint);
457 }
458 Bounds bounds(const DrawVertices& op) const {
459 return this->adjustAndMap(op.vertices->bounds(), &op.paint);
460 }
461 Bounds bounds(const DrawMesh& op) const {
462 return this->adjustAndMap(op.mesh.bounds(), &op.paint);
463 }
464 Bounds bounds(const DrawAtlas& op) const {
465 if (op.cull) {
466 // TODO: <reed> can we pass nullptr for the paint? Isn't cull already "correct"
467 // for the paint (by the caller)?
468 return this->adjustAndMap(*op.cull, op.paint);
469 } else {
470 return fCullRect;
471 }
472 }
473
474 Bounds bounds(const DrawShadowRec& op) const {
476 SkDrawShadowMetrics::GetLocalBounds(op.path, op.rec, fCTM, &bounds);
477 return this->adjustAndMap(bounds, nullptr);
478 }
479
480 Bounds bounds(const DrawPicture& op) const {
481 SkRect dst = op.picture->cullRect();
482 op.matrix.mapRect(&dst);
483 return this->adjustAndMap(dst, op.paint);
484 }
485
486 Bounds bounds(const DrawTextBlob& op) const {
487 SkRect dst = op.blob->bounds();
488 dst.offset(op.x, op.y);
489 return this->adjustAndMap(dst, &op.paint);
490 }
491
492 Bounds bounds(const DrawSlug& op) const {
493 SkRect dst = op.slug->sourceBoundsWithOrigin();
494 return this->adjustAndMap(dst, &op.paint);
495 }
496
497 Bounds bounds(const DrawDrawable& op) const {
498 return this->adjustAndMap(op.worstCaseBounds, nullptr);
499 }
500
501 Bounds bounds(const DrawAnnotation& op) const {
502 return this->adjustAndMap(op.rect, nullptr);
503 }
504 Bounds bounds(const DrawEdgeAAQuad& op) const {
505 SkRect bounds = op.rect;
506 if (op.clip) {
507 bounds.setBounds(op.clip, 4);
508 }
509 return this->adjustAndMap(bounds, nullptr);
510 }
511 Bounds bounds(const DrawEdgeAAImageSet& op) const {
513 int clipIndex = 0;
514 for (int i = 0; i < op.count; ++i) {
515 SkRect entryBounds = op.set[i].fDstRect;
516 if (op.set[i].fHasClip) {
517 entryBounds.setBounds(op.dstClips + clipIndex, 4);
518 clipIndex += 4;
519 }
520 if (op.set[i].fMatrixIndex >= 0) {
521 op.preViewMatrices[op.set[i].fMatrixIndex].mapRect(&entryBounds);
522 }
523 rect.join(this->adjustAndMap(entryBounds, nullptr));
524 }
525 return rect;
526 }
527
528 // Returns true if rect was meaningfully adjusted for the effects of paint,
529 // false if the paint could affect the rect in unknown ways.
530 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) {
531 if (paint) {
532 if (paint->canComputeFastBounds()) {
533 *rect = paint->computeFastBounds(*rect, rect);
534 return true;
535 }
536 return false;
537 }
538 return true;
539 }
540
541 bool adjustForSaveLayerPaints(SkRect* rect, int savesToIgnore = 0) const {
542 for (int i = fSaveStack.size() - 1 - savesToIgnore; i >= 0; i--) {
543 SkMatrix inverse;
544 if (!fSaveStack[i].ctm.invert(&inverse)) {
545 return false;
546 }
547 inverse.mapRect(rect);
548 if (!AdjustForPaint(fSaveStack[i].paint, rect)) {
549 return false;
550 }
551 fSaveStack[i].ctm.mapRect(rect);
552 }
553 return true;
554 }
555
556 // We do not guarantee anything for operations outside of the cull rect
557 const SkRect fCullRect;
558
559 // Conservative identity-space bounds for each op in the SkRecord.
560 Bounds* fBounds;
561
562 // Parallel array to fBounds, holding metadata for each bounds rect.
564
565 // We walk fCurrentOp through the SkRecord,
566 // as we go using updateCTM() to maintain the exact CTM (fCTM).
567 int fCurrentOp;
568 SkMatrix fCTM;
569
570 // Used to track the bounds of Save/Restore blocks and the control ops inside them.
571 SkTDArray<SaveBounds> fSaveStack;
572 SkTDArray<int> fControlIndices;
573};
574
575} // namespace SkRecords
576
577void SkRecordFillBounds(const SkRect& cullRect, const SkRecord& record,
579 {
580 SkRecords::FillBounds visitor(cullRect, record, bounds, meta);
581 for (int i = 0; i < record.count(); i++) {
582 visitor.setCurrentOp(i);
583 record.visit(i, visitor);
584 }
585 }
586}
SkPathOp ops[]
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kSrcOut
r = s * (1-da)
@ kDstIn
r = d * sa
@ kModulate
r = s*d
@ kDstATop
r = d*sa + s*(1-da)
@ kSrcIn
r = s * da
@ kClear
r = 0
static SkColorFilterBase * as_CFB(SkColorFilter *filter)
static SkImageFilter_Base * as_IFB(SkImageFilter *filter)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
void SkRecordFillBounds(const SkRect &cullRect, const SkRecord &record, SkRect bounds[], SkBBoxHierarchy::Metadata meta[])
void SkRecordDraw(const SkRecord &record, SkCanvas *canvas, SkPicture const *const drawablePicts[], SkDrawable *const drawables[], int drawableCount, const SkBBoxHierarchy *bbh, SkPicture::AbortCallback *callback)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
virtual void search(const SkRect &query, std::vector< int > *results) const =0
static void ResetClip(SkCanvas *canvas)
Definition: SkCanvasPriv.h:61
static void DrawBehind(SkCanvas *canvas, const SkPaint &paint)
Definition: SkCanvasPriv.h:56
static int SaveBehind(SkCanvas *canvas, const SkRect *subset)
Definition: SkCanvasPriv.h:53
SkRect getLocalClipBounds() const
Definition: SkCanvas.cpp:1586
void drawDrawable(SkDrawable *drawable, const SkMatrix *matrix=nullptr)
Definition: SkCanvas.cpp:2574
void drawPicture(const SkPicture *picture)
Definition: SkCanvas.h:1961
bool affectsTransparentBlack() const
bool affectsTransparentBlack() const
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
SkMatrix & preConcat(const SkMatrix &other)
Definition: SkMatrix.cpp:674
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:315
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
auto visit(int i, F &&f) const -> decltype(f(SkRecords::NoOp()))
Definition: SkRecord.h:45
int count() const
Definition: SkRecord.h:38
FillBounds(const SkRect &cullRect, const SkRecord &record, SkRect bounds[], SkBBoxHierarchy::Metadata meta[])
void setCurrentOp(int currentOp)
void operator()(const T &op)
Bounds adjustAndMap(SkRect rect, const SkPaint *paint) const
const T & back() const
Definition: SkTDArray.h:162
int size() const
Definition: SkTDArray.h:138
bool empty() const
Definition: SkTDArray.h:135
void push_back(const T &v)
Definition: SkTDArray.h:219
void pop_back()
Definition: SkTDArray.h:223
T * get() const
Definition: SkRefCnt.h:303
DlColor color
float SkScalar
Definition: extension.cpp:12
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
uint8_t value
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Definition: dart.idl:629
static void drawPath(SkPath &path, SkCanvas *canvas, SkColor color, const SkRect &clip, SkPaint::Cap cap, SkPaint::Join join, SkPaint::Style style, SkPathFillType fill, SkScalar strokeWidth)
Definition: linepaths.cpp:22
double y
double x
void GetLocalBounds(const SkPath &path, const SkDrawShadowRec &rec, const SkMatrix &ctm, SkRect *bounds)
skia_private::AutoTArray< SkCanvas::ImageSetEntry > set
Definition: SkRecords.h:362
DRAW(SaveLayer, saveLayer(SkCanvasPriv::ScaledBackdropLayer(r.bounds, r.paint, r.backdrop.get(), r.backdropScale, r.saveLayerFlags, SkCanvas::FilterSpan{const_cast< sk_sp< SkImageFilter > * >(r.filters.data()), r.filters.size()}))) template<> void Draw
experimental_DrawEdgeAAImageSet(r.set.get(), r.count, r.dstClips, r.preViewMatrices, r.sampling, r.paint, r.constraint)) template<> void Draw
SkBlendMode mode
Definition: SkRecords.h:336
clipRRect(r.rrect, r.opAA.op(), r.opAA.aa())) DRAW(ClipRect
SkCanvas::SaveLayerFlags saveLayerFlags
Definition: SkRecords.h:192
drawTextBlob(r.blob.get(), r.x, r.y, r.paint)) DRAW(DrawSlug
sk_sp< const SkImage > atlas
Definition: SkRecords.h:331
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
drawSlug(r.slug.get(), r.paint)) DRAW(DrawAtlas
Optional< SkRect > bounds
Definition: SkRecords.h:189
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
PODArray< SkRect > texs
Definition: SkRecords.h:333
PODArray< SkPoint > dstClips
Definition: SkRecords.h:364
drawAnnotation(r.rect, r.key.c_str(), r.value.get())) DRAW(DrawEdgeAAQuad
SkScalar backdropScale
Definition: SkRecords.h:193
sk_sp< const SkImage > image
Definition: SkRecords.h:269
int count
Definition: SkRecords.h:335
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
sk_sp< const SkPicture > picture
Definition: SkRecords.h:299
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
sk_sp< const SkImageFilter > backdrop
Definition: SkRecords.h:191
SkRRect rrect
Definition: SkRecords.h:232
SkString key
Definition: SkRecords.h:352
experimental_DrawEdgeAAQuad(r.rect, r.clip, r.aa, r.color, r.mode)) DRAW(DrawEdgeAAImageSet
drawPicture(r.picture.get(), &r.matrix, r.paint)) DRAW(DrawTextBlob
SkRect dst
Definition: SkRecords.h:278
SkRect oval
Definition: SkRecords.h:249
PODArray< SkRSXform > xforms
Definition: SkRecords.h:332
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkMatrix > preViewMatrices
Definition: SkRecords.h:365
drawAtlas(r.atlas.get(), r.xforms, r.texs, r.colors, r.count, r.mode, r.sampling, r.cull, r.paint)) DRAW(DrawAnnotation
SkMesh mesh
Definition: SkRecords.h:345
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkSamplingOptions sampling
Definition: SkRecords.h:337
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
Optional< SkPaint > paint
Definition: SkRecords.h:190
void DrawImage(SkCanvas *canvas, const SkImage *image, SkScalar x, SkScalar y, const SkSamplingOptions &sampling={}, const SkPaint *paint=nullptr, SkCanvas::SrcRectConstraint constraint=SkCanvas::kFast_SrcRectConstraint)
SK_API void DrawImageRect(SkCanvas *canvas, const SkImage *image, const SkRect &src, const SkRect &dst, const SkSamplingOptions &sampling={}, const SkPaint *paint=nullptr, SkCanvas::SrcRectConstraint constraint=SkCanvas::kFast_SrcRectConstraint)
static const char * Concat(const char *a, const char *b)
Definition: file_test.cc:86
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
const myers::Point & get(const myers::Segment &)
skgpu::graphite::DrawAtlas DrawAtlas
#define T
Definition: precompiler.cc:65
const Scalar scale
int fYCount
number of y-coordinates
Definition: SkCanvas.h:1617
const SkIRect * fBounds
source bounds to draw from
Definition: SkCanvas.h:1618
const int * fYDivs
y-axis values dividing bitmap
Definition: SkCanvas.h:1614
int fXCount
number of x-coordinates
Definition: SkCanvas.h:1616
const RectType * fRectTypes
array of fill types
Definition: SkCanvas.h:1615
const SkColor * fColors
array of colors
Definition: SkCanvas.h:1619
const int * fXDivs
x-axis values dividing bitmap
Definition: SkCanvas.h:1613
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
void outset(float dx, float dy)
Definition: SkRect.h:1077
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
void offset(float dx, float dy)
Definition: SkRect.h:1016
void setBounds(const SkPoint pts[], int count)
Definition: SkRect.h:881
void set(const SkIRect &src)
Definition: SkRect.h:849