SkLayerDrawLooper.cpp revision 3c1225bee4d9ea0963acf47fc5df080b2d5b26b2
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkLayerDrawLooper.h" 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::SkLayerDrawLooper() { 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRecs = NULL; 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCount = 0; 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::~SkLayerDrawLooper() { 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* next = rec->fNext; 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(rec); 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = next; 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 190e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.orgSkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCount += 1; 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = SkNEW(Rec); 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fNext = fRecs; 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fOffset.set(dx, dy); 250e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org rec->fBits = bits; 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRecs = rec; 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return &rec->fPaint; 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 314e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.comvoid SkLayerDrawLooper::init(SkCanvas* canvas) { 324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCurrRec = fRecs; 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->save(SkCanvas::kMatrix_SaveFlag); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 360e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.orgvoid SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src, 370e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org BitFlags bits) { 383c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org if (0 == bits) { 393c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org return; 403c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org } 410e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (kEntirePaint_Bits == bits) { 420e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org *dst = src; 430e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org return; 440e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 450e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 460e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org SkColor c = dst->getColor(); 470e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kAlpha_Bit) { 480e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org c &= 0x00FFFFFF; 490e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org c |= src.getColor() & 0xFF000000; 500e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 510e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kColor_Bit) { 520e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org c &= 0xFF000000; 530e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org c |= src.getColor() & 0x00FFFFFF; 540e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 550e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setColor(c); 560e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 570e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kStyle_Bit) { 580e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStyle(src.getStyle()); 590e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeWidth(src.getStrokeWidth()); 600e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeMiter(src.getStrokeMiter()); 610e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeCap(src.getStrokeCap()); 620e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeJoin(src.getStrokeJoin()); 630e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 640e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 650e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kTextSkewX_Bit) { 660e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextSkewX(src.getTextSkewX()); 670e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 680e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 690e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kPathEffect_Bit) { 700e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setPathEffect(src.getPathEffect()); 710e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 720e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kMaskFilter_Bit) { 730e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setMaskFilter(src.getMaskFilter()); 740e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 750e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kShader_Bit) { 760e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setShader(src.getShader()); 770e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 780e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kColorFilter_Bit) { 790e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setColorFilter(src.getColorFilter()); 800e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 810e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kXfermode_Bit) { 820e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setXfermode(src.getXfermode()); 830e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 840e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 850e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org // we never copy these 860e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#if 0 870e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setFlags(src.getFlags()); 880e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTypeface(src.getTypeface()); 890e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextSize(src.getTextSize()); 900e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextScaleX(src.getTextScaleX()); 910e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextSkewX(src.getTextSkewX()); 920e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setRasterizer(src.getRasterizer()); 930e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setLooper(src.getLooper()); 940e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextEncoding(src.getTextEncoding()); 950e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setHinting(src.getHinting()); 960e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#endif 970e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org} 980e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.combool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { 1004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com canvas->restore(); 1014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com if (NULL == fCurrRec) { 1024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1050e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits); 1064e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com canvas->save(SkCanvas::kMatrix_SaveFlag); 1074e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY); 108e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org fCurrRec = fCurrRec->fNext; 109e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org 1104e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) { 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = head; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* prev = NULL; 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* next = rec->fNext; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fNext = prev; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev = rec; 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = next; 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return prev; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) { 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count += 1; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count == fCount); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeInt(fCount); 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < fCount; i++) { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(rec->fOffset.fX); 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(rec->fOffset.fY); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPaint.flatten(buffer); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer) 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(buffer) { 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRecs = NULL; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCount = 0; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = buffer.readInt(); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < count; i++) { 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar dx = buffer.readScalar(); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar dy = buffer.readScalar(); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addLayer(dx, dy)->unflatten(buffer); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count == fCount); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we're in reverse order, so fix it now 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRecs = Rec::Reverse(fRecs); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 0; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n += 1; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count == n); 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkFlattenable::Registrar gReg("SkLayerDrawLooper", 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkLayerDrawLooper::CreateProc); 187