SkLayerDrawLooper.cpp revision 076f4c9791c3710a3714452b61d61fd049601f57
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"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkLayerDrawLooper.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
120716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com#include "SkUnPreMultiply.h"
130716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
140456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.comSK_DEFINE_INST_COUNT(SkLayerDrawLooper)
150456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com
160716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comSkLayerDrawLooper::LayerInfo::LayerInfo() {
17a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    fFlagsMask = 0;                     // ignore our paint flags
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),
263c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCount(0),
273c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCurrRec(NULL) {
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
390716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comSkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fCount += 1;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = SkNEW(Rec);
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    rec->fNext = fRecs;
440716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    rec->fInfo = info;
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRecs = rec;
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return &rec->fPaint;
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
50a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgvoid SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
510716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    LayerInfo info;
520716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
530716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    info.fOffset.set(dx, dy);
54a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    (void)this->addLayer(info);
550716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
560716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
574e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.comvoid SkLayerDrawLooper::init(SkCanvas* canvas) {
584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    fCurrRec = fRecs;
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas->save(SkCanvas::kMatrix_SaveFlag);
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
620716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
630716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    switch (mode) {
640716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        case SkXfermode::kSrc_Mode:
650716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return src;
660716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        case SkXfermode::kDst_Mode:
670716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return dst;
680716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        default: {
690716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor pmS = SkPreMultiplyColor(src);
700716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor pmD = SkPreMultiplyColor(dst);
710716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
720716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com            return SkUnPreMultiply::PMColorToColor(result);
730716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        }
740716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    }
750716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
760716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
778426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// Even with kEntirePaint_Bits, we always ensure that the master paint's
788426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text-encoding is respected, since that controls how we interpret the
798426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com// text/length parameters of a draw[Pos]Text call.
80a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.orgvoid SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src,
81a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org                                  const LayerInfo& info) {
82a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
83a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    uint32_t mask = info.fFlagsMask;
84a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    dst->setFlags((dst->getFlags() & ~mask) | (src.getFlags() & mask));
85a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
86a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org
87a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    BitFlags bits = info.fPaintBits;
888426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com    SkPaint::TextEncoding encoding = dst->getTextEncoding();
890716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
903c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org    if (0 == bits) {
913c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org        return;
923c1225bee4d9ea0963acf47fc5df080b2d5b26b2mike@reedtribe.org    }
930e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (kEntirePaint_Bits == bits) {
94a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        // we've already computed these, so save it from the assignment
95a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        uint32_t f = dst->getFlags();
960716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        SkColor c = dst->getColor();
970e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        *dst = src;
98a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org        dst->setFlags(f);
990716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        dst->setColor(c);
1008426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com        dst->setTextEncoding(encoding);
1010e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        return;
1020e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1030e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1040e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kStyle_Bit) {
1050e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStyle(src.getStyle());
1060e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeWidth(src.getStrokeWidth());
1070e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeMiter(src.getStrokeMiter());
1080e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeCap(src.getStrokeCap());
1090e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setStrokeJoin(src.getStrokeJoin());
1100e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1110e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1120e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kTextSkewX_Bit) {
1130e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setTextSkewX(src.getTextSkewX());
1140e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1150e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1160e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kPathEffect_Bit) {
1170e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setPathEffect(src.getPathEffect());
1180e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1190e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kMaskFilter_Bit) {
1200e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setMaskFilter(src.getMaskFilter());
1210e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1220e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kShader_Bit) {
1230e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setShader(src.getShader());
1240e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1250e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kColorFilter_Bit) {
1260e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setColorFilter(src.getColorFilter());
1270e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1280e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    if (bits & kXfermode_Bit) {
1290e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org        dst->setXfermode(src.getXfermode());
1300e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    }
1310e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1328426058dee0faf75a18b81cfcde47ee8ab8c31d9reed@google.com    // we don't override these
1330e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#if 0
1340e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTypeface(src.getTypeface());
1350e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextSize(src.getTextSize());
1360e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextScaleX(src.getTextScaleX());
1370e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setRasterizer(src.getRasterizer());
1380e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setLooper(src.getLooper());
1390e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setTextEncoding(src.getTextEncoding());
1400e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org    dst->setHinting(src.getHinting());
1410e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org#endif
1420e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org}
1430e2810be95d3f1aa95c341521d3f514eb9e9ebdemike@reedtribe.org
1440716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com// Should we add this to canvas?
1450716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.comstatic void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
1460716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    SkMatrix m = canvas->getTotalMatrix();
1470716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    m.postTranslate(dx, dy);
1480716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    canvas->setMatrix(m);
1490716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com}
1500716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
1514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.combool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
1524e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    canvas->restore();
1534e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    if (NULL == fCurrRec) {
1544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com        return false;
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
157a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6mike@reedtribe.org    ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
1580716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com
1594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    canvas->save(SkCanvas::kMatrix_SaveFlag);
1600716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    if (fCurrRec->fInfo.fPostTranslate) {
1610716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
1620716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com                      fCurrRec->fInfo.fOffset.fY);
1630716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    } else {
1640716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY);
1650716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com    }
166e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org    fCurrRec = fCurrRec->fNext;
167e5d0def6d9864463565f9ca6a6e9ceedcb72712dmike@reedtribe.org
1684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com    return true;
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = head;
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* prev = NULL;
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (rec) {
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* next = rec->fNext;
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec->fNext = prev;
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        prev = rec;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec = next;
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return prev;
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) const {
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::flatten(buffer);
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* rec = fRecs;
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = 0;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (rec) {
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            rec = rec->fNext;
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            count += 1;
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count == fCount);
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeInt(fCount);
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* rec = fRecs;
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fCount; i++) {
204076f4c9791c3710a3714452b61d61fd049601f57reed@google.com        buffer.writeInt(rec->fInfo.fFlagsMask);
2050716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeInt(rec->fInfo.fPaintBits);
2060716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeInt(rec->fInfo.fColorMode);
2070716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeScalar(rec->fInfo.fOffset.fX);
2080716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeScalar(rec->fInfo.fOffset.fY);
2090716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        buffer.writeBool(rec->fInfo.fPostTranslate);
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec->fPaint.flatten(buffer);
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        rec = rec->fNext;
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
2163c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org        : INHERITED(buffer),
2173c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fRecs(NULL),
2183c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCount(0),
2193c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org          fCurrRec(NULL) {
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = buffer.readInt();
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
2230716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        LayerInfo info;
224076f4c9791c3710a3714452b61d61fd049601f57reed@google.com        info.fFlagsMask = buffer.readInt();
2250716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fPaintBits = buffer.readInt();
2260716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fColorMode = (SkXfermode::Mode)buffer.readInt();
2270716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fOffset.fX = buffer.readScalar();
2280716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fOffset.fY = buffer.readScalar();
2290716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        info.fPostTranslate = buffer.readBool();
2300716c63332a64c3cc77a9afb87ae2fd9614f0c4freed@google.com        this->addLayer(info)->unflatten(buffer);
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(count == fCount);
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // we're in reverse order, so fix it now
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRecs = Rec::Reverse(fRecs);
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Rec* rec = fRecs;
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = 0;
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (rec) {
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            rec = rec->fNext;
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n += 1;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count == n);
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
252d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkLayerDrawLooper)
253