SkLayerDrawLooper.cpp revision e5d0def6d9864463565f9ca6a6e9ceedcb72712d
15a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#include "SkCanvas.h"
2bf832fc29e9e9141c1886d8d0d2123766a9aeb4cmostang.com!davidm#include "SkLayerDrawLooper.h"
35a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#include "SkPaint.h"
45a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
55a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmSkLayerDrawLooper::SkLayerDrawLooper() {
65a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    fRecs = NULL;
75a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    fCount = 0;
85a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
95a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
105a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmSkLayerDrawLooper::~SkLayerDrawLooper() {
115a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    Rec* rec = fRecs;
125a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    while (rec) {
135a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        Rec* next = rec->fNext;
145a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        SkDELETE(rec);
155a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        rec = next;
165a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    }
175a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
185a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
195a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmSkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
205a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    fCount += 1;
215a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
225a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    Rec* rec = SkNEW(Rec);
235a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    rec->fNext = fRecs;
245a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    rec->fOffset.set(dx, dy);
255a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    fRecs = rec;
265a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
275a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    return &rec->fPaint;
285a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
295a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
305a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmvoid SkLayerDrawLooper::init(SkCanvas* canvas) {
315a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    fCurrRec = fRecs;
325a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    canvas->save(SkCanvas::kMatrix_SaveFlag);
335a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
345a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
355a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmbool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
365a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    canvas->restore();
375a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    if (NULL == fCurrRec) {
385a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        return false;
3950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    }
4050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
4150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    *paint = fCurrRec->fPaint;
4250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    canvas->save(SkCanvas::kMatrix_SaveFlag);
4350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
4450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    fCurrRec = fCurrRec->fNext;
4550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
4650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    return true;
4750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm}
4850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
4950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmSkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
5050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    Rec* rec = head;
5150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    Rec* prev = NULL;
5250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    while (rec) {
5350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        Rec* next = rec->fNext;
5450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        rec->fNext = prev;
5550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        prev = rec;
5650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        rec = next;
5750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    }
5850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    return prev;
5950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm}
6050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
6150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm///////////////////////////////////////////////////////////////////////////////
6250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
6350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmvoid SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
6450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    this->INHERITED::flatten(buffer);
6550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
6650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#ifdef SK_DEBUG
6750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    {
6850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        Rec* rec = fRecs;
6950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        int count = 0;
7050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        while (rec) {
7150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm            rec = rec->fNext;
7250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm            count += 1;
7350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        }
7450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        SkASSERT(count == fCount);
7550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    }
7650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#endif
7750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
7850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    buffer.writeInt(fCount);
795a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
805a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    Rec* rec = fRecs;
815a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    for (int i = 0; i < fCount; i++) {
825a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        buffer.writeScalar(rec->fOffset.fX);
8350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        buffer.writeScalar(rec->fOffset.fY);
8450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        rec->fPaint.flatten(buffer);
855a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        rec = rec->fNext;
865d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantala    }
875a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
885a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
89f576cce7480d6acee537cecfeb5530187e50f785hp.com!davidmSkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
905a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        : INHERITED(buffer) {
9150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    fRecs = NULL;
9250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    fCount = 0;
9350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
9450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    int count = buffer.readInt();
9550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
9650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    for (int i = 0; i < count; i++) {
9750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        SkScalar dx = buffer.readScalar();
9850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        SkScalar dy = buffer.readScalar();
9950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm        this->addLayer(dx, dy)->unflatten(buffer);
10050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    }
10150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    SkASSERT(count == fCount);
1025a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
10350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    // we're in reverse order, so fix it now
10450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    fRecs = Rec::Reverse(fRecs);
10550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
1065a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#ifdef SK_DEBUG
10750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    {
1085a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        Rec* rec = fRecs;
1095a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        int n = 0;
1105a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm        while (rec) {
111            rec = rec->fNext;
112            n += 1;
113        }
114        SkASSERT(count == n);
115    }
116#endif
117}
118
119///////////////////////////////////////////////////////////////////////////////
120
121static SkFlattenable::Registrar gReg("SkLayerDrawLooper",
122                                     SkLayerDrawLooper::CreateProc);
123