SkAAClip.cpp revision 34f7e47a3593911d03307a08e5af625b218ceec3
1e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 2e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/* 3e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * Copyright 2011 Google Inc. 4e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * 5e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * Use of this source code is governed by a BSD-style license that can be 6e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * found in the LICENSE file. 7e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com */ 8e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 9e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkAAClip.h" 10e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkBlitter.h" 11e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkPath.h" 12e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkScan.h" 13e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#include "SkThread.h" 1434f7e47a3593911d03307a08e5af625b218ceec3reed@google.com#include "SkUtils.h" 15e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 161c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com#define kMaxInt32 0x7FFFFFFF 171c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 18e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstatic inline bool x_in_rect(int x, const SkIRect& rect) { 19e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 20e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 21e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 22e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstatic inline bool y_in_rect(int y, const SkIRect& rect) { 23e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 24e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 25e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 26e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/* 27e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com * Data runs are packed [count, alpha] 28e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com */ 29e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 30e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstruct SkAAClip::YOffset { 31e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int32_t fY; 32e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com uint32_t fOffset; 33e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com}; 34e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 35e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstruct SkAAClip::RunHead { 36e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int32_t fRefCnt; 37e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int32_t fRowCount; 38e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int32_t fDataSize; 39e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 40e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com YOffset* yoffsets() { 41e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (YOffset*)((char*)this + sizeof(RunHead)); 42e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 43e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const YOffset* yoffsets() const { 44e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (const YOffset*)((const char*)this + sizeof(RunHead)); 45e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 46e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com uint8_t* data() { 47e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (uint8_t*)(this->yoffsets() + fRowCount); 48e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 49e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* data() const { 50e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return (const uint8_t*)(this->yoffsets() + fRowCount); 51e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 52e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 53e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com static RunHead* Alloc(int rowCount, size_t dataSize) { 54e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com size_t size = sizeof(RunHead) + rowCount * sizeof(YOffset) + dataSize; 55e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com RunHead* head = (RunHead*)sk_malloc_throw(size); 56e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com head->fRefCnt = 1; 57e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com head->fRowCount = rowCount; 58e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com head->fDataSize = dataSize; 59e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return head; 60e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 61e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com}; 62e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 63322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comclass SkAAClip::Iter { 64322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.compublic: 65322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com Iter(const SkAAClip&); 66322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 67322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool done() const { return fDone; } 681c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com int top() const { return fTop; } 691c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com int bottom() const { return fBottom; } 701c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com const uint8_t* data() const { return fData; } 71322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com void next(); 72322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 73322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comprivate: 74322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const YOffset* fCurrYOff; 75322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const YOffset* fStopYOff; 76322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* fData; 77322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 78322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int fTop, fBottom; 79322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool fDone; 80322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com}; 81322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 82322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comSkAAClip::Iter::Iter(const SkAAClip& clip) { 83322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (clip.isEmpty()) { 84322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fDone = true; 851c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fTop = fBottom = clip.fBounds.fBottom; 861c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fData = NULL; 87322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return; 88322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 89322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 90322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const RunHead* head = clip.fRunHead; 91322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fCurrYOff = head->yoffsets(); 92322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fStopYOff = fCurrYOff + head->fRowCount; 93322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fData = head->data() + fCurrYOff->fOffset; 94322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 95322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // setup first value 96322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fTop = clip.fBounds.fTop; 97322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fBottom = clip.fBounds.fTop + fCurrYOff->fY + 1; 98322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fDone = false; 99322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 100322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 101322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comvoid SkAAClip::Iter::next() { 1021c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (!fDone) { 1031c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com const YOffset* prev = fCurrYOff; 1041c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com const YOffset* curr = prev + 1; 1051c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(curr <= fStopYOff); 106322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 107322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fTop = fBottom; 1081c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (curr >= fStopYOff) { 1091c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fDone = true; 1101c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fBottom = kMaxInt32; 1111c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fData = NULL; 1121c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 1131c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fBottom += curr->fY - prev->fY; 1141c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fData += curr->fOffset - prev->fOffset; 1151c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fCurrYOff = curr; 1161c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 117322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 118322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 119322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 120e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 121e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 122e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClip::freeRuns() { 12347ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com if (fRunHead) { 124e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fRunHead->fRefCnt >= 1); 125e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (1 == sk_atomic_dec(&fRunHead->fRefCnt)) { 126e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com sk_free(fRunHead); 127e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 128e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 129e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 130e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 131e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comSkAAClip::SkAAClip() { 132e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBounds.setEmpty(); 13347ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com fRunHead = NULL; 134e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 135e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 136e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comSkAAClip::SkAAClip(const SkAAClip& src) { 13747ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com fRunHead = NULL; 138e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com *this = src; 139e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 140e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 141e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comSkAAClip::~SkAAClip() { 142e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->freeRuns(); 143e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 144e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 145e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comSkAAClip& SkAAClip::operator=(const SkAAClip& src) { 146e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (this != &src) { 147e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->freeRuns(); 148e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBounds = src.fBounds; 149e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fRunHead = src.fRunHead; 15047ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com if (fRunHead) { 151e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com sk_atomic_inc(&fRunHead->fRefCnt); 152e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 153e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 154e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return *this; 155e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 156e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 157e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.combool operator==(const SkAAClip& a, const SkAAClip& b) { 158e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (&a == &b) { 159e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return true; 160e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 161e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (a.fBounds != b.fBounds) { 162e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 163e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 164e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 165e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const SkAAClip::RunHead* ah = a.fRunHead; 166e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const SkAAClip::RunHead* bh = b.fRunHead; 167e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 168e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // this catches empties and rects being equal 169e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (ah == bh) { 170e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return true; 171e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 172e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 173e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // now we insist that both are complex (but different ptrs) 17447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com if (!a.fRunHead || !b.fRunHead) { 175e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 176e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 177e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 178e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return ah->fRowCount == bh->fRowCount && 179e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ah->fDataSize == bh->fDataSize && 180e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com !memcmp(ah->data(), bh->data(), ah->fDataSize); 181e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 182e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 183e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClip::swap(SkAAClip& other) { 184e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkTSwap(fBounds, other.fBounds); 185e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkTSwap(fRunHead, other.fRunHead); 186e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 187e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 188322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.combool SkAAClip::set(const SkAAClip& src) { 189322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com *this = src; 190322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return !this->isEmpty(); 191322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 192322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 193e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.combool SkAAClip::setEmpty() { 194e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->freeRuns(); 195e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBounds.setEmpty(); 19647ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com fRunHead = NULL; 197e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 198e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 199e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 200e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.combool SkAAClip::setRect(const SkIRect& bounds) { 201e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (bounds.isEmpty()) { 202e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return this->setEmpty(); 203e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 20447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com 20547ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com // TODO: special case this 20647ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com 20747ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com SkRect r; 20847ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com r.set(bounds); 20947ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com SkPath path; 21047ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com path.addRect(r); 21147ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com return this->setPath(path); 212e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 213e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 214f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.combool SkAAClip::setRect(const SkRect& r, bool doAA) { 215e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (r.isEmpty()) { 216e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return this->setEmpty(); 217e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 218e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 219e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkPath path; 220e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com path.addRect(r); 221f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com return this->setPath(path, NULL, doAA); 222f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com} 223f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com 224f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.combool SkAAClip::setRegion(const SkRegion& rgn) { 225f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com if (rgn.isEmpty()) { 226f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com return this->setEmpty(); 227f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com } 228f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com if (rgn.isRect()) { 229f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com return this->setRect(rgn.getBounds()); 230f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com } 231f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com 232f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com SkAAClip clip; 233f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com SkRegion::Iterator iter(rgn); 234f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com for (; !iter.done(); iter.next()) { 235f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com clip.op(iter.rect(), SkRegion::kUnion_Op); 236f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com } 237f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com this->swap(clip); 2383771a030b0b6686b0ec81359774836cc376ea3f4reed@google.com return !this->isEmpty(); 239e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 240e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 241e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 242e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 243e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comconst uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const { 24447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com SkASSERT(fRunHead); 245e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 246e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (!y_in_rect(y, fBounds)) { 247e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return NULL; 248e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 249e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com y -= fBounds.y(); // our yoffs values are relative to the top 250e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 251e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const YOffset* yoff = fRunHead->yoffsets(); 252e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com while (yoff->fY < y) { 253e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com yoff += 1; 254e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(yoff - fRunHead->yoffsets() < fRunHead->fRowCount); 255e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 256e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 257e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (lastYForRow) { 258e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com *lastYForRow = yoff->fY; 259e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 260e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return fRunHead->data() + yoff->fOffset; 261e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 262e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 263e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comconst uint8_t* SkAAClip::findX(const uint8_t data[], int x, int* initialCount) const { 264e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(x_in_rect(x, fBounds)); 265e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com x -= fBounds.x(); 266e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 267e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // first skip up to X 268e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (;;) { 269e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int n = data[0]; 270e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (x < n) { 271e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com *initialCount = n - x; 272e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com break; 273e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 274e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com data += 2; 275e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com x -= n; 276e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 277e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return data; 278e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 279e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 280e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.combool SkAAClip::quickContains(int left, int top, int right, int bottom) const { 281e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (this->isEmpty()) { 282e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 283e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 284e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (!fBounds.contains(left, top, right, bottom)) { 285e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 286e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 287322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com#if 0 288e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (this->isRect()) { 289e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return true; 290e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 291322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com#endif 292e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 293e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int lastY; 294e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* row = this->findRow(top, &lastY); 295e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (lastY < bottom) { 296e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return false; 297e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 298e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // now just need to check in X 299e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int initialCount; 300e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = this->findX(row, left, &initialCount); 301e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return initialCount >= (right - left) && 0xFF == row[1]; 302e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 303e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 304e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 305e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 306e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comclass SkAAClip::Builder { 307e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkIRect fBounds; 308e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com struct Row { 309e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int fY; 310e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int fWidth; 311e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkTDArray<uint8_t>* fData; 312e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com }; 313e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkTDArray<Row> fRows; 314e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* fCurrRow; 315e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int fPrevY; 316e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int fWidth; 317e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 318e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.compublic: 319e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Builder(const SkIRect& bounds) : fBounds(bounds) { 320e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fPrevY = -1; 321e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fWidth = bounds.width(); 322e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fCurrRow = NULL; 323e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 324e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 325e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ~Builder() { 326e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* row = fRows.begin(); 327e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* stop = fRows.end(); 328e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com while (row < stop) { 329e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com delete row->fData; 330e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row += 1; 331e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 332e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 333e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 334322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const SkIRect& getBounds() const { return fBounds; } 335322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 336e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com void addRun(int x, int y, U8CPU alpha, int count) { 337e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(count > 0); 338e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fBounds.contains(x, y)); 339e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fBounds.contains(x + count - 1, y)); 340e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 341e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com x -= fBounds.left(); 342e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com y -= fBounds.top(); 343e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 344e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* row = fCurrRow; 345e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (y != fPrevY) { 346e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(y > fPrevY); 347e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fPrevY = y; 348e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = this->flushRow(true); 349e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row->fY = y; 350e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row->fWidth = 0; 351e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(row->fData); 352e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(0 == row->fData->count()); 353e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fCurrRow = row; 354e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 355e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 356e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(row->fWidth <= x); 357e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(row->fWidth < fBounds.width()); 358e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 359e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkTDArray<uint8_t>& data = *row->fData; 360e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 361e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int gap = x - row->fWidth; 362e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (gap) { 363e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com AppendRun(data, 0, gap); 364e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row->fWidth += gap; 365e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(row->fWidth < fBounds.width()); 366e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 367e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 368e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com AppendRun(data, alpha, count); 369e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row->fWidth += count; 370e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(row->fWidth <= fBounds.width()); 371e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 372e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 373e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com RunHead* finish() { 374e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->flushRow(false); 375e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 376e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const Row* row = fRows.begin(); 377e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const Row* stop = fRows.end(); 378e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 379e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com size_t dataSize = 0; 380e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com while (row < stop) { 381e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com dataSize += row->fData->count(); 382e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row += 1; 383e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 384e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 385e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com RunHead* head = RunHead::Alloc(fRows.count(), dataSize); 386e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com YOffset* yoffset = head->yoffsets(); 387e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com uint8_t* data = head->data(); 388e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com uint8_t* baseData = data; 389e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 390e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = fRows.begin(); 391e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com while (row < stop) { 392e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com yoffset->fY = row->fY; 393e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com yoffset->fOffset = data - baseData; 394e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com yoffset += 1; 395e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 396e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com size_t n = row->fData->count(); 397e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com memcpy(data, row->fData->begin(), n); 398e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com data += n; 399e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 400e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row += 1; 401e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 402e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 403e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return head; 404e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 405e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 406e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com void dump() { 407e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->validate(); 408e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int y; 409e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (y = 0; y < fRows.count(); ++y) { 410e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const Row& row = fRows[y]; 411e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf("Y:%3d W:%3d", row.fY, row.fWidth); 412e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const SkTDArray<uint8_t>& data = *row.fData; 413e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = data.count(); 414e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(!(count & 1)); 415e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* ptr = data.begin(); 416e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int x = 0; x < count; x += 2) { 417e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf(" [%3d:%02X]", ptr[0], ptr[1]); 418e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ptr += 2; 419e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 420e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf("\n"); 421e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 422e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 4231c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com#if 0 424e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int prevY = -1; 425e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (y = 0; y < fRows.count(); ++y) { 426e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const Row& row = fRows[y]; 427e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const SkTDArray<uint8_t>& data = *row.fData; 428e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = data.count(); 429e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int n = prevY; n < row.fY; ++n) { 430e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* ptr = data.begin(); 431e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int x = 0; x < count; x += 2) { 432e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int i = 0; i < ptr[0]; ++i) { 433e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf("%02X", ptr[1]); 434e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 435e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ptr += 2; 436e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 437e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf("\n"); 438e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 439e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com prevY = row.fY; 440e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 441e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#endif 442e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 443e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 444e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com void validate() { 445e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#ifdef SK_DEBUG 446e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int prevY = -1; 447e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int i = 0; i < fRows.count(); ++i) { 448e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const Row& row = fRows[i]; 449e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(prevY < row.fY); 450e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fWidth == row.fWidth); 451e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = row.fData->count(); 452e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* ptr = row.fData->begin(); 453e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(!(count & 1)); 454e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int w = 0; 455e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (int x = 0; x < count; x += 2) { 456e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com w += ptr[0]; 457e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(w <= fWidth); 458e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ptr += 2; 459e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 460e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(w == fWidth); 461e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com prevY = row.fY; 462e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 463e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com#endif 464e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 465e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 466e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comprivate: 467e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* flushRow(bool readyForAnother) { 468e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* next = NULL; 469e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = fRows.count(); 470e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (count > 0) { 471e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // flush current row if needed 472e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* curr = &fRows[count - 1]; 473e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (curr->fWidth < fWidth) { 474e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com AppendRun(*curr->fData, 0, fWidth - curr->fWidth); 475e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 476e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 477e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (count > 1) { 478e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // are our last two runs the same? 479e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* prev = &fRows[count - 2]; 480e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Row* curr = &fRows[count - 1]; 481e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(prev->fWidth == fWidth); 482e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(curr->fWidth == fWidth); 483e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (*prev->fData == *curr->fData) { 484e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com prev->fY = curr->fY; 485e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (readyForAnother) { 486e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com curr->fData->rewind(); 487e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com next = curr; 488e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } else { 489e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com delete curr->fData; 490e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fRows.removeShuffle(count - 1); 491e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 492e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } else { 493e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (readyForAnother) { 494e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com next = fRows.append(); 495e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com next->fData = new SkTDArray<uint8_t>; 496e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 497e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 498e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } else { 499e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (readyForAnother) { 500e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com next = fRows.append(); 501e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com next->fData = new SkTDArray<uint8_t>; 502e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 503e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 504e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return next; 505e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 506e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 507e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com static void AppendRun(SkTDArray<uint8_t>& data, U8CPU alpha, int count) { 508e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com do { 509e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int n = count; 510e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (n > 255) { 511e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com n = 255; 512e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 513e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com uint8_t* ptr = data.append(2); 514e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ptr[0] = n; 515e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com ptr[1] = alpha; 516e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com count -= n; 517e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } while (count > 0); 518e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 519e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com}; 520e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 521e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comclass SkAAClip::BuilderBlitter : public SkBlitter { 522e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.compublic: 523e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com BuilderBlitter(Builder* builder) { 524e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBuilder = builder; 5251778564c75de5799d45126984f8faafd03523100reed@google.com fLeft = builder->getBounds().fLeft; 5261778564c75de5799d45126984f8faafd03523100reed@google.com fRight = builder->getBounds().fRight; 527e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 528e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 529e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE 530e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com { unexpected(); } 531e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE 532e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com { unexpected(); } 533e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE 534e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com { unexpected(); } 535e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 536e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual const SkBitmap* justAnOpaqueColor(uint32_t*) SK_OVERRIDE { 5373771a030b0b6686b0ec81359774836cc376ea3f4reed@google.com return NULL; 538e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 539e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 540e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual void blitH(int x, int y, int width) SK_OVERRIDE { 541e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBuilder->addRun(x, y, 0xFF, width); 542e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 543e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 544e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com virtual void blitAntiH(int x, int y, const SkAlpha alpha[], 545e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const int16_t runs[]) SK_OVERRIDE { 546e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (;;) { 547e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = *runs; 548e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (count <= 0) { 549e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return; 550e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 5511778564c75de5799d45126984f8faafd03523100reed@google.com 5521778564c75de5799d45126984f8faafd03523100reed@google.com // The supersampler's buffer can be the width of the device, so 5531778564c75de5799d45126984f8faafd03523100reed@google.com // we may have to trim the run to our bounds. If so, we assert that 5541778564c75de5799d45126984f8faafd03523100reed@google.com // the extra spans are always alpha==0 5551778564c75de5799d45126984f8faafd03523100reed@google.com int localX = x; 5561778564c75de5799d45126984f8faafd03523100reed@google.com int localCount = count; 5571778564c75de5799d45126984f8faafd03523100reed@google.com if (x < fLeft) { 5581778564c75de5799d45126984f8faafd03523100reed@google.com SkASSERT(0 == *alpha); 5591778564c75de5799d45126984f8faafd03523100reed@google.com int gap = fLeft - x; 5601778564c75de5799d45126984f8faafd03523100reed@google.com SkASSERT(gap <= count); 5611778564c75de5799d45126984f8faafd03523100reed@google.com localX += gap; 5621778564c75de5799d45126984f8faafd03523100reed@google.com localCount -= gap; 5631778564c75de5799d45126984f8faafd03523100reed@google.com } 5641778564c75de5799d45126984f8faafd03523100reed@google.com int right = x + count; 5651778564c75de5799d45126984f8faafd03523100reed@google.com if (right > fRight) { 5661778564c75de5799d45126984f8faafd03523100reed@google.com SkASSERT(0 == *alpha); 5671778564c75de5799d45126984f8faafd03523100reed@google.com localCount -= right - fRight; 5681778564c75de5799d45126984f8faafd03523100reed@google.com SkASSERT(localCount >= 0); 5691778564c75de5799d45126984f8faafd03523100reed@google.com } 5701778564c75de5799d45126984f8faafd03523100reed@google.com 5711778564c75de5799d45126984f8faafd03523100reed@google.com if (localCount) { 5721778564c75de5799d45126984f8faafd03523100reed@google.com fBuilder->addRun(localX, y, *alpha, localCount); 5731778564c75de5799d45126984f8faafd03523100reed@google.com } 5741778564c75de5799d45126984f8faafd03523100reed@google.com NEXT_RUN: 575e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com runs += count; 576e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com alpha += count; 577e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com x += count; 578e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 579e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 580e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 581e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comprivate: 582e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Builder* fBuilder; 5831778564c75de5799d45126984f8faafd03523100reed@google.com int fLeft; // cache of builder's bounds' left edge 5841778564c75de5799d45126984f8faafd03523100reed@google.com int fRight; 585e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 586e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com void unexpected() { 587e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDebugf("---- did not expect to get called here"); 588e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com sk_throw(); 589e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 590e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com}; 591e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 592f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.combool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) { 593322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (clip && clip->isEmpty()) { 594e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return this->setEmpty(); 595e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 596e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 597e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkIRect ibounds; 598322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com path.getBounds().roundOut(&ibounds); 599e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 600322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkRegion tmpClip; 601322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (NULL == clip) { 602322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com tmpClip.setRect(ibounds); 603322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com clip = &tmpClip; 604322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 605322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 606e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (!path.isInverseFillType()) { 607322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (ibounds.isEmpty() || !ibounds.intersect(clip->getBounds())) { 608e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return this->setEmpty(); 609e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 610e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 611e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 612e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com Builder builder(ibounds); 613e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com BuilderBlitter blitter(&builder); 614e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 615f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com if (doAA) { 616f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com SkScan::AntiFillPath(path, *clip, &blitter, true); 617f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com } else { 618f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com SkScan::FillPath(path, *clip, &blitter); 619f3c1da1e977a0e02535af71749fe9e92665ed51ereed@google.com } 620e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 621e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->freeRuns(); 622e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBounds = ibounds; 623e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fRunHead = builder.finish(); 624e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 6253771a030b0b6686b0ec81359774836cc376ea3f4reed@google.com //builder.dump(); 6263771a030b0b6686b0ec81359774836cc376ea3f4reed@google.com return !this->isEmpty(); 627e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 628e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 629e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 630e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 631322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comtypedef void (*RowProc)(SkAAClip::Builder&, int bottom, 632322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* rowA, const SkIRect& rectA, 633322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* rowB, const SkIRect& rectB); 634322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 635322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic void sectRowProc(SkAAClip::Builder& builder, int bottom, 636322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* rowA, const SkIRect& rectA, 637322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* rowB, const SkIRect& rectB) { 638322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 639322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 640322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 641322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comtypedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB); 642322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 643322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) { 644322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // Multiply 645322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return SkMulDiv255Round(alphaA, alphaB); 646322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 647322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 648322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) { 649322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // SrcOver 650322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return alphaA + alphaB - SkMulDiv255Round(alphaA, alphaB); 651322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 652322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 653322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic U8CPU diffAlphaProc(U8CPU alphaA, U8CPU alphaB) { 654322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // SrcOut 655322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return SkMulDiv255Round(alphaA, 0xFF - alphaB); 656322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 657322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 658322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic U8CPU xorAlphaProc(U8CPU alphaA, U8CPU alphaB) { 659322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // XOR 660322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return alphaA + alphaB - 2 * SkMulDiv255Round(alphaA, alphaB); 661322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 662322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 663322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic AlphaProc find_alpha_proc(SkRegion::Op op) { 664322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com switch (op) { 665322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kIntersect_Op: 666322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return sectAlphaProc; 667322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kDifference_Op: 668322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return diffAlphaProc; 669322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kUnion_Op: 670322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return unionAlphaProc; 671322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kXOR_Op: 672322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return xorAlphaProc; 673322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com default: 674322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(!"unexpected region op"); 675322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return sectAlphaProc; 676322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 677322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 678322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 679322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic const uint8_t gEmptyRow[] = { 680322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 681322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 682322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 683322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 684322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 685322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 686322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 687322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 688322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com}; 689322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 690322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comclass RowIter { 691322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.compublic: 692322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com RowIter(const uint8_t* row, const SkIRect& bounds) { 693322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fRow = row; 694322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fLeft = bounds.fLeft; 695322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fBoundsRight = bounds.fRight; 6961c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (row) { 6971c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fRight = bounds.fLeft + row[0]; 6981c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(fRight <= fBoundsRight); 6991c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fAlpha = row[1]; 7001c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fDone = false; 7011c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 7021c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fDone = true; 7031c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fRight = kMaxInt32; 7041c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fAlpha = 0; 7051c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 706322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 707322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 708322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool done() const { return fDone; } 7091c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com int left() const { return fLeft; } 7101c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com int right() const { return fRight; } 7111c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com U8CPU alpha() const { return fAlpha; } 712322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com void next() { 7131c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (!fDone) { 714322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fLeft = fRight; 7151c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (fRight == fBoundsRight) { 7161c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fDone = true; 7171c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fRight = kMaxInt32; 7181c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fAlpha = 0; 7191c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 7201c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fRow += 2; 7211c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fRight += fRow[0]; 7221c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com fAlpha = fRow[1]; 7231c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(fRight <= fBoundsRight); 7241c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 725322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 726322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 727322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 728322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comprivate: 729322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* fRow; 730322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int fLeft; 731322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int fRight; 732322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int fBoundsRight; 733322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool fDone; 7341c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com uint8_t fAlpha; 735322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com}; 736322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 7371c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.comstatic void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) { 7381c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (rite == riteA) { 7391c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com iter.next(); 7401c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com leftA = iter.left(); 7411c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com riteA = iter.right(); 742322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 743322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 744322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 7451c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.comstatic bool intersect(int& min, int& max, int boundsMin, int boundsMax) { 7461c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(min < max); 7471c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(boundsMin < boundsMax); 7481c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (min >= boundsMax || max <= boundsMin) { 7491c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com return false; 7501c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 7511c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (min < boundsMin) { 7521c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com min = boundsMin; 7531c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 7541c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (max > boundsMax) { 7551c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com max = boundsMax; 7561c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 7571c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com return true; 7581c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com} 7591c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 760322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic void operatorX(SkAAClip::Builder& builder, int lastY, 761322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com RowIter& iterA, RowIter& iterB, 762322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com AlphaProc proc, const SkIRect& bounds) { 763322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int leftA = iterA.left(); 764322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int riteA = iterA.right(); 765322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int leftB = iterB.left(); 766322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int riteB = iterB.right(); 767322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 7681c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com int prevRite = bounds.fLeft; 7691c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 7701c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com do { 771322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com U8CPU alphaA = 0; 772322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com U8CPU alphaB = 0; 773322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int left, rite; 7741c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 7751c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (leftA < leftB) { 776322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com left = leftA; 777322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com alphaA = iterA.alpha(); 7781c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (riteA <= leftB) { 7791c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com rite = riteA; 7801c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 7811c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com rite = leftA = leftB; 7821c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 7831c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else if (leftB < leftA) { 784322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com left = leftB; 785322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com alphaB = iterB.alpha(); 7861c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (riteB <= leftA) { 7871c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com rite = riteB; 7881c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 7891c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com rite = leftB = leftA; 7901c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 791322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } else { 7921c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com left = leftA; // or leftB, since leftA == leftB 7931c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com rite = leftA = leftB = SkMin32(riteA, riteB); 794322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com alphaA = iterA.alpha(); 795322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com alphaB = iterB.alpha(); 796322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 797322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 798322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (left >= bounds.fRight) { 799322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com break; 800322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 80134f7e47a3593911d03307a08e5af625b218ceec3reed@google.com if (rite > bounds.fRight) { 80234f7e47a3593911d03307a08e5af625b218ceec3reed@google.com rite = bounds.fRight; 80334f7e47a3593911d03307a08e5af625b218ceec3reed@google.com } 80434f7e47a3593911d03307a08e5af625b218ceec3reed@google.com 805322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (left >= bounds.fLeft) { 8061c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(rite > left); 807322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com builder.addRun(left, lastY, proc(alphaA, alphaB), rite - left); 8081c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com prevRite = rite; 809322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 8101c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 8111c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com adjust_row(iterA, leftA, riteA, rite); 8121c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com adjust_row(iterB, leftB, riteB, rite); 8131c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } while (!iterA.done() || !iterB.done()); 8141c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 8151c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (prevRite < bounds.fRight) { 8161c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com builder.addRun(prevRite, lastY, 0, bounds.fRight - prevRite); 817322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 818322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 819322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 8201c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.comstatic void adjust_iter(SkAAClip::Iter& iter, int& topA, int& botA, int bot) { 8211c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (bot == botA) { 8221c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com iter.next(); 8231c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com topA = botA; 8241c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(botA == iter.top()); 8251c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com botA = iter.bottom(); 826322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 827322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 828322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 829322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic void operateY(SkAAClip::Builder& builder, const SkAAClip& A, 830322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const SkAAClip& B, SkRegion::Op op) { 831322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com AlphaProc proc = find_alpha_proc(op); 832322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const SkIRect& bounds = builder.getBounds(); 833322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 834322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkAAClip::Iter iterA(A); 835322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkAAClip::Iter iterB(B); 836322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 837322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(!iterA.done()); 838322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int topA = iterA.top(); 839322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int botA = iterA.bottom(); 840322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(!iterB.done()); 841322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int topB = iterB.top(); 842322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int botB = iterB.bottom(); 843322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 8441c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com do { 8451c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com const uint8_t* rowA = NULL; 8461c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com const uint8_t* rowB = NULL; 847322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int top, bot; 8481c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 8491c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (topA < topB) { 850322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com top = topA; 851322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com rowA = iterA.data(); 8521c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (botA <= topB) { 8531c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com bot = botA; 8541c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 8551c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com bot = topA = topB; 8561c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 8571c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 8581c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else if (topB < topA) { 859322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com top = topB; 860322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com rowB = iterB.data(); 8611c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (botB <= topA) { 8621c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com bot = botB; 8631c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else { 8641c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com bot = topB = topA; 8651c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 866322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } else { 8671c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com top = topA; // or topB, since topA == topB 8681c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com bot = topA = topB = SkMin32(botA, botB); 869322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com rowA = iterA.data(); 870322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com rowB = iterB.data(); 871322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 872322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 873322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (top >= bounds.fBottom) { 874322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com break; 875322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 87634f7e47a3593911d03307a08e5af625b218ceec3reed@google.com 87734f7e47a3593911d03307a08e5af625b218ceec3reed@google.com if (bot > bounds.fBottom) { 87834f7e47a3593911d03307a08e5af625b218ceec3reed@google.com bot = bounds.fBottom; 87934f7e47a3593911d03307a08e5af625b218ceec3reed@google.com } 88034f7e47a3593911d03307a08e5af625b218ceec3reed@google.com SkASSERT(top < bot); 88134f7e47a3593911d03307a08e5af625b218ceec3reed@google.com 8821c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (!rowA && !rowB) { 8831c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com builder.addRun(bounds.fLeft, bot - 1, 0, bounds.width()); 8841c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } else if (top >= bounds.fTop) { 8851c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com SkASSERT(bot <= bounds.fBottom); 8861c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com RowIter rowIterA(rowA, rowA ? A.getBounds() : bounds); 8871c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com RowIter rowIterB(rowB, rowB ? B.getBounds() : bounds); 888322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com operatorX(builder, bot - 1, rowIterA, rowIterB, proc, bounds); 889322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 890322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 8911c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com adjust_iter(iterA, topA, botA, bot); 8921c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com adjust_iter(iterB, topB, botB, bot); 8931c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } while (!iterA.done() || !iterB.done()); 894322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 895322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 896322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.combool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig, 897322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkRegion::Op op) { 898322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (SkRegion::kReplace_Op == op) { 899322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->set(clipBOrig); 900322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 901322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 902322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const SkAAClip* clipA = &clipAOrig; 903322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const SkAAClip* clipB = &clipBOrig; 904322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 905322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (SkRegion::kReverseDifference_Op == op) { 906322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkTSwap(clipA, clipB); 907322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com op = SkRegion::kDifference_Op; 908322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 909322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 910322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool a_empty = clipA->isEmpty(); 911322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bool b_empty = clipB->isEmpty(); 912322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 913322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkIRect bounds; 914322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com switch (op) { 915322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kDifference_Op: 916322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (a_empty) { 917322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->setEmpty(); 918322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 919322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (b_empty || !SkIRect::Intersects(clipA->fBounds, clipB->fBounds)) { 920322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->set(*clipA); 921322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 922322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bounds = clipA->fBounds; 923322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com break; 924322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 925322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kIntersect_Op: 926322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if ((a_empty | b_empty) || !bounds.intersect(clipA->fBounds, 927322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com clipB->fBounds)) { 928322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->setEmpty(); 929322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 930322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com break; 931322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 932322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kUnion_Op: 933322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com case SkRegion::kXOR_Op: 934322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (a_empty) { 935322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->set(*clipB); 936322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 937322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (b_empty) { 938322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return this->set(*clipA); 939322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 940322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bounds = clipA->fBounds; 941322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com bounds.join(clipB->fBounds); 942322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com break; 943322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 944322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com default: 945322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(!"unknown region op"); 946322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return !this->isEmpty(); 947322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 948322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 949322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds)); 950322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds)); 951322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 952322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com Builder builder(bounds); 953322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com operateY(builder, *clipA, *clipB, op); 954322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com // don't free us until now, since we might be clipA or clipB 955322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com this->freeRuns(); 956322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fBounds = bounds; 957322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com fRunHead = builder.finish(); 958322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 959322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return !this->isEmpty(); 960e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 961e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 96247ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.combool SkAAClip::op(const SkIRect& r, SkRegion::Op op) { 96347ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com SkAAClip clip; 96447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com clip.setRect(r); 96547ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com return this->op(*this, clip, op); 96647ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com} 96747ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com 9680017708a5bcb6d0fbff0fac565085bef65de7433reed@google.combool SkAAClip::op(const SkRect& r, SkRegion::Op op, bool doAA) { 96947ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com SkAAClip clip; 9700017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com clip.setRect(r, doAA); 97147ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com return this->op(*this, clip, op); 97247ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com} 97347ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com 97447ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.combool SkAAClip::op(const SkAAClip& clip, SkRegion::Op op) { 97547ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com return this->op(*this, clip, op); 97647ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com} 97747ac84edafc6f26e2146ab10363e2043c5af0e62reed@google.com 978e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 979e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com/////////////////////////////////////////////////////////////////////////////// 980e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 981e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstatic void expandToRuns(const uint8_t* SK_RESTRICT data, int initialCount, int width, 982e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int16_t* SK_RESTRICT runs, SkAlpha* SK_RESTRICT aa) { 983e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // we don't read our initial n from data, since the caller may have had to 984e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // clip it, hence the initialCount parameter. 985e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int n = initialCount; 986e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (;;) { 987e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (n > width) { 988e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com n = width; 989e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 990e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(n > 0); 991e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com runs[0] = n; 992e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com runs += n; 993e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 994e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com aa[0] = data[1]; 995e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com aa += n; 996e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 997e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com data += 2; 998e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com width -= n; 999e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0 == width) { 1000e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com break; 1001e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1002e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // load the next count 1003e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com n = data[0]; 1004e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1005e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com runs[0] = 0; // sentinel 1006e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1007e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1008e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comSkAAClipBlitter::~SkAAClipBlitter() { 1009e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com sk_free(fRuns); 1010e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1011e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1012e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::ensureRunsAndAA() { 1013e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (NULL == fRuns) { 1014e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com // add 1 so we can store the terminating run count of 0 1015e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int count = fAAClipBounds.width() + 1; 1016e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fRuns = (int16_t*)sk_malloc_throw(count * sizeof(int16_t) + 1017e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com count * sizeof(SkAlpha)); 1018e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fAA = (SkAlpha*)(fRuns + count); 1019e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 102034f7e47a3593911d03307a08e5af625b218ceec3reed@google.com SkDEBUGCODE(sk_memset16((uint16_t*)fRuns, 0xFFFF, fAAClipBounds.width() + 1);) 1021e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1022e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1023e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::blitH(int x, int y, int width) { 1024e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(width > 0); 1025e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fAAClipBounds.contains(x, y)); 1026e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(fAAClipBounds.contains(x + width - 1, y)); 1027e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1028e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int lastY; 1029e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* row = fAAClip->findRow(y, &lastY); 1030e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int initialCount; 1031e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = fAAClip->findX(row, x, &initialCount); 1032e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1033e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (initialCount >= width) { 1034e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkAlpha alpha = row[1]; 1035e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0 == alpha) { 1036e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return; 1037e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1038e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0xFF == alpha) { 1039e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitH(x, y, width); 1040e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return; 1041e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1042e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1043e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1044e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->ensureRunsAndAA(); 1045e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com expandToRuns(row, initialCount, width, fRuns, fAA); 1046e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1047e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitAntiH(x, y, fAA, fRuns); 1048e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1049e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1050e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comstatic void merge(const uint8_t* SK_RESTRICT row, int rowN, 1051e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const SkAlpha* SK_RESTRICT srcAA, 1052e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const int16_t* SK_RESTRICT srcRuns, 1053e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkAlpha* SK_RESTRICT dstAA, 1054e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int16_t* SK_RESTRICT dstRuns, 1055e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int width) { 1056e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDEBUGCODE(int accumulated = 0;) 1057e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int srcN = srcRuns[0]; 1058e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com for (;;) { 1059e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0 == srcN) { 1060e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com break; 1061e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1062e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(rowN > 0); 1063e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(srcN > 0); 1064e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1065e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com unsigned newAlpha = SkMulDiv255Round(srcAA[0], row[1]); 1066e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int minN = SkMin32(srcN, rowN); 1067e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com dstRuns[0] = minN; 1068e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com dstRuns += minN; 1069e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com dstAA[0] = newAlpha; 1070e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com dstAA += minN; 1071e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1072e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0 == (srcN -= minN)) { 1073e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com srcN = srcRuns[0]; // refresh 1074e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com srcRuns += srcN; 1075e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com srcAA += srcN; 1076e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com srcN = srcRuns[0]; // reload 1077e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1078e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (0 == (rowN -= minN)) { 1079e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row += 2; 1080e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com rowN = row[0]; // reload 1081e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1082e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1083e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkDEBUGCODE(accumulated += minN;) 1084e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkASSERT(accumulated <= width); 1085e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 108634f7e47a3593911d03307a08e5af625b218ceec3reed@google.com dstRuns[0] = 0; 1087e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1088e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1089e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 1090e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const int16_t runs[]) { 1091e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int lastY; 1092e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* row = fAAClip->findRow(y, &lastY); 1093e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int initialCount; 1094e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = fAAClip->findX(row, x, &initialCount); 1095e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1096e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->ensureRunsAndAA(); 1097e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1098e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com merge(row, initialCount, aa, runs, fAA, fRuns, fAAClipBounds.width()); 1099e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitAntiH(x, y, fAA, fRuns); 1100e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1101e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1102e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1103e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (fAAClip->quickContains(x, y, x + 1, y + height)) { 1104e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitV(x, y, height, alpha); 1105e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return; 1106e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1107e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1108e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int stopY = y + height; 1109e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com do { 1110e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int lastY; 1111e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com const uint8_t* row = fAAClip->findRow(y, &lastY); 1112e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com int initialCount; 1113e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com row = fAAClip->findX(row, x, &initialCount); 1114e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com SkAlpha newAlpha = SkMulDiv255Round(alpha, row[1]); 1115e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (newAlpha) { 1116e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitV(x, y, lastY - y + 1, newAlpha); 1117e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1118e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com y = lastY + 1; 1119e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } while (y < stopY); 1120e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1121e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1122e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::blitRect(int x, int y, int width, int height) { 1123e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com if (fAAClip->quickContains(x, y, x + width, y + height)) { 1124e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitRect(x, y, width, height); 1125e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return; 1126e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1127e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1128e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com while (--height >= 0) { 1129e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com this->blitH(x, y, width); 1130e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com y += 1; 1131e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com } 1132e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1133e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1134e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comvoid SkAAClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1135e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com fBlitter->blitMask(mask, clip); 1136e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1137e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1138e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.comconst SkBitmap* SkAAClipBlitter::justAnOpaqueColor(uint32_t* value) { 1139e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com return NULL; 1140e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com} 1141e36707a4a82a4dea7d480d969220f3ed223305dcreed@google.com 1142322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com/////////////////////////////////////////////////////////////////////////////// 1143322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 114434f7e47a3593911d03307a08e5af625b218ceec3reed@google.combool SkAAClip::translate(int dx, int dy, SkAAClip* dst) const { 114534f7e47a3593911d03307a08e5af625b218ceec3reed@google.com if (NULL == dst) { 114634f7e47a3593911d03307a08e5af625b218ceec3reed@google.com return !this->isEmpty(); 11471c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 11481c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 11491c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com if (this->isEmpty()) { 115034f7e47a3593911d03307a08e5af625b218ceec3reed@google.com return dst->setEmpty(); 11511c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com } 11521c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 115334f7e47a3593911d03307a08e5af625b218ceec3reed@google.com if (this != dst) { 115434f7e47a3593911d03307a08e5af625b218ceec3reed@google.com sk_atomic_inc(&fRunHead->fRefCnt); 115534f7e47a3593911d03307a08e5af625b218ceec3reed@google.com dst->fRunHead = fRunHead; 115634f7e47a3593911d03307a08e5af625b218ceec3reed@google.com dst->fBounds = fBounds; 115734f7e47a3593911d03307a08e5af625b218ceec3reed@google.com } 11581c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com dst->fBounds.offset(dx, dy); 11591c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com return true; 11601c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com} 11611c04bf97b6245b55ac58c2f3902f8ca95ca91c3dreed@google.com 1162322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comstatic void expand_row_to_mask(uint8_t* SK_RESTRICT mask, 1163322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const uint8_t* SK_RESTRICT row, 1164322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int width) { 1165322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com while (width > 0) { 1166322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int n = row[0]; 1167322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com SkASSERT(width >= n); 1168322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com memset(mask, row[1], n); 1169322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask += n; 1170322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com row += 2; 1171322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com width -= n; 1172322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 1173322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 1174322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 1175322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.comvoid SkAAClip::copyToMask(SkMask* mask) const { 1176322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fFormat = SkMask::kA8_Format; 1177322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com if (this->isEmpty()) { 1178322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fBounds.setEmpty(); 1179322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fImage = NULL; 1180322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fRowBytes = 0; 1181322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com return; 1182322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 1183322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 1184322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fBounds = fBounds; 1185322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fRowBytes = fBounds.width(); 1186322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com size_t size = mask->computeImageSize(); 1187322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com mask->fImage = SkMask::AllocImage(size); 1188322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 1189322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com Iter iter(*this); 1190322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com uint8_t* dst = mask->fImage; 1191322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com const int width = fBounds.width(); 1192322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 1193322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com int y = fBounds.fTop; 1194322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com while (!iter.done()) { 1195322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com do { 1196322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com expand_row_to_mask(dst, iter.data(), width); 1197322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com dst += mask->fRowBytes; 1198322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } while (++y < iter.bottom()); 1199322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com iter.next(); 1200322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com } 1201322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com} 1202322878907f6c5c5fb8abdbce7d348a3cd66ff2fareed@google.com 1203