40 blitter->
blitH(
x, fy >> 16, 1);
42 }
while (++
x < stopx);
50 blitter->
blitH(fx >> 16,
y, 1);
52 }
while (++
y < stopy);
56static bool canConvertFDot6ToFixed(
SkFDot6 x) {
57 const int maxDot6 =
SK_MaxS32 >> (16 - 6);
75 for (
int i = 0; i < arrayCount - 1; ++i) {
97 SkASSERT(canConvertFDot6ToFixed(x0));
98 SkASSERT(canConvertFDot6ToFixed(y0));
99 SkASSERT(canConvertFDot6ToFixed(x1));
100 SkASSERT(canConvertFDot6ToFixed(y1));
123 blitter = clipper.
apply(origBlitter,
clip);
141#if defined(SK_BUILD_FOR_FUZZER)
142 if ((ix1 - ix0) > 100000 || (ix1 - ix0) < 0) {
149 horiline(ix0, ix1, startY, slope, blitter);
161#if defined(SK_BUILD_FOR_FUZZER)
162 if ((iy1 - iy0) > 100000 || (iy1 - iy0) < 0) {
169 vertline(iy0, iy1, startX, slope, blitter);
196 if (
clip.quickReject(r)) {
199 if (!
clip.quickContains(r)) {
202 clipRgn = &
clip.bwRgn();
205 clipRgn = &wrapper.
getRgn();
208 blitter = clipper.
apply(blitter, clipRgn);
230#define kMaxCubicSubdivideLevel 9
231#define kMaxQuadSubdivideLevel 5
250 return idx + (idy >> 1);
252 return idy + (idx >> 1);
260 SkQuadCoeff coeff(pts);
262 const int lines = 1 << level;
267 SkASSERT((
unsigned)lines < std::size(tmp));
273 for (
int i = 1; i < lines; ++i) {
275 ((
A * t +
B) * t +
C).
store(&tmp[i]);
278 lineproc(tmp, lines + 1,
clip, blitter);
286 for (
int i = 1; i < 3; ++i) {
302 return a.fLeft <
b.fRight &&
b.fLeft <
a.fRight &&
303 a.fTop <
b.fBottom &&
b.fTop <
a.fBottom;
331 value.store(components);
332 return std::max(components[0], components[1]);
341 const float2 oneThird(1.0f / 3.0f);
342 const float2 twoThird(2.0f / 3.0f);
344 float2 p13 = oneThird * p3 + twoThird * p0;
345 float2 p23 = oneThird * p0 + twoThird * p3;
365 return lt_90(pts[1], pts[0], pts[3]) &&
366 lt_90(pts[2], pts[0], pts[3]) &&
367 lt_90(pts[1], pts[3], pts[0]) &&
368 lt_90(pts[2], pts[3], pts[0]);
375 return (sk_bit_cast<mask2>(
x) & exp_mask) != exp_mask;
383 SkPoint tmp[2] = { pts[0], pts[3] };
384 lineproc(tmp, 2,
clip, blitter);
388 SkCubicCoeff coeff(pts);
394 SkASSERT((
unsigned)lines < std::size(tmp));
402 for (
int i = 1; i < lines; ++i) {
408 if (all(is_finite)) {
410 lineproc(tmp, lines + 1,
clip, blitter);
419 for (
int i = 1; i < 4; ++i) {
446 for (
int i = 0; i <
count; i++) {
459 int level = (33 -
SkCLZ(
d)) >> 1;
471template <SkPa
int::Cap capStyle>
479 int controls = ptCount - 1;
482 tangent = *first - *++ctrl;
483 }
while (tangent.
isZero() && --controls > 0);
486 controls = ptCount - 1;
491 first->
fX += tangent.
fX * capOutset;
492 first->
fY += tangent.
fY * capOutset;
494 }
while (++controls < ptCount);
498 SkPoint* last = &pts[ptCount - 1];
500 int controls = ptCount - 1;
503 tangent = *last - *--ctrl;
504 }
while (tangent.
isZero() && --controls > 0);
507 controls = ptCount - 1;
512 last->
fX += tangent.
fX * capOutset;
513 last->
fY += tangent.
fY * capOutset;
515 }
while (++controls < ptCount);
519template <SkPa
int::Cap capStyle>
522 if (path.isEmpty()) {
528 SkRect insetStorage, outsetStorage;
529 const SkRect* insetClip =
nullptr;
530 const SkRect* outsetClip =
nullptr;
534 const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut);
542 wrap.
init(rclip, blitter);
562 outsetStorage = insetStorage.
makeOutset(1, 1);
563 insetStorage.
inset(1, 1);
574 insetClip = &insetStorage;
576 outsetClip = &outsetStorage;
582 SkPoint pts[4], firstPt, lastPt;
589 while (iter !=
end) {
590 auto [pathVerb, pathPts,
w] = *iter++;
596 firstPt = lastPt = pts[0];
600 extend_pts<capStyle>(prevVerb, nextVerb, pts, 2);
602 lineproc(pts, 2,
clip, blitter);
607 extend_pts<capStyle>(prevVerb, nextVerb, pts, 3);
614 extend_pts<capStyle>(prevVerb, nextVerb, pts, 3);
618 const SkPoint* quadPts = converter.computeQuads(pts, *
w, tol);
619 for (
int i = 0; i < converter.countQuads(); ++i) {
621 hairquad(quadPts,
clip, insetClip, outsetClip, blitter, level, lineproc);
629 extend_pts<capStyle>(prevVerb, nextVerb, pts, 4);
639 extend_pts<capStyle>(prevVerb, nextVerb, pts, 2);
641 lineproc(pts, 2,
clip, blitter);
657 hair_path<SkPaint::kButt_Cap>(path,
clip, blitter, SkScan::HairLineRgn);
661 hair_path<SkPaint::kButt_Cap>(path,
clip, blitter, SkScan::AntiHairLineRgn);
665 hair_path<SkPaint::kSquare_Cap>(path,
clip, blitter, SkScan::HairLineRgn);
669 hair_path<SkPaint::kSquare_Cap>(path,
clip, blitter, SkScan::AntiHairLineRgn);
673 hair_path<SkPaint::kRound_Cap>(path,
clip, blitter, SkScan::HairLineRgn);
677 hair_path<SkPaint::kRound_Cap>(path,
clip, blitter, SkScan::AntiHairLineRgn);
686 if (strokeSize.
fX < 0 || strokeSize.
fY < 0) {
719 HairLineRgn(pts,
count, &
clip.bwRgn(), blitter);
733 HairLineRgn(pts,
count, clipRgn, blitter);
740 AntiHairLineRgn(pts,
count, &
clip.bwRgn(), blitter);
748 if (!
clip.quickContains(r.
roundOut().makeOutset(1, 1))) {
753 AntiHairLineRgn(pts,
count, clipRgn, blitter);
SkFixed SkFDot6ToFixed(SkFDot6 x)
#define SkScalarToFDot6(x)
#define SkFixedDiv(numer, denom)
static bool SkIsFinite(T x, Pack... values)
int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tValues[3])
static skvx::float2 from_point(const SkPoint &point)
static int SkCLZ(uint32_t mask)
static constexpr int32_t SK_MaxS32
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
void swap(sk_sp< T > &a, sk_sp< T > &b)
static int32_t SkAbs32(int32_t value)
#define SkScalarCeilToInt(x)
#define SkScalarFloorToInt(x)
#define kMaxQuadSubdivideLevel
#define kMaxCubicSubdivideLevel
skvx::Vec< 2, uint32_t > mask2
static SkScalar max_component(const float2 &value)
static void haircubic(const SkPoint pts[4], const SkRegion *clip, const SkRect *insetClip, const SkRect *outsetClip, SkBlitter *blitter, int level, SkScan::HairRgnProc lineproc)
static void hairquad(const SkPoint pts[3], const SkRegion *clip, const SkRect *insetClip, const SkRect *outsetClip, SkBlitter *blitter, int level, SkScan::HairRgnProc lineproc)
static bool quick_cubic_niceness_check(const SkPoint pts[4])
static int compute_quad_level(const SkPoint pts[3])
static SkRect compute_nocheck_cubic_bounds(const SkPoint pts[4])
static uint32_t compute_int_quad_dist(const SkPoint pts[3])
static bool geometric_overlap(const SkRect &a, const SkRect &b)
static bool lt_90(SkPoint p0, SkPoint pivot, SkPoint p2)
void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint *pts, int ptCount)
static bool is_inverted(const SkRect &r)
void hair_path(const SkPath &path, const SkRasterClip &rclip, SkBlitter *blitter, SkScan::HairRgnProc lineproc)
static void hair_quad(const SkPoint pts[3], const SkRegion *clip, SkBlitter *blitter, int level, SkScan::HairRgnProc lineproc)
static void vertline(int y, int stopy, SkFixed fx, SkFixed dx, SkBlitter *blitter)
static void hair_cubic(const SkPoint pts[4], const SkRegion *clip, SkBlitter *blitter, SkScan::HairRgnProc lineproc)
static SkRect compute_nocheck_quad_bounds(const SkPoint pts[3])
static int compute_cubic_segs(const SkPoint pts[4])
static void horiline(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter *blitter)
static bool geometric_contains(const SkRect &outer, const SkRect &inner)
static mask2 float2_is_finite(const float2 &x)
void init(const SkRasterClip &, SkBlitter *)
const SkRegion & getRgn() const
SkBlitter * apply(SkBlitter *blitter, const SkRegion *clip, const SkIRect *bounds=nullptr)
virtual void blitH(int x, int y, int width)=0
Blit a horizontal run of one or more pixels.
virtual void blitRect(int x, int y, int width, int height)
Blit a solid rectangle one or more pixels wide.
static bool IntersectLine(const SkPoint src[2], const SkRect &clip, SkPoint dst[2])
@ kButt_Cap
no stroke extension
static int PtsInIter(unsigned verb)
SkPath::RangeIter RangeIter
const SkRect & getBounds() const
bool isRect(SkRect *rect, bool *isClosed=nullptr, SkPathDirection *direction=nullptr) const
const SkRegion & bwRgn() const
bool quickContains(const SkIRect &rect) const
bool quickReject(const SkIRect &rect) const
static void HairLine(const SkPoint[], int count, const SkRasterClip &, SkBlitter *)
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 FillRect(const SkRect &, 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 AntiHairLine(const SkPoint[], int count, const SkRasterClip &, SkBlitter *)
static void AntiHairSquarePath(const SkPath &, const SkRasterClip &, SkBlitter *)
void(* HairRgnProc)(const SkPoint[], int count, const SkRegion *, SkBlitter *)
static void HairRect(const SkRect &, const SkRasterClip &, SkBlitter *)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static float max(float r, float g, float b)
static float min(float r, float g, float b)
Optional< SkRect > bounds
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SIT T max(const Vec< 1, T > &x)
SIT T min(const Vec< 1, T > &x)
bool intersect(const SkIRect &r)
static bool Intersects(const SkIRect &a, const SkIRect &b)
int32_t fBottom
larger y-axis bounds
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
int32_t fLeft
smaller x-axis bounds
void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom)
bool contains(int32_t x, int32_t y) const
int32_t fRight
larger x-axis bounds
SkPath::RangeIter begin()
static float DotProduct(const SkVector &a, const SkVector &b)
void set(float x, float y)
SkScalar fBottom
larger y-axis bounds
void inset(float dx, float dy)
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
constexpr float height() const
void setLTRB(float left, float top, float right, float bottom)
void setBounds(const SkPoint pts[], int count)
constexpr float width() const
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
void set(const SkIRect &src)
SkScalar fTop
smaller y-axis bounds
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
SKVX_ALWAYS_INLINE void store(void *ptr) const