Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | 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
 
virtual void paintMasks (SkZip< const SkGlyph *, SkPoint > accepted, const SkPaint &paint) const =0
 
virtual void drawBitmap (const SkBitmap &, const SkMatrix &, const SkRect *dstOrNull, const SkSamplingOptions &, const SkPaint &) const =0
 

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}
 

Detailed Description

Definition at line 40 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 113 of file SkDrawBase.h.

Member Enumeration Documentation

◆ RectType

Enumerator
kHair_RectType 
kFill_RectType 
kStroke_RectType 
kPath_RectType 

Definition at line 95 of file SkDrawBase.h.

95 {
100 };
@ kFill_RectType
Definition: SkDrawBase.h:97
@ kPath_RectType
Definition: SkDrawBase.h:99
@ kHair_RectType
Definition: SkDrawBase.h:96
@ kStroke_RectType
Definition: SkDrawBase.h:98

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
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Optional< SkRect > bounds
Definition: SkRecords.h:189
int32_t fX
x-axis value
Definition: SkPoint_impl.h:29
int32_t fY
y-axis value
Definition: SkPoint_impl.h:30
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38
SkIRect makeOutset(int32_t dx, int32_t dy) const
Definition: SkRect.h:350
Definition: SkMask.h:25
@ 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)
Definition: SkDrawBase.cpp:100
@ 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
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
int32_t width

◆ 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
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
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
Definition: FontMgrTest.cpp:50
static bool SkIsFinite(T x, Pack... values)
static SkPathEffectBase * as_PEB(SkPathEffect *effect)
#define SkScalarHalf(a)
Definition: SkScalar.h:75
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
@ 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:60
const SkRasterClip * fRC
Definition: SkDrawBase.h:156
void drawRect(const SkRect &prePaintRect, const SkPaint &, const SkMatrix *paintMatrix, const SkRect *postPaintRect) const
Definition: SkDrawBase.cpp:159
void validate() const
Definition: SkDrawBase.h:162
const SkMatrix * fCTM
Definition: SkDrawBase.h:155
void drawDevicePoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint &, SkDevice *) const
Definition: SkDrawBase.cpp:597
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
Definition: SkPath.h:59
bool isEmpty() const
Definition: SkPath.cpp:416
static SkPath Line(const SkPoint a, const SkPoint b)
Definition: SkPath.h:106
const SkIRect & getBounds() const
Definition: SkRasterClip.h:60
bool isEmpty() const
Definition: SkRasterClip.h:47
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
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
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:153
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
Definition: SkRect.h:32
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 60 of file SkDrawBase.h.

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

◆ 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 71 of file SkDrawBase.h.

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

◆ 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)
Definition: SkDrawBase.cpp:139
static SkPoint compute_stroke_size(const SkPaint &paint, const SkMatrix &matrix)
Definition: SkDrawBase.cpp:90
static void draw_rect_as_path(const SkDrawBase &orig, const SkRect &prePaintRect, const SkPaint &paint, const SkMatrix &ctm)
Definition: SkDrawBase.cpp:147
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static RectType ComputeRectType(const SkRect &, const SkPaint &, const SkMatrix &, SkPoint *strokeSize)
Definition: SkDrawBase.cpp:111
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
Definition: SkRasterClip.h:85
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
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
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 47 of file SkDrawBase.h.

47 {
48 this->drawRect(rect, paint, nullptr, nullptr);
49 }

◆ 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.
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
Definition: SkPictureFlat.h:47
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}
static void draw_into_mask(const SkMask &mask, const SkPath &devPath, SkStrokeRec::InitStyle style)
Definition: SkDrawBase.cpp:527
#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)
Definition: SkDrawBase.cpp:494
bool isInverseFillType() const
Definition: SkPath.h:244
const SkRect & getBounds() const
Definition: SkPath.cpp:430
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

◆ validate()

void SkDrawBase::validate ( ) const
inline

Definition at line 162 of file SkDrawBase.h.

162{}

Member Data Documentation

◆ fBlitterChooser

BlitterChooser* SkDrawBase::fBlitterChooser {nullptr}

Definition at line 154 of file SkDrawBase.h.

◆ fCTM

const SkMatrix* SkDrawBase::fCTM {nullptr}

Definition at line 155 of file SkDrawBase.h.

◆ fDst

SkPixmap SkDrawBase::fDst

Definition at line 153 of file SkDrawBase.h.

◆ fProps

const SkSurfaceProps* SkDrawBase::fProps {nullptr}

Definition at line 157 of file SkDrawBase.h.

◆ fRC

const SkRasterClip* SkDrawBase::fRC {nullptr}

Definition at line 156 of file SkDrawBase.h.


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