Chromium Code Reviews| Index: src/core/SkScan_AntiPath.cpp |
| diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp |
| index b7d470715de0e9786c9442c20e20999bbd5e3dd7..6049e7909b4b3b20f77826e565738d7db8c85177 100644 |
| --- a/src/core/SkScan_AntiPath.cpp |
| +++ b/src/core/SkScan_AntiPath.cpp |
| @@ -45,7 +45,7 @@ |
| class BaseSuperBlitter : public SkBlitter { |
| public: |
| BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip); |
| + const SkRegion& clip, bool isInverse); |
| /// Must be explicitly defined on subclasses. |
| virtual void blitAntiH(int x, int y, const SkAlpha antialias[], |
| @@ -73,38 +73,44 @@ protected: |
| int fCurrY; |
| /// Initial y coordinate (top of bounds). |
| int fTop; |
| + |
| + SkIRect fSectBounds; |
| }; |
| -BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip) { |
| - fRealBlitter = realBlitter; |
| +BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir, const SkRegion& clip, |
| + bool isInverse) { |
| + fRealBlitter = realBlit; |
| + |
| + SkIRect sectBounds; |
| + if (isInverse) { |
| + sectBounds = clip.getBounds(); |
| + } else { |
| + if (!sectBounds.intersect(ir, clip.getBounds())) { |
| + sectBounds.setEmpty(); |
| + } |
| + } |
| /* |
| * We use the clip bounds instead of the ir, since we may be asked to |
| * draw outside of the rect if we're a inverse filltype |
|
caryclark
2014/10/15 15:51:31
comment no longer accurate?
|
| */ |
| - const int left = clip.getBounds().fLeft; |
| - const int right = clip.getBounds().fRight; |
| + const int left = sectBounds.left(); |
| + const int right = sectBounds.right(); |
| fLeft = left; |
| fSuperLeft = left << SHIFT; |
| fWidth = right - left; |
| -#if 0 |
| - fCurrIY = -1; |
| - fCurrY = -1; |
| -#else |
| - fTop = ir.fTop; |
| - fCurrIY = ir.fTop - 1; |
| - fCurrY = (ir.fTop << SHIFT) - 1; |
| -#endif |
| + fTop = sectBounds.top(); |
| + fCurrIY = fTop - 1; |
| + fCurrY = (fTop << SHIFT) - 1; |
| + |
| SkDEBUGCODE(fCurrX = -1;) |
| } |
| /// Run-length-encoded supersampling antialiased blitter. |
| class SuperBlitter : public BaseSuperBlitter { |
| public: |
| - SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip); |
| + SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse); |
| virtual ~SuperBlitter() { |
| this->flush(); |
| @@ -149,9 +155,10 @@ private: |
| int fOffsetX; |
| }; |
| -SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip) |
| - : BaseSuperBlitter(realBlitter, ir, clip) { |
| +SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, |
| + bool isInverse) |
| + : BaseSuperBlitter(realBlitter, ir, clip, isInverse) |
| +{ |
| fRunsToBuffer = realBlitter->requestRowsPreserved(); |
| fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz()); |
| fCurrentRun = -1; |
| @@ -398,8 +405,7 @@ void SuperBlitter::blitRect(int x, int y, int width, int height) { |
| /// Masked supersampling antialiased blitter. |
| class MaskSuperBlitter : public BaseSuperBlitter { |
| public: |
| - MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip); |
| + MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion&, bool isInverse); |
| virtual ~MaskSuperBlitter() { |
| fRealBlitter->blitMask(fMask, fClipRect); |
| } |
| @@ -437,10 +443,12 @@ private: |
| uint32_t fStorage[(kMAX_STORAGE >> 2) + 1]; |
| }; |
| -MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| - const SkRegion& clip) |
| - : BaseSuperBlitter(realBlitter, ir, clip) { |
| +MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, |
| + bool isInverse) |
| + : BaseSuperBlitter(realBlitter, ir, clip, isInverse) |
| +{ |
| SkASSERT(CanHandleRect(ir)); |
| + SkASSERT(!isInverse); |
| fMask.fImage = (uint8_t*)fStorage; |
| fMask.fBounds = ir; |
| @@ -628,6 +636,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| return; |
| } |
| + const bool isInverse = path.isInverseFillType(); |
| SkIRect ir; |
| if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) { |
| @@ -638,7 +647,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| return; |
| } |
| if (ir.isEmpty()) { |
| - if (path.isInverseFillType()) { |
| + if (isInverse) { |
| blitter->blitRegion(origClip); |
| } |
| return; |
| @@ -648,7 +657,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| // will overflow 32767 when << by SHIFT, we can't supersample, |
| // so draw without antialiasing. |
| SkIRect clippedIR; |
| - if (path.isInverseFillType()) { |
| + if (isInverse) { |
| // If the path is an inverse fill, it's going to fill the entire |
| // clip, and we care whether the entire clip exceeds our limits. |
| clippedIR = origClip.getBounds(); |
| @@ -685,7 +694,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| const SkIRect* clipRect = clipper.getClipRect(); |
| if (clipper.getBlitter() == NULL) { // clipped out |
| - if (path.isInverseFillType()) { |
| + if (isInverse) { |
| blitter->blitRegion(*clipRgn); |
| } |
| return; |
| @@ -694,7 +703,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| // now use the (possibly wrapped) blitter |
| blitter = clipper.getBlitter(); |
| - if (path.isInverseFillType()) { |
| + if (isInverse) { |
| sk_blit_above(blitter, ir, *clipRgn); |
| } |
| @@ -710,16 +719,16 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it |
| // if we're an inverse filltype |
| - if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) { |
| - MaskSuperBlitter superBlit(blitter, ir, *clipRgn); |
| + if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) { |
| + MaskSuperBlitter superBlit(blitter, ir, *clipRgn, isInverse); |
| SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); |
| sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn); |
| } else { |
| - SuperBlitter superBlit(blitter, ir, *clipRgn); |
| + SuperBlitter superBlit(blitter, ir, *clipRgn, isInverse); |
| sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn); |
| } |
| - if (path.isInverseFillType()) { |
| + if (isInverse) { |
| sk_blit_below(blitter, ir, *clipRgn); |
| } |
| } |