blob: ee0fc985ccaa32f215157d4bccf9fdb0b95199ad [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#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
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000019SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000020 fCount += 1;
21
22 Rec* rec = SkNEW(Rec);
23 rec->fNext = fRecs;
24 rec->fOffset.set(dx, dy);
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000025 rec->fBits = bits;
reed@android.com8a1c16f2008-12-17 15:59:43 +000026 fRecs = rec;
27
28 return &rec->fPaint;
29}
30
reed@google.com4e2b3d32011-04-07 14:18:59 +000031void SkLayerDrawLooper::init(SkCanvas* canvas) {
32 fCurrRec = fRecs;
reed@android.com8a1c16f2008-12-17 15:59:43 +000033 canvas->save(SkCanvas::kMatrix_SaveFlag);
34}
35
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000036void 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
reed@google.com4e2b3d32011-04-07 14:18:59 +000096bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
97 canvas->restore();
98 if (NULL == fCurrRec) {
99 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000101
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000102 ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits);
reed@google.com4e2b3d32011-04-07 14:18:59 +0000103 canvas->save(SkCanvas::kMatrix_SaveFlag);
104 canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
mike@reedtribe.orge5d0def2011-04-08 00:53:48 +0000105 fCurrRec = fCurrRec->fNext;
106
reed@google.com4e2b3d32011-04-07 14:18:59 +0000107 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108}
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);