SkLayerDrawLooper.cpp revision daaafa6e81860e3dc52660ba019c336f0a43f1e7
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 90716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com#include "SkColor.h" 108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkLayerDrawLooper.h" 134991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkString.h" 144991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkStringUtils.h" 150716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com#include "SkUnPreMultiply.h" 160716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 170716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comSkLayerDrawLooper::LayerInfo::LayerInfo() { 18a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org fPaintBits = 0; // ignore our paint fields 190716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com fColorMode = SkXfermode::kDst_Mode; // ignore our color 200716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com fOffset.set(0, 0); 210716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com fPostTranslate = false; 220716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com} 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 243c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.orgSkLayerDrawLooper::SkLayerDrawLooper() 253c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org : fRecs(NULL), 268f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org fTopRec(NULL), 2779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fCount(0) { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::~SkLayerDrawLooper() { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* next = rec->fNext; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(rec); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = next; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 380716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 3979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.orgSkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, void* storage) const { 40091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org canvas->save(); 4179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, LayerDrawLooperContext, (this)); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 440716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) { 450716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com switch (mode) { 460716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com case SkXfermode::kSrc_Mode: 470716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com return src; 480716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com case SkXfermode::kDst_Mode: 490716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com return dst; 500716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com default: { 510716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com SkPMColor pmS = SkPreMultiplyColor(src); 520716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com SkPMColor pmD = SkPreMultiplyColor(dst); 530716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD); 540716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com return SkUnPreMultiply::PMColorToColor(result); 550716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com } 560716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com } 570716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com} 580716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 598426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// Even with kEntirePaint_Bits, we always ensure that the master paint's 608426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text-encoding is respected, since that controls how we interpret the 618426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text/length parameters of a draw[Pos]Text call. 6279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.orgvoid SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo( 6379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkPaint* dst, const SkPaint& src, const LayerInfo& info) { 64a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org 65a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode)); 66a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org 67a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org BitFlags bits = info.fPaintBits; 688426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com SkPaint::TextEncoding encoding = dst->getTextEncoding(); 690716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 703c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org if (0 == bits) { 713c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org return; 723c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org } 730e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (kEntirePaint_Bits == bits) { 74a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org // we've already computed these, so save it from the assignment 75a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org uint32_t f = dst->getFlags(); 760716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com SkColor c = dst->getColor(); 770e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org *dst = src; 78a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org dst->setFlags(f); 790716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com dst->setColor(c); 808426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com dst->setTextEncoding(encoding); 810e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org return; 820e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 830e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 840e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kStyle_Bit) { 850e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStyle(src.getStyle()); 860e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeWidth(src.getStrokeWidth()); 870e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeMiter(src.getStrokeMiter()); 880e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeCap(src.getStrokeCap()); 890e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setStrokeJoin(src.getStrokeJoin()); 900e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 910e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 920e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kTextSkewX_Bit) { 930e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextSkewX(src.getTextSkewX()); 940e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 950e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 960e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kPathEffect_Bit) { 970e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setPathEffect(src.getPathEffect()); 980e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 990e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kMaskFilter_Bit) { 1000e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setMaskFilter(src.getMaskFilter()); 1010e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 1020e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kShader_Bit) { 1030e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setShader(src.getShader()); 1040e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 1050e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kColorFilter_Bit) { 1060e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setColorFilter(src.getColorFilter()); 1070e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 1080e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org if (bits & kXfermode_Bit) { 1090e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setXfermode(src.getXfermode()); 1100e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org } 1110e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 1128426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com // we don't override these 1130e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#if 0 1140e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTypeface(src.getTypeface()); 1150e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextSize(src.getTextSize()); 1160e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextScaleX(src.getTextScaleX()); 1170e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setRasterizer(src.getRasterizer()); 1180e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setLooper(src.getLooper()); 1190e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setTextEncoding(src.getTextEncoding()); 1200e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org dst->setHinting(src.getHinting()); 1210e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#endif 1220e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org} 1230e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org 1240716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com// Should we add this to canvas? 1250716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) { 1260716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com SkMatrix m = canvas->getTotalMatrix(); 1270716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com m.postTranslate(dx, dy); 1280716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com canvas->setMatrix(m); 1290716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com} 1300716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 13179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.orgSkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext( 13279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {} 13379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org 13479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.orgbool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas, 13579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkPaint* paint) { 1364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com canvas->restore(); 1374e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com if (NULL == fCurrRec) { 1384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 141a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo); 1420716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com 143091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org canvas->save(); 1440716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com if (fCurrRec->fInfo.fPostTranslate) { 1450716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com postTranslate(canvas, fCurrRec->fInfo.fOffset.fX, 1460716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com fCurrRec->fInfo.fOffset.fY); 1470716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com } else { 14879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org canvas->translate(fCurrRec->fInfo.fOffset.fX, 14979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fCurrRec->fInfo.fOffset.fY); 1500716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com } 151e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org fCurrRec = fCurrRec->fNext; 152e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org 1534e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 156daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.combool SkLayerDrawLooper::asABlurShadow(BlurShadowRec* bsRec) const { 157daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (fCount != 2) { 158daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 159daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 160daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com const Rec* rec = fRecs; 161daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 162daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com // bottom layer needs to be just blur(maskfilter) 163daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if ((rec->fInfo.fPaintBits & ~kMaskFilter_Bit)) { 164daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 165daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 166daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (SkXfermode::kSrc_Mode != rec->fInfo.fColorMode) { 167daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 168daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 169daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com const SkMaskFilter* mf = rec->fPaint.getMaskFilter(); 170daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (NULL == mf) { 171daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 172daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 173daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com SkMaskFilter::BlurRec maskBlur; 174daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (!mf->asABlur(&maskBlur)) { 175daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 176daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 177daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 178daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com rec = rec->fNext; 179daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com // top layer needs to be "plain" 180daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (rec->fInfo.fPaintBits) { 181daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 182daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 183daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (SkXfermode::kDst_Mode != rec->fInfo.fColorMode) { 184daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 185daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 186daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (!rec->fInfo.fOffset.equals(0, 0)) { 187daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 188daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 189daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 190daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (bsRec) { 191daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com bsRec->fSigma = maskBlur.fSigma; 192daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com bsRec->fOffset = fRecs->fInfo.fOffset; 193daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com bsRec->fColor = fRecs->fPaint.getColor(); 194daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com bsRec->fStyle = maskBlur.fStyle; 195daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com bsRec->fQuality = maskBlur.fQuality; 196daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 197daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return true; 198daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com} 199daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2028b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const { 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->INHERITED::flatten(buffer); 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count += 1; 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count == fCount); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeInt(fCount); 218fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Rec* rec = fRecs; 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < fCount; i++) { 221842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com // Legacy "flagsmask" field -- now ignored, remove when we bump version 222842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com buffer.writeInt(0); 223842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com 2240716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com buffer.writeInt(rec->fInfo.fPaintBits); 2250716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com buffer.writeInt(rec->fInfo.fColorMode); 226c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writePoint(rec->fInfo.fOffset); 2270716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com buffer.writeBool(rec->fInfo.fPostTranslate); 228c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writePaint(rec->fPaint); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = buffer.readInt(); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Builder builder; 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < count; i++) { 2380716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com LayerInfo info; 239842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com // Legacy "flagsmask" field -- now ignored, remove when we bump version 24048f31bdbb3346e3003581229395022bf44828b13reed@google.com (void)buffer.readInt(); 241842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com 2420716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com info.fPaintBits = buffer.readInt(); 2430716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com info.fColorMode = (SkXfermode::Mode)buffer.readInt(); 244c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.readPoint(&info.fOffset); 2450716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com info.fPostTranslate = buffer.readBool(); 24674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org buffer.readPaint(builder.addLayerOnTop(info)); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkLayerDrawLooper* looper = builder.detachLooper(); 24974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkASSERT(count == looper->fCount); 250fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 25374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Rec* rec = looper->fRecs; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 0; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (rec) { 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec = rec->fNext; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n += 1; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count == n); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 26274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 26374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org return looper; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2654991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 2660f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 2674991b8f23482afc1494fd17647421ce68de53331robertphillips@google.comvoid SkLayerDrawLooper::toString(SkString* str) const { 2684991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->appendf("SkLayerDrawLooper (%d): ", fCount); 2694991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 2704991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com Rec* rec = fRecs; 2714991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com for (int i = 0; i < fCount; i++) { 272842292f10fc08bc8701114f7eec00944b6ea26d2reed@google.com str->appendf("%d: paintBits: (", i); 2734991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com if (0 == rec->fInfo.fPaintBits) { 2744991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("None"); 2754991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) { 2764991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("EntirePaint"); 2774991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } else { 2784991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com bool needSeparator = false; 2794991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com SkAddFlagToString(str, SkToBool(kStyle_Bit & rec->fInfo.fPaintBits), "Style", 2804991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 281cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec->fInfo.fPaintBits), "TextSkewX", 2824991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 2834991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec->fInfo.fPaintBits), "PathEffect", 2844991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 2854991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec->fInfo.fPaintBits), "MaskFilter", 2864991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 287cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com SkAddFlagToString(str, SkToBool(kShader_Bit & rec->fInfo.fPaintBits), "Shader", 2884991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 289cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec->fInfo.fPaintBits), "ColorFilter", 2904991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 291cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec->fInfo.fPaintBits), "Xfermode", 2924991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com &needSeparator); 2934991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } 2944991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append(") "); 2954991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 2964991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com static const char* gModeStrings[SkXfermode::kLastMode+1] = { 2974991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn", 2984991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus", 2994991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDodge", 3004991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion" 3014991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com }; 3024991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 3034991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->appendf("mode: %s ", gModeStrings[rec->fInfo.fColorMode]); 3044991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 3054991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("offset: ("); 3064991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->appendScalar(rec->fInfo.fOffset.fX); 3074991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append(", "); 3084991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->appendScalar(rec->fInfo.fOffset.fY); 3094991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append(") "); 3104991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 3114991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("postTranslate: "); 3124991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com if (rec->fInfo.fPostTranslate) { 3134991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("true "); 3144991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } else { 3154991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com str->append("false "); 3164991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } 3174991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com 318791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com rec->fPaint.toString(str); 3194991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com rec = rec->fNext; 3204991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com } 3214991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com} 3224991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#endif 32374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 32474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkLayerDrawLooper::Builder::Builder() 32574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org : fRecs(NULL), 32674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fTopRec(NULL), 32774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fCount(0) { 32874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 32974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 33074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkLayerDrawLooper::Builder::~Builder() { 33174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Rec* rec = fRecs; 33274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org while (rec) { 33374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Rec* next = rec->fNext; 33474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkDELETE(rec); 33574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org rec = next; 33674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org } 33774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 33874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 33974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) { 34074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fCount += 1; 34174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 34274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Rec* rec = SkNEW(Rec); 34374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org rec->fNext = fRecs; 34474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org rec->fInfo = info; 34574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fRecs = rec; 34674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org if (NULL == fTopRec) { 34774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fTopRec = rec; 34874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org } 34974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 35074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org return &rec->fPaint; 35174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 35274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 35374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgvoid SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) { 35474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org LayerInfo info; 35574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 35674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org info.fOffset.set(dx, dy); 35774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org (void)this->addLayer(info); 35874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 35974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 36074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) { 36174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fCount += 1; 36274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 36374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org Rec* rec = SkNEW(Rec); 36474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org rec->fNext = NULL; 36574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org rec->fInfo = info; 36674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org if (NULL == fRecs) { 36774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fRecs = rec; 36874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org } else { 36974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkASSERT(NULL != fTopRec); 37074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fTopRec->fNext = rec; 37174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org } 37274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fTopRec = rec; 37374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 37474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org return &rec->fPaint; 37574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 37674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 37774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.orgSkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() { 37874ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org SkLayerDrawLooper* looper = SkNEW(SkLayerDrawLooper); 37974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org looper->fCount = fCount; 38074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org looper->fRecs = fRecs; 38174ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 38274ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fCount = 0; 38374ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fRecs = NULL; 38474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org fTopRec = NULL; 38574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org 38674ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org return looper; 38774ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org} 388