SkLayerDrawLooper.cpp revision 8b0e8ac5f582de80356019406e2975079bf0829d
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    fFlagsMask = 0;                     // ignore our paint flags
19a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    fPaintBits = 0;                     // ignore our paint fields
200716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    fColorMode = SkXfermode::kDst_Mode; // ignore our color
210716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    fOffset.set(0, 0);
220716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    fPostTranslate = false;
230716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
253c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.orgSkLayerDrawLooper::SkLayerDrawLooper()
263c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org        : fRecs(NULL),
278f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org          fTopRec(NULL),
283c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCount(0),
293c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCurrRec(NULL) {
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::~SkLayerDrawLooper() {
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = fRecs;
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (rec) {
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* next = rec->fNext;
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDELETE(rec);
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec = next;
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
400716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
410716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comSkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fCount += 1;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = SkNEW(Rec);
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    rec->fNext = fRecs;
460716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    rec->fInfo = info;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRecs = rec;
488f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    if (NULL == fTopRec) {
498f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        fTopRec = rec;
508f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    }
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return &rec->fPaint;
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
55a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgvoid SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
560716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    LayerInfo info;
570716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
580716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    info.fOffset.set(dx, dy);
59a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    (void)this->addLayer(info);
600716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
610716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
628f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgSkPaint* SkLayerDrawLooper::addLayerOnTop(const LayerInfo& info) {
638f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    fCount += 1;
648f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
658f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    Rec* rec = SkNEW(Rec);
668f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    rec->fNext = NULL;
678f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    rec->fInfo = info;
688f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    if (NULL == fRecs) {
698f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        fRecs = rec;
708f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    } else {
718f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        SkASSERT(NULL != fTopRec);
728f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        fTopRec->fNext = rec;
738f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    }
748f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    fTopRec = rec;
758f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
768f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    return &rec->fPaint;
778f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}
788f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.comvoid SkLayerDrawLooper::init(SkCanvas* canvas) {
804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    fCurrRec = fRecs;
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas->save(SkCanvas::kMatrix_SaveFlag);
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
840716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
850716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    switch (mode) {
860716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        case SkXfermode::kSrc_Mode:
870716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return src;
880716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        case SkXfermode::kDst_Mode:
890716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return dst;
900716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        default: {
910716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor pmS = SkPreMultiplyColor(src);
920716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor pmD = SkPreMultiplyColor(dst);
930716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
940716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return SkUnPreMultiply::PMColorToColor(result);
950716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        }
960716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    }
970716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
980716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
998426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// Even with kEntirePaint_Bits, we always ensure that the master paint's
1008426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text-encoding is respected, since that controls how we interpret the
1018426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text/length parameters of a draw[Pos]Text call.
102a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgvoid SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src,
103a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                                  const LayerInfo& info) {
104a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
105a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    uint32_t mask = info.fFlagsMask;
106a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    dst->setFlags((dst->getFlags() & ~mask) | (src.getFlags() & mask));
107a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
108a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
109a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    BitFlags bits = info.fPaintBits;
1108426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com    SkPaint::TextEncoding encoding = dst->getTextEncoding();
1110716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
1123c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org    if (0 == bits) {
1133c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org        return;
1143c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org    }
1150e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (kEntirePaint_Bits == bits) {
116a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        // we've already computed these, so save it from the assignment
117a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        uint32_t f = dst->getFlags();
1180716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        SkColor c = dst->getColor();
1190e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        *dst = src;
120a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        dst->setFlags(f);
1210716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        dst->setColor(c);
1228426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com        dst->setTextEncoding(encoding);
1230e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        return;
1240e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1250e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1260e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kStyle_Bit) {
1270e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStyle(src.getStyle());
1280e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeWidth(src.getStrokeWidth());
1290e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeMiter(src.getStrokeMiter());
1300e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeCap(src.getStrokeCap());
1310e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeJoin(src.getStrokeJoin());
1320e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1330e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1340e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kTextSkewX_Bit) {
1350e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setTextSkewX(src.getTextSkewX());
1360e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1370e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1380e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kPathEffect_Bit) {
1390e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setPathEffect(src.getPathEffect());
1400e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1410e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kMaskFilter_Bit) {
1420e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setMaskFilter(src.getMaskFilter());
1430e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1440e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kShader_Bit) {
1450e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setShader(src.getShader());
1460e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1470e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kColorFilter_Bit) {
1480e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setColorFilter(src.getColorFilter());
1490e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1500e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kXfermode_Bit) {
1510e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setXfermode(src.getXfermode());
1520e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1530e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1548426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com    // we don't override these
1550e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#if 0
1560e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTypeface(src.getTypeface());
1570e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextSize(src.getTextSize());
1580e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextScaleX(src.getTextScaleX());
1590e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setRasterizer(src.getRasterizer());
1600e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setLooper(src.getLooper());
1610e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextEncoding(src.getTextEncoding());
1620e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setHinting(src.getHinting());
1630e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#endif
1640e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org}
1650e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1660716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com// Should we add this to canvas?
1670716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
1680716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    SkMatrix m = canvas->getTotalMatrix();
1690716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    m.postTranslate(dx, dy);
1700716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    canvas->setMatrix(m);
1710716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
1720716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
1734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.combool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
1744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    canvas->restore();
1754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    if (NULL == fCurrRec) {
1764e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com        return false;
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
179a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
1800716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
1814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    canvas->save(SkCanvas::kMatrix_SaveFlag);
1820716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    if (fCurrRec->fInfo.fPostTranslate) {
1830716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
1840716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com                      fCurrRec->fInfo.fOffset.fY);
1850716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    } else {
1860716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY);
1870716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    }
188e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org    fCurrRec = fCurrRec->fNext;
189e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org
1904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    return true;
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1958b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::flatten(buffer);
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* rec = fRecs;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = 0;
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (rec) {
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            rec = rec->fNext;
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            count += 1;
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count == fCount);
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeInt(fCount);
211fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = fRecs;
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fCount; i++) {
214076f4c9791c3710a3714452b61d61fd049601f57reed@google.com        buffer.writeInt(rec->fInfo.fFlagsMask);
2150716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeInt(rec->fInfo.fPaintBits);
2160716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeInt(rec->fInfo.fColorMode);
217c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com        buffer.writePoint(rec->fInfo.fOffset);
2180716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeBool(rec->fInfo.fPostTranslate);
219c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com        buffer.writePaint(rec->fPaint);
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec = rec->fNext;
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2248b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkLayerDrawLooper::SkLayerDrawLooper(SkReadBuffer& buffer)
2253c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org        : INHERITED(buffer),
2263c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fRecs(NULL),
2278f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org          fTopRec(NULL),
2283c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCount(0),
2293c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCurrRec(NULL) {
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = buffer.readInt();
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
2330716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        LayerInfo info;
234076f4c9791c3710a3714452b61d61fd049601f57reed@google.com        info.fFlagsMask = buffer.readInt();
2350716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fPaintBits = buffer.readInt();
2360716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fColorMode = (SkXfermode::Mode)buffer.readInt();
237c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com        buffer.readPoint(&info.fOffset);
2380716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fPostTranslate = buffer.readBool();
2398f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        buffer.readPaint(this->addLayerOnTop(info));
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(count == fCount);
242fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* rec = fRecs;
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = 0;
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (rec) {
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            rec = rec->fNext;
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n += 1;
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count == n);
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2554991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
2564991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#ifdef SK_DEVELOPER
2574991b8f23482afc1494fd17647421ce68de53331robertphillips@google.comvoid SkLayerDrawLooper::toString(SkString* str) const {
2584991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com    str->appendf("SkLayerDrawLooper (%d): ", fCount);
2594991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
2604991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com    Rec* rec = fRecs;
2614991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com    for (int i = 0; i < fCount; i++) {
2624991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->appendf("%d: ", i);
2634991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
2644991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append("flagsMask: (");
2654991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        if (0 == rec->fInfo.fFlagsMask) {
2664991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            str->append("None");
2674991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        } else {
2684991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            bool needSeparator = false;
269cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kAntiAlias_Flag & rec->fInfo.fFlagsMask),
2704991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "AntiAlias", &needSeparator);
2719cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com//            SkAddFlagToString(str, SkToBool(SkPaint::kFilterBitmap_Flag & rec->fInfo.fFlagsMask), "FilterBitmap", &needSeparator);
272cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kDither_Flag & rec->fInfo.fFlagsMask),
2734991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "Dither", &needSeparator);
274cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kUnderlineText_Flag & rec->fInfo.fFlagsMask),
2754991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "UnderlineText", &needSeparator);
276cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kStrikeThruText_Flag & rec->fInfo.fFlagsMask),
2774991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "StrikeThruText", &needSeparator);
278cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kFakeBoldText_Flag & rec->fInfo.fFlagsMask),
2794991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "FakeBoldText", &needSeparator);
280cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kLinearText_Flag & rec->fInfo.fFlagsMask),
2814991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "LinearText", &needSeparator);
282cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kSubpixelText_Flag & rec->fInfo.fFlagsMask),
2834991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "SubpixelText", &needSeparator);
284cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kDevKernText_Flag & rec->fInfo.fFlagsMask),
2854991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "DevKernText", &needSeparator);
286cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kLCDRenderText_Flag & rec->fInfo.fFlagsMask),
2874991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "LCDRenderText", &needSeparator);
2884991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            SkAddFlagToString(str, SkToBool(SkPaint::kEmbeddedBitmapText_Flag & rec->fInfo.fFlagsMask),
2894991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "EmbeddedBitmapText", &needSeparator);
290cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kAutoHinting_Flag & rec->fInfo.fFlagsMask),
2914991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "Autohinted", &needSeparator);
292cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(SkPaint::kVerticalText_Flag & rec->fInfo.fFlagsMask),
2934991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "VerticalText", &needSeparator);
2944991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            SkAddFlagToString(str, SkToBool(SkPaint::kGenA8FromLCD_Flag & rec->fInfo.fFlagsMask),
2954991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              "GenA8FromLCD", &needSeparator);
2964991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        }
2974991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append(") ");
2984991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
2994991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append("paintBits: (");
3004991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        if (0 == rec->fInfo.fPaintBits) {
3014991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            str->append("None");
3024991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) {
3034991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            str->append("EntirePaint");
3044991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        } else {
3054991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            bool needSeparator = false;
3064991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            SkAddFlagToString(str, SkToBool(kStyle_Bit & rec->fInfo.fPaintBits), "Style",
3074991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
308cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec->fInfo.fPaintBits), "TextSkewX",
3094991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
3104991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec->fInfo.fPaintBits), "PathEffect",
3114991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
3124991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec->fInfo.fPaintBits), "MaskFilter",
3134991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
314cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(kShader_Bit & rec->fInfo.fPaintBits), "Shader",
3154991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
316cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec->fInfo.fPaintBits), "ColorFilter",
3174991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
318cdcb2ce2744c7e5c47453328dbf292edee79ab37skia.committer@gmail.com            SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec->fInfo.fPaintBits), "Xfermode",
3194991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com                              &needSeparator);
3204991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        }
3214991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append(") ");
3224991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
3234991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        static const char* gModeStrings[SkXfermode::kLastMode+1] = {
3244991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn",
3254991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus",
3264991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDodge",
3274991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion"
3284991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        };
3294991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
3304991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->appendf("mode: %s ", gModeStrings[rec->fInfo.fColorMode]);
3314991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
3324991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append("offset: (");
3334991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->appendScalar(rec->fInfo.fOffset.fX);
3344991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append(", ");
3354991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->appendScalar(rec->fInfo.fOffset.fY);
3364991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append(") ");
3374991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
3384991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        str->append("postTranslate: ");
3394991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        if (rec->fInfo.fPostTranslate) {
3404991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            str->append("true ");
3414991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        } else {
3424991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com            str->append("false ");
3434991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        }
3444991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com
345791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com        rec->fPaint.toString(str);
3464991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com        rec = rec->fNext;
3474991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com    }
3484991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com}
3494991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#endif
350