blob: 5e6c632b9178fdc2a5078a51b5292627d80f6fd6 [file] [log] [blame]
reed@google.combb6992a2011-04-26 17:41:56 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "SkCanvas.h"
19#include "SkPaint.h"
reed@google.comacd471f2011-05-03 21:26:46 +000020#include "SkGPipe.h"
reed@google.combb6992a2011-04-26 17:41:56 +000021#include "SkGPipePriv.h"
22#include "SkReader32.h"
reed@google.comf5842f72011-05-04 18:30:04 +000023#include "SkStream.h"
reed@google.combb6793b2011-05-05 15:18:15 +000024
25#include "SkColorFilter.h"
26#include "SkDrawLooper.h"
27#include "SkMaskFilter.h"
28#include "SkPathEffect.h"
29#include "SkRasterizer.h"
30#include "SkShader.h"
reed@google.comf5842f72011-05-04 18:30:04 +000031#include "SkTypeface.h"
reed@google.combb6793b2011-05-05 15:18:15 +000032#include "SkXfermode.h"
33
reed@google.comb55d1182011-05-11 00:42:04 +000034static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
35 SkASSERT(paintFlat < kCount_PaintFlats);
36 switch (paintFlat) {
37 case kColorFilter_PaintFlat:
38 paint->setColorFilter((SkColorFilter*)obj);
39 break;
reed@google.com0faac1e2011-05-11 05:58:58 +000040 case kDrawLooper_PaintFlat:
41 paint->setLooper((SkDrawLooper*)obj);
42 break;
reed@google.comb55d1182011-05-11 00:42:04 +000043 case kMaskFilter_PaintFlat:
44 paint->setMaskFilter((SkMaskFilter*)obj);
45 break;
46 case kPathEffect_PaintFlat:
47 paint->setPathEffect((SkPathEffect*)obj);
48 break;
49 case kRasterizer_PaintFlat:
50 paint->setRasterizer((SkRasterizer*)obj);
51 break;
52 case kShader_PaintFlat:
53 paint->setShader((SkShader*)obj);
54 break;
55 case kXfermode_PaintFlat:
56 paint->setXfermode((SkXfermode*)obj);
57 break;
58 default:
59 SkASSERT(!"never gets here");
60 }
61}
62
reed@google.combb6793b2011-05-05 15:18:15 +000063template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
64public:
65 ~SkRefCntTDArray() { this->unrefAll(); }
66};
reed@google.combb6992a2011-04-26 17:41:56 +000067
68class SkGPipeState {
69public:
70 SkGPipeState();
71 ~SkGPipeState();
reed@google.combb6793b2011-05-05 15:18:15 +000072
73 void setReader(SkFlattenableReadBuffer* reader) { fReader = reader; }
74
reed@google.com31891582011-05-12 03:03:56 +000075 const SkPaint& paint() const { return fPaint; }
76 SkPaint* editPaint() { return &fPaint; }
reed@google.combb6992a2011-04-26 17:41:56 +000077
reed@google.comb55d1182011-05-11 00:42:04 +000078 SkFlattenable* getFlat(unsigned index) const {
79 if (0 == index) {
80 return NULL;
81 }
82 return fFlatArray[index - 1];
83 }
84
85 void defFlattenable(PaintFlats pf, unsigned index) {
86 SkFlattenable* obj = fReader->readFlattenable();
87 *fFlatArray.append() = obj;
88 SkASSERT(index == fFlatArray.count());
89 }
90
reed@google.combb6793b2011-05-05 15:18:15 +000091 void addTypeface() {
92 size_t size = fReader->readU32();
93 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +000094 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +000095 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
reed@google.com0faac1e2011-05-11 05:58:58 +000096 }
reed@google.combb6793b2011-05-05 15:18:15 +000097 void setTypeface(SkPaint* paint, unsigned id) {
98 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
99 }
reed@google.combb6793b2011-05-05 15:18:15 +0000100
reed@google.combb6793b2011-05-05 15:18:15 +0000101 SkFlattenableReadBuffer* fReader;
reed@google.comb55d1182011-05-11 00:42:04 +0000102
103private:
reed@google.com31891582011-05-12 03:03:56 +0000104 SkPaint fPaint;
105 SkTDArray<SkFlattenable*> fFlatArray;
106 SkTDArray<SkTypeface*> fTypefaces;
reed@google.combb6992a2011-04-26 17:41:56 +0000107};
108
109///////////////////////////////////////////////////////////////////////////////
110
111template <typename T> const T* skip(SkReader32* reader, int count = 1) {
112 SkASSERT(count >= 0);
113 size_t size = sizeof(T) * count;
114 SkASSERT(SkAlign4(size) == size);
115 return reinterpret_cast<const T*>(reader->skip(size));
116}
117
118template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
119 SkASSERT(count >= 0);
120 size_t size = SkAlign4(sizeof(T) * count);
121 return reinterpret_cast<const T*>(reader->skip(size));
122}
123
reed@google.combb6992a2011-04-26 17:41:56 +0000124///////////////////////////////////////////////////////////////////////////////
125///////////////////////////////////////////////////////////////////////////////
126
127static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
128 SkGPipeState* state) {
129 SkPath path;
130 path.unflatten(*reader);
131 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
132}
133
134static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
135 SkGPipeState* state) {
136 SkRegion rgn;
reed@google.comb55d1182011-05-11 00:42:04 +0000137 SkReadRegion(reader, &rgn);
reed@google.combb6992a2011-04-26 17:41:56 +0000138 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
139}
140
141static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
142 SkGPipeState* state) {
143 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
144}
145
146///////////////////////////////////////////////////////////////////////////////
147
148static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
149 SkGPipeState* state) {
150 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000151 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000152 canvas->setMatrix(matrix);
153}
154
155static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
156 SkGPipeState* state) {
157 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000158 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000159 canvas->concat(matrix);
160}
161
162static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
163 SkGPipeState* state) {
164 const SkScalar* param = skip<SkScalar>(reader, 2);
165 canvas->scale(param[0], param[1]);
166}
167
168static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
169 SkGPipeState* state) {
170 const SkScalar* param = skip<SkScalar>(reader, 2);
171 canvas->skew(param[0], param[1]);
172}
173
174static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
175 SkGPipeState* state) {
176 canvas->rotate(reader->readScalar());
177}
178
179static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
180 SkGPipeState* state) {
181 const SkScalar* param = skip<SkScalar>(reader, 2);
182 canvas->translate(param[0], param[1]);
183}
184
185///////////////////////////////////////////////////////////////////////////////
186
187static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
188 SkGPipeState* state) {
189 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
190}
191
192static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
193 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000194 unsigned flags = DrawOp_unpackFlags(op32);
195 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000196
197 const SkRect* bounds = NULL;
198 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
199 bounds = skip<SkRect>(reader);
200 }
201 const SkPaint* paint = NULL;
202 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
reed@google.com31891582011-05-12 03:03:56 +0000203 paint = &state->paint();
reed@google.combb6992a2011-04-26 17:41:56 +0000204 }
reed@google.comacd471f2011-05-03 21:26:46 +0000205 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000206}
207
208static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
209 SkGPipeState* state) {
210 canvas->restore();
211}
212
213///////////////////////////////////////////////////////////////////////////////
214
215static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
216 SkGPipeState* state) {
217 SkColor color = 0;
218 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
219 color = reader->readU32();
220 }
221 canvas->clear(color);
222}
223
224static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
225 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000226 canvas->drawPaint(state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000227}
228
229static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
230 SkGPipeState* state) {
231 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
232 size_t count = reader->readU32();
233 const SkPoint* pts = skip<SkPoint>(reader, count);
reed@google.com31891582011-05-12 03:03:56 +0000234 canvas->drawPoints(mode, count, pts, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000235}
236
237static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
238 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000239 canvas->drawRect(*skip<SkRect>(reader), state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000240}
241
242static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
243 SkGPipeState* state) {
244 SkPath path;
245 path.unflatten(*reader);
reed@google.com31891582011-05-12 03:03:56 +0000246 canvas->drawPath(path, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000247}
248
249static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
250 SkGPipeState* state) {
251 unsigned flags = DrawOp_unpackFlags(op32);
252
253 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
254 int vertexCount = reader->readU32();
255 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
256
257 const SkPoint* texs = NULL;
258 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
259 texs = skip<SkPoint>(reader, vertexCount);
260 }
261
262 const SkColor* colors = NULL;
263 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
264 colors = skip<SkColor>(reader, vertexCount);
265 }
266
267 // TODO: flatten/unflatten xfermodes
268 SkXfermode* xfer = NULL;
269
270 int indexCount = 0;
271 const uint16_t* indices = NULL;
272 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
273 indexCount = reader->readU32();
274 indices = skipAlign<uint16_t>(reader, indexCount);
275 }
276
277 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
reed@google.com31891582011-05-12 03:03:56 +0000278 indices, indexCount, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000279}
280
281///////////////////////////////////////////////////////////////////////////////
282
283static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
284 SkGPipeState* state) {
285 size_t len = reader->readU32();
286 const void* text = reader->skip(SkAlign4(len));
287 const SkScalar* xy = skip<SkScalar>(reader, 2);
reed@google.com31891582011-05-12 03:03:56 +0000288 canvas->drawText(text, len, xy[0], xy[1], state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000289}
290
291static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
292 SkGPipeState* state) {
293 size_t len = reader->readU32();
294 const void* text = reader->skip(SkAlign4(len));
295 size_t posCount = reader->readU32(); // compute by our writer
296 const SkPoint* pos = skip<SkPoint>(reader, posCount);
reed@google.com31891582011-05-12 03:03:56 +0000297 canvas->drawPosText(text, len, pos, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000298}
299
300static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
301 SkGPipeState* state) {
302 size_t len = reader->readU32();
303 const void* text = reader->skip(SkAlign4(len));
304 size_t posCount = reader->readU32(); // compute by our writer
305 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
306 SkScalar constY = reader->readScalar();
reed@google.com31891582011-05-12 03:03:56 +0000307 canvas->drawPosTextH(text, len, xpos, constY, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000308}
309
310static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
311 SkGPipeState* state) {
312 size_t len = reader->readU32();
313 const void* text = reader->skip(SkAlign4(len));
314
315 SkPath path;
316 path.unflatten(*reader);
317
318 SkMatrix matrixStorage;
319 const SkMatrix* matrix = NULL;
320 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
reed@google.comb55d1182011-05-11 00:42:04 +0000321 SkReadMatrix(reader, &matrixStorage);
reed@google.combb6992a2011-04-26 17:41:56 +0000322 matrix = &matrixStorage;
323 }
324
reed@google.com31891582011-05-12 03:03:56 +0000325 canvas->drawTextOnPath(text, len, path, matrix, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000326}
327
328///////////////////////////////////////////////////////////////////////////////
329
330static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
331 SkGPipeState* state) {
332 UNIMPLEMENTED
333}
334
335static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
336 SkGPipeState* state) {
337 UNIMPLEMENTED
338}
339
340static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
341 SkGPipeState* state) {
342 UNIMPLEMENTED
343}
344
345static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
346 SkGPipeState* state) {
347 UNIMPLEMENTED
348}
349
350///////////////////////////////////////////////////////////////////////////////
351
352static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
353 SkGPipeState* state) {
354 // since we don't have a paint, we can use data for our (small) sizes
355 size_t size = DrawOp_unpackData(op32);
356 if (0 == size) {
357 size = reader->readU32();
358 }
359 const void* data = reader->skip(SkAlign4(size));
360 canvas->drawData(data, size);
361}
362
363static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
364 SkGPipeState* state) {
365 UNIMPLEMENTED
366}
367
368static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
369 SkGPipeState* state) {
370 UNIMPLEMENTED
371}
372
373///////////////////////////////////////////////////////////////////////////////
374
reed@google.combb6992a2011-04-26 17:41:56 +0000375static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
376 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000377 size_t offset = reader->offset();
378 size_t stop = offset + PaintOp_unpackData(op32);
reed@google.com31891582011-05-12 03:03:56 +0000379 SkPaint* p = state->editPaint();
reed@google.combb6992a2011-04-26 17:41:56 +0000380
381 do {
382 uint32_t p32 = reader->readU32();
383 unsigned op = PaintOp_unpackOp(p32);
384 unsigned data = PaintOp_unpackData(p32);
reed@google.combb6992a2011-04-26 17:41:56 +0000385
reed@google.comb55d1182011-05-11 00:42:04 +0000386// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000387
388 switch (op) {
389 case kReset_PaintOp: p->reset(); break;
390 case kFlags_PaintOp: p->setFlags(data); break;
391 case kColor_PaintOp: p->setColor(reader->readU32()); break;
392 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
393 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
394 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
395 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
396 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
397 case kEncoding_PaintOp:
398 p->setTextEncoding((SkPaint::TextEncoding)data);
399 break;
400 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
401 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
402 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
403 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
404 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000405
reed@google.comb55d1182011-05-11 00:42:04 +0000406 case kFlatIndex_PaintOp: {
407 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
408 unsigned index = data;
409 set_paintflat(p, state->getFlat(index), pf);
410 break;
411 }
412
reed@google.combb6793b2011-05-05 15:18:15 +0000413 case kTypeface_PaintOp: state->setTypeface(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000414 default: SkASSERT(!"bad paintop"); return;
415 }
reed@google.comb55d1182011-05-11 00:42:04 +0000416 SkASSERT(reader->offset() <= stop);
reed@google.com31891582011-05-12 03:03:56 +0000417 } while (reader->offset() < stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000418}
419
reed@google.combb6793b2011-05-05 15:18:15 +0000420///////////////////////////////////////////////////////////////////////////////
421
reed@google.com0faac1e2011-05-11 05:58:58 +0000422static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
423 state->addTypeface();
424}
425
reed@google.comb55d1182011-05-11 00:42:04 +0000426static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
427 SkGPipeState* state) {
428 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
429 unsigned index = DrawOp_unpackData(op32);
430 state->defFlattenable(pf, index);
431}
432
reed@google.combb6992a2011-04-26 17:41:56 +0000433///////////////////////////////////////////////////////////////////////////////
434
reed@google.comacd471f2011-05-03 21:26:46 +0000435static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
436 size_t bytes = DrawOp_unpackData(op32);
437 (void)reader->skip(bytes);
438}
439
reed@google.combb6992a2011-04-26 17:41:56 +0000440static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
441
442typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
443
444static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000445 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000446 clipPath_rp,
447 clipRegion_rp,
448 clipRect_rp,
449 concat_rp,
450 drawBitmap_rp,
451 drawBitmapMatrix_rp,
452 drawBitmapRect_rp,
453 drawClear_rp,
454 drawData_rp,
455 drawPaint_rp,
456 drawPath_rp,
457 drawPicture_rp,
458 drawPoints_rp,
459 drawPosText_rp,
460 drawPosTextH_rp,
461 drawRect_rp,
462 drawShape_rp,
463 drawSprite_rp,
464 drawText_rp,
465 drawTextOnPath_rp,
466 drawVertices_rp,
467 restore_rp,
468 rotate_rp,
469 save_rp,
470 saveLayer_rp,
471 scale_rp,
472 setMatrix_rp,
473 skew_rp,
474 translate_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000475
reed@google.combb6992a2011-04-26 17:41:56 +0000476 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000477 def_Typeface_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000478 def_PaintFlat_rp,
479
reed@google.combb6992a2011-04-26 17:41:56 +0000480 done_rp
481};
482
483///////////////////////////////////////////////////////////////////////////////
484
reed@google.com31891582011-05-12 03:03:56 +0000485SkGPipeState::SkGPipeState() {}
reed@google.combb6992a2011-04-26 17:41:56 +0000486
reed@google.comb55d1182011-05-11 00:42:04 +0000487SkGPipeState::~SkGPipeState() {
reed@google.com31891582011-05-12 03:03:56 +0000488 fTypefaces.unrefAll();
reed@google.comb55d1182011-05-11 00:42:04 +0000489 fFlatArray.unrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000490}
491
492///////////////////////////////////////////////////////////////////////////////
493
494#include "SkGPipe.h"
495
496SkGPipeReader::SkGPipeReader(SkCanvas* target) {
497 SkSafeRef(target);
498 fCanvas = target;
499 fState = NULL;
500}
501
502SkGPipeReader::~SkGPipeReader() {
503 SkSafeUnref(fCanvas);
504 delete fState;
505}
506
507SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length) {
508 if (NULL == fCanvas) {
509 return kError_Status;
510 }
511
512 if (NULL == fState) {
513 fState = new SkGPipeState;
514 }
515
reed@google.com0faac1e2011-05-11 05:58:58 +0000516 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
517
reed@google.combb6992a2011-04-26 17:41:56 +0000518 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000519 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000520 SkCanvas* canvas = fCanvas;
reed@google.combb6793b2011-05-05 15:18:15 +0000521
522 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000523 while (!reader.eof()) {
524 uint32_t op32 = reader.readU32();
525 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000526 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000527
528 if (op >= SK_ARRAY_COUNT(gReadTable)) {
529 SkDebugf("---- bad op during GPipeState::playback\n");
530 return kError_Status;
531 }
532 if (kDone_DrawOp == op) {
533 return kDone_Status;
534 }
535 table[op](canvas, &reader, op32, fState);
536 }
537 return kEOF_Status;
538}
539
540