55bool SkDrawBase::computeConservativeLocalClipBounds(
SkRect* localBounds)
const {
96 matrix.mapVectors(&size, &pt, 1);
117 const bool zeroWidth = (0 ==
width);
124 if (
paint.getPathEffect() ||
paint.getMaskFilter() ||
129 }
else if (zeroWidth) {
140 return reinterpret_cast<const SkPoint*
>(&r);
144 return reinterpret_cast<SkPoint*
>(&r);
148 const SkRect& prePaintRect,
156 draw.drawPath(tmp,
paint,
nullptr,
true);
171 matrix.writable()->preConcat(*paintMatrix);
185 const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
194 if (
paint.getStrokeWidth() == 0) {
227 if (
paint.isAntiAlias()) {
234 if (
paint.isAntiAlias()) {
241 if (
paint.isAntiAlias()) {
267 if (matrix.hasPerspective()) {
274 matrix.mapVectors(dst, src, 2);
307 if (
paint.getMaskFilter()) {
321 path.addRRect(rrect);
325void SkDrawBase::drawDevPath(
const SkPath& devPath,
const SkPaint&
paint,
bool drawCoverage,
326 SkBlitter* customBlitter,
bool doFill)
const {
332 if (
nullptr == customBlitter) {
333 blitter = blitterStorage.
choose(*
this,
nullptr,
paint, drawCoverage);
335 blitter = customBlitter;
338 if (
paint.getMaskFilter()) {
341 if (
as_MFB(
paint.getMaskFilter())->filterPath(devPath, *
fCTM, *
fRC, blitter, style)) {
348 if (
paint.isAntiAlias()) {
354 if (
paint.isAntiAlias()) {
355 switch (
paint.getStrokeCap()) {
367 switch (
paint.getStrokeCap()) {
381 proc(devPath, *
fRC, blitter);
385 const SkMatrix* prePathMatrix,
bool pathIsMutable,
386 bool drawCoverage,
SkBlitter* customBlitter)
const {
397 SkPath* tmpPath = &tmpPathStorage;
405 if (!pathIsMutable) {
407 pathIsMutable =
true;
412 matrix.writable()->preConcat(*prePathMatrix);
423 paint.writable()->setStrokeWidth(0);
444 const SkRect* cullRectPtr =
nullptr;
445 if (this->computeConservativeLocalClipBounds(&cullRect)) {
446 cullRectPtr = &cullRect;
453 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath;
458#if defined(SK_BUILD_FOR_FUZZER)
464 this->drawDevPath(*devPathPtr, *
paint, drawCoverage, customBlitter, doFill);
506 if (!
as_MFB(filter)->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
518 static constexpr int kMaxMargin = 128;
519 if (!bounds->intersect(clipBounds.
makeOutset(std::min(margin.
fX, kMaxMargin),
520 std::min(margin.
fY, kMaxMargin)))) {
531 if (!
draw.fDst.reset(mask)) {
545 paint.setAntiAlias(
true);
575 filterMatrix, &dst->bounds()))
581 dst->rowBytes() = dst->fBounds.width();
582 size_t size = dst->computeImageSize();
629 for (
size_t i = 0; i <
count; ++i) {
631 pts[i].fX + radius, pts[i].fY + radius);
632 device->drawOval(r, newPaint);
638 path.addCircle(0, 0, radius);
639 for (
size_t i = 0; i <
count; i++) {
643 path.setIsVolatile((
count-1) == i);
650 for (
size_t i = 0; i <
count; i++) {
652 r.
fTop = pts[i].
fY - radius;
656 device->drawRect(r, newPaint);
729 for (
int i = 0; i < pointData.
fNumPoints; ++i) {
735 device->drawRect(r, newP);
752 path.setIsVolatile(
true);
753 for (
size_t i = 0; i <
count; i += inc) {
755 path.lineTo(pts[i+1]);
757 device->drawPath(path, p,
true);
759 this->
drawPath(path, p,
nullptr,
true);
static const int strokeWidth
#define SkDEBUGFAIL(message)
bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode mode)
SkBlitter * SkA8Blitter_Choose(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *alloc, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &)
bool draw_into_mask(SkMaskBuilder *mask, const SkRect &bounds, Proc proc)
static const SkPoint * rect_points(const SkRect &r)
static SkPoint compute_stroke_size(const SkPaint &paint, const SkMatrix &matrix)
bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix &matrix, SkScalar *coverage)
static SkScalar fast_len(const SkVector &vec)
static void draw_rect_as_path(const SkDrawBase &orig, const SkRect &prePaintRect, const SkPaint &paint, const SkMatrix &ctm)
static bool easy_rect_join(const SkRect &rect, const SkPaint &paint, const SkMatrix &matrix, SkPoint *strokeSize)
static void draw_into_mask(const SkMask &mask, const SkPath &devPath, SkStrokeRec::InitStyle style)
bool SkDrawTreatAsHairline(const SkPaint &paint, const SkMatrix &matrix, SkScalar *coverage)
static bool SkIsFinite(T x, Pack... values)
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
static SkPathEffectBase * as_PEB(SkPathEffect *effect)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define SkScalarAve(a, b)
#define SkScalarRoundToInt(x)
#define SK_ScalarInfinity
#define SK_ScalarNegativeInfinity
constexpr uint8_t SkToU8(S x)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Type::kYUV Type::kRGBA() int(0.7 *637)
SkBlitter * choose(const SkDrawBase &draw, const SkMatrix *ctm, const SkPaint &paint, bool drawCoverage=false)
@ kLines_PointMode
draw each pair of points as a line segment
@ kPolygon_PointMode
draw the array of points as a open polygon
@ kPoints_PointMode
draw each point separately
void drawRRect(const SkRRect &, const SkPaint &) const
BlitterChooser * fBlitterChooser
void drawPath(const SkPath &path, const SkPaint &paint, const SkMatrix *prePathMatrix=nullptr, bool pathIsMutable=false) const
static bool DrawToMask(const SkPath &devPath, const SkIRect &clipBounds, const SkMaskFilter *, const SkMatrix *filterMatrix, SkMaskBuilder *dst, SkMaskBuilder::CreateMode mode, SkStrokeRec::InitStyle style)
static bool ComputeMaskBounds(const SkRect &devPathBounds, const SkIRect &clipBounds, const SkMaskFilter *filter, const SkMatrix *filterMatrix, SkIRect *bounds)
void drawPaint(const SkPaint &) const
void drawRect(const SkRect &prePaintRect, const SkPaint &, const SkMatrix *paintMatrix, const SkRect *postPaintRect) const
void drawBitmap(const SkBitmap &, const SkMatrix &, const SkRect *dstOrNull, const SkSamplingOptions &, const SkPaint &) const override
static RectType ComputeRectType(const SkRect &, const SkPaint &, const SkMatrix &, SkPoint *strokeSize)
void paintMasks(SkZip< const SkGlyph *, SkPoint > accepted, const SkPaint &paint) const override
void drawDevicePoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint &, SkDevice *) const
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
bool invert(SkMatrix *inverse) const
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ kButt_Cap
no stroke extension
void setStyle(Style style)
SkPathEffect * getPathEffect() const
void setStrokeCap(Cap cap)
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
@ kStrokeAndFill_Style
sets to stroke and fill geometry
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
SkScalar getStrokeWidth() const
@ kMiter_Join
extends to miter limit
void setStrokeWidth(SkScalar width)
std::optional< SkBlendMode > asBlendMode() const
bool asPoints(PointData *results, const SkPath &src, const SkStrokeRec &, const SkMatrix &, const SkRect *cullR) const
static bool TooBigForMath(const SkRect &bounds)
bool isInverseFillType() const
void setFillType(SkPathFillType ft)
SkPath & setIsVolatile(bool isVolatile)
const SkRect & getBounds() const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static SkPath Line(const SkPoint a, const SkPoint b)
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
bool transform(const SkMatrix &matrix, SkRRect *dst) const
const SkIRect & getBounds() const
bool quickReject(const SkIRect &rect) const
static bool FitsInFixed(const SkRect &r)
static void HairRoundPath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void HairPath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void HairSquarePath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void AntiHairRect(const SkRect &, const SkRasterClip &, SkBlitter *)
static void AntiFillRect(const SkRect &, const SkRasterClip &, SkBlitter *)
static void FillRect(const SkRect &, const SkRasterClip &, SkBlitter *)
static void AntiFillPath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void AntiHairPath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void FrameRect(const SkRect &, const SkPoint &strokeSize, const SkRasterClip &, SkBlitter *)
static void AntiHairRoundPath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void FillPath(const SkPath &, const SkIRect &, SkBlitter *)
static void AntiHairSquarePath(const SkPath &, const SkRasterClip &, SkBlitter *)
static void AntiFrameRect(const SkRect &, const SkPoint &strokeSize, const SkRasterClip &, SkBlitter *)
static void FillIRect(const SkIRect &, const SkRasterClip &, SkBlitter *)
static void HairRect(const SkRect &, const SkRasterClip &, SkBlitter *)
unsigned useCenter Optional< SkMatrix > matrix
static void swap(TArray< T, M > &a, TArray< T, M > &b)
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
static constexpr SkIPoint Make(int32_t x, int32_t y)
SkIRect makeOutset(int32_t dx, int32_t dy) const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
void setWH(int32_t width, int32_t height)
int32_t fLeft
smaller x-axis bounds
void outset(int32_t dx, int32_t dy)
bool contains(int32_t x, int32_t y) const
@ kComputeBoundsAndRenderImage_CreateMode
compute bounds, alloc image and render into it
@ kJustRenderImage_CreateMode
render into preallocate mask
@ kJustComputeBounds_CreateMode
compute bounds and return
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
static constexpr SkPoint Make(float x, float y)
constexpr float y() const
constexpr float x() const
static SkRect Make(const SkISize &size)
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
void outset(float dx, float dy)
SkRect makeOutset(float dx, float dy) const
SkScalar fRight
larger x-axis bounds
void roundOut(SkIRect *dst) const
void setLTRB(float left, float top, float right, float bottom)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
SkScalar fTop
smaller y-axis bounds