blob: db641334e59b9718707c7a21ba54dbd61278746e [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) {
mike@reedtribe.org3c1225b2011-04-09 18:54:08 +000038 if (0 == bits) {
39 return;
40 }
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000041 if (kEntirePaint_Bits == bits) {
42 *dst = src;
43 return;
44 }
45
46 SkColor c = dst->getColor();
47 if (bits & kAlpha_Bit) {
48 c &= 0x00FFFFFF;
49 c |= src.getColor() & 0xFF000000;
50 }
51 if (bits & kColor_Bit) {
52 c &= 0xFF000000;
53 c |= src.getColor() & 0x00FFFFFF;
54 }
55 dst->setColor(c);
56
57 if (bits & kStyle_Bit) {
58 dst->setStyle(src.getStyle());
59 dst->setStrokeWidth(src.getStrokeWidth());
60 dst->setStrokeMiter(src.getStrokeMiter());
61 dst->setStrokeCap(src.getStrokeCap());
62 dst->setStrokeJoin(src.getStrokeJoin());
63 }
64
65 if (bits & kTextSkewX_Bit) {
66 dst->setTextSkewX(src.getTextSkewX());
67 }
68
69 if (bits & kPathEffect_Bit) {
70 dst->setPathEffect(src.getPathEffect());
71 }
72 if (bits & kMaskFilter_Bit) {
73 dst->setMaskFilter(src.getMaskFilter());
74 }
75 if (bits & kShader_Bit) {
76 dst->setShader(src.getShader());
77 }
78 if (bits & kColorFilter_Bit) {
79 dst->setColorFilter(src.getColorFilter());
80 }
81 if (bits & kXfermode_Bit) {
82 dst->setXfermode(src.getXfermode());
83 }
84
85 // we never copy these
86#if 0
87 dst->setFlags(src.getFlags());
88 dst->setTypeface(src.getTypeface());
89 dst->setTextSize(src.getTextSize());
90 dst->setTextScaleX(src.getTextScaleX());
91 dst->setTextSkewX(src.getTextSkewX());
92 dst->setRasterizer(src.getRasterizer());
93 dst->setLooper(src.getLooper());
94 dst->setTextEncoding(src.getTextEncoding());
95 dst->setHinting(src.getHinting());
96#endif
97}
98
reed@google.com4e2b3d32011-04-07 14:18:59 +000099bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
100 canvas->restore();
101 if (NULL == fCurrRec) {
102 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000105 ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits);
reed@google.com4e2b3d32011-04-07 14:18:59 +0000106 canvas->save(SkCanvas::kMatrix_SaveFlag);
107 canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
mike@reedtribe.orge5d0def2011-04-08 00:53:48 +0000108 fCurrRec = fCurrRec->fNext;
109
reed@google.com4e2b3d32011-04-07 14:18:59 +0000110 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111}
112
113SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
114 Rec* rec = head;
115 Rec* prev = NULL;
116 while (rec) {
117 Rec* next = rec->fNext;
118 rec->fNext = prev;
119 prev = rec;
120 rec = next;
121 }
122 return prev;
123}
124
125///////////////////////////////////////////////////////////////////////////////
126
127void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
128 this->INHERITED::flatten(buffer);
129
130#ifdef SK_DEBUG
131 {
132 Rec* rec = fRecs;
133 int count = 0;
134 while (rec) {
135 rec = rec->fNext;
136 count += 1;
137 }
138 SkASSERT(count == fCount);
139 }
140#endif
141
142 buffer.writeInt(fCount);
143
144 Rec* rec = fRecs;
145 for (int i = 0; i < fCount; i++) {
146 buffer.writeScalar(rec->fOffset.fX);
147 buffer.writeScalar(rec->fOffset.fY);
148 rec->fPaint.flatten(buffer);
149 rec = rec->fNext;
150 }
151}
152
153SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
154 : INHERITED(buffer) {
155 fRecs = NULL;
156 fCount = 0;
157
158 int count = buffer.readInt();
159
160 for (int i = 0; i < count; i++) {
161 SkScalar dx = buffer.readScalar();
162 SkScalar dy = buffer.readScalar();
163 this->addLayer(dx, dy)->unflatten(buffer);
164 }
165 SkASSERT(count == fCount);
166
167 // we're in reverse order, so fix it now
168 fRecs = Rec::Reverse(fRecs);
169
170#ifdef SK_DEBUG
171 {
172 Rec* rec = fRecs;
173 int n = 0;
174 while (rec) {
175 rec = rec->fNext;
176 n += 1;
177 }
178 SkASSERT(count == n);
179 }
180#endif
181}
182
183///////////////////////////////////////////////////////////////////////////////
184
185static SkFlattenable::Registrar gReg("SkLayerDrawLooper",
186 SkLayerDrawLooper::CreateProc);