| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkScanPriv.h" | 8 #include "SkScanPriv.h" |
| 9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
| 10 #include "SkEdge.h" | 10 #include "SkEdge.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 #else | 39 #else |
| 40 #define validate_sort(edge) | 40 #define validate_sort(edge) |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 static inline void remove_edge(SkEdge* edge) { | 43 static inline void remove_edge(SkEdge* edge) { |
| 44 edge->fPrev->fNext = edge->fNext; | 44 edge->fPrev->fNext = edge->fNext; |
| 45 edge->fNext->fPrev = edge->fPrev; | 45 edge->fNext->fPrev = edge->fPrev; |
| 46 } | 46 } |
| 47 | 47 |
| 48 static inline void insert_edge_after(SkEdge* edge, SkEdge* afterMe) { | 48 static inline void swap_edges(SkEdge* prev, SkEdge* next) { |
| 49 edge->fPrev = afterMe; | 49 SkASSERT(prev->fNext == next && next->fPrev == prev); |
| 50 edge->fNext = afterMe->fNext; | 50 |
| 51 afterMe->fNext->fPrev = edge; | 51 // remove prev from the list |
| 52 afterMe->fNext = edge; | 52 prev->fPrev->fNext = next; |
| 53 next->fPrev = prev->fPrev; |
| 54 |
| 55 // insert prev after next |
| 56 prev->fNext = next->fNext; |
| 57 next->fNext->fPrev = prev; |
| 58 next->fNext = prev; |
| 59 prev->fPrev = next; |
| 53 } | 60 } |
| 54 | 61 |
| 55 static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, cur
r_y)) { | 62 static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, cur
r_y)) { |
| 56 SkFixed x = edge->fX; | 63 SkFixed x = edge->fX; |
| 57 | 64 |
| 58 SkEdge* prev = edge->fPrev; | 65 for (;;) { |
| 59 while (prev->fX > x) { | 66 SkEdge* prev = edge->fPrev; |
| 60 prev = prev->fPrev; | 67 |
| 61 } | 68 // add 1 to curr_y since we may have added new edges (built from curves) |
| 62 if (prev->fNext != edge) { | 69 // that start on the next scanline |
| 63 remove_edge(edge); | 70 SkASSERT(prev && prev->fFirstY <= curr_y + 1); |
| 64 insert_edge_after(edge, prev); | 71 |
| 72 if (prev->fX <= x) { |
| 73 break; |
| 74 } |
| 75 swap_edges(prev, edge); |
| 65 } | 76 } |
| 66 } | 77 } |
| 67 | 78 |
| 68 static void insert_new_edges(SkEdge* newEdge, int curr_y) { | 79 static void insert_new_edges(SkEdge* newEdge, int curr_y) { |
| 69 SkASSERT(newEdge->fFirstY >= curr_y); | 80 SkASSERT(newEdge->fFirstY >= curr_y); |
| 70 | 81 |
| 71 while (newEdge->fFirstY == curr_y) { | 82 while (newEdge->fFirstY == curr_y) { |
| 72 SkEdge* next = newEdge->fNext; | 83 SkEdge* next = newEdge->fNext; |
| 73 backward_insert_edge_based_on_x(newEdge SkPARAM(curr_y)); | 84 backward_insert_edge_based_on_x(newEdge SkPARAM(curr_y)); |
| 74 newEdge = next; | 85 newEdge = next; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 95 #pragma warning ( push ) | 106 #pragma warning ( push ) |
| 96 #pragma warning ( disable : 4701 ) | 107 #pragma warning ( disable : 4701 ) |
| 97 #endif | 108 #endif |
| 98 | 109 |
| 99 typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline); | 110 typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline); |
| 100 #define PREPOST_START true | 111 #define PREPOST_START true |
| 101 #define PREPOST_END false | 112 #define PREPOST_END false |
| 102 | 113 |
| 103 static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType, | 114 static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType, |
| 104 SkBlitter* blitter, int start_y, int stop_y, | 115 SkBlitter* blitter, int start_y, int stop_y, |
| 105 PrePostProc proc, int rightClip) { | 116 PrePostProc proc) { |
| 106 validate_sort(prevHead->fNext); | 117 validate_sort(prevHead->fNext); |
| 107 | 118 |
| 108 int curr_y = start_y; | 119 int curr_y = start_y; |
| 109 // returns 1 for evenodd, -1 for winding, regardless of inverse-ness | 120 // returns 1 for evenodd, -1 for winding, regardless of inverse-ness |
| 110 int windingMask = (fillType & 1) ? 1 : -1; | 121 int windingMask = (fillType & 1) ? 1 : -1; |
| 111 | 122 |
| 112 for (;;) { | 123 for (;;) { |
| 113 int w = 0; | 124 int w = 0; |
| 114 int left SK_INIT_TO_AVOID_WARNING; | 125 int left SK_INIT_TO_AVOID_WARNING; |
| 115 bool in_interval = false; | 126 bool in_interval = false; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 if (newX < prevX) { // ripple currE backwards until it is x-sort
ed | 176 if (newX < prevX) { // ripple currE backwards until it is x-sort
ed |
| 166 backward_insert_edge_based_on_x(currE SkPARAM(curr_y)); | 177 backward_insert_edge_based_on_x(currE SkPARAM(curr_y)); |
| 167 } else { | 178 } else { |
| 168 prevX = newX; | 179 prevX = newX; |
| 169 } | 180 } |
| 170 } | 181 } |
| 171 currE = next; | 182 currE = next; |
| 172 SkASSERT(currE); | 183 SkASSERT(currE); |
| 173 } | 184 } |
| 174 | 185 |
| 175 // was our right-edge culled away? | |
| 176 if (in_interval) { | |
| 177 int width = rightClip - left; | |
| 178 if (width > 0) { | |
| 179 blitter->blitH(left, curr_y, width); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 if (proc) { | 186 if (proc) { |
| 184 proc(blitter, curr_y, PREPOST_END); // post-proc | 187 proc(blitter, curr_y, PREPOST_END); // post-proc |
| 185 } | 188 } |
| 186 | 189 |
| 187 curr_y += 1; | 190 curr_y += 1; |
| 188 if (curr_y >= stop_y) { | 191 if (curr_y >= stop_y) { |
| 189 break; | 192 break; |
| 190 } | 193 } |
| 191 // now currE points to the first edge with a Yint larger than curr_y | 194 // now currE points to the first edge with a Yint larger than curr_y |
| 192 insert_new_edges(currE, curr_y); | 195 insert_new_edges(currE, curr_y); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 // | 429 // |
| 427 // clipRect (if no null) has already been shifted up | 430 // clipRect (if no null) has already been shifted up |
| 428 // | 431 // |
| 429 void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
r, | 432 void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
r, |
| 430 int start_y, int stop_y, int shiftEdgesUp, | 433 int start_y, int stop_y, int shiftEdgesUp, |
| 431 const SkRegion& clipRgn) { | 434 const SkRegion& clipRgn) { |
| 432 SkASSERT(blitter); | 435 SkASSERT(blitter); |
| 433 | 436 |
| 434 SkEdgeBuilder builder; | 437 SkEdgeBuilder builder; |
| 435 | 438 |
| 436 // If we're convex, then we need both edges, even the right edge is past the
clip | 439 int count = builder.build(path, clipRect, shiftEdgesUp); |
| 437 const bool cullToTheRight = !path.isConvex(); | |
| 438 | |
| 439 int count = builder.build(path, clipRect, shiftEdgesUp, cullToTheRight); | |
| 440 SkEdge** list = builder.edgeList(); | 440 SkEdge** list = builder.edgeList(); |
| 441 | 441 |
| 442 if (count < 2) { | 442 if (count < 2) { |
| 443 if (path.isInverseFillType()) { | 443 if (path.isInverseFillType()) { |
| 444 /* | 444 /* |
| 445 * Since we are in inverse-fill, our caller has already drawn above | 445 * Since we are in inverse-fill, our caller has already drawn above |
| 446 * our top (start_y) and will draw below our bottom (stop_y). Thus | 446 * our top (start_y) and will draw below our bottom (stop_y). Thus |
| 447 * we need to restrict our drawing to the intersection of the clip | 447 * we need to restrict our drawing to the intersection of the clip |
| 448 * and those two limits. | 448 * and those two limits. |
| 449 */ | 449 */ |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 | 493 |
| 494 InverseBlitter ib; | 494 InverseBlitter ib; |
| 495 PrePostProc proc = NULL; | 495 PrePostProc proc = NULL; |
| 496 | 496 |
| 497 if (path.isInverseFillType()) { | 497 if (path.isInverseFillType()) { |
| 498 ib.setBlitter(blitter, clipRgn.getBounds(), shiftEdgesUp); | 498 ib.setBlitter(blitter, clipRgn.getBounds(), shiftEdgesUp); |
| 499 blitter = &ib; | 499 blitter = &ib; |
| 500 proc = PrePostInverseBlitterProc; | 500 proc = PrePostInverseBlitterProc; |
| 501 } | 501 } |
| 502 | 502 |
| 503 int rightEdge; | |
| 504 if (clipRect) { | |
| 505 rightEdge = clipRect->right(); | |
| 506 } else { | |
| 507 rightEdge = SkScalarRoundToInt(path.getBounds().right()); | |
| 508 } | |
| 509 | |
| 510 if (path.isConvex() && (NULL == proc)) { | 503 if (path.isConvex() && (NULL == proc)) { |
| 511 walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_
y, NULL); | 504 walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_
y, NULL); |
| 512 } else { | 505 } else { |
| 513 walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc
, rightEdge); | 506 walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc
); |
| 514 } | 507 } |
| 515 } | 508 } |
| 516 | 509 |
| 517 void sk_blit_above(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip)
{ | 510 void sk_blit_above(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip)
{ |
| 518 const SkIRect& cr = clip.getBounds(); | 511 const SkIRect& cr = clip.getBounds(); |
| 519 SkIRect tmp; | 512 SkIRect tmp; |
| 520 | 513 |
| 521 tmp.fLeft = cr.fLeft; | 514 tmp.fLeft = cr.fLeft; |
| 522 tmp.fRight = cr.fRight; | 515 tmp.fRight = cr.fRight; |
| 523 tmp.fTop = cr.fTop; | 516 tmp.fTop = cr.fTop; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 clipRgn = &wrap.getRgn(); | 724 clipRgn = &wrap.getRgn(); |
| 732 blitter = wrap.getBlitter(); | 725 blitter = wrap.getBlitter(); |
| 733 } | 726 } |
| 734 | 727 |
| 735 SkScanClipper clipper(blitter, clipRgn, ir); | 728 SkScanClipper clipper(blitter, clipRgn, ir); |
| 736 blitter = clipper.getBlitter(); | 729 blitter = clipper.getBlitter(); |
| 737 if (blitter) { | 730 if (blitter) { |
| 738 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); | 731 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); |
| 739 } | 732 } |
| 740 } | 733 } |
| OLD | NEW |