SkLayerDrawLooper.cpp revision 0e2810be95d3f1aa95c341521d3f514eb9e9ebde
1#include "SkCanvas.h"
2#include "SkLayerDrawLooper.h"
3#include "SkPaint.h"
4
5SkLayerDrawLooper::SkLayerDrawLooper() {
6    fRecs = NULL;
7    fCount = 0;
8}
9
10SkLayerDrawLooper::~SkLayerDrawLooper() {
11    Rec* rec = fRecs;
12    while (rec) {
13        Rec* next = rec->fNext;
14        SkDELETE(rec);
15        rec = next;
16    }
17}
18
19SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) {
20    fCount += 1;
21
22    Rec* rec = SkNEW(Rec);
23    rec->fNext = fRecs;
24    rec->fOffset.set(dx, dy);
25    rec->fBits = bits;
26    fRecs = rec;
27
28    return &rec->fPaint;
29}
30
31void SkLayerDrawLooper::init(SkCanvas* canvas) {
32    fCurrRec = fRecs;
33    canvas->save(SkCanvas::kMatrix_SaveFlag);
34}
35
36void SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src,
37                                  BitFlags bits) {
38    if (kEntirePaint_Bits == bits) {
39        *dst = src;
40        return;
41    }
42
43    SkColor c = dst->getColor();
44    if (bits & kAlpha_Bit) {
45        c &= 0x00FFFFFF;
46        c |= src.getColor() & 0xFF000000;
47    }
48    if (bits & kColor_Bit) {
49        c &= 0xFF000000;
50        c |= src.getColor() & 0x00FFFFFF;
51    }
52    dst->setColor(c);
53
54    if (bits & kStyle_Bit) {
55        dst->setStyle(src.getStyle());
56        dst->setStrokeWidth(src.getStrokeWidth());
57        dst->setStrokeMiter(src.getStrokeMiter());
58        dst->setStrokeCap(src.getStrokeCap());
59        dst->setStrokeJoin(src.getStrokeJoin());
60    }
61
62    if (bits & kTextSkewX_Bit) {
63        dst->setTextSkewX(src.getTextSkewX());
64    }
65
66    if (bits & kPathEffect_Bit) {
67        dst->setPathEffect(src.getPathEffect());
68    }
69    if (bits & kMaskFilter_Bit) {
70        dst->setMaskFilter(src.getMaskFilter());
71    }
72    if (bits & kShader_Bit) {
73        dst->setShader(src.getShader());
74    }
75    if (bits & kColorFilter_Bit) {
76        dst->setColorFilter(src.getColorFilter());
77    }
78    if (bits & kXfermode_Bit) {
79        dst->setXfermode(src.getXfermode());
80    }
81
82    // we never copy these
83#if 0
84    dst->setFlags(src.getFlags());
85    dst->setTypeface(src.getTypeface());
86    dst->setTextSize(src.getTextSize());
87    dst->setTextScaleX(src.getTextScaleX());
88    dst->setTextSkewX(src.getTextSkewX());
89    dst->setRasterizer(src.getRasterizer());
90    dst->setLooper(src.getLooper());
91    dst->setTextEncoding(src.getTextEncoding());
92    dst->setHinting(src.getHinting());
93#endif
94}
95
96bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
97    canvas->restore();
98    if (NULL == fCurrRec) {
99        return false;
100    }
101
102    ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits);
103    canvas->save(SkCanvas::kMatrix_SaveFlag);
104    canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
105    fCurrRec = fCurrRec->fNext;
106
107    return true;
108}
109
110SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
111    Rec* rec = head;
112    Rec* prev = NULL;
113    while (rec) {
114        Rec* next = rec->fNext;
115        rec->fNext = prev;
116        prev = rec;
117        rec = next;
118    }
119    return prev;
120}
121
122///////////////////////////////////////////////////////////////////////////////
123
124void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
125    this->INHERITED::flatten(buffer);
126
127#ifdef SK_DEBUG
128    {
129        Rec* rec = fRecs;
130        int count = 0;
131        while (rec) {
132            rec = rec->fNext;
133            count += 1;
134        }
135        SkASSERT(count == fCount);
136    }
137#endif
138
139    buffer.writeInt(fCount);
140
141    Rec* rec = fRecs;
142    for (int i = 0; i < fCount; i++) {
143        buffer.writeScalar(rec->fOffset.fX);
144        buffer.writeScalar(rec->fOffset.fY);
145        rec->fPaint.flatten(buffer);
146        rec = rec->fNext;
147    }
148}
149
150SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
151        : INHERITED(buffer) {
152    fRecs = NULL;
153    fCount = 0;
154
155    int count = buffer.readInt();
156
157    for (int i = 0; i < count; i++) {
158        SkScalar dx = buffer.readScalar();
159        SkScalar dy = buffer.readScalar();
160        this->addLayer(dx, dy)->unflatten(buffer);
161    }
162    SkASSERT(count == fCount);
163
164    // we're in reverse order, so fix it now
165    fRecs = Rec::Reverse(fRecs);
166
167#ifdef SK_DEBUG
168    {
169        Rec* rec = fRecs;
170        int n = 0;
171        while (rec) {
172            rec = rec->fNext;
173            n += 1;
174        }
175        SkASSERT(count == n);
176    }
177#endif
178}
179
180///////////////////////////////////////////////////////////////////////////////
181
182static SkFlattenable::Registrar gReg("SkLayerDrawLooper",
183                                     SkLayerDrawLooper::CreateProc);
184