Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | List of all members
SkDrawBase Class Reference

#include <SkDrawBase.h>

Inheritance diagram for SkDrawBase:
SkGlyphRunListPainterCPU::BitmapDevicePainter SkDraw SkBitmapDevice::BDDraw

Public Types

enum  RectType { kHair_RectType , kFill_RectType , kStroke_RectType , kPath_RectType }
 
using BlitterChooser = SkBlitter *(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &, SkArenaAlloc *, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &)
 

Public Member Functions

 SkDrawBase ()
 
void drawPaint (const SkPaint &) const
 
void drawRect (const SkRect &prePaintRect, const SkPaint &, const SkMatrix *paintMatrix, const SkRect *postPaintRect) const
 
void drawRect (const SkRect &rect, const SkPaint &paint) const
 
void drawRRect (const SkRRect &, const SkPaint &) const
 
void drawPath (const SkPath &path, const SkPaint &paint, const SkMatrix *prePathMatrix=nullptr, bool pathIsMutable=false) const
 
void drawPathCoverage (const SkPath &src, const SkPaint &paint, SkBlitter *customBlitter=nullptr) const
 
void drawDevicePoints (SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint &, SkDevice *) const
 
void validate () const
 
- Public Member Functions inherited from SkGlyphRunListPainterCPU::BitmapDevicePainter
 BitmapDevicePainter ()=default
 
 BitmapDevicePainter (const BitmapDevicePainter &)=default
 
virtual ~BitmapDevicePainter ()=default
 

Static Public Member Functions

static bool ComputeMaskBounds (const SkRect &devPathBounds, const SkIRect &clipBounds, const SkMaskFilter *filter, const SkMatrix *filterMatrix, SkIRect *bounds)
 
static bool DrawToMask (const SkPath &devPath, const SkIRect &clipBounds, const SkMaskFilter *, const SkMatrix *filterMatrix, SkMaskBuilder *dst, SkMaskBuilder::CreateMode mode, SkStrokeRec::InitStyle style)
 
static RectType ComputeRectType (const SkRect &, const SkPaint &, const SkMatrix &, SkPoint *strokeSize)
 

Public Attributes

SkPixmap fDst
 
BlitterChooserfBlitterChooser {nullptr}
 
const SkMatrixfCTM {nullptr}
 
const SkRasterClipfRC {nullptr}
 
const SkSurfacePropsfProps {nullptr}
 

Private Member Functions

void paintMasks (SkZip< const SkGlyph *, SkPoint > accepted, const SkPaint &paint) const override
 
void drawBitmap (const SkBitmap &, const SkMatrix &, const SkRect *dstOrNull, const SkSamplingOptions &, const SkPaint &) const override
 

Detailed Description

Definition at line 38 of file SkDrawBase.h.

Member Typedef Documentation

◆ BlitterChooser

using SkDrawBase::BlitterChooser = SkBlitter* (const SkPixmap& dst, const SkMatrix& ctm, const SkPaint&, SkArenaAlloc*, bool drawCoverage, sk_sp<SkShader> clipShader, const SkSurfaceProps&)

Definition at line 111 of file SkDrawBase.h.

Member Enumeration Documentation

◆ RectType

Enumerator
kHair_RectType 
kFill_RectType 
kStroke_RectType 
kPath_RectType 

Definition at line 93 of file SkDrawBase.h.

Constructor & Destructor Documentation

◆ SkDrawBase()

SkDrawBase::SkDrawBase ( )

Definition at line 53 of file SkDrawBase.cpp.

53{}

Member Function Documentation

◆ ComputeMaskBounds()

bool SkDrawBase::ComputeMaskBounds ( const SkRect devPathBounds,
const SkIRect clipBounds,
const SkMaskFilter filter,
const SkMatrix filterMatrix,
SkIRect bounds 
)
static

Definition at line 494 of file SkDrawBase.cpp.

496 {
497 // init our bounds from the path
499
500 SkIPoint margin = SkIPoint::Make(0, 0);
501 if (filter) {
502 SkASSERT(filterMatrix);
503
504 SkMask srcM(nullptr, *bounds, 0, SkMask::kA8_Format);
505 SkMaskBuilder dstM;
506 if (!as_MFB(filter)->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
507 return false;
508 }
509 }
510
511 // trim the bounds to reflect the clip (plus whatever slop the filter needs)
512 // Ugh. Guard against gigantic margins from wacky filters. Without this
513 // check we can request arbitrary amounts of slop beyond our visible
514 // clip, and bring down the renderer (at least on finite RAM machines
515 // like handsets, etc.). Need to balance this invented value between
516 // quality of large filters like blurs, and the corresponding memory
517 // requests.
518 static constexpr int kMaxMargin = 128;
519 if (!bounds->intersect(clipBounds.makeOutset(std::min(margin.fX, kMaxMargin),
520 std::min(margin.fY, kMaxMargin)))) {
521 return false;
522 }
523
524 return true;
525}
#define SkASSERT(cond)
Definition SkAssert.h:116
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
#define SK_ScalarHalf
Definition SkScalar.h:19
Optional< SkRect > bounds
Definition SkRecords.h:189
int32_t fX
x-axis value
int32_t fY
y-axis value
static constexpr SkIPoint Make(int32_t x, int32_t y)
SkIRect makeOutset(int32_t dx, int32_t dy) const
Definition SkRect.h:350
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28
SkRect makeOutset(float dx, float dy) const
Definition SkRect.h:1002
void roundOut(SkIRect *dst) const
Definition SkRect.h:1241

◆ ComputeRectType()

SkDrawBase::RectType SkDrawBase::ComputeRectType ( const SkRect rect,
const SkPaint paint,
const SkMatrix matrix,
SkPoint strokeSize 
)
static

Based on the paint's style, strokeWidth, and the matrix, classify how to draw the rect. If no special-case is available, returns kPath_RectType.

Iff RectType == kStroke_RectType, then strokeSize is set to the device width and height of the stroke.

Definition at line 111 of file SkDrawBase.cpp.

114 {
115 RectType rtype;
116 const SkScalar width = paint.getStrokeWidth();
117 const bool zeroWidth = (0 == width);
118 SkPaint::Style style = paint.getStyle();
119
120 if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
121 style = SkPaint::kFill_Style;
122 }
123
124 if (paint.getPathEffect() || paint.getMaskFilter() ||
125 !matrix.rectStaysRect() || SkPaint::kStrokeAndFill_Style == style) {
126 rtype = kPath_RectType;
127 } else if (SkPaint::kFill_Style == style) {
128 rtype = kFill_RectType;
129 } else if (zeroWidth) {
130 rtype = kHair_RectType;
131 } else if (easy_rect_join(rect, paint, matrix, strokeSize)) {
132 rtype = kStroke_RectType;
133 } else {
134 rtype = kPath_RectType;
135 }
136 return rtype;
137}
static bool easy_rect_join(const SkRect &rect, const SkPaint &paint, const SkMatrix &matrix, SkPoint *strokeSize)
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition SkPaint.h:195
const Paint & paint
float SkScalar
Definition extension.cpp:12
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
int32_t width

◆ drawBitmap()

void SkDrawBase::drawBitmap ( const SkBitmap ,
const SkMatrix ,
const SkRect dstOrNull,
const SkSamplingOptions ,
const SkPaint  
) const
overrideprivatevirtual

Implements SkGlyphRunListPainterCPU::BitmapDevicePainter.

Definition at line 470 of file SkDrawBase.cpp.

471 {
472 SkASSERT(false);
473}

◆ drawDevicePoints()

void SkDrawBase::drawDevicePoints ( SkCanvas::PointMode  mode,
size_t  count,
const SkPoint  pts[],
const SkPaint paint,
SkDevice device 
) const

Definition at line 597 of file SkDrawBase.cpp.

599 {
600 // if we're in lines mode, force count to be even
601 if (SkCanvas::kLines_PointMode == mode) {
602 count &= ~(size_t)1;
603 }
604
605 SkASSERT(pts != nullptr);
606 SkDEBUGCODE(this->validate();)
607
608 // nothing to draw
609 if (!count || fRC->isEmpty()) {
610 return;
611 }
612
613 // needed?
614 if (!SkIsFinite(&pts[0].fX, count * 2)) {
615 return;
616 }
617
618 switch (mode) {
620 // temporarily mark the paint as filling.
621 SkPaint newPaint(paint);
622 newPaint.setStyle(SkPaint::kFill_Style);
623
624 SkScalar width = newPaint.getStrokeWidth();
625 SkScalar radius = SkScalarHalf(width);
626
627 if (newPaint.getStrokeCap() == SkPaint::kRound_Cap) {
628 if (device) {
629 for (size_t i = 0; i < count; ++i) {
630 SkRect r = SkRect::MakeLTRB(pts[i].fX - radius, pts[i].fY - radius,
631 pts[i].fX + radius, pts[i].fY + radius);
632 device->drawOval(r, newPaint);
633 }
634 } else {
635 SkPath path;
636 SkMatrix preMatrix;
637
638 path.addCircle(0, 0, radius);
639 for (size_t i = 0; i < count; i++) {
640 preMatrix.setTranslate(pts[i].fX, pts[i].fY);
641 // pass true for the last point, since we can modify
642 // then path then
643 path.setIsVolatile((count-1) == i);
644 this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
645 }
646 }
647 } else {
648 SkRect r;
649
650 for (size_t i = 0; i < count; i++) {
651 r.fLeft = pts[i].fX - radius;
652 r.fTop = pts[i].fY - radius;
653 r.fRight = r.fLeft + width;
654 r.fBottom = r.fTop + width;
655 if (device) {
656 device->drawRect(r, newPaint);
657 } else {
658 this->drawRect(r, newPaint);
659 }
660 }
661 }
662 break;
663 }
665 if (2 == count && paint.getPathEffect()) {
666 // most likely a dashed line - see if it is one of the ones
667 // we can accelerate
668 SkStrokeRec stroke(paint);
670
671 SkPath path = SkPath::Line(pts[0], pts[1]);
672
673 SkRect cullRect = SkRect::Make(fRC->getBounds());
674
675 if (as_PEB(paint.getPathEffect())->asPoints(&pointData, path, stroke, *fCTM,
676 &cullRect)) {
677 // 'asPoints' managed to find some fast path
678
679 SkPaint newP(paint);
680 newP.setPathEffect(nullptr);
681 newP.setStyle(SkPaint::kFill_Style);
682
683 if (!pointData.fFirst.isEmpty()) {
684 if (device) {
685 device->drawPath(pointData.fFirst, newP);
686 } else {
687 this->drawPath(pointData.fFirst, newP);
688 }
689 }
690
691 if (!pointData.fLast.isEmpty()) {
692 if (device) {
693 device->drawPath(pointData.fLast, newP);
694 } else {
695 this->drawPath(pointData.fLast, newP);
696 }
697 }
698
699 if (pointData.fSize.fX == pointData.fSize.fY) {
700 // The rest of the dashed line can just be drawn as points
701 SkASSERT(pointData.fSize.fX == SkScalarHalf(newP.getStrokeWidth()));
702
704 newP.setStrokeCap(SkPaint::kRound_Cap);
705 } else {
706 newP.setStrokeCap(SkPaint::kButt_Cap);
707 }
708
709 if (device) {
711 pointData.fNumPoints,
712 pointData.fPoints,
713 newP);
714 } else {
716 pointData.fNumPoints,
717 pointData.fPoints,
718 newP,
719 device);
720 }
721 break;
722 } else {
723 // The rest of the dashed line must be drawn as rects
725 pointData.fFlags));
726
727 SkRect r;
728
729 for (int i = 0; i < pointData.fNumPoints; ++i) {
730 r.setLTRB(pointData.fPoints[i].fX - pointData.fSize.fX,
731 pointData.fPoints[i].fY - pointData.fSize.fY,
732 pointData.fPoints[i].fX + pointData.fSize.fX,
733 pointData.fPoints[i].fY + pointData.fSize.fY);
734 if (device) {
735 device->drawRect(r, newP);
736 } else {
737 this->drawRect(r, newP);
738 }
739 }
740 }
741
742 break;
743 }
744 }
745 [[fallthrough]]; // couldn't take fast path
747 count -= 1;
748 SkPath path;
749 SkPaint p(paint);
750 p.setStyle(SkPaint::kStroke_Style);
751 size_t inc = (SkCanvas::kLines_PointMode == mode) ? 2 : 1;
752 path.setIsVolatile(true);
753 for (size_t i = 0; i < count; i += inc) {
754 path.moveTo(pts[i]);
755 path.lineTo(pts[i+1]);
756 if (device) {
757 device->drawPath(path, p, true);
758 } else {
759 this->drawPath(path, p, nullptr, true);
760 }
761 path.rewind();
762 }
763 break;
764 }
765 }
766}
int count
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static bool SkIsFinite(T x, Pack... values)
static SkPathEffectBase * as_PEB(SkPathEffect *effect)
#define SkScalarHalf(a)
Definition SkScalar.h:75
@ kLines_PointMode
draw each pair of points as a line segment
Definition SkCanvas.h:1242
@ kPolygon_PointMode
draw the array of points as a open polygon
Definition SkCanvas.h:1243
@ kPoints_PointMode
draw each point separately
Definition SkCanvas.h:1241
void drawPath(const SkPath &path, const SkPaint &paint, const SkMatrix *prePathMatrix=nullptr, bool pathIsMutable=false) const
Definition SkDrawBase.h:58
const SkRasterClip * fRC
Definition SkDrawBase.h:154
void drawRect(const SkRect &prePaintRect, const SkPaint &, const SkMatrix *paintMatrix, const SkRect *postPaintRect) const
void validate() const
Definition SkDrawBase.h:160
const SkMatrix * fCTM
Definition SkDrawBase.h:153
void drawDevicePoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint &, SkDevice *) const
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:254
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
bool asPoints(PointData *results, const SkPath &src, const SkStrokeRec &, const SkMatrix &, const SkRect *cullR) const
bool isEmpty() const
Definition SkPath.cpp:406
static SkPath Line(const SkPoint a, const SkPoint b)
Definition SkPath.h:106
const SkIRect & getBounds() const
bool isEmpty() const
VkDevice device
Definition main.cc:53
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition switches.h:228
float fX
x-axis value
float fY
y-axis value
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void setLTRB(float left, float top, float right, float bottom)
Definition SkRect.h:865
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15

◆ drawPaint()

void SkDrawBase::drawPaint ( const SkPaint paint) const

Definition at line 74 of file SkDrawBase.cpp.

74 {
75 SkDEBUGCODE(this->validate();)
76
77 if (fRC->isEmpty()) {
78 return;
79 }
80
81 SkIRect devRect;
82 devRect.setWH(fDst.width(), fDst.height());
83
84 SkAutoBlitterChoose blitter(*this, nullptr, paint);
85 SkScan::FillIRect(devRect, *fRC, blitter.get());
86}
SkPixmap fDst
Definition SkDrawBase.h:151
int width() const
Definition SkPixmap.h:160
int height() const
Definition SkPixmap.h:166
static void FillIRect(const SkIRect &, const SkRasterClip &, SkBlitter *)
Definition SkScan.cpp:65
void setWH(int32_t width, int32_t height)
Definition SkRect.h:275

◆ drawPath()

void SkDrawBase::drawPath ( const SkPath path,
const SkPaint paint,
const SkMatrix prePathMatrix = nullptr,
bool  pathIsMutable = false 
) const
inline

To save on mallocs, we allow a flag that tells us that srcPath is mutable, so that we don't have to make copies of it as we transform it.

If prePathMatrix is not null, it should logically be applied before any stroking or other effects. If there are no effects on the paint that affect the geometry/rasterization, then the pre matrix can just be pre-concated with the current matrix.

Definition at line 58 of file SkDrawBase.h.

59 {
60 this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
61 }

◆ drawPathCoverage()

void SkDrawBase::drawPathCoverage ( const SkPath src,
const SkPaint paint,
SkBlitter customBlitter = nullptr 
) const
inline

Overwrite the target with the path's coverage (i.e. its mask). Will overwrite the entire device, so it need not be zero'd first.

Only device A8 is supported right now.

Definition at line 69 of file SkDrawBase.h.

70 {
71 bool isHairline = paint.getStyle() == SkPaint::kStroke_Style &&
72 paint.getStrokeWidth() == 0;
73 this->drawPath(src, paint, nullptr, false, !isHairline, customBlitter);
74 }

◆ drawRect() [1/2]

void SkDrawBase::drawRect ( const SkRect prePaintRect,
const SkPaint paint,
const SkMatrix paintMatrix,
const SkRect postPaintRect 
) const

Definition at line 159 of file SkDrawBase.cpp.

160 {
161 SkDEBUGCODE(this->validate();)
162
163 // nothing to draw
164 if (fRC->isEmpty()) {
165 return;
166 }
167
169 if (paintMatrix) {
170 SkASSERT(postPaintRect);
171 matrix.writable()->preConcat(*paintMatrix);
172 } else {
173 SkASSERT(!postPaintRect);
174 }
175
176 SkPoint strokeSize;
177 RectType rtype = ComputeRectType(prePaintRect, paint, *fCTM, &strokeSize);
178
179 if (kPath_RectType == rtype) {
180 draw_rect_as_path(*this, prePaintRect, paint, *matrix);
181 return;
182 }
183
184 SkRect devRect;
185 const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
186 // skip the paintMatrix when transforming the rect by the CTM
187 fCTM->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
188 devRect.sort();
189
190 // look for the quick exit, before we build a blitter
191 SkRect bbox = devRect;
192 if (paint.getStyle() != SkPaint::kFill_Style) {
193 // extra space for hairlines
194 if (paint.getStrokeWidth() == 0) {
195 bbox.outset(1, 1);
196 } else {
197 // For kStroke_RectType, strokeSize is already computed.
198 const SkPoint& ssize = (kStroke_RectType == rtype)
199 ? strokeSize
201 bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
202 }
203 }
204 if (SkPathPriv::TooBigForMath(bbox)) {
205 return;
206 }
207
208 if (!SkRectPriv::FitsInFixed(bbox) && rtype != kHair_RectType) {
209 draw_rect_as_path(*this, prePaintRect, paint, *matrix);
210 return;
211 }
212
213 SkIRect ir = bbox.roundOut();
214 if (fRC->quickReject(ir)) {
215 return;
216 }
217
218 SkAutoBlitterChoose blitterStorage(*this, matrix, paint);
219 const SkRasterClip& clip = *fRC;
220 SkBlitter* blitter = blitterStorage.get();
221
222 // we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
223 // case we are also hairline (if we've gotten to here), which devolves to
224 // effectively just kFill
225 switch (rtype) {
226 case kFill_RectType:
227 if (paint.isAntiAlias()) {
228 SkScan::AntiFillRect(devRect, clip, blitter);
229 } else {
230 SkScan::FillRect(devRect, clip, blitter);
231 }
232 break;
233 case kStroke_RectType:
234 if (paint.isAntiAlias()) {
235 SkScan::AntiFrameRect(devRect, strokeSize, clip, blitter);
236 } else {
237 SkScan::FrameRect(devRect, strokeSize, clip, blitter);
238 }
239 break;
240 case kHair_RectType:
241 if (paint.isAntiAlias()) {
242 SkScan::AntiHairRect(devRect, clip, blitter);
243 } else {
244 SkScan::HairRect(devRect, clip, blitter);
245 }
246 break;
247 default:
248 SkDEBUGFAIL("bad rtype");
249 }
250}
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
static const SkPoint * rect_points(const SkRect &r)
static SkPoint compute_stroke_size(const SkPaint &paint, const SkMatrix &matrix)
static void draw_rect_as_path(const SkDrawBase &orig, const SkRect &prePaintRect, const SkPaint &paint, const SkMatrix &ctm)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
static RectType ComputeRectType(const SkRect &, const SkPaint &, const SkMatrix &, SkPoint *strokeSize)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
static bool TooBigForMath(const SkRect &bounds)
Definition SkPathPriv.h:290
bool quickReject(const SkIRect &rect) const
static bool FitsInFixed(const SkRect &r)
Definition SkRectPriv.h:56
static void AntiHairRect(const SkRect &, const SkRasterClip &, SkBlitter *)
static void AntiFillRect(const SkRect &, const SkRasterClip &, SkBlitter *)
static void FillRect(const SkRect &, const SkRasterClip &, SkBlitter *)
Definition SkScan.cpp:95
static void FrameRect(const SkRect &, const SkPoint &strokeSize, const SkRasterClip &, SkBlitter *)
static void AntiFrameRect(const SkRect &, const SkPoint &strokeSize, const SkRasterClip &, SkBlitter *)
static void HairRect(const SkRect &, const SkRasterClip &, SkBlitter *)
constexpr float y() const
constexpr float x() const
void outset(float dx, float dy)
Definition SkRect.h:1077
void sort()
Definition SkRect.h:1313

◆ drawRect() [2/2]

void SkDrawBase::drawRect ( const SkRect rect,
const SkPaint paint 
) const
inline

Definition at line 45 of file SkDrawBase.h.

45 {
46 this->drawRect(rect, paint, nullptr, nullptr);
47 }

◆ drawRRect()

void SkDrawBase::drawRRect ( const SkRRect rrect,
const SkPaint paint 
) const

Definition at line 286 of file SkDrawBase.cpp.

286 {
287 SkDEBUGCODE(this->validate());
288
289 if (fRC->isEmpty()) {
290 return;
291 }
292
293 {
294 // TODO: Investigate optimizing these options. They are in the same
295 // order as SkDrawBase::drawPath, which handles each case. It may be
296 // that there is no way to optimize for these using the SkRRect path.
298 if (SkDrawTreatAsHairline(paint, *fCTM, &coverage)) {
299 goto DRAW_PATH;
300 }
301
302 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
303 goto DRAW_PATH;
304 }
305 }
306
307 if (paint.getMaskFilter()) {
308 // Transform the rrect into device space.
309 SkRRect devRRect;
310 if (rrect.transform(*fCTM, &devRRect)) {
311 SkAutoBlitterChoose blitter(*this, nullptr, paint);
312 if (as_MFB(paint.getMaskFilter())->filterRRect(devRRect, *fCTM, *fRC, blitter.get())) {
313 return; // filterRRect() called the blitter, so we're done
314 }
315 }
316 }
317
319 // Now fall back to the default case of using a path.
320 SkPath path;
321 path.addRRect(rrect);
322 this->drawPath(path, paint, nullptr, true);
323}
bool SkDrawTreatAsHairline(const SkPaint &paint, const SkMatrix &matrix, SkScalar *coverage)
Definition SkDrawProcs.h:24
@ DRAW_PATH
bool transform(const SkMatrix &matrix, SkRRect *dst) const
Definition SkRRect.cpp:436
SkRRect rrect
Definition SkRecords.h:232

◆ DrawToMask()

bool SkDrawBase::DrawToMask ( const SkPath devPath,
const SkIRect clipBounds,
const SkMaskFilter filter,
const SkMatrix filterMatrix,
SkMaskBuilder dst,
SkMaskBuilder::CreateMode  mode,
SkStrokeRec::InitStyle  style 
)
static

Helper function that creates a mask from a path and an optional maskfilter. Note however, that the resulting mask will not have been actually filtered, that must be done afterwards (by calling filterMask). The maskfilter is provided solely to assist in computing the mask's bounds (if the mode requests that).

Definition at line 559 of file SkDrawBase.cpp.

562 {
563 if (devPath.isEmpty()) {
564 return false;
565 }
566
568 // By using infinite bounds for inverse fills, ComputeMaskBounds is able to clip it to
569 // 'clipBounds' outset by whatever extra margin the mask filter requires.
570 static const SkRect kInverseBounds = { SK_ScalarNegativeInfinity, SK_ScalarNegativeInfinity,
572 SkRect pathBounds = devPath.isInverseFillType() ? kInverseBounds
573 : devPath.getBounds();
574 if (!ComputeMaskBounds(pathBounds, clipBounds, filter,
575 filterMatrix, &dst->bounds()))
576 return false;
577 }
578
580 dst->format() = SkMask::kA8_Format;
581 dst->rowBytes() = dst->fBounds.width();
582 size_t size = dst->computeImageSize();
583 if (0 == size) {
584 // we're too big to allocate the mask, abort
585 return false;
586 }
588 }
589
591 draw_into_mask(*dst, devPath, style);
592 }
593
594 return true;
595}
bool draw_into_mask(SkMaskBuilder *mask, const SkRect &bounds, Proc proc)
#define SK_ScalarInfinity
Definition SkScalar.h:26
#define SK_ScalarNegativeInfinity
Definition SkScalar.h:27
static bool ComputeMaskBounds(const SkRect &devPathBounds, const SkIRect &clipBounds, const SkMaskFilter *filter, const SkMatrix *filterMatrix, SkIRect *bounds)
bool isInverseFillType() const
Definition SkPath.h:244
const SkRect & getBounds() const
Definition SkPath.cpp:420
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
dst
Definition cp.py:12
@ kComputeBoundsAndRenderImage_CreateMode
compute bounds, alloc image and render into it
Definition SkMask.h:301
@ kJustRenderImage_CreateMode
render into preallocate mask
Definition SkMask.h:300
@ kJustComputeBounds_CreateMode
compute bounds and return
Definition SkMask.h:299
@ kZeroInit_Alloc
Definition SkMask.h:293
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
Definition SkMask.cpp:45

◆ paintMasks()

void SkDrawBase::paintMasks ( SkZip< const SkGlyph *, SkPoint accepted,
const SkPaint paint 
) const
overrideprivatevirtual

Implements SkGlyphRunListPainterCPU::BitmapDevicePainter.

Definition at line 467 of file SkDrawBase.cpp.

467 {
468 SkASSERT(false);
469}

◆ validate()

void SkDrawBase::validate ( ) const
inline

Definition at line 160 of file SkDrawBase.h.

160{}

Member Data Documentation

◆ fBlitterChooser

BlitterChooser* SkDrawBase::fBlitterChooser {nullptr}

Definition at line 152 of file SkDrawBase.h.

152{nullptr}; // required

◆ fCTM

const SkMatrix* SkDrawBase::fCTM {nullptr}

Definition at line 153 of file SkDrawBase.h.

153{nullptr}; // required

◆ fDst

SkPixmap SkDrawBase::fDst

Definition at line 151 of file SkDrawBase.h.

◆ fProps

const SkSurfaceProps* SkDrawBase::fProps {nullptr}

Definition at line 155 of file SkDrawBase.h.

155{nullptr}; // optional

◆ fRC

const SkRasterClip* SkDrawBase::fRC {nullptr}

Definition at line 154 of file SkDrawBase.h.

154{nullptr}; // required

The documentation for this class was generated from the following files: