add isRect() check to AAClip, to detect if a soft-clip is really just an irect
taken from (https://codereview.chromium.org/445233006/)
fix: don't assume that the first yoffset is 0, since we may have performed a translate and not
re-alloced our data.
This reverts commit 0aeea6d344
.
TBR=
Author: reed@google.com
Review URL: https://codereview.chromium.org/443353004
This commit is contained in:
parent
7b62448065
commit
202ab2a5ca
@ -684,6 +684,34 @@ bool SkAAClip::setRect(const SkIRect& bounds) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SkAAClip::isRect() const {
|
||||
if (this->isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RunHead* head = fRunHead;
|
||||
if (head->fRowCount != 1) {
|
||||
return false;
|
||||
}
|
||||
const YOffset* yoff = head->yoffsets();
|
||||
if (yoff->fY != fBounds.fBottom - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t* row = head->data() + yoff->fOffset;
|
||||
int width = fBounds.width();
|
||||
do {
|
||||
if (row[1] != 0xFF) {
|
||||
return false;
|
||||
}
|
||||
int n = row[0];
|
||||
SkASSERT(n <= width);
|
||||
width -= n;
|
||||
row += 2;
|
||||
} while (width > 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkAAClip::setRect(const SkRect& r, bool doAA) {
|
||||
if (r.isEmpty()) {
|
||||
return this->setEmpty();
|
||||
|
@ -29,6 +29,10 @@ public:
|
||||
bool isEmpty() const { return NULL == fRunHead; }
|
||||
const SkIRect& getBounds() const { return fBounds; }
|
||||
|
||||
// Returns true iff the clip is not empty, and is just a hard-edged rect (no partial alpha).
|
||||
// If true, getBounds() can be used in place of this clip.
|
||||
bool isRect() const;
|
||||
|
||||
bool setEmpty();
|
||||
bool setRect(const SkIRect&);
|
||||
bool setRect(const SkRect&, bool doAA = true);
|
||||
|
@ -222,7 +222,10 @@ void SkRasterClip::convertToAA() {
|
||||
SkASSERT(fIsBW);
|
||||
fAA.setRegion(fBW);
|
||||
fIsBW = false;
|
||||
(void)this->updateCacheAndReturnNonEmpty();
|
||||
|
||||
// since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize"
|
||||
// ourselves back to BW.
|
||||
(void)this->updateCacheAndReturnNonEmpty(false);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
|
@ -89,11 +89,19 @@ private:
|
||||
}
|
||||
|
||||
bool computeIsRect() const {
|
||||
return fIsBW ? fBW.isRect() : false;
|
||||
return fIsBW ? fBW.isRect() : fAA.isRect();
|
||||
}
|
||||
|
||||
bool updateCacheAndReturnNonEmpty() {
|
||||
bool updateCacheAndReturnNonEmpty(bool detectAARect = true) {
|
||||
fIsEmpty = this->computeIsEmpty();
|
||||
|
||||
// detect that our computed AA is really just a (hard-edged) rect
|
||||
if (detectAARect && !fIsEmpty && !fIsBW && fAA.isRect()) {
|
||||
fBW.setRect(fAA.getBounds());
|
||||
fAA.setEmpty(); // don't need this guy anymore
|
||||
fIsBW = true;
|
||||
}
|
||||
|
||||
fIsRect = this->computeIsRect();
|
||||
return !fIsEmpty;
|
||||
}
|
||||
|
@ -318,6 +318,30 @@ static void test_path_with_hole(skiatest::Reporter* reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_really_a_rect(skiatest::Reporter* reporter) {
|
||||
SkRRect rrect;
|
||||
rrect.setRectXY(SkRect::MakeWH(100, 100), 5, 5);
|
||||
|
||||
SkPath path;
|
||||
path.addRRect(rrect);
|
||||
|
||||
SkAAClip clip;
|
||||
clip.setPath(path);
|
||||
|
||||
REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeWH(100, 100));
|
||||
REPORTER_ASSERT(reporter, !clip.isRect());
|
||||
|
||||
// This rect should intersect the clip, but slice-out all of the "soft" parts,
|
||||
// leaving just a rect.
|
||||
const SkIRect ir = SkIRect::MakeLTRB(10, -10, 50, 90);
|
||||
|
||||
clip.op(ir, SkRegion::kIntersect_Op);
|
||||
|
||||
REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeLTRB(10, 0, 50, 90));
|
||||
// the clip recognized that that it is just a rect!
|
||||
REPORTER_ASSERT(reporter, clip.isRect());
|
||||
}
|
||||
|
||||
#include "SkRasterClip.h"
|
||||
|
||||
static void copyToMask(const SkRasterClip& rc, SkMask* mask) {
|
||||
@ -404,4 +428,5 @@ DEF_TEST(AAClip, reporter) {
|
||||
test_path_with_hole(reporter);
|
||||
test_regressions();
|
||||
test_nearly_integral(reporter);
|
||||
test_really_a_rect(reporter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user