37#define kEDGE_HEAD_Y SK_MinS32
38#define kEDGE_TAIL_Y SK_MaxS32
53 #define validate_sort(edge)
57 if (newEdge->
fFirstY != curr_y) {
61 if (
prev->fX <= newEdge->
fX) {
70 if (
start->fNext == newEdge) {
74 if (after->
fX >= newEdge->
fX) {
84 }
while (newEdge->
fFirstY == curr_y);
89 while (edge->
fFirstY <= curr_y) {
100 #define validate_edges_for_y(edge, curr_y)
104#pragma warning ( push )
105#pragma warning ( disable : 4701 )
109#define PREPOST_START true
110#define PREPOST_END false
113 SkBlitter* blitter,
int start_y,
int stop_y,
117 int curr_y = start_y;
132 while (currE->
fFirstY <= curr_y) {
137 if ((
w & windingMask) == 0) {
143 if ((
w & windingMask) == 0) {
154 if (currE->
fLastY == curr_y) {
171 newX = currE->
fX + currE->
fDX;
184 if ((
w & windingMask) != 0) {
196 if (curr_y >= stop_y) {
207 if (last_y == edge->
fLastY) {
225#define ASSERT_RETURN(cond) \
228 SkDEBUGFAILF("assert(%s)", #cond); \
246 while (local_top < stop_y) {
251 local_bot = std::min(local_bot, stop_y - 1);
258 int count = local_bot - local_top;
261 if (0 == (dLeft | dRite)) {
271 local_top = local_bot + 1;
280 blitter->
blitH(L, local_top,
R - L);
289 }
while (--
count >= 0);
296 if (currE->
fFirstY >= stop_y) {
300 currE = currE->
fNext;
304 if (currE->
fFirstY >= stop_y) {
308 currE = currE->
fNext;
325 fFirstX =
clip.fLeft << shift;
326 fLastX =
clip.fRight << shift;
332 int invWidth = fLastX - fPrevX;
334 fBlitter->
blitH(fPrevX,
y, invWidth);
341 int invWidth =
x - fPrevX;
343 fBlitter->
blitH(fPrevX,
y, invWidth);
364 int fFirstX, fLastX, fPrevX;
374#pragma warning ( pop )
378 int valuea =
a.fFirstY;
379 int valueb =
b.fFirstY;
381 if (valuea == valueb) {
386 return valuea < valueb;
393 for (
int i = 1; i <
count; i++) {
394 list[i - 1]->
fNext = list[i];
395 list[i]->
fPrev = list[i - 1];
398 *last = list[
count - 1];
404 int start_y,
int stop_y,
int shiftEdgesUp,
bool pathContainedInClip) {
407 SkIRect shiftedClip = clipRect;
414 int count = builder.buildEdges(path, pathContainedInClip ?
nullptr : &shiftedClip);
415 SkEdge** list = builder.edgeList();
418 if (path.isInverseFillType()) {
426 if (rect.fTop < start_y) {
429 if (rect.fBottom > stop_y) {
430 rect.fBottom = stop_y;
432 if (!rect.isEmpty()) {
433 blitter->
blitRect(rect.fLeft << shiftEdgesUp,
434 rect.fTop << shiftEdgesUp,
435 rect.width() << shiftEdgesUp,
436 rect.height() << shiftEdgesUp);
442 SkEdge headEdge, tailEdge, *last;
446 headEdge.
fPrev =
nullptr;
447 headEdge.
fNext = edge;
450 edge->
fPrev = &headEdge;
452 tailEdge.
fPrev = last;
453 tailEdge.
fNext =
nullptr;
455 last->
fNext = &tailEdge;
461 if (!pathContainedInClip && start_y < shiftedClip.
fTop) {
462 start_y = shiftedClip.
fTop;
464 if (!pathContainedInClip && stop_y > shiftedClip.
fBottom) {
471 if (path.isInverseFillType()) {
472 ib.
setBlitter(blitter, clipRect, shiftEdgesUp);
478 if (path.isConvex() && (
nullptr == proc) &&
count >= 2) {
481 walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc,
482 shiftedClip.
right());
520 const SkIRect& ir,
bool skipRejectTest,
bool irPreClipped) {
531 if (!irPreClipped && fClipRect->
contains(ir)) {
533 fRectClipCheckBlitter.init(blitter, *fClipRect);
534 blitter = &fRectClipCheckBlitter;
541 fRectBlitter.
init(blitter, *fClipRect);
542 blitter = &fRectBlitter;
545 fRectClipCheckBlitter.
init(blitter, *fClipRect);
546 blitter = &fRectClipCheckBlitter;
552 blitter = &fRgnBlitter;
563 const int32_t limit = 32767 >> 1;
566 limitR.
setLTRB(-limit, -limit, limit, limit);
632 const SkRegion* clipPtr = &origClip;
638 clipPtr = &finiteClip;
643 SkRect bounds = path.getBounds();
644 bool irPreClipped =
false;
654 if (path.isInverseFillType()) {
660 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType(), irPreClipped);
666 if (path.isInverseFillType()) {
673 if (path.isInverseFillType()) {
698 if (edge->
setLine(pts[0], pts[1], clipRect, 0)) {
702 if (edge->
setLine(pts[1], pts[2], clipRect, 0)) {
706 if (edge->
setLine(pts[2], pts[0], clipRect, 0)) {
709 return (
int)(list -
start);
725 SkEdge headEdge, tailEdge, *last;
730 headEdge.
fPrev =
nullptr;
731 headEdge.
fNext = edge;
734 edge->
fPrev = &headEdge;
736 tailEdge.
fPrev = last;
737 tailEdge.
fNext =
nullptr;
739 last->
fNext = &tailEdge;
743 if (clipRect && stop_y > clipRect->fBottom) {
744 stop_y = clipRect->fBottom;
746 int start_y = ir.
fTop;
747 if (clipRect && start_y < clipRect->fTop) {
748 start_y = clipRect->fTop;
767 path.addPoly(pts, 3,
false);
780 clipRgn = &
clip.bwRgn();
static float next(float f)
static float prev(float f)
#define SkDEBUGFAIL(message)
#define SkFixedRoundToInt(x)
static constexpr int sk_double_saturate2int(double x)
#define SK_INIT_TO_AVOID_WARNING
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
static constexpr int32_t SK_MinS32
static constexpr int16_t SK_MaxS16
static constexpr int32_t SK_MaxS32
static bool contains(const SkRect &r, SkPoint p)
static bool SkPathFillType_IsEvenOdd(SkPathFillType ft)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
static bool left(const SkPoint &p0, const SkPoint &p1)
static constexpr int32_t Sk32_can_overflow_add(int32_t a, int32_t b)
static void remove_edge(EdgeType *edge)
void backward_insert_edge_based_on_x(EdgeType *edge)
static void insert_edge_after(EdgeType *edge, EdgeType *afterMe)
EdgeType * backward_insert_start(EdgeType *prev, SkFixed x)
#define validate_edges_for_y(edge, curr_y)
static SkIRect conservative_round_to_int(const SkRect &src)
void sk_fill_path(const SkPath &path, const SkIRect &clipRect, SkBlitter *blitter, int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip)
static SkEdge * sort_edges(SkEdge *list[], int count, SkEdge **last)
static const double kConservativeRoundBias
static bool clip_to_limit(const SkRegion &orig, SkRegion *reduced)
static int round_down_to_int(SkScalar x)
static void walk_simple_edges(SkEdge *prevHead, SkBlitter *blitter, int start_y, int stop_y)
static int round_up_to_int(SkScalar x)
static int build_tri_edges(SkEdge edge[], const SkPoint pts[], const SkIRect *clipRect, SkEdge *list[])
static void insert_new_edges(SkEdge *newEdge, int curr_y)
static void walk_edges(SkEdge *prevHead, SkPathFillType fillType, SkBlitter *blitter, int start_y, int stop_y, PrePostProc proc, int rightClip)
#define ASSERT_RETURN(cond)
static bool update_edge(SkEdge *edge, int last_y)
static void sk_fill_triangle(const SkPoint pts[], const SkIRect *clipRect, SkBlitter *blitter, const SkIRect &ir)
#define validate_sort(edge)
void sk_blit_below(SkBlitter *blitter, const SkIRect &ir, const SkRegion &clip)
void(* PrePostProc)(SkBlitter *blitter, int y, bool isStartOfScanline)
void sk_blit_above(SkBlitter *blitter, const SkIRect &ir, const SkRegion &clip)
static bool operator<(const SkEdge &a, const SkEdge &b)
static void PrePostInverseBlitterProc(SkBlitter *blitter, int y, bool isStart)
void SkTQSort(T *begin, T *end, const C &lessThan)
void setBlitter(SkBlitter *blitter, const SkIRect &clip, int shift)
void blitH(int x, int y, int width) override
Blit a horizontal run of one or more pixels.
void blitAntiH(int, int, const SkAlpha[], const int16_t runs[]) override
void blitMask(const SkMask &, const SkIRect &clip) override
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
void prepost(int y, bool isStart)
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
void init(const SkRasterClip &, SkBlitter *)
const SkRegion & getRgn() const
void blitRectRegion(const SkIRect &rect, const SkRegion &clip)
void blitRegion(const SkRegion &clip)
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.
const SkRect & getBounds() const
bool isRect(SkRect *rect, bool *isClosed=nullptr, SkPathDirection *direction=nullptr) const
void init(SkBlitter *blitter, const SkIRect &clipRect)
static SkRect MakeLargeS32()
@ kIntersect_Op
target intersected with operand
const SkIRect & getBounds() const
bool op(const SkIRect &rect, Op op)
void init(SkBlitter *blitter, const SkRegion *clipRgn)
SkScanClipper(SkBlitter *blitter, const SkRegion *clip, const SkIRect &bounds, bool skipRejectTest=false, bool boundsPreClipped=false)
SkBlitter * getBlitter() const
const SkIRect * getClipRect() const
static bool PathRequiresTiling(const SkIRect &bounds)
static void FillPath(const SkPath &, const SkIRect &, SkBlitter *)
static void FillTriangle(const SkPoint pts[], const SkRasterClip &, SkBlitter *)
int setLine(const SkPoint &p0, const SkPoint &p1, const SkIRect *clip, int shiftUp)
static bool Intersects(const SkIRect &a, const SkIRect &b)
int32_t fBottom
larger y-axis bounds
constexpr int32_t right() const
int32_t fTop
smaller y-axis bounds
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
void setBounds(const SkPoint pts[], int count)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)