SkLayerDrawLooper.cpp revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
131af32cfcd61671cbb5e567870103766b3231521Petr Machata#include "SkCanvas.h"
231af32cfcd61671cbb5e567870103766b3231521Petr Machata#include "SkLayerDrawLooper.h"
331af32cfcd61671cbb5e567870103766b3231521Petr Machata#include "SkPaint.h"
431af32cfcd61671cbb5e567870103766b3231521Petr Machata
531af32cfcd61671cbb5e567870103766b3231521Petr MachataSkLayerDrawLooper::SkLayerDrawLooper() {
631af32cfcd61671cbb5e567870103766b3231521Petr Machata    fRecs = NULL;
731af32cfcd61671cbb5e567870103766b3231521Petr Machata    fCount = 0;
831af32cfcd61671cbb5e567870103766b3231521Petr Machata}
931af32cfcd61671cbb5e567870103766b3231521Petr Machata
1031af32cfcd61671cbb5e567870103766b3231521Petr MachataSkLayerDrawLooper::~SkLayerDrawLooper() {
1131af32cfcd61671cbb5e567870103766b3231521Petr Machata    Rec* rec = fRecs;
1231af32cfcd61671cbb5e567870103766b3231521Petr Machata    while (rec) {
1331af32cfcd61671cbb5e567870103766b3231521Petr Machata        Rec* next = rec->fNext;
1431af32cfcd61671cbb5e567870103766b3231521Petr Machata        SkDELETE(rec);
1531af32cfcd61671cbb5e567870103766b3231521Petr Machata        rec = next;
1631af32cfcd61671cbb5e567870103766b3231521Petr Machata    }
1731af32cfcd61671cbb5e567870103766b3231521Petr Machata}
1831af32cfcd61671cbb5e567870103766b3231521Petr Machata
1931af32cfcd61671cbb5e567870103766b3231521Petr MachataSkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
2031af32cfcd61671cbb5e567870103766b3231521Petr Machata    fCount += 1;
2131af32cfcd61671cbb5e567870103766b3231521Petr Machata
2231af32cfcd61671cbb5e567870103766b3231521Petr Machata    Rec* rec = SkNEW(Rec);
2331af32cfcd61671cbb5e567870103766b3231521Petr Machata    rec->fNext = fRecs;
2431af32cfcd61671cbb5e567870103766b3231521Petr Machata    rec->fOffset.set(dx, dy);
2531af32cfcd61671cbb5e567870103766b3231521Petr Machata    fRecs = rec;
2631af32cfcd61671cbb5e567870103766b3231521Petr Machata
2731af32cfcd61671cbb5e567870103766b3231521Petr Machata    return &rec->fPaint;
2831af32cfcd61671cbb5e567870103766b3231521Petr Machata}
2931af32cfcd61671cbb5e567870103766b3231521Petr Machata
3031af32cfcd61671cbb5e567870103766b3231521Petr Machatavoid SkLayerDrawLooper::init(SkCanvas* canvas, SkPaint* paint) {
3131af32cfcd61671cbb5e567870103766b3231521Petr Machata    fIter.fSavedPaint = *paint;
3231af32cfcd61671cbb5e567870103766b3231521Petr Machata    fIter.fPaint = paint;
3331af32cfcd61671cbb5e567870103766b3231521Petr Machata    fIter.fCanvas = canvas;
3431af32cfcd61671cbb5e567870103766b3231521Petr Machata    fIter.fRec = fRecs;
3531af32cfcd61671cbb5e567870103766b3231521Petr Machata    canvas->save(SkCanvas::kMatrix_SaveFlag);
3631af32cfcd61671cbb5e567870103766b3231521Petr Machata}
3731af32cfcd61671cbb5e567870103766b3231521Petr Machata
3831af32cfcd61671cbb5e567870103766b3231521Petr Machatabool SkLayerDrawLooper::next() {
3931af32cfcd61671cbb5e567870103766b3231521Petr Machata    Rec* rec = fIter.fRec;
4031af32cfcd61671cbb5e567870103766b3231521Petr Machata    if (rec) {
4131af32cfcd61671cbb5e567870103766b3231521Petr Machata        *fIter.fPaint = rec->fPaint;
4231af32cfcd61671cbb5e567870103766b3231521Petr Machata        fIter.fCanvas->restore();
4331af32cfcd61671cbb5e567870103766b3231521Petr Machata        fIter.fCanvas->save(SkCanvas::kMatrix_SaveFlag);
4431af32cfcd61671cbb5e567870103766b3231521Petr Machata        fIter.fCanvas->translate(rec->fOffset.fX, rec->fOffset.fY);
4531af32cfcd61671cbb5e567870103766b3231521Petr Machata
4631af32cfcd61671cbb5e567870103766b3231521Petr Machata        fIter.fRec = rec->fNext;
4731af32cfcd61671cbb5e567870103766b3231521Petr Machata        return true;
4831af32cfcd61671cbb5e567870103766b3231521Petr Machata    }
4931af32cfcd61671cbb5e567870103766b3231521Petr Machata    return false;
5031af32cfcd61671cbb5e567870103766b3231521Petr Machata}
5131af32cfcd61671cbb5e567870103766b3231521Petr Machata
5231af32cfcd61671cbb5e567870103766b3231521Petr Machatavoid SkLayerDrawLooper::restore() {
5331af32cfcd61671cbb5e567870103766b3231521Petr Machata    fIter.fCanvas->restore();
5431af32cfcd61671cbb5e567870103766b3231521Petr Machata    *fIter.fPaint = fIter.fSavedPaint;
5531af32cfcd61671cbb5e567870103766b3231521Petr Machata}
5631af32cfcd61671cbb5e567870103766b3231521Petr Machata
5731af32cfcd61671cbb5e567870103766b3231521Petr MachataSkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
5831af32cfcd61671cbb5e567870103766b3231521Petr Machata    Rec* rec = head;
5931af32cfcd61671cbb5e567870103766b3231521Petr Machata    Rec* prev = NULL;
6031af32cfcd61671cbb5e567870103766b3231521Petr Machata    while (rec) {
6131af32cfcd61671cbb5e567870103766b3231521Petr Machata        Rec* next = rec->fNext;
6231af32cfcd61671cbb5e567870103766b3231521Petr Machata        rec->fNext = prev;
63        prev = rec;
64        rec = next;
65    }
66    return prev;
67}
68
69///////////////////////////////////////////////////////////////////////////////
70
71void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
72    this->INHERITED::flatten(buffer);
73
74#ifdef SK_DEBUG
75    {
76        Rec* rec = fRecs;
77        int count = 0;
78        while (rec) {
79            rec = rec->fNext;
80            count += 1;
81        }
82        SkASSERT(count == fCount);
83    }
84#endif
85
86    buffer.writeInt(fCount);
87
88    Rec* rec = fRecs;
89    for (int i = 0; i < fCount; i++) {
90        buffer.writeScalar(rec->fOffset.fX);
91        buffer.writeScalar(rec->fOffset.fY);
92        rec->fPaint.flatten(buffer);
93        rec = rec->fNext;
94    }
95}
96
97SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
98        : INHERITED(buffer) {
99    fRecs = NULL;
100    fCount = 0;
101
102    int count = buffer.readInt();
103
104    for (int i = 0; i < count; i++) {
105        SkScalar dx = buffer.readScalar();
106        SkScalar dy = buffer.readScalar();
107        this->addLayer(dx, dy)->unflatten(buffer);
108    }
109    SkASSERT(count == fCount);
110
111    // we're in reverse order, so fix it now
112    fRecs = Rec::Reverse(fRecs);
113
114#ifdef SK_DEBUG
115    {
116        Rec* rec = fRecs;
117        int n = 0;
118        while (rec) {
119            rec = rec->fNext;
120            n += 1;
121        }
122        SkASSERT(count == n);
123    }
124#endif
125}
126
127///////////////////////////////////////////////////////////////////////////////
128
129static SkFlattenable::Registrar gReg("SkLayerDrawLooper",
130                                     SkLayerDrawLooper::CreateProc);
131